The updatePeriod() function fails to update lastUpdateTime correctly when a new period starts. This results in rewards being calculated incorrectly, as the time elapsed between the end of the previous period and the start of the new period is also counted, leading to an over-distribution of rewards.
https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/governance/gauges/BaseGauge.sol#L452
The updatePeriod() function is responsible for transitioning the contract from one period to the next. However, it does not update lastUpdateTime to the start of the new period. Instead, it sets lastUpdateTime to nextPeriodStart, which is the start of the next period. This causes the following issue:
When getRewardPerToken() is called, it calculates rewards based on the time elapsed since lastUpdateTime.
If lastUpdateTime is not updated to the start of the new period, the time elapsed between the end of the previous period and the start of the new period is also included in the reward calculation.
This results in rewards being over-distributed, as the contract incorrectly accounts for time outside the active period.
Over-Distribution of Rewards: Users can claim rewards for time outside the active period, leading to an unfair distribution of tokens.
Financial Loss: The protocol may lose funds due to excessive reward payouts.
Incorrect Accounting: The reward distribution mechanism becomes unreliable, undermining trust in the protocol.
run in BaseGauge.test.js
Manual code review.
Test output analysis.
Update lastUpdateTime to the start of the new period in the updatePeriod() function. Specifically, set lastUpdateTime to periodState.periodStartTime after resetting the period state.
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.