fix: prevent compressible account funding with 1 epoch#1993
fix: prevent compressible account funding with 1 epoch#1993ananas-block merged 18 commits intomainfrom
Conversation
WalkthroughRemoves legacy compressed-token account tests and adds a modular ctoken test suite with shared helpers; forbids exactly 1‑epoch rent prefunding; introduces DuplicateMint and OneEpochPrefundingNotAllowed errors; migrates many ArrayVec usages to ArrayMap/tinyvec/fixed arrays; adjusts rent constants, discriminators, Transfer2/CToken layouts, SDK types, and CI/workspace deps. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Client
participant Program as Compressed Token Program
rect rgba(230,245,255,0.6)
note right of Program: Create / Init (compressible)
Client->>Program: CreateTokenAccount{compressible_config.rent_payment = N}
Program->>Program: if rent_payment == 1 -> log & Err(OneEpochPrefundingNotAllowed)
alt rent_payment != 1
Program->>Program: check already-initialized -> proceed init
Program-->>Client: Ok
end
end
sequenceDiagram
autonumber
actor Client
participant Program as Compressed Token Program
participant Ledger as Token Account
rect rgba(240,255,240,0.6)
note right of Program: Compress-and-Close
Client->>Program: Transfer2: CompressAndClose(source, ...)
Program->>Ledger: Read source account
alt source.delegate != None
Program-->>Client: Err(CompressAndCloseDelegateNotAllowed)
else
Program->>Program: determine owner = compress_to_pubkey ? source_pubkey : owner_pubkey
Program->>Program: perform compress & close -> outputs/destination handling
Program-->>Client: Ok
end
end
sequenceDiagram
autonumber
actor SDK
participant Program as Compressed Token Program
rect rgba(255,245,230,0.6)
note right of Program: CToken Transfer layout & parsing
SDK->>SDK: build_instruction(data = [3u8 | padding? | amount_le])
SDK-->>Program: invoke(instruction_data)
Program->>Program: parse starting at byte 1 (expect >=3 accounts) else Err(NotEnoughAccountKeys)
Program-->>SDK: Ok / logs
end
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
WalkthroughIntroduces a new validation rejecting exactly 1-epoch prefunding for compressible accounts, adds a corresponding error code, updates documentation, and adjusts tests to use 2-epoch prefunding with updated epoch warps. Test code also switches many async error propagations to unwraps and removes a Result return from one test. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant C as Client
participant P as Compressed Token Program
participant V as Prefund Validator
participant F as Account Creation Flow
rect rgba(230,240,255,0.6)
note right of C: Create (associated) token account with compressible config
C->>P: Instruction (compressible_config, rent_payment)
P->>V: Validate compressible_config
V-->>P: rent_payment == 1 ?
alt New check: exactly 1 epoch
P-->>C: Error: OneEpochPrefundingNotAllowed
else Allowed
P->>F: Proceed with existing creation/compression logic
F-->>C: Success (account created)
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
programs/compressed-token/program/src/create_associated_token_account.rs (1)
152-156: Early validation prevents footgun scenario.The validation correctly rejects exactly 1 epoch prefunding before expensive operations. The error message is helpful and actionable.
Consider extracting validation to shared helper.
This validation logic is duplicated in
create_token_account.rs(lines 159-163). Consider extracting to a shared function to maintain consistency and reduce duplication:// In shared module pub fn validate_rent_payment(rent_payment: u64) -> Result<(), ProgramError> { if rent_payment == 1 { msg!("Prefunding for exactly 1 epoch is not allowed. If the account is created near an epoch boundary, it could become immediately compressible. Use 0 or 2+ epochs."); return Err(anchor_compressed_token::ErrorCode::OneEpochPrefundingNotAllowed.into()); } Ok(()) }programs/compressed-token/program/src/create_token_account.rs (1)
159-163: Early validation prevents epoch boundary issues.The validation correctly rejects exactly 1 epoch prefunding with a clear, actionable error message. The early return prevents unnecessary processing.
Note: This validation logic is duplicated from
create_associated_token_account.rs(lines 152-156). The suggestion to extract to a shared helper applies here as well.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
program-tests/compressed-token-test/tests/account.rs(6 hunks)program-tests/compressed-token-test/tests/compressible.rs(27 hunks)program-tests/compressed-token-test/tests/transfer2/compress_failing.rs(1 hunks)program-tests/compressed-token-test/tests/transfer2/decompress_failing.rs(1 hunks)programs/compressed-token/anchor/src/lib.rs(1 hunks)programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md(5 hunks)programs/compressed-token/program/src/create_associated_token_account.rs(1 hunks)programs/compressed-token/program/src/create_token_account.rs(1 hunks)sdk-libs/compressed-token-sdk/tests/create_associated_token_account.rs(1 hunks)sdk-tests/sdk-token-test/src/process_create_ctoken_with_compress_to_pubkey.rs(1 hunks)sdk-tests/sdk-token-test/tests/pda_ctoken.rs(1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
programs/compressed-token/program/src/{create_token_account.rs,create_associated_token_account.rs}
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Enforce ACTIVE-only config validation for Create CToken Account and Create Associated CToken Account instructions
Files:
programs/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/src/create_token_account.rs
programs/compressed-token/program/src/**/*.rs
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Return errors as ProgramError::Custom(error_code as u32) on-chain
Files:
programs/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/src/create_token_account.rs
programs/compressed-token/program/docs/instructions/*.md
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Each instruction doc must include: path, description, instruction_data (code paths), Accounts (order and checks), instruction logic and checks, and Errors (with causes)
Files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md
📄 CodeRabbit inference engine (programs/compressed-token/program/docs/CLAUDE.md)
Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions
Files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
programs/compressed-token/program/docs/**/instructions/**/*.md
📄 CodeRabbit inference engine (programs/compressed-token/program/docs/CLAUDE.md)
Keep detailed instruction documentation files under the instructions/ directory; add additional instruction docs as needed
Files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
sdk-tests/sdk-token-test/**/tests/**/*.rs
📄 CodeRabbit inference engine (sdk-tests/sdk-token-test/CLAUDE.md)
Every test should only contain functional integration tests
Files:
sdk-tests/sdk-token-test/tests/pda_ctoken.rs
🧠 Learnings (24)
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/{create_token_account.rs,create_associated_token_account.rs} : Enforce ACTIVE-only config validation for Create CToken Account and Create Associated CToken Account instructions
Applied to files:
programs/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/close_token_account{.rs,/**} : On closing ctoken accounts: if compressible, return rent exemption to the rent recipient; send remaining lamports to the destination
Applied to files:
programs/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprogram-tests/compressed-token-test/tests/account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Refactor rent logic so that 1 lamport is the minimum rent payment
Applied to files:
programs/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprogram-tests/compressed-token-test/tests/account.rssdk-tests/sdk-token-test/tests/pda_ctoken.rsprogram-tests/compressed-token-test/tests/transfer2/decompress_failing.rsprogram-tests/compressed-token-test/tests/transfer2/compress_failing.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Update RentConfig values at claim time to reflect current policy
Applied to files:
programs/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/config.rs : Update config parameters including max write fee and max funded epoch
Applied to files:
programs/compressed-token/program/src/create_associated_token_account.rssdk-libs/compressed-token-sdk/tests/create_associated_token_account.rssdk-tests/sdk-token-test/tests/pda_ctoken.rsprogram-tests/compressed-token-test/tests/transfer2/decompress_failing.rsprogram-tests/compressed-token-test/tests/transfer2/compress_failing.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/{claim/**,withdraw_funding_pool.rs} : Enforce Not Inactive config validation for Claim and Withdraw Funding Pool instructions
Applied to files:
programs/compressed-token/program/src/create_associated_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Determine compressibility and compute rent using calculate_rent_and_balance
Applied to files:
programs/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprogram-tests/compressed-token-test/tests/account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/config.rs : Implement CompressibleConfig account with Anchor, Borsh, and Pod serialization for Light Registry integration
Applied to files:
programs/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/programs/compressed-token/anchor/src/lib.rs : Define all program-specific error codes in anchor_compressed_token::ErrorCode and expose them for program-wide use
Applied to files:
programs/compressed-token/program/src/create_token_account.rsprograms/compressed-token/anchor/src/lib.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Document closing decompressed token accounts with rent distribution in instructions/CLOSE_TOKEN_ACCOUNT.md
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLAIM.md : Document rent reclamation from expired compressible accounts in instructions/CLAIM.md
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:45:40.029Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.029Z
Learning: Applies to programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md : Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CREATE_TOKEN_ACCOUNT.md : Document Create Token Account & Associated Token Account instructions in instructions/CREATE_TOKEN_ACCOUNT.md
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/{CREATE_TOKEN_ACCOUNT,MINT_ACTION,TRANSFER2,CLAIM,CLOSE_TOKEN_ACCOUNT,DECOMPRESSED_TRANSFER,WITHDRAW_FUNDING_POOL}.md : Every instruction description must include sections: path, description, instruction_data, Accounts, instruction logic and checks, Errors
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/docs/ACCOUNTS.md : Accounts documentation must include: description, discriminator, state layout, serialization example, hashing (only for compressed accounts), derivation (only for PDAs), and associated instructions
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/docs/instructions/*.md : Each instruction doc must include: path, description, instruction_data (code paths), Accounts (order and checks), instruction logic and checks, and Errors (with causes)
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/**/ACCOUNTS.md : Provide complete account layouts and data structures in ACCOUNTS.md
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/DECOMPRESSED_TRANSFER.md : Document SPL-compatible transfers between decompressed accounts in instructions/DECOMPRESSED_TRANSFER.md
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/error.rs : Provide ProgramError conversions compatible with Anchor, Pinocchio, and Solana error types
Applied to files:
programs/compressed-token/anchor/src/lib.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/error.rs : Maintain stable mapping of AccountError to ProgramError, including Pinocchio code mapping (1–11), in error.rs
Applied to files:
programs/compressed-token/anchor/src/lib.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/**/*.rs : Return errors as ProgramError::Custom(error_code as u32) on-chain
Applied to files:
programs/compressed-token/anchor/src/lib.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/**/*.rs : Return AccountError variants (codes 12006–12021) and rely on automatic ProgramError conversions; avoid returning raw ProgramError directly
Applied to files:
programs/compressed-token/anchor/src/lib.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Implement rent curve algorithms via rent_curve_per_epoch
Applied to files:
program-tests/compressed-token-test/tests/account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Expose claimable rent computation via claimable_lamports
Applied to files:
program-tests/compressed-token-test/tests/account.rsprogram-tests/compressed-token-test/tests/compressible.rs
🧬 Code graph analysis (1)
program-tests/compressed-token-test/tests/compressible.rs (2)
program-tests/utils/src/spl.rs (1)
create_mint_helper(260-263)sdk-libs/program-test/src/utils/assert.rs (1)
assert_rpc_error(7-56)
🪛 LanguageTool
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
[grammar] ~76-~76: There might be a mistake here.
Context: ...is not exactly 1 epoch - Check: compressible_config.rent_payment != 1 - Error: `ErrorCode::OneEpochPrefundingNot...
(QB_NEW_EN)
[grammar] ~180-~180: There might be a mistake here.
Context: ...epoch (see create ctoken account errors)
(QB_NEW_EN)
🪛 markdownlint-cli2 (0.18.1)
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
112-112: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
180-180: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: stateless-js-v1
- GitHub Check: system-programs (sdk-anchor-test-program, ["cargo-test-sbf -p sdk-anchor-test", "cargo-test-sbf -...
- GitHub Check: system-programs (sdk-token-test-program, ["cargo-test-sbf -p sdk-token-test"])
- GitHub Check: system-programs (sdk-test-program, ["cargo-test-sbf -p sdk-native-test", "cargo-test-sbf -p sdk-v...
- GitHub Check: system-programs (sdk-libs, light-sdk-macros light-sdk light-program-test light-client light-compr...
- GitHub Check: stateless-js-v2
- GitHub Check: cli-v2
- GitHub Check: cli-v1
- GitHub Check: lint
- GitHub Check: Forester e2e test
🔇 Additional comments (15)
programs/compressed-token/anchor/src/lib.rs (1)
415-416: LGTM! Clear error message for prefunding validation.The new error variant is well-documented with a clear message explaining the epoch boundary timing risk and providing actionable guidance (use 0 or 2+ epochs).
sdk-tests/sdk-token-test/src/process_create_ctoken_with_compress_to_pubkey.rs (1)
35-35: LGTM! Test updated for new validation.Correctly updates
pre_pay_num_epochsfrom 1 to 2 to align with the new validation that disallows exactly 1 epoch prefunding.program-tests/compressed-token-test/tests/transfer2/decompress_failing.rs (1)
102-102: LGTM! Test setup aligned with new validation.sdk-libs/compressed-token-sdk/tests/create_associated_token_account.rs (1)
40-40: LGTM! Test input updated correctly.sdk-tests/sdk-token-test/tests/pda_ctoken.rs (1)
216-216: LGTM! Test setup updated appropriately.program-tests/compressed-token-test/tests/transfer2/compress_failing.rs (1)
98-98: LGTM! Test setup updated consistently.program-tests/compressed-token-test/tests/compressible.rs (4)
71-71: LGTM! Acceptable test pattern for explicit success-path handling.The conversion from
?error propagation to.unwrap()is appropriate for tests, as it provides clear panic messages on failure while simplifying the test logic.Also applies to: 84-86, 111-112, 115-117, 123-125
143-143: LGTM! Consistent with the unwrap() pattern.The removal of the
Resultreturn type aligns with the shift from error propagation to panicking on failure, which is acceptable in test code.
154-154: LGTM! Correctly avoids 1-epoch prefunding.The loop range shift from
1..=10to2..=11ensures all test accounts comply with the new validation rule that forbids exactly 1 epoch of rent prefunding, while maintaining the same test coverage of 10 accounts with varying prepaid epochs.
443-443: LGTM! Complies with new 1-epoch prefunding restriction.The update of
pre_pay_num_epochsfrom 1 to 2 across all test scenarios correctly implements the new validation rule that forbids exactly 1 epoch of rent prefunding, ensuring tests reflect the intended behavior.Also applies to: 565-565, 600-600, 714-714
program-tests/compressed-token-test/tests/account.rs (2)
403-403: LGTM! Enforces minimum 2-epoch prefunding.The update from 1 to 2 prepaid epochs correctly implements the new validation rule that prevents exactly 1 epoch of rent prefunding, ensuring these test cases comply with the updated constraints.
Also applies to: 574-574
827-827: LGTM! Clear test progression with updated epoch accounting.The changes correctly:
- Update
pre_pay_num_epochsfrom 1 to 2 to comply with the new validation rule- Adjust comments to reflect the new total of 3 epochs (2 prepaid + 1 topped up)
- Update epoch progression expectations to match the new timing (epoch 3 instead of previous values)
The updated comments enhance test readability by clearly documenting the rent funding timeline.
Also applies to: 845-883
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md (3)
39-43: LGTM! Clear rationale for the validation rule.The documentation effectively explains:
- The forbidden value (rent_payment = 1)
- Allowed values (0 or 2+ epochs)
- The rationale: preventing accounts from becoming immediately compressible due to epoch boundary timing
This helps developers understand why the restriction exists and how to comply with it.
As per coding guidelines
75-78: LGTM! Well-positioned early validation.The addition of step 3.0 as an early validation check is appropriate:
- Fails fast before resource allocation
- Clear check condition and error code
- Explains the purpose of preventing epoch boundary timing issues
As per coding guidelines
112-112: LGTM! Consistent error documentation across instruction types.The error documentation:
- Includes the error code (6116) and name (OneEpochPrefundingNotAllowed)
- Explains the cause (rent_payment is exactly 1 epoch)
- Is consistently documented for both create_token_account and create_associated_token_account
- Follows the required schema of including error codes with descriptions
As per coding guidelines
Also applies to: 162-165, 180-180
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md (1)
18-18: Fix instruction path (missing/program/)Current path points to programs/compressed-token/src/create_token_account.rs; repository uses programs/compressed-token/program/src/create_token_account.rs.
Apply:
- **path:** programs/compressed-token/src/create_token_account.rs + **path:** programs/compressed-token/program/src/create_token_account.rsAs per coding guidelines
program-tests/compressed-token-test/tests/account.rs (1)
291-298: Fix assertion: hardcoded rent delta and mismatched messageTest still assumes 1-epoch constants and inconsistent numbers. Compute rent via RentConfig to match num_prepaid_epochs.
Apply:
- let tx_fee = 10_000; // Standard transaction fee - assert_eq!( - payer_balance_before - payer_balance_after, - 11_776 + tx_fee, - "Payer should have paid exactly 14,830 lamports for additional rent (1 epoch) plus {} tx fee", - tx_fee - ); + let rent = RentConfig::default() + .get_rent_with_compression_cost(COMPRESSIBLE_TOKEN_ACCOUNT_SIZE, num_prepaid_epochs); + let tx_fee = 10_000; // Standard transaction fee + assert_eq!( + payer_balance_before - payer_balance_after, + rent + tx_fee, + "Payer should have paid {} lamports for additional rent ({} epochs) plus {} tx fee", + rent, + num_prepaid_epochs, + tx_fee + );
🧹 Nitpick comments (9)
sdk-tests/sdk-token-test/src/process_create_ctoken_with_compress_to_pubkey.rs (1)
35-35: Consider adding a comment explaining the epoch count.The hardcoded value of 2 epochs is now required due to the new validation that rejects exactly 1 epoch. A brief inline comment would help future maintainers understand this constraint.
- pre_pay_num_epochs: 2, // Pre-pay for 2 epochs + pre_pay_num_epochs: 2, // Pre-pay for 2 epochs (1 epoch is disallowed due to epoch boundary timing risk)programs/compressed-token/program/src/create_associated_token_account.rs (1)
152-156: Consider extracting shared validation logic.This validation is duplicated in
create_token_account.rs(lines 159-163). Consider extracting to a shared helper function to maintain consistency and reduce duplication.Example location:
src/shared/mod.rsor a newsrc/shared/rent_validation.rs:pub fn validate_rent_payment(rent_payment: u16) -> Result<(), ProgramError> { if rent_payment == 1 { msg!("Prefunding for exactly 1 epoch is not allowed. If the account is created near an epoch boundary, it could become immediately compressible. Use 0 or 2+ epochs."); return Err(anchor_compressed_token::ErrorCode::OneEpochPrefundingNotAllowed.into()); } Ok(()) }programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md (4)
112-112: Fix list indentation (markdownlint MD007)Unordered list item should be top-level aligned like other Errors.
- - `ErrorCode::OneEpochPrefundingNotAllowed` (error code: 6116) - rent_payment is exactly 1 epoch, which is forbidden due to epoch boundary timing edge case +- `ErrorCode::OneEpochPrefundingNotAllowed` (error code: 6116) - rent_payment is exactly 1 epoch, which is forbidden due to epoch boundary timing edge caseAs per coding guidelines
10-10: Typo: “instruciton” → “instruction”Minor docs nit.
- - **instruciton logic and checks** + - **instruction logic and checks**As per coding guidelines
162-164: ATA docs: validation noted; fix list indentation
- Validation lines look good and mirror Create flow.
- Also fix MD007 indentation for the Errors bullet like above.
- - `ErrorCode::OneEpochPrefundingNotAllowed` (error code: 6116) - rent_payment is exactly 1 epoch (see create ctoken account errors) +- `ErrorCode::OneEpochPrefundingNotAllowed` (error code: 6116) - rent_payment is exactly 1 epoch (see create ctoken account errors)As per coding guidelines
Also applies to: 180-180
64-68: Unify account naming: rent_payer_pda vs. fee_payer_pdaDocs mix “rent_payer_pda” (Create) and “fee_payer_pda” (ATA) for the same role. Pick one term and define it once to avoid confusion.
As per coding guidelines
Also applies to: 148-153
program-tests/compressed-token-test/tests/account.rs (1)
472-477: Minor: Message refers to “Pool PDA” while using a custom rent payerSince rent_sponsor is the custom payer, tweak the message to avoid “Pool PDA” phrasing.
program-tests/compressed-token-test/tests/compressible.rs (2)
150-153: Update comment to match new range (2..=11)Loop now creates 2..=11 prepaid epochs; fix the stale “1 to 10” comment.
-// Create 10 token accounts with varying prepaid epochs (1 to 10) +// Create 10 token accounts with varying prepaid epochs (2 to 11) -for i in 2..=11 { +for i in 2..=11 {Also applies to: 154-156
142-147: Add a negative test for 1‑epoch prefundingPlease add a test that attempts num_prepaid_epochs = 1 and asserts ErrorCode::OneEpochPrefundingNotAllowed (6116). This locks in the new rule.
Example:
#[tokio::test] async fn test_reject_one_epoch_prefunding() { let mut rpc = LightProgramTest::new(ProgramTestConfig::new_v2(false, None)).await.unwrap(); let payer = rpc.get_payer().insecure_clone(); let owner = Keypair::new(); let mint = create_mint_helper(&mut rpc, &payer).await; let result = create_compressible_token_account( &mut rpc, CreateCompressibleTokenAccountInputs { owner: owner.pubkey(), mint, num_prepaid_epochs: 1, payer: &payer, token_account_keypair: None, lamports_per_write: Some(100), token_account_version: light_ctoken_types::state::TokenDataVersion::ShaFlat, }, ) .await; // Expect custom error 6116 on instruction 0 assert_rpc_error(result, 0, 6116).unwrap(); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
program-tests/compressed-token-test/tests/account.rs(6 hunks)program-tests/compressed-token-test/tests/compressible.rs(27 hunks)program-tests/compressed-token-test/tests/transfer2/compress_failing.rs(1 hunks)program-tests/compressed-token-test/tests/transfer2/decompress_failing.rs(1 hunks)programs/compressed-token/anchor/src/lib.rs(1 hunks)programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md(5 hunks)programs/compressed-token/program/src/create_associated_token_account.rs(1 hunks)programs/compressed-token/program/src/create_token_account.rs(1 hunks)sdk-libs/compressed-token-sdk/tests/create_associated_token_account.rs(1 hunks)sdk-tests/sdk-token-test/src/process_create_ctoken_with_compress_to_pubkey.rs(1 hunks)sdk-tests/sdk-token-test/tests/pda_ctoken.rs(1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
programs/compressed-token/program/src/{create_token_account.rs,create_associated_token_account.rs}
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Enforce ACTIVE-only config validation for Create CToken Account and Create Associated CToken Account instructions
Files:
programs/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/src/create_token_account.rs
programs/compressed-token/program/src/**/*.rs
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Return errors as ProgramError::Custom(error_code as u32) on-chain
Files:
programs/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/src/create_token_account.rs
programs/compressed-token/program/docs/instructions/*.md
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Each instruction doc must include: path, description, instruction_data (code paths), Accounts (order and checks), instruction logic and checks, and Errors (with causes)
Files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md
📄 CodeRabbit inference engine (programs/compressed-token/program/docs/CLAUDE.md)
Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions
Files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
programs/compressed-token/program/docs/**/instructions/**/*.md
📄 CodeRabbit inference engine (programs/compressed-token/program/docs/CLAUDE.md)
Keep detailed instruction documentation files under the instructions/ directory; add additional instruction docs as needed
Files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
sdk-tests/sdk-token-test/**/tests/**/*.rs
📄 CodeRabbit inference engine (sdk-tests/sdk-token-test/CLAUDE.md)
Every test should only contain functional integration tests
Files:
sdk-tests/sdk-token-test/tests/pda_ctoken.rs
🧠 Learnings (24)
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/{create_token_account.rs,create_associated_token_account.rs} : Enforce ACTIVE-only config validation for Create CToken Account and Create Associated CToken Account instructions
Applied to files:
programs/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdsdk-tests/sdk-token-test/src/process_create_ctoken_with_compress_to_pubkey.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/close_token_account{.rs,/**} : On closing ctoken accounts: if compressible, return rent exemption to the rent recipient; send remaining lamports to the destination
Applied to files:
programs/compressed-token/program/src/create_associated_token_account.rsprogram-tests/compressed-token-test/tests/transfer2/compress_failing.rsprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprogram-tests/compressed-token-test/tests/account.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Refactor rent logic so that 1 lamport is the minimum rent payment
Applied to files:
programs/compressed-token/program/src/create_associated_token_account.rsprogram-tests/compressed-token-test/tests/transfer2/compress_failing.rsprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprogram-tests/compressed-token-test/tests/transfer2/decompress_failing.rsprogram-tests/compressed-token-test/tests/account.rssdk-tests/sdk-token-test/tests/pda_ctoken.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/config.rs : Update config parameters including max write fee and max funded epoch
Applied to files:
programs/compressed-token/program/src/create_associated_token_account.rsprogram-tests/compressed-token-test/tests/transfer2/compress_failing.rsprogram-tests/compressed-token-test/tests/transfer2/decompress_failing.rssdk-tests/sdk-token-test/tests/pda_ctoken.rssdk-libs/compressed-token-sdk/tests/create_associated_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Update RentConfig values at claim time to reflect current policy
Applied to files:
programs/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Determine compressibility and compute rent using calculate_rent_and_balance
Applied to files:
programs/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprogram-tests/compressed-token-test/tests/account.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/config.rs : Implement CompressibleConfig account with Anchor, Borsh, and Pod serialization for Light Registry integration
Applied to files:
programs/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/programs/compressed-token/anchor/src/lib.rs : Define all program-specific error codes in anchor_compressed_token::ErrorCode and expose them for program-wide use
Applied to files:
programs/compressed-token/anchor/src/lib.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/error.rs : Maintain stable mapping of AccountError to ProgramError, including Pinocchio code mapping (1–11), in error.rs
Applied to files:
programs/compressed-token/anchor/src/lib.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/error.rs : Provide ProgramError conversions compatible with Anchor, Pinocchio, and Solana error types
Applied to files:
programs/compressed-token/anchor/src/lib.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/**/*.rs : Return errors as ProgramError::Custom(error_code as u32) on-chain
Applied to files:
programs/compressed-token/anchor/src/lib.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/**/*.rs : Return AccountError variants (codes 12006–12021) and rely on automatic ProgramError conversions; avoid returning raw ProgramError directly
Applied to files:
programs/compressed-token/anchor/src/lib.rs
📚 Learning: 2025-10-15T03:45:40.029Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.029Z
Learning: Applies to programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md : Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CREATE_TOKEN_ACCOUNT.md : Document Create Token Account & Associated Token Account instructions in instructions/CREATE_TOKEN_ACCOUNT.md
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Document closing decompressed token accounts with rent distribution in instructions/CLOSE_TOKEN_ACCOUNT.md
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/{CREATE_TOKEN_ACCOUNT,MINT_ACTION,TRANSFER2,CLAIM,CLOSE_TOKEN_ACCOUNT,DECOMPRESSED_TRANSFER,WITHDRAW_FUNDING_POOL}.md : Every instruction description must include sections: path, description, instruction_data, Accounts, instruction logic and checks, Errors
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/docs/ACCOUNTS.md : Accounts documentation must include: description, discriminator, state layout, serialization example, hashing (only for compressed accounts), derivation (only for PDAs), and associated instructions
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLAIM.md : Document rent reclamation from expired compressible accounts in instructions/CLAIM.md
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/docs/instructions/*.md : Each instruction doc must include: path, description, instruction_data (code paths), Accounts (order and checks), instruction logic and checks, and Errors (with causes)
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/**/ACCOUNTS.md : Provide complete account layouts and data structures in ACCOUNTS.md
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/DECOMPRESSED_TRANSFER.md : Document SPL-compatible transfers between decompressed accounts in instructions/DECOMPRESSED_TRANSFER.md
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Implement rent curve algorithms via rent_curve_per_epoch
Applied to files:
program-tests/compressed-token-test/tests/account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Expose claimable rent computation via claimable_lamports
Applied to files:
program-tests/compressed-token-test/tests/account.rsprogram-tests/compressed-token-test/tests/compressible.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/**/*.rs : Validate account type with 8-byte discriminators using check_discriminator before deserialization
Applied to files:
sdk-libs/compressed-token-sdk/tests/create_associated_token_account.rs
🧬 Code graph analysis (1)
program-tests/compressed-token-test/tests/compressible.rs (2)
program-tests/utils/src/spl.rs (1)
create_mint_helper(260-263)sdk-libs/program-test/src/utils/assert.rs (1)
assert_rpc_error(7-56)
🪛 LanguageTool
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
[grammar] ~76-~76: There might be a mistake here.
Context: ...is not exactly 1 epoch - Check: compressible_config.rent_payment != 1 - Error: `ErrorCode::OneEpochPrefundingNot...
(QB_NEW_EN)
[grammar] ~180-~180: There might be a mistake here.
Context: ...epoch (see create ctoken account errors)
(QB_NEW_EN)
🪛 markdownlint-cli2 (0.18.1)
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
112-112: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
180-180: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: stateless-js-v1
- GitHub Check: system-programs (sdk-anchor-test-program, ["cargo-test-sbf -p sdk-anchor-test", "cargo-test-sbf -...
- GitHub Check: system-programs (sdk-token-test-program, ["cargo-test-sbf -p sdk-token-test"])
- GitHub Check: system-programs (sdk-test-program, ["cargo-test-sbf -p sdk-native-test", "cargo-test-sbf -p sdk-v...
- GitHub Check: system-programs (sdk-libs, light-sdk-macros light-sdk light-program-test light-client light-compr...
- GitHub Check: stateless-js-v2
- GitHub Check: cli-v2
- GitHub Check: cli-v1
- GitHub Check: lint
- GitHub Check: Forester e2e test
🔇 Additional comments (8)
programs/compressed-token/program/src/create_associated_token_account.rs (1)
152-156: LGTM! Well-placed footgun prevention.The early validation correctly prevents exactly 1-epoch prefunding before account creation. The error message clearly explains the risk and provides alternative options.
As per coding guidelines (based on learnings).
programs/compressed-token/anchor/src/lib.rs (1)
415-416: LGTM! Clear error code definition.The error code is well-defined with a descriptive message that explains both the constraint and the rationale. The conversion to
ProgramError::Customfollows the established pattern.As per coding guidelines (based on learnings).
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md (3)
39-43: Good: Clear rent_payment policy documentedExplicitly forbidding 1 epoch and allowing 0 or 2+ is clear and matches the new validation intent.
As per coding guidelines
75-79: Good: Validation and error surfaced in logicThe check and error mapping are documented in the right place. Please also verify the numeric error code matches the program (6116).
Run a quick grep to confirm the compiled/custom error code value for OneEpochPrefundingNotAllowed matches 6116 in programs/compressed-token/anchor/src/lib.rs and any anchor-generated IDL. As per coding guidelines
16-18: Verify discriminatorsPlease confirm discriminator values (Create: 18; ATA: 103/101) reflect current program enum/dispatch.
As per coding guidelines
Also applies to: 117-119
program-tests/compressed-token-test/tests/account.rs (2)
403-403: LGTM: Bumped pre_pay_num_epochs to 2Matches the new “no 1-epoch” rule across tests.
Also applies to: 574-574, 827-827
845-858: LGTM: Epoch warp updates align with 2+1 top-up timelineAdvancing to epochs 1 and 3 matches the 2-prepaid + 1 top-up flow.
Also applies to: 880-884
program-tests/compressed-token-test/tests/compressible.rs (1)
84-86: Tests: unwraps are fine hereSwitching to unwrap() for success paths simplifies tests and is acceptable.
Also applies to: 198-201, 412-415, 501-503, 536-539, 619-622, 662-664, 769-771, 71-71, 331-331, 365-365, 399-399
| // Validate that rent_payment is not exactly 1 epoch (footgun prevention) | ||
| if compressible_config.rent_payment == 1 { | ||
| msg!("Prefunding for exactly 1 epoch is not allowed. If the account is created near an epoch boundary, it could become immediately compressible. Use 0 or 2+ epochs."); | ||
| return Err(anchor_compressed_token::ErrorCode::OneEpochPrefundingNotAllowed.into()); | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
❓ Verification inconclusive
LGTM! Consistent validation with ATA creation.
The validation correctly prevents exactly 1-epoch prefunding and mirrors the logic in create_associated_token_account.rs. The error message is clear and actionable.
Verify that test coverage exists for the new error path. From the provided files, I don't see explicit tests that attempt to create a compressible account with pre_pay_num_epochs: 1 and assert the OneEpochPrefundingNotAllowed error.
As per coding guidelines (based on learnings).
🏁 Script executed:
#!/bin/bash
# Search for tests that explicitly validate the OneEpochPrefundingNotAllowed error
rg -n -C3 'OneEpochPrefundingNotAllowed|6116' --type=rs -g '**/*test*.rs'Length of output: 26
🏁 Script executed:
#!/bin/bash
# Search for tests referencing the OneEpochPrefundingNotAllowed error code or its numeric value 6116
rg -n -C3 'OneEpochPrefundingNotAllowed|6116' -g '*test*.rs' -g 'tests/*.rs'Length of output: 0
Add missing tests for OneEpochPrefundingNotAllowed error
Add unit tests for both create_token_account and create_associated_token_account that set pre_pay_num_epochs (or rent_payment) to 1 and assert the OneEpochPrefundingNotAllowed error is returned.
🤖 Prompt for AI Agents
In programs/compressed-token/program/src/create_token_account.rs around lines
159-163, the code returns OneEpochPrefundingNotAllowed when rent_payment == 1
but there are no unit tests covering this; add two unit tests: one for
create_token_account and one for create_associated_token_account that set
pre_pay_num_epochs (or rent_payment) to 1 and assert the program returns
anchor_compressed_token::ErrorCode::OneEpochPrefundingNotAllowed. Each test
should build the minimum required accounts, call the respective instruction with
rent_payment/pre_pay_num_epochs = 1, capture the error result, and assert the
error matches OneEpochPrefundingNotAllowed (with proper conversion to Anchor
error type).
| name: programs | ||
| if: github.event.pull_request.draft == false | ||
| runs-on: warp-ubuntu-latest-x64-4x | ||
| timeout-minutes: 90 | ||
|
|
||
| services: | ||
| redis: | ||
| image: redis:8.0.1 | ||
| ports: | ||
| - 6379:6379 | ||
| options: >- | ||
| --health-cmd "redis-cli ping" | ||
| --health-interval 10s | ||
| --health-timeout 5s | ||
| --health-retries 5 | ||
|
|
||
| env: | ||
| REDIS_URL: redis://localhost:6379 | ||
|
|
||
| strategy: | ||
| matrix: | ||
| include: | ||
| - program: account-compression-and-registry | ||
| sub-tests: '["cargo-test-sbf -p account-compression-test", "cargo-test-sbf -p registry-test"]' | ||
| - program: light-system-program-address | ||
| sub-tests: '["cargo-test-sbf -p system-test -- test_with_address"]' | ||
| - program: light-system-program-compression | ||
| sub-tests: '["cargo-test-sbf -p system-test -- test_with_compression", "cargo-test-sbf -p system-test --test test_re_init_cpi_account"]' | ||
| - program: compressed-token-and-e2e | ||
| sub-tests: '["cargo-test-sbf -p compressed-token-test -- --skip test_transfer_with_photon_and_batched_tree", "cargo-test-sbf -p e2e-test"]' | ||
| - program: compressed-token-batched-tree | ||
| sub-tests: '["cargo-test-sbf -p compressed-token-test -- test_transfer_with_photon_and_batched_tree"]' | ||
| - program: system-cpi-test | ||
| sub-tests: | ||
| '["cargo-test-sbf -p system-cpi-test", "cargo test -p light-system-program-pinocchio", | ||
| "cargo-test-sbf -p system-cpi-v2-test -- --skip functional_ --skip event::parse", "cargo-test-sbf -p system-cpi-v2-test -- event::parse" | ||
| ]' | ||
| - program: system-cpi-test-v2-functional-read-only | ||
| sub-tests: '["cargo-test-sbf -p system-cpi-v2-test -- functional_read_only"]' | ||
| - program: system-cpi-test-v2-functional-account-infos | ||
| sub-tests: '["cargo-test-sbf -p system-cpi-v2-test -- functional_account_infos"]' | ||
| steps: | ||
| - name: Checkout sources | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Setup and build | ||
| uses: ./.github/actions/setup-and-build | ||
| with: | ||
| skip-components: "redis,disk-cleanup" | ||
| cache-suffix: "system-programs" | ||
|
|
||
| - name: Build CLI | ||
| run: | | ||
| npx nx build @lightprotocol/zk-compression-cli | ||
|
|
||
| - name: ${{ matrix.program }} | ||
| run: | | ||
|
|
||
| IFS=',' read -r -a sub_tests <<< "${{ join(fromJSON(matrix['sub-tests']), ', ') }}" | ||
| for subtest in "${sub_tests[@]}" | ||
| do | ||
| echo "$subtest" | ||
|
|
||
| # Retry logic for flaky batched-tree test | ||
| if [[ "$subtest" == *"test_transfer_with_photon_and_batched_tree"* ]]; then | ||
| echo "Running flaky test with retry logic (max 3 attempts)..." | ||
| attempt=1 | ||
| max_attempts=3 | ||
| until RUSTFLAGS="-D warnings" eval "$subtest"; do | ||
| attempt=$((attempt + 1)) | ||
| if [ $attempt -gt $max_attempts ]; then | ||
| echo "Test failed after $max_attempts attempts" | ||
| exit 1 | ||
| fi | ||
| echo "Attempt $attempt/$max_attempts failed, retrying..." | ||
| sleep 5 | ||
| done | ||
| echo "Test passed on attempt $attempt" | ||
| else | ||
| RUSTFLAGS="-D warnings" eval "$subtest" | ||
| if [ "$subtest" == "cargo-test-sbf -p e2e-test" ]; then | ||
| pnpm --filter @lightprotocol/programs run build-compressed-token-small | ||
| RUSTFLAGS="-D warnings" eval "$subtest -- --test test_10_all" | ||
| fi | ||
| fi | ||
| done |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 months ago
To fix this problem, explicitly set the permissions key for the workflow. Since none of the workflow steps write to the repo or interact with issues or PRs, the safest minimum is contents: read. This should be added at the root of the workflow YAML (before jobs:), to apply to all jobs unless overridden.
You should add:
permissions:
contents: readdirectly after the name: programs key (line 27).
| @@ -25,6 +25,9 @@ | ||
|
|
||
| name: programs | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.ref }} | ||
| cancel-in-progress: true |
There was a problem hiding this comment.
Actionable comments posted: 11
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
program-tests/utils/src/assert_create_token_account.rs (1)
75-116: Idempotent mode check happens too late; skip deep equality before itYou assert full CToken equality (Line 110) and lamports (Lines 57-74) before detecting idempotent mode (Lines 112-116). If the account already existed, fields like last_claimed_slot or prepaid layout may differ, causing false failures. Guard and early-return before deep checks.
Apply this diff to insert an early idempotent branch and remove the late one:
@@ - // Calculate expected lamports balance - let rent_exemption = rpc - .get_minimum_balance_for_rent_exemption(COMPRESSIBLE_TOKEN_ACCOUNT_SIZE as usize) - .await - .expect("Failed to get rent exemption"); - - let rent_with_compression = RentConfig::default().get_rent_with_compression_cost( - COMPRESSIBLE_TOKEN_ACCOUNT_SIZE, - compressible_info.num_prepaid_epochs, - ); - let expected_lamports = rent_exemption + rent_with_compression; - - assert_eq!( - account_info.lamports, expected_lamports, - "Account should have rent-exempt balance ({}) plus prepaid rent with compression cost ({}) = {} lamports, but has {}", - rent_exemption, rent_with_compression, expected_lamports, account_info.lamports - ); + // Check if account existed before transaction (for idempotent mode) + let account_existed_before = rpc + .get_pre_transaction_account(&token_account_pubkey) + .is_some(); + + // Transaction fee: 5000 lamports per signature + // For ATA: 1 signer (payer only), else: 2 signers (token_account_keypair + payer) + let tx_fee = if is_ata { 5_000 } else { 10_000 }; + + // Assert payer and rent sponsor balance changes + let payer_balance_before = rpc + .get_pre_transaction_account(&compressible_info.payer) + .expect("Payer should exist in pre-transaction context") + .lamports; + let payer_balance_after = rpc + .get_account(compressible_info.payer) + .await + .expect("Failed to get payer account") + .expect("Payer should exist") + .lamports; + + if account_existed_before { + // In idempotent mode, account already existed, so only tx fee is paid + assert_eq!( + payer_balance_before - payer_balance_after, + tx_fee, + "In idempotent mode (account already existed), payer should only pay tx fee ({} lamports), but paid {}", + tx_fee, + payer_balance_before - payer_balance_after + ); + return; + } + + // Calculate expected lamports balance (non-idempotent path) + let rent_exemption = rpc + .get_minimum_balance_for_rent_exemption(COMPRESSIBLE_TOKEN_ACCOUNT_SIZE as usize) + .await + .expect("Failed to get rent exemption"); + let rent_with_compression = RentConfig::default().get_rent_with_compression_cost( + COMPRESSIBLE_TOKEN_ACCOUNT_SIZE, + compressible_info.num_prepaid_epochs, + ); + let expected_lamports = rent_exemption + rent_with_compression; + assert_eq!( + account_info.lamports, expected_lamports, + "Account should have rent-exempt balance ({}) plus prepaid rent with compression cost ({}) = {} lamports, but has {}", + rent_exemption, rent_with_compression, expected_lamports, account_info.lamports + ); @@ - assert_eq!(actual_token_account, expected_token_account); - - // Check if account existed before transaction (for idempotent mode) - let account_existed_before = rpc - .get_pre_transaction_account(&token_account_pubkey) - .is_some(); - - // Assert payer and rent sponsor balance changes - let payer_balance_before = rpc - .get_pre_transaction_account(&compressible_info.payer) - .expect("Payer should exist in pre-transaction context") - .lamports; - let payer_balance_after = rpc - .get_account(compressible_info.payer) - .await - .expect("Failed to get payer account") - .expect("Payer should exist") - .lamports; - let rent_sponsor_balance_before = rpc - .get_pre_transaction_account(&compressible_info.rent_sponsor) - .expect("Rent sponsor should exist in pre-transaction context") - .lamports; - let rent_sponsor_balance_after = rpc - .get_account(compressible_info.rent_sponsor) - .await - .expect("Failed to get rent sponsor account") - .expect("Rent sponsor should exist") - .lamports; - // Transaction fee: 5000 lamports per signature - // For ATA: 1 signer (payer only) = 5,000 lamports - // For regular token account: 2 signers (token_account_keypair + payer) = 10,000 lamports - let tx_fee = if is_ata { 5_000 } else { 10_000 }; + assert_eq!(actual_token_account, expected_token_account); + + // Balances (non-idempotent path) + let rent_sponsor_balance_before = rpc + .get_pre_transaction_account(&compressible_info.rent_sponsor) + .expect("Rent sponsor should exist in pre-transaction context") + .lamports; + let rent_sponsor_balance_after = rpc + .get_account(compressible_info.rent_sponsor) + .await + .expect("Failed to get rent sponsor account") + .expect("Rent sponsor should exist") + .lamports; @@ - // If account existed before (idempotent mode), only tx fee is charged - if account_existed_before { - // In idempotent mode, account already existed, so only tx fee is paid - assert_eq!( - payer_balance_before - payer_balance_after, - tx_fee, - "In idempotent mode (account already existed), payer should only pay tx fee ({} lamports), but paid {}", - tx_fee, - payer_balance_before - payer_balance_after - ); - return; - } + // Non-idempotent path continues…
♻️ Duplicate comments (2)
programs/compressed-token/program/src/transfer2/compression/ctoken/compress_or_decompress_ctokens.rs (1)
130-130: Extract magic number into a shared constant.This is the same hardcoded value
2700480that appears inctoken_transfer.rs:81andassert_ctoken_transfer.rs:109. Consolidate this into a shared constant to improve maintainability.See the comment on
programs/compressed-token/program/src/ctoken_transfer.rs:81for the suggested refactor.program-tests/utils/src/assert_ctoken_transfer.rs (1)
109-109: Extract magic number into a shared constant.This hardcoded value
2700480is duplicated acrossctoken_transfer.rs:81,compress_or_decompress_ctokens.rs:130, and here. Consolidate into a shared constant.See the comment on
programs/compressed-token/program/src/ctoken_transfer.rs:81for the suggested refactor.
🧹 Nitpick comments (17)
sdk-libs/program-test/src/utils/assert.rs (1)
89-131: Duplicate mapping logic; extract and reuse a single helperThe BanksClientError path repeats the same large match. Use a shared helper (see above) for both branches to reduce drift and maintenance.
.github/workflows/programs.yml (3)
35-37: Guard skips pushes; allow push runs tooOn push events, github.event.pull_request is null, so the job always skips. Make the guard PR-only or allow pushes:
- if: github.event.pull_request.draft == false + if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
26-31: Add least-privilege GITHUB_TOKEN permissionsSet explicit permissions as recommended.
name: programs + +permissions: + contents: read
41-49: Pin Redis Docker image to a digest
redis:8.0.1 exists, but pinning to its digest ensures immutable, reproducible builds.program-tests/compressed-token-test/Cargo.toml (1)
52-52: Scope features to what tests actually needIf “mut” or “derive” isn’t used in this crate’s tests, drop it to speed builds.
programs/compressed-token/program/docs/instructions/TRANSFER2.md (2)
5-14: Avoid line-number navigation; use anchors onlyLine numbers rot quickly. Replace “(line …)” with in-doc anchors.
289-314: Stabilize error referencesNumeric codes for Solana built-ins can drift across versions. Prefer symbolic names (e.g., ProgramError::ArithmeticOverflow) or note the Solana version these map to.
As per coding guidelines
program-tests/utils/src/assert_close_token_account.rs (1)
155-159: Consider extracting transaction fee into a test constant.The hardcoded
tx_fee = 10_000value is used throughout the assertions. While the comment explains the calculation (5000 lamports per signature × 2 signers), consider extracting this into a named constant for clarity and reusability across test utilities.// At module level or in a shared test constants module const TX_FEE_TWO_SIGNERS: u64 = 10_000; // 5000 lamports per signature * 2 signersThen use:
- // Transaction fee: 5000 lamports per signature * 2 signers = 10,000 lamports - let tx_fee = 10_000; + // Transaction fee: 5000 lamports per signature * 2 signers + let tx_fee = TX_FEE_TWO_SIGNERS;program-tests/compressed-token-test/tests/ctoken/close.rs (1)
105-107: Replace magic error numbers with named constants and fix mismatched commentsTests use raw integers (e.g., 75, 4, 11, 74, 76) while comments reference 607x variants. This is brittle and confusing. Centralize with named constants (or derive from program errors) and keep comments aligned with the actual assertion semantics.
Example at Lines 165–216 and 272–323: comments say 6074/6076 but assertions pass 74/76. Unify by:
- Using a helper to assert by error variant, or
- Defining constants that reflect your assert mapping (e.g., ANCHOR_BASE + variant), or
- Referencing the SDK/util’s exported mapping if available.
This avoids silent drift when codes change and improves readability.
Also applies to: 118-119, 138-139, 160-161, 213-214, 267-268, 320-321
program-tests/compressed-token-test/tests/ctoken/functional_ata.rs (1)
177-181: Assert specific error code instead of just is_err()Make the failure deterministic by asserting the expected error code (e.g., IllegalOwner or the mapped InstructionError) using your assert helper, not just is_err().
Example:
- assert!( - result.is_err(), - "Non-idempotent ATA creation should fail when account already exists" - ); + light_program_test::utils::assert::assert_rpc_error(result, 0, /* expected */ 29).unwrap();program-tests/compressed-token-test/tests/ctoken/create_ata.rs (1)
218-219: Replace magic error numbers with named constants or helper mappingUse named constants (or a single source of truth from the program/SDK) for error codes instead of raw integers (101, 29, 1, 2, 21/19, 20001, 20000). This makes tests resilient to code shifts and easier to read. If your assert helper supports variant-based matching, prefer that.
Also applies to: 255-256, 297-299, 363-365, 431-434, 473-474, 509-510
program-tests/utils/src/assert_create_token_account.rs (2)
95-105: Avoid hard-coding config_account_version = 1 in expected extensionConfig version can change across environments. Either (a) fetch and assert against the actual extension’s config_account_version, or (b) compare fields selectively instead of full struct equality to reduce brittleness.
142-146: Hard-coded fee (5_000/signature) risks brittlenessPrefer deriving the fee from the test harness (e.g., a helper or rpc/context-provided constant) to avoid coupling to a magic number.
program-tests/compressed-token-test/tests/ctoken/shared.rs (4)
214-268: Avoid manual discriminator (18) when initializing non-compressible accountsBuilding the instruction by hand with a magic discriminator is fragile. Prefer the SDK helper (create_token_account) or a typed constructor from light_ctoken_types to construct the instruction and required accounts.
570-576: Make warp_to_slot relative to current slotUsing absolute SLOTS_PER_EPOCH * epochs can move time backwards or not far enough depending on current slot. Derive from current slot.
- context - .rpc - .warp_to_slot((SLOTS_PER_EPOCH * epochs) + 1) - .unwrap(); + let current = context.rpc.get_slot().await.unwrap_or(0); + context + .rpc + .warp_to_slot(current + (SLOTS_PER_EPOCH * epochs)) + .unwrap();
680-710: Optional: compute is_compressible instead of hard-coding trueFor negative-path tests, deriving is_compressible from the account avoids false positives if called with a non-compressible account.
784-787: Compute current_epoch dynamicallyAvoid hard-coding 0; derive from slot for correctness across runs.
- let current_epoch = 0; + let current_epoch = context.rpc.get_slot().await.unwrap_or(0) / SLOTS_PER_EPOCH;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (33)
.github/workflows/programs.yml(1 hunks)Cargo.toml(1 hunks)program-libs/compressible/tests/compression_info.rs(1 hunks)program-libs/compressible/tests/rent.rs(1 hunks)program-tests/compressed-token-test/Cargo.toml(1 hunks)program-tests/compressed-token-test/tests/account.rs(0 hunks)program-tests/compressed-token-test/tests/ctoken.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/close.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/compress_and_close.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/create.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/create_ata.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/functional.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/functional_ata.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/shared.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/transfer.rs(1 hunks)program-tests/compressed-token-test/tests/transfer2/mod.rs(1 hunks)program-tests/compressed-token-test/tests/transfer2/spl_ctoken.rs(1 hunks)program-tests/registry-test/Cargo.toml(1 hunks)program-tests/registry-test/tests/compressible.rs(28 hunks)program-tests/utils/src/assert_close_token_account.rs(5 hunks)program-tests/utils/src/assert_create_token_account.rs(4 hunks)program-tests/utils/src/assert_ctoken_transfer.rs(1 hunks)program-tests/utils/src/assert_transfer2.rs(2 hunks)programs/compressed-token/program/docs/instructions/CTOKEN_TRANSFER.md(1 hunks)programs/compressed-token/program/docs/instructions/TRANSFER2.md(1 hunks)programs/compressed-token/program/src/ctoken_transfer.rs(3 hunks)programs/compressed-token/program/src/shared/initialize_ctoken_account.rs(1 hunks)programs/compressed-token/program/src/transfer2/compression/ctoken/compress_and_close.rs(1 hunks)programs/compressed-token/program/src/transfer2/compression/ctoken/compress_or_decompress_ctokens.rs(1 hunks)sdk-libs/program-test/src/compressible.rs(1 hunks)sdk-libs/program-test/src/utils/assert.rs(1 hunks)sdk-libs/token-client/src/actions/ctoken_transfer.rs(1 hunks)sdk-libs/token-client/src/instructions/transfer2.rs(3 hunks)
💤 Files with no reviewable changes (1)
- program-tests/compressed-token-test/tests/account.rs
✅ Files skipped from review due to trivial changes (2)
- sdk-libs/program-test/src/compressible.rs
- program-libs/compressible/tests/compression_info.rs
🧰 Additional context used
📓 Path-based instructions (5)
programs/compressed-token/program/src/transfer2/**
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Transfer2 must support Compress, Decompress, and CompressAndClose modes and perform multi-mint sum checks
Files:
programs/compressed-token/program/src/transfer2/compression/ctoken/compress_and_close.rsprograms/compressed-token/program/src/transfer2/compression/ctoken/compress_or_decompress_ctokens.rs
programs/compressed-token/program/src/**/*.rs
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Return errors as ProgramError::Custom(error_code as u32) on-chain
Files:
programs/compressed-token/program/src/transfer2/compression/ctoken/compress_and_close.rsprograms/compressed-token/program/src/ctoken_transfer.rsprograms/compressed-token/program/src/shared/initialize_ctoken_account.rsprograms/compressed-token/program/src/transfer2/compression/ctoken/compress_or_decompress_ctokens.rs
programs/compressed-token/program/src/ctoken_transfer.rs
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
CTokenTransfer must perform SPL-compatible transfers between decompressed accounts
Files:
programs/compressed-token/program/src/ctoken_transfer.rs
programs/compressed-token/program/docs/instructions/*.md
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Each instruction doc must include: path, description, instruction_data (code paths), Accounts (order and checks), instruction logic and checks, and Errors (with causes)
Files:
programs/compressed-token/program/docs/instructions/TRANSFER2.mdprograms/compressed-token/program/docs/instructions/CTOKEN_TRANSFER.md
programs/compressed-token/program/docs/**/instructions/**/*.md
📄 CodeRabbit inference engine (programs/compressed-token/program/docs/CLAUDE.md)
Keep detailed instruction documentation files under the instructions/ directory; add additional instruction docs as needed
Files:
programs/compressed-token/program/docs/instructions/TRANSFER2.mdprograms/compressed-token/program/docs/instructions/CTOKEN_TRANSFER.md
🧠 Learnings (29)
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/close_token_account{.rs,/**} : On closing ctoken accounts: if compressible, return rent exemption to the rent recipient; send remaining lamports to the destination
Applied to files:
programs/compressed-token/program/src/transfer2/compression/ctoken/compress_and_close.rsprograms/compressed-token/program/src/ctoken_transfer.rsprogram-tests/utils/src/assert_ctoken_transfer.rsprograms/compressed-token/program/src/transfer2/compression/ctoken/compress_or_decompress_ctokens.rsprograms/compressed-token/program/docs/instructions/TRANSFER2.mdsdk-libs/token-client/src/instructions/transfer2.rsprogram-tests/utils/src/assert_transfer2.rsprogram-tests/compressed-token-test/tests/ctoken/functional.rsprogram-tests/utils/src/assert_close_token_account.rsprogram-tests/compressed-token-test/tests/ctoken/compress_and_close.rsprogram-tests/compressed-token-test/tests/ctoken/close.rsprogram-tests/utils/src/assert_create_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/{create_token_account.rs,create_associated_token_account.rs} : Enforce ACTIVE-only config validation for Create CToken Account and Create Associated CToken Account instructions
Applied to files:
programs/compressed-token/program/src/transfer2/compression/ctoken/compress_and_close.rsprograms/compressed-token/program/src/shared/initialize_ctoken_account.rsprogram-tests/compressed-token-test/tests/ctoken/create.rsprogram-tests/utils/src/assert_create_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/ctoken_transfer.rs : CTokenTransfer must perform SPL-compatible transfers between decompressed accounts
Applied to files:
programs/compressed-token/program/src/transfer2/compression/ctoken/compress_and_close.rsprograms/compressed-token/program/src/ctoken_transfer.rsprogram-tests/utils/src/assert_ctoken_transfer.rsprograms/compressed-token/program/src/transfer2/compression/ctoken/compress_or_decompress_ctokens.rssdk-libs/token-client/src/actions/ctoken_transfer.rssdk-libs/token-client/src/instructions/transfer2.rsprogram-tests/utils/src/assert_transfer2.rsprogram-tests/compressed-token-test/tests/ctoken/functional.rsprogram-tests/compressed-token-test/tests/transfer2/mod.rsprogram-tests/compressed-token-test/tests/ctoken/transfer.rsprogram-tests/compressed-token-test/tests/transfer2/spl_ctoken.rsprogram-tests/utils/src/assert_create_token_account.rsprograms/compressed-token/program/docs/instructions/CTOKEN_TRANSFER.md
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/transfer2/native_compression/** : For Compress & Close via registry paths, enforce Not Inactive config validation
Applied to files:
programs/compressed-token/program/src/transfer2/compression/ctoken/compress_and_close.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Expose claimable rent computation via claimable_lamports
Applied to files:
program-tests/utils/src/assert_ctoken_transfer.rsprogram-libs/compressible/tests/rent.rsprogram-tests/utils/src/assert_close_token_account.rsprogram-tests/registry-test/tests/compressible.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/**/*.rs : On account initialization, call account_info_init to set the 8-byte discriminator
Applied to files:
programs/compressed-token/program/src/shared/initialize_ctoken_account.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Document closing decompressed token accounts with rent distribution in instructions/CLOSE_TOKEN_ACCOUNT.md
Applied to files:
programs/compressed-token/program/docs/instructions/TRANSFER2.mdprogram-tests/compressed-token-test/tests/ctoken/compress_and_close.rsprogram-tests/compressed-token-test/tests/ctoken/close.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/TRANSFER2.md : Document the batch transfer instruction supporting compressed/decompressed operations in instructions/TRANSFER2.md
Applied to files:
programs/compressed-token/program/docs/instructions/TRANSFER2.mdprograms/compressed-token/program/docs/instructions/CTOKEN_TRANSFER.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/DECOMPRESSED_TRANSFER.md : Document SPL-compatible transfers between decompressed accounts in instructions/DECOMPRESSED_TRANSFER.md
Applied to files:
programs/compressed-token/program/docs/instructions/TRANSFER2.mdsdk-libs/token-client/src/instructions/transfer2.rsprogram-tests/compressed-token-test/tests/transfer2/spl_ctoken.rsprograms/compressed-token/program/docs/instructions/CTOKEN_TRANSFER.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLAIM.md : Document rent reclamation from expired compressible accounts in instructions/CLAIM.md
Applied to files:
programs/compressed-token/program/docs/instructions/TRANSFER2.md
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/transfer2/** : Transfer2 must support Compress, Decompress, and CompressAndClose modes and perform multi-mint sum checks
Applied to files:
programs/compressed-token/program/docs/instructions/TRANSFER2.mdsdk-libs/token-client/src/instructions/transfer2.rsprogram-tests/utils/src/assert_transfer2.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Refactor rent logic so that 1 lamport is the minimum rent payment
Applied to files:
program-libs/compressible/tests/rent.rsprogram-tests/utils/src/assert_close_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Determine compressibility and compute rent using calculate_rent_and_balance
Applied to files:
program-libs/compressible/tests/rent.rssdk-libs/token-client/src/instructions/transfer2.rsprogram-tests/utils/src/assert_close_token_account.rsprogram-tests/utils/src/assert_create_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Update RentConfig values at claim time to reflect current policy
Applied to files:
program-libs/compressible/tests/rent.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Compute close lamport distribution with calculate_close_lamports
Applied to files:
program-libs/compressible/tests/rent.rsprogram-tests/utils/src/assert_close_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Implement rent curve algorithms via rent_curve_per_epoch
Applied to files:
program-libs/compressible/tests/rent.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/docs/RENT.md : Document rent calculation functions and compressibility checks in docs/RENT.md
Applied to files:
program-libs/compressible/tests/rent.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/config.rs : Update config parameters including max write fee and max funded epoch
Applied to files:
program-libs/compressible/tests/rent.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: CToken account layout matches SPL token accounts with a custom Compressible extension; compressed mint accounts support the TokenMetadata extension
Applied to files:
sdk-libs/token-client/src/instructions/transfer2.rsprogram-tests/utils/src/assert_transfer2.rsprogram-tests/compressed-token-test/tests/ctoken/functional.rs
📚 Learning: 2025-10-15T03:46:26.758Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.758Z
Learning: Applies to programs/registry/src/account_compression_cpi/mod.rs : Export each new operation module by adding pub mod <operation>; and re-export with pub use <operation>::*.
Applied to files:
program-tests/compressed-token-test/tests/ctoken.rsprogram-tests/compressed-token-test/tests/transfer2/mod.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/error.rs : Maintain stable mapping of AccountError to ProgramError, including Pinocchio code mapping (1–11), in error.rs
Applied to files:
sdk-libs/program-test/src/utils/assert.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/**/*.rs : Return errors as ProgramError::Custom(error_code as u32) on-chain
Applied to files:
sdk-libs/program-test/src/utils/assert.rs
📚 Learning: 2025-10-15T03:45:40.029Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.029Z
Learning: Applies to programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md : Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions
Applied to files:
program-tests/compressed-token-test/tests/ctoken/create.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CREATE_TOKEN_ACCOUNT.md : Document Create Token Account & Associated Token Account instructions in instructions/CREATE_TOKEN_ACCOUNT.md
Applied to files:
program-tests/compressed-token-test/tests/ctoken/create.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/config.rs : Implement CompressibleConfig account with Anchor, Borsh, and Pod serialization for Light Registry integration
Applied to files:
program-tests/registry-test/tests/compressible.rsprogram-tests/utils/src/assert_create_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/programs/compressed-token/anchor/src/lib.rs : Define all program-specific error codes in anchor_compressed_token::ErrorCode and expose them for program-wide use
Applied to files:
program-tests/registry-test/tests/compressible.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/program-libs/ctoken-types/{state/**,instructions/**,state/extensions/**} : Define all state and instruction data structures (including extensions like Compressible and TokenMetadata) in the light-ctoken-types crate
Applied to files:
program-tests/utils/src/assert_create_token_account.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Gate SDK-specific implementations with #[cfg(feature = "solana"|"pinocchio"|"test-only")]
Applied to files:
program-tests/utils/src/assert_create_token_account.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/{CREATE_TOKEN_ACCOUNT,MINT_ACTION,TRANSFER2,CLAIM,CLOSE_TOKEN_ACCOUNT,DECOMPRESSED_TRANSFER,WITHDRAW_FUNDING_POOL}.md : Every instruction description must include sections: path, description, instruction_data, Accounts, instruction logic and checks, Errors
Applied to files:
programs/compressed-token/program/docs/instructions/CTOKEN_TRANSFER.md
🧬 Code graph analysis (11)
program-tests/compressed-token-test/tests/ctoken/functional_ata.rs (3)
program-tests/utils/src/assert_create_token_account.rs (2)
assert_create_token_account(236-252)assert_create_associated_token_account(258-291)program-tests/compressed-token-test/tests/ctoken/shared.rs (1)
setup_account_test(40-63)program-tests/utils/src/assert_close_token_account.rs (1)
assert_close_token_account(8-106)
program-tests/compressed-token-test/tests/ctoken/functional.rs (4)
program-tests/compressed-token-test/tests/ctoken/shared.rs (2)
setup_account_test(40-63)setup_destination_account(66-80)program-tests/utils/src/assert_create_token_account.rs (1)
assert_create_token_account(236-252)program-tests/utils/src/assert_close_token_account.rs (1)
assert_close_token_account(8-106)program-tests/utils/src/assert_transfer2.rs (1)
assert_transfer2_compress(576-590)
sdk-libs/program-test/src/utils/assert.rs (1)
js/stateless.js/src/errors.ts (1)
RpcError(79-79)
program-tests/compressed-token-test/tests/ctoken/shared.rs (6)
program-tests/utils/src/assert_close_token_account.rs (1)
assert_close_token_account(8-106)program-tests/utils/src/assert_create_token_account.rs (2)
assert_create_token_account(236-252)assert_create_associated_token_account(258-291)sdk-libs/program-test/src/compressible.rs (1)
new(44-64)sdk-libs/program-test/src/utils/assert.rs (1)
assert_rpc_error(7-144)sdk-libs/token-client/src/instructions/transfer2.rs (1)
create_generic_transfer2_instruction(145-640)js/stateless.js/src/utils/instruction.ts (1)
PackedAccounts(5-99)
program-tests/compressed-token-test/tests/ctoken/create_ata.rs (3)
program-tests/compressed-token-test/tests/ctoken/shared.rs (3)
setup_account_test(40-63)create_and_assert_ata(400-461)create_and_assert_ata_fails(464-514)sdk-libs/program-test/src/compressible.rs (1)
new(44-64)program-tests/utils/src/assert_create_token_account.rs (1)
assert_create_associated_token_account(258-291)
program-tests/compressed-token-test/tests/ctoken/compress_and_close.rs (2)
program-tests/compressed-token-test/tests/ctoken/shared.rs (7)
setup_compress_and_close_test(530-579)compress_and_close_owner_and_assert(587-662)setup_account_test(40-63)create_non_compressible_token_account(210-278)create_and_assert_ata(400-461)compress_and_close_and_assert_fails(672-729)compress_and_close_forester_with_invalid_output(750-902)program-tests/utils/src/assert_transfer2.rs (2)
assert_transfer2(550-552)assert_transfer2_compress_and_close(594-628)
program-tests/compressed-token-test/tests/ctoken/close.rs (1)
program-tests/compressed-token-test/tests/ctoken/shared.rs (4)
setup_account_test_with_created_account(178-207)close_and_assert_token_account(281-353)close_and_assert_token_account_fails(356-396)create_and_assert_token_account(82-127)
program-tests/compressed-token-test/tests/ctoken/create.rs (2)
program-tests/compressed-token-test/tests/ctoken/shared.rs (3)
setup_account_test(40-63)create_and_assert_token_account(82-127)create_and_assert_token_account_fails(130-172)sdk-libs/program-test/src/utils/assert.rs (1)
assert_rpc_error(7-144)
program-tests/compressed-token-test/tests/ctoken/transfer.rs (3)
program-tests/compressed-token-test/tests/ctoken/shared.rs (3)
setup_account_test(40-63)create_and_assert_token_account(82-127)create_non_compressible_token_account(210-278)program-tests/utils/src/assert_ctoken_transfer.rs (1)
assert_ctoken_transfer(150-201)sdk-libs/program-test/src/utils/assert.rs (1)
assert_rpc_error(7-144)
program-tests/registry-test/tests/compressible.rs (2)
program-tests/utils/src/spl.rs (1)
create_mint_helper(260-263)sdk-libs/program-test/src/utils/assert.rs (1)
assert_rpc_error(7-144)
program-tests/compressed-token-test/tests/transfer2/spl_ctoken.rs (2)
program-tests/utils/src/spl.rs (3)
create_mint_helper(260-263)create_token_2022_account(435-488)mint_spl_tokens(69-105)js/stateless.js/src/errors.ts (1)
RpcError(79-79)
🪛 GitHub Actions: Lint GitHub Actions workflows
.github/workflows/programs.yml
[error] 83-83: Input 'cache-suffix' is not defined for action "Setup and build". Available inputs are "cache-key", "skip-components". The workflow failed with exit code 1.
🪛 GitHub Check: CodeQL
.github/workflows/programs.yml
[warning] 34-119: Workflow does not contain permissions
Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {{contents: read}}
🪛 LanguageTool
programs/compressed-token/program/docs/instructions/CTOKEN_TRANSFER.md
[grammar] ~21-~21: There might be a mistake here.
Context: ...riminator (3) - Second byte: 0 (padding) - Remaining bytes: SPL TokenInstruction::T...
(QB_NEW_EN)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (19)
- GitHub Check: cli-v2
- GitHub Check: system-programs (sdk-libs, light-sdk-macros light-sdk light-program-test light-client light-compr...
- GitHub Check: system-programs (sdk-test-program, ["cargo-test-sbf -p sdk-native-test", "cargo-test-sbf -p sdk-v...
- GitHub Check: system-programs (sdk-token-test-program, ["cargo-test-sbf -p sdk-token-test"])
- GitHub Check: system-programs (sdk-anchor-test-program, ["cargo-test-sbf -p sdk-anchor-test", "cargo-test-sbf -...
- GitHub Check: programs (system-cpi-test-v2-functional-account-infos, ["cargo-test-sbf -p system-cpi-v2-test -- ...
- GitHub Check: lint
- GitHub Check: programs (light-system-program-compression, ["cargo-test-sbf -p system-test -- test_with_compress...
- GitHub Check: programs (system-cpi-test-v2-functional-read-only, ["cargo-test-sbf -p system-cpi-v2-test -- func...
- GitHub Check: programs (light-system-program-address, ["cargo-test-sbf -p system-test -- test_with_address"])
- GitHub Check: programs (compressed-token-batched-tree, ["cargo-test-sbf -p compressed-token-test -- test_transf...
- GitHub Check: Test batched-merkle-tree-simulate
- GitHub Check: Test program-libs-slow
- GitHub Check: programs (compressed-token-and-e2e, ["cargo-test-sbf -p compressed-token-test -- --skip test_tran...
- GitHub Check: Forester e2e test
- GitHub Check: cli-v1
- GitHub Check: stateless-js-v2
- GitHub Check: Test program-libs-fast
- GitHub Check: stateless-js-v1
🔇 Additional comments (12)
programs/compressed-token/program/docs/instructions/CTOKEN_TRANSFER.md (1)
21-21: LGTM! Documentation accurately reflects the instruction data format change.The update from "SPL Token Transfer instruction discriminator (3)" to "0 (padding)" correctly documents the new instruction data layout, which aligns with the implementation changes in
sdk-libs/token-client/src/actions/ctoken_transfer.rs.program-tests/compressed-token-test/tests/transfer2/mod.rs (1)
7-7: LGTM! New test module added.The addition of the
spl_ctokenmodule expands test coverage for cross-token transfer scenarios.programs/compressed-token/program/src/transfer2/compression/ctoken/compress_and_close.rs (1)
76-81: LGTM! Appropriate validation for compress-and-close operations.The validation correctly prevents compress-and-close operations on accounts with delegates, since compressed tokens don't support delegation. The error message and error code (
CompressAndCloseDelegateNotAllowed) clearly communicate the constraint.sdk-libs/token-client/src/actions/ctoken_transfer.rs (1)
71-71: LGTM! Instruction data format updated to use padding byte.The change from the SPL transfer discriminator (3) to padding (0) aligns with the documented instruction format in
CTOKEN_TRANSFER.mdand the on-chain implementation.program-tests/utils/src/assert_ctoken_transfer.rs (2)
107-107: LGTM! Correct parameter for calculating expected top-up.The change from
lamports_aftertolamports_beforeis correct. The function should calculate what the top-up should be based on the pre-transaction state, then verify that the post-transaction state matches expectations.
113-127: LGTM! Improved clarity in top-up verification logic.The rewritten logic explicitly handles both cases (top-up applied vs. no top-up needed) with clear assertions and error messages, making test failures easier to diagnose.
program-tests/utils/src/assert_close_token_account.rs (1)
89-104: LGTM! Transaction fee handling improves test accuracy.The additions correctly account for transaction fees in lamport distribution assertions, distinguishing between cases where:
- Authority is/isn't the destination
- Payer is/isn't involved in rent recipient or authority payments
- Rent authority is/isn't the signer
This makes the test assertions more robust and accurate.
Also applies to: 247-338
program-tests/compressed-token-test/tests/ctoken/functional.rs (1)
35-39: Verify the extra padding byte on initialize accountPushing an extra 0 byte onto the initialize-account instruction data seems unrelated to the documented CTOKEN_TRANSFER padding change. Please confirm this is required for the init path; otherwise drop it or add a clarifying comment with a reference.
program-tests/compressed-token-test/tests/ctoken.rs (1)
4-27: Module wiring LGTMSubmodule paths are clear and correctly scoped.
program-tests/utils/src/assert_create_token_account.rs (2)
234-252: Wrapper refactor LGTMPublic wrappers delegating to the internal impl (with is_ata flag) simplify call sites and match the new API.
268-291: ATA assertion helper LGTMDeriving the ATA and asserting existence before delegating is clean and explicit.
program-tests/compressed-token-test/tests/ctoken/shared.rs (1)
398-461: ATA helpers LGTMCreation and assertion (including idempotent path) are clear and match the updated API.
| // Test 2: Account already initialized (non-idempotent) | ||
| // Creating the same ATA twice with non-idempotent mode should fail. | ||
| // Error: 18 (IllegalOwner - account is no longer owned by system program) | ||
| { | ||
| // Use a different mint for this test | ||
| context.mint_pubkey = solana_sdk::pubkey::Pubkey::new_unique(); | ||
|
|
||
| let compressible_data = CompressibleData { | ||
| compression_authority: context.compression_authority, |
There was a problem hiding this comment.
Fix comment/code mismatch for IllegalOwner
Comment says “Error: 18 (IllegalOwner)”, but assertion uses 29. Align the expected code or the comment to avoid confusion.
Also applies to: 255-256
🤖 Prompt for AI Agents
In program-tests/compressed-token-test/tests/ctoken/create_ata.rs around lines
223-231 (and similarly at lines 255-256), the inline comment states the expected
error is 18 (IllegalOwner) but the test assertion checks for error code 29;
update either the comment or the assertion so they match: change the comment to
reflect error 29 if that is the correct expected error, or change the asserted
error code to 18 if IllegalOwner is the intended expectation; ensure both
occurrences (223-231 and 255-256) are updated consistently.
| /// Test: | ||
| /// 1. SUCCESS: Create system account with compressible token size | ||
| /// 2. SUCCESS: Initialize compressible token account with rent authority and recipient | ||
| /// 3. SUCCESS: Verify compressible account structure using existing assertion helper | ||
| /// 4. SUCCESS: Close account using rent authority | ||
| /// 5. SUCCESS: Verify lamports transferred to rent recipient using existing assertion helper | ||
| #[tokio::test] | ||
| #[serial] | ||
| async fn test_compressible_account_with_compression_authority_lifecycle() { |
There was a problem hiding this comment.
Doc mismatch: authority used for close is the owner, not the rent authority
Comments say “Close account using rent authority,” but the instruction signs with owner. Update the doc to “owner,” or switch the authority if you intended rent-authority closure.
Also applies to: 266-273
🤖 Prompt for AI Agents
In program-tests/compressed-token-test/tests/ctoken/functional.rs around lines
93-101 (and also apply same change at lines 266-273), the test documentation
says “Close account using rent authority” but the test signs the close with the
owner; update the documentation to accurately reflect the code by changing “rent
authority” to “owner” in the doc comments, or if you intended to use the rent
authority instead, modify the test to sign the close with the rent authority
keypair and adjust any assertions accordingly so doc and implementation match.
| // Calculate transaction fee from the transaction result | ||
| let tx_fee = 10_000; // Standard transaction fee | ||
| assert_eq!( | ||
| payer_balance_before - payer_balance_after, | ||
| 11_776 + tx_fee, | ||
| "Payer should have paid exactly 14,830 lamports for additional rent (1 epoch) plus {} tx fee", | ||
| tx_fee | ||
| ); |
There was a problem hiding this comment.
Avoid hard-coded lamport deltas; compute or rely on existing helpers
The assertion uses a hard-coded 11_776 + tx_fee while the message claims 14,830 and “1 epoch” even though pre_pay_num_epochs = 2. This is fragile and inconsistent.
Prefer:
- Deriving the expected delta programmatically (from prepay params and rent math), or
- Relying solely on assert_create_token_account which already validates lamport flows.
At minimum, fix the message to match the actual expectation.
🤖 Prompt for AI Agents
In program-tests/compressed-token-test/tests/ctoken/functional.rs around lines
209 to 216, the test asserts a hard-coded lamport delta (11_776 + tx_fee) while
the assertion message references 14,830 and “1 epoch” despite pre_pay_num_epochs
= 2, making it fragile and inconsistent; update the assertion to compute the
expected lamport change programmatically (derive the prepay rent amount from the
same pre_pay_num_epochs and rent calculation used elsewhere or call the existing
helper that computes expected rent) and then assert payer_balance_before -
payer_balance_after == expected_rent + tx_fee, or if you prefer the helper
route, remove the manual delta and call assert_create_token_account (or the
appropriate helper) that already validates lamport flows; if you cannot refactor
now, at minimum update the assertion message to match the computed expectation
(correct amount and epoch count).
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
program-tests/compressed-token-test/tests/ctoken/transfer.rs (1)
118-122: Pass the real system program, not the zero pubkey.
AccountMeta::new_readonly(Pubkey::default(), …)hands the transfer CPI a zeroed program id. As soon as a transfer hits the rent top-up path, the CPI into the system program will fail withIncorrectProgramId, so teststest_ctoken_transfer_compressible_with_topup(line 227) andtest_ctoken_transfer_mixed_compressible_non_compressible(line 441) cannot succeed.Apply this diff:
- AccountMeta::new_readonly(Pubkey::default(), false), // System program for lamport transfers during top-up + AccountMeta::new_readonly(solana_sdk::system_program::ID, false), // System program for lamport transfers during top-upprograms/compressed-token/program/src/create_token_account.rs (1)
165-169: Verify error conversion follows coding guidelines.The validation logic correctly prevents 1-epoch prefunding with a clear error message. However, per the coding guidelines, errors should be returned as
ProgramError::Custom(error_code as u32)on-chain.Verify that
anchor_compressed_token::ErrorCode::OneEpochPrefundingNotAllowed.into()properly converts toProgramError::Custom(...):#!/bin/bash # Description: Check the ErrorCode implementation to verify it converts to ProgramError::Custom # Find the ErrorCode enum definition and its Into<ProgramError> implementation ast-grep --pattern $'impl From<ErrorCode> for $_ { $$$ }' # Also search for the OneEpochPrefundingNotAllowed error code definition rg -nP --type=rs -C5 'OneEpochPrefundingNotAllowed\s*[=,]'As per coding guidelines.
Note: As flagged in the previous review, test coverage for this error path is still missing. Please add unit tests that set
rent_paymentto 1 and assert theOneEpochPrefundingNotAllowederror is returned.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (7)
Cargo.toml(1 hunks)program-tests/compressed-token-test/tests/ctoken.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/spl_instruction_compat.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/transfer.rs(1 hunks)programs/compressed-token/program/src/create_token_account.rs(2 hunks)programs/compressed-token/program/src/lib.rs(1 hunks)sdk-libs/token-client/src/actions/ctoken_transfer.rs(0 hunks)
💤 Files with no reviewable changes (1)
- sdk-libs/token-client/src/actions/ctoken_transfer.rs
🚧 Files skipped from review as they are similar to previous changes (1)
- program-tests/compressed-token-test/tests/ctoken.rs
🧰 Additional context used
📓 Path-based instructions (2)
programs/compressed-token/program/src/**/*.rs
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Return errors as ProgramError::Custom(error_code as u32) on-chain
Files:
programs/compressed-token/program/src/lib.rsprograms/compressed-token/program/src/create_token_account.rs
programs/compressed-token/program/src/{create_token_account.rs,create_associated_token_account.rs}
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Enforce ACTIVE-only config validation for Create CToken Account and Create Associated CToken Account instructions
Files:
programs/compressed-token/program/src/create_token_account.rs
🧠 Learnings (13)
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/ctoken_transfer.rs : CTokenTransfer must perform SPL-compatible transfers between decompressed accounts
Applied to files:
programs/compressed-token/program/src/lib.rsprogram-tests/compressed-token-test/tests/ctoken/spl_instruction_compat.rsprogram-tests/compressed-token-test/tests/ctoken/transfer.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/{create_token_account.rs,create_associated_token_account.rs} : Enforce ACTIVE-only config validation for Create CToken Account and Create Associated CToken Account instructions
Applied to files:
programs/compressed-token/program/src/lib.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/transfer2/** : Transfer2 must support Compress, Decompress, and CompressAndClose modes and perform multi-mint sum checks
Applied to files:
program-tests/compressed-token-test/tests/ctoken/transfer.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/close_token_account{.rs,/**} : On closing ctoken accounts: if compressible, return rent exemption to the rent recipient; send remaining lamports to the destination
Applied to files:
program-tests/compressed-token-test/tests/ctoken/transfer.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CREATE_TOKEN_ACCOUNT.md : Document Create Token Account & Associated Token Account instructions in instructions/CREATE_TOKEN_ACCOUNT.md
Applied to files:
programs/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Document closing decompressed token accounts with rent distribution in instructions/CLOSE_TOKEN_ACCOUNT.md
Applied to files:
programs/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: CToken account layout matches SPL token accounts with a custom Compressible extension; compressed mint accounts support the TokenMetadata extension
Applied to files:
programs/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:45:40.029Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.029Z
Learning: Applies to programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md : Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions
Applied to files:
programs/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/config.rs : Implement CompressibleConfig account with Anchor, Borsh, and Pod serialization for Light Registry integration
Applied to files:
programs/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Determine compressibility and compute rent using calculate_rent_and_balance
Applied to files:
programs/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Update RentConfig values at claim time to reflect current policy
Applied to files:
programs/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Refactor rent logic so that 1 lamport is the minimum rent payment
Applied to files:
programs/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/programs/compressed-token/anchor/src/lib.rs : Define all program-specific error codes in anchor_compressed_token::ErrorCode and expose them for program-wide use
Applied to files:
programs/compressed-token/program/src/create_token_account.rs
🧬 Code graph analysis (3)
programs/compressed-token/program/src/lib.rs (1)
programs/compressed-token/program/src/ctoken_transfer.rs (1)
process_ctoken_transfer(19-35)
program-tests/compressed-token-test/tests/ctoken/spl_instruction_compat.rs (1)
program-tests/compressed-token-test/tests/ctoken/shared.rs (1)
setup_account_test(40-63)
program-tests/compressed-token-test/tests/ctoken/transfer.rs (3)
program-tests/compressed-token-test/tests/ctoken/shared.rs (3)
setup_account_test(40-63)create_and_assert_token_account(82-127)create_non_compressible_token_account(210-278)program-tests/utils/src/assert_ctoken_transfer.rs (1)
assert_ctoken_transfer(150-201)sdk-libs/program-test/src/utils/assert.rs (1)
assert_rpc_error(7-144)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
- GitHub Check: Test program-libs-fast
- GitHub Check: Test batched-merkle-tree-simulate
- GitHub Check: programs (compressed-token-and-e2e, ["cargo-test-sbf -p compressed-token-test -- --skip test_tran...
- GitHub Check: Test program-libs-slow
- GitHub Check: programs (system-cpi-test, ["cargo-test-sbf -p system-cpi-test", "cargo test -p light-system-prog...
- GitHub Check: programs (account-compression-and-registry, ["cargo-test-sbf -p account-compression-test", "cargo...
- GitHub Check: programs (system-cpi-test-v2-functional-account-infos, ["cargo-test-sbf -p system-cpi-v2-test -- ...
- GitHub Check: programs (light-system-program-compression, ["cargo-test-sbf -p system-test -- test_with_compress...
- GitHub Check: programs (system-cpi-test-v2-functional-read-only, ["cargo-test-sbf -p system-cpi-v2-test -- func...
- GitHub Check: programs (light-system-program-address, ["cargo-test-sbf -p system-test -- test_with_address"])
- GitHub Check: programs (compressed-token-batched-tree, ["cargo-test-sbf -p compressed-token-test -- test_transf...
- GitHub Check: system-programs (sdk-token-test-program, ["cargo-test-sbf -p sdk-token-test"])
- GitHub Check: system-programs (sdk-libs, light-sdk-macros light-sdk light-program-test light-client light-compr...
- GitHub Check: system-programs (sdk-anchor-test-program, ["cargo-test-sbf -p sdk-anchor-test", "cargo-test-sbf -...
- GitHub Check: lint
- GitHub Check: system-programs (sdk-test-program, ["cargo-test-sbf -p sdk-native-test", "cargo-test-sbf -p sdk-v...
- GitHub Check: cli-v1
- GitHub Check: stateless-js-v2
- GitHub Check: Forester e2e test
- GitHub Check: cli-v2
- GitHub Check: stateless-js-v1
🔇 Additional comments (8)
Cargo.toml (1)
221-221: Thanks for reverting to the shared git source.Pointing
pinocchio-token-programback to the git dependency keeps the workspace portable and fixes the CI breakage from the absolute local path. Looks good.programs/compressed-token/program/src/lib.rs (1)
115-115: This is a bug fix—approve as-is.The change from
[2..]to[1..]corrects an incorrect offset. Git history confirms the prior value was[2..], which was wrong. All nine instructions in the file now consistently use[1..]after the single-byte discriminator (line 108). Tests already expect this format:transfer.rsline 111 constructs instruction data asvec + amount, confirming[1..]is correct.If the old code with
[2..]was ever deployed, it would have been parsing instruction data incorrectly by skipping an extra byte. This is a correctness fix.program-tests/compressed-token-test/tests/ctoken/transfer.rs (5)
1-98: LGTM: Test setup correctly uses 2 prepaid epochs.The
setup_transfer_testhelper properly creates compressible accounts with 2 prepaid epochs (not 1), aligning with the PR's objective to prohibit single-epoch prefunding. The setup logic for creating source/destination accounts and minting tokens is sound.
127-181: LGTM: Transfer helpers correctly use assertion utilities.The
transfer_and_assertandtransfer_and_assert_failshelpers properly execute transfers and validate outcomes using shared assertion utilities fromlight_test_utilsandlight_program_test.
187-274: Tests correctly use 2 prepaid epochs, but top-up test will fail.The successful transfer tests properly use 2 prepaid epochs for compressible accounts, aligning with the PR objective. However,
test_ctoken_transfer_compressible_with_topup(line 227) will fail due to the system program issue at line 121. Once that's fixed, this test should pass.
280-414: LGTM: Comprehensive failure scenario coverage.The failing transfer tests correctly validate critical error modes (insufficient balance, frozen accounts, wrong authority, mint mismatch) with appropriate error codes. Using non-compressible accounts avoids the system program issue at line 121.
420-500: Edge cases well covered, but mixed test will fail.The zero-amount transfer test correctly validates SPL token behavior. The mixed compressible/non-compressible test properly uses 2 prepaid epochs and funds the owner for top-ups, but will fail due to the system program issue at line 121 until that's resolved.
programs/compressed-token/program/src/create_token_account.rs (1)
61-67: Ignore call-site verification for create_token_account
Theprocess_create_token_accounthandler is only invoked via on-chain dispatch and has no internal callers to update.Likely an incorrect or invalid review comment.
| // Step 2: Initialize using SPL token initialize_account3 instruction | ||
| // Note: initialize_account3 doesn't require account to be signer (SPL compatibility) | ||
| let mut init_ix = spl_token_2022::instruction::initialize_account3( | ||
| &spl_token_2022::ID, | ||
| &account1_keypair.pubkey(), | ||
| &context.mint_pubkey, | ||
| &context.owner_keypair.pubkey(), | ||
| ) | ||
| .unwrap(); | ||
|
|
||
| // Change program_id to ctoken program for compatibility test | ||
| init_ix.program_id = light_compressed_token::ID; | ||
|
|
||
| context | ||
| .rpc | ||
| .create_and_send_transaction(&[init_ix], &payer_pubkey, &[&context.payer]) | ||
| .await | ||
| .unwrap(); | ||
|
|
||
| println!("First token account created successfully"); | ||
| } | ||
|
|
||
| println!("Creating second token account..."); | ||
|
|
||
| // Create second account using SPL token instruction format | ||
| { | ||
| // Step 1: Create account via system program with ctoken program as owner | ||
| let rent = context | ||
| .rpc | ||
| .get_minimum_balance_for_rent_exemption(165) | ||
| .await | ||
| .unwrap(); | ||
|
|
||
| let create_account_ix = solana_sdk::system_instruction::create_account( | ||
| &payer_pubkey, | ||
| &account2_keypair.pubkey(), | ||
| rent, | ||
| 165, | ||
| &light_compressed_token::ID, // Use ctoken program as owner | ||
| ); | ||
|
|
||
| context | ||
| .rpc | ||
| .create_and_send_transaction( | ||
| &[create_account_ix], | ||
| &payer_pubkey, | ||
| &[&context.payer, &account2_keypair], | ||
| ) | ||
| .await | ||
| .unwrap(); | ||
|
|
||
| // Step 2: Initialize using SPL token initialize_account3 instruction | ||
| // Note: initialize_account3 doesn't require account to be signer (SPL compatibility) | ||
| let mut init_ix = spl_token_2022::instruction::initialize_account3( | ||
| &spl_token_2022::ID, | ||
| &account2_keypair.pubkey(), | ||
| &context.mint_pubkey, | ||
| &context.owner_keypair.pubkey(), | ||
| ) | ||
| .unwrap(); | ||
|
|
||
| // Change program_id to ctoken program for compatibility test | ||
| init_ix.program_id = light_compressed_token::ID; | ||
|
|
||
| context | ||
| .rpc | ||
| .create_and_send_transaction(&[init_ix], &payer_pubkey, &[&context.payer]) | ||
| .await | ||
| .unwrap(); |
There was a problem hiding this comment.
Missing mint account initialization prevents every instruction from succeeding
setup_account_test() only hands back a random mint_pubkey; it never creates a Mint account on chain. The very first initialize_account3 (and every later transfer/close) therefore references a non-existent mint, so the transaction aborts with InstructionError::MissingAccount/AccountNotFound. Please create and initialize the mint (e.g., system create_account + spl_token_2022::instruction::initialize_mint2 through the ctoken program) before issuing the account/move/close instructions.
🤖 Prompt for AI Agents
In program-tests/compressed-token-test/tests/ctoken/spl_instruction_compat.rs
around lines 49–117, the test uses a random mint_pubkey but never
creates/initializes the Mint account on-chain, so subsequent initialize_account3
calls fail with AccountNotFound; fix by creating and initializing the mint
before creating token accounts: allocate a mint Keypair, call system
create_account with correct rent-exempt lamports, space and owner =
light_compressed_token::ID (using the test payer as payer), then call
spl_token_2022::instruction::initialize_mint2 (with desired decimals and
mint/authority params), change that instruction’s program_id to
light_compressed_token::ID for compatibility, include the mint Keypair (and
payer) in the transaction signers, and await/unwrap the RPC call before
proceeding to initialize token accounts.
89619aa to
165f5d4
Compare
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
sdk-libs/token-client/src/instructions/transfer2.rs (1)
525-586: Fix compress_to_pubkey handling
compress_to_pubkeyin the compressible extension is the target pubkey, not a boolean flag. Conflating it withtrue/falseand, when “true”, reusingsource_index(the Solana token account being closed) means the packed owner meta no longer points at the intended Pubkey. For accounts wherecompress_to_pubkeyisSome(pubkey), this will surface as instruction failures because the owner index references the wrong account key. Please deserializecompress_to_pubkeyas the Pubkey it encodes and insert that key intopacked_tree_accounts(falling back to the original owner when it isNone), rather than reusing the source account index.program-tests/utils/src/assert_create_token_account.rs (1)
198-229: Remove magic number 165; rely on BASE_TOKEN_ACCOUNT_SIZE only.Two size assertions; one uses hard‑coded 165. Keep a single assertion with the constant to avoid drift.
Apply:
- assert_eq!(account_info.data.len(), 165); // SPL token account size + // SPL token account size + assert_eq!(account_info.data.len(), BASE_TOKEN_ACCOUNT_SIZE as usize); ... - assert_eq!(actual_spl_token_account, expected_spl_token_account); - assert_eq!(account_info.data.len(), BASE_TOKEN_ACCOUNT_SIZE as usize); + assert_eq!(actual_spl_token_account, expected_spl_token_account);
♻️ Duplicate comments (10)
program-tests/registry-test/tests/compressible.rs (2)
151-157: Update comment to reflect actual epoch range (2-11).The comment states "1 to 10" but the loop creates accounts with prepaid epochs ranging from 2 to 11. This mismatch should be corrected.
Apply this diff to fix the comment:
- // Create 10 token accounts with varying prepaid epochs (1 to 10) + // Create 10 token accounts with varying prepaid epochs (2 to 11) let mut token_accounts = Vec::new(); let mut owners = Vec::new(); for i in 2..=11 {
185-187: Align comment with actual epoch warp count (11).The comment says "Warp forward 10 epochs" but the code warps forward 11 epochs. Update the comment to match the code.
Apply this diff to fix the comment:
- // Warp forward 10 epochs using the new wrapper method + // Warp forward 11 epochs using the new wrapper method rpc.warp_epoch_forward(11).await.unwrap();sdk-libs/program-test/src/utils/assert.rs (3)
44-87: Critical: Hardcoded discriminants don't match standard Solana SDK and reference non-existent variants.Based on previous analysis, the numeric discriminants are offset by 1 and several variants don't exist in
solana-sdk:
- Line 53:
AccountDataTooSmallis 4 in SDK, not 5- Line 54:
InsufficientFundsis 5 in SDK, not 6- Lines 61-62, 66:
MaxSeedLengthExceeded,InvalidSeeds,ComputationalBudgetExceededdon't exist in standard SDK- All subsequent mappings are similarly offset
This will cause:
- Compile errors if these variants don't exist in
solana_instruction::error::InstructionError- Logic errors if the discriminants are wrong, causing tests to fail or pass incorrectly
Refactor to:
- Match on the variant directly instead of hardcoding numbers
- Extract shared logic into a helper function to eliminate duplication with lines 89-130
- Add explicit discriminant conversion if needed:
err as u32 == expected_error_codeExample refactor:
- Err(RpcError::TransactionError(TransactionError::InstructionError(index, ref err))) - if index == index_instruction => - { - match (err, expected_error_code) { - (InstructionError::GenericError, 0) => Ok(()), - (InstructionError::InvalidArgument, 1) => Ok(()), - // ... 30+ more lines - _ => Err(RpcError::AssertRpcError(format!( - "Expected error code {}, but got {:?}", - expected_error_code, err - ))), - } - } + Err(RpcError::TransactionError(TransactionError::InstructionError(index, ref err))) + if index == index_instruction => + { + if matches_instruction_error(err, expected_error_code) { + Ok(()) + } else { + Err(RpcError::AssertRpcError(format!( + "Expected error code {}, but got {:?}", + expected_error_code, err + ))) + } + }Add helper function before
assert_rpc_error:fn matches_instruction_error(err: &InstructionError, expected_code: u32) -> bool { match err { InstructionError::Custom(code) => *code == expected_code, _ => { // For built-in variants, cast the discriminant directly // This avoids hardcoding and keeps in sync with the enum definition let discriminant = unsafe { *(err as *const InstructionError as *const u32) }; discriminant == expected_code } } }Or use a simpler approach if the crate has serialization:
fn matches_instruction_error(err: &InstructionError, expected_code: u32) -> bool { match err { InstructionError::Custom(code) => *code == expected_code, other => std::mem::discriminant(other) == std::mem::discriminant(&(expected_code as InstructionError)), } }
89-130: Critical: Exact duplication of lines 44-87 with different error source.This block duplicates the same hardcoded discriminant logic from lines 44-87, only wrapped in
BanksClientErrorinstead of directTransactionError. All the same issues apply:
- Incorrect discriminants
- Non-existent variants
- Maintenance burden
Replace with the same helper function approach:
- Err(RpcError::BanksError(BanksClientError::TransactionError( - TransactionError::InstructionError(index, ref err), - ))) if index == index_instruction => match (err, expected_error_code) { - (InstructionError::GenericError, 0) => Ok(()), - // ... 30+ more duplicated lines - _ => Err(RpcError::AssertRpcError(format!( - "Expected error code {}, but got {:?}", - expected_error_code, err - ))), - }, + Err(RpcError::BanksError(BanksClientError::TransactionError( + TransactionError::InstructionError(index, ref err), + ))) if index == index_instruction => + { + if matches_instruction_error(err, expected_error_code) { + Ok(()) + } else { + Err(RpcError::AssertRpcError(format!( + "Expected error code {}, but got {:?}", + expected_error_code, err + ))) + } + }
44-130: Add handling for index mismatch on non-Custom errors.Currently, only Custom errors (lines 16-24, 27-35) check for index mismatch. Non-Custom errors at lines 44-130 don't have a symmetric branch for
index != index_instruction, causing them to fall through to the generic "Unexpected error type" message on line 136-139.Add branches before lines 45 and 90:
+ // Index mismatch for non-Custom TransactionError + Err(RpcError::TransactionError(TransactionError::InstructionError(index, ref err))) + if index != index_instruction => + { + Err(RpcError::AssertRpcError(format!( + "Expected error at instruction {}, but got at {} with error {:?}", + index_instruction, index, err + ))) + } + // Handle built-in Solana errors (non-Custom) - TransactionError variants Err(RpcError::TransactionError(TransactionError::InstructionError(index, ref err))) if index == index_instruction =>And before line 90:
+ // Index mismatch for non-Custom BanksClientError + Err(RpcError::BanksError(BanksClientError::TransactionError( + TransactionError::InstructionError(index, ref err), + ))) if index != index_instruction => + { + Err(RpcError::AssertRpcError(format!( + "Expected error at instruction {}, but got at {} with error {:?}", + index_instruction, index, err + ))) + } + // Handle built-in Solana errors (non-Custom) - BanksClientError variants Err(RpcError::BanksError(BanksClientError::TransactionError(programs/compressed-token/program/src/create_token_account.rs (1)
165-169: This is the same validation issue flagged in the past review comment. The validation logic is correct and consistent withcreate_associated_token_account.rs, but tests explicitly exercising theOneEpochPrefundingNotAllowederror path are still missing.Based on the test files provided, all tests use valid epoch values (0, 2+) and none attempt to set
rent_payment = 1to verify the error is returned.program-tests/compressed-token-test/tests/ctoken/functional.rs (1)
209-216: Assertion message inconsistent with test parameters.The assertion message claims "14,830 lamports for additional rent (1 epoch)" but the test uses
num_prepaid_epochs = 2(line 121), and the hard-coded delta is11_776 + tx_fee, not 14,830. This makes the test fragile and confusing.As noted in the previous review, either:
- Compute the expected delta programmatically from
pre_pay_num_epochsand rent calculations, or- Rely on
assert_create_token_accountwhich already validates lamport flowsAt minimum, fix the message to accurately reflect the actual values and epoch count.
.github/workflows/programs.yml (1)
34-119: Add explicit permissions block to limit GITHUB_TOKEN scope.The workflow does not specify permissions for the GITHUB_TOKEN, granting it default permissions which may be overly broad. As a security best practice, explicitly limit the token's permissions to the minimum required.
Add this block at the job level (after line 33):
jobs: system-programs: name: programs + permissions: + contents: read if: github.event.pull_request.draft == falseBased on static analysis.
program-tests/compressed-token-test/tests/ctoken/create_ata.rs (1)
223-256: Align the IllegalOwner comment with the asserted codeInline comment still says “Error: 18 (IllegalOwner)” while the assertion expects 29. Please update one or the other so the narrative matches the behavior.
program-tests/compressed-token-test/tests/ctoken/transfer.rs (1)
118-122: Wire the actual system program into transfer CPI
AccountMeta::new_readonly(Pubkey::default(), …)feeds a zero program id to the CPI, so any rent top-up immediately tripsIncorrectProgramId. Please pass the real system program id instead.- AccountMeta::new_readonly(Pubkey::default(), false), // System program for lamport transfers during top-up + AccountMeta::new_readonly(solana_sdk::system_program::ID, false), // System program for lamport transfers during top-up
🧹 Nitpick comments (16)
program-tests/registry-test/tests/compressible.rs (2)
4-4: TODO: Refactor into directory structure.This organizational task is flagged. The test file could benefit from being split into multiple modules within a directory.
Would you like me to generate a proposed directory structure and migration plan, or open a new issue to track this refactoring task?
144-147: Consider preserving error context with Result return types.The function signature changed from returning
Result<(), RpcError>to a unit return, and error handling throughout the test now uses.unwrap()instead of the?operator. While tests will still fail appropriately through panics, this reduces error context visibility when debugging failures.If detailed error messages are important for debugging, consider keeping the
Resultreturn type and using?for error propagation:-async fn test_claim_multiple_accounts_different_epochs() { - let mut rpc = LightProgramTest::new(ProgramTestConfig::new_v2(false, None)) - .await - .unwrap(); +async fn test_claim_multiple_accounts_different_epochs() -> Result<(), RpcError> { + let mut rpc = LightProgramTest::new(ProgramTestConfig::new_v2(false, None)) + .await?;Apply similar changes throughout the function where
.unwrap()is used on operations that returnResult<_, RpcError>.program-tests/compressed-token-test/tests/transfer2/spl_ctoken.rs (4)
44-47: Consider removing debug print statement.This debug print appears to be a development artifact. Consider removing it or converting to a proper test log if the output is needed for debugging.
Apply this diff to remove the debug print:
- println!( - "spl_token_account_keypair {:?}", - spl_token_account_keypair.pubkey() - );
128-128: Consider removing debug print statement.This debug print appears to be a development artifact. Consider removing it or converting to a proper test log if the output is needed for debugging.
Apply this diff to remove the debug print:
- println!("Testing reverse transfer: ctoken to SPL");
73-76: Reduce code duplication and document magic number.The parsing logic for
PodAccountis duplicated five times throughout the test. Additionally, the hardcoded slice[..165]used for compressed token accounts (lines 114, 171) is a magic number that should be documented or extracted as a constant.Consider refactoring the parsing logic into helper functions:
fn parse_spl_account(data: &[u8]) -> Result<PodAccount, RpcError> { spl_pod::bytemuck::pod_from_bytes::<PodAccount>(data) .map(|acc| *acc) .map_err(|e| RpcError::AssertRpcError(format!("Failed to parse SPL token account: {}", e))) } fn parse_ctoken_account(data: &[u8]) -> Result<PodAccount, RpcError> { const CTOKEN_ACCOUNT_POD_SIZE: usize = 165; spl_pod::bytemuck::pod_from_bytes::<PodAccount>(&data[..CTOKEN_ACCOUNT_POD_SIZE]) .map(|acc| *acc) .map_err(|e| RpcError::AssertRpcError(format!("Failed to parse compressed token account: {}", e))) }Then use these helpers throughout the test to reduce duplication and improve maintainability.
Also applies to: 98-103, 114-118, 151-156, 171-178
91-125: Consider flattening nested blocks for improved readability.The nested blocks (lines 91-125 and 144-184) are used to scope variables but add unnecessary nesting. Consider flattening these blocks to improve readability, as the variable names don't conflict.
Example refactoring for the first verification block:
- { - // Verify SPL token balance decreased - let spl_account_data = rpc - .get_account(spl_token_account_keypair.pubkey()) - .await - .unwrap() - .unwrap(); - let spl_account = spl_pod::bytemuck::pod_from_bytes::<PodAccount>(&spl_account_data.data) - .map_err(|e| { - RpcError::AssertRpcError(format!("Failed to parse SPL token account: {}", e)) - }) - .unwrap(); - let final_spl_balance: u64 = spl_account.amount.into(); - assert_eq!(final_spl_balance, amount - transfer_amount); - } - { - // Verify compressed token balance increased - let spl_account_data = rpc - .get_account(associated_token_account) - .await - .unwrap() - .unwrap(); - let spl_account = - spl_pod::bytemuck::pod_from_bytes::<PodAccount>(&spl_account_data.data[..165]) - .map_err(|e| { - RpcError::AssertRpcError(format!("Failed to parse SPL token account: {}", e)) - }) - .unwrap(); - assert_eq!( - u64::from(spl_account.amount), - transfer_amount, - "Recipient should have {} compressed tokens", - transfer_amount - ); - } + // Verify SPL token balance decreased + let spl_account_data = rpc + .get_account(spl_token_account_keypair.pubkey()) + .await + .unwrap() + .unwrap(); + let spl_account = spl_pod::bytemuck::pod_from_bytes::<PodAccount>(&spl_account_data.data) + .map_err(|e| { + RpcError::AssertRpcError(format!("Failed to parse SPL token account: {}", e)) + }) + .unwrap(); + let final_spl_balance: u64 = spl_account.amount.into(); + assert_eq!(final_spl_balance, amount - transfer_amount); + + // Verify compressed token balance increased + let ctoken_account_data = rpc + .get_account(associated_token_account) + .await + .unwrap() + .unwrap(); + let ctoken_account = + spl_pod::bytemuck::pod_from_bytes::<PodAccount>(&ctoken_account_data.data[..165]) + .map_err(|e| { + RpcError::AssertRpcError(format!("Failed to parse SPL token account: {}", e)) + }) + .unwrap(); + assert_eq!( + u64::from(ctoken_account.amount), + transfer_amount, + "Recipient should have {} compressed tokens", + transfer_amount + );Also applies to: 144-184
program-tests/utils/src/assert_create_token_account.rs (4)
2-2: Remove unused import.
use light_client::rpc::Rpc;is not used.Apply:
-use light_client::rpc::Rpc;
75-111: Avoid brittle full-struct equality on CToken; assert stable fields only.
last_claimed_slot == current_slotandconfig_account_version = 1can drift and cause flaky tests. Prefer asserting invariant fields (mint, owner, amount=0, state, extension core values), and checklast_claimed_slot <= current_slot.Example approach (sketch):
- Extract
CompressionInfofromactual_token_account.- Assert:
- mint/owner/amount/state as today
- compression_authority/rent_sponsor/lamports_per_write/compress_to_pubkey/account_version
- rent_config equals expected default (or compare relevant fields)
- last_claimed_slot <= current_slot
- Drop
expected_token_accountconstruction andassert_eq!(actual, expected).Based on learnings.
142-146: Don’t hard‑code fee per signature (5_000).Fee can change; hard‑coding risks flakes. Derive fee dynamically and multiply by signer count.
Consider:
- Query lamports per signature via the test RPC (e.g., fees endpoint) and compute
tx_fee = lamports_per_sig * (is_ata ? 1 : 2).- If not available, thread expected
lamports_per_siginto this helper from the caller.
267-279: Redundant ATA existence pre‑check.
assert_create_token_account_internalimmediately fetches and asserts existence; this extra fetch/assert duplicates work.Apply:
- // Verify the account exists at the derived address - let account = rpc - .get_account(ata_pubkey) - .await - .expect("Failed to get ATA account"); - - assert!( - account.is_some(), - "ATA should exist at derived address {} for owner {} and mint {}", - ata_pubkey, - owner_pubkey, - mint_pubkey - );program-tests/utils/src/assert_transfer2.rs (1)
389-414: Avoid magic 165; use BASE_TOKEN_ACCOUNT_SIZEUse the shared base token account size constant for length checks to avoid brittle literals.
- let compress_to_pubkey = if pre_account_data.data.len() > 165 { + let compress_to_pubkey = if pre_account_data.data.len() + > light_ctoken_types::BASE_TOKEN_ACCOUNT_SIZE as usize + {Add import near the top of this file:
use light_ctoken_types::BASE_TOKEN_ACCOUNT_SIZE;Apply similarly anywhere else 165 is used for SPL account header sizing in this helper.
Also applies to: 422-427
program-tests/compressed-token-test/tests/ctoken/compress_and_close.rs (3)
67-75: Replace repeated 165 byte constants with BASE_TOKEN_ACCOUNT_SIZEReferencing SPL account header size via a shared constant improves clarity and avoids drift.
- Import and use light_ctoken_types::BASE_TOKEN_ACCOUNT_SIZE for:
- unpack/pack slices: &data[..BASE_TOKEN_ACCOUNT_SIZE as usize]
- length checks comparing against 165
Apply across this file for all occurrences shown and similar ones.Also applies to: 117-125, 609-613, 810-817
457-465: Clarify payer vs pool variables and assertion messageVariable pool_balance_before actually holds the payer’s balance. Rename to payer_balance_before and update the assertion message to avoid confusion.
- let pool_balance_before = context + let payer_balance_before = context .rpc - .get_account(payer_pubkey) + .get_account(payer_pubkey) .await .unwrap() - .expect("Pool PDA should exist") + .expect("Payer should exist") .lamports; ... - assert_eq!( - pool_balance_before - payer_balance_after, + assert_eq!( + payer_balance_before - payer_balance_after, rent_exemption + rent + tx_fee, - "Pool PDA should have paid {} lamports for account creation (rent-exempt), and the additional rent", + "Payer should have covered rent-exempt + additional rent + fee", rent_exemption );Also applies to: 495-511
237-239: Use get_output_pubkey consistently for output queueSome tests use get_output_pubkey() while others read .queue. For consistency and to avoid packing mismatches, prefer get_output_pubkey() everywhere in these tests.
Also applies to: 290-291
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md (1)
112-112: Fix markdown list indentation.The error list items have incorrect indentation (2 spaces instead of 0), which violates markdown linting rules.
Apply this fix to both locations:
- - `ErrorCode::OneEpochPrefundingNotAllowed` (error code: 6116) - rent_payment is exactly 1 epoch... +- `ErrorCode::OneEpochPrefundingNotAllowed` (error code: 6116) - rent_payment is exactly 1 epoch...Based on static analysis.
Also applies to: 180-180
program-tests/compressed-token-test/tests/ctoken/create_ata.rs (1)
441-473: Keep the InvalidAccountOwner commentary in sync with the assertionThe prose calls out error 14, but the check asserts 20001. Adjust the comment (or the expectation) so readers don’t chase the wrong code.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (47)
.github/workflows/programs.yml(1 hunks)Cargo.toml(1 hunks)program-libs/compressible/tests/compression_info.rs(1 hunks)program-libs/compressible/tests/rent.rs(1 hunks)program-libs/ctoken-types/src/constants.rs(1 hunks)program-tests/compressed-token-test/Cargo.toml(1 hunks)program-tests/compressed-token-test/tests/account.rs(0 hunks)program-tests/compressed-token-test/tests/ctoken.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/close.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/compress_and_close.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/create.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/create_ata.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/functional.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/functional_ata.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/shared.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/spl_instruction_compat.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/transfer.rs(1 hunks)program-tests/compressed-token-test/tests/transfer2/compress_failing.rs(1 hunks)program-tests/compressed-token-test/tests/transfer2/decompress_failing.rs(1 hunks)program-tests/compressed-token-test/tests/transfer2/mod.rs(1 hunks)program-tests/compressed-token-test/tests/transfer2/spl_ctoken.rs(1 hunks)program-tests/compressed-token-test/tests/v1.rs(5 hunks)program-tests/registry-test/Cargo.toml(1 hunks)program-tests/registry-test/tests/compressible.rs(28 hunks)program-tests/system-cpi-test/tests/test.rs(2 hunks)program-tests/system-test/tests/test.rs(1 hunks)program-tests/utils/src/assert_close_token_account.rs(5 hunks)program-tests/utils/src/assert_create_token_account.rs(4 hunks)program-tests/utils/src/assert_ctoken_transfer.rs(1 hunks)program-tests/utils/src/assert_transfer2.rs(2 hunks)programs/compressed-token/anchor/src/lib.rs(1 hunks)programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md(5 hunks)programs/compressed-token/program/docs/instructions/CTOKEN_TRANSFER.md(1 hunks)programs/compressed-token/program/docs/instructions/TRANSFER2.md(1 hunks)programs/compressed-token/program/src/create_associated_token_account.rs(1 hunks)programs/compressed-token/program/src/create_token_account.rs(2 hunks)programs/compressed-token/program/src/ctoken_transfer.rs(3 hunks)programs/compressed-token/program/src/lib.rs(1 hunks)programs/compressed-token/program/src/shared/initialize_ctoken_account.rs(1 hunks)programs/compressed-token/program/src/transfer2/compression/ctoken/compress_and_close.rs(1 hunks)programs/compressed-token/program/src/transfer2/compression/ctoken/compress_or_decompress_ctokens.rs(1 hunks)sdk-libs/compressed-token-sdk/tests/create_associated_token_account.rs(1 hunks)sdk-libs/program-test/src/utils/assert.rs(1 hunks)sdk-libs/token-client/src/actions/ctoken_transfer.rs(0 hunks)sdk-libs/token-client/src/instructions/transfer2.rs(3 hunks)sdk-tests/sdk-token-test/src/process_create_ctoken_with_compress_to_pubkey.rs(1 hunks)sdk-tests/sdk-token-test/tests/pda_ctoken.rs(1 hunks)
💤 Files with no reviewable changes (2)
- sdk-libs/token-client/src/actions/ctoken_transfer.rs
- program-tests/compressed-token-test/tests/account.rs
✅ Files skipped from review due to trivial changes (1)
- program-tests/compressed-token-test/tests/transfer2/mod.rs
🚧 Files skipped from review as they are similar to previous changes (14)
- programs/compressed-token/program/docs/instructions/TRANSFER2.md
- sdk-tests/sdk-token-test/tests/pda_ctoken.rs
- programs/compressed-token/program/src/lib.rs
- program-libs/compressible/tests/rent.rs
- program-tests/compressed-token-test/tests/transfer2/decompress_failing.rs
- programs/compressed-token/program/src/shared/initialize_ctoken_account.rs
- programs/compressed-token/program/src/transfer2/compression/ctoken/compress_and_close.rs
- program-tests/compressed-token-test/tests/ctoken/spl_instruction_compat.rs
- program-tests/utils/src/assert_ctoken_transfer.rs
- programs/compressed-token/program/src/ctoken_transfer.rs
- Cargo.toml
- sdk-tests/sdk-token-test/src/process_create_ctoken_with_compress_to_pubkey.rs
- program-tests/registry-test/Cargo.toml
- program-tests/compressed-token-test/tests/ctoken/shared.rs
🧰 Additional context used
📓 Path-based instructions (6)
programs/compressed-token/program/docs/instructions/*.md
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Each instruction doc must include: path, description, instruction_data (code paths), Accounts (order and checks), instruction logic and checks, and Errors (with causes)
Files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprograms/compressed-token/program/docs/instructions/CTOKEN_TRANSFER.md
programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md
📄 CodeRabbit inference engine (programs/compressed-token/program/docs/CLAUDE.md)
Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions
Files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
programs/compressed-token/program/docs/**/instructions/**/*.md
📄 CodeRabbit inference engine (programs/compressed-token/program/docs/CLAUDE.md)
Keep detailed instruction documentation files under the instructions/ directory; add additional instruction docs as needed
Files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprograms/compressed-token/program/docs/instructions/CTOKEN_TRANSFER.md
programs/compressed-token/program/src/{create_token_account.rs,create_associated_token_account.rs}
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Enforce ACTIVE-only config validation for Create CToken Account and Create Associated CToken Account instructions
Files:
programs/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/src/create_token_account.rs
programs/compressed-token/program/src/**/*.rs
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Return errors as ProgramError::Custom(error_code as u32) on-chain
Files:
programs/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/src/transfer2/compression/ctoken/compress_or_decompress_ctokens.rsprograms/compressed-token/program/src/create_token_account.rs
programs/compressed-token/program/src/transfer2/**
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Transfer2 must support Compress, Decompress, and CompressAndClose modes and perform multi-mint sum checks
Files:
programs/compressed-token/program/src/transfer2/compression/ctoken/compress_or_decompress_ctokens.rs
🧠 Learnings (32)
📓 Common learnings
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/close_token_account{.rs,/**} : On closing ctoken accounts: if compressible, return rent exemption to the rent recipient; send remaining lamports to the destination
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/error.rs : Maintain stable mapping of AccountError to ProgramError, including Pinocchio code mapping (1–11), in error.rs
Applied to files:
sdk-libs/program-test/src/utils/assert.rsprograms/compressed-token/anchor/src/lib.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/**/*.rs : Return errors as ProgramError::Custom(error_code as u32) on-chain
Applied to files:
sdk-libs/program-test/src/utils/assert.rsprograms/compressed-token/anchor/src/lib.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Document closing decompressed token accounts with rent distribution in instructions/CLOSE_TOKEN_ACCOUNT.md
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprogram-tests/compressed-token-test/tests/ctoken/functional.rsprogram-tests/compressed-token-test/tests/ctoken/compress_and_close.rsprogram-tests/compressed-token-test/tests/ctoken/close.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/close_token_account{.rs,/**} : On closing ctoken accounts: if compressible, return rent exemption to the rent recipient; send remaining lamports to the destination
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprogram-tests/compressed-token-test/tests/ctoken/functional.rsprogram-tests/utils/src/assert_transfer2.rsprogram-libs/ctoken-types/src/constants.rsprograms/compressed-token/program/src/create_associated_token_account.rsprogram-tests/compressed-token-test/tests/ctoken/transfer.rssdk-libs/token-client/src/instructions/transfer2.rsprograms/compressed-token/program/src/transfer2/compression/ctoken/compress_or_decompress_ctokens.rsprogram-tests/utils/src/assert_create_token_account.rsprogram-tests/compressed-token-test/tests/ctoken/compress_and_close.rsprogram-tests/utils/src/assert_close_token_account.rsprogram-tests/compressed-token-test/tests/ctoken/close.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: CToken account layout matches SPL token accounts with a custom Compressible extension; compressed mint accounts support the TokenMetadata extension
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprogram-tests/utils/src/assert_transfer2.rsprogram-libs/ctoken-types/src/constants.rssdk-libs/token-client/src/instructions/transfer2.rsprograms/compressed-token/program/src/transfer2/compression/ctoken/compress_or_decompress_ctokens.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/{create_token_account.rs,create_associated_token_account.rs} : Enforce ACTIVE-only config validation for Create CToken Account and Create Associated CToken Account instructions
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprograms/compressed-token/program/src/create_associated_token_account.rsprogram-tests/utils/src/assert_create_token_account.rsprogram-tests/compressed-token-test/tests/ctoken/create.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:45:40.029Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.029Z
Learning: Applies to programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md : Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprogram-tests/compressed-token-test/tests/ctoken/create.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/docs/ACCOUNTS.md : Accounts documentation must include: description, discriminator, state layout, serialization example, hashing (only for compressed accounts), derivation (only for PDAs), and associated instructions
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/{CREATE_TOKEN_ACCOUNT,MINT_ACTION,TRANSFER2,CLAIM,CLOSE_TOKEN_ACCOUNT,DECOMPRESSED_TRANSFER,WITHDRAW_FUNDING_POOL}.md : Every instruction description must include sections: path, description, instruction_data, Accounts, instruction logic and checks, Errors
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprograms/compressed-token/program/docs/instructions/CTOKEN_TRANSFER.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLAIM.md : Document rent reclamation from expired compressible accounts in instructions/CLAIM.md
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/docs/instructions/*.md : Each instruction doc must include: path, description, instruction_data (code paths), Accounts (order and checks), instruction logic and checks, and Errors (with causes)
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/**/ACCOUNTS.md : Provide complete account layouts and data structures in ACCOUNTS.md
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/DECOMPRESSED_TRANSFER.md : Document SPL-compatible transfers between decompressed accounts in instructions/DECOMPRESSED_TRANSFER.md
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdsdk-libs/token-client/src/instructions/transfer2.rsprograms/compressed-token/program/docs/instructions/CTOKEN_TRANSFER.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CREATE_TOKEN_ACCOUNT.md : Document Create Token Account & Associated Token Account instructions in instructions/CREATE_TOKEN_ACCOUNT.md
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprogram-tests/compressed-token-test/tests/ctoken/create.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Determine compressibility and compute rent using calculate_rent_and_balance
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprogram-libs/ctoken-types/src/constants.rsprograms/compressed-token/program/src/create_associated_token_account.rsprogram-libs/compressible/tests/compression_info.rssdk-libs/token-client/src/instructions/transfer2.rsprograms/compressed-token/program/src/transfer2/compression/ctoken/compress_or_decompress_ctokens.rsprogram-tests/utils/src/assert_create_token_account.rsprogram-tests/utils/src/assert_close_token_account.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Refactor rent logic so that 1 lamport is the minimum rent payment
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprogram-libs/ctoken-types/src/constants.rsprograms/compressed-token/program/src/create_associated_token_account.rsprogram-libs/compressible/tests/compression_info.rsprogram-tests/compressed-token-test/tests/transfer2/compress_failing.rsprogram-tests/utils/src/assert_close_token_account.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Update RentConfig values at claim time to reflect current policy
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprogram-libs/ctoken-types/src/constants.rsprograms/compressed-token/program/src/create_associated_token_account.rsprogram-libs/compressible/tests/compression_info.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/ctoken_transfer.rs : CTokenTransfer must perform SPL-compatible transfers between decompressed accounts
Applied to files:
program-tests/compressed-token-test/tests/ctoken/functional.rsprogram-tests/utils/src/assert_transfer2.rsprogram-tests/compressed-token-test/tests/ctoken/transfer.rssdk-libs/token-client/src/instructions/transfer2.rsprograms/compressed-token/program/src/transfer2/compression/ctoken/compress_or_decompress_ctokens.rsprogram-tests/utils/src/assert_create_token_account.rsprogram-tests/compressed-token-test/tests/transfer2/spl_ctoken.rsprogram-tests/compressed-token-test/tests/ctoken.rsprograms/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/docs/instructions/CTOKEN_TRANSFER.md
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/transfer2/** : Transfer2 must support Compress, Decompress, and CompressAndClose modes and perform multi-mint sum checks
Applied to files:
program-tests/utils/src/assert_transfer2.rsprogram-tests/compressed-token-test/tests/ctoken/transfer.rssdk-libs/token-client/src/instructions/transfer2.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/config.rs : Include default initialization for CToken V1 config in CompressibleConfig
Applied to files:
program-libs/ctoken-types/src/constants.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/docs/RENT.md : Document rent calculation functions and compressibility checks in docs/RENT.md
Applied to files:
program-libs/ctoken-types/src/constants.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Expose claimable rent computation via claimable_lamports
Applied to files:
program-libs/ctoken-types/src/constants.rsprogram-libs/compressible/tests/compression_info.rsprograms/compressed-token/program/src/transfer2/compression/ctoken/compress_or_decompress_ctokens.rsprogram-tests/registry-test/tests/compressible.rsprogram-tests/utils/src/assert_close_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/config.rs : Update config parameters including max write fee and max funded epoch
Applied to files:
programs/compressed-token/program/src/create_associated_token_account.rsprogram-libs/compressible/tests/compression_info.rsprogram-tests/compressed-token-test/tests/transfer2/compress_failing.rssdk-libs/compressed-token-sdk/tests/create_associated_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/config.rs : Implement CompressibleConfig account with Anchor, Borsh, and Pod serialization for Light Registry integration
Applied to files:
programs/compressed-token/program/src/create_associated_token_account.rsprogram-tests/system-cpi-test/tests/test.rsprogram-tests/utils/src/assert_create_token_account.rsprogram-tests/registry-test/tests/compressible.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Compute close lamport distribution with calculate_close_lamports
Applied to files:
program-libs/compressible/tests/compression_info.rsprogram-tests/utils/src/assert_close_token_account.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Gate SDK-specific implementations with #[cfg(feature = "solana"|"pinocchio"|"test-only")]
Applied to files:
program-tests/system-cpi-test/tests/test.rsprogram-tests/utils/src/assert_create_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/program-libs/ctoken-types/{state/**,instructions/**,state/extensions/**} : Define all state and instruction data structures (including extensions like Compressible and TokenMetadata) in the light-ctoken-types crate
Applied to files:
program-tests/utils/src/assert_create_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/programs/compressed-token/anchor/src/lib.rs : Define all program-specific error codes in anchor_compressed_token::ErrorCode and expose them for program-wide use
Applied to files:
program-tests/registry-test/tests/compressible.rsprograms/compressed-token/program/src/create_token_account.rsprograms/compressed-token/anchor/src/lib.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/error.rs : Provide ProgramError conversions compatible with Anchor, Pinocchio, and Solana error types
Applied to files:
programs/compressed-token/anchor/src/lib.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/**/*.rs : Return AccountError variants (codes 12006–12021) and rely on automatic ProgramError conversions; avoid returning raw ProgramError directly
Applied to files:
programs/compressed-token/anchor/src/lib.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/TRANSFER2.md : Document the batch transfer instruction supporting compressed/decompressed operations in instructions/TRANSFER2.md
Applied to files:
programs/compressed-token/program/docs/instructions/CTOKEN_TRANSFER.md
🧬 Code graph analysis (12)
sdk-libs/program-test/src/utils/assert.rs (1)
js/stateless.js/src/errors.ts (1)
RpcError(79-79)
program-tests/compressed-token-test/tests/ctoken/functional.rs (4)
program-tests/compressed-token-test/tests/ctoken/shared.rs (2)
setup_account_test(40-63)setup_destination_account(66-80)program-tests/utils/src/assert_create_token_account.rs (1)
assert_create_token_account(236-252)program-tests/utils/src/assert_close_token_account.rs (1)
assert_close_token_account(8-106)program-tests/utils/src/assert_transfer2.rs (1)
assert_transfer2_compress(576-590)
program-tests/compressed-token-test/tests/ctoken/transfer.rs (3)
program-tests/compressed-token-test/tests/ctoken/shared.rs (3)
setup_account_test(40-63)create_and_assert_token_account(82-127)create_non_compressible_token_account(210-278)program-tests/utils/src/assert_ctoken_transfer.rs (1)
assert_ctoken_transfer(150-201)sdk-libs/program-test/src/utils/assert.rs (1)
assert_rpc_error(7-144)
program-tests/compressed-token-test/tests/ctoken/functional_ata.rs (3)
program-tests/utils/src/assert_create_token_account.rs (2)
assert_create_token_account(236-252)assert_create_associated_token_account(258-291)program-tests/compressed-token-test/tests/ctoken/shared.rs (1)
setup_account_test(40-63)program-tests/utils/src/assert_close_token_account.rs (1)
assert_close_token_account(8-106)
program-tests/compressed-token-test/tests/ctoken/compress_and_close.rs (3)
program-tests/compressed-token-test/tests/ctoken/shared.rs (7)
setup_compress_and_close_test(530-579)compress_and_close_owner_and_assert(587-662)setup_account_test(40-63)create_non_compressible_token_account(210-278)create_and_assert_ata(400-461)compress_and_close_and_assert_fails(672-729)compress_and_close_forester_with_invalid_output(750-902)program-tests/utils/src/assert_transfer2.rs (2)
assert_transfer2(550-552)assert_transfer2_compress_and_close(594-628)sdk-libs/token-client/src/instructions/transfer2.rs (1)
create_generic_transfer2_instruction(145-640)
program-tests/registry-test/tests/compressible.rs (2)
program-tests/utils/src/spl.rs (1)
create_mint_helper(260-263)sdk-libs/program-test/src/utils/assert.rs (1)
assert_rpc_error(7-144)
program-tests/compressed-token-test/tests/ctoken/create_ata.rs (4)
program-tests/compressed-token-test/tests/ctoken/shared.rs (3)
setup_account_test(40-63)create_and_assert_ata(400-461)create_and_assert_ata_fails(464-514)sdk-libs/program-test/src/compressible.rs (1)
new(44-64)sdk-libs/program-test/src/utils/assert.rs (1)
assert_rpc_error(7-144)program-tests/utils/src/assert_create_token_account.rs (1)
assert_create_associated_token_account(258-291)
program-tests/compressed-token-test/tests/ctoken/create.rs (2)
program-tests/compressed-token-test/tests/ctoken/shared.rs (3)
setup_account_test(40-63)create_and_assert_token_account(82-127)create_and_assert_token_account_fails(130-172)sdk-libs/program-test/src/utils/assert.rs (1)
assert_rpc_error(7-144)
program-tests/compressed-token-test/tests/ctoken/close.rs (1)
program-tests/compressed-token-test/tests/ctoken/shared.rs (4)
setup_account_test_with_created_account(178-207)close_and_assert_token_account(281-353)close_and_assert_token_account_fails(356-396)create_and_assert_token_account(82-127)
program-tests/compressed-token-test/tests/transfer2/spl_ctoken.rs (1)
program-tests/utils/src/spl.rs (3)
create_mint_helper(260-263)create_token_2022_account(435-488)mint_spl_tokens(69-105)
program-tests/compressed-token-test/tests/ctoken.rs (1)
programs/registry/src/lib.rs (1)
compress_and_close(765-778)
program-tests/system-test/tests/test.rs (1)
sdk-libs/program-test/src/utils/assert.rs (1)
assert_rpc_error(7-144)
🪛 GitHub Check: CodeQL
.github/workflows/programs.yml
[warning] 34-119: Workflow does not contain permissions
Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {{contents: read}}
🪛 LanguageTool
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
[grammar] ~76-~76: There might be a mistake here.
Context: ...is not exactly 1 epoch - Check: compressible_config.rent_payment != 1 - Error: `ErrorCode::OneEpochPrefundingNot...
(QB_NEW_EN)
[grammar] ~180-~180: There might be a mistake here.
Context: ...epoch (see create ctoken account errors)
(QB_NEW_EN)
programs/compressed-token/program/docs/instructions/CTOKEN_TRANSFER.md
[grammar] ~21-~21: There might be a mistake here.
Context: ...riminator (3) - Second byte: 0 (padding) - Remaining bytes: SPL TokenInstruction::T...
(QB_NEW_EN)
🪛 markdownlint-cli2 (0.18.1)
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
112-112: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
180-180: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
- GitHub Check: cli-v1
- GitHub Check: system-programs (sdk-libs, light-sdk-macros light-sdk light-program-test light-client light-compr...
- GitHub Check: system-programs (sdk-test-program, ["cargo-test-sbf -p sdk-native-test", "cargo-test-sbf -p sdk-v...
- GitHub Check: system-programs (sdk-token-test-program, ["cargo-test-sbf -p sdk-token-test"])
- GitHub Check: system-programs (sdk-anchor-test-program, ["cargo-test-sbf -p sdk-anchor-test", "cargo-test-sbf -...
- GitHub Check: cli-v2
- GitHub Check: Test program-libs-slow
- GitHub Check: Test program-libs-fast
- GitHub Check: Test batched-merkle-tree-simulate
- GitHub Check: lint
- GitHub Check: Forester e2e test
- GitHub Check: programs (system-cpi-test-v2-functional-account-infos, ["cargo-test-sbf -p system-cpi-v2-test -- ...
- GitHub Check: stateless-js-v2
- GitHub Check: programs (compressed-token-and-e2e, ["cargo-test-sbf -p compressed-token-test -- --skip test_tran...
- GitHub Check: programs (account-compression-and-registry, ["cargo-test-sbf -p account-compression-test", "cargo...
- GitHub Check: programs (light-system-program-address, ["cargo-test-sbf -p system-test -- test_with_address"])
- GitHub Check: programs (system-cpi-test-v2-functional-read-only, ["cargo-test-sbf -p system-cpi-v2-test -- func...
- GitHub Check: programs (light-system-program-compression, ["cargo-test-sbf -p system-test -- test_with_compress...
- GitHub Check: programs (system-cpi-test, ["cargo-test-sbf -p system-cpi-test", "cargo test -p light-system-prog...
- GitHub Check: stateless-js-v1
- GitHub Check: programs (compressed-token-batched-tree, ["cargo-test-sbf -p compressed-token-test -- test_transf...
| // Create SPL token account and mint tokens | ||
| let spl_token_account_keypair = Keypair::new(); | ||
| create_token_2022_account(&mut rpc, &mint, &spl_token_account_keypair, &sender, false) | ||
| .await | ||
| .unwrap(); | ||
| mint_spl_tokens( | ||
| &mut rpc, | ||
| &mint, | ||
| &spl_token_account_keypair.pubkey(), | ||
| &payer.pubkey(), | ||
| &payer, | ||
| amount, | ||
| false, | ||
| ) | ||
| .await | ||
| .unwrap(); |
There was a problem hiding this comment.
Fix token owner mismatch in mint operation.
The SPL token account is created with sender as the owner (line 30), but mint_spl_tokens is called with payer.pubkey() as the token_owner parameter (line 37). This mismatch could cause the mint operation to fail or behave incorrectly.
Apply this diff to fix the token owner:
mint_spl_tokens(
&mut rpc,
&mint,
&spl_token_account_keypair.pubkey(),
- &payer.pubkey(),
+ &sender.pubkey(),
&payer,
amount,
false,
)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Create SPL token account and mint tokens | |
| let spl_token_account_keypair = Keypair::new(); | |
| create_token_2022_account(&mut rpc, &mint, &spl_token_account_keypair, &sender, false) | |
| .await | |
| .unwrap(); | |
| mint_spl_tokens( | |
| &mut rpc, | |
| &mint, | |
| &spl_token_account_keypair.pubkey(), | |
| &payer.pubkey(), | |
| &payer, | |
| amount, | |
| false, | |
| ) | |
| .await | |
| .unwrap(); | |
| // Create SPL token account and mint tokens | |
| let spl_token_account_keypair = Keypair::new(); | |
| create_token_2022_account(&mut rpc, &mint, &spl_token_account_keypair, &sender, false) | |
| .await | |
| .unwrap(); | |
| mint_spl_tokens( | |
| &mut rpc, | |
| &mint, | |
| &spl_token_account_keypair.pubkey(), | |
| &sender.pubkey(), | |
| &payer, | |
| amount, | |
| false, | |
| ) | |
| .await | |
| .unwrap(); |
🤖 Prompt for AI Agents
In program-tests/compressed-token-test/tests/transfer2/spl_ctoken.rs around
lines 28 to 43, the SPL token account was created with sender as the owner but
mint_spl_tokens is called with payer.pubkey() as the token_owner; change the
token_owner argument in the mint_spl_tokens call to sender.pubkey() so the mint
operation uses the actual account owner and removes the mismatch.
| result, | ||
| 0, | ||
| anchor_lang::error::ErrorCode::ConstraintSeeds.into(), | ||
| result, 0, 21, //anchor_lang::error::ErrorCode::ConstraintSeeds.into(), |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Replace magic number with semantic error constant.
Using the hard-coded error code 21 reduces test readability and maintainability. If this represents the new OneEpochPrefundingNotAllowed error mentioned in the PR, consider defining and using a semantic constant.
- result, 0, 21, //anchor_lang::error::ErrorCode::ConstraintSeeds.into(),
+ result, 0, ErrorCode::OneEpochPrefundingNotAllowed.into(),If ErrorCode::OneEpochPrefundingNotAllowed is not accessible in this test file's scope, import it or define a test constant like ONE_EPOCH_PREFUNDING_NOT_ALLOWED_ERROR_CODE at the module level with a clear comment explaining its value.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| result, 0, 21, //anchor_lang::error::ErrorCode::ConstraintSeeds.into(), | |
| // … previous lines … | |
| result, 0, ErrorCode::OneEpochPrefundingNotAllowed.into(), | |
| // … following lines … |
🤖 Prompt for AI Agents
In program-tests/compressed-token-test/tests/v1.rs around line 1174, replace the
hard-coded magic number 21 with a semantic error constant (e.g.,
ErrorCode::OneEpochPrefundingNotAllowed.into() or a test-level constant
ONE_EPOCH_PREFUNDING_NOT_ALLOWED_ERROR_CODE) to improve readability; if the enum
variant isn't in scope, import the ErrorCode enum or add a module-level const
with a comment clarifying it equals 21, then use that constant in the assertion.
| result, 0, | ||
| 21, // Panic AccountCompressionErrorCode::AddressMerkleTreeAccountDiscriminatorMismatch.into(), |
There was a problem hiding this comment.
Inconsistent error handling approach and unclear comment.
This change directly expects error code 21 (panic), while program-tests/system-test/tests/test.rs (lines 862-868) uses a fallback mechanism that tries the specific error first, then falls back to error code 21. This inconsistency suggests:
- Different failure modes: Are these two cases failing differently, or should they use the same pattern?
- Unclear intent: The comment "Panic AccountCompressionErrorCode::AddressMerkleTreeAccountDiscriminatorMismatch.into()" is ambiguous - does it mean "this panics instead of returning AddressMerkleTreeAccountDiscriminatorMismatch" or "this is a panic case related to AddressMerkleTreeAccountDiscriminatorMismatch"?
Recommendations:
- Use the same fallback pattern as in
program-tests/system-test/tests/test.rsfor consistency:
assert_rpc_error(
- result, 0,
- 21, // Panic AccountCompressionErrorCode::AddressMerkleTreeAccountDiscriminatorMismatch.into(),
+ result.clone(),
+ 0,
+ AccountCompressionErrorCode::AddressMerkleTreeAccountDiscriminatorMismatch.into(),
)
+ .or_else(|_| {
+ // Fallback: program panics instead of returning specific error code
+ assert_rpc_error(result, 0, 21)
+ })
.unwrap();- If panic is always expected here (not a fallback), clarify the comment:
assert_rpc_error(
result, 0,
- 21, // Panic AccountCompressionErrorCode::AddressMerkleTreeAccountDiscriminatorMismatch.into(),
+ 21, // Program panics with invalid batch tree account instead of returning
+ // AccountCompressionErrorCode::AddressMerkleTreeAccountDiscriminatorMismatch
)
.unwrap();- Investigate why this specific test case always panics while others (in system-test) require a fallback. Document the findings.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In program-tests/system-cpi-test/tests/test.rs around lines 911-912 the test
unconditionally expects error code 21 (a panic) and leaves an ambiguous comment
about
AccountCompressionErrorCode::AddressMerkleTreeAccountDiscriminatorMismatch;
change this to the same two-step fallback pattern used in
program-tests/system-test/tests/test.rs (try to match the specific
AccountCompressionErrorCode::AddressMerkleTreeAccountDiscriminatorMismatch error
first, and if that fails, assert error code 21), replace the ambiguous inline
comment with a clear comment stating "expect specific
AddressMerkleTreeAccountDiscriminatorMismatch or panic fallback (code 21)" and
add a short TODO to investigate and document why this case panics here while the
system-test uses a fallback.
| if assert_rpc_error(result.clone(), 0, expected_error_code).is_err() { | ||
| // In case program panics instead of returning an error code. | ||
| // This can happen if proof verification fails and debug print runs oom. | ||
| assert_rpc_error(result, 0, 21) | ||
| } else { | ||
| Ok(()) | ||
| } |
There was a problem hiding this comment.
Fallback to generic panic error weakens test precision.
Accepting error code 21 (ProgramFailedToComplete) as a fallback makes this test less strict and could mask regressions. When proof verification fails, the test should ideally verify the specific failure mode rather than accepting any panic.
Consider one of these approaches:
- Fix the root cause: If debug printing causes OOM during proof verification, increase memory limits or reduce debug output rather than accepting panics.
- Make the fallback explicit: If panic is the expected behavior for certain inputs, document which test scenarios require this fallback and why.
- Add validation: Before falling back to error 21, verify that the failure truly occurred during proof verification (e.g., by checking transaction logs).
Apply this diff to add a clear comment documenting when the fallback is expected:
let result = rpc
.create_and_send_transaction(&[instruction], &payer.pubkey(), &[payer])
.await;
- if assert_rpc_error(result.clone(), 0, expected_error_code).is_err() {
- // In case program panics instead of returning an error code.
- // This can happen if proof verification fails and debug print runs oom.
- assert_rpc_error(result, 0, 21)
- } else {
- Ok(())
- }
+ // Primary assertion: verify the expected error code
+ if assert_rpc_error(result.clone(), 0, expected_error_code).is_err() {
+ // Fallback: In production, proof verification failures may panic (error code 21)
+ // instead of returning a specific error code when debug assertions run OOM.
+ // TODO: Investigate if memory limits can be increased to avoid this fallback.
+ assert_rpc_error(result, 0, 21)
+ } else {
+ Ok(())
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if assert_rpc_error(result.clone(), 0, expected_error_code).is_err() { | |
| // In case program panics instead of returning an error code. | |
| // This can happen if proof verification fails and debug print runs oom. | |
| assert_rpc_error(result, 0, 21) | |
| } else { | |
| Ok(()) | |
| } | |
| // Primary assertion: verify the expected error code | |
| if assert_rpc_error(result.clone(), 0, expected_error_code).is_err() { | |
| // Fallback: In production, proof verification failures may panic (error code 21) | |
| // instead of returning a specific error code when debug assertions run OOM. | |
| // TODO: Investigate if memory limits can be increased to avoid this fallback. | |
| assert_rpc_error(result, 0, 21) | |
| } else { | |
| Ok(()) | |
| } |
| // For non-compressible accounts, authority balance check depends on if they're also the destination | ||
| if authority_pubkey == destination { | ||
| // Authority is the destination, they receive the lamports | ||
| assert_eq!( | ||
| final_authority_lamports, | ||
| initial_authority_lamports + account_lamports_before_close, | ||
| "Authority (as destination) should receive all {} lamports for non-compressible account closure", | ||
| account_lamports_before_close | ||
| ); | ||
| } else { | ||
| // Authority is not the destination, shouldn't receive anything | ||
| assert_eq!( | ||
| final_authority_lamports, initial_authority_lamports, | ||
| "Authority (not destination) should not receive any lamports for non-compressible account closure" | ||
| ); | ||
| } |
There was a problem hiding this comment.
Missing transaction fee adjustment for non-compressible accounts.
The authority balance checks do not account for transaction fees when the authority is also the payer. This is inconsistent with the compressible account path (lines 312-317, 326-331), which correctly adjusts for tx_fee when authority_pubkey == payer_pubkey.
Apply this diff to add tx_fee handling:
// For non-compressible accounts, authority balance check depends on if they're also the destination
if authority_pubkey == destination {
// Authority is the destination, they receive the lamports
+ let expected_authority_lamports = if authority_pubkey == payer_pubkey {
+ initial_authority_lamports + account_lamports_before_close - tx_fee
+ } else {
+ initial_authority_lamports + account_lamports_before_close
+ };
+
assert_eq!(
- final_authority_lamports,
- initial_authority_lamports + account_lamports_before_close,
+ final_authority_lamports, expected_authority_lamports,
"Authority (as destination) should receive all {} lamports for non-compressible account closure",
account_lamports_before_close
);
} else {
// Authority is not the destination, shouldn't receive anything
+ let expected_authority_lamports = if authority_pubkey == payer_pubkey {
+ initial_authority_lamports - tx_fee
+ } else {
+ initial_authority_lamports
+ };
+
assert_eq!(
- final_authority_lamports, initial_authority_lamports,
+ final_authority_lamports, expected_authority_lamports,
"Authority (not destination) should not receive any lamports for non-compressible account closure"
);
}🤖 Prompt for AI Agents
In program-tests/utils/src/assert_close_token_account.rs around lines 89 to 104,
the authority balance assertions for non-compressible account closure don't
account for transaction fees when the authority is also the payer; update the
branch where authority_pubkey == destination to subtract tx_fee from the
expected final_authority_lamports if authority_pubkey == payer_pubkey (i.e.,
expected = initial_authority_lamports + account_lamports_before_close - tx_fee),
and ensure the other branch (authority not destination) similarly subtracts
tx_fee from the expected balance when authority_pubkey == payer_pubkey (i.e.,
expected = initial_authority_lamports - tx_fee); follow the same tx_fee
conditional pattern used in the compressible account checks at lines ~312-331.
| process_transfer(accounts, instruction_data) | ||
| .map_err(|e| ProgramError::Custom(u64::from(e) as u32))?; | ||
|
|
||
| msg!("CToken transfer: transfer processed"); |
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (4)
program-tests/registry-test/tests/compressible.rs (2)
151-156: Fix comment to match epoch rangeComment still says “1 to 10” while the loop actually iterates
2..=11. Please sync the comment with the code.- // Create 10 token accounts with varying prepaid epochs (1 to 10) + // Create 10 token accounts with varying prepaid epochs (2 to 11)
185-186: Align warp comment with actual epoch countThe comment claims we warp 10 epochs, but the call is
warp_epoch_forward(11). Update the comment so it reflects the 11-epoch warp.- // Warp forward 10 epochs using the new wrapper method + // Warp forward 11 epochs using the new wrapper methodprogram-tests/compressed-token-test/tests/ctoken/shared.rs (1)
103-105: Wire compress_to_pubkey into create instructionSet compress_to_account_pubkey to Some(token_account_pubkey) when compressible_data.compress_to_pubkey is true.
- payer: payer_pubkey, - compress_to_account_pubkey: None, + payer: payer_pubkey, + compress_to_account_pubkey: if compressible_data.compress_to_pubkey { + Some(token_account_pubkey) + } else { + None + }, token_account_version: compressible_data.account_version,Also applies to: 155-157
program-tests/compressed-token-test/tests/ctoken/transfer.rs (1)
118-122: Pass the real system program ID, not Pubkey::default()Using Pubkey::default() will make any CPI to system program fail (IncorrectProgramId) during top-ups. Replace with the real system program id.
- AccountMeta::new_readonly(Pubkey::default(), false), // System program for lamport transfers during top-up + AccountMeta::new_readonly(solana_sdk::system_program::ID, false), // System program for lamport transfers during top-up
🧹 Nitpick comments (9)
program-tests/utils/src/assert_create_token_account.rs (1)
142-145: Consider extracting hardcoded fee values to named constants.The transaction fees (5,000 and 10,000 lamports) are hardcoded. For better maintainability and clarity, consider extracting these to named constants.
+const TX_FEE_PER_SIGNATURE: u64 = 5_000; + // Transaction fee: 5000 lamports per signature // For ATA: 1 signer (payer only) = 5,000 lamports // For regular token account: 2 signers (token_account_keypair + payer) = 10,000 lamports -let tx_fee = if is_ata { 5_000 } else { 10_000 }; +let num_signers = if is_ata { 1 } else { 2 }; +let tx_fee = TX_FEE_PER_SIGNATURE * num_signers;programs/compressed-token/program/tests/multi_sum_check.rs (1)
120-130: Trim iteration/log noise to speed CI (optional).3000 scenarios with printlns can slow CI. Consider reducing to ~500 and remove prints except on failure.
program-tests/compressed-token-test/tests/ctoken/compress_and_close.rs (2)
237-245: Use consistent output queue accessor.Elsewhere you use get_output_pubkey(); here you use .queue. Prefer a single accessor to avoid API drift:
- let output_queue = context.rpc.get_random_state_tree_info().unwrap().queue; + let output_queue = context + .rpc + .get_random_state_tree_info() + .unwrap() + .get_output_pubkey() + .unwrap();Also applies to: 348-356
457-511: Rename var and fix comment: this is payer balance, not pool PDA.The variable tracks payer balance. Rename and update message for clarity:
- let pool_balance_before = context + let payer_balance_before = context .rpc .get_account(payer_pubkey) .await .unwrap() .expect("Pool PDA should exist") .lamports; @@ - assert_eq!( - pool_balance_before - payer_balance_after, + assert_eq!( + payer_balance_before - payer_balance_after, rent_exemption + rent + tx_fee, - "Pool PDA should have paid {} lamports for account creation (rent-exempt), and the additional rent", + "Payer should have paid {} lamports for account creation (rent-exempt) and the additional rent", rent_exemption );program-tests/compressed-token-test/tests/ctoken/create.rs (1)
32-47: Comment nit: label says “Three epoch” but uses 2.Update the test label to avoid confusion.
- // Test 2: Three epoch prefunding + // Test 2: Two epoch prefundingsdk-libs/compressed-token-sdk/src/instructions/create_token_account/instruction.rs (1)
29-31: Add doc hint for allowedpre_pay_num_epochsvalues- /// Number of epochs of rent to prepay + /// Number of epochs of rent to prepay (0 or ≥ 2; 1 is rejected on-chain) pub pre_pay_num_epochs: u8,Optional: implement an SDK-level check to reject
1early (negative tests that set1will need updating).program-tests/compressed-token-test/tests/ctoken/transfer.rs (2)
307-312: Avoid hardcoded byte offsets for freezing; use the SPL Account structDirectly mutating data[108] is brittle. Unpack, set state to Frozen, and repack via spl_token_2022::state::Account for stability across versions.
Also applies to: 336-340
110-113: Prefer a named constant or SDK builder for the discriminatorHardcoding 3 is error-prone. If available, use a constant or the SDK’s instruction builder to construct the transfer payload.
programs/compressed-token/program/src/transfer2/sum_check.rs (1)
137-140: Don’t conflate “missing mint account” with DuplicateMintMapping a missing packed mint account to DuplicateMint is misleading. Prefer a sum-check/validation error (e.g., SumCheckFailed or a specific MissingMint/InvalidMintIndex variant if available).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (25)
program-libs/compressible/docs/RENT.md(2 hunks)program-libs/compressible/src/compression_info.rs(1 hunks)program-libs/compressible/tests/compression_info.rs(1 hunks)program-libs/compressible/tests/rent.rs(3 hunks)program-libs/ctoken-types/src/instructions/extensions/compressible.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/compress_and_close.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/create.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/create_ata.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/shared.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/transfer.rs(1 hunks)program-tests/registry-test/tests/compressible.rs(29 hunks)program-tests/utils/src/assert_create_token_account.rs(4 hunks)program-tests/utils/src/assert_ctoken_transfer.rs(1 hunks)programs/compressed-token/anchor/src/lib.rs(1 hunks)programs/compressed-token/program/Cargo.toml(1 hunks)programs/compressed-token/program/docs/instructions/TRANSFER2.md(2 hunks)programs/compressed-token/program/src/create_associated_token_account.rs(2 hunks)programs/compressed-token/program/src/create_token_account.rs(3 hunks)programs/compressed-token/program/src/ctoken_transfer.rs(2 hunks)programs/compressed-token/program/src/transfer2/processor.rs(5 hunks)programs/compressed-token/program/src/transfer2/sum_check.rs(5 hunks)programs/compressed-token/program/tests/multi_sum_check.rs(3 hunks)sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs(2 hunks)sdk-libs/compressed-token-sdk/src/instructions/create_token_account/instruction.rs(1 hunks)sdk-libs/token-client/src/actions/create_compressible_token_account.rs(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- program-libs/compressible/docs/RENT.md
🚧 Files skipped from review as they are similar to previous changes (5)
- programs/compressed-token/anchor/src/lib.rs
- programs/compressed-token/program/src/create_associated_token_account.rs
- program-libs/compressible/tests/compression_info.rs
- program-tests/compressed-token-test/tests/ctoken/create_ata.rs
- program-libs/compressible/tests/rent.rs
🧰 Additional context used
📓 Path-based instructions (6)
programs/compressed-token/program/src/ctoken_transfer.rs
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
CTokenTransfer must perform SPL-compatible transfers between decompressed accounts
Files:
programs/compressed-token/program/src/ctoken_transfer.rs
programs/compressed-token/program/src/**/*.rs
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Return errors as ProgramError::Custom(error_code as u32) on-chain
Files:
programs/compressed-token/program/src/ctoken_transfer.rsprograms/compressed-token/program/src/transfer2/sum_check.rsprograms/compressed-token/program/src/transfer2/processor.rsprograms/compressed-token/program/src/create_token_account.rs
programs/compressed-token/program/src/transfer2/**
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Transfer2 must support Compress, Decompress, and CompressAndClose modes and perform multi-mint sum checks
Files:
programs/compressed-token/program/src/transfer2/sum_check.rsprograms/compressed-token/program/src/transfer2/processor.rs
programs/compressed-token/program/docs/instructions/*.md
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Each instruction doc must include: path, description, instruction_data (code paths), Accounts (order and checks), instruction logic and checks, and Errors (with causes)
Files:
programs/compressed-token/program/docs/instructions/TRANSFER2.md
programs/compressed-token/program/docs/**/instructions/**/*.md
📄 CodeRabbit inference engine (programs/compressed-token/program/docs/CLAUDE.md)
Keep detailed instruction documentation files under the instructions/ directory; add additional instruction docs as needed
Files:
programs/compressed-token/program/docs/instructions/TRANSFER2.md
programs/compressed-token/program/src/{create_token_account.rs,create_associated_token_account.rs}
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Enforce ACTIVE-only config validation for Create CToken Account and Create Associated CToken Account instructions
Files:
programs/compressed-token/program/src/create_token_account.rs
🧠 Learnings (26)
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/ctoken_transfer.rs : CTokenTransfer must perform SPL-compatible transfers between decompressed accounts
Applied to files:
programs/compressed-token/program/src/ctoken_transfer.rsprograms/compressed-token/program/docs/instructions/TRANSFER2.mdprogram-tests/utils/src/assert_create_token_account.rsprograms/compressed-token/program/src/transfer2/processor.rsprograms/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/tests/multi_sum_check.rsprogram-tests/utils/src/assert_ctoken_transfer.rsprogram-tests/compressed-token-test/tests/ctoken/transfer.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/close_token_account{.rs,/**} : On closing ctoken accounts: if compressible, return rent exemption to the rent recipient; send remaining lamports to the destination
Applied to files:
programs/compressed-token/program/src/ctoken_transfer.rssdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rsprogram-tests/compressed-token-test/tests/ctoken/compress_and_close.rsprogram-libs/compressible/src/compression_info.rsprograms/compressed-token/program/docs/instructions/TRANSFER2.mdprogram-tests/utils/src/assert_create_token_account.rsprograms/compressed-token/program/src/transfer2/processor.rsprograms/compressed-token/program/src/create_token_account.rsprogram-tests/utils/src/assert_ctoken_transfer.rsprogram-tests/compressed-token-test/tests/ctoken/shared.rsprogram-tests/registry-test/tests/compressible.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/DECOMPRESSED_TRANSFER.md : Document SPL-compatible transfers between decompressed accounts in instructions/DECOMPRESSED_TRANSFER.md
Applied to files:
programs/compressed-token/program/src/ctoken_transfer.rsprograms/compressed-token/program/docs/instructions/TRANSFER2.mdprogram-tests/compressed-token-test/tests/ctoken/transfer.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Refactor rent logic so that 1 lamport is the minimum rent payment
Applied to files:
program-libs/ctoken-types/src/instructions/extensions/compressible.rsprogram-libs/compressible/src/compression_info.rsprogram-tests/utils/src/assert_create_token_account.rssdk-libs/compressed-token-sdk/src/instructions/create_token_account/instruction.rsprograms/compressed-token/program/src/create_token_account.rsprogram-tests/utils/src/assert_ctoken_transfer.rsprogram-tests/registry-test/tests/compressible.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Determine compressibility and compute rent using calculate_rent_and_balance
Applied to files:
program-libs/ctoken-types/src/instructions/extensions/compressible.rsprogram-libs/compressible/src/compression_info.rsprogram-tests/utils/src/assert_create_token_account.rsprograms/compressed-token/program/src/create_token_account.rsprogram-tests/utils/src/assert_ctoken_transfer.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/{create_token_account.rs,create_associated_token_account.rs} : Enforce ACTIVE-only config validation for Create CToken Account and Create Associated CToken Account instructions
Applied to files:
sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rsprogram-tests/utils/src/assert_create_token_account.rsprograms/compressed-token/program/src/transfer2/processor.rsprograms/compressed-token/program/src/create_token_account.rsprogram-tests/compressed-token-test/tests/ctoken/create.rsprograms/compressed-token/program/tests/multi_sum_check.rsprogram-tests/compressed-token-test/tests/ctoken/shared.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Document closing decompressed token accounts with rent distribution in instructions/CLOSE_TOKEN_ACCOUNT.md
Applied to files:
program-tests/compressed-token-test/tests/ctoken/compress_and_close.rsprograms/compressed-token/program/docs/instructions/TRANSFER2.mdprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/config.rs : Update config parameters including max write fee and max funded epoch
Applied to files:
program-libs/compressible/src/compression_info.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Expose claimable rent computation via claimable_lamports
Applied to files:
program-libs/compressible/src/compression_info.rsprogram-tests/utils/src/assert_create_token_account.rsprograms/compressed-token/program/src/create_token_account.rsprogram-tests/utils/src/assert_ctoken_transfer.rsprogram-tests/registry-test/tests/compressible.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Update RentConfig values at claim time to reflect current policy
Applied to files:
program-libs/compressible/src/compression_info.rsprogram-tests/utils/src/assert_create_token_account.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Implement rent curve algorithms via rent_curve_per_epoch
Applied to files:
program-libs/compressible/src/compression_info.rsprogram-tests/utils/src/assert_create_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/docs/RENT.md : Document rent calculation functions and compressibility checks in docs/RENT.md
Applied to files:
program-libs/compressible/src/compression_info.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Compute close lamport distribution with calculate_close_lamports
Applied to files:
program-libs/compressible/src/compression_info.rsprogram-tests/utils/src/assert_create_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/transfer2/** : Transfer2 must support Compress, Decompress, and CompressAndClose modes and perform multi-mint sum checks
Applied to files:
programs/compressed-token/program/src/transfer2/sum_check.rsprograms/compressed-token/program/docs/instructions/TRANSFER2.mdprograms/compressed-token/program/src/transfer2/processor.rsprograms/compressed-token/program/tests/multi_sum_check.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/TRANSFER2.md : Document the batch transfer instruction supporting compressed/decompressed operations in instructions/TRANSFER2.md
Applied to files:
programs/compressed-token/program/docs/instructions/TRANSFER2.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/MINT_ACTION.md : Document Mint operations and compressed mint management (9 actions) in instructions/MINT_ACTION.md
Applied to files:
programs/compressed-token/program/docs/instructions/TRANSFER2.md
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/programs/compressed-token/anchor/src/lib.rs : Define all program-specific error codes in anchor_compressed_token::ErrorCode and expose them for program-wide use
Applied to files:
programs/compressed-token/program/docs/instructions/TRANSFER2.mdprograms/compressed-token/program/src/transfer2/processor.rsprograms/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/tests/multi_sum_check.rsprogram-tests/registry-test/tests/compressible.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/error.rs : Provide ProgramError conversions compatible with Anchor, Pinocchio, and Solana error types
Applied to files:
programs/compressed-token/program/src/transfer2/processor.rsprograms/compressed-token/program/tests/multi_sum_check.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/**/*.rs : Return errors as ProgramError::Custom(error_code as u32) on-chain
Applied to files:
programs/compressed-token/program/src/transfer2/processor.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/config.rs : Implement CompressibleConfig account with Anchor, Borsh, and Pod serialization for Light Registry integration
Applied to files:
programs/compressed-token/program/src/transfer2/processor.rsprograms/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/tests/multi_sum_check.rsprogram-tests/registry-test/tests/compressible.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: CToken account layout matches SPL token accounts with a custom Compressible extension; compressed mint accounts support the TokenMetadata extension
Applied to files:
programs/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLAIM.md : Document rent reclamation from expired compressible accounts in instructions/CLAIM.md
Applied to files:
programs/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CREATE_TOKEN_ACCOUNT.md : Document Create Token Account & Associated Token Account instructions in instructions/CREATE_TOKEN_ACCOUNT.md
Applied to files:
programs/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:45:40.029Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.029Z
Learning: Applies to programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md : Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions
Applied to files:
program-tests/compressed-token-test/tests/ctoken/create.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/checks.rs : Expose and maintain account validation helpers (check_owner, check_program, check_mut/non_mut, check_signer, check_discriminator, set_discriminator, check_pda_seeds, check_account_balance_is_rent_exempt, account_info_init) in checks.rs
Applied to files:
programs/compressed-token/program/tests/multi_sum_check.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Gate SDK-specific implementations with #[cfg(feature = "solana"|"pinocchio"|"test-only")]
Applied to files:
programs/compressed-token/program/tests/multi_sum_check.rs
🧬 Code graph analysis (8)
program-tests/compressed-token-test/tests/ctoken/compress_and_close.rs (2)
program-tests/compressed-token-test/tests/ctoken/shared.rs (5)
compress_and_close_owner_and_assert(587-662)create_non_compressible_token_account(210-278)create_and_assert_ata(400-461)compress_and_close_and_assert_fails(672-729)compress_and_close_forester_with_invalid_output(750-902)sdk-libs/token-client/src/instructions/transfer2.rs (1)
create_generic_transfer2_instruction(145-640)
program-tests/utils/src/assert_create_token_account.rs (1)
sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs (1)
derive_ctoken_ata(226-235)
programs/compressed-token/program/src/transfer2/processor.rs (1)
programs/compressed-token/program/src/transfer2/sum_check.rs (3)
sum_check_multi_mint(92-121)sum_compressions(34-63)validate_mint_uniqueness(127-161)
program-tests/compressed-token-test/tests/ctoken/create.rs (3)
program-tests/compressed-token-test/tests/ctoken/shared.rs (3)
setup_account_test(40-63)create_and_assert_token_account(82-127)create_and_assert_token_account_fails(130-172)sdk-libs/compressed-token-sdk/src/instructions/create_token_account/instruction.rs (1)
create_compressible_token_account(38-88)sdk-libs/program-test/src/utils/assert.rs (1)
assert_rpc_error(7-144)
programs/compressed-token/program/tests/multi_sum_check.rs (1)
programs/compressed-token/program/src/transfer2/sum_check.rs (2)
sum_check_multi_mint(92-121)validate_mint_uniqueness(127-161)
program-tests/compressed-token-test/tests/ctoken/shared.rs (8)
sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs (5)
create_associated_token_account(98-104)derive_ctoken_ata(226-235)create_compressible_associated_token_account_idempotent(48-52)create_compressible_associated_token_account(41-45)create_associated_token_account_idempotent(107-113)sdk-libs/compressed-token-sdk/src/instructions/create_token_account/instruction.rs (2)
create_token_account(90-116)create_compressible_token_account(38-88)program-tests/utils/src/assert_close_token_account.rs (1)
assert_close_token_account(8-106)program-tests/utils/src/assert_create_token_account.rs (2)
assert_create_token_account(236-252)assert_create_associated_token_account(258-291)sdk-libs/program-test/src/compressible.rs (1)
new(44-64)sdk-libs/token-client/src/actions/create_compressible_token_account.rs (1)
create_compressible_token_account(29-95)sdk-libs/token-client/src/instructions/transfer2.rs (1)
create_generic_transfer2_instruction(145-640)programs/registry/src/utils.rs (1)
get_forester_epoch_pda_from_authority(13-16)
program-tests/compressed-token-test/tests/ctoken/transfer.rs (3)
program-tests/compressed-token-test/tests/ctoken/shared.rs (3)
setup_account_test(40-63)create_and_assert_token_account(82-127)create_non_compressible_token_account(210-278)program-tests/utils/src/assert_ctoken_transfer.rs (1)
assert_ctoken_transfer(150-201)sdk-libs/program-test/src/utils/assert.rs (1)
assert_rpc_error(7-144)
program-tests/registry-test/tests/compressible.rs (2)
program-tests/utils/src/spl.rs (1)
create_mint_helper(260-263)sdk-libs/program-test/src/utils/assert.rs (1)
assert_rpc_error(7-144)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
- GitHub Check: cli-v1
- GitHub Check: Test program-libs-slow
- GitHub Check: Test batched-merkle-tree-simulate
- GitHub Check: Test program-libs-fast
- GitHub Check: programs (light-system-program-address, ["cargo-test-sbf -p system-test -- test_with_address"])
- GitHub Check: programs (system-cpi-test-v2-functional-account-infos, ["cargo-test-sbf -p system-cpi-v2-test -- ...
- GitHub Check: stateless-js-v2
- GitHub Check: programs (system-cpi-test-v2-functional-read-only, ["cargo-test-sbf -p system-cpi-v2-test -- func...
- GitHub Check: programs (light-system-program-compression, ["cargo-test-sbf -p system-test -- test_with_compress...
- GitHub Check: programs (compressed-token-batched-tree, ["cargo-test-sbf -p compressed-token-test -- test_transf...
- GitHub Check: programs (system-cpi-test, ["cargo-test-sbf -p system-cpi-test", "cargo test -p light-system-prog...
- GitHub Check: programs (account-compression-and-registry, ["cargo-test-sbf -p account-compression-test", "cargo...
- GitHub Check: programs (compressed-token-and-e2e, ["cargo-test-sbf -p compressed-token-test -- --skip test_tran...
- GitHub Check: lint
- GitHub Check: system-programs (sdk-anchor-test-program, ["cargo-test-sbf -p sdk-anchor-test", "cargo-test-sbf -...
- GitHub Check: system-programs (sdk-test-program, ["cargo-test-sbf -p sdk-native-test", "cargo-test-sbf -p sdk-v...
- GitHub Check: system-programs (sdk-token-test-program, ["cargo-test-sbf -p sdk-token-test"])
- GitHub Check: system-programs (sdk-libs, light-sdk-macros light-sdk light-program-test light-client light-compr...
- GitHub Check: cli-v2
- GitHub Check: stateless-js-v1
- GitHub Check: Forester e2e test
🔇 Additional comments (19)
programs/compressed-token/program/src/create_token_account.rs (1)
165-168: Clear guard against 1-epoch prefundingNice job adding the explicit check and error to stop the 1-epoch footgun while preserving the informative log message. Fully aligned with the associated ATA flow.
program-tests/utils/src/assert_create_token_account.rs (7)
29-48: LGTM! Well-structured function signature and validation.The addition of the
is_ataparameter to distinguish between ATA (1 signer) and regular token accounts (2 signers) is a good design choice that enables more accurate fee validation. The basic account validation is correct.
63-110: LGTM! Compressible account validation is thorough and correct.The rent calculation, lamports balance verification, and zero-copy deserialization are all properly implemented. The type casts (u8→u64 at line 65, bool→u8 at line 103) are appropriate conversions for the underlying data structures.
112-158: Excellent idempotent mode handling!The detection of existing accounts via
get_pre_transaction_accountand the special handling to only validate transaction fees in idempotent mode is well-designed and prevents false positives when accounts are created idempotently.
160-194: LGTM! Fee handling logic is precise and well-documented.The distinction between custom fee payer (where payer pays everything) and split payment scenarios (where rent sponsor pays rent exemption and payer pays compression cost + tx fee) is correctly implemented with comprehensive assertions and clear error messages.
234-252: LGTM! Clean public API wrapper.The separation of the public API wrapper from the internal implementation provides good encapsulation and makes the distinction between ATA and regular token accounts clear to callers.
254-291: LGTM! ATA wrapper with helpful validation.The explicit existence check at lines 267-279 provides clear, contextual error messages when the ATA doesn't exist at the derived address, improving the debugging experience. The wrapper correctly derives the ATA address and delegates to the internal function.
17-17: Verify u8 limit for num_prepaid_epochs
Ensure narrowing fromu64tou8(0–255) covers all current and future use cases; confirm no scenario requires more than 255 prepaid epochs.programs/compressed-token/program/src/ctoken_transfer.rs (2)
23-34: Guarding SPL transfer preconditions looks solid.
process_transferalways expects source, destination, and authority; failing fast withNotEnoughAccountKeyskeeps us SPL-compatible and avoids later panics.
75-82: Thanks for removing the hard-coded rent exemption.Routing through
COMPRESSIBLE_TOKEN_RENT_EXEMPTIONkeeps this logic aligned with the shared rent policy and resolves the prior duplication.sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs (1)
32-33: Type change keeps client and instruction in sync.Limiting
pre_pay_num_epochstou8mirrors the on-chain struct and blocks accidental oversized prefunding requests.programs/compressed-token/program/docs/instructions/TRANSFER2.md (1)
275-307: Error matrix update is comprehensive.Documenting
DuplicateMintalongside the existing sum-check failures keeps operators aligned with the new invariant.program-libs/ctoken-types/src/instructions/extensions/compressible.rs (1)
18-23: rent_payment downcast matches new validation limits.Switching to
u8aligns serialization with the SDK and enforces the max-epoch policy directly in the instruction payload.program-libs/compressible/src/compression_info.rs (1)
113-125: Switching to available_balance clarifies the funding window.Deriving
epochs_funded_aheadfromget_available_rent_balancemirrors the rent helpers and should prevent the negative-balance edge cases we saw with the previous heuristic.program-tests/utils/src/assert_ctoken_transfer.rs (1)
105-127: Test now mirrors the on-chain top-up inputs.Using the pre-transfer lamports together with
COMPRESSIBLE_TOKEN_RENT_EXEMPTIONmakes the assertion matchcalculate_and_execute_top_up_transfers, so any drift will surface immediately.programs/compressed-token/program/src/transfer2/processor.rs (1)
191-197: Nice: multi‑mint sum check integrated pre‑CPI with mint_map.Returning the mint_map and following with a uniqueness check aligns with Transfer2 requirements.
programs/compressed-token/program/tests/multi_sum_check.rs (1)
382-421: Good coverage for duplicate mint index scenarios.Validates allowed same-index aggregation across inputs/compressions and different mints. LGTM.
programs/compressed-token/program/src/transfer2/sum_check.rs (1)
92-121: On-chain error mapping is correctly implemented
Errors returned asErrorCodeby sum checks are mapped toProgramError::Custom(e as u32 + 6000)inprograms/compressed-token/program/src/transfer2/processor.rs.program-tests/compressed-token-test/tests/ctoken/transfer.rs (1)
187-205: Review comment is incorrect—assert_ctoken_transfer tolerates non-compressible accounts.The helper only validates compressible extensions if they existed before the transfer (lines 57–83). For non-compressible accounts without extensions, the validation block is skipped and the function returns successfully. The test will not encounter false failures.
| // Error: 1 (InsufficientFunds from system program) | ||
| { | ||
| // Create a payer with insufficient funds (only enough for tx fees + account creation) | ||
| let poor_payer = Keypair::new(); | ||
| context | ||
| .rpc | ||
| .airdrop_lamports(&poor_payer.pubkey(), 10000) // Not enough for additional rent | ||
| .await | ||
| .unwrap(); | ||
|
|
||
| let poor_payer_pubkey = poor_payer.pubkey(); | ||
| let token_account_pubkey = Keypair::new(); | ||
|
|
||
| let create_token_account_ix = | ||
| light_compressed_token_sdk::instructions::create_compressible_token_account( | ||
| light_compressed_token_sdk::instructions::CreateCompressibleTokenAccount { | ||
| account_pubkey: token_account_pubkey.pubkey(), | ||
| mint_pubkey: context.mint_pubkey, | ||
| owner_pubkey: context.owner_keypair.pubkey(), | ||
| compressible_config: context.compressible_config, | ||
| rent_sponsor: context.rent_sponsor, | ||
| pre_pay_num_epochs: 10, // High number to require more lamports | ||
| lamports_per_write: Some(1000), | ||
| payer: poor_payer_pubkey, | ||
| compress_to_account_pubkey: None, | ||
| token_account_version: light_ctoken_types::state::TokenDataVersion::ShaFlat, | ||
| }, | ||
| ) | ||
| .unwrap(); | ||
|
|
||
| let result = context | ||
| .rpc | ||
| .create_and_send_transaction( | ||
| &[create_token_account_ix], | ||
| &poor_payer_pubkey, | ||
| &[&poor_payer, &token_account_pubkey], | ||
| ) | ||
| .await; | ||
|
|
||
| // Should fail with InsufficientFunds (1) from system program | ||
| light_program_test::utils::assert::assert_rpc_error(result, 0, 1).unwrap(); | ||
| } |
There was a problem hiding this comment.
Fix expected error code for InsufficientFunds (should be 6).
Solana InstructionError::InsufficientFunds is 6, not 1. Update comment and assertion:
- // Error: 1 (InsufficientFunds from system program)
+ // Error: 6 (InsufficientFunds from system program)
@@
- // Should fail with InsufficientFunds (1) from system program
- light_program_test::utils::assert::assert_rpc_error(result, 0, 1).unwrap();
+ // Should fail with InsufficientFunds (6) from system program
+ light_program_test::utils::assert::assert_rpc_error(result, 0, 6).unwrap();📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Error: 1 (InsufficientFunds from system program) | |
| { | |
| // Create a payer with insufficient funds (only enough for tx fees + account creation) | |
| let poor_payer = Keypair::new(); | |
| context | |
| .rpc | |
| .airdrop_lamports(&poor_payer.pubkey(), 10000) // Not enough for additional rent | |
| .await | |
| .unwrap(); | |
| let poor_payer_pubkey = poor_payer.pubkey(); | |
| let token_account_pubkey = Keypair::new(); | |
| let create_token_account_ix = | |
| light_compressed_token_sdk::instructions::create_compressible_token_account( | |
| light_compressed_token_sdk::instructions::CreateCompressibleTokenAccount { | |
| account_pubkey: token_account_pubkey.pubkey(), | |
| mint_pubkey: context.mint_pubkey, | |
| owner_pubkey: context.owner_keypair.pubkey(), | |
| compressible_config: context.compressible_config, | |
| rent_sponsor: context.rent_sponsor, | |
| pre_pay_num_epochs: 10, // High number to require more lamports | |
| lamports_per_write: Some(1000), | |
| payer: poor_payer_pubkey, | |
| compress_to_account_pubkey: None, | |
| token_account_version: light_ctoken_types::state::TokenDataVersion::ShaFlat, | |
| }, | |
| ) | |
| .unwrap(); | |
| let result = context | |
| .rpc | |
| .create_and_send_transaction( | |
| &[create_token_account_ix], | |
| &poor_payer_pubkey, | |
| &[&poor_payer, &token_account_pubkey], | |
| ) | |
| .await; | |
| // Should fail with InsufficientFunds (1) from system program | |
| light_program_test::utils::assert::assert_rpc_error(result, 0, 1).unwrap(); | |
| } | |
| // Error: 6 (InsufficientFunds from system program) | |
| { | |
| // Create a payer with insufficient funds (only enough for tx fees + account creation) | |
| let poor_payer = Keypair::new(); | |
| context | |
| .rpc | |
| .airdrop_lamports(&poor_payer.pubkey(), 10000) // Not enough for additional rent | |
| .await | |
| .unwrap(); | |
| let poor_payer_pubkey = poor_payer.pubkey(); | |
| let token_account_pubkey = Keypair::new(); | |
| let create_token_account_ix = | |
| light_compressed_token_sdk::instructions::create_compressible_token_account( | |
| light_compressed_token_sdk::instructions::CreateCompressibleTokenAccount { | |
| account_pubkey: token_account_pubkey.pubkey(), | |
| mint_pubkey: context.mint_pubkey, | |
| owner_pubkey: context.owner_keypair.pubkey(), | |
| compressible_config: context.compressible_config, | |
| rent_sponsor: context.rent_sponsor, | |
| pre_pay_num_epochs: 10, // High number to require more lamports | |
| lamports_per_write: Some(1000), | |
| payer: poor_payer_pubkey, | |
| compress_to_account_pubkey: None, | |
| token_account_version: light_ctoken_types::state::TokenDataVersion::ShaFlat, | |
| }, | |
| ) | |
| .unwrap(); | |
| let result = context | |
| .rpc | |
| .create_and_send_transaction( | |
| &[create_token_account_ix], | |
| &poor_payer_pubkey, | |
| &[&poor_payer, &token_account_pubkey], | |
| ) | |
| .await; | |
| // Should fail with InsufficientFunds (6) from system program | |
| light_program_test::utils::assert::assert_rpc_error(result, 0, 6).unwrap(); | |
| } |
🤖 Prompt for AI Agents
In program-tests/compressed-token-test/tests/ctoken/create.rs around lines 216
to 257, the test expects InsufficientFunds error code 1 but Solana's
InstructionError::InsufficientFunds is 6; update the inline comment to reflect
the correct code and change the assert_rpc_error call to expect 6 instead of 1
(i.e., replace the asserted error code value and update the comment text
accordingly).
| let mut mint_map: ArrayMap<u8, u64, 5> = ArrayMap::new(); | ||
| sum_compressions(compressions, &mut mint_map)?; | ||
|
|
||
| // Validate mint uniqueness | ||
| validate_mint_uniqueness(&mint_map, &validated_accounts.packed_accounts) | ||
| .map_err(|e| ProgramError::Custom(e as u32 + 6000))?; | ||
|
|
There was a problem hiding this comment.
Do not offset custom error codes; return ProgramError::Custom(e as u32).
Per guidelines, on-chain must map to ProgramError::Custom(error_code as u32). The +6000 offset breaks consistency and downstream assertions.
Apply:
- validate_mint_uniqueness(&mint_map, &validated_accounts.packed_accounts)
- .map_err(|e| ProgramError::Custom(e as u32 + 6000))?;
+ validate_mint_uniqueness(&mint_map, &validated_accounts.packed_accounts)
+ .map_err(|e| ProgramError::Custom(e as u32))?;
@@
- let mint_map = sum_check_multi_mint(
+ let mint_map = sum_check_multi_mint(
&inputs.in_token_data,
&inputs.out_token_data,
inputs.compressions.as_deref(),
)
- .map_err(|e| ProgramError::Custom(e as u32 + 6000))?;
+ .map_err(|e| ProgramError::Custom(e as u32))?;
@@
- validate_mint_uniqueness(&mint_map, &validated_accounts.packed_accounts)
- .map_err(|e| ProgramError::Custom(e as u32 + 6000))?;
+ validate_mint_uniqueness(&mint_map, &validated_accounts.packed_accounts)
+ .map_err(|e| ProgramError::Custom(e as u32))?;As per coding guidelines
Also applies to: 191-202
🤖 Prompt for AI Agents
In programs/compressed-token/program/src/transfer2/processor.rs around lines
129-135 (and also apply the same change at lines 191-202), the review points out
that custom error codes are being offset by +6000 when converted to
ProgramError::Custom; remove the +6000 offset so the function maps errors
directly using ProgramError::Custom(e as u32). Update both call sites to return
ProgramError::Custom(e as u32) instead of ProgramError::Custom(e as u32 + 6000),
ensuring the error type casts to u32 as before.
| if let Some(existing_index) = seen_pubkeys.get_by_pubkey(mint_pubkey) { | ||
| // Same pubkey referenced by different index - this is an attack | ||
| if *existing_index != *mint_index { | ||
| msg!( | ||
| "Duplicate mint detected: index {} and {} both reference the same mint pubkey", | ||
| existing_index, | ||
| mint_index | ||
| ); | ||
| return Err(ErrorCode::DuplicateMint); | ||
| } | ||
| } else { | ||
| // First time seeing this pubkey, record it | ||
| seen_pubkeys.insert(*mint_pubkey, *mint_index, ErrorCode::TooManyMints)?; | ||
| } |
There was a problem hiding this comment.
Fix invalid method call on ArrayMap: use get_by_key
ArrayMap doesn’t expose get_by_pubkey. This won’t compile. Use get_by_key with the same key type as the map.
- if let Some(existing_index) = seen_pubkeys.get_by_pubkey(mint_pubkey) {
+ if let Some(existing_index) = seen_pubkeys.get_by_key(mint_pubkey) {
// Same pubkey referenced by different index - this is an attack
if *existing_index != *mint_index {
msg!(
"Duplicate mint detected: index {} and {} both reference the same mint pubkey",
existing_index,
mint_index
);
return Err(ErrorCode::DuplicateMint);
}
} else {
// First time seeing this pubkey, record it
seen_pubkeys.insert(*mint_pubkey, *mint_index, ErrorCode::TooManyMints)?;
}🤖 Prompt for AI Agents
In programs/compressed-token/program/src/transfer2/sum_check.rs around lines
143–156, the code calls seen_pubkeys.get_by_pubkey(mint_pubkey) which doesn't
exist on ArrayMap; replace that call with seen_pubkeys.get_by_key(...) using the
exact key type the map expects (e.g., pass *mint_pubkey if the map keys are
Pubkey or &mint_pubkey if it expects a reference) so the lookup compiles; leave
the insert logic as-is but ensure the key/value types you pass to get_by_key and
insert match the ArrayMap's key/value types.
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (3)
program-tests/compressed-token-test/tests/v1.rs (2)
1174-1174: Conflating distinct error types to generic error code reduces test precision.Multiple semantically different error checks (ConstraintSeeds, StateMerkleTreeAccountDiscriminatorMismatch, ProofVerificationFailed) are now standardized to the hard-coded error code
21(InstructionError::ProgramFailedToComplete). This generic built-in Solana error is far less specific than the original custom error codes, resulting in:
- Loss of semantic information - tests can no longer distinguish between different failure modes (e.g., invalid seeds vs. account discriminator mismatch)
- Reduced test coverage - a single error code now covers multiple distinct program error paths, potentially masking regressions
- Poor maintainability - the magic number
21requires consulting comments or external references to understand its meaningIf the underlying program behavior has changed to emit ProgramFailedToComplete in these scenarios, consider:
- Defining test-level constants like
PROGRAM_FAILED_TO_COMPLETE_ERROR_CODE = 21with explanatory comments- Documenting why these previously distinct errors now map to the same code
- Verifying whether this conflation is intentional or if more specific error codes should be restored
Based on past review comments.
Also applies to: 1239-1240, 2284-2285, 2329-2330, 2761-2762
5962-5962: Replace magic number with semantic constant.Error code
21lacks clarity. Define a test-level constant or use a descriptive identifier to improve readability:- assert_rpc_error(result, 0, 21).unwrap(); + // ProgramFailedToComplete when no sender account is provided + const PROGRAM_FAILED_TO_COMPLETE: u32 = 21; + assert_rpc_error(result, 0, PROGRAM_FAILED_TO_COMPLETE).unwrap();Alternatively, if this maps to a specific custom error like
OneEpochPrefundingNotAllowedmentioned in the PR, use that error code instead.Based on past review comments.
.github/workflows/programs.yml (1)
32-120: Add an explicitpermissionsblock.The workflow still runs with default write-all token permissions. Please add the minimal block (
permissions: contents: read) at the job or workflow level to close out the CodeQL warning.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
.github/workflows/programs.yml(1 hunks)program-libs/compressible/src/compression_info.rs(1 hunks)program-libs/compressible/src/rent/account_rent.rs(3 hunks)program-libs/compressible/tests/compression_info.rs(2 hunks)program-tests/compressed-token-test/tests/v1.rs(6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- program-libs/compressible/src/compression_info.rs
🧰 Additional context used
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/close_token_account{.rs,/**} : On closing ctoken accounts: if compressible, return rent exemption to the rent recipient; send remaining lamports to the destination
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/config.rs : Update config parameters including max write fee and max funded epoch
Applied to files:
program-libs/compressible/tests/compression_info.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Update RentConfig values at claim time to reflect current policy
Applied to files:
program-libs/compressible/tests/compression_info.rsprogram-libs/compressible/src/rent/account_rent.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Refactor rent logic so that 1 lamport is the minimum rent payment
Applied to files:
program-libs/compressible/tests/compression_info.rsprogram-libs/compressible/src/rent/account_rent.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Determine compressibility and compute rent using calculate_rent_and_balance
Applied to files:
program-libs/compressible/tests/compression_info.rsprogram-libs/compressible/src/rent/account_rent.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Expose claimable rent computation via claimable_lamports
Applied to files:
program-libs/compressible/tests/compression_info.rsprogram-libs/compressible/src/rent/account_rent.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Implement rent curve algorithms via rent_curve_per_epoch
Applied to files:
program-libs/compressible/tests/compression_info.rsprogram-libs/compressible/src/rent/account_rent.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Compute close lamport distribution with calculate_close_lamports
Applied to files:
program-libs/compressible/tests/compression_info.rsprogram-libs/compressible/src/rent/account_rent.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/close_token_account{.rs,/**} : On closing ctoken accounts: if compressible, return rent exemption to the rent recipient; send remaining lamports to the destination
Applied to files:
program-libs/compressible/src/rent/account_rent.rs
🧬 Code graph analysis (1)
program-tests/compressed-token-test/tests/v1.rs (1)
sdk-libs/program-test/src/utils/assert.rs (1)
assert_rpc_error(7-144)
🪛 GitHub Check: CodeQL
.github/workflows/programs.yml
[warning] 34-120: Workflow does not contain permissions
Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {{contents: read}}
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
- GitHub Check: stateless-js-v2
- GitHub Check: stateless-js-v1
- GitHub Check: lint
- GitHub Check: system-programs (sdk-token-test-program, ["cargo-test-sbf -p sdk-token-test"])
- GitHub Check: Test program-libs-fast
- GitHub Check: system-programs (sdk-anchor-test-program, ["cargo-test-sbf -p sdk-anchor-test", "cargo-test-sbf -...
- GitHub Check: programs (system-cpi-test-v2-functional-account-infos, ["cargo-test-sbf -p system-cpi-v2-test -- ...
- GitHub Check: system-programs (sdk-libs, light-sdk-macros light-sdk light-program-test light-client light-compr...
- GitHub Check: programs (light-system-program-compression, ["cargo-test-sbf -p system-test -- test_with_compress...
- GitHub Check: Test batched-merkle-tree-simulate
- GitHub Check: system-programs (sdk-test-program, ["cargo-test-sbf -p sdk-native-test", "cargo-test-sbf -p sdk-v...
- GitHub Check: Test program-libs-slow
- GitHub Check: programs (account-compression-and-registry, ["cargo-test-sbf -p account-compression-test", "cargo...
- GitHub Check: programs (system-cpi-test, ["cargo-test-sbf -p system-cpi-test", "cargo test -p light-system-prog...
- GitHub Check: programs (system-cpi-test-v2-functional-read-only, ["cargo-test-sbf -p system-cpi-v2-test -- func...
- GitHub Check: programs (compressed-token-and-e2e, ["cargo-test-sbf -p compressed-token-test --test v1", "cargo-...
- GitHub Check: programs (light-system-program-address, ["cargo-test-sbf -p system-test -- test_with_address", "c...
- GitHub Check: programs (compressed-token-batched-tree, ["cargo-test-sbf -p compressed-token-test -- test_transf...
- GitHub Check: Forester e2e test
- GitHub Check: cli-v2
- GitHub Check: cli-v1
🔇 Additional comments (4)
program-libs/compressible/tests/compression_info.rs (3)
334-564: Excellent comprehensive test coverage!The new
test_calculate_top_up_lamportstest function is well-structured with:
- Clear organization using TestCase struct
- Systematic coverage of three main paths (compressible, not compressible, well-funded)
- Thorough edge case testing
- Descriptive test case names and documentation
- Detailed assertion messages for debugging
The test cases effectively verify the rent calculation logic across various scenarios including epoch boundaries, partial epochs, and extreme gaps.
526-533: Verify the invalid state edge case is intentionally supported.This test case explicitly sets up an invalid state where
current_lamportsis missing the requiredFULL_COMPRESSION_COSTS. While testingsaturating_subbehavior is good defensive programming, confirm that your implementation should gracefully handle this invalid state rather than rejecting it with an error.If accounts should never reach this state in practice, consider whether an explicit validation error would be more appropriate than silently handling it with saturating subtraction.
Based on learnings
9-10: Constants are verified as consistent across the codebase.All values check out:
TEST_BYTES = 260matches in both test filesRENT_PER_EPOCH = 260 + 128is consistent everywhere- Rent exemption value
2700480matchesCOMPRESSIBLE_TOKEN_RENT_EXEMPTIONdefined inprogram-libs/ctoken-types/src/constants.rs:22and is used consistently throughout the codebaseprogram-libs/compressible/src/rent/account_rent.rs (1)
81-82: LGTM: Good defensive overflow protection.Using
saturating_mulinstead of direct multiplication prevents potential integer overflow in rent calculations. The comment accurately notes it's cheaper thanchecked_mulsince it avoids conditional branching. In the extremely unlikely event of overflow with unrealistic epoch or rent values, saturation provides sensible fallback behavior:
is_compressiblecorrectly identifies the account as compressible with a large deficitcalculate_claimable_rentcaps atu64::MAX(only called after passing compressibility check)get_unused_lamportsreturns 0, correctly indicating no unused lamports if rent due is massiveFor production blockchain code, graceful degradation via saturation is preferable to panicking.
Also applies to: 115-116, 156-157
| system-programs: | ||
| name: programs | ||
| if: github.event.pull_request.draft == false | ||
| runs-on: warp-ubuntu-latest-x64-4x | ||
| timeout-minutes: 90 | ||
|
|
||
| services: | ||
| redis: | ||
| image: redis:8.0.1 | ||
| ports: | ||
| - 6379:6379 | ||
| options: >- | ||
| --health-cmd "redis-cli ping" | ||
| --health-interval 10s | ||
| --health-timeout 5s | ||
| --health-retries 5 | ||
|
|
||
| env: | ||
| REDIS_URL: redis://localhost:6379 | ||
|
|
||
| strategy: | ||
| matrix: | ||
| include: | ||
| - program: account-compression-and-registry | ||
| sub-tests: '["cargo-test-sbf -p account-compression-test", "cargo-test-sbf -p registry-test"]' | ||
| - program: light-system-program-address | ||
| sub-tests: '["cargo-test-sbf -p system-test -- test_with_address", "cargo-test-sbf -p e2e-test", "cargo-test-sbf -p compressed-token-test --test ctoken"]' | ||
| - program: light-system-program-compression | ||
| sub-tests: '["cargo-test-sbf -p system-test -- test_with_compression", "cargo-test-sbf -p system-test --test test_re_init_cpi_account"]' | ||
| - program: compressed-token-and-e2e | ||
| sub-tests: '["cargo-test-sbf -p compressed-token-test --test v1", "cargo-test-sbf -p compressed-token-test --test mint"]' | ||
| - program: compressed-token-batched-tree | ||
| sub-tests: '["cargo-test-sbf -p compressed-token-test -- test_transfer_with_photon_and_batched_tree"]' | ||
| - program: system-cpi-test | ||
| sub-tests: | ||
| '["cargo-test-sbf -p system-cpi-test", "cargo test -p light-system-program-pinocchio", | ||
| "cargo-test-sbf -p system-cpi-v2-test -- --skip functional_ --skip event::parse", "cargo-test-sbf -p system-cpi-v2-test -- event::parse" | ||
| "cargo-test-sbf -p compressed-token-test --test transfer2" | ||
| ]' | ||
| - program: system-cpi-test-v2-functional-read-only | ||
| sub-tests: '["cargo-test-sbf -p system-cpi-v2-test -- functional_read_only"]' | ||
| - program: system-cpi-test-v2-functional-account-infos | ||
| sub-tests: '["cargo-test-sbf -p system-cpi-v2-test -- functional_account_infos"]' | ||
| steps: |
There was a problem hiding this comment.
Allow push workflows to run.
if: github.event.pull_request.draft == false short-circuits every push build because github.event.pull_request is null on push events, leaving main without coverage. Gate only pull_request events (e.g., if: github.event_name != 'pull_request' || github.event.pull_request.draft == false') so pushes still execute.
- if: github.event.pull_request.draft == false
+ if: github.event_name != 'pull_request' || github.event.pull_request.draft == false🤖 Prompt for AI Agents
In .github/workflows/programs.yml around lines 33 to 76 the current if:
github.event.pull_request.draft == false will be null on push events and
short-circuit those runs; change the conditional to only gate draft pull
requests by using a compound check such as: if: github.event_name !=
'pull_request' || github.event.pull_request.draft == false so that
non-pull_request events (pushes) still run while draft PRs remain blocked.
| IFS=',' read -r -a sub_tests <<< "${{ join(fromJSON(matrix['sub-tests']), ', ') }}" | ||
| for subtest in "${sub_tests[@]}" | ||
| do | ||
| echo "$subtest" | ||
|
|
||
| # Retry logic for flaky batched-tree test | ||
| if [[ "$subtest" == *"test_transfer_with_photon_and_batched_tree"* ]]; then | ||
| echo "Running flaky test with retry logic (max 3 attempts)..." | ||
| attempt=1 | ||
| max_attempts=3 | ||
| until RUSTFLAGS="-D warnings" eval "$subtest"; do | ||
| attempt=$((attempt + 1)) | ||
| if [ $attempt -gt $max_attempts ]; then | ||
| echo "Test failed after $max_attempts attempts" | ||
| exit 1 | ||
| fi | ||
| echo "Attempt $attempt/$max_attempts failed, retrying..." | ||
| sleep 5 | ||
| done | ||
| echo "Test passed on attempt $attempt" | ||
| else | ||
| RUSTFLAGS="-D warnings" eval "$subtest" | ||
| if [ "$subtest" == "cargo-test-sbf -p e2e-test" ]; then | ||
| pnpm --filter @lightprotocol/programs run build-compressed-token-small | ||
| RUSTFLAGS="-D warnings" eval "$subtest -- --test test_10_all" | ||
| fi |
There was a problem hiding this comment.
Trim subtest strings before comparisons.
Splitting on commas leaves each element with a leading space, so the literal comparison on Line 115 never matches "cargo-test-sbf -p e2e-test". As a result, the extra CLI build and --test test_10_all run are silently skipped. Strip the whitespace (e.g., subtest="${subtest## }") or iterate the JSON array directly to ensure the equality check fires.
- for subtest in "${sub_tests[@]}"
+ for subtest in "${sub_tests[@]}"
do
- echo "$subtest"
+ subtest="${subtest## }"
+ echo "$subtest"🤖 Prompt for AI Agents
In .github/workflows/programs.yml around lines 93 to 118, the elements produced
by splitting the JSON string contain leading spaces so the equality check for
"cargo-test-sbf -p e2e-test" never matches; fix this by trimming
leading/trailing whitespace from each subtest before any comparisons or evals
(or iterate the JSON array directly), and use the trimmed value for the
retry/eval and the subsequent equality branch so the extra build and the `--test
test_10_all` invocation run as intended.
3422afc to
a0c9ae0
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
programs/compressed-token/program/src/create_token_account.rs (1)
164-168: Consistent validation with ATA creation.The 1-epoch prefunding validation correctly prevents the footgun scenario and mirrors the logic in
create_associated_token_account.rs. The error message clearly explains the issue and suggests alternatives.However, as noted in the previous review, explicit test coverage for this error path is still missing.
As per coding guidelines (based on learnings).
🧹 Nitpick comments (5)
programs/compressed-token/program/tests/allocation_test.rs (1)
21-29: LGTM! Clean migration to tinyvec.The replacement of
arrayvec::ArrayVecwithtinyvec::ArrayVecis correct. Element types satisfy theDefaultrequirement, and capacities (35 for outputs, 8 for inputs) are appropriate for these test cases.Optional: Consider using the
array_vec!macro for cleaner construction.Based on learnings, tinyvec provides the
array_vec!macro for more concise initialization:- let mut outputs_no_ext = tinyvec::ArrayVec::<[(bool, u32); 35]>::new(); - outputs_no_ext.push((true, expected_mint_size_no_ext as u32)); + let mut outputs_no_ext = tinyvec::array_vec![(bool, u32); 35 => (true, expected_mint_size_no_ext as u32)];However, the current explicit form is also perfectly fine and may be clearer for readers unfamiliar with the macro.
Also applies to: 54-62
programs/compressed-token/program/src/mint_action/actions/create_spl_mint/create_token_pool.rs (1)
34-43: Consider removing commented-out code.The commented-out PDA verification logic is no longer in use and leaves the
_program_idparameter (line 16) unused. Consider either removing this dead code and the unused parameter, or uncommenting and completing the verification if it's needed.program-tests/compressed-token-test/tests/mint/random.rs (1)
320-349: Simpler filtering approach improves maintainability.The state-based filtering using a HashSet to track removed keys is correct and more maintainable than complex reordering logic. The manual index manipulation handles the removal case properly by not incrementing when an action is dropped.
For a more idiomatic Rust pattern, consider using
retainorfilterto avoid manual index management:- let mut removed_keys: HashSet<Vec<u8>> = HashSet::new(); - let mut i = 0; - - while i < actions.len() { - match &actions[i] { - MintActionType::RemoveMetadataKey { key, .. } => { - // Track that this key has been removed - removed_keys.insert(key.clone()); - i += 1; - } - MintActionType::UpdateMetadataField { - key, field_type: 3, .. - } => { - // If trying to update a key that was already removed, remove this action - if removed_keys.contains(key) { - actions.remove(i); - // Don't increment i, check the same position again - } else { - i += 1; - } - } - _ => { - i += 1; - } - } - } + // First pass: collect all removed keys + let removed_keys: HashSet<Vec<u8>> = actions + .iter() + .filter_map(|action| match action { + MintActionType::RemoveMetadataKey { key, .. } => Some(key.clone()), + _ => None, + }) + .collect(); + + // Second pass: filter out updates for removed keys + actions.retain(|action| { + !matches!( + action, + MintActionType::UpdateMetadataField { + key, + field_type: 3, + .. + } if removed_keys.contains(key) + ) + });This two-pass approach separates concerns (collecting removed keys, then filtering) and avoids manual index management, though both implementations are functionally correct.
programs/compressed-token/program/src/extensions/mod.rs (1)
125-126: Clarify the mixed usage of arrayvec and tinyvec.The code uses
arrayvec::ArrayVecforconfigs(line 125) andtinyvec::ArrayVecforprocessed_keys(line 126). While both serve similar purposes, mixing two different crate implementations in the same function can reduce maintainability and increase cognitive load.Consider standardizing on one crate throughout this module. Based on the retrieved learnings,
tinyvec1.10.0 is 100% safe Rust and actively maintained. If the broader codebase is migrating totinyvec, complete the migration here; otherwise, document why both are needed.Based on learnings.
programs/compressed-token/program/src/create_associated_token_account.rs (1)
151-155: Consider extracting the validation to a shared helper.This validation is identical to the one in
create_token_account.rs(lines 164-168). While the duplication is minimal, extracting it to a shared validation function would ensure consistency and make future policy changes easier to maintain.Example:
// In shared module: pub fn validate_rent_payment(rent_payment: u32) -> Result<(), ProgramError> { if rent_payment == 1 { msg!("Prefunding for exactly 1 epoch is not allowed. If the account is created near an epoch boundary, it could become immediately compressible. Use 0 or 2+ epochs."); return Err(anchor_compressed_token::ErrorCode::OneEpochPrefundingNotAllowed.into()); } Ok(()) }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (19)
.github/workflows/programs.yml(1 hunks)program-libs/ctoken-types/Cargo.toml(1 hunks)program-libs/ctoken-types/src/hash_cache.rs(2 hunks)program-libs/ctoken-types/src/instructions/extensions/compressible.rs(3 hunks)program-tests/compressed-token-test/tests/mint/random.rs(1 hunks)programs/compressed-token/program/Cargo.toml(1 hunks)programs/compressed-token/program/src/create_associated_token_account.rs(3 hunks)programs/compressed-token/program/src/create_token_account.rs(4 hunks)programs/compressed-token/program/src/extensions/mod.rs(1 hunks)programs/compressed-token/program/src/mint_action/actions/create_spl_mint/create_mint_account.rs(1 hunks)programs/compressed-token/program/src/mint_action/actions/create_spl_mint/create_token_pool.rs(1 hunks)programs/compressed-token/program/src/mint_action/zero_copy_config.rs(1 hunks)programs/compressed-token/program/src/shared/cpi_bytes_size.rs(2 hunks)programs/compressed-token/program/src/shared/create_pda_account.rs(2 hunks)programs/compressed-token/program/src/transfer2/cpi.rs(2 hunks)programs/compressed-token/program/tests/allocation_test.rs(3 hunks)programs/compressed-token/program/tests/exact_allocation_test.rs(2 hunks)programs/compressed-token/program/tests/token_input.rs(1 hunks)programs/compressed-token/program/tests/token_output.rs(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- .github/workflows/programs.yml
- program-libs/ctoken-types/Cargo.toml
- programs/compressed-token/program/Cargo.toml
- program-libs/ctoken-types/src/hash_cache.rs
🧰 Additional context used
📓 Path-based instructions (4)
programs/compressed-token/program/src/transfer2/**
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Transfer2 must support Compress, Decompress, and CompressAndClose modes and perform multi-mint sum checks
Files:
programs/compressed-token/program/src/transfer2/cpi.rs
programs/compressed-token/program/src/**/*.rs
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Return errors as ProgramError::Custom(error_code as u32) on-chain
Files:
programs/compressed-token/program/src/transfer2/cpi.rsprograms/compressed-token/program/src/mint_action/zero_copy_config.rsprograms/compressed-token/program/src/mint_action/actions/create_spl_mint/create_mint_account.rsprograms/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/src/mint_action/actions/create_spl_mint/create_token_pool.rsprograms/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/src/extensions/mod.rsprograms/compressed-token/program/src/shared/create_pda_account.rsprograms/compressed-token/program/src/shared/cpi_bytes_size.rs
programs/compressed-token/program/src/mint_action/**
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
MintAction must implement the 9 listed actions and handle both compressed and decompressed minting flows
Files:
programs/compressed-token/program/src/mint_action/zero_copy_config.rsprograms/compressed-token/program/src/mint_action/actions/create_spl_mint/create_mint_account.rsprograms/compressed-token/program/src/mint_action/actions/create_spl_mint/create_token_pool.rs
programs/compressed-token/program/src/{create_token_account.rs,create_associated_token_account.rs}
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Enforce ACTIVE-only config validation for Create CToken Account and Create Associated CToken Account instructions
Files:
programs/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/src/create_associated_token_account.rs
🧠 Learnings (26)
📚 Learning: 2025-10-15T03:46:26.758Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.758Z
Learning: Applies to programs/registry/src/account_compression_cpi/**/*.rs : Pass the data Vec<u8> through unchanged from the wrapper to the target program CPI; the target program performs deserialization.
Applied to files:
programs/compressed-token/program/src/transfer2/cpi.rsprograms/compressed-token/program/src/shared/cpi_bytes_size.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/programs/compressed-token/anchor/src/lib.rs : Define all program-specific error codes in anchor_compressed_token::ErrorCode and expose them for program-wide use
Applied to files:
programs/compressed-token/program/src/mint_action/zero_copy_config.rsprograms/compressed-token/program/tests/token_output.rsprograms/compressed-token/program/src/mint_action/actions/create_spl_mint/create_mint_account.rsprograms/compressed-token/program/tests/token_input.rsprograms/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/src/mint_action/actions/create_spl_mint/create_token_pool.rsprograms/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/src/shared/create_pda_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/error.rs : Provide ProgramError conversions compatible with Anchor, Pinocchio, and Solana error types
Applied to files:
programs/compressed-token/program/src/mint_action/zero_copy_config.rsprograms/compressed-token/program/src/mint_action/actions/create_spl_mint/create_mint_account.rsprograms/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/src/mint_action/actions/create_spl_mint/create_token_pool.rsprograms/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/src/shared/create_pda_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/**/*.rs : Return errors as ProgramError::Custom(error_code as u32) on-chain
Applied to files:
programs/compressed-token/program/src/mint_action/zero_copy_config.rsprograms/compressed-token/program/src/mint_action/actions/create_spl_mint/create_mint_account.rsprograms/compressed-token/program/src/mint_action/actions/create_spl_mint/create_token_pool.rsprograms/compressed-token/program/src/shared/create_pda_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/config.rs : Implement CompressibleConfig account with Anchor, Borsh, and Pod serialization for Light Registry integration
Applied to files:
programs/compressed-token/program/src/mint_action/zero_copy_config.rsprograms/compressed-token/program/tests/token_output.rsprograms/compressed-token/program/tests/token_input.rsprograms/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/src/shared/cpi_bytes_size.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/ctoken_transfer.rs : CTokenTransfer must perform SPL-compatible transfers between decompressed accounts
Applied to files:
programs/compressed-token/program/src/mint_action/zero_copy_config.rsprograms/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:46:26.758Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.758Z
Learning: Applies to programs/registry/src/account_compression_cpi/**/*.rs : CPI processing functions must derive PDA signer seeds as [CPI_AUTHORITY_PDA_SEED, bump] and use CpiContext::new_with_signer with cpi_authority as the authority account and mapped target accounts.
Applied to files:
programs/compressed-token/program/src/mint_action/actions/create_spl_mint/create_mint_account.rsprograms/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/src/create_associated_token_account.rsprograms/compressed-token/program/src/shared/create_pda_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/close_token_account{.rs,/**} : On closing ctoken accounts: if compressible, return rent exemption to the rent recipient; send remaining lamports to the destination
Applied to files:
programs/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/src/create_associated_token_account.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Document closing decompressed token accounts with rent distribution in instructions/CLOSE_TOKEN_ACCOUNT.md
Applied to files:
programs/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/{create_token_account.rs,create_associated_token_account.rs} : Enforce ACTIVE-only config validation for Create CToken Account and Create Associated CToken Account instructions
Applied to files:
programs/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/src/create_associated_token_account.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: CToken account layout matches SPL token accounts with a custom Compressible extension; compressed mint accounts support the TokenMetadata extension
Applied to files:
programs/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLAIM.md : Document rent reclamation from expired compressible accounts in instructions/CLAIM.md
Applied to files:
programs/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Update RentConfig values at claim time to reflect current policy
Applied to files:
programs/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/src/create_associated_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Refactor rent logic so that 1 lamport is the minimum rent payment
Applied to files:
programs/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/src/create_associated_token_account.rsprogram-libs/ctoken-types/src/instructions/extensions/compressible.rs
📚 Learning: 2025-10-15T03:46:26.758Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.758Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Context structs for wrapper instructions must include standard accounts: optional registered_forester_pda (mut), authority Signer, cpi_authority with seeds/bump for CPI_AUTHORITY_PDA_SEED, registered_program_pda, target program handle, log_wrapper, and mutable target_account.
Applied to files:
programs/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/checks.rs : Expose and maintain account validation helpers (check_owner, check_program, check_mut/non_mut, check_signer, check_discriminator, set_discriminator, check_pda_seeds, check_account_balance_is_rent_exempt, account_info_init) in checks.rs
Applied to files:
programs/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Determine compressibility and compute rent using calculate_rent_and_balance
Applied to files:
programs/compressed-token/program/src/create_token_account.rsprograms/compressed-token/program/src/create_associated_token_account.rsprogram-libs/ctoken-types/src/instructions/extensions/compressible.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Expose claimable rent computation via claimable_lamports
Applied to files:
programs/compressed-token/program/src/create_token_account.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/error.rs : Maintain stable mapping of AccountError to ProgramError, including Pinocchio code mapping (1–11), in error.rs
Applied to files:
programs/compressed-token/program/src/mint_action/actions/create_spl_mint/create_token_pool.rsprograms/compressed-token/program/src/shared/create_pda_account.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/account_iterator.rs : Use AccountIterator for sequential account retrieval to get precise file:line:column error locations; avoid manual index handling
Applied to files:
programs/compressed-token/program/src/create_associated_token_account.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/config.rs : Provide PDA derivation helpers derive_pda and derive_v1_config_pda for CompressibleConfig
Applied to files:
programs/compressed-token/program/src/create_associated_token_account.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/account_info/{solana.rs,pinocchio.rs,test_account_info.rs} : Gate SDK-specific implementations with #[cfg(feature = "solana"|"pinocchio"|"test-only")]
Applied to files:
programs/compressed-token/program/src/shared/create_pda_account.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/discriminator.rs : Define and keep discriminator constants and the Discriminator trait in discriminator.rs for compile-time verification
Applied to files:
programs/compressed-token/program/src/shared/cpi_bytes_size.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/**/*.rs : Validate account type with 8-byte discriminators using check_discriminator before deserialization
Applied to files:
programs/compressed-token/program/src/shared/cpi_bytes_size.rs
📚 Learning: 2025-10-11T21:59:52.702Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/docs/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:52.702Z
Learning: Applies to program-libs/account-checks/docs/**/DISCRIMINATOR.md : DISCRIMINATOR.md must document 8-byte discriminators, the Discriminator trait, constant arrays for compile-time checks, and integration with account initialization
Applied to files:
programs/compressed-token/program/src/shared/cpi_bytes_size.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/**/*.rs : On account initialization, call account_info_init to set the 8-byte discriminator
Applied to files:
programs/compressed-token/program/src/shared/cpi_bytes_size.rs
🧬 Code graph analysis (4)
programs/compressed-token/program/tests/token_output.rs (1)
programs/compressed-token/program/src/shared/cpi_bytes_size.rs (1)
compressed_token_data_len(30-36)
programs/compressed-token/program/src/create_token_account.rs (1)
programs/compressed-token/anchor/src/lib.rs (1)
from(422-424)
programs/compressed-token/program/src/mint_action/actions/create_spl_mint/create_token_pool.rs (1)
js/compressed-token/src/constants.ts (1)
POOL_SEED(2-2)
programs/compressed-token/program/src/create_associated_token_account.rs (1)
programs/compressed-token/anchor/src/lib.rs (1)
from(422-424)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
- GitHub Check: Test program-libs-slow
- GitHub Check: Test program-libs-fast
- GitHub Check: Test batched-merkle-tree-simulate
- GitHub Check: stateless-js-v1
- GitHub Check: system-programs (sdk-token-test-program, ["cargo-test-sbf -p sdk-token-test"])
- GitHub Check: system-programs (sdk-test-program, ["cargo-test-sbf -p sdk-native-test", "cargo-test-sbf -p sdk-v...
- GitHub Check: system-programs (sdk-libs, light-sdk-macros light-sdk light-program-test light-client light-compr...
- GitHub Check: system-programs (sdk-anchor-test-program, ["cargo-test-sbf -p sdk-anchor-test", "cargo-test-sbf -...
- GitHub Check: programs (compressed-token-batched-tree, ["cargo-test-sbf -p compressed-token-test -- test_transf...
- GitHub Check: cli-v1
- GitHub Check: programs (system-cpi-test, ["cargo-test-sbf -p system-cpi-test", "cargo test -p light-system-prog...
- GitHub Check: programs (system-cpi-test-v2-functional-account-infos, ["cargo-test-sbf -p system-cpi-v2-test -- ...
- GitHub Check: programs (system-cpi-test-v2-functional-read-only, ["cargo-test-sbf -p system-cpi-v2-test -- func...
- GitHub Check: programs (compressed-token-and-e2e, ["cargo-test-sbf -p compressed-token-test --test v1", "cargo-...
- GitHub Check: programs (light-system-program-address, ["cargo-test-sbf -p system-test -- test_with_address", "c...
- GitHub Check: programs (account-compression-and-registry, ["cargo-test-sbf -p account-compression-test", "cargo...
- GitHub Check: programs (light-system-program-compression, ["cargo-test-sbf -p system-test -- test_with_compress...
- GitHub Check: stateless-js-v2
- GitHub Check: cli-v2
- GitHub Check: Forester e2e test
- GitHub Check: lint
🔇 Additional comments (19)
programs/compressed-token/program/tests/exact_allocation_test.rs (2)
47-51: LGTM: Correct tinyvec migration.The migration from
arrayvectotinyvec::ArrayVecis correct and maintains identical semantics. The capacities (35 for outputs, 8 for input accounts) are adequate for the test scenarios, and tinyvec's panic-on-overflow behavior matches the original arrayvec implementation.
302-306: LGTM: Consistent migration pattern.The tinyvec migration here mirrors the changes at lines 47-51, maintaining consistency across both test functions. The allocations correctly support the various metadata size test cases.
programs/compressed-token/program/tests/allocation_test.rs (1)
167-175: LGTM! Consistent with the tinyvec migration.The container type changes here mirror those in
test_extension_allocation_only, maintaining consistency across the test suite. The migration correctly preserves test logic while adopting the new container type.programs/compressed-token/program/tests/token_input.rs (1)
92-97: LGTM! ArrayVec migration to tinyvec is correct.The migration from
arrayvec::ArrayVectotinyvec::ArrayVecfor bothinput_accountsandoutput_accountsis implemented correctly. Both element types (booland(bool, u32)) implementDefaultas required by tinyvec, and the capacities (8 and 35) are appropriate for the test workload. The tinyvec library provides equivalent functionality with the added benefit of being implemented in 100% safe Rust.Based on learnings.
programs/compressed-token/program/src/mint_action/actions/create_spl_mint/create_token_pool.rs (2)
47-53: LGTM! Clean migration to fixed-size array.The refactor from
ArrayVecto a fixed-size array for seed construction is efficient and aligns with the broader codebase migration pattern. The seed order (POOL_SEED, mint_key, bump) is correct for PDA derivation.
95-98: Correct error handling per guidelines.The error conversion to
ProgramError::Customcorrectly follows the on-chain error handling pattern specified in the coding guidelines.programs/compressed-token/program/src/shared/cpi_bytes_size.rs (1)
40-41: Type syntax correctly updated for tinyvec API.The field types have been properly migrated from
ArrayVec<T, N>(arrayvec const generic syntax) toArrayVec<[T; N]>(tinyvec array-backed syntax). All usages within the file (lines 54, 57, 61, 65, 78-79, 81-82) are compatible with the new API.programs/compressed-token/program/src/transfer2/cpi.rs (1)
5-5: LGTM: Consistent migration to tinyvec.The import and type annotation changes are consistent with the migration in
cpi_bytes_size.rs. TheArrayVec::new()initialization and subsequentpush()operations (line 22) are fully compatible with tinyvec's API.Also applies to: 19-20
programs/compressed-token/program/src/mint_action/zero_copy_config.rs (1)
10-10: Tinyvec migration verified—sufficient capacity confirmed.The
CpiConfigInputstruct defines:
input_accounts: ArrayVec<[bool; 8]>→ supports max 1 element required ✓output_accounts: ArrayVec<[(bool, u32); 35]>→ supports max 30 elements required ✓Capacities are adequate. The migration to tinyvec is sound and consistent with usage elsewhere in the codebase (e.g.,
transfer2/cpi.rs).programs/compressed-token/program/tests/token_output.rs (1)
71-77: Test file changes are compatible, but broader migration is incomplete.The replacement of
arrayvec::ArrayVecwithtinyvec::ArrayVecin lines 71 and 77 is correct—capacities are safe and the API is compatible. However, verification reveals thatarrayvecis still actively used in five other files in the same program:
programs/compressed-token/program/src/extensions/mod.rs:125programs/compressed-token/program/src/shared/create_pda_account.rs:60programs/compressed-token/program/src/transfer2/compression/mod.rs:3programs/compressed-token/program/src/convert_account_infos.rs:16programs/compressed-token/program/src/convert_account_infos.rs:35Both dependencies remain in
Cargo.toml. Clarify whether this PR is intended as a complete migration across the codebase or targeted only at test files. If the latter, document why the partial approach is acceptable.program-libs/ctoken-types/src/instructions/extensions/compressible.rs (2)
6-6: Migration to tinyvec confirmed.The import change to
tinyvec::ArrayVecaligns with the broader codebase migration. Per the library documentation, tinyvec 1.10.0 is 100% safe Rust with no unsafe code, which improves memory safety guarantees.Note: tinyvec's ArrayVec panics on capacity overflow rather than returning errors. Ensure all usage sites validate input lengths before pushing elements (see comment on lines 38-41).
Based on learnings.
20-20: Verify serialization compatibility and domain constraints.Changing
rent_paymentfromu64tou8breaks the previous serialization format and caps rent pre-payment at 255 epochs. Inputs are alreadyu8(so no overflow risk) and the 1-epoch footgun check remains. Please confirm:
- 255 epochs is sufficient for all expected use cases
- A migration path exists for any on-chain data still using the old
u64formatprograms/compressed-token/program/src/create_token_account.rs (2)
60-66: LGTM! Correct signer requirement for compressible accounts.The conditional logic correctly requires
token_accountto be a signer when creating compressible accounts (via CPI), while maintaining SPL compatibility for non-compressible accounts. This aligns with the CPI account creation flow and the parallel changes increate_associated_token_account.rs.
207-213: LGTM! Simplified seed handling.The refactor from dynamic
ArrayVecto fixed-size arrays reduces allocations and simplifies the code. Theseeds_inputsarray construction is straightforward and maintains the same functional behavior.programs/compressed-token/program/src/create_associated_token_account.rs (2)
109-116: LGTM! Clean seed refactor for non-compressible path.The conversion to fixed-size arrays is straightforward and maintains the same PDA derivation logic while reducing allocations.
181-209: Seed construction logic is correct and safely handles empty elements.The
create_pda_accountfunction properly processes both scenarios:
Custom rent payer (true): When
seeds_inputs = [ata_seeds.as_slice(), &[]], the loop at line 61–65 iterates both elements and skips the empty slice via theif !seeds.is_empty()check (line 62), resulting in only ATA seeds being used. ✓Rent sponsor scenario (false): Both
rent_sponsor_seedsandata_seedsslices are non-empty and both are added to the signers in the correct order. ✓Empty slice handling: The conditional check at line 62 (
if !seeds.is_empty()) explicitly filters out empty seed sets before building the signer array, making the dual-array pattern safe and intentional. ✓programs/compressed-token/program/src/shared/create_pda_account.rs (2)
41-41: Breaking API change simplifies seed handling.The parameter type change from
ArrayVec<&[Seed], N>to[&[Seed]; N]is a breaking change that simplifies the API by requiring callers to provide fixed-size arrays. This reduces allocations and aligns with the broader refactor across create_token_account, create_associated_token_account, and create_mint_account.Ensure all callers have been updated to the new signature. Based on the provided files, the major callers appear to have been updated.
As per coding guidelines.
60-65: LGTM! Correct handling of empty seed sets.The loop correctly iterates by reference, skips empty seed sets with the
!seeds.is_empty()check, and dereferences seeds when creating signers. This properly handles the dual-seed scenario increate_associated_token_account.rswhere one array element may be empty whencustom_rent_payeris true.programs/compressed-token/program/src/mint_action/actions/create_spl_mint/create_mint_account.rs (1)
36-42: LGTM! Consistent seed refactor.The conversion to fixed-size arrays follows the same pattern as
create_token_account.rsandcreate_associated_token_account.rs, providing consistency across the codebase while reducing allocations.
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
program-libs/compressible/docs/CONFIG_ACCOUNT.md (1)
131-136: Update default rent constants to match code.
RentConfig::default()now pullsbase_rent = 500,compression_cost = 6000,compression_incentive = 4000(combined 10000), andlamports_per_byte_per_epoch = 6(seeprogram-libs/compressible/src/constants.rs). The table still reports the legacy 1220/11000/10 values, so it will mislead integrators. Please refresh these defaults to reflect the current constants.
♻️ Duplicate comments (2)
program-tests/compressed-token-test/tests/ctoken/create_ata.rs (1)
223-256: Align the documented error code with the expectation.The inline comment still calls out “Error: 18 (IllegalOwner)”, but the assertion checks for error code 29. Please update the comment (here and around Line 255) or the expectation so they match and avoid confusion.
program-tests/compressed-token-test/tests/ctoken/shared.rs (1)
93-107: Wirecompress_to_account_pubkeywhencompress_to_pubkeyis requested
CompressibleDataexposescompress_to_pubkey, but both create paths still hardcodecompress_to_account_pubkey: None. That means accounts meant to compress back to their own pubkey never set the flag, so the new compress_to_pubkey logic you introduced is never exercised and downstream ownership checks will fail. Please propagate the flag when building the instruction.- compress_to_account_pubkey: None, + compress_to_account_pubkey: if compressible_data.compress_to_pubkey { + Some(token_account_pubkey) + } else { + None + },Also applies to: 145-159
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (41)
program-libs/compressible/CLAUDE.md(0 hunks)program-libs/compressible/docs/CONFIG_ACCOUNT.md(1 hunks)program-libs/ctoken-types/src/error.rs(2 hunks)program-libs/ctoken-types/src/instructions/extensions/compressible.rs(4 hunks)program-libs/ctoken-types/src/instructions/transfer2/instruction_data.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/create_ata.rs(1 hunks)program-tests/compressed-token-test/tests/ctoken/shared.rs(1 hunks)program-tests/compressed-token-test/tests/mint/random.rs(1 hunks)program-tests/compressed-token-test/tests/transfer2/compress_failing.rs(3 hunks)program-tests/compressed-token-test/tests/transfer2/compress_spl_failing.rs(2 hunks)program-tests/compressed-token-test/tests/transfer2/decompress_failing.rs(3 hunks)program-tests/compressed-token-test/tests/transfer2/transfer_failing.rs(2 hunks)programs/compressed-token/program/CLAUDE.md(1 hunks)programs/compressed-token/program/docs/instructions/CLAIM.md(1 hunks)programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md(5 hunks)programs/compressed-token/program/docs/instructions/MINT_ACTION.md(1 hunks)programs/compressed-token/program/docs/instructions/TRANSFER2.md(3 hunks)programs/compressed-token/program/docs/instructions/WITHDRAW_FUNDING_POOL.md(1 hunks)programs/compressed-token/program/src/lib.rs(4 hunks)programs/compressed-token/program/src/shared/owner_validation.rs(1 hunks)programs/compressed-token/program/src/transfer2/token_outputs.rs(1 hunks)programs/compressed-token/program/tests/multi_sum_check.rs(3 hunks)programs/registry/src/compressible/claim.rs(1 hunks)programs/registry/src/compressible/withdraw_funding_pool.rs(1 hunks)sdk-libs/compressed-token-sdk/src/account2.rs(6 hunks)sdk-libs/compressed-token-sdk/src/instructions/claim.rs(1 hunks)sdk-libs/compressed-token-sdk/src/instructions/compress_and_close.rs(2 hunks)sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs(3 hunks)sdk-libs/compressed-token-sdk/src/instructions/decompress_full.rs(1 hunks)sdk-libs/compressed-token-sdk/src/instructions/mint_action/instruction.rs(1 hunks)sdk-libs/compressed-token-sdk/src/instructions/transfer2/instruction.rs(3 hunks)sdk-libs/compressed-token-sdk/src/instructions/withdraw_funding_pool.rs(1 hunks)sdk-libs/compressed-token-sdk/tests/create_associated_token_account.rs(2 hunks)sdk-libs/compressed-token-types/src/constants.rs(1 hunks)sdk-libs/program-test/src/forester/compress_and_close_forester.rs(1 hunks)sdk-libs/token-client/src/instructions/transfer2.rs(7 hunks)sdk-tests/sdk-token-test/src/lib.rs(0 hunks)sdk-tests/sdk-token-test/src/process_compress_full_and_close.rs(2 hunks)sdk-tests/sdk-token-test/src/process_four_transfer2.rs(2 hunks)sdk-tests/sdk-token-test/tests/compress_and_close_cpi.rs(4 hunks)sdk-tests/sdk-token-test/tests/test_compress_full_and_close.rs(1 hunks)
💤 Files with no reviewable changes (2)
- program-libs/compressible/CLAUDE.md
- sdk-tests/sdk-token-test/src/lib.rs
✅ Files skipped from review due to trivial changes (2)
- programs/compressed-token/program/docs/instructions/MINT_ACTION.md
- programs/compressed-token/program/src/shared/owner_validation.rs
🚧 Files skipped from review as they are similar to previous changes (1)
- sdk-libs/compressed-token-sdk/tests/create_associated_token_account.rs
🧰 Additional context used
📓 Path-based instructions (7)
program-libs/compressible/docs/CONFIG_ACCOUNT.md
📄 CodeRabbit inference engine (program-libs/compressible/CLAUDE.md)
Maintain documentation for CompressibleConfig structure and methods in docs/CONFIG_ACCOUNT.md
Files:
program-libs/compressible/docs/CONFIG_ACCOUNT.md
programs/compressed-token/program/src/transfer2/**
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Transfer2 must support Compress, Decompress, and CompressAndClose modes and perform multi-mint sum checks
Files:
programs/compressed-token/program/src/transfer2/token_outputs.rs
programs/compressed-token/program/src/**/*.rs
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Return errors as ProgramError::Custom(error_code as u32) on-chain
Files:
programs/compressed-token/program/src/transfer2/token_outputs.rsprograms/compressed-token/program/src/lib.rs
sdk-tests/sdk-token-test/**/tests/**/*.rs
📄 CodeRabbit inference engine (sdk-tests/sdk-token-test/CLAUDE.md)
Every test should only contain functional integration tests
Files:
sdk-tests/sdk-token-test/tests/compress_and_close_cpi.rssdk-tests/sdk-token-test/tests/test_compress_full_and_close.rs
programs/compressed-token/program/docs/instructions/*.md
📄 CodeRabbit inference engine (programs/compressed-token/program/CLAUDE.md)
Each instruction doc must include: path, description, instruction_data (code paths), Accounts (order and checks), instruction logic and checks, and Errors (with causes)
Files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprograms/compressed-token/program/docs/instructions/TRANSFER2.mdprograms/compressed-token/program/docs/instructions/CLAIM.mdprograms/compressed-token/program/docs/instructions/WITHDRAW_FUNDING_POOL.md
programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md
📄 CodeRabbit inference engine (programs/compressed-token/program/docs/CLAUDE.md)
Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions
Files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
programs/compressed-token/program/docs/**/instructions/**/*.md
📄 CodeRabbit inference engine (programs/compressed-token/program/docs/CLAUDE.md)
Keep detailed instruction documentation files under the instructions/ directory; add additional instruction docs as needed
Files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprograms/compressed-token/program/docs/instructions/TRANSFER2.mdprograms/compressed-token/program/docs/instructions/CLAIM.mdprograms/compressed-token/program/docs/instructions/WITHDRAW_FUNDING_POOL.md
🧠 Learnings (33)
📓 Common learnings
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/close_token_account{.rs,/**} : On closing ctoken accounts: if compressible, return rent exemption to the rent recipient; send remaining lamports to the destination
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/ctoken_transfer.rs : CTokenTransfer must perform SPL-compatible transfers between decompressed accounts
Applied to files:
sdk-libs/compressed-token-types/src/constants.rsprogram-tests/compressed-token-test/tests/transfer2/compress_failing.rssdk-libs/compressed-token-sdk/src/instructions/decompress_full.rssdk-libs/compressed-token-sdk/src/account2.rsprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdsdk-libs/token-client/src/instructions/transfer2.rssdk-tests/sdk-token-test/src/process_four_transfer2.rsprograms/compressed-token/program/docs/instructions/TRANSFER2.mdprogram-tests/compressed-token-test/tests/transfer2/decompress_failing.rsprogram-tests/compressed-token-test/tests/transfer2/transfer_failing.rssdk-tests/sdk-token-test/src/process_compress_full_and_close.rssdk-tests/sdk-token-test/tests/test_compress_full_and_close.rsprograms/compressed-token/program/src/lib.rsprogram-tests/compressed-token-test/tests/transfer2/compress_spl_failing.rssdk-libs/compressed-token-sdk/src/instructions/compress_and_close.rsprograms/compressed-token/program/tests/multi_sum_check.rssdk-libs/compressed-token-sdk/src/instructions/transfer2/instruction.rs
📚 Learning: 2025-10-11T21:59:52.702Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/docs/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:52.702Z
Learning: Applies to program-libs/account-checks/docs/**/DISCRIMINATOR.md : DISCRIMINATOR.md must document 8-byte discriminators, the Discriminator trait, constant arrays for compile-time checks, and integration with account initialization
Applied to files:
programs/compressed-token/program/CLAUDE.mdprogram-libs/compressible/docs/CONFIG_ACCOUNT.mdprograms/compressed-token/program/src/lib.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/MINT_ACTION.md : Document Mint operations and compressed mint management (9 actions) in instructions/MINT_ACTION.md
Applied to files:
programs/compressed-token/program/CLAUDE.mdsdk-libs/compressed-token-sdk/src/instructions/mint_action/instruction.rsprograms/compressed-token/program/docs/instructions/TRANSFER2.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/{CREATE_TOKEN_ACCOUNT,MINT_ACTION,TRANSFER2,CLAIM,CLOSE_TOKEN_ACCOUNT,DECOMPRESSED_TRANSFER,WITHDRAW_FUNDING_POOL}.md : Every instruction description must include sections: path, description, instruction_data, Accounts, instruction logic and checks, Errors
Applied to files:
programs/compressed-token/program/CLAUDE.mdprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLAIM.md : Document rent reclamation from expired compressible accounts in instructions/CLAIM.md
Applied to files:
programs/compressed-token/program/CLAUDE.mdprogram-libs/compressible/docs/CONFIG_ACCOUNT.mdprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprograms/compressed-token/program/docs/instructions/CLAIM.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CLOSE_TOKEN_ACCOUNT.md : Document closing decompressed token accounts with rent distribution in instructions/CLOSE_TOKEN_ACCOUNT.md
Applied to files:
programs/compressed-token/program/CLAUDE.mdprogram-libs/compressible/docs/CONFIG_ACCOUNT.mdprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdsdk-libs/token-client/src/instructions/transfer2.rsprograms/compressed-token/program/docs/instructions/TRANSFER2.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/DECOMPRESSED_TRANSFER.md : Document SPL-compatible transfers between decompressed accounts in instructions/DECOMPRESSED_TRANSFER.md
Applied to files:
programs/compressed-token/program/CLAUDE.mdprogram-libs/compressible/docs/CONFIG_ACCOUNT.mdsdk-libs/compressed-token-sdk/src/account2.rsprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdsdk-libs/token-client/src/instructions/transfer2.rsprograms/compressed-token/program/docs/instructions/TRANSFER2.mdprogram-tests/compressed-token-test/tests/transfer2/compress_spl_failing.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/mint_action/** : MintAction must implement the 9 listed actions and handle both compressed and decompressed minting flows
Applied to files:
programs/compressed-token/program/CLAUDE.md
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/docs/instructions/*.md : Each instruction doc must include: path, description, instruction_data (code paths), Accounts (order and checks), instruction logic and checks, and Errors (with causes)
Applied to files:
programs/compressed-token/program/CLAUDE.mdprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/{claim/**,withdraw_funding_pool.rs} : Enforce Not Inactive config validation for Claim and Withdraw Funding Pool instructions
Applied to files:
programs/compressed-token/program/CLAUDE.mdsdk-libs/compressed-token-sdk/src/instructions/claim.rsprograms/compressed-token/program/docs/instructions/CLAIM.mdprograms/compressed-token/program/docs/instructions/WITHDRAW_FUNDING_POOL.md
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/docs/ACCOUNTS.md : Accounts documentation must include: description, discriminator, state layout, serialization example, hashing (only for compressed accounts), derivation (only for PDAs), and associated instructions
Applied to files:
program-libs/compressible/docs/CONFIG_ACCOUNT.mdprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/docs/CONFIG_ACCOUNT.md : Maintain documentation for CompressibleConfig structure and methods in docs/CONFIG_ACCOUNT.md
Applied to files:
program-libs/compressible/docs/CONFIG_ACCOUNT.md
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/CREATE_TOKEN_ACCOUNT.md : Document Create Token Account & Associated Token Account instructions in instructions/CREATE_TOKEN_ACCOUNT.md
Applied to files:
program-libs/compressible/docs/CONFIG_ACCOUNT.mdprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/{create_token_account.rs,create_associated_token_account.rs} : Enforce ACTIVE-only config validation for Create CToken Account and Create Associated CToken Account instructions
Applied to files:
program-libs/compressible/docs/CONFIG_ACCOUNT.mdsdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rsprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprogram-tests/compressed-token-test/tests/ctoken/shared.rsprograms/compressed-token/program/src/lib.rs
📚 Learning: 2025-10-15T03:45:40.029Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.029Z
Learning: Applies to programs/compressed-token/program/docs/**/ACCOUNTS.md : Maintain ACCOUNTS.md with complete account layouts and data structures
Applied to files:
program-libs/compressible/docs/CONFIG_ACCOUNT.md
📚 Learning: 2025-10-15T03:46:26.758Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.758Z
Learning: Applies to programs/registry/src/account_compression_cpi/*.rs : Context structs for wrapper instructions must include standard accounts: optional registered_forester_pda (mut), authority Signer, cpi_authority with seeds/bump for CPI_AUTHORITY_PDA_SEED, registered_program_pda, target program handle, log_wrapper, and mutable target_account.
Applied to files:
program-libs/compressible/docs/CONFIG_ACCOUNT.mdsdk-tests/sdk-token-test/tests/compress_and_close_cpi.rsprograms/registry/src/compressible/withdraw_funding_pool.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/**/ACCOUNTS.md : Provide complete account layouts and data structures in ACCOUNTS.md
Applied to files:
program-libs/compressible/docs/CONFIG_ACCOUNT.mdprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/close_token_account{.rs,/**} : On closing ctoken accounts: if compressible, return rent exemption to the rent recipient; send remaining lamports to the destination
Applied to files:
program-libs/compressible/docs/CONFIG_ACCOUNT.mdsdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rsprogram-tests/compressed-token-test/tests/transfer2/compress_failing.rssdk-tests/sdk-token-test/tests/compress_and_close_cpi.rssdk-libs/compressed-token-sdk/src/instructions/decompress_full.rsprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdsdk-libs/token-client/src/instructions/transfer2.rssdk-tests/sdk-token-test/src/process_four_transfer2.rsprograms/compressed-token/program/docs/instructions/TRANSFER2.mdsdk-tests/sdk-token-test/src/process_compress_full_and_close.rsprogram-tests/compressed-token-test/tests/ctoken/shared.rssdk-libs/compressed-token-sdk/src/instructions/compress_and_close.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Refactor rent logic so that 1 lamport is the minimum rent payment
Applied to files:
program-tests/compressed-token-test/tests/transfer2/compress_failing.rsprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprogram-tests/compressed-token-test/tests/transfer2/decompress_failing.rsprogram-libs/ctoken-types/src/instructions/extensions/compressible.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/config.rs : Update config parameters including max write fee and max funded epoch
Applied to files:
program-tests/compressed-token-test/tests/transfer2/compress_failing.rsprogram-tests/compressed-token-test/tests/transfer2/decompress_failing.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: CToken account layout matches SPL token accounts with a custom Compressible extension; compressed mint accounts support the TokenMetadata extension
Applied to files:
program-tests/compressed-token-test/tests/transfer2/compress_failing.rsprograms/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdsdk-libs/token-client/src/instructions/transfer2.rssdk-tests/sdk-token-test/src/process_compress_full_and_close.rsprogram-tests/compressed-token-test/tests/transfer2/compress_spl_failing.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/TRANSFER2.md : Document the batch transfer instruction supporting compressed/decompressed operations in instructions/TRANSFER2.md
Applied to files:
sdk-libs/compressed-token-sdk/src/account2.rsprograms/compressed-token/program/docs/instructions/TRANSFER2.md
📚 Learning: 2025-10-15T03:46:26.758Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.758Z
Learning: Applies to programs/registry/src/account_compression_cpi/**/*.rs : Pass the data Vec<u8> through unchanged from the wrapper to the target program CPI; the target program performs deserialization.
Applied to files:
programs/registry/src/compressible/withdraw_funding_pool.rs
📚 Learning: 2025-10-15T03:46:26.758Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/registry/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:26.758Z
Learning: Applies to programs/registry/src/account_compression_cpi/**/*.rs : CPI processing functions must derive PDA signer seeds as [CPI_AUTHORITY_PDA_SEED, bump] and use CpiContext::new_with_signer with cpi_authority as the authority account and mapped target accounts.
Applied to files:
programs/registry/src/compressible/withdraw_funding_pool.rs
📚 Learning: 2025-10-15T03:45:40.029Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:40.029Z
Learning: Applies to programs/compressed-token/program/docs/**/instructions/CREATE_TOKEN_ACCOUNT.md : Provide CREATE_TOKEN_ACCOUNT.md in the instructions/ directory documenting create token account and associated token account instructions
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Determine compressibility and compute rent using calculate_rent_and_balance
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdsdk-libs/token-client/src/instructions/transfer2.rs
📚 Learning: 2025-10-15T03:44:42.664Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/compressible/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:44:42.664Z
Learning: Applies to program-libs/compressible/src/rent.rs : Update RentConfig values at claim time to reflect current policy
Applied to files:
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdprograms/registry/src/compressible/claim.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/src/transfer2/** : Transfer2 must support Compress, Decompress, and CompressAndClose modes and perform multi-mint sum checks
Applied to files:
programs/compressed-token/program/docs/instructions/TRANSFER2.mdprograms/compressed-token/program/tests/multi_sum_check.rs
📚 Learning: 2025-10-15T03:45:17.264Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:45:17.264Z
Learning: Applies to programs/compressed-token/program/programs/compressed-token/anchor/src/lib.rs : Define all program-specific error codes in anchor_compressed_token::ErrorCode and expose them for program-wide use
Applied to files:
programs/compressed-token/program/docs/instructions/TRANSFER2.mdprograms/compressed-token/program/tests/multi_sum_check.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/discriminator.rs : Define and keep discriminator constants and the Discriminator trait in discriminator.rs for compile-time verification
Applied to files:
programs/compressed-token/program/src/lib.rs
📚 Learning: 2025-10-11T21:59:25.201Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: program-libs/account-checks/CLAUDE.md:0-0
Timestamp: 2025-10-11T21:59:25.201Z
Learning: Applies to program-libs/account-checks/src/**/*.rs : Validate account type with 8-byte discriminators using check_discriminator before deserialization
Applied to files:
programs/compressed-token/program/src/lib.rs
📚 Learning: 2025-10-15T03:46:03.545Z
Learnt from: CR
PR: Lightprotocol/light-protocol#0
File: programs/compressed-token/program/docs/instructions/CLAUDE.md:0-0
Timestamp: 2025-10-15T03:46:03.545Z
Learning: Applies to programs/compressed-token/program/docs/instructions/instructions/WITHDRAW_FUNDING_POOL.md : Document withdrawal from the rent recipient funding pool in instructions/WITHDRAW_FUNDING_POOL.md
Applied to files:
programs/compressed-token/program/docs/instructions/WITHDRAW_FUNDING_POOL.md
🧬 Code graph analysis (13)
program-tests/compressed-token-test/tests/transfer2/compress_failing.rs (1)
sdk-libs/compressed-token-sdk/src/account2.rs (1)
new_empty(99-114)
sdk-libs/compressed-token-sdk/src/instructions/decompress_full.rs (1)
sdk-libs/compressed-token-sdk/src/account2.rs (1)
new(32-60)
sdk-libs/token-client/src/instructions/transfer2.rs (1)
sdk-libs/compressed-token-sdk/src/account2.rs (5)
new(32-60)new_delegated(66-96)owner(383-385)mint(371-373)new_empty(99-114)
sdk-tests/sdk-token-test/src/process_four_transfer2.rs (1)
sdk-libs/compressed-token-sdk/src/account2.rs (1)
new(32-60)
program-tests/compressed-token-test/tests/transfer2/decompress_failing.rs (1)
sdk-libs/compressed-token-sdk/src/account2.rs (1)
new(32-60)
program-tests/compressed-token-test/tests/transfer2/transfer_failing.rs (1)
sdk-libs/compressed-token-sdk/src/account2.rs (1)
new(32-60)
sdk-tests/sdk-token-test/src/process_compress_full_and_close.rs (1)
sdk-libs/compressed-token-sdk/src/account2.rs (1)
new_empty(99-114)
program-tests/compressed-token-test/tests/ctoken/create_ata.rs (4)
program-tests/compressed-token-test/tests/ctoken/shared.rs (3)
setup_account_test(40-63)create_and_assert_ata(400-461)create_and_assert_ata_fails(464-514)sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs (3)
create_compressible_associated_token_account(41-45)create_associated_token_account(98-104)derive_ctoken_ata(226-235)sdk-libs/program-test/src/utils/assert.rs (1)
assert_rpc_error(7-144)program-tests/utils/src/assert_create_token_account.rs (1)
assert_create_associated_token_account(258-291)
program-tests/compressed-token-test/tests/ctoken/shared.rs (8)
sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs (5)
create_associated_token_account(98-104)derive_ctoken_ata(226-235)create_compressible_associated_token_account_idempotent(48-52)create_compressible_associated_token_account(41-45)create_associated_token_account_idempotent(107-113)sdk-libs/compressed-token-sdk/src/instructions/create_token_account/instruction.rs (2)
create_token_account(90-116)create_compressible_token_account(38-88)sdk-libs/program-test/src/forester/compress_and_close_forester.rs (1)
compress_and_close_forester(38-244)program-tests/utils/src/assert_close_token_account.rs (1)
assert_close_token_account(8-106)program-tests/utils/src/assert_create_token_account.rs (2)
assert_create_token_account(236-252)assert_create_associated_token_account(258-291)sdk-libs/program-test/src/utils/assert.rs (1)
assert_rpc_error(7-144)sdk-libs/token-client/src/instructions/transfer2.rs (1)
create_generic_transfer2_instruction(145-638)js/stateless.js/src/utils/instruction.ts (1)
PackedAccounts(5-99)
programs/compressed-token/program/src/lib.rs (1)
programs/compressed-token/program/src/ctoken_transfer.rs (1)
process_ctoken_transfer(19-34)
program-tests/compressed-token-test/tests/transfer2/compress_spl_failing.rs (1)
sdk-libs/compressed-token-sdk/src/account2.rs (2)
mint(371-373)new_empty(99-114)
sdk-libs/compressed-token-sdk/src/instructions/compress_and_close.rs (1)
sdk-libs/compressed-token-sdk/src/account2.rs (1)
new_empty(99-114)
programs/compressed-token/program/tests/multi_sum_check.rs (1)
programs/compressed-token/program/src/transfer2/sum_check.rs (2)
sum_check_multi_mint(92-121)validate_mint_uniqueness(127-161)
🪛 LanguageTool
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
[grammar] ~76-~76: There might be a mistake here.
Context: ...is not exactly 1 epoch - Check: compressible_config.rent_payment != 1 - Error: `ErrorCode::OneEpochPrefundingNot...
(QB_NEW_EN)
[grammar] ~117-~117: There might be a mistake here.
Context: ...* 100 (non-idempotent), 102 (idempotent) enum: `CTokenInstruction::CreateAsso...
(QB_NEW_EN)
[grammar] ~180-~180: There might be a mistake here.
Context: ...epoch (see create ctoken account errors)
(QB_NEW_EN)
programs/compressed-token/program/docs/instructions/CLAIM.md
[grammar] ~3-~3: There might be a mistake here.
Context: ## Claim discriminator: 104 enum: InstructionType::Claim **pat...
(QB_NEW_EN)
programs/compressed-token/program/docs/instructions/WITHDRAW_FUNDING_POOL.md
[grammar] ~3-~3: There might be a mistake here.
Context: ...raw Funding Pool discriminator: 105 enum: `InstructionType::WithdrawFund...
(QB_NEW_EN)
🪛 markdownlint-cli2 (0.18.1)
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
112-112: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
180-180: Unordered list indentation
Expected: 0; Actual: 2
(MD007, ul-indent)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (21)
- GitHub Check: system-programs (sdk-libs, light-sdk-macros light-sdk light-program-test light-client light-compr...
- GitHub Check: system-programs (sdk-anchor-test-program, ["cargo-test-sbf -p sdk-anchor-test", "cargo-test-sbf -...
- GitHub Check: system-programs (sdk-token-test-program, ["cargo-test-sbf -p sdk-token-test"])
- GitHub Check: system-programs (sdk-test-program, ["cargo-test-sbf -p sdk-native-test", "cargo-test-sbf -p sdk-v...
- GitHub Check: Forester e2e test
- GitHub Check: Test batched-merkle-tree-simulate
- GitHub Check: stateless-js-v2
- GitHub Check: stateless-js-v1
- GitHub Check: Test program-libs-slow
- GitHub Check: Test program-libs-fast
- GitHub Check: cli-v1
- GitHub Check: programs (system-cpi-test-v2-functional-account-infos, ["cargo-test-sbf -p system-cpi-v2-test -- ...
- GitHub Check: cli-v2
- GitHub Check: programs (compressed-token-batched-tree, ["cargo-test-sbf -p compressed-token-test -- test_transf...
- GitHub Check: programs (light-system-program-address, ["cargo-test-sbf -p system-test -- test_with_address", "c...
- GitHub Check: programs (compressed-token-and-e2e, ["cargo-test-sbf -p compressed-token-test --test v1", "cargo-...
- GitHub Check: programs (system-cpi-test-v2-functional-read-only, ["cargo-test-sbf -p system-cpi-v2-test -- func...
- GitHub Check: programs (system-cpi-test, ["cargo-test-sbf -p system-cpi-test", "cargo test -p light-system-prog...
- GitHub Check: programs (account-compression-and-registry, ["cargo-test-sbf -p account-compression-test", "cargo...
- GitHub Check: programs (light-system-program-compression, ["cargo-test-sbf -p system-test -- test_with_compress...
- GitHub Check: lint
🔇 Additional comments (24)
sdk-tests/sdk-token-test/src/process_four_transfer2.rs (1)
190-192: LGTM! Clean API migration.The changes correctly migrate from the old API where
output_tree_indexwas passed toCTokenAccount2::newto the new API where it's specified once viaTransfer2Inputs.output_queue. This consolidation simplifies the API and reduces redundancy, as all accounts in a transfer now share a single output queue index.The migration is consistent across both transfer operations and properly maintains error handling.
Also applies to: 200-202, 244-244
programs/registry/src/compressible/withdraw_funding_pool.rs (1)
47-48: No action required: WithdrawFundingPool discriminator 105 matches compressed-token programprogram-libs/ctoken-types/src/error.rs (1)
130-131: LGTM: TooManySeeds variant correctly implemented and usedThe
TooManySeedsvariant, message, and error code (18041) follow existing patterns, and its usage in seed-limit checks has been verified.programs/registry/src/compressible/claim.rs (1)
37-38: LGTM! Discriminator update consistent with SDK.The discriminator update from 107 to 104 is correct and consistent with the corresponding change in
sdk-libs/compressed-token-sdk/src/instructions/claim.rs. The comment accurately reflects the new discriminator value.As noted in the SDK file review, this is a breaking change requiring coordinated deployment across all components.
sdk-libs/compressed-token-sdk/src/instructions/claim.rs (1)
36-36: Discriminator update verified; breaking change requires coordinated deployment.Verification confirms no remaining references to discriminator 107u8 in SDK code—the update to 104u8 is cleanly applied. The breaking change concern remains valid and critical: old SDK clients will reject transactions against the new on-chain program expecting 104, and new SDK clients will fail against old programs still expecting 107. Ensure atomic deployment of SDK and on-chain program.
sdk-libs/compressed-token-sdk/src/instructions/create_associated_token_account.rs (3)
158-158: Type change correctly propagated through function signature.The
u64 → u8type change forpre_pay_num_epochsis correctly propagated through thecompressible_configtuple parameter and unpacking logic. The assignment torent_paymentat line 174 maintains type consistency.Also applies to: 169-174
32-32: Program-side validation and documentation confirmed; type narrowing approved.Verification confirms the 1-epoch prefunding constraint is properly enforced:
- Validation checks
rent_payment == 1in bothcreate_associated_token_account.rs:152andcreate_token_account.rs:165- Returns
OneEpochPrefundingNotAllowederror (code 6116) with clear error messaging- Constraint is documented in
programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.mdwith explanation of the epoch boundary footgun preventionThe type narrowing from
u64tou8is appropriate for epoch counts and aligns with the PR's constraint enforcement.
15-16: Discriminators verified as consistent with program specification.The values (100 for non-idempotent, 102 for idempotent) match the program documentation in
CREATE_TOKEN_ACCOUNT.md. No consistency issues detected.sdk-libs/compressed-token-sdk/src/instructions/withdraw_funding_pool.rs (3)
23-26: LGTM! The instruction data encoding is correct.The instruction data is correctly formatted with the discriminator, bump, and amount in the expected order and byte layout.
28-37: LGTM! Account setup is correct.The accounts are properly configured with the correct mutability and signer flags:
- Pool PDA is writable (source of funds)
- Authority is readonly and a signer
- Destination is writable (receives funds)
- System program is readonly
24-24: WithdrawFundingPool discriminator consistency confirmed
The 105 value is used across the SDK, registry program, on-chain compressed-token program, and no 108 references remain in code or tests.sdk-libs/compressed-token-sdk/src/account2.rs (2)
32-60: LGTM: Simplified constructor signature.Removing the
output_merkle_tree_indexparameter streamlines the API by centralizing output queue configuration at the instruction level rather than per-account.
469-480: Based on verification of the codebase, the hardcodedoutput_queue: 0for decompressed account transfers is appropriate and consistent.Comment clarity could be improved.
The value
output_queue: 0appears correctly across multiple decompressed-only transfer patterns (account2.rslines 479, 556 andcompress_and_close.rsline 258), and the field is used for queue indices calculation even in decompressed contexts. However, the comment "Decompressed accounts only, no output queue needed" is slightly ambiguous compared to the clearer comment incompress_and_close.rs("Output queue is at index 0 in packed_accounts"), which explicitly documents what the index value represents.Consider updating the comments to be consistent and explicit about what
output_queue: 0means in this context—either clarify that it refers to index placement or that compressed token outputs are not generated.sdk-libs/program-test/src/forester/compress_and_close_forester.rs (1)
84-84: LGTM: Removed unused index binding.The
output_tree_indexbinding is no longer needed since output queue handling is now centralized.sdk-tests/sdk-token-test/tests/test_compress_full_and_close.rs (1)
260-261: LGTM: Consistent removal of unused index binding.programs/compressed-token/program/CLAUDE.md (2)
61-76: LGTM: Documentation updated for discriminator changes.The discriminator updates are consistent with the code changes and clearly documented.
275-275: Good clarification on compress_to_pubkey validation.The added note clarifies that
compress_to_pubkeyvalidation ONLY applies when the rent authority closes, not when the owner closes. This is an important distinction for understanding the permission model.sdk-libs/compressed-token-sdk/src/instructions/transfer2/instruction.rs (3)
66-66: LGTM: Added output_queue field to Transfer2Inputs.The field is properly wired through the instruction creation flow.
71-80: LGTM: Proper extraction and usage of output_queue.
102-121: LGTM: Correct propagation of output_queue to instruction data.programs/compressed-token/program/docs/instructions/TRANSFER2.md (3)
16-16: LGTM: Discriminator documentation updated.
275-282: Excellent clarification on compress_to_pubkey validation scope.This note clearly distinguishes between owner-initiated and rent-authority-initiated closures, preventing potential confusion about when validation applies.
306-306: LGTM: New DuplicateMint error documented.The error description clearly explains the validation: "Duplicate mint index detected in inputs, outputs, or compressions (same mint referenced by multiple indices or same index used multiple times)."
program-libs/ctoken-types/src/instructions/transfer2/instruction_data.rs (1)
19-19: The review comment mischaracterizes this change as a breaking change.The
output_queuefield has a sensible default value (0 foru8), andTransfer2InputsderivesDefault. All 11 callsites identified are correctly updated: 10 explicitly provideoutput_queue, and 1 (decompress_full.rs:110–115) properly uses..Default::default(), which setsoutput_queueto its default. This pattern is idiomatic Rust and requires no corrective action.Likely an incorrect or invalid review comment.
| - `rent_payment`: Number of epochs to prepay for rent (u64) | ||
| - `rent_payment = 1` is explicitly forbidden to prevent epoch boundary timing edge case | ||
| - Allowed values: 0 (no prefunding) or 2+ epochs (safe buffer) | ||
| - Rationale: Accounts created with exactly 1 epoch near epoch boundaries could become immediately compressible | ||
| - `write_top_up`: Additional lamports allocated for future write operations on the compressed account | ||
|
|
There was a problem hiding this comment.
Update rent_payment type to match code
CompressibleExtensionInstructionData::rent_payment was narrowed to u8, but this doc still advertises it as u64. Please update the type (and any related wording) so the instruction documentation matches the current serialization.
🤖 Prompt for AI Agents
In programs/compressed-token/program/docs/instructions/CREATE_TOKEN_ACCOUNT.md
around lines 39 to 44, the documentation lists `rent_payment` as a u64 but the
code now serializes it as u8; update the type and any related wording to reflect
`rent_payment: u8` (e.g., "Number of epochs to prepay for rent (u8)"), ensure
allowed values wording still makes sense for an 8-bit range (0 or 2+ epochs) and
adjust any examples or serialization notes to reference u8 instead of u64 so the
doc matches the implementation.
| // Build instruction data: [discriminator(105), pool_pda_bump, amount] | ||
| let mut instruction_data = vec![105u8]; // WithdrawFundingPool instruction discriminator | ||
|
|
||
| instruction_data.extend_from_slice(&amount.to_le_bytes()); |
There was a problem hiding this comment.
Fix the stale comment describing instruction data format.
The comment on line 47 claims the instruction data includes pool_pda_bump, but the code only appends the discriminator (line 48) and amount (line 50). The bump is never added to instruction_data.
Apply this diff to correct the comment:
- // Build instruction data: [discriminator(105), pool_pda_bump, amount]
+ // Build instruction data: [discriminator(105), amount]
let mut instruction_data = vec![105u8]; // WithdrawFundingPool instruction discriminator
instruction_data.extend_from_slice(&amount.to_le_bytes());📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Build instruction data: [discriminator(105), pool_pda_bump, amount] | |
| let mut instruction_data = vec![105u8]; // WithdrawFundingPool instruction discriminator | |
| instruction_data.extend_from_slice(&amount.to_le_bytes()); | |
| // Build instruction data: [discriminator(105), amount] | |
| let mut instruction_data = vec![105u8]; // WithdrawFundingPool instruction discriminator | |
| instruction_data.extend_from_slice(&amount.to_le_bytes()); |
🤖 Prompt for AI Agents
In programs/registry/src/compressible/withdraw_funding_pool.rs around lines 47
to 50, the comment incorrectly states the instruction data contains
`pool_pda_bump` though the code only pushes the discriminator and the amount;
update the comment to accurately describe the data layout (e.g.,
"[discriminator(105), amount]") so it matches the actual instruction_data being
constructed, or alternatively, if the bump is actually required, append the bump
byte to instruction_data—ensure comment and code are consistent.
| pub const CREATE_TOKEN_POOL: [u8; 8] = [23, 169, 27, 122, 147, 169, 209, 152]; | ||
| pub const CREATE_ADDITIONAL_TOKEN_POOL: [u8; 8] = [114, 143, 210, 73, 96, 115, 1, 228]; | ||
| pub const TRANSFER2: u8 = 104; | ||
| pub const TRANSFER2: u8 = 101; |
There was a problem hiding this comment.
🧩 Analysis chain
Breaking change: Discriminator updated.
The TRANSFER2 discriminator changed from 104 to 101. This is a breaking change that affects all clients and must be coordinated with documentation updates.
Verify all usages of the TRANSFER2 discriminator have been updated:
🏁 Script executed:
#!/bin/bash
# Search for any remaining references to the old discriminator value 104
rg -n '\b104\b' --type rust | rg -i 'transfer2|discriminator'Length of output: 0
🏁 Script executed:
#!/bin/bash
# Search for any occurrences of the old discriminator value 104 in Rust code
rg -nP '\b104\b' --type rust -C2 || true
# Search for any occurrences of the old discriminator in markdown documentation
rg -n '104' -g '*.md' -C2 || true
# Search for any usage of the constant TRANSFER2
rg -n 'TRANSFER2' --type rust -C2 || trueLength of output: 14842
Update program docs: correct TRANSFER2 discriminator
Change the Transfer2 discriminator in programs/compressed-token/program/docs/ACCOUNTS.md (line 25) from 104 to 101.
🤖 Prompt for AI Agents
In sdk-libs/compressed-token-types/src/constants.rs around line 52, TRANSFER2 is
defined as 101 but the program docs still list the Transfer2 discriminator as
104; update programs/compressed-token/program/docs/ACCOUNTS.md (around line 25)
to change the Transfer2 discriminator value from 104 to 101 so the documentation
matches the constant, and save the file.
Summary by CodeRabbit
Bug Fixes
Documentation
Tests
Chores