Closed sherlock-admin2 closed 11 months ago
Hello,
Thanks a lot for your attention.
We are aware of a potential Out Of Gas (OOG) issue if a user does not claim at all over an extended period. As you mentioned, in cases spanning multiple years, the transaction could be blocked. However, this is an extreme case and is unlikely to occur. If it does happen, we can implement a simple function within the upgradeable pattern to allow claims with a maximum limit, thus unblocking the users if necessary.
Therefore, in conclusion, we must consider your issue as invalid.
Regards, Convergence Team
detectiveking
medium
Claiming rewards might take more gas than Ethereum block gas limit
Summary
There is a specific case where claiming rewards might cost the user more than 30,000,000 gas (the Ethereum block gas limit), meaning they might never be able to claim rewards.
Vulnerability Detail
Here is a snippet from
_claimCvgSdtRewards
:First, let's start with
_stakedAmountEligibleAtCycle
:We first iterate through all cycles since the last time that we claimed (or just the first time we staked), and then inside
_stakedAmountEligibleAtCycle
have to again iterate through all the cycles in_stakingHistoryByToken
, which is just all the staking cycles in which we deposited or withdrew. Let's say that we haven't claimed rewards for an extremely long, but still reasonable time (say 5 - 10 years, which translates to 260 - 520 cycles). We've also been consistently depositing/withdrawing every week during this timeframe, but again not claiming. This becomes extremely expensive in that case, and there's also a SLOAD inside the while loop.There is also this inside
_claimCvgSdtRewards
:For each cycle since the last time we claimed, we must not only iterate through all possible reward tokens, but also make a separate storage access for each one. This can also get expensive very fast, especially if we haven't claimed in a long time and there are lots of reward tokens.
This can get even worse when you consider that in
SdtRewardReceiver
we have aclaimMultipleStaking
which should be able to claim for multiple staking contracts and multiple token ids.Impact
Under specific circumstances, user might not be able to claim rewards since it would take more than 30,000,000 gas
Code Snippet
https://github.com/sherlock-audit/2023-11-convergence/blob/main/sherlock-cvg/contracts/Staking/StakeDAO/SdtStakingPositionService.sol#L429-L515
Tool used
Manual Review
Recommendation
No need to have two loops (one outer loop over the cycle and then an inner loop to determine the staking amount before the cycle); you can just use a two pointers approach instead.