Skip to content

fix(programs): allow account-level delegate to compress CToken (M-02)#2262

Merged
ananas-block merged 2 commits intomainfrom
jorrit/fix-certora-m02-delegate-compress
Feb 10, 2026
Merged

fix(programs): allow account-level delegate to compress CToken (M-02)#2262
ananas-block merged 2 commits intomainfrom
jorrit/fix-certora-m02-delegate-compress

Conversation

@ananas-block
Copy link
Contributor

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

Summary

  • Certora audit M-02: An account-level delegate (set via CTokenApprove) could not compress tokens from a CToken account. check_ctoken_owner() only checked owner and permanent delegate.
  • Fix: Add delegate check in check_ctoken_owner() so delegates approved via CTokenApprove can compress tokens.

Changes

  • owner_validation.rs: Added check for compressed_token.delegate() matching the authority.

Summary by CodeRabbit

  • New Features
    • Authorization for compressed token operations now recognizes account-level delegates as valid signers. The authorization framework has been extended to include owner, permanent delegate, and account-level delegate paths, enabling more flexible permission management.

check_ctoken_owner() only checked owner and permanent delegate.
An account-level delegate (approved via CTokenApprove) could not
compress tokens. Added delegate check after permanent delegate.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 9, 2026

Caution

Review failed

An error occurred during the review process. Please try again later.

Walkthrough

The change adds account-level delegate validation to the check_ctoken_owner function. When the authority key matches a delegate stored on a compressed token, authorization succeeds before reaching the OwnerMismatch error, extending the authorization chain to include owner, permanent delegate, and account delegate paths.

Changes

Cohort / File(s) Summary
Owner Delegate Validation
programs/compressed-token/program/src/shared/owner_validation.rs
Adds account-level delegate check in check_ctoken_owner, allowing authorization when authority_key matches the delegate present on the compressed token, creating an additional successful authorization path before error handling.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested labels

ai-review

Suggested reviewers

  • sergeytimoshin
  • SwenSchaeferjohann

Poem

🔐 A delegate steps forth with key in hand,
Where owner once stood guard alone,
Three paths now open through the land—
Authorization's circle has grown! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main change: allowing account-level delegates to compress CTokens, addressing the M-02 audit finding.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 70.00%.

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jorrit/fix-certora-m02-delegate-compress

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

❤️ Share

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

@ananas-block ananas-block changed the title fix(M-02): allow account-level delegate to compress CToken fix(programs): allow account-level delegate to compress CToken (M-02) Feb 9, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@programs/compressed-token/program/src/shared/owner_validation.rs`:
- Around line 118-119: The returned Err(ErrorCode::OwnerMismatch.into()) is too
generic now that authority can be owner, permanent delegate, or account
delegate; add a clearer error variant (e.g., ErrorCode::InvalidAuthorizer or
ErrorCode::AuthorityNotAuthorized) in the ErrorCode enum and replace the usage
in owner_validation.rs (the site that currently returns OwnerMismatch) with the
new variant, or alternatively add distinct variants (OwnerNotMatched,
DelegateNotMatched) and return the most appropriate one; update any
error-to-string mappings/tests that reference OwnerMismatch accordingly.
- Around line 111-116: The delegate check in owner_validation.rs currently
allows any account-level delegate (compressed_token.delegate()) to compress
regardless of delegated_amount; either explicitly document this design in the
APPROVE instruction docs and add a clarifying comment in owner_validation module
referencing the M-02 audit, or enforce an amount check here by fetching the
delegate record's delegated_amount and returning an error unless
delegated_amount >= the amount being compressed (or point to where downstream
enforcement occurs). Update the APPROVE instruction documentation and add an
inline comment in owner_validation.rs near the compressed_token.delegate() check
if choosing documentation, or add the delegated_amount comparison and
corresponding error return in the same block if choosing to enforce.

Comment on lines +118 to 119
// Authority is neither owner, permanent delegate, nor account delegate
Err(ErrorCode::OwnerMismatch.into())
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Error message could be more specific now that there are three authorization paths.

The OwnerMismatch error is returned when authority is neither owner, permanent delegate, nor account delegate. The error name OwnerMismatch is a bit misleading now that delegates are valid authorizers too. This is pre-existing, so just a minor observation — no action needed unless you want to improve diagnostics.

🤖 Prompt for AI Agents
In `@programs/compressed-token/program/src/shared/owner_validation.rs` around
lines 118 - 119, The returned Err(ErrorCode::OwnerMismatch.into()) is too
generic now that authority can be owner, permanent delegate, or account
delegate; add a clearer error variant (e.g., ErrorCode::InvalidAuthorizer or
ErrorCode::AuthorityNotAuthorized) in the ErrorCode enum and replace the usage
in owner_validation.rs (the site that currently returns OwnerMismatch) with the
new variant, or alternatively add distinct variants (OwnerNotMatched,
DelegateNotMatched) and return the most appropriate one; update any
error-to-string mappings/tests that reference OwnerMismatch accordingly.

@ananas-block ananas-block force-pushed the jorrit/fix-certora-m02-delegate-compress branch from 19a820d to da38720 Compare February 9, 2026 16:12
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 9, 2026

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":500,"request":{"method":"PATCH","url":"https://api.github.com/repos/Lightprotocol/light-protocol/issues/comments/3870002648","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- This is an auto-generated comment: failure by coderabbit.ai -->\n\n> [!CAUTION]\n> ## Review failed\n> \n> An error occurred during the review process. Please try again later.\n\n<!-- end of auto-generated comment: failure by coderabbit.ai -->\n\n<!-- walkthrough_start -->\n\n## Walkthrough\n\nThe change adds account-level delegate validation to the `check_ctoken_owner` function. When the authority key matches a delegate stored on a compressed token, authorization succeeds before reaching the OwnerMismatch error, extending the authorization chain to include owner, permanent delegate, and account delegate paths.\n\n## Changes\n\n|Cohort / File(s)|Summary|\n|---|---|\n|**Owner Delegate Validation** <br> `programs/compressed-token/program/src/shared/owner_validation.rs`|Adds account-level delegate check in `check_ctoken_owner`, allowing authorization when authority_key matches the delegate present on the compressed token, creating an additional successful authorization path before error handling.|\n\n## Estimated code review effort\n\n🎯 2 (Simple) | ⏱️ ~10 minutes\n\n## Possibly related PRs\n\n- Lightprotocol/light-protocol#2022 — Modifies owner and delegate authorization logic in `verify_owner_or_delegate_signer`, creating parallel changes to the authorization validation framework.\n\n## Suggested labels\n\n`ai-review`\n\n## Suggested reviewers\n\n- sergeytimoshin\n- SwenSchaeferjohann\n\n## Poem\n\n> 🔐 A delegate steps forth with key in hand,  \n> Where owner once stood guard alone,  \n> Three paths now open through the land—  \n> Authorization's circle has grown! ✨\n\n<!-- walkthrough_end -->\n\n<!-- pre_merge_checks_walkthrough_start -->\n\n<details>\n<summary>🚥 Pre-merge checks | ✅ 3</summary>\n\n<details>\n<summary>✅ Passed checks (3 passed)</summary>\n\n|     Check name     | Status   | Explanation                                                                                                                                             |\n| :----------------: | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------ |\n|  Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled.                                                                                             |\n|     Title check    | ✅ Passed | The title clearly and specifically summarizes the main change: allowing account-level delegates to compress CTokens, addressing the M-02 audit finding. |\n| Docstring Coverage | ✅ Passed | Docstring coverage is 100.00% which is sufficient. The required threshold is 70.00%.                                                                    |\n\n</details>\n\n<sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub>\n\n</details>\n\n<!-- pre_merge_checks_walkthrough_end -->\n\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing touches</summary>\n\n<details>\n<summary>🧪 Generate unit tests (beta)</summary>\n\n- [ ] <!-- {\"checkboxId\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Create PR with unit tests\n- [ ] <!-- {\"checkboxId\": \"07f1e7d6-8a8e-4e23-9900-8731c2c87f58\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Post copyable unit tests in a comment\n- [ ] <!-- {\"checkboxId\": \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Commit unit tests in branch `jorrit/fix-certora-m02-delegate-compress`\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=Lightprotocol/light-protocol&utm_content=2262)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->\n\n<!-- internal state start -->\n\n\n<!-- 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 -->\n\n<!-- internal state end -->"},"request":{"retryCount":3,"retries":3,"retryAfter":16}},"response":{"url":"https://api.github.com/repos/Lightprotocol/light-protocol/issues/comments/3870002648","status":500,"headers":{"access-control-allow-origin":"*","access-control-expose-headers":"ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset","content-length":"0","content-security-policy":"default-src 'none'","content-type":"application/json; charset=utf-8","date":"Mon, 09 Feb 2026 16:14:46 GMT","referrer-policy":"origin-when-cross-origin, strict-origin-when-cross-origin","server":"github.com","strict-transport-security":"max-age=31536000; includeSubdomains; preload","vary":"Accept-Encoding, Accept, X-Requested-With","x-accepted-github-permissions":"issues=write; pull_requests=write","x-content-type-options":"nosniff","x-frame-options":"deny","x-github-api-version-selected":"2022-11-28","x-github-media-type":"github.v3; format=json","x-github-request-id":"4004:59E6F:CCA9F9:373EE22:698A07F4","x-ratelimit-limit":"5000","x-ratelimit-remaining":"4802","x-ratelimit-reset":"1770655550","x-ratelimit-resource":"core","x-ratelimit-used":"198","x-xss-protection":"0"},"data":""}}

2 similar comments
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 9, 2026

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":500,"request":{"method":"PATCH","url":"https://api.github.com/repos/Lightprotocol/light-protocol/issues/comments/3870002648","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- This is an auto-generated comment: failure by coderabbit.ai -->\n\n> [!CAUTION]\n> ## Review failed\n> \n> An error occurred during the review process. Please try again later.\n\n<!-- end of auto-generated comment: failure by coderabbit.ai -->\n\n<!-- walkthrough_start -->\n\n## Walkthrough\n\nThe change adds account-level delegate validation to the `check_ctoken_owner` function. When the authority key matches a delegate stored on a compressed token, authorization succeeds before reaching the OwnerMismatch error, extending the authorization chain to include owner, permanent delegate, and account delegate paths.\n\n## Changes\n\n|Cohort / File(s)|Summary|\n|---|---|\n|**Owner Delegate Validation** <br> `programs/compressed-token/program/src/shared/owner_validation.rs`|Adds account-level delegate check in `check_ctoken_owner`, allowing authorization when authority_key matches the delegate present on the compressed token, creating an additional successful authorization path before error handling.|\n\n## Estimated code review effort\n\n🎯 2 (Simple) | ⏱️ ~10 minutes\n\n## Possibly related PRs\n\n- Lightprotocol/light-protocol#2022 — Modifies owner and delegate authorization logic in `verify_owner_or_delegate_signer`, creating parallel changes to the authorization validation framework.\n\n## Suggested labels\n\n`ai-review`\n\n## Suggested reviewers\n\n- sergeytimoshin\n- SwenSchaeferjohann\n\n## Poem\n\n> 🔐 A delegate steps forth with key in hand,  \n> Where owner once stood guard alone,  \n> Three paths now open through the land—  \n> Authorization's circle has grown! ✨\n\n<!-- walkthrough_end -->\n\n<!-- pre_merge_checks_walkthrough_start -->\n\n<details>\n<summary>🚥 Pre-merge checks | ✅ 3</summary>\n\n<details>\n<summary>✅ Passed checks (3 passed)</summary>\n\n|     Check name     | Status   | Explanation                                                                                                                                             |\n| :----------------: | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------ |\n|  Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled.                                                                                             |\n|     Title check    | ✅ Passed | The title clearly and specifically summarizes the main change: allowing account-level delegates to compress CTokens, addressing the M-02 audit finding. |\n| Docstring Coverage | ✅ Passed | Docstring coverage is 100.00% which is sufficient. The required threshold is 70.00%.                                                                    |\n\n</details>\n\n<sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub>\n\n</details>\n\n<!-- pre_merge_checks_walkthrough_end -->\n\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing touches</summary>\n\n<details>\n<summary>🧪 Generate unit tests (beta)</summary>\n\n- [ ] <!-- {\"checkboxId\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Create PR with unit tests\n- [ ] <!-- {\"checkboxId\": \"07f1e7d6-8a8e-4e23-9900-8731c2c87f58\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Post copyable unit tests in a comment\n- [ ] <!-- {\"checkboxId\": \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Commit unit tests in branch `jorrit/fix-certora-m02-delegate-compress`\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=Lightprotocol/light-protocol&utm_content=2262)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->\n\n<!-- internal state start -->\n\n\n<!-- DwQgtGAEAqAWCWBnSTIEMB26CuAXA9mAOYCmGJATmriQCaQDG+Ats2bgFyQAOFk+AIwBWJBrngA3EsgEBPRvlqU0AgfFwA6NPEgQAfACgjoCEYDEZyAAUASpETZWaCrKPR1AGxJcAZvAAeABQAsmAADABMAJRcaB4e+ADu6AxM2Bi4YF5SHpBKXkTUJJAECsy80sgAwtD4ANZkkJAGAHKOApRcEREAbBFNBgCqNgAyXLC4uNyIHAD0s0TqsNgCGkzMsyPwRBO8+ARMHrMe2xNgewf4R9zY8bPdfQODiJ3oGJhoiGACCQx1AwBlfDYCgMYoCKgYBiwLhCfAUCjqWZ+fxgMEUAhUMDMSJgfIkQo0NEsCqIZCAJMIYM5SLhIBDMNCuMxtFhmgDcNRsDN+NxGs0qhQSEV6NQupEeuEIuEAJzQMIADg4YWlHAALABGABaRgBjmZLg4BigAEFaLRBWTpJAqpRMWgcLR1JA/BhHRgiJBQpFYqlgRksiQcnkSAUishAi9aRJ4PaavUyMbuHspFEFLd6Bh9mVScgCA0MMgfBQWOhrbV8yk0hk6aI0FzirhYMUSP4kOJ3Ywm39+BgPPIJHF4LRhSUm/xEuQ+Jh6I3iryKMzyNX8YSSBojdbYJhSFxsNxhzRIAADaGiOoAfTE8Yw56Sk8CUSPJXw6A8iBfp+7Pnhx/WObo555mQGgrkUD5PsyuDQvAHazjgjbwuosgADSQGQKgnB2oE0MgaBJsWUj0NGsblgm+H4FIz48JQ34LtmFrIPg87UPA+AFuuUAAGLwF4kDMIo8B+HQXBHnelDngOJwHqxGAaBQiBPoEaBmnQwahoen7/GgPg0Hw86LuwakEkUUTrkaYCGAYJhQGQ9D4D48GEKQk4jusbAZFwvD8MIojiFIMjyEwShUKo6haDo+hWeAUBwKgqCYI5xBkMoND0G57BcFQyQOE4Lh0oFijKKFmjaLoFlGFFpgGHsRBUMwiCzH+DF0GAQEYLMNV1bMiCgt1W6CrQsxiRQEmDtJbFyTMBgAESzQYFiQMaACSSUual9h6s48j2Z227SEYJpmrhnZns6P4JWgvrpJk2QhkZq6QIERYlnG+aJsmJCpjBJ1/JebW3hOlAaJAS0OXBdYIYiuCyOeDTyJBp65mO2FzhahlsaOxRNZUqltahcE+OkYgyZAmbJIKuAggWkAAPJ1IED6ph0tGo4o2AMDBHpwTTgMUMESAI7AaEIvCwOxcgLY0K6uF4LAiEAF4sRjpQwQwHjYEo46Tqh+mYIZKOodOlZ+rSKPA1UbG4MWuQ+AkyRkygULq0ouFYMpjriGxcQbaklSE7k3DUELvCsXwpQEzB3uUMWFBmeYljGh4ulK9T4fI6IHjOCnjEOS23DwutP43D88AMGhGTqPA+0bi0H5bu6VqlIg2zvJTFr8Ln/j5xiqlFysJxl+wlfSGZC3BJggnSLS3G8ca7x9vLlBGFs5DINCe20FwADU8qzGA6pGAAoog4iQapQXFIK0YkMkJA+LRnCenQ8CODNc3mZZ1nl3ZDkQ05yVUHWulDykAsobVyvIOQChgoqDUCVCK5Uv5uXUOeIciBzxXyrokACJ9nC0kipVKAPhaBhFoBEMIPQ0DSj6BEaU5CBAAFZ1RULCCQMI6p5SqnlBEdU0oADMPh1QMAiCQAA7HwnoYQyqf2imUZgKC0EYMDFggCtlpGEJ4IKc8bAKCkEvF2Oo6DcEYnUQYAA3gYJo00kC2AAEK/AaLQC2rB2BWHwCfOg01fBxBeMhSxkBpqIDlumex+A/i2C8c6HxJA/FWKQDTKQCIhxKAwJEnw0TYkBMdLQGw6QAAiYT2SIndIgKoBjIlW2wDE/x01sm5IwO4XAXgylngqRQKpmTalDnqXk6QDBETcE9hgFpfw0kZJqZhRxS0yRVMQEUyJs1OmZxPiMuoNhpC3FwIgSJABtfxTQLFNCOQEzSLQ0BsAWb0xA/T4CDJJqs6amTjmBI5JTbZXBKnVOOVYvOmdW4yQWas+wdRbm8noFAC2SgbCwPUIATAJkAIB2AGIMOV9TyFQOhH4dANCPP2Uc6a/ElALMSM4DAnNcXfICYhRY89VlnIuVwWpfSBlDOmnigAvk8yAhzvnTVOeckgCzGm8U0hS3luC3ltI6Xin5Xc/kpyFWOcQTSsZeGcH2N49BEC8g5n4BgcQNWoucPAReSNijMm+uvBusR4hJE5sba6yK7oo1zB+EkDEyzXkQIbM0DF7VwS9P0OsHtnQwTdEQHFXKrGEsFYyklFAyXujFc8wUTAMB+CICCWNUS3xfN5dSyOHg6UCoWcqrwbLjmcrxTy55/KGUBIKQwE+xSPQW0SWgUgyb8USq5FKvNzzfkfFZYyxtzb7VMHbaQFAyB1RhDCBoOdABSSAiQEDQmnRte+pcq4ZDFmOQUABHbA8ABqjgtHLDw9BUCiPnUuyNMqAkxuJaS8lUaqWIhpXEYt9balhLHSUitRz2X+IALpLM+LgWwVybl3LYgsgQPRVTSnlD0DoojmaiLBNQkhPgejSlEeqShYQGACOlCQdUDDRHoeVOqWgAhVS0IIwwVUPhhF8No5IxDYi+EkbFdNZZkGbDCuzbU3hgjVRoB4fqnooi6O9B6LOnwAhUh8PEbQBhPh5SRDCGgPhtA+gCDCAwtAqoeg+FEQw7ofCIhobQCQaUaAGECD4fKaUfHaB/qtpzNtyhSBLQyJQee7IiiRJrQEzq5yGrY0tLQVq14OrFlquc7qvUgnODoENXmo0pIp0mqFh900CAcg8JxImQz3mQHVG+6ahMoTlYAOpLFHV5gDXA+Ecv8cB4DGiKjaMoHozS6C1GRS/n/c8gd6znglSQKbHITEELMfxiDVg6wvFoMaXA6zr7YKcSweRuALbXS8WEbro28D4HG6tmb03zzDYskAA -->\n\n<!-- internal state end -->"},"request":{"retryCount":3,"retries":3,"retryAfter":16}},"response":{"url":"https://api.github.com/repos/Lightprotocol/light-protocol/issues/comments/3870002648","status":500,"headers":{"access-control-allow-origin":"*","access-control-expose-headers":"ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset","content-length":"0","content-security-policy":"default-src 'none'","content-type":"application/json; charset=utf-8","date":"Mon, 09 Feb 2026 16:14:46 GMT","referrer-policy":"origin-when-cross-origin, strict-origin-when-cross-origin","server":"github.com","strict-transport-security":"max-age=31536000; includeSubdomains; preload","vary":"Accept-Encoding, Accept, X-Requested-With","x-accepted-github-permissions":"issues=write; pull_requests=write","x-content-type-options":"nosniff","x-frame-options":"deny","x-github-api-version-selected":"2022-11-28","x-github-media-type":"github.v3; format=json","x-github-request-id":"4004:59E6F:CCA9F9:373EE22:698A07F4","x-ratelimit-limit":"5000","x-ratelimit-remaining":"4802","x-ratelimit-reset":"1770655550","x-ratelimit-resource":"core","x-ratelimit-used":"198","x-xss-protection":"0"},"data":""}}

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 9, 2026

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":500,"request":{"method":"PATCH","url":"https://api.github.com/repos/Lightprotocol/light-protocol/issues/comments/3870002648","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- This is an auto-generated comment: failure by coderabbit.ai -->\n\n> [!CAUTION]\n> ## Review failed\n> \n> An error occurred during the review process. Please try again later.\n\n<!-- end of auto-generated comment: failure by coderabbit.ai -->\n\n<!-- walkthrough_start -->\n\n## Walkthrough\n\nThe change adds account-level delegate validation to the `check_ctoken_owner` function. When the authority key matches a delegate stored on a compressed token, authorization succeeds before reaching the OwnerMismatch error, extending the authorization chain to include owner, permanent delegate, and account delegate paths.\n\n## Changes\n\n|Cohort / File(s)|Summary|\n|---|---|\n|**Owner Delegate Validation** <br> `programs/compressed-token/program/src/shared/owner_validation.rs`|Adds account-level delegate check in `check_ctoken_owner`, allowing authorization when authority_key matches the delegate present on the compressed token, creating an additional successful authorization path before error handling.|\n\n## Estimated code review effort\n\n🎯 2 (Simple) | ⏱️ ~10 minutes\n\n## Possibly related PRs\n\n- Lightprotocol/light-protocol#2022 — Modifies owner and delegate authorization logic in `verify_owner_or_delegate_signer`, creating parallel changes to the authorization validation framework.\n\n## Suggested labels\n\n`ai-review`\n\n## Suggested reviewers\n\n- sergeytimoshin\n- SwenSchaeferjohann\n\n## Poem\n\n> 🔐 A delegate steps forth with key in hand,  \n> Where owner once stood guard alone,  \n> Three paths now open through the land—  \n> Authorization's circle has grown! ✨\n\n<!-- walkthrough_end -->\n\n<!-- pre_merge_checks_walkthrough_start -->\n\n<details>\n<summary>🚥 Pre-merge checks | ✅ 3</summary>\n\n<details>\n<summary>✅ Passed checks (3 passed)</summary>\n\n|     Check name     | Status   | Explanation                                                                                                                                             |\n| :----------------: | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------ |\n|  Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled.                                                                                             |\n|     Title check    | ✅ Passed | The title clearly and specifically summarizes the main change: allowing account-level delegates to compress CTokens, addressing the M-02 audit finding. |\n| Docstring Coverage | ✅ Passed | Docstring coverage is 100.00% which is sufficient. The required threshold is 70.00%.                                                                    |\n\n</details>\n\n<sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub>\n\n</details>\n\n<!-- pre_merge_checks_walkthrough_end -->\n\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing touches</summary>\n\n<details>\n<summary>🧪 Generate unit tests (beta)</summary>\n\n- [ ] <!-- {\"checkboxId\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Create PR with unit tests\n- [ ] <!-- {\"checkboxId\": \"07f1e7d6-8a8e-4e23-9900-8731c2c87f58\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Post copyable unit tests in a comment\n- [ ] <!-- {\"checkboxId\": \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Commit unit tests in branch `jorrit/fix-certora-m02-delegate-compress`\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n\n<!-- tips_start -->\n\n---\n\nThanks for using [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=Lightprotocol/light-protocol&utm_content=2262)! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.\n\n<details>\n<summary>❤️ Share</summary>\n\n- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)\n- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)\n- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)\n- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)\n\n</details>\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->\n\n<!-- internal state start -->\n\n\n<!-- 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 -->\n\n<!-- internal state end -->"},"request":{"retryCount":3,"retries":3,"retryAfter":16}},"response":{"url":"https://api.github.com/repos/Lightprotocol/light-protocol/issues/comments/3870002648","status":500,"headers":{"access-control-allow-origin":"*","access-control-expose-headers":"ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset","content-length":"0","content-security-policy":"default-src 'none'","content-type":"application/json; charset=utf-8","date":"Mon, 09 Feb 2026 16:14:46 GMT","referrer-policy":"origin-when-cross-origin, strict-origin-when-cross-origin","server":"github.com","strict-transport-security":"max-age=31536000; includeSubdomains; preload","vary":"Accept-Encoding, Accept, X-Requested-With","x-accepted-github-permissions":"issues=write; pull_requests=write","x-content-type-options":"nosniff","x-frame-options":"deny","x-github-api-version-selected":"2022-11-28","x-github-media-type":"github.v3; format=json","x-github-request-id":"4004:59E6F:CCA9F9:373EE22:698A07F4","x-ratelimit-limit":"5000","x-ratelimit-remaining":"4802","x-ratelimit-reset":"1770655550","x-ratelimit-resource":"core","x-ratelimit-used":"198","x-xss-protection":"0"},"data":""}}

@ananas-block ananas-block merged commit 1e6013c into main Feb 10, 2026
7 checks passed
@ananas-block ananas-block deleted the jorrit/fix-certora-m02-delegate-compress branch February 10, 2026 22:25
SwenSchaeferjohann pushed a commit that referenced this pull request Feb 11, 2026
…#2262)

* fix: allow account-level delegate to compress tokens from CToken (M-02)

check_ctoken_owner() only checked owner and permanent delegate.
An account-level delegate (approved via CTokenApprove) could not
compress tokens. Added delegate check after permanent delegate.

* test: compress by delegate
SwenSchaeferjohann added a commit that referenced this pull request Feb 11, 2026
refactor

remove fetch-accounts

renaming, simplify trait

fomat

excl photon-api submodule

fix: multi-pass cold account lookup in test indexer RPC

Align get_account_interface and get_multiple_account_interfaces with
Photon's lookup strategy: search compressed_accounts by onchain_pubkey,
then by PDA seed derivation, then token_compressed_accounts, then by
token_data.owner. Also fix as_mint() to accept ColdContext::Account
since Photon returns mints as generic compressed accounts.

Co-authored-by: Cursor <cursoragent@cursor.com>

lint

fix lint

fix: reject rent sponsor self-referencing the token account (#2257)

* fix: reject rent sponsor self-referencing the token account

Audit issue #9 (INFO): The rent payer could be the same account as
the target token account being created. Add a check that rejects
this self-reference to prevent accounting issues.

* test: add failing test rent sponsor self reference

fix: process metadata add/remove actions in sequential order (#2256)

* fix: process metadata add/remove actions in sequential order

Audit issue #16 (LOW): should_add_key checked for any add and any
remove independently, ignoring action ordering. An add-remove-add
sequence would incorrectly remove the key. Process actions
sequentially so the final state reflects the actual order.

* chore: format

* test: add randomized test for metadata action processing

Validates that process_extensions_config_with_actions produces correct
AdditionalMetadataConfig for random sequences of UpdateMetadataField
and RemoveMetadataKey actions, covering the add-remove-add bug from
audit issue #16.

* test: add integration test for audit issue #13 (no double rent charge)

Verifies that two compress operations targeting the same compressible
CToken account in a single Transfer2 instruction do not double-charge
the rent top-up budget.

* chore: format extensions_metadata test

fix: validate authority on self-transfer early return (#2252)

* fix: handle self-transfer in ctoken transfer and transfer_checked

Validate that the authority is a signer and is the owner or delegate
before allowing self-transfer early return. Previously the self-transfer
path returned Ok(()) without any authority validation.

* fix: simplify map_or to is_some_and per clippy

* fix: use pubkey_eq for self-transfer check

* refactor: extract self-transfer validation into shared function

Extract duplicate self-transfer check from default.rs and checked.rs
into validate_self_transfer() in shared.rs with cold path for authority
validation.

* chore: format

* fix: deduplicate random metadata keys in test_random_mint_action

Random key generation could produce duplicate keys, causing
DuplicateMetadataKey error (18040) with certain seeds.

fix: enforce mint extension checks in cToken-to-cToken decompress (#2246)

* fix: enforce mint extension checks in cToken-to-cToken decompress hot path

Add enforce_extension_state() to MintExtensionChecks and call it in the
Decompress branch when decompress_inputs is None (hot-path, not
CompressedOnly restore). This prevents cToken-to-cToken transfers from
bypassing pause, transfer fee, and transfer hook restrictions.

* fix test

chore: reject compress for mints with restricted extensions in build_mint_extension_cache (#2240)

* chore: reject compress for mints with restricted extensions in mint check

* Update programs/compressed-token/program/src/compressed_token/transfer2/check_extensions.rs

Co-authored-by: 0xa5df-c <172008956+0xa5df-c@users.noreply.github.com>

* fix: format else-if condition for lint

---------

Co-authored-by: 0xa5df-c <172008956+0xa5df-c@users.noreply.github.com>

fix: token-pool index 0 check (#2239)

fix(programs): add MintCloseAuthority as restricted extension (M-03) (#2263)

* fix: add MintCloseAuthority as restricted extension (M-03)

A mint with MintCloseAuthority can be closed and re-opened with
different extensions. Treating it as restricted ensures compressed
tokens from such mints require CompressedOnly mode.

* test: add MintCloseAuthority compression_only requirement tests

Add test coverage for MintCloseAuthority requiring compression_only mode,
complementing the fix in f2da063.

refactor: light program pinocchio macro (#2247)

* refactor: light program pinocchio macro

* fix: address CodeRabbit review comments on macro codegen

- Fix account order bug in process_update_config (config=0, authority=1)
- Use backend-provided serialize/deserialize derives in LightAccountData
- Remove redundant is_pinocchio() branch for has_le_bytes unpack fields
- DRY doc attribute generation across 4 struct generation methods
- Unify unpack_data path using account_crate re-export for both backends

chore(libs): bump versions (#2272)

fix(programs): allow account-level delegate to compress CToken (M-02) (#2262)

* fix: allow account-level delegate to compress tokens from CToken (M-02)

check_ctoken_owner() only checked owner and permanent delegate.
An account-level delegate (approved via CTokenApprove) could not
compress tokens. Added delegate check after permanent delegate.

* test: compress by delegate

fix: accumulate delegated amount at decompression (#2242)

* fix: accumulate delegated amount at decompression

* fix lint

* refactor: simplify apply_delegate to single accumulation path

* fix: ignore delegated_amount without delegate

* restore decompress amount check

fix programtest, wallet owner tracking for ata

fmt and lint
SwenSchaeferjohann added a commit that referenced this pull request Feb 11, 2026
refactor

remove fetch-accounts

renaming, simplify trait

fomat

excl photon-api submodule

fix: multi-pass cold account lookup in test indexer RPC

Align get_account_interface and get_multiple_account_interfaces with
Photon's lookup strategy: search compressed_accounts by onchain_pubkey,
then by PDA seed derivation, then token_compressed_accounts, then by
token_data.owner. Also fix as_mint() to accept ColdContext::Account
since Photon returns mints as generic compressed accounts.

Co-authored-by: Cursor <cursoragent@cursor.com>

lint

fix lint

fix: reject rent sponsor self-referencing the token account (#2257)

* fix: reject rent sponsor self-referencing the token account

Audit issue #9 (INFO): The rent payer could be the same account as
the target token account being created. Add a check that rejects
this self-reference to prevent accounting issues.

* test: add failing test rent sponsor self reference

fix: process metadata add/remove actions in sequential order (#2256)

* fix: process metadata add/remove actions in sequential order

Audit issue #16 (LOW): should_add_key checked for any add and any
remove independently, ignoring action ordering. An add-remove-add
sequence would incorrectly remove the key. Process actions
sequentially so the final state reflects the actual order.

* chore: format

* test: add randomized test for metadata action processing

Validates that process_extensions_config_with_actions produces correct
AdditionalMetadataConfig for random sequences of UpdateMetadataField
and RemoveMetadataKey actions, covering the add-remove-add bug from
audit issue #16.

* test: add integration test for audit issue #13 (no double rent charge)

Verifies that two compress operations targeting the same compressible
CToken account in a single Transfer2 instruction do not double-charge
the rent top-up budget.

* chore: format extensions_metadata test

fix: validate authority on self-transfer early return (#2252)

* fix: handle self-transfer in ctoken transfer and transfer_checked

Validate that the authority is a signer and is the owner or delegate
before allowing self-transfer early return. Previously the self-transfer
path returned Ok(()) without any authority validation.

* fix: simplify map_or to is_some_and per clippy

* fix: use pubkey_eq for self-transfer check

* refactor: extract self-transfer validation into shared function

Extract duplicate self-transfer check from default.rs and checked.rs
into validate_self_transfer() in shared.rs with cold path for authority
validation.

* chore: format

* fix: deduplicate random metadata keys in test_random_mint_action

Random key generation could produce duplicate keys, causing
DuplicateMetadataKey error (18040) with certain seeds.

fix: enforce mint extension checks in cToken-to-cToken decompress (#2246)

* fix: enforce mint extension checks in cToken-to-cToken decompress hot path

Add enforce_extension_state() to MintExtensionChecks and call it in the
Decompress branch when decompress_inputs is None (hot-path, not
CompressedOnly restore). This prevents cToken-to-cToken transfers from
bypassing pause, transfer fee, and transfer hook restrictions.

* fix test

chore: reject compress for mints with restricted extensions in build_mint_extension_cache (#2240)

* chore: reject compress for mints with restricted extensions in mint check

* Update programs/compressed-token/program/src/compressed_token/transfer2/check_extensions.rs

Co-authored-by: 0xa5df-c <172008956+0xa5df-c@users.noreply.github.com>

* fix: format else-if condition for lint

---------

Co-authored-by: 0xa5df-c <172008956+0xa5df-c@users.noreply.github.com>

fix: token-pool index 0 check (#2239)

fix(programs): add MintCloseAuthority as restricted extension (M-03) (#2263)

* fix: add MintCloseAuthority as restricted extension (M-03)

A mint with MintCloseAuthority can be closed and re-opened with
different extensions. Treating it as restricted ensures compressed
tokens from such mints require CompressedOnly mode.

* test: add MintCloseAuthority compression_only requirement tests

Add test coverage for MintCloseAuthority requiring compression_only mode,
complementing the fix in f2da063.

refactor: light program pinocchio macro (#2247)

* refactor: light program pinocchio macro

* fix: address CodeRabbit review comments on macro codegen

- Fix account order bug in process_update_config (config=0, authority=1)
- Use backend-provided serialize/deserialize derives in LightAccountData
- Remove redundant is_pinocchio() branch for has_le_bytes unpack fields
- DRY doc attribute generation across 4 struct generation methods
- Unify unpack_data path using account_crate re-export for both backends

chore(libs): bump versions (#2272)

fix(programs): allow account-level delegate to compress CToken (M-02) (#2262)

* fix: allow account-level delegate to compress tokens from CToken (M-02)

check_ctoken_owner() only checked owner and permanent delegate.
An account-level delegate (approved via CTokenApprove) could not
compress tokens. Added delegate check after permanent delegate.

* test: compress by delegate

fix: accumulate delegated amount at decompression (#2242)

* fix: accumulate delegated amount at decompression

* fix lint

* refactor: simplify apply_delegate to single accumulation path

* fix: ignore delegated_amount without delegate

* restore decompress amount check

fix programtest, wallet owner tracking for ata

fmt and lint
SwenSchaeferjohann added a commit that referenced this pull request Feb 11, 2026
refactor

remove fetch-accounts

renaming, simplify trait

fomat

excl photon-api submodule

fix: multi-pass cold account lookup in test indexer RPC

Align get_account_interface and get_multiple_account_interfaces with
Photon's lookup strategy: search compressed_accounts by onchain_pubkey,
then by PDA seed derivation, then token_compressed_accounts, then by
token_data.owner. Also fix as_mint() to accept ColdContext::Account
since Photon returns mints as generic compressed accounts.

Co-authored-by: Cursor <cursoragent@cursor.com>

lint

fix lint

fix: reject rent sponsor self-referencing the token account (#2257)

* fix: reject rent sponsor self-referencing the token account

Audit issue #9 (INFO): The rent payer could be the same account as
the target token account being created. Add a check that rejects
this self-reference to prevent accounting issues.

* test: add failing test rent sponsor self reference

fix: process metadata add/remove actions in sequential order (#2256)

* fix: process metadata add/remove actions in sequential order

Audit issue #16 (LOW): should_add_key checked for any add and any
remove independently, ignoring action ordering. An add-remove-add
sequence would incorrectly remove the key. Process actions
sequentially so the final state reflects the actual order.

* chore: format

* test: add randomized test for metadata action processing

Validates that process_extensions_config_with_actions produces correct
AdditionalMetadataConfig for random sequences of UpdateMetadataField
and RemoveMetadataKey actions, covering the add-remove-add bug from
audit issue #16.

* test: add integration test for audit issue #13 (no double rent charge)

Verifies that two compress operations targeting the same compressible
CToken account in a single Transfer2 instruction do not double-charge
the rent top-up budget.

* chore: format extensions_metadata test

fix: validate authority on self-transfer early return (#2252)

* fix: handle self-transfer in ctoken transfer and transfer_checked

Validate that the authority is a signer and is the owner or delegate
before allowing self-transfer early return. Previously the self-transfer
path returned Ok(()) without any authority validation.

* fix: simplify map_or to is_some_and per clippy

* fix: use pubkey_eq for self-transfer check

* refactor: extract self-transfer validation into shared function

Extract duplicate self-transfer check from default.rs and checked.rs
into validate_self_transfer() in shared.rs with cold path for authority
validation.

* chore: format

* fix: deduplicate random metadata keys in test_random_mint_action

Random key generation could produce duplicate keys, causing
DuplicateMetadataKey error (18040) with certain seeds.

fix: enforce mint extension checks in cToken-to-cToken decompress (#2246)

* fix: enforce mint extension checks in cToken-to-cToken decompress hot path

Add enforce_extension_state() to MintExtensionChecks and call it in the
Decompress branch when decompress_inputs is None (hot-path, not
CompressedOnly restore). This prevents cToken-to-cToken transfers from
bypassing pause, transfer fee, and transfer hook restrictions.

* fix test

chore: reject compress for mints with restricted extensions in build_mint_extension_cache (#2240)

* chore: reject compress for mints with restricted extensions in mint check

* Update programs/compressed-token/program/src/compressed_token/transfer2/check_extensions.rs

Co-authored-by: 0xa5df-c <172008956+0xa5df-c@users.noreply.github.com>

* fix: format else-if condition for lint

---------

Co-authored-by: 0xa5df-c <172008956+0xa5df-c@users.noreply.github.com>

fix: token-pool index 0 check (#2239)

fix(programs): add MintCloseAuthority as restricted extension (M-03) (#2263)

* fix: add MintCloseAuthority as restricted extension (M-03)

A mint with MintCloseAuthority can be closed and re-opened with
different extensions. Treating it as restricted ensures compressed
tokens from such mints require CompressedOnly mode.

* test: add MintCloseAuthority compression_only requirement tests

Add test coverage for MintCloseAuthority requiring compression_only mode,
complementing the fix in f2da063.

refactor: light program pinocchio macro (#2247)

* refactor: light program pinocchio macro

* fix: address CodeRabbit review comments on macro codegen

- Fix account order bug in process_update_config (config=0, authority=1)
- Use backend-provided serialize/deserialize derives in LightAccountData
- Remove redundant is_pinocchio() branch for has_le_bytes unpack fields
- DRY doc attribute generation across 4 struct generation methods
- Unify unpack_data path using account_crate re-export for both backends

chore(libs): bump versions (#2272)

fix(programs): allow account-level delegate to compress CToken (M-02) (#2262)

* fix: allow account-level delegate to compress tokens from CToken (M-02)

check_ctoken_owner() only checked owner and permanent delegate.
An account-level delegate (approved via CTokenApprove) could not
compress tokens. Added delegate check after permanent delegate.

* test: compress by delegate

fix: accumulate delegated amount at decompression (#2242)

* fix: accumulate delegated amount at decompression

* fix lint

* refactor: simplify apply_delegate to single accumulation path

* fix: ignore delegated_amount without delegate

* restore decompress amount check

fix programtest, wallet owner tracking for ata

fmt and lint

upd amm test

simplify client usage, remove unnecessary endpoints

clean

cleanup

lint
SwenSchaeferjohann added a commit that referenced this pull request Feb 11, 2026
refactor

remove fetch-accounts

renaming, simplify trait

fomat

excl photon-api submodule

fix: multi-pass cold account lookup in test indexer RPC

Align get_account_interface and get_multiple_account_interfaces with
Photon's lookup strategy: search compressed_accounts by onchain_pubkey,
then by PDA seed derivation, then token_compressed_accounts, then by
token_data.owner. Also fix as_mint() to accept ColdContext::Account
since Photon returns mints as generic compressed accounts.

Co-authored-by: Cursor <cursoragent@cursor.com>

lint

fix lint

fix: reject rent sponsor self-referencing the token account (#2257)

* fix: reject rent sponsor self-referencing the token account

Audit issue #9 (INFO): The rent payer could be the same account as
the target token account being created. Add a check that rejects
this self-reference to prevent accounting issues.

* test: add failing test rent sponsor self reference

fix: process metadata add/remove actions in sequential order (#2256)

* fix: process metadata add/remove actions in sequential order

Audit issue #16 (LOW): should_add_key checked for any add and any
remove independently, ignoring action ordering. An add-remove-add
sequence would incorrectly remove the key. Process actions
sequentially so the final state reflects the actual order.

* chore: format

* test: add randomized test for metadata action processing

Validates that process_extensions_config_with_actions produces correct
AdditionalMetadataConfig for random sequences of UpdateMetadataField
and RemoveMetadataKey actions, covering the add-remove-add bug from
audit issue #16.

* test: add integration test for audit issue #13 (no double rent charge)

Verifies that two compress operations targeting the same compressible
CToken account in a single Transfer2 instruction do not double-charge
the rent top-up budget.

* chore: format extensions_metadata test

fix: validate authority on self-transfer early return (#2252)

* fix: handle self-transfer in ctoken transfer and transfer_checked

Validate that the authority is a signer and is the owner or delegate
before allowing self-transfer early return. Previously the self-transfer
path returned Ok(()) without any authority validation.

* fix: simplify map_or to is_some_and per clippy

* fix: use pubkey_eq for self-transfer check

* refactor: extract self-transfer validation into shared function

Extract duplicate self-transfer check from default.rs and checked.rs
into validate_self_transfer() in shared.rs with cold path for authority
validation.

* chore: format

* fix: deduplicate random metadata keys in test_random_mint_action

Random key generation could produce duplicate keys, causing
DuplicateMetadataKey error (18040) with certain seeds.

fix: enforce mint extension checks in cToken-to-cToken decompress (#2246)

* fix: enforce mint extension checks in cToken-to-cToken decompress hot path

Add enforce_extension_state() to MintExtensionChecks and call it in the
Decompress branch when decompress_inputs is None (hot-path, not
CompressedOnly restore). This prevents cToken-to-cToken transfers from
bypassing pause, transfer fee, and transfer hook restrictions.

* fix test

chore: reject compress for mints with restricted extensions in build_mint_extension_cache (#2240)

* chore: reject compress for mints with restricted extensions in mint check

* Update programs/compressed-token/program/src/compressed_token/transfer2/check_extensions.rs

Co-authored-by: 0xa5df-c <172008956+0xa5df-c@users.noreply.github.com>

* fix: format else-if condition for lint

---------

Co-authored-by: 0xa5df-c <172008956+0xa5df-c@users.noreply.github.com>

fix: token-pool index 0 check (#2239)

fix(programs): add MintCloseAuthority as restricted extension (M-03) (#2263)

* fix: add MintCloseAuthority as restricted extension (M-03)

A mint with MintCloseAuthority can be closed and re-opened with
different extensions. Treating it as restricted ensures compressed
tokens from such mints require CompressedOnly mode.

* test: add MintCloseAuthority compression_only requirement tests

Add test coverage for MintCloseAuthority requiring compression_only mode,
complementing the fix in f2da063.

refactor: light program pinocchio macro (#2247)

* refactor: light program pinocchio macro

* fix: address CodeRabbit review comments on macro codegen

- Fix account order bug in process_update_config (config=0, authority=1)
- Use backend-provided serialize/deserialize derives in LightAccountData
- Remove redundant is_pinocchio() branch for has_le_bytes unpack fields
- DRY doc attribute generation across 4 struct generation methods
- Unify unpack_data path using account_crate re-export for both backends

chore(libs): bump versions (#2272)

fix(programs): allow account-level delegate to compress CToken (M-02) (#2262)

* fix: allow account-level delegate to compress tokens from CToken (M-02)

check_ctoken_owner() only checked owner and permanent delegate.
An account-level delegate (approved via CTokenApprove) could not
compress tokens. Added delegate check after permanent delegate.

* test: compress by delegate

fix: accumulate delegated amount at decompression (#2242)

* fix: accumulate delegated amount at decompression

* fix lint

* refactor: simplify apply_delegate to single accumulation path

* fix: ignore delegated_amount without delegate

* restore decompress amount check

fix programtest, wallet owner tracking for ata

fmt and lint

upd amm test

simplify client usage, remove unnecessary endpoints

clean

cleanup

lint
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants