3

I'm looking into Uniswap V2 code and found that it uses _safeTransfer function to transfer ERC20 tokens in the Pair contract.

    function _safeTransfer(address token, address to, uint value) private {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'UniswapV2: TRANSFER_FAILED');
    }
...

    function burn(address to) external lock returns (uint amount0, uint amount1) {
        ...
        _safeTransfer(_token0, to, amount0);
        ...
    }

Why doesn't it simply call IERC20(_token).transfer(to, amount0) ?

1 Answer 1

6

Because the ERC20 standard kinda sucks, and is unclear about how you should handle non-succeeding token transfers, both reverting and just returning false are technically allowed, so this takes both cases into account

(bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value));
        // Case where there is no return data      case where there is return data
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'UniswapV2: TRANSFER_FAILED');
  • if success is false, the call to the token contract reverted, and we revert the whole transaction,
  • if success is true and there is no return data, the token contract doesnt return anything on transfer and the transfer succeeded (this is technically non compliant with the ERC20 standard, but USDT infamously does that, which is a pain)
  • if success is true but there is return data, we check if it's a bool (if it's not the contract we called isnt compliant with the ERC20 standard and we revert)
    • if that bool is false the transfer didnt complete and we revert
    • if it's true, the transfer completed normally
2
  • Thank you, this is super helpful! Is executing bool code = IERC20(_token).transfer(to, amount0) and require(code) equivalent to _safeTransfer?
    – ywat
    Oct 21, 2022 at 0:43
  • 2
    No, because that would break in the case where the token's transfer function doesn't return a bool (case 2 in my list)
    – Foxxxey
    Oct 21, 2022 at 1:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.