A double scaling error in liquidateBorrower()
results in systematic overfunding of liquidations, causing persistent fund misallocation in the Stability Pool. Because getUserDebt()
already applies rayMul(reserve.usageIndex)
, calling rayMul(getNormalizedDebt())
again in liquidateBorrower()
inflates the perceived user debt, leading to unnecessary excess fund transfers. This issue is exacerbated over time as the usageIndex
increases exponentially, forcing managers to continuously top up Stability Pool reserves wastefully with more allocated funds than intended. The flaw creates an inefficient liquidation mechanism, drains protocol resources, and distorts Stability Pool reserves.
Note: liquidateBorrower()
will also need to call lendingPool.updateState()
before getting the user's debt from the LendingPool as I have separately reported.
In liquidateBorrower()
, the contract first retrieves the user’s total debt:
However, getUserDebt()
already applies rayMul(reserve.usageIndex)
:
Instead of using this correctly scaled debt amount, liquidateBorrower()
scales it again:
This doubles the scaling effect, overestimating the user’s debt and causing unnecessary excess prefunding of Stability Pool with crvUSDToken
in order for the following check to pass:
The thing is managers query lendingPool.getUserDebt()
and assume it returns the correct amount needed for liquidation. However, due to the double scaling issue, the contract believes there is insufficient crvUSDBalance
and reverts liquidations unless extra funds are allocated. If managers don’t notice this flaw, they may continuously send additional funds to "fix" the issue, leading to fund leakage over multiple liquidation cycles.
Since Stability Pool funds are pre-allocated, managers may opt to overfund liquidations rather than debugging why their transactions fail. This turns the Stability Pool into a constantly misused liquidity sink, making it impossible to accurately track available reserves. And, there is no rescueToken()
or refund logic for the excess crvUSDToken
sent in.
Over time, usageIndex
increases exponentially, so the discrepancy widens, amplifying the cascading wastes.
Perpetual Stability Pool Drainage:
Overfunded liquidations reduce Stability Pool efficiency, depleting protocol reserves over time.
Systemic Fund Misallocation:
The Stability Pool no longer holds an accurate reserve of available funds, causing unexpected capital inefficiencies.
Increased Liquidation Costs for Users:
Managers may unnecessarily lose more assets in liquidations due to artificially inflated debt amounts.
Protocol-Wide Capital Inefficiency:
The protocol mismanages funds, requiring either constant manager intervention or excess liquidity to compensate for miscalculations.
Manual
Consider making the following refactoring:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.