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;
int128 adjustedBias = point.bias;
if (timeDelta > 0) {
int128 decay = (point.slope * int128(int256(timeDelta))) / int128(int256(1));
adjustedBias = point.bias - decay;
}
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.