I have a function that uses the ERC20 transfer function to send an ERC20 token from a smart contract to another wallet address.

function withdrawTokens(address _tokenContract, uint256 _amount) external onlyOwner {
    IERC20 tokenContract = IERC20(_tokenContract);
    tokenContract.transfer(_wallet, _amount);
    emit FundsWithdrawn(_wallet, _amount);

For some reason this is not working for sending Tether USDT (0xdac17f958d2ee523a2206206994597c13d831ec7) out of the contract, but it does work for sending USDC. Is Tether non ERC-20 compliant? How do I implement this function to work for USDT?

1 Answer 1


No USDT is a black sheep amongst ERC20 tokens. Not only does it have only 6 decimals, but it also has special transfer and approve functions.

Firstly transfer function does not return any boolean if successful or not. That is why you should always use safeTransfer instead of checking the return status.

// Forward ERC20 methods to upgraded contract if this one is deprecated
function transfer(address _to, uint _value) public whenNotPaused {
    if (deprecated) {
        return UpgradedStandardToken(upgradedAddress).transferByLegacy(msg.sender, _to, _value);
    } else {
        return super.transfer(_to, _value);

Secondly, when setting approval, you should always first set it to 0 and then to desired amount otherwise it fails.

  • Thanks, shocking that they haven't upgraded Feb 8, 2023 at 18:30

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.