The notifyRewardAmount
function in BaseGauge
contract is used to adjust the rewardRate
by distributing a specified amount
of rewards. However, there is a discrepancy between the actual rewards distributed and the value stored in state.distributed
. This inconsistency arises because state.distributed
is incremented by the amount
passed to notifyRewardAmount
, but the actual rewards distributed depend on the rewardRate
and the duration of the period. If notifyRewardAmount
is called multiple times, state.distributed
may not accurately reflect the true amount of rewards distributed, leading to potential issues in reward accounting and distribution.
The notifyRewardAmount
function updates the rewardRate
and increments state.distributed
by the amount
provided. Here is the relevant code:
The notifyReward
function calculates the rewardRate
based on the amount
and the period duration. Here is the relevant code:
Every time notifyRewardAmount
is called, state.distributed
is incremented by the amount
passed to the function. This assumes that the entire amount
will be distributed immediately, which is not the case. However, the actual rewards distributed depend on the rewardRate
and the duration of the period. The rewardRate
is calculated as amount / periodDuration
, meaning the rewards are distributed gradually over the period. If notifyRewardAmount
is called multiple times within a single period, the rewardRate
is updated, but the actual rewards distributed may not match the sum of the amounts
passed to notifyRewardAmount
.
Example Scenario
First Call to notifyRewardAmount
:
amount = 1000
periodDuration = 7 days
rewardRate = 1000 / 7 days ≈ 142.857 per day
state.distributed = 1000
Second Call to notifyRewardAmount
(after 3 days):
amount = 1000
rewardRate = 1000 / 7 days ≈ 142.857 per day
state.distributed = 1000 + 1000 = 2000
Actual Rewards Distributed:
After 3 days, the first rewardRate
would have distributed 142.857 * 3 ≈ 428.571
.
The second rewardRate
would distribute 142.857 * 4 ≈ 571.428
over the remaining 4 days.
Total rewards distributed: 428.571 + 571.428 ≈ 1000
However, state.distributed
is 2000
, which is double the actual rewards distributed.
Inaccurate Reward Accounting:
state.distributed
does not reflect the actual rewards distributed, leading to discrepancies in the protocol's accounting.
Potential Overestimation of Rewards:
If notifyRewardAmount
is called multiple times, state.distributed
may exceed the actual rewards distributed, causing the protocol to overestimate the rewards.
Reward Distribution Issues:
The discrepancy between state.distributed
and the actual rewards distributed can lead to incorrect reward calculations, potentially causing users to receive fewer rewards than expected.
The impact is Medium, the likelihood is Medium, so the severity is Medium.
Manual Review
Instead of incrementing state.distributed
by the amount
passed to notifyRewardAmount
, track the actual rewards distributed based on the rewardRate
and the time elapsed since the last update.
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.