Core Contracts

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

RAAC Reward Dilution for Early Stakers in StabilityPool

Summary

The StabilityPool contract faces an issue where rewards are distributed without considering the duration a user has been staked. When new participants deposit their assets, they receive RAAC rewards at the same rate as long-term stakers. Since rewards are calculated based on the ratio totalRewards * userDeposit / totalDeposits, this causes dilution—reducing the rewards of early participants while new users, who have been staked for a shorter time, receive the same benefit.

Vulnerability Details

  • Issue:

    • The current reward distribution mechanism considers only the proportion of assets a user holds in the pool but does not account for how long they have been staked.

    • As new users join, the total deposit pool increases, reducing the reward share for early participants. Since the formula does not factor in staking duration, long-term stakers do not receive any additional benefit.

  • Affected Code:

    return (totalRewards * userDeposit) / totalDeposits;
    • This approach distributes rewards solely based on asset proportion without rewarding early stakers for their extended commitment.

Impact

  • Unfair Reward Allocation:
    Early stakers, who have contributed to the pool for a longer duration, receive the same rewards as new participants, leading to an inequitable distribution.

  • Reduced Incentives for Long-Term Staking:
    As new users deposit funds, rewards for existing users decrease, discouraging them from keeping their assets staked in the pool.

  • Inefficient Reward System:
    The lack of time-based weighting results in an unfair system where users who have recently joined benefit as much as those who have participated from the beginning.

Tools Used

  • Manual Code Review

Recommendations

  1. Introduce Time-Based Weighting for Rewards:
    Adjust the reward calculation to consider the staking duration of each user. This ensures that early stakers receive a larger portion of the rewards compared to new participants.

    Modified formula for time-weighted rewards:

    uint256 stakingDuration = block.timestamp - userStakingStart[user];
    uint256 totalDuration = block.timestamp - poolStartTime;
    uint256 weightedUserDeposit = userDeposit * stakingDuration;
    uint256 weightedTotalDeposits = totalDeposits * totalDuration;
    return (totalRewards * weightedUserDeposit) / weightedTotalDeposits;
  2. Track Individual Staking Durations:
    Introduce a mechanism to store the timestamp of each user's first deposit, allowing the system to factor in how long assets have been staked.

    Example implementation for tracking staking start time:

    mapping(address => uint256) public userStakingStart;
    function deposit(uint256 amount) external {
    if (userStakingStart[msg.sender] == 0) {
    userStakingStart[msg.sender] = block.timestamp; // Record initial staking time
    }
    // Proceed with deposit logic...
    }
Updates

Lead Judging Commences

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

Give us feedback!