Core Contracts

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

user loss rewards after first claim

Author Revealed upon completion

Summary

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;
}

The reward is implemented to be received based on the value returned from the _calculatePendingRewards function. The reward is received as a percentage of the totalDistributed based on the voting power. However, after the first reward, userRewards[user] is set to totalDistributed, causing the user to lose rewards.

For example, assuming user A has a voting power percentage of 1% and totalDistributed is 100, the first reward will be 1% of 100, which is 1. Afterward, userRewards[user] will be set to 100, and the user will not receive rewards until totalDistributed exceeds 10,000.

Recommended mitigation steps

// Reset user rewards before transfer
// userRewards[user] = totalDistributed;
userRewards[user] = pendingReward;

By making the change above, users will be able to receive rewards correctly.

References

Updates

Lead Judging Commences

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