Description:
The FeeCollector::claimRewards function incorrectly sets userRewards[user] to totalDistributed instead of pendingReward. Since totalDistributed is continuously incremented by shares[0], this results in an inflated value stored in userRewards[user].
Later, when _calculatePendingRewards is called, the function computes share as:
If a user has low voting power compared to the total voting power, their share will always be lower than userRewards[user], causing the function to return zero. This means affected users can never claim rewards again.
Impact:
Users with low voting power will permanently lose the ability to claim rewards after their first claim.
The function behaves as if they have already received all their future rewards, even though they haven’t.
This introduces a severe fairness issue where smaller stakeholders are disproportionately affected.
Proof of Concept:
Scenario:
Alice calls FeeCollector::claimRewards to claim her rewards.
userRewards[Alice] = totalDistributed is set (incorrectly).
Some time passes, and Alice calls _calculatePendingRewards again.
As Alice has low voting power, her computed share is lower than userRewards[Alice].
The function returns zero, permanently locking her out of future rewards.
Set userRewards[user] to pendingRewardinstead oftotalDistributed`.
Ensure _calculatePendingRewards accounts for past claims properly, without penalizing users with low voting power.
Review other areas where totalDistributeds used to prevent similar logical errors.
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.