Core Contracts

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

`StabilityPool::liquidateBorrower()` will revert every time because `stabilityPool` does not hold `crvUSD`

Summary

Whenever a borrower is liquidated, the Stability Pool covers the debt to keep the Lending Pool operational.

A problem arises because the token held in the Lending Pool is crvUSD, while the Stability Pool holds rToken.

rToken is minted whenever users deposit into the Lending Pool, meaning crvUSD and rToken are completely different entities.

Vulnerability Details

To finalize a liquidation, the manager or owner of the Stability Pool must call liquidateBorrower.

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)); //@audit -> this will return 0 everytime
if (crvUSDBalance < scaledUserDebt) revert InsufficientBalance(); // this will revert
// Approve the LendingPool to transfer the debt amount
bool approveSuccess = crvUSDToken.approve(address(lendingPool), scaledUserDebt);
if (!approveSuccess) revert ApprovalFailed();
// Update lending pool state before liquidation
lendingPool.updateState();
// Call finalizeLiquidation on LendingPool
lendingPool.finalizeLiquidation(userAddress);
emit BorrowerLiquidated(userAddress, scaledUserDebt);
}

As shown the function will revert every time due to insufficient balance.

Impact

Permanent DoS of liquidateBorrower.

Tools Used

Manual review

Recommendations

Fix is not trivial, but an idea is to utilize the RToken::transferAsset() function.

Updates

Lead Judging Commences

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

StabilityPool design flaw where liquidations will always fail as StabilityPool receives rTokens but LendingPool expects it to provide crvUSD

Support

FAQs

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

Give us feedback!