'Getting TransferHelper: TRANSFER_FROM_FAILED from TransferHelper.sol. Why?

I'm new to solidity. I'm currently getting the following error TransferHelper: TRANSFER_FROM_FAILED from the safeTransferFrom function. Can someone tell me why?

What is this line doing?

 (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(0x23b872dd, from, to, value)
        );

Here's the entire contract:

// SPDX-License-Identifier: MIT

pragma solidity 0.8.7;

/**
 * @dev A helper methods for interacting with ERC20 tokens and
    sending ETH that do not consistently return true/false.
 */
library TransferHelper {
    function safeApprove(
        address token,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('approve(address,uint256)')));
        (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(0x095ea7b3, to, value)
        );
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            "TransferHelper: APPROVE_FAILED"
        );
    }

    function safeTransfer(
        address token,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('transfer(address,uint256)')));
        (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(0xa9059cbb, to, value)
        );
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            "TransferHelper: TRANSFER_FAILED"
        );
    }

    function safeTransferFrom(
        address token,
        address from,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
        (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(0x23b872dd, from, to, value)
        );
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            "TransferHelper: TRANSFER_FROM_FAILED"
        );
    }

    function safeTransferETH(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, "TransferHelper: ETH_TRANSFER_FAILED");
    }
}



Solution 1:[1]

Just a note, TransferHelper is the prewritten library, and we shouldn't touch into it. What you should do is see the message like: Transfer From Failed or approved fail and check our ERC20 token code as well as the data submit whether it's valid or not.


1st question:

This problem usually happens when your ERC20 token can't be transfer. There're several reason for this: un-approval, not enough balance...


2nd question:

abi.encodeWithSelector(0x23b872dd, from, to, value)

This function returns a selector (think of is as a function ref) to the transfer(...) of your ERC20 token. And this is called by token.call( a kind of reflection.

Solution 2:[2]

This error is for the following reasons:

  • if the token has fees on transfer remember to be correctly calling the exchange function that supports transfer fees: https://docs.uniswap.org/protocol/V2/reference/smart-contracts/router-02

  • note that the token submissions permission is sufficient in the token contract. The same happens with the manipulation of WETH it is necessary to give the necessary permissions in the contract.

If this answer helped you, please choose the correct one.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 PySoL
Solution 2 Gamer Noob