fix: junior withdrawal balance drift causes permanent fund lockup - #103
Conversation
process_withdraw subtracted withdrawal_amount (derived from the loss-adjusted effective_junior_balance) from the raw junior_balance. When insurance losses exist, effective < raw, so the raw balance accumulated a residual with each withdrawal. After all junior LP holders exit and insurance is returned, the orphaned junior_balance blocks new junior deposits (supply=0, value>0 guard) and locks tokens permanently in the vault — inaccessible to senior holders because senior_balance excludes effective_junior_balance. Fix: when all junior LP is burned, zero out junior_balance. For partial withdrawals, decrease junior_balance proportionally by the LP share of the raw balance (lp_amount * junior_balance / junior_lp) rather than by the loss-adjusted withdrawal_amount. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
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)
📝 WalkthroughWalkthroughThe Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 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 |
|
Sentinel security review — MERGE Fix is correct and the bug is real. Current master subtracts the loss-adjusted The fix is correct on both paths: zero-out when all LP is burned, proportional raw-balance reduction on partial withdrawal. The u128 intermediate prevents overflow. Logic matches the proportional LP math used elsewhere in the codebase. No conflicts with any other open PR. No new issues introduced. Severity confirmed: HIGH (CVSS ~7.5 — permanent fund lockup of returned insurance tokens, no admin recovery path). Security APPROVED PR #103 — findings: none | junior_balance accounting fix prevents permanent vault lockup on insurance return |
Summary
withdrawal_amount(derived from loss-adjustedeffective_junior_balance) from the rawjunior_balance, causing a permanent residual when insurance losses existjunior_balance > 0withjunior_total_lp == 0triggers thesupply=0 && value>0guard incalc_junior_lp_for_deposit, permanently blocking new junior deposits and locking returned insurance tokens in the vaultSeverity
HIGH — permanent token lockup. Returned insurance tokens become inaccessible to both senior and junior holders.
Reproduction
total_flushed=500)junior_balance = 1000 - 500 = 500(should be 0)total_returned=500, vault has 4500senior_balance = 4500 - 500). 500 tokens locked forever.Fix
new_junior_lp == 0), zero outjunior_balancejunior_balanceproportionally by LP share of the raw balance (lp_amount * junior_balance / junior_lp_before), not by the loss-adjustedwithdrawal_amountTest plan
cargo build— compiles cleanlycargo clippy— zero warnings🤖 Generated with Claude Code
Summary by CodeRabbit