The BaseGauge
contract is designed to distribute rewards over fixed periods. However, a critical flaw in how the contract calculates the period's end time results in an infinite extension of the period. This prevents proper period transitions and disrupts the intended reward distribution mechanism.
The periodFinish()
function determines when a reward period ends:
https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/governance/gauges/BaseGauge.sol#L560
This function calculates the period's end time as lastUpdateTime + getPeriodDuration()
. However, lastUpdateTime
is updated frequently in the _updateReward()
function, which means the period is continuously extended and never truly ends.
https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/governance/gauges/BaseGauge.sol#L167
The _updateReward()
function dynamically updates lastUpdateTime
:
Since lastUpdateTime
is updated frequently, periodFinish()
always returns a time in the future, effectively preventing the period from ever ending.
This mean that lastTimeRewardApplicable
will in most case return block.timestamp
https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/governance/gauges/BaseGauge.sol#L552
No True Period End: The period is continuously extended, allowing new rewards to be injected indefinitely without transitioning to a new period.
Admin Dependency: Admins will manually start a new period using updatePeriod
. If a period ends and the emission cap is exceeded before a new period begins, users may receive disproportionate rewards, and some users may lose rewards due to insufficient reward notification.
Reward Distribution Issues: Rewards are distributed based on periods, and the inability to properly end a period lead to inconsistencies in reward distribution.
To fix this issue, modify the periodFinish()
function to use a fixed start time for the period instead of the dynamically updated lastUpdateTime
. This ensures that each period has a definitive start and end.
Replace lastUpdateTime
with a fixed periodStartTime
that is set only once at the beginning of a new period:
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.