Core Contracts

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

Decimal Mismatch in StabilityPool Reward Calculation Can Lead to Incorrect RAAC Distributions

Relevant GitHub Links

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

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

Summary

The calculateRaacRewards function in StabilityPool.sol uses values with potentially different decimals without normalization, which can lead to incorrect RAAC token reward calculations when rToken and deToken have different decimal places.

Vulnerability Details

In StabilityPool.sol, rewards are calculated using values in different token denominations without decimal normalization:

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

The contract tracks token decimals but doesn't use them in calculations:

uint8 public rTokenDecimals;
uint8 public deTokenDecimals;

When rToken and deToken have different decimals, the reward calculation will be incorrect due to mismatched decimal places in the division.

Impact

  • Users receive incorrect RAAC reward amounts when token decimals differ

  • Protocol incentive distribution becomes inaccurate

  • Could lead to unfair reward distribution among participants

Tools Used

Manual Review

Recommendations

Normalize the decimals before calculation:

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;
// Normalize decimals
if (rTokenDecimals > deTokenDecimals) {
userDeposit = userDeposit / (10 ** (rTokenDecimals - deTokenDecimals));
} else if (deTokenDecimals > rTokenDecimals) {
totalDeposits = totalDeposits / (10 ** (deTokenDecimals - rTokenDecimals));
}
return (totalRewards * userDeposit) / totalDeposits;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Appeal created

0xterrah Submitter
7 months ago
inallhonesty Lead Judge
7 months ago
inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!