Core Contracts

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

Incorrect Calculation of Pending Rewards in FeeCollector Contract

Summary

The FeeCollector contract in its current implementation contains a vulnerability in the _calculatePendingRewards function that results in incorrect reward calculations for users who claim rewards multiple times. The issue stems from the calculation of rewards based on the userRewards[user] value, which doesn't properly account for subsequent reward distributions, leading to incorrect reward payouts.

Vulnerability Details

The function _calculatePendingRewards is responsible for calculating the pending rewards for a user based on their voting power in the protocol. The current logic is as follows:

return share > userRewards[user] ? share - userRewards[user] : 0;

Here, share is the amount of reward the user should receive for the current period, while userRewards[user] is supposed to track the total amount the user has claimed. However, userRewards[user] is incorrectly being used to track the total rewards claimed by all users globally, instead of just the individual user's claims.

Incorrect Comparison: The condition share > userRewards[user] is comparing an individual user's claim (share) with the global total claimed rewards (userRewards[user]), which is incorrect. This causes the logic to return 0 for future claims, preventing the user from claiming further rewards.

Impact

This issue affects the reward distribution logic for users in the protocol. Specifically:

  1. Potential Loss of Rewards: Users may fail to claim all their rightful rewards, leading to a loss of potential earnings.

  2. Disrupted Reward Mechanism: This vulnerability undermines the integrity of the reward distribution mechanism, which is crucial for incentivizing users to participate in the protocol.

Tools Used

Manual Code Review

Recommendations

The issue can be fixed by modifying the reward calculation logic in the _calculatePendingRewards function. The formula should properly account for the difference between the total distributed rewards and the rewards already claimed by the user, and scale that difference based on the user's voting power.

Replace the current reward calculation with the following:

function _calculatePendingRewards(address user) internal view returns (uint256) {
uint256 userVotingPower = veRAACToken.getVotingPower(user);
if (userVotingPower == 0) return 0;
uint256 totalVotingPower = veRAACToken.getTotalVotingPower();
if (totalVotingPower == 0) return 0;
- uint256 share = (totalDistributed * userVotingPower) / totalVotingPower;
- return share > userRewards[user] ? share - userRewards[user] : 0;
+ return totalDistributed > userRewards[user] ? ((totalDistributed - userRewards[user]) * userVotingPower) / totalVotingPower : 0;
}
Updates

Lead Judging Commences

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

FeeCollector::claimRewards sets `userRewards[user]` to `totalDistributed` seriously grieving users from rewards

Support

FAQs

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