fix: allow fully wiped junior LP exits - #181
Conversation
📝 WalkthroughWalkthrough
Fully-wiped junior LP zero-payout exit
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 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 |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tests/integration.rs (1)
888-889: 💤 Low valueConsider renaming the test to reflect the fix rather than the bug.
The current name
poc_fully_wiped_junior_lp_cannot_exit_due_zero_payout_guardreads as though it tests the broken behavior. Since the assertion confirms the fix works (zero-payout exit is allowed), a name liketest_fully_wiped_junior_lp_can_exit_with_zero_payoutwould better convey intent.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/integration.rs` around lines 888 - 889, The test function name `poc_fully_wiped_junior_lp_cannot_exit_due_zero_payout_guard` is misleading because it suggests the test validates that the junior LP cannot exit, when the test actually verifies that the junior LP can exit with zero payout (the fix). Rename this test function to `test_fully_wiped_junior_lp_can_exit_with_zero_payout` or similar to accurately reflect that it validates the fixed behavior where exiting with zero payout is allowed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@tests/integration.rs`:
- Around line 888-889: The test function name
`poc_fully_wiped_junior_lp_cannot_exit_due_zero_payout_guard` is misleading
because it suggests the test validates that the junior LP cannot exit, when the
test actually verifies that the junior LP can exit with zero payout (the fix).
Rename this test function to
`test_fully_wiped_junior_lp_can_exit_with_zero_payout` or similar to accurately
reflect that it validates the fixed behavior where exiting with zero payout is
allowed.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 53109fb2-0b1f-477d-b658-ca4a16d0d95f
📒 Files selected for processing (2)
src/processor.rstests/integration.rs
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b8d9440993
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let fully_wiped_junior_exit = pool.tranche_enabled() | ||
| && is_junior | ||
| && pool.effective_junior_balance() == 0 | ||
| && withdrawal_amount == 0; |
There was a problem hiding this comment.
Bypass HWM for zero-payout junior cleanup
When HWM is enabled and prior withdrawals plus a later insurance flush leave the pool already below the current HWM floor, this new exception only bypasses ZeroAmount; the withdraw then falls through to the HWM check below, where post_tvl == current_tvl and the zero-payout cleanup is still rejected. Because a fully wiped junior exit transfers no collateral and cannot further reduce TVL, HWM should not block this path or the worthless junior LP can remain unburnable in exactly the cleanup scenario this change is meant to allow.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in the latest push.
The zero-payout fully-wiped junior exit now bypasses HWM enforcement because no collateral leaves the pool and the cleanup cannot reduce TVL. I also added regression coverage for an HWM-blocked setup to ensure this terminal cleanup path can still proceed while normal zero-payout withdrawals remain rejected.
b8d9440 to
5c50b87
Compare
Summary
Fixes #180.
This PR fixes the fully-wiped junior LP exit path where a junior LP position with zero remaining effective collateral could not be closed because the withdraw flow rejected
withdrawal_amount == 0before LP burn and cleanup logic could run.The withdraw path now only permits a zero-payout withdrawal when all of the following are true:
pool.effective_junior_balance() == 0withdrawal_amount == 0For that specific terminal state, the SPL token transfer is skipped, and HWM enforcement is bypassed because the zero-payout cleanup cannot reduce TVL. The LP burn and deposit/tranche cleanup path can still execute.
Why
A fully-wiped junior LP can legitimately have no remaining collateral claim after absorbing losses.
Previously, the generic
ZeroAmountguard rejected the withdrawal before the LP burn and cleanup path. After allowing the zero-payout path, HWM enforcement also needs to avoid blocking this specific cleanup scenario because no collateral leaves the pool.This PR keeps zero-payout withdrawals rejected for normal/non-terminal cases, while allowing cleanup of a fully-wiped junior LP position.
Changes
fully_wiped_junior_exitcondition inprocess_withdraw.StakeError::ZeroAmountfor all zero-payout withdrawals except fully-wiped junior exits.withdrawal_amount == 0.How to test
cargo test poc_fully_wiped_junior_lp_cannot_exit_due_zero_payout_guard -- --nocapturecargo test --test v17_stake_insurance_e2e -- --nocapturecargo testChecklist
cargo build-sbfpassescargo test --test v17_stake_insurance_e2e -- --nocapturepassescargo testpasses