Core Contracts

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

StabilityPool cannot perform Liquidations; Missing Asset Conversion Mechanism

Summary

The StabilityPool contract currently lacks the necessary functionality to convert rTokens to crvUSD and handle crvUSD deposits. This oversight renders the protocol's liquidation mechanism non-functional, as liquidations require crvUSD transfers that the system cannot facilitate.

Vulnerability Details

The vulnerability arises because of the following reasons:

1.The StabilityPool only accepts rToken deposits, with no provision for crvUSD:

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);
}

2.The stability contract doesn't implement any functions to convert RTokens to crvUSD.

3.Liquidations require crvUSD transfers, but the system has no way to obtain or handle crvUSD:

function finalizeLiquidation(
address userAddress
) external nonReentrant onlyStabilityPool {
//...
// Transfer reserve assets from Stability Pool to cover the debt
IERC20(reserve.reserveAssetAddress).safeTransferFrom(
msg.sender,
reserve.reserveRTokenAddress,
amountScaled
);
// rest of the code
}

Impact

This vulnerability has severe consequences for protocol functionality:

  1. All liquidation attempts will revert

  2. Protocol's liquidation mechanism is non-functional

  3. StabilityPool cannot fulfill its core purpose.

Tools Used

Manual review

Recommendations

Since the issue arises because the StabilityPool does not have any crvUSD to supply for the liquidations, the following solutions could help solve it:

Add crvUSD deposit functionality to StabilityPool:

function depositCrvUSD(uint256 amount) external {
crvUSD.safeTransferFrom(msg.sender, address(this), amount);
emit CrvUSDDeposited(msg.sender, amount);
}

Implement rToken to crvUSD conversion in RToken:

function convertToCrvUSD(uint256 rTokenAmount) external {
uint256 crvUSDAmount = calculateConversion(rTokenAmount);
crvUSD.safeTransfer(msg.sender, crvUSDAmount);
_burn(msg.sender, rTokenAmount);
}

PLEASE NOTE: Proper access controls need to be implemented through require statements or modifiers for new functions.

Updates

Lead Judging Commences

inallhonesty Lead Judge 4 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.