Closed sherlock-admin4 closed 1 month ago
juaan
Medium
If a reward is distributed while there are no stakers, the reward is permanently lost.
In StakingRewards:144, the updateReward modifier is called. The modifier includes the following code:
updateReward
rewardPerTokenStored = rewardPerToken(); lastUpdateTime = lastTimeRewardApplicable();
The first line sets rewardPerTokenStored to the result of the following function:
rewardPerTokenStored
function rewardPerToken() public view returns (uint256) { if (_totalSupply == 0) { return rewardPerTokenStored; } return rewardPerTokenStored + (((lastTimeRewardApplicable() - lastUpdateTime) * rewardRate * 1e18) / _totalSupply); }
When there are no stakers yet, _totalSupply is 0.
_totalSupply
0
This means that rewardPerTokenStored is not updated if there are no stakers.
However at the same time, lastUpdateTime is updated to block.timestamp:
lastUpdateTime
block.timestamp
function lastTimeRewardApplicable() public view returns (uint256) { return block.timestamp < periodFinish ? block.timestamp : periodFinish; }
Since the timestamp has been updated but the rewards per token have not, the rewards are effectively lost and stuck in the contract.
The rewards distributed to the StakingRewards contract are lost and un-redeemable.
StakingRewards
https://github.com/sherlock-audit/2024-06-makerdao-endgame/blob/dba30d7a676c20dfed3bda8c52fd6702e2e85bb1/endgame-toolkit/src/synthetix/StakingRewards.sol#L144
Manual Review
Duplicate of #96
juaan
Medium
If a reward is distributed while there are no stakers, the reward is permanently lost.
Summary
If a reward is distributed while there are no stakers, the reward is permanently lost.
Vulnerability Detail
In StakingRewards:144, the
updateReward
modifier is called. The modifier includes the following code:The first line sets
rewardPerTokenStored
to the result of the following function:When there are no stakers yet,
_totalSupply
is0
.This means that
rewardPerTokenStored
is not updated if there are no stakers.However at the same time,
lastUpdateTime
is updated toblock.timestamp
:Since the timestamp has been updated but the rewards per token have not, the rewards are effectively lost and stuck in the contract.
Impact
The rewards distributed to the
StakingRewards
contract are lost and un-redeemable.Code Snippet
https://github.com/sherlock-audit/2024-06-makerdao-endgame/blob/dba30d7a676c20dfed3bda8c52fd6702e2e85bb1/endgame-toolkit/src/synthetix/StakingRewards.sol#L144
Tool used
Manual Review
Recommendation
Duplicate of #96