Broad Umber Eagle
Medium
The lastTimeRewardDistributed
function in GovernanceStaker.sol
has a logical flaw that can result in incorrect reward distribution timestamps. This issue can lead to miscalculated rewards and an unfair distribution of funds among stakers.
The lastTimeRewardDistributed
function is intended to return the last timestamp when rewards were distributed. Its current logic is if the current time (block.timestamp) is greater than or equal to the reward period end time (rewardEndTime), it returns rewardEndTime
, otherwise, it returns the current time (block.timestamp).
This approach can fail in scenarios where the reward period is extended:
- A new reward period starts with rewardEndTime set 30 days into the future.
- Midway through this period (e.g., after 15 days), the notifyRewardAmount function is called to add more rewards, extending the reward period by updating rewardEndTime.
- In this case, lastTimeRewardDistributed would return the current block.timestamp, which does not accurately reflect the last time rewards were distributed.
- Incorrect Reward Calculations: using an inaccurate timestamp from lastTimeRewardDistributed can result in incorrect reward amounts being distributed to stakers.
- Unequal Distribution of Rewards: stakers may receive more or fewer rewards than they are entitled to, depending on the timing of their interactions with the contract.
function lastTimeRewardDistributed() public view virtual returns (uint256) {
if (rewardEndTime <= block.timestamp) return rewardEndTime;
else return block.timestamp;
}
To address this issue, a new state variable should be introduced to explicitly store the last reward distribution timestamp. This variable must be updated whenever notifyRewardAmount is called to ensure accuracy.
Suggested Fix:
- Introduce a State Variable: add a new variable lastRewardDistributionTime to track the actual last reward distribution time.
- Update in notifyRewardAmount: ensure this variable is updated whenever the reward period is modified.
- Refactor lastTimeRewardDistributed: modify the function to return the value of lastRewardDistributionTime for accurate tracking.