Malicious actors can repeatedly call distributeRewards
with a reward of 0 to gradually reduce the rewardRate, which will dilute stakers' rewards.
distributeRewards makes a call to _notifyReward. Inside the _notifyReward()
, If the current time is past rewardData.periodFinish, the reward rate is calculated simply as:
If not, it takes the remaining time and leftover rewards into account:
A malicious actor can repeatedly call distributeRewards
with nextRewardAmount set to 0 .
By doing so, they can manipulate the rewardRate calculation, causing it to decrease gradually over time.
Suppose rewardData.rewardRate is initially 1000.
After 20% of the rewardDuration has passed, a malicious actor calls distributeRewards
with nextRewardAmount set to 0.
The remaining time is 0.8 * rewardDuration and leftover rewards are 0.8 * rewardDuration * 1000 = 800.
The rewardRate drops from 1000 to 800.
Similarly if second Call is made to distributeRewards
with nextRewardAmount = 0, then rewardRate drops from 800 to 640.
if the function is called repeatedly, the rewards for stakers will be diluted over time.
Manual review, Vs Code
Ensure nextRewardAmount is managed carefully and cannot be set to 0 or a very low value maliciously so that the reward rate can be prevented from decreasing unfairly when new rewards are added.
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.