Skip to content

fix: validate mint for all token accounts, not just compressible#2251

Merged
ananas-block merged 7 commits intomainfrom
fix/audit-issue-7-mint-validation
Feb 12, 2026
Merged

fix: validate mint for all token accounts, not just compressible#2251
ananas-block merged 7 commits intomainfrom
fix/audit-issue-7-mint-validation

Conversation

@ananas-block
Copy link
Contributor

@ananas-block ananas-block commented Feb 6, 2026

Summary

  • Extend mint account validation to all ctoken account initialization paths, not just compressible accounts, preventing use of invalid or mismatched mints.
  • Read mint data once in initialize_ctoken_account, extract decimals during validation and pass down to configure_compression_info.

Summary by CodeRabbit

  • Refactor
    • Initialization now extracts and caches token decimal precision earlier, removing extra runtime reads and ensuring compressed token accounts store correct decimals at setup.
  • Tests
    • End-to-end and unit tests updated to create and use real on-chain mints; added helpers to provision decompressed mints for compression-related tests.
  • Chores
    • Account-loading sequence adjusted so mint data is prepared before dependent account loads.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 6, 2026

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (22)
  • js/compressed-token/src/v3/actions/mint-to-interface.ts is excluded by none and included by none
  • js/compressed-token/src/v3/actions/mint-to.ts is excluded by none and included by none
  • js/compressed-token/src/v3/actions/update-metadata.ts is excluded by none and included by none
  • js/compressed-token/src/v3/actions/update-mint.ts is excluded by none and included by none
  • js/compressed-token/src/v3/get-mint-interface.ts is excluded by none and included by none
  • js/compressed-token/src/v3/instructions/mint-to-interface.ts is excluded by none and included by none
  • js/compressed-token/src/v3/instructions/mint-to.ts is excluded by none and included by none
  • js/compressed-token/src/v3/instructions/update-metadata.ts is excluded by none and included by none
  • js/compressed-token/src/v3/instructions/update-mint.ts is excluded by none and included by none
  • js/compressed-token/tests/e2e/get-or-create-ata-interface.test.ts is excluded by none and included by none
  • js/compressed-token/tests/e2e/mint-to-ctoken.test.ts is excluded by none and included by none
  • js/compressed-token/tests/e2e/mint-to-interface.test.ts is excluded by none and included by none
  • js/compressed-token/tests/e2e/mint-workflow.test.ts is excluded by none and included by none
  • program-tests/compressed-token-test/tests/transfer2/compress_failing.rs is excluded by none and included by none
  • sdk-tests/anchor-semi-manual-test/tests/stress_test.rs is excluded by none and included by none
  • sdk-tests/anchor-semi-manual-test/tests/test_create_all.rs is excluded by none and included by none
  • sdk-tests/anchor-semi-manual-test/tests/test_create_ata.rs is excluded by none and included by none
  • sdk-tests/anchor-semi-manual-test/tests/test_create_token_vault.rs is excluded by none and included by none
  • sdk-tests/pinocchio-light-program-test/tests/stress_test.rs is excluded by none and included by none
  • sdk-tests/pinocchio-light-program-test/tests/test_create_all.rs is excluded by none and included by none
  • sdk-tests/pinocchio-light-program-test/tests/test_create_ata.rs is excluded by none and included by none
  • sdk-tests/pinocchio-light-program-test/tests/test_create_token_vault.rs is excluded by none and included by none

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Caches mint decimals during ctoken initialization and threads that value into compression setup; tests now create real on-chain decompressed mints before creating token accounts; client account-load ordering is changed so mint loads occur before dependent PDA/ATA loads.

Changes

Cohort / File(s) Summary
Initialization & compression logic
programs/compressed-token/program/src/shared/initialize_ctoken_account.rs
Extracts/validates mint_decimals: Option<u8> from mint data; configure_compression_info signature changed to accept mint_decimals instead of mint_account; propagation of decimals into compression extension at initialization.
Tests: on-chain mint creation & usage
forester/tests/e2e_test.rs, forester/tests/test_compressible_ctoken.rs
Added on-chain decompressed mint creation helper (create_decompressed_mint) and replaced local compressed-address derivation in multiple tests; tests now create and use real on-chain mints for compressible accounts.
Client account-load sequencing
sdk-libs/client/src/interface/load_accounts.rs
Reordered load generation so mint loads are emitted before DecompressAccountsIdempotent/PDA/ATA loads to ensure ATAs/PDAs depending on mints find the mint on-chain.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

ai-review

Suggested reviewers

  • sergeytimoshin
  • SwenSchaeferjohann

Poem

🌱 A mint appears where bytes align,
Decimals cached to save some time.
Tests now build the mint on-chain,
Loads reordered, flows refine.
Small edits hum — the trees grow fine. 🌿

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: validate mint for all token accounts, not just compressible' accurately summarizes the main change: extending mint validation across all ctoken initialization paths rather than just compressible accounts.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 70.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/audit-issue-7-mint-validation

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@programs/compressed-token/program/src/shared/initialize_ctoken_account.rs`:
- Around line 164-178: The code currently skips validation when mint data is
empty; change the mint validation block (around mint_decimals, where
AccountInfoTrait::try_borrow_data(mint_account) is used) to treat empty mint
data as an error instead of returning None: if mint_data.is_empty() then log a
descriptive msg! and return Err(ProgramError::InvalidAccountData); otherwise
continue to call is_valid_mint(mint_account.owner(), &mint_data)? and extract
decimals from byte 44 as before. Ensure the same error path and message are used
as other invalid-mint branches so tests like mint_validation.rs fail
appropriately for empty data.

Copy link
Contributor

@SwenSchaeferjohann SwenSchaeferjohann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consensus - we want to force mints to be decompressed when creating token accounts for Light Mints cc @ananas-block

Audit issue #7 (MEDIUM): is_valid_mint was only called inside
configure_compression_info, so non-compressible token accounts
could be initialized with an invalid mint. Move validation to
initialize_ctoken_account so it runs for all account types.
@ananas-block ananas-block force-pushed the fix/audit-issue-7-mint-validation branch from 6885468 to 27ae6fa Compare February 12, 2026 02:18
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
forester/tests/e2e_test.rs (1)

444-459: ⚠️ Potential issue | 🔴 Critical

This is the pipeline failure: subscriber account still uses Pubkey::new_unique() as mint.

Line 450 passes mint: Pubkey::new_unique() — a nonexistent account. Since this PR enforces mint validation for all token account init paths (not just compressible), the on-chain program now rejects this with "Invalid mint account: account data is empty," which is exactly what the CI failure reports.

You need to use compressible_mint here (or create a second real mint), just as you did for the bootstrap account on line 400.

🐛 Proposed fix — reuse the existing on-chain mint
     // Create 2nd compressible token account with 0 epochs rent (instantly compressible)
     // This account is picked up by the subscriber
     let compressible_account_subscriber = create_compressible_token_account(
         &mut rpc,
         CreateCompressibleTokenAccountInputs {
             owner: Keypair::new().pubkey(),
-            mint: Pubkey::new_unique(),
+            mint: compressible_mint,
             num_prepaid_epochs: 0,
             payer: &payer,
             token_account_keypair: None,
             lamports_per_write: Some(100),
             token_account_version: TokenDataVersion::ShaFlat,
         },
     )
     .await
     .expect("Failed to create compressible token account");

@ananas-block ananas-block merged commit 0a41106 into main Feb 12, 2026
30 checks passed
@ananas-block ananas-block deleted the fix/audit-issue-7-mint-validation branch February 12, 2026 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants