The FeeCollector
contract calculates user rewards based on their current voting power rather than historical voting power at the time of fee distribution, leading to unfair reward distribution and potential manipulation.
In FeeCollector.sol
, the _calculatePendingRewards
function uses current voting power ratios to determine user rewards for all historical fee distributions:
The issue arises because:
totalDistributed
accumulates all historical fee distributions and is never reset
Rewards calculation uses current voting power ratio against this cumulative value
No tracking of historical voting power when fees were actually distributed
Users who acquire veRAACToken later unfairly receive rewards from distributions that occurred before they held tokens
Users who had more veRAACToken in the past but reduced their position get fewer rewards than they should
Can be manipulated by timing veRAACToken acquisitions just before reward claims
Incorrect economic model that doesn't properly incentivize long-term holding
Manual Review
Implement standard rewards distribution tracking similar to widely used and audited staking reward systems (like Synthetix's StakingRewards). The key improvements should be:
Track rewards per token instead of cumulative total distributed rewards
Store user checkpoints that record when users modify their veRAACToken positions
Calculate rewards based on the actual period users held their tokens
Update user reward checkpoints whenever they:
Claim rewards
Modify their veRAACToken balance
Interact with rewards in any way
This ensures users only receive rewards for periods they actually held tokens and prevents manipulation through timing of token acquisitions.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.