Algo Ssstablecoinsss

AI First Flight #2
Beginner FriendlyDeFi
EXP
View results
Submission Details
Impact: high
Likelihood: medium
Invalid

No bad-debt floor: a collateral crash below 200% leaves un-liquidatable positions and permanently unbacked DSC

Protocol cannot be made whole when collateral crashes below 200%, leaving permanent bad debt and an undercollateralized stablecoin

Description

Liquidation pays the liquidator the debt-equivalent collateral plus a 10% bonus, all priced from the same feed, with no floor for when total collateral is already worth less than the debt.

# dsc_engine.vy:121-130 (liquidate)
bonus_collateral: uint256 = (
token_amount_from_debt_covered * LIQUIDATION_BONUS
) // LIQUIDATION_PRECISION
self._redeem_collateral(
collateral,
token_amount_from_debt_covered + bonus_collateral, # @> demands debt+10% even if user has less
user,
msg.sender,
)

With LIQUIDATION_THRESHOLD = 50 a position only needs 200% collateralization. If price gaps down so collateral value falls below 110% of debt, the _redeem_collateral subtraction (dsc_engine.vy:249-251) underflows and reverts — so no liquidator can clear the position.

Risk

Likelihood:
Medium. Crypto collateral routinely gaps >50% in a single block; the design has no partial-bad-debt handling.

Impact:
High. Underwater positions become un-liquidatable (revert on underflow), the protocol keeps the bad debt forever, and DSC is no longer fully backed, driving a depeg. Even when liquidatable, the bonus can consume more collateral than exists, so good positions subsidize the loss.

Proof of Concept

Open a position at the 200% minimum, drop the price 60%, attempt liquidation.

engine.deposit_collateral_and_mint_dsc(weth, 1 * 10**18, 1000 * 10**18) # $2000 -> 1000 DSC
mock_feed.updateAnswer(800 * 10**8) # WETH now $800, collateral < debt
engine.liquidate(weth, user, 1000 * 10**18) # reverts: collateral underflow, debt is stuck

Recommended Mitigation

Cap the seized collateral at the user's balance and book the shortfall instead of reverting.

- self._redeem_collateral(
- collateral,
- token_amount_from_debt_covered + bonus_collateral,
- user, msg.sender,
- )
+ seizable: uint256 = self.user_to_token_address_to_amount_deposited[user][collateral]
+ to_seize: uint256 = min(token_amount_from_debt_covered + bonus_collateral, seizable)
+ self._redeem_collateral(collateral, to_seize, user, msg.sender)
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 5 hours ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!