fix(stake): verify wrapper_vault SPL Token ownership before raw mint read in FlushToInsurance - #227
Conversation
…ead in FlushToInsurance process_flush_to_insurance reads wrapper_vault data[0..32] as mint without first confirming wrapper_vault.owner == spl_token::id(). A crafted account owned by any program with forged bytes at offset [0..32] matching the collateral mint passes the check. Every other vault-touching handler (pre_accrue_mode1, process_accrue_fees, process_return_insurance) already performs this owner check. This adds the missing guard immediately before the raw data borrow.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughIn ChangesSPL Token owner guard in process_flush_to_insurance
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
) Implements the N-2 timelock that #243 prepared (TIMELOCK_SLOTS). The capital-LOCK vector in #242 is a cooldown_slots INCREASE: a compromised admin could set cooldown = MAX_COOLDOWN_SLOTS (~1 year) in a single UpdateConfig tx and lock LP withdrawals instantly. That increase now requires a two-phase, time-delayed commit. - ProposeCooldownIncrease (tag 7, reclaimed) — admin records the new (larger) value + proposal slot. Rejects non-increases (those use UpdateConfig). - CommitCooldownIncrease (tag 8) — applies the pending value ONLY after TIMELOCK_SLOTS (~48h) have elapsed, giving LP holders a guaranteed exit window. - CancelCooldownIncrease (tag 9) — admin withdraws a pending proposal. - UpdateConfig now REJECTS a cooldown INCREASE (CooldownIncreaseRequiresTimelock); decreases (LP-friendly) and deposit_cap stay immediate. State: pending_cooldown_slots + cooldown_proposed_at_slot stored in the previously-free _reserved[10..26] — no struct-size change, no version bump (fresh-start cutover). 3 new errors (25/26/27). FlushToInsurance / SetMarketResolved intentionally stay immediate (PDA-custody + #227/#229 guards / one-way operational — see N-2 comment). Verification: - timelock_window_elapsed extracted as a pure helper; 3 unit tests + 2 accessor tests + collision-with-neighbors test; instruction round-trip tests; tombstone tests updated. - Kani proof kani_timelock_window_elapsed_matches_spec: VERIFIED (293 properties, 2/2 cover properties satisfied — non-vacuous, both elapsed/not-elapsed reachable, overflow is Err not panic). - 138 lib tests + full integration suite (incl. LiteSVM e2e) pass, 0 failures; cargo build-sbf clean. NOT deployed (cutover-gated). Closes #242. Co-authored-by: dcccrypto <dcccrypto@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fixes #226
Change
Adds
wrapper_vault.owner == spl_token::id()check inprocess_flush_to_insurancebefore the rawdata[0..32]mint read, matching the guard already present inpre_accrue_mode1,process_accrue_fees, andprocess_return_insurance.Why
A non-token account with forged bytes at offset
[0..32]matchingpool.collateral_mintpasses the existing mint check. The SPL Token program's CPI validates the account on its side, but an explicit owner check here is consistent with every other vault-touching handler in the file and eliminates the inconsistency.Test plan
cargo test)wrapper_vaultnow returnsStakeError::InvalidAccountinstead of propagating to the CPISummary by CodeRabbit