Skip to content

fix: reject duplicate accounts in convert_account_infos#2258

Merged
ananas-block merged 4 commits into
mainfrom
fix/audit-issue-21-duplicate-accounts
Feb 9, 2026
Merged

fix: reject duplicate accounts in convert_account_infos#2258
ananas-block merged 4 commits into
mainfrom
fix/audit-issue-21-duplicate-accounts

Conversation

@ananas-block
Copy link
Copy Markdown
Contributor

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

Summary

  • Improved handling of duplicate accounts in the compressed token program so duplicate entries now share state correctly at runtime. This prevents inconsistent balances and data for repeated account references.

Audit issue #21 (INFO): convert_account_infos created multiple mutable
references when duplicate account keys were passed. Add a pre-check
that detects duplicate keys and returns InvalidArgument to prevent
undefined behavior from aliased mutable references.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 6, 2026

📝 Walkthrough

Walkthrough

Adds runtime-safe duplicate-account detection to convert_account_infos: on duplicate keys, reuses existing Rc pointers for lamports and data via Rc::clone, and pushes an AccountInfo that shares state while copying owner, rent_epoch, signer/writable/executable fields. Public signature unchanged.

Changes

Cohort / File(s) Summary
Duplicate Account Handling
programs/compressed-token/program/src/convert_account_infos.rs
Detect duplicate account keys during iteration and reuse existing Rc pointers for lamports and data instead of allocating new ones. Pushes a new AccountInfo that shares the underlying state while copying non-shared metadata; no public API or signature changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

Two entries with the same old key,
We clone the Rc and let states be.
Lamports and data now mirror clear,
One truth shown twice, handled near. 🚀

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: reject duplicate accounts in convert_account_infos' directly and clearly describes the main change: adding duplicate account detection and rejection logic to the convert_account_infos function.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 70.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/audit-issue-21-duplicate-accounts

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.

Replace blanket rejection of duplicate account keys with Rc sharing
that mimics Solana runtime behavior. When the same account appears
in multiple positions (e.g., fee_payer and authority are the same
signer), the Rc<RefCell<>> from the first occurrence is reused,
preventing independent mutable references while allowing legitimate
duplicate account usage.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@programs/compressed-token/program/src/convert_account_infos.rs`:
- Line 43: Add a one-line SAFETY comment inside the duplicate-account branch
(the block starting with if let Some(existing) = solana_accounts.iter().find(|a|
a.key == key) {) explaining that Pinocchio may present duplicate AccountInfo
entries that point to the same underlying memory, therefore we must share the
existing Rc/RefCell rather than creating a new RefCell around the same raw
pointer because creating independent RefCell wrappers (or separate mutable
owners) for the same memory would be unsound; mention the key symbols
(solana_accounts, existing, Rc/RefCell) so future readers know why we
clone/share the existing Rc here.

Comment thread programs/compressed-token/program/src/convert_account_infos.rs Outdated
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@programs/compressed-token/program/src/convert_account_infos.rs`:
- Around line 40-48: Remove the duplicate comment block about sharing
Rc<RefCell<>> for duplicate accounts so the explanation and SAFETY note appear
only once; locate the repeated verbatim lines mentioning "For duplicate
accounts, share Rc<RefCell<>> from the first occurrence" and the "SAFETY:
pinocchio..." sentence in convert_account_infos.rs and delete the redundant
copy, leaving a single, continuous comment describing the shared RefCell
behavior and the SAFETY rationale.

Comment thread programs/compressed-token/program/src/convert_account_infos.rs Outdated
// SAFETY: pinocchio backs duplicate keys with the same memory region, so
// wrapping it in a second RefCell would allow aliased &mut — hence we must
// share the original RefCell via Rc::clone.
if let Some(existing) = solana_accounts.iter().find(|a| a.key == key) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

use pubkey_eq for comparison

- Remove duplicated comment block
- Use light_array_map::pubkey_eq with pinocchio keys directly
  instead of comparing solana_pubkey::Pubkey references
@ananas-block ananas-block merged commit 94ae5ca into main Feb 9, 2026
33 checks passed
@ananas-block ananas-block deleted the fix/audit-issue-21-duplicate-accounts branch February 9, 2026 14:57
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