Core Contracts

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

Outdated `totalRewards` Leads to Stale RAAC Rewards Calculation in `getPendingRewards` Function

Summary

The getPendingRewards function in the StabilityPool contract calculates a user's pending RAAC rewards based on the contract’s RAAC token balance (totalRewards = raacToken.balanceOf(address(this))). However, this value does not get updated whenever new RAAC rewards are minted by the RaacMinter contract. As a result, users may see incorrect pending rewards because the calculation does not account for newly minted RAAC tokens, potentially leading to lower-than-expected rewards.

Vulnerability Details

  • Issue:

    • The getPendingRewards function retrieves totalRewards from the contract's RAAC token balance but does not ensure that newly minted rewards are included in this value.

    • The minting of new RAAC rewards occurs within _mintRAACRewards, which is triggered through the tick() function based on emissionRate and block timestamps. However, since getPendingRewards does not call this function, it relies on potentially outdated values.

    • This means that users checking their pending rewards may see stale reward amounts, leading to miscalculations.

  • Affected Code:

    function getPendingRewards(address user) external view returns (uint256) {
    return calculateRaacRewards(user);
    }
    function calculateRaacRewards(address user) public view returns (uint256) {
    uint256 userDeposit = userDeposits[user];
    uint256 totalDeposits = deToken.totalSupply();
    uint256 totalRewards = raacToken.balanceOf(address(this)); // Potentially outdated value
    if (totalDeposits < 1e6) return 0;
    return (totalRewards * userDeposit) / totalDeposits;
    }
  • Root Cause:
    The getPendingRewards function does not update the RAAC rewards balance before performing calculations, leading to outdated or incorrect reward estimates.

Impact

  • Inaccurate Reward Calculation:
    Users may see lower pending rewards than they are entitled to because the calculation does not include newly minted RAAC tokens.

  • Unequal Reward Distribution:
    Users who frequently interact with the system (e.g., deposit, withdraw) may receive correct rewards, while those who only check their pending rewards without further interactions may get outdated values.

Tools Used

  • Manual Code Review

Recommendations

  1. Ensure totalRewards is Updated Before Calculating Pending Rewards:
    Modify the getPendingRewards function to refresh the RAAC rewards before performing calculations. This can be done by calling _mintRAACRewards() or RaacMinter.tick() to ensure the latest rewards are accounted for.

    Example Fix:

    function getPendingRewards(address user) external view returns (uint256) {
    // Ensure rewards are updated before calculation
    _mintRAACRewards();
    return calculateRaacRewards(user);
    }
  2. Decouple Reward Calculation from Minting Logic:
    Instead of minting new rewards every time getPendingRewards is called (which could be inefficient), ensure that the contract updates totalRewards at fixed intervals or upon specific triggers (e.g., when users deposit or withdraw funds).

  3. Implement Automated Reward Updates:
    Set up a mechanism where the minting of new RAAC rewards happens consistently at predetermined intervals or upon certain user interactions. This will prevent the accumulation of stale rewards and maintain fair and transparent reward distribution.

Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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