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];
uint256 totalDeposits = deToken.totalSupply();
uint256 totalRewards = raacToken.balanceOf(address(this));
if (totalDeposits < 1e6) return 0;
return (totalRewards * userDeposit) / totalDeposits;
}
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;
if (rTokenDecimals > deTokenDecimals) {
userDeposit = userDeposit / (10 ** (rTokenDecimals - deTokenDecimals));
} else if (deTokenDecimals > rTokenDecimals) {
totalDeposits = totalDeposits / (10 ** (deTokenDecimals - rTokenDecimals));
}
return (totalRewards * userDeposit) / totalDeposits;
}