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 of
totalDistributed`.
Ensure _calculatePendingRewards
accounts for past claims properly, without penalizing users with low voting power.
Review other areas where totalDistributed
s 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.