Core Contracts

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

Potential RAAC Token Drain from StabilityPool due to Conversion logic and withdraw cooldown time

Summary

The StabilityPool contract has vulnerability in its token conversion logic where the calculateRcrvUSDAmount and calculateDeCRVUSDAmount functions implement a 1:1 mapping ratio. This design flaw, combined with the calculateRaacRewards function, could allow malicious users to drain RAAC tokens from the contract.

Vulnerability Details

Source

The vulnerability stems from three key components:

  1. The calculateDeCRVUSDAmount function returns a 1:1 ratio for token conversion:

function calculateDeCRVUSDAmount(uint256 rcrvUSDAmount) public view returns (uint256) {
uint256 scalingFactor = 10**(18 + deTokenDecimals - rTokenDecimals);
return (rcrvUSDAmount * scalingFactor) / getExchangeRate();
}
  1. The calculateRcrvUSDAmount function also maintains the same 1:1 ratio:

function calculateRcrvUSDAmount(uint256 deCRVUSDAmount) public view returns (uint256) {
uint256 scalingFactor = 10**(18 + rTokenDecimals - deTokenDecimals);
return (deCRVUSDAmount * getExchangeRate()) / scalingFactor;
}
function getExchangeRate() public view returns (uint256) {
__snip___
return 1e18;
}
  1. The calculateRaacRewards function uses these values to determine rewards.

function calculateRaacRewards(address user) public view returns (uint256) {
uint256 userDeposit = userDeposits[user];
uint256 totalDeposits = deToken.totalSupply();
uint256 totalRewards = raacToken.balanceOf(address(this));
if (totalDeposits < 1e6) return 0;
return (totalRewards * userDeposit) / totalDeposits;
}

since the getExchangeRate function return 1e18 this cancels out the scalingFactor since both rToken and deToken are 18 decimal

Proof of Concept

  1. Attacker deposits 1000 rTokens into the StabilityPool using the deposit function.

  2. The attacker then calls the calculateDeCRVUSDAmount function to get 1000 deTokens, exploiting the 1:1 mapping ratio.

  3. With the 1000 deTokens, the attacker calls the withdraw function to retrieve their original deposit of 1000 rTokens.

  4. The attacker then calls the calculateRaacRewards function to claim 100 RAAC Token rewards, using the 1:1 mapping ratio and the 100 RAAC reward rate. (assume the RAAC calculated is 100 RAAC Token)

  5. The attacker repeats steps 1-4, accumulating more RAAC tokens while maintaining their original capital of 1000 rTokens.

Impact

  • Potential drain of RAAC tokens from the contract

  • imbalance in the reward distribution system

  • Unfair advantage for malicious users over honest participants

Tools Used

  • Manual code review

Recommendations

Implement a better token conversion ratio.

Additionally:

  • Implement cooldown periods between deposits and withdrawals

  • Consider implementing TWA reward

Updates

Lead Judging Commences

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

StabilityPool::calculateRaacRewards is vulnerable to just in time deposits

Support

FAQs

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

Give us feedback!