The liquidate() function is designed to seize collateral from unhealthy positions, calculating the total amount needed (debt + 10% bonus) and calling _redeem_collateral() to transfer it to the liquidator.
The function never checks if the user actually has enough collateral to cover the liquidation amount. When liquidating deeply underwater positions (collateral value < debt), the redemption attempts to subtract more collateral than exists, causing an underflow that reverts the entire transaction.
Likelihood:
Market crashes cause collateral values to drop rapidly below debt values, creating underwater positions where debt exceeds available collateral.
The 200% collateralization requirement provides only a 50% price drop buffer before positions become unliquidatable, occurring frequently in volatile crypto markets.
Impact:
Unliquidatable Bad Debt: Underwater positions cannot be liquidated, accumulating as protocol bad debt that exceeds collateral backing.
Protocol Insolvency: Failed liquidations during market crashes prevent bad debt cleanup, leaving the protocol undercollateralized with more DSC in circulation than collateral value.
Attack Steps:
User deposits 10 ETH at $2,000 = $20,000 collateral
User mints 9,900 DSC (health factor 1.01, barely safe)
ETH crashes 60% to $800
User position now: $8,000 collateral, $9,900 debt (underwater)
Liquidator attempts liquidation of full $9,900 debt
System calculates: needs 13.6125 ETH (12.375 + 10% bonus)
User only has 10 ETH
_redeem_collateral tries: 10 ETH - 13.6125 ETH → UNDERFLOW
Transaction reverts, position unliquidatable
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.