Core Contracts

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

User fund can be stuck if totalDistributed increases at very slow amount and user VotingPower increases very fast.

FeeCollector.sol::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();
userRewards[user] = totalDistributed;
// Transfer rewards
raacToken.safeTransfer(user, pendingReward);
emit RewardClaimed(user, pendingReward);
return pendingReward;
}

code snippet for FeeCollector.sol::_calculatePendingRewards -

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

Vulnerability Details

  1. for first call to claimRewards(); let's say totalDistributed = 100, userVotingPower = 100, totalVotingPower = 100.
    share_1 = 100*100/100 = 100, userRewards[user] = 100.

  2. for second call to claimRewards(); let's say totalDistributed = 200, userVotingPower = 150, totalVotingPower = 400.
    share_2 = 200*150/400 = 75

since; share_2 (latest share) < share_1 (old share), the else condition will be executed which means user will get 0
reward. even though user is eligible to get his reward.

Impact

whenever someone will call claimRewards() -> _calculatePendingRewards(), the user will not be able to get the reward due to revertion (if above scenario arises).

Tools Used

Manual

Recommendations

Reconsider architecture

Updates

Lead Judging Commences

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

Give us feedback!