The FeeCollector::claimRewards() function incorrectly updates user reward tracking by setting it to totalDistributed
instead of adding the claimed amount, causing users to lose rewards as their voting power decreases over time.
In FeeCollector::claimRewards(), after calculating pending rewards, the function updates userRewards[user]
by setting it to totalDistributed
:
This is problematic because:
userRewards[user]
should track the cumulative amount of rewards claimed by the user
totalDistributed
represents all fees distributed to date
Setting userRewards[user] = totalDistributed
means future reward calculations will compare against the total distributed amount rather than what the user has actually claimed
The _calculatePendingRewards() function calculates rewards based on:
Since voting power decreases over time, setting userRewards[user] = totalDistributed
means the user's calculated share
will always be less than their recorded userRewards
, resulting in 0 rewards.
User A deposits tokens and receives voting power of 1000
totalDistributed
is 10000 tokens
User A claims rewards:
share = (10000 * 1000) / 10000 = 1000
userRewards[A] = 0
Claims 1000 tokens
userRewards[A]
is set to 10000 (totalDistributed)
Time passes, voting power decays to 800
New rewards are distributed, totalDistributed = 12000
User A tries to claim again:
share = (12000 * 800) / 10000 = 960
Since 960 < 10000 (userRewards[A]
), user gets 0 rewards
Users are denied their rightful rewards because the system incorrectly compares their earned share against the total distributed amount instead of their previously claimed amount. Even when users should be eligible for new rewards due to their voting power, they receive nothing since their calculated share will always be less than the total distributed amount from their last claim.
Track actual claimed amounts:
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.