Hi @Skyge,
USDT approve doesn’t comply with the ERC20 standard.
I modified Test.sol to use SafeERC20 and this worked in Remix on a testnet (I haven’t tried on mainnet):
Test.sol
pragma solidity ^0.5.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.4.0/contracts/token/ERC20/IERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.4.0/contracts/token/ERC20/SafeERC20.sol";
contract Test {
using SafeERC20 for IERC20;
function tokenAllowAll(address asset, address allowee) public {
IERC20 token = IERC20(asset);
if (token.allowance(address(this), allowee) != uint256(-1)) {
token.safeApprove(allowee, uint256(-1));
}
}
}
ERC20 Verifier
I used https://erc20-verifier.openzeppelin.com/ to verify USDT and got the following report showing approve was non-standard:
Contract TetherToken
== ERC20 functions definition ==
[x] transfer (address, uint256) -> (bool)
[x] approve (address, uint256) -> (bool)
[x] transferFrom (address, address, uint256) -> (bool)
[✓] allowance (address, address) -> (uint256)
[✓] balanceOf (address) -> (uint256)
== Custom modifiers ==
[✓] No custom modifiers in ERC20 functions
== ERC20 events ==
[✓] Transfer (address, address, uint256)
[✓] Approval (address, address, uint256)
== ERC20 getters ==
[✓] totalSupply () -> (uint256)
[x] decimals () -> (uint8)
[✓] symbol () -> (string)
[✓] name () -> (string)
== Allowance frontrunning mitigation ==
[x] increaseAllowance (address, uint256) -> (bool)
[x] decreaseAllowance (address, uint256) -> (bool)
== Balance check in approve function ==
[✓] approve function should not check for sender's balance
USDT
https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7#code
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
* @param _spender The address which will spend the funds.
* @param _value The amount of tokens to be spent.
*/
function approve(address _spender, uint _value) public onlyPayloadSize(2 * 32) {
// To change the approve amount you first have to reduce the addresses`
// allowance to zero by calling `approve(_spender, 0)` if it is not
// already 0 to mitigate the race condition described here:
// https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
require(!((_value != 0) && (allowed[msg.sender][_spender] != 0)));
allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
}