Lucene search

K
code423n4Code4renaCODE423N4:2021-12-POOLTOGETHER-FINDINGS-ISSUES-99
HistoryDec 12, 2021 - 12:00 a.m.

Tokens with fee on transfer are not supported

2021-12-1200:00:00
Code4rena
github.com
5

Handle

WatchPug

Vulnerability details

There are ERC20 tokens that charge fee for every transfer() or transferFrom().

In the current implementation, createPromotion() assumes that the received amount is the same as the transfer amount, and uses it to calculate reward amounts.

As a result, in claimRewards(), later users may not be able to successfully claim their rewards, as it may revert at L186 for insufficient balance.

<https://github.com/pooltogether/v4-periphery/blob/0e94c54774a6fce29daf9cb23353208f80de63eb/contracts/TwabRewards.sol#L88-L116&gt;

function createPromotion(
    address _ticket,
    IERC20 _token,
    uint216 _tokensPerEpoch,
    uint32 _startTimestamp,
    uint32 _epochDuration,
    uint8 _numberOfEpochs
) external override returns (uint256) {
    _requireTicket(_ticket);

    uint256 _nextPromotionId = _latestPromotionId + 1;
    _latestPromotionId = _nextPromotionId;

    _promotions[_nextPromotionId] = Promotion(
        msg.sender,
        _ticket,
        _token,
        _tokensPerEpoch,
        _startTimestamp,
        _epochDuration,
        _numberOfEpochs
    );

    _token.safeTransferFrom(msg.sender, address(this), _tokensPerEpoch * _numberOfEpochs);

    emit PromotionCreated(_nextPromotionId);

    return _nextPromotionId;
}

<https://github.com/pooltogether/v4-periphery/blob/0e94c54774a6fce29daf9cb23353208f80de63eb/contracts/TwabRewards.sol#L162-L191&gt;

function claimRewards(
    address _user,
    uint256 _promotionId,
    uint256[] calldata _epochIds
) external override returns (uint256) {
    Promotion memory _promotion = _getPromotion(_promotionId);

    uint256 _rewardsAmount;
    uint256 _userClaimedEpochs = _claimedEpochs[_promotionId][_user];

    for (uint256 index = 0; index &lt; _epochIds.length; index++) {
        uint256 _epochId = _epochIds[index];

        require(
            !_isClaimedEpoch(_userClaimedEpochs, _epochId),
            "TwabRewards/rewards-already-claimed"
        );

        _rewardsAmount += _calculateRewardAmount(_user, _promotion, _epochId);
        _userClaimedEpochs = _updateClaimedEpoch(_userClaimedEpochs, _epochId);
    }

    _claimedEpochs[_promotionId][_user] = _userClaimedEpochs;

    _promotion.token.safeTransfer(_user, _rewardsAmount);

    emit RewardsClaimed(_promotionId, _epochIds, _user, _rewardsAmount);

    return _rewardsAmount;
}

Recommendation

Consider comparing before and after balance to get the actual transferred amount.


The text was updated successfully, but these errors were encountered:

All reactions