Platform: Code4rena
Start Date: 09/12/2021
Pot Size: $25,000 USDC
Total HM: 12
Participants: 25
Period: 4 days
Judge: LSDan
Total Solo HM: 4
Id: 64
League: ETH
Rank: 6/25
Findings: 4
Award: $1,067.54
🌟 Selected for report: 2
🚀 Solo Findings: 0
certora
cancelPromotion might fail unexpectedly. cancelPromotion calls _getRemainingRewards which calls _getCurrentEpochId:
function _getCurrentEpochId(Promotion memory _promotion) internal view returns (uint256) { // elapsedTimestamp / epochDurationTimestamp return (block.timestamp - _promotion.startTimestamp) / _promotion.epochDuration; }
If block.timestamp < _promotion.startTimestamp, it will revert due to underflow.
A promotion cannot be canceled before it started.
check in _getRemainingRewards if the promotion started yet, if it didn't then return the entire amount.
#0 - PierrickGT
2021-12-13T17:53:51Z
🌟 Selected for report: certora
280.3604 USDC - $280.36
certora
getRewardsAmount gets epochs ids as uint256[]. However, it should be uint8[].
In _calculateRewardAmount, the epoch start time and end time are calculated:
uint256 _epochStartTimestamp = _promotion.startTimestamp + (_epochDuration * _epochId); uint256 _epochEndTimestamp = _epochStartTimestamp + _epochDuration;
and then are casted to uint64 for the rest of the function. if it's greater than 2**64, it will be truncated.
getRewardsAmount
might return wrong result
manual review
get _epochIds as uint8[] instead uint256[]
#0 - PierrickGT
2021-12-13T16:37:15Z
Will be fixed with this issue: https://github.com/code-423n4/2021-12-pooltogether-findings/issues/3
🌟 Selected for report: certora
280.3604 USDC - $280.36
certora
the comment of _requirePromotionActive is Determine if a promotion is active. However, it doesn't check whether the promotion started. Therefore, if the promotion didn't start yet, it will not revert.
extendPromotion can be called even if the promotion is not active (if it didn't start yet)
check whether the promotion started in _requirePromotionActive
#0 - PierrickGT
2021-12-13T17:52:19Z
Yes, we could do a better job at naming this function.
That being said, considering that a promotion is active between the moment it is created and the end of the promotion, won't have any undesirable impact, since we should be able to cancel or extend a promotion before it has even started.
For this reason, I've acknowledged the issue but we won't make any changes to the _requirePromotionActive
function.
🌟 Selected for report: sirhashalot
Also found by: certora
44.9501 USDC - $44.95
certora
there are unsafe casts from uint256 to uint64 in _calculateRewardAmount
use safe cast.
#0 - PierrickGT
2021-12-13T17:57:26Z
certora
getCurrentEpochId might behave unexpectedly. getCurrentEpochId calls _getCurrentEpochId:
function _getCurrentEpochId(Promotion memory _promotion) internal view returns (uint256) { // elapsedTimestamp / epochDurationTimestamp return (block.timestamp - _promotion.startTimestamp) / _promotion.epochDuration; }
If the promotion is over, it'll return an epoch that doesn't exist in the promotion.
any external call to getCurrentEpochId will behave unexpectedly if the promotion is over.
revert if the promotion is over.
#0 - PierrickGT
2021-12-13T17:56:05Z