sherlock-audit / 2023-09-Gitcoin-judging

11 stars 7 forks source link

AsenXDeth - Allo.sol#_fundPool #849

Closed sherlock-admin2 closed 11 months ago

sherlock-admin2 commented 12 months ago

AsenXDeth

medium

Allo.sol#_fundPool

The amount with which a user funds the pool is not calculated correctly when using fee-on-transfer tokens. According to the contest details they are in scope.

Vulnerability Detail

Let's see the code of the _fundPool function:

    function _fundPool(uint256 _amount, uint256 _poolId, IStrategy _strategy) internal {
        uint256 feeAmount;
        uint256 amountAfterFee = _amount;

        Pool storage pool = pools[_poolId];
        address _token = pool.token;

        if (percentFee > 0) {
            feeAmount = (_amount * percentFee) / getFeeDenominator();
            amountAfterFee -= feeAmount;

            _transferAmountFrom(_token, TransferData({from: msg.sender, to: treasury, amount: feeAmount}));
        }

        _transferAmountFrom(_token, TransferData({from: msg.sender, to: address(_strategy), amount: amountAfterFee}));
        _strategy.increasePoolAmount(amountAfterFee);

        emit PoolFunded(_poolId, amountAfterFee, feeAmount);
    }

As you can see we're increasing the balance of the pool here:

_strategy.increasePoolAmount(amountAfterFee);

However, the balance won't be increased with the right amount as after the transfer, a fee will be charged if using fee-on-transfer tokens.

Impact

The internal accounting of the pool will be wrong leading to accounting issues when withdrawing, adding funds, etc. Potentially leading to someone not being able to receive all of the funds they have on paper.

Code Snippet

https://github.com/allo-protocol/allo-v2/blob/main/contracts/core/Allo.sol#L502

Tool used

Manual Review

Recommendation

Calculate the balance before and after the transfer to see the exact amount of tokens that were transferred:

        uint256 balanceBefore = _token.balanceOf(address(_strategy));
        _transferAmountFrom(_token, TransferData({from: msg.sender, to: address(_strategy), amount: amountAfterFee}));
        uint256 amountToAdd = _token.balanceOf(address(_strategy)); - balanceBefore;
        _strategy.increasePoolAmount(amountToAdd);

Duplicate of #19