In the withdrawNFT
function where the liquidation threshold is applied incorrectly, allowing users to withdraw NFT collateral even if it leaves their position undercollateralized. The protocol uses a multiplicative check (debt * threshold
) instead of the required reciprocal relationship (debt / threshold
), violating the core lending/borrowing safety invariant.
The liquidation threshold is designed to enforce a minimum collateral-to-debt ratio (e.g., 125% collateral for an 80% LTV threshold). However, the code erroneously checks:
This calculates debt * threshold
(e.g., $100 * 80% = $80) instead of the correct debt / threshold
(e.g., $100 / 80% = $125). This allows withdrawals that reduce collateral below the safe threshold.
Critical Severity: Users can systematically drain collateral while maintaining debt, creating undercollateralized positions that should have been liquidated.
Example Attack Flow (Liquidation Threshold = 80%):
Initial State:
Collateral: 125 crvUSD (5 NFTs @ 25 each)
Debt: 100 crvUSD
Required Collateral: 100 / 80% = 125 crvUSD ✅
Withdraw 1 NFT (25 crvUSD):
New Collateral: 100 crvUSD
Required Collateral: 100 / 80% = 125 crvUSD ❌
Protocol Check: 100 < (100 * 80%) → 100 < 80 → False → Allows withdrawal
Result:
Position is undercollateralized (100 crvUSD collateral for 100 crvUSD debt → 100% LTV) but remains active.
Accumulation of undercollateralized positions threatens protocol solvency during market downturns.
Manual Review
Change the collateral check to use the reciprocal of the liquidation threshold:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.