You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It rebases the yield amount and the leftover yields over the yieldDuration period.
This can lead to diluting the yield rate and rewards being dragged out forever by malicious new yield deposits.
Let's take a look at the following example:
For the sake of the example, imagine the current yieldRate is 1000 yield / yieldDuration.
When 10% of yieldDuration has passed, a malicious notifier calls notifyRewards with _amount = 0.
The new yieldRate = 0 + 900 / yieldDuration, which means the yieldRate just dropped by 10%.
This can be repeated infinitely. After another 10% of yield time passed, they trigger notifyRewardAmount(0) to reduce it by another 10% again: yieldRate = 0 + 720 / yieldDuration.
The yieldRate should never decrease by a notifyRewardAmount call.
Recommendations
There are two potential fixes to this issue:
If the periodFinish is not changed at all and not extended on every notifyRewardAmount call. The yieldRate should just increase by yieldRate += amount / (periodFinish - block.timestamp).
Keep the yieldRate constant but extend periodFinish time by += amount / yieldRate.
The text was updated successfully, but these errors were encountered:
Severity
Impact: High, because users` yield can be manipulated
Likelihood: Medium, because a malicious notifier can call it as many times as he wants
Description
The
notifyRewardAmount
function takes a yield amount and extends theperiodFinish
to now +yieldDuration
:periodFinish = block.timestamp + yieldDuration;
If the
block.timestamp
is less thanperiodFinish
, it will enter the followingelse
block:It rebases the yield amount and the
leftover
yields over theyieldDuration
period.This can lead to diluting the yield rate and rewards being dragged out forever by malicious new yield deposits.
Let's take a look at the following example:
yieldRate
is1000 yield / yieldDuration
.yieldDuration
has passed, a malicious notifier callsnotifyRewards
with_amount = 0
.yieldRate = 0 + 900 / yieldDuration
, which means theyieldRate
just dropped by 10%.yieldRate = 0 + 720 / yieldDuration
.The yieldRate should never decrease by a
notifyRewardAmount
call.Recommendations
There are two potential fixes to this issue:
If the
periodFinish
is not changed at all and not extended on everynotifyRewardAmount
call. TheyieldRate
should just increase byyieldRate += amount / (periodFinish - block.timestamp)
.Keep the
yieldRate
constant but extendperiodFinish
time by+= amount / yieldRate
.The text was updated successfully, but these errors were encountered: