sherlock-audit / 2023-09-Gitcoin-judging

11 stars 7 forks source link

alexzoid - Fee-on-Transfer Tokens Issue in `_fundPool()` #841

Closed sherlock-admin2 closed 11 months ago

sherlock-admin2 commented 12 months ago

alexzoid

medium

Fee-on-Transfer Tokens Issue in _fundPool()

The _fundPool() method within the provided smart contract does not correctly support fee-on-transfer tokens. When such tokens are used, the _strategy.increasePoolAmount() method can potentially receive an inaccurate value due to the fee deductions inherent in the token transfer itself, leading to discrepancies in pool funding.

Vulnerability Detail

Fee-on-transfer tokens automatically deduct a fee on every transfer. The issue arises when the _fundPool() method tries to fund a pool with such a token. The logic calculates and deducts the feeAmount and then transfers the amountAfterFee to the strategy. However, since the token itself deducts a fee on transfer, the actual amount received by the strategy might be less than amountAfterFee. This discrepancy is not accounted for, and as a result, _strategy.increasePoolAmount() is called with a potentially incorrect value.

Impact

This can lead to significant discrepancies in the recorded and actual amounts within the strategy.

Code Snippet

https://github.com/sherlock-audit/2023-09-Gitcoin/blob/main/allo-v2/contracts/core/Allo.sol#L502-L520

Tool used

Manual review

Recommendation

To fix this issue:

  1. Before the transfer, check the balance of the strategy.
  2. After the transfer, check the balance again to get the actual transferred amount.
  3. Use the actual transferred amount in the _strategy.increasePoolAmount() method. Here's the adjusted snippet:
    
    uint256 strategyBalanceBefore = IERC20(_token).balanceOf(address(_strategy));

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

uint256 strategyBalanceAfter = IERC20(_token).balanceOf(address(_strategy)); uint256 actualTransferredAmount = strategyBalanceAfter - strategyBalanceBefore;

_strategy.increasePoolAmount(actualTransferredAmount);



Duplicate of #19