Core Contracts

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

stealing rewards from StabilityPool.sol

Summary

StabilityPool.sol can be drained from its rewards due to how rewards are calculated via flashloan or ordinary deposit/withdraw cycles from users .

Vulnerability Detail

calculateRaacRewards is called everytime a withdraw is initiated from msg.sender calculating his rewards proportional to his Deposit amounts from TotalRewards and TotalDeposits in the system.

function withdraw(uint256 deCRVUSDAmount) external nonReentrant whenNotPaused validAmount(deCRVUSDAmount) {
_update();
if (deToken.balanceOf(msg.sender) < deCRVUSDAmount) revert InsufficientBalance();
uint256 rcrvUSDAmount = calculateRcrvUSDAmount(deCRVUSDAmount);
uint256 raacRewards = calculateRaacRewards(msg.sender);
if (userDeposits[msg.sender] < rcrvUSDAmount) revert InsufficientBalance();
userDeposits[msg.sender] -= rcrvUSDAmount;
if (userDeposits[msg.sender] == 0) {
delete userDeposits[msg.sender];
}
deToken.burn(msg.sender, deCRVUSDAmount);
rToken.safeTransfer(msg.sender, rcrvUSDAmount);
if (raacRewards > 0) {
raacToken.safeTransfer(msg.sender, raacRewards);
}
emit Withdraw(msg.sender, rcrvUSDAmount, deCRVUSDAmount, raacRewards);
}

due to how userRewards are calculated : (totalRewards * userDeposit) / totalDeposits
example math :
TotalRewards = 5000 , userDeposit = 1000 , totalDeposits = 10000
(5000*1000) / 10000 = 500 userRewards

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;

}
That way of simplistic Rewards calculation taking balances and deposits at the moment for calculation , and malicious user being able to deposit and withdraw without restrictions he can deposit/Withdraw as much as he wants and everytime take a share of the rewards for the pool till its drained or malicious user can wait for the Depositing of RaacRewards through depositRAACFromPool ,Flashloan huge amount of Rtoken making his userDeposit big % of TotalDeposits in the pool , leading to him stealing huge amount of rewards from the pool ,that is also repeatable till the rewards are drained .

Impact

due to how rewards are calculated and no restrictions on deposit/withdraw to users , Rewards can be easily drained vie Deposit/Withdraw cycles or flashloans .

Tools Used

manual review

Recommendations

incorporate Time restrictions on deposit and withdraw or locking similiar to veRAACtoken.sol
change the Rewards calculation to take into account the Locking mechanism .

Updates

Lead Judging Commences

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