code-423n4 / 2021-12-pooltogether-findings

0 stars 0 forks source link

`getRemainingRewards()` Malfunction for ended promotions #108

Closed code423n4 closed 2 years ago

code423n4 commented 2 years ago

Handle

WatchPug

Vulnerability details

For ended promotions, _getCurrentEpochId() may return a epochId larger than numberOfEpochs.

As a result, _getRemainingRewards() will revert at _promotion.numberOfEpochs - _getCurrentEpochId(_promotion).

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;
}

Recommendation

Consider checking if block.timestamp > _promotionEndTimestamp in getRemainingRewards() and return 0 for ended promotions.

PierrickGT commented 2 years ago

The promotion will be inactive, so it will revert before calculating the remaining rewards. For this reason, I have disputed the issue. Relevant code:

dmvt commented 2 years ago

Agree with sponsor's explanation