The liquidate() function in dsc_engine.vy requires that the borrower's ending health factor must strictly exceed their starting health factor. Because liquidators receive a 10% liquidation bonus, liquidations of positions with an initial Health Factor mathematically reduce the borrower's health factor. This causes the assertion ending_user_health_factor > starting_user_health_factor to revert, permanently freezing liquidations on underwater positions and accumulating bad debt.
In src/dsc_engine.vy, liquidate() executes:
During liquidation, a liquidator pays debt and receives $1.1 \Delta D$ worth of collateral in USD.
Let:
: Initial Collateral USD value
: Initial Debt in DSC
: Liquidation threshold (50%)
: Liquidation bonus (10%)
The health factor equations are:
For :
Substituting :
$2 \cdot HF_{start} > 1.10 \iff HF_{start} > 0.55$
When a user's health factor falls to (e.g. during a market crash or rapid price decline), any liquidation mathematically results in . As a result, assert ending_user_health_factor > starting_user_health_factor ALWAYS reverts with "DSCEngine__HealthFactorNotImproved".
Catastrophic Protocol Insolvency: Any borrower position whose Health Factor falls to can NEVER be liquidated.
Permanent Bad Debt Accumulation: Liquidators are blocked from liquidating the protocol's most severely underwater accounts, leaving the stablecoin backing severely compromised.
Automated tests are provided in:
tests/unit/test_poc_audit.py::test_poc_liquidation_fails_when_hf_below_55
tests/fuzz/test_invariant_audit.py::test_invariant_liquidation_cannot_clear_bad_debt_when_hf_drops
In the test, ETH price drops from $2,000 to $10, causing the borrower's HF to drop to 0.50 (where collateral $100 debt $100). The liquidator attempts to cover debt, but every liquidation call reverts with "DSCEngine__HealthFactorNotImproved".
Moccasin v0.4.4
Titanoboa v0.2.8
Hypothesis v6.168.0
Remove the strict monotonicity requirement when accounts are deeply underwater, or allow 100% full liquidations that clear debt completely:
Alternatively, follow industry standard designs (e.g. MakerDAO/Aave) where liquidators can liquidate up to a close factor (e.g. 50% or 100%) without requiring health factor improvement.
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.