Use safeTransferFrom success but use transferFrom failed

When I transfer USDT (ERC20) in the test environment, the code is copy from mainnet,contract address: 0xdAC17F958D2ee523a2206206994597C13D831ec7. the solidity version of USDT is 0.4.17.

I started by using the transferFrom method of IERC20,like this:

IERC20(applyToken).transferFrom(
            msg.sender,
            multiSign,
            totalCost
        );

but I got error,but no specific error content is displayed.

then I update the code,use SafeERC20 library,like this:

using SafeERC20 for IERC20;
IERC20(applyToken).safeTransferFrom(
            msg.sender,
            multiSign,
            totalCost
        );

this way I get the correct execution.
after that I add a new ERC20 contract like this:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract MyToken is ERC20, Ownable {
    constructor() ERC20("MyToken", "MTK") {}

    function mint(address to, uint256 amount) public onlyOwner {
        _mint(to, amount);
    }
}

I Using this new contract, I re-verified the two transfer methods and found that they were all successful.

Can anyone tell me what is willing to cause this problem, thanks a lot!

@abcoathup can you help me,thanks!

Hi, welcome to the community! :wave:

I think USDT is not a standard ERC20 token, it does not have returning value for transferFrom(), so I think you can not use the standard ERC20 interface, so you can use safeTransferFrom() as above or you can use another interface, such as:

interface non_standard_IERC20 {
  function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external ;
}

Then:

non_standard_IERC20(USDT).transferFrom(
   msg.sender,
   multiSign,
  totalCost
);
2 Likes

Why is the safeTransferFrom method successful? Isn't it also calling transferFrom?

There's a useful answer which refers to this issue at https://ethereum.stackexchange.com/a/78376.

Just read through the code example which appears below the 'UPDATE' title.

The bottom line in that answer:

  • If you execute a function which returns nothing using an interface of it which returns bool, then the transaction reverts
  • If you execute a function which returns bool using an interface of it which returns nothing, then the transaction completes
2 Likes