Core Contracts

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

RAAC Reward Calculation Vulnerability Allows Draining of Manager Funds

Summary

The StabilityPool contract improperly includes manager-allocated RAAC tokens in user reward calculations. This allows regular users to drain funds reserved for managers by claiming a disproportionate share of the total RAAC balance through the reward system.

Vulnerability Details

RAAC tokens deposited for managers via depositRAACFromPool() are stored in the same contract balance used for user rewards

function depositRAACFromPool(uint256 amount) external onlyLiquidityPool validAmount(amount) {
uint256 preBalance = raacToken.balanceOf(address(this));
raacToken.safeTransferFrom(msg.sender, address(this), amount);
uint256 postBalance = raacToken.balanceOf(address(this));
if (postBalance != preBalance + amount) revert InvalidTransfer();
// TODO: Logic for distributing to managers based on allocation
emit RAACDepositedFromPool(msg.sender, amount);
}

The calculateRaacRewards() function uses the total contract RAAC balance (raacToken.balanceOf(address(this))) when determining user 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;
}

This combination allows users to claim rewards proportional to their deposits relative to the entire RAAC balance, including funds intended for manager allocations.

Impact

Users can steal manager-allocated RAAC tokens

Tools Used

Manual Review

Recommended Fix

Implement segregated balance tracking:

// Add new state variables
uint256 public managerRaacBalance;
uint256 public userRaacBalance;
// Modify depositRAACFromPool
function depositRAACFromPool(uint256 amount) external... {
...
managerRaacBalance += amount;
// Instead of direct transfer
}
// Modify reward calculation
function calculateRaacRewards(address user) public view returns (uint256) {
uint256 totalDeposits = deToken.totalSupply();
if (totalDeposits < 1e6) return 0;
return (userRaacBalance * userDeposits[user]) / totalDeposits;
}

This creates separate accounting tracks for user rewards and manager allocations, preventing fund commingling.

Updates

Lead Judging Commences

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

StabilityPool::calculateRaacRewards uses contract balance for reward calculation, incorrectly including tokens meant for manager allocation - Manager allocation not implemented

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

StabilityPool::calculateRaacRewards uses contract balance for reward calculation, incorrectly including tokens meant for manager allocation - Manager allocation not implemented

Support

FAQs

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

Give us feedback!