Core Contracts

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

User rewards are incorrectly reset in claim rewards function in fee collector contract.

Summary

User rewards are incorrectly reset in claim rewards function which can cause loss of rewards for the user.

Vulnerability Details

Following is claim rewards function

function claimRewards(address user) external override nonReentrant whenNotPaused returns (uint256) {
if (user == address(0)) revert InvalidAddress();
uint256 pendingReward = _calculatePendingRewards(user);
if (pendingReward == 0) revert InsufficientBalance();
// Reset user rewards before transfer
userRewards[user] = totalDistributed;
// Transfer rewards
raacToken.safeTransfer(user, pendingReward);
emit RewardClaimed(user, pendingReward);
return pendingReward;
}
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;
}

Suppose initally 100 tokens are distributed and user voting power = 50 and total voting power = 200

So the user rewards will be 100*50/200 = 25 tokens.

User claims these 25 tokens.

Now userRewards[user] will be set to total distributed i.e = 100

Now suppose 100 more tokens are distributed due to which totalDistributed = 200

Now the user voting power left = 40 and total voting power is still 200

So now the user should receive 100*(40/200) = 20 more tokens

Lets see how share value is calcualted now

share = (totalDistributed * userVotingPower) / totalVotingPower;

share = 200*40/200 = 40

As initially userRewards[user] were set to 100

Hence share(40) will be less than userRewards[user] (100) hence pending reward will be zero and claim function will revert.Hence loss of rewards.

Impact

User doesn't receive their legitimate rewards which causes loss to them.

Tools Used

Manual

Recommendations

Redesign how userRewards[user] needs to be set for fair and accurate calculation of the rewards.

Updates

Lead Judging Commences

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