Algo Ssstablecoinsss

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

Deeply underwater positions cannot be liquidated

Root + Impact

The root cause is that the function doesn't check that the collateral depth plus bonus is it greater than the user's actual collateral that he deposited.

Impact:

Now if you subtract the high amount from the low amount and you into fifty six, the wipers will give you... will revert. And, uh, this way, the most deeply underwater positions can't be liquidated.

Description

in the liquidated function, the d s c underscore engine dot v y contract. There's a missing check that... if the user's position is deeply under watered and that even his deposited amount is less than the depth that he has now, so that's... in that case, he can't be liquidated because of the underflow error that we have in the liquidated function.

// Root cause in the codebase with @> marks to highlight the relevant section
def liquidate(collateral: address, user: address, debt_to_cover: uint256):
assert debt_to_cover > 0, "DSCEngine__NeedsMoreThanZero"
starting_user_health_factor: uint256 = self._health_factor(user)
assert (
starting_user_health_factor < MIN_HEALTH_FACTOR
), "DSCEngine__HealthFactorOk"
token_amount_from_debt_covered: uint256 = self._get_token_amount_from_usd(
collateral, debt_to_cover
)
bonus_collateral: uint256 = (
token_amount_from_debt_covered * LIQUIDATION_BONUS
) // LIQUIDATION_PRECISION
self._redeem_collateral(
collateral,
token_amount_from_debt_covered + bonus_collateral,
user,
msg.sender,
)
self._burn_dsc(debt_to_cover, user, msg.sender)
ending_user_health_factor: uint256 = self._health_factor(user)
assert (
ending_user_health_factor > starting_user_health_factor
), "DSCEngine__HealthFactorNotImproved"
self._revert_if_health_factor_is_broken(msg.sender)

Risk

Likelihood:

  • The likelihood is high because, uh, crypto is known as for its volatile prices, and prices can go can go up and down very violently. So that's why it can happen... this can happen very likely.

Impact:

  • And, also, the impact would be that the protocol won't be able to liquidate the users. most positions are DP and water.

Proof of Concept


User deposits 1 ETH worth $100
User mints $50 DSC
ETH price crashes to $30
Liquidator tries to cover $50 debt
Protocol calculates: needs 1.67 ETH + 0.167 ETH bonus = 1.837 ETH
User only has 1 ETH deposited
_redeem_collateral tries to subtract 1.837 from 1 — underflow revert
Liquidation impossible. Bad debt stuck forever.

Recommended Mitigation

In normal liquidation:

  • Liquidator gets: debt collateral + 10% bonus

  • Everyone is happy

But in deeply underwater position:

  • Full amount + bonus > what user actually has

  • So instead of reverting — just take everything the user has left

  • Liquidator gets less than 10% bonus — but at least they get something

  • Bad debt gets cleared — protocol is saved


Think of it like this. Real world example.

Someone owes you $100 but only has $80 left. You have two choices:

  1. Say "I want my full $100 or nothing" — you get nothing, debt stays forever

  2. Say "okay give me your $80, I'll take the loss on $20" — at least you recover something

The fix forces option 2. Take whatever is available, clear the position, move on.

- remove this code
+ add this code
+
user_balance = self.user_to_token_address_to_amount_deposited[user][collateral]
total_to_redeem = token_amount_from_debt_covered + bonus_collateral
if total_to_redeem > user_balance:
total_to_redeem = user_balance
+
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 8 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!