Algo Ssstablecoinsss

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

Dust Debt After Partial Liquidation Makes Positions Unliquidatable

Root + Impact

Description

  • * The protocol allows liquidators to partially liquidate unhealthy positions by repaying a portion of the user's debt in exchange for collateral plus a bonus. The liquidation function checks that the user's health factor improves after liquidation.

    * When a liquidator partially liquidates a position, the remaining debt may become too small to be profitably liquidated due to gas costs. This leaves the user with an unhealthy position that cannot be liquidated, creating bad debt that accumulates in the protocol.

    ```vyper

    @external

    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) // @> Partial liquidation allowed

    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:

  • * Liquidators will prefer to liquidate only profitable portions of debt, leaving small remaining debts

    * Gas costs make it unprofitable to liquidate very small debt amounts (e.g., < $10 worth of debt)

    * Market conditions can cause positions to become unhealthy with small debt amounts remaining after partial liquidations

Impact:

  • * Users become stuck with unhealthy positions that cannot be liquidated

    * Bad debt accumulates in the protocol, reducing overall solvency

    * Protocol becomes insolvent if enough positions become unliquidatable

    * No mechanism exists to recover from these dust positions

Proof of Concept

```python
# Scenario:
# 1. User has 100 DSC debt, collateral worth $50 (HF = 0.5, unhealthy)
# 2. Liquidator repays 99 DSC, leaving 1 DSC debt
# 3. Remaining collateral worth ~$0.50
# 4. Gas cost to liquidate 1 DSC > profit from liquidation
# 5. No liquidator will liquidate the remaining 1 DSC
# 6. User position remains unhealthy (HF < 1.0) but unliquidatable
# 7. Bad debt of 1 DSC accumulates in protocol
```

Recommended Mitigation

```diff
@external
def liquidate(collateral: address, user: address, debt_to_cover: uint256):
assert debt_to_cover > 0, "DSCEngine__NeedsMoreThanZero"
+ MIN_LIQUIDATION_AMOUNT: constant(uint256) = 100 * 10**18 # $100 minimum
+ assert debt_to_cover >= MIN_LIQUIDATION_AMOUNT, "DSCEngine__LiquidationTooSmall"
starting_user_health_factor: uint256 = self._health_factor(user)
assert (
starting_user_health_factor < MIN_HEALTH_FACTOR
), "DSCEngine__HealthFactorOk"
+ user_debt: uint256 = self.user_to_dsc_minted[user]
+ # Require full liquidation if remaining debt would be below minimum
+ if user_debt - debt_to_cover < MIN_LIQUIDATION_AMOUNT:
+ assert debt_to_cover == user_debt, "DSCEngine__MustLiquidateFully"
token_amount_from_debt_covered: uint256 = self._get_token_amount_from_usd(
collateral, debt_to_cover
)
```
Alternatively, implement a mechanism to handle dust positions, such as a protocol-owned account that liquidates dust positions or a write-off mechanism for positions below a threshold.
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge 16 days 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!