Core Contracts

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

StabilityPool checking crvUSD balance instead of RToken balance causes all liquidations to revert

Summary

The liquidateBorrower function checks the crvUSD balance of the StabilityPool, but since the pool holds RTokens instead of crvUSD directly, this will cause all liquidation attempts to revert.

Vulnerability Details

https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/pools/StabilityPool/StabilityPool.sol#L457

function liquidateBorrower(address userAddress) external onlyManagerOrOwner nonReentrant whenNotPaused {
// ...
// @audit StabilityPool holds RTokens, not crvUSD
uint256 crvUSDBalance = crvUSDToken.balanceOf(address(this));
if (crvUSDBalance < scaledUserDebt) revert InsufficientBalance();

The issue is that:

StabilityPool receives RTokens when users deposit, not crvUSD
The actual crvUSD is held in the RToken contract
Checking crvUSD balance of StabilityPool will always return 0

function deposit(uint256 amount) external nonReentrant whenNotPaused validAmount(amount) {
_update();
rToken.safeTransferFrom(msg.sender, address(this), amount); <@
uint256 deCRVUSDAmount = calculateDeCRVUSDAmount(amount);
deToken.mint(msg.sender, deCRVUSDAmount);
userDeposits[msg.sender] += amount;
_mintRAACRewards();
emit Deposit(msg.sender, amount, deCRVUSDAmount);
}

Impact

High. The incorrect balance check:

Will always revert due to checking wrong token balance
Makes liquidations impossible as the check will never pass

Recommended Mitigation

Check the RToken balance instead of crvUSD:

// Check RToken balance instead of crvUSD
uint256 rTokenBalance = rToken.balanceOf(address(this));
if (rTokenBalance < userDebt) revert InsufficientBalance();
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!