Core Contracts

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

Incorrect Reward Distribution in StabilityPool Based on rToken Deposits Instead of deToken Holdings

Summary

The rewards distribution mechanism in StabilityPool incorrectly calculates user rewards based on rToken deposits instead of deToken holdings. This leads to an unfair allocation of rewards, disproportionately benefiting users who deposit more rToken rather than those who hold more deToken, which is the correct metric for rewards distribution.

Vulnerability Details

Issue: Incorrect Reward Calculation Formula

  • When users deposit rToken, they receive deToken based on a predefined exchange rate (e.g., 1 deToken per 2 rToken).

  • The contract currently calculates user rewards as:

    return (totalRewards * userDeposit) / totalDeposits;

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

    where userDeposit is the rToken amount deposited by the user, and totalDeposits is the total supply of deToken.

Example of Incorrect Distribution

Scenario:

  • exchangeRate is 2

  • User A deposits 100 rToken, receiving 50 deToken.

  • User B deposits 900 rToken, receiving 450 deToken.

  • Total rewards = 100.

  • Total deToken supply = 500.

Current Calculation (Incorrect):

  • User A’s reward: 100 * 100 / 500 = 20

  • User B’s reward: 900 * 100 / 500 = 180

The total reward is 100 but 200 share.

Impact

Incorrect reward distribution

Tools Used

  • Manual code review.

Recommendations

  • Update the reward calculation formula to be based on deToken holdings:

    function calculateRaacRewards(address user) public view returns (uint256) {
    uint256 userBalance = deToken.balanceOf(user);
    uint256 totalSupply = deToken.totalSupply();
    uint256 totalRewards = raacToken.balanceOf(address(this));
    if (totalSupply == 0) return 0;
    return (totalRewards * userBalance) / totalSupply;
    }

correct Calculation :

  • User A’s reward: 50 * 100 / 500 = 10

  • User B’s reward: 450 * 100 / 500 = 90

Updates

Lead Judging Commences

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