When a veRAAC holder claims rewards with claimRewards function in FeeCollector contract, pending rewards are calculated as follows:
The problem is that this function assumes userRewards[user]will return the rewards already claimed by the user, but it is not the case. Indeed, claimRewards function executes the following line:
This means each time a user claims rewards, userRewards[user]is set to the total veRAAC distributed by the contract (already claimed or not, by all users).
This will lead to DoS of the claimRewards function and wrong calculation of rewards amount leading to loss of rewards fo veRAAC holders.
Consequences of this vulnerability are:
First claim will happen normally, with share > userRewards[user]and share being claimed (not the correct amount, but this is another issue).
For the second claim, _calculatePendingRewards will return 0, because share won't be greater than userRewards[user]which is set to totalDistributed. User will have to wait for share to be greater than userRewards[user] (totalDistributed at the moment of last claim). If a user has 1% of veRAAC token supply, he will have to wait for totalDistributed to be 100 more bigger than when he first claimed. Once share is greater than userRewards[user](totalDistributed), the reward for the user is calculated with share - userRewards[user]which is incorrect because userRewards[user] represents total distributed rewards instead of total rewards claimed by the user, leading to a way lower amount of rewards than expected.
This means :
The less veRAAC tokens a user holds, the more time the DoS will last after first claim, because more fees need to be distributed to make _calculatePendingRewards not return 0
The more totalDistributed grows, the more the DoS increases between 2 claims.
But the biggest problem is that after first claim, claimable fees are way lower than they should.
The impact of this issue is high, given that it leads to loss of rewards for user + denial of service of claimRewards function after first claim
Manual review.
Make sure that userRewards[user] indeed tracks rewards claimed per user.
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.