The FeeCollector contract's 'claimRewards' contains a critical flaw in its checkpoint logic. By setting userRewards[user] = totalDistributed, the contract prevents users from claiming future rewards because the calculated share will always be less than their checkpoint value.
In the claimRewards
function:
The issue arises because of the reward calculation in _calculatePendingRewards
:
Mathematical proof of the issue:
After first claim: userRewards[user] = totalDistributed
For any subsequent claim:
share = (totalDistributed * userVotingPower) / totalVotingPower
Since userVotingPower < totalVotingPower
, then share < totalDistributed
Therefore share < userRewards[user]
always
Result: returns 0, making rewards unclaimable
Users can only claim rewards once
All subsequent reward distributions become unclaimable
Breaks the entire reward distribution mechanism
Loss of funds for users who should receive rewards
Manual code review
Track claimed amount instead of total distributed.
Alternative: Use distribution index tracking or use a cumulative rewards per share approach.
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.