Open code423n4 opened 2 years ago
WatchPug
For unstarted promotions, cancelPromotion() will revert at block.timestamp - _promotion.startTimestamp in _getCurrentEpochId().
cancelPromotion()
block.timestamp - _promotion.startTimestamp
_getCurrentEpochId()
Call stack: cancelPromotion() -> _getRemainingRewards() -> _getCurrentEpochId().
_getRemainingRewards()
https://github.com/pooltogether/v4-periphery/blob/0e94c54774a6fce29daf9cb23353208f80de63eb/contracts/TwabRewards.sol#L331-L336
function _getRemainingRewards(Promotion memory _promotion) internal view returns (uint256) { // _tokensPerEpoch * _numberOfEpochsLeft return _promotion.tokensPerEpoch * (_promotion.numberOfEpochs - _getCurrentEpochId(_promotion)); }
https://github.com/pooltogether/v4-periphery/blob/0e94c54774a6fce29daf9cb23353208f80de63eb/contracts/TwabRewards.sol#L276-L279
function _getCurrentEpochId(Promotion memory _promotion) internal view returns (uint256) { // elapsedTimestamp / epochDurationTimestamp return (block.timestamp - _promotion.startTimestamp) / _promotion.epochDuration; }
Consider checking if _promotion.startTimestamp > block.timestamp and refund _promotion.tokensPerEpoch * _promotion.numberOfEpochs in cancelPromotion().
_promotion.startTimestamp > block.timestamp
_promotion.tokensPerEpoch * _promotion.numberOfEpochs
Handle
WatchPug
Vulnerability details
For unstarted promotions,
cancelPromotion()
will revert atblock.timestamp - _promotion.startTimestamp
in_getCurrentEpochId()
.Call stack:
cancelPromotion()
->_getRemainingRewards()
->_getCurrentEpochId()
.https://github.com/pooltogether/v4-periphery/blob/0e94c54774a6fce29daf9cb23353208f80de63eb/contracts/TwabRewards.sol#L331-L336
https://github.com/pooltogether/v4-periphery/blob/0e94c54774a6fce29daf9cb23353208f80de63eb/contracts/TwabRewards.sol#L276-L279
Recommendation
Consider checking if
_promotion.startTimestamp > block.timestamp
and refund_promotion.tokensPerEpoch * _promotion.numberOfEpochs
incancelPromotion()
.