Core Contracts

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

Calculate pending rewards in fee collector contract incorrectly uses user current voting power.

Summary

Calculate pending rewards in fee collector contract incorrectly uses user current voting power.

Vulnerability Details

Following is how pending rewards are calculated

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

In this when user voting power is calculated it calls getvoting power of user which is as follows

function getVotingPower(address account) public view returns (uint256) {
return _votingState.getCurrentPower(account, block.timestamp);
}

And getCurrentPower is as follows

function getCurrentPower(
VotingPowerState storage state,
address account,
uint256 timestamp
) internal view returns (uint256) {
RAACVoting.Point memory point = state.points[account];
if (point.timestamp == 0) return 0;
if (timestamp < point.timestamp) {
return uint256(uint128(point.bias));
}
uint256 timeDelta = timestamp - point.timestamp;
// Calculate decay
int128 adjustedBias = point.bias;
if (timeDelta > 0) {
// Calculate decay per second and multiply by time delta
int128 decay = (point.slope * int128(int256(timeDelta))) / int128(int256(1));
adjustedBias = point.bias - decay;
}
// Return 0 if power has fully decayed
return adjustedBias > 0 ? uint256(uint128(adjustedBias)) : 0;
}

As can be seen from above that the decayed power is returned .

But when total voting power is calculated it only checks the the total Supply of ve raac tokens as can be seen as follows

function getTotalVotingPower() external view override returns (uint256) {
return totalSupply();
}

this has various issue like suppose some users still have power left they will only be able to redeem rewards corresponding to voting power left and rest rewards will be left and they will be stuck.

So calculation of the voting power should be consistent.

Impact

Unfair calculation of the rewards.

Tools Used

Manual Review

Recommendations

Consider calcualting the user voting power by using their ve raac token balance instead of current power it make fair calculation of the rewards.

Updates

Lead Judging Commences

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

veRAACToken::getTotalVotingPower returns non-decaying totalSupply while individual voting powers decay, causing impossible governance quorums and stuck rewards in FeeCollector

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

veRAACToken::getTotalVotingPower returns non-decaying totalSupply while individual voting powers decay, causing impossible governance quorums and stuck rewards in FeeCollector

Support

FAQs

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