The function notifyRewardAmount(uint256 amount) attempts to enforce a cap on rewards by checking if amount > periodState.emission. However, it does not account for cumulative distributions within the same period. Specifically, periodState.distributed tracks how much has already been distributed, but the function does not check if adding the new amount exceeds the period’s emission limit. This allows an attacker (or even an honest controller) to repeatedly call notifyRewardAmount() within the same period, each time staying below periodState.emission in a single call but exceeding the cap cumulatively over multiple calls. The faulty implementation is as follows:
Because the function only checks whether amount is greater than periodState.emission per call and not whether periodState.distributed + amount exceeds periodState.emission, an attacker can drain the reward contract by calling notifyRewardAmount() multiple times, distributing far more rewards than intended.
The contract can distribute an unlimited amount of rewards, potentially depleting the entire rewardToken balance and leading to loss of funds for future stakers.
Modify notifyRewardAmount() to include a cumulative check:
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.