DoS possible with many stakes
Severity: Low Difficulty: Medium
Type: Finding ID: TOB-UNI-STK-004
Target: UniswapV3Staker.sol
Description
To end an incentive a receive a refund for unclaimed rewards, an incentive creator must call the endIncentive function:
function endIncentive(IncentiveKey memory key) external override returns (uint256 refund) {
require(block.timestamp >= key.endTime, 'UniswapV3Staker::endIncentive: cannot end incentive before end time');
bytes32 incentiveId = IncentiveId.compute(key);
Incentive storage incentive = incentives[incentiveId];
refund = incentive.totalRewardUnclaimed;
require(refund > 0, 'UniswapV3Staker::endIncentive: no refund available');
require(
incentive.numberOfStakes == 0,
'UniswapV3Staker::endIncentive: cannot end incentive while deposits are staked'
);
// issue the refund
incentive.totalRewardUnclaimed = 0;
TransferHelper.safeTransfer(address(key.rewardToken), key.refundee, refund);
// note we never clear totalSecondsClaimedX128
emit IncentiveEnded(incentiveId, refund);
}
Figure 4.1: endIncentive function
The function requires that the number of stakes in the incentive be nil. A stake can be unstaked by anyone after the end of the incentive. Nevertheless, it can happen that an attacker willing to pay a sufficiently high gas fee can prevent the incentive creator from withdrawing their refund.
Exploit Scenario
Eve deposits 1000 NFTs representing negligible position amounts. She stakes them all unto one incentive. Alice, an incentive creator, cannot end her incentive and withdraw her refund.
Recommendation
Consider adding a mechanism to allow an incentive creator to end an incentive if a sufficient amount of time has passed after the end of the incentive. In that case, ensure that users can still unstake & withdraw their token, even if they might not get rewards anymore.
Description To end an incentive a receive a refund for unclaimed rewards, an incentive creator must call the
endIncentive
function:Figure 4.1:
endIncentive
function The function requires that the number of stakes in the incentive be nil. A stake can be unstaked by anyone after the end of the incentive. Nevertheless, it can happen that an attacker willing to pay a sufficiently high gas fee can prevent the incentive creator from withdrawing their refund. Exploit Scenario Eve deposits 1000 NFTs representing negligible position amounts. She stakes them all unto one incentive. Alice, an incentive creator, cannot end her incentive and withdraw her refund. Recommendation Consider adding a mechanism to allow an incentive creator to end an incentive if a sufficient amount of time has passed after the end of the incentive. In that case, ensure that users can still unstake & withdraw their token, even if they might not get rewards anymore.