Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: high
Valid

Liquidation overestimate the user debt

Summary

An error in the computation of a user’s debt in the liquidateBorrower function of the StabilityPool can cause the call to fail, even if the protocol has sufficient balance to liquidate the user.

Vulnerability Details

During a liquidation, the liquidateBorrower function in the StabilityPool contract performs a check to ensure that the StabilityPool has enough crvUSD. As we can see, the function multiplies the user’s debt by the usage index to compute the actual debt:

function liquidateBorrower(address userAddress) external onlyManagerOrOwner nonReentrant whenNotPaused {
_update();
// Get the user's debt from the LendingPool.
uint256 userDebt = lendingPool.getUserDebt(userAddress);
uint256 scaledUserDebt = WadRayMath.rayMul(userDebt, lendingPool.getNormalizedDebt());
if (userDebt == 0) revert InvalidAmount();
uint256 crvUSDBalance = crvUSDToken.balanceOf(address(this));
if (crvUSDBalance < scaledUserDebt) revert InsufficientBalance();

The issue is that the view function getUserDebt, which is used in this computation, is already applied in a previous step, causing the protocol to overestimate the necessary balance.

As seen here:

function getUserDebt(address userAddress) public view returns (uint256) {
UserData storage user = userData[userAddress];
return user.scaledDebtBalance.rayMul(reserve.usageIndex);
}

The scaledUserDebt = debt.mul( usageIndex ).mul(usageIndex)

The protocol multiplies the debt twice by the usage index, leading to an overestimation of the required balance.

Impact

The call will revert even if the protocol have enough balance.

Tools Used

Manual review

Recommendations

The protocol should directly the user debt to compute the necessary balance.

Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

StabilityPool::liquidateBorrower double-scales debt by multiplying already-scaled userDebt with usage index again, causing liquidations to fail

Support

FAQs

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