Core Contracts

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

Users can't claim their rewards in `FeeColletor`

Summary

Current reward claiming mechainsm prevents some users from claiming their share of the rewards.

Vulnerability Details

To claim rewards users calls claimRewards.

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

claimRewards uses _calculatePendingRewards to calculate user's rewards. It considers user's current voting power and total voting power to calcualte user's share of the totalDistributed tokens.

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 issue is that claimRewards sets totalDistributed as user's claimed rewards. It prevents user from future reward claims.

Example:

First claim:

Alice voting power = 100
Bob voting power = 100
Total voting power = 200
totalDistributed = 100

Alice and Bob receive 50 tokens from totalDistributed and for both of them the userRewards is set to 100.

Second claim:

Alice voting power = 100
Bob voting power = 900
Total voting power = 1000
totalDistributed = 200 -> 100 more tokens are now distributed for 1000 total voting power

Alice should receive 20 tokens from new totalDistributed and Bob should receive 180 tokens.

For Bob the calculations are (180 > 100 so) 180 - 100 (userRewards) = 80 and he will receive his rewards.

For Alice the calculations are (20 < 100 so) _calculatePendingRewards will return 0.

Impact

_calculatePendingRewards will block some users from claiming part of their rewards.

Tools Used

Manual Review, Hardhat

Recommendations

Fix _calculatePendingRewards so that users can claim their 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.