veRAACToken holders are entitled to part of the fees collected. The fees are distributed using _processDistributions()
function of the fee collector, where totalDistributed
variable is incremented.
Later holders can call claimRewards()
to claim their rewards. However, the function incorrectly sets userRewards to totalDistributed
instead of pendingReward
.
Assume a scenario where total voting power is 1000, user's voting power is 100, while totalDistributed
is also 100. _calculatePendingRewards
will calculated user's rewards in the following way.
share
will be equal to 10, and as userRewards
currently is 0, the function will return 10. After that userRewards
will be set to totalDistributed
, which is 100. Now let's say totalDistributed
got incremented to 110. If claimRewards
is called again, logically user's share should be calculated as 110 * 100 / 1000 = 11
, and the final value to receive is 11 minus 10 of already claimed rewards, so the final result of new rewards should be 1. However, because userRewards
is currently equal to 100, the return value of the _calculatePendingRewards()
will be 0, since share
is lesser than userRewards
, while userRewards
will yet again be set to totalDistributed
which is now equal to 110. As a result, after the first claim user has no way of claiming new rewards.
After user has claimed his rewards from feeCollector for the first time, he is now unable to claim any subsequent rewards. Rewards belonging to users will remain locked in the feeCollector without a way to claim them.
Set userRewards
to pendingReward
instead of totalDistributed
.
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.