Closed sherlock-admin4 closed 1 month ago
Even if some rewards end up not being claimed it is not a significant issue. The submission fails to show an impact to the project. Also this code is unchanged from the original Synthetix Staking Rewards contract, so out of scope. Also, the rewards are not even "permanently locked" as the owner can use recoverERC20().
Matin
Medium
Rewards are distributed even when there are no stakers, resulting in the rewards being permanently locked away
Summary
An issue causes the system to mistakenly believe that rewards are being dispersed even in the absence of stakers. If
notifyRewardAmount()
is called before any users stake, the rewards intended for the first stakers become permanently locked in the contract. This issue results in non-distributed rewards being stuck in the contract.Vulnerability Detail
The code accounts for scenarios where there are no users by not updating the cumulative rate when
_totalSupply
is zero. However, it fails to include a similar condition for tracking the time duration.Due to this oversight, even when there are no users staking, the accounting logic incorrectly assumes that funds are being dispersed during that duration because the starting timestamp is updated. As a result, if the
notifyRewardAmount()
function is called before any users are staking, the rewards that should have been allocated to the first stakers instead accrue to no one and become permanently locked in the contract.Proof of Concept
This test shows the scenario mentioned above:
The test result is:
Consequently, 86400 ether is locked in the contract, as these rewards were never distributed.
Impact
Non-distributed rewards are stuck in the contract.
Code Snippet
https://github.com/sherlock-audit/2024-06-makerdao-endgame/blob/main/endgame-toolkit/src/synthetix/StakingRewards.sol#L84-L90
Tool used
Manual Review
Recommendation
In the function
notifyRewardAmount()
, check if there are stakers in the contract: