■ Description

Some tokens (e.g. USDTKNC) do not allow approving an amount M > 0 when an existing amount N > 0 is already approved. This is to protect from an ERC20 attack vector described here.

■ Example

  1. Tom approve 100 USDT for Tomy approve(Tomy, 100)
  2. Tom approve 150 USDT for Tomy approve(Tomy, 150) Failed!!!
function approve(address usr, uint wad) override public returns (bool) {
    require(allowance[msg.sender][usr] == 0, "unsafe-approve");
    return super.approve(usr, wad);
}

■ How to protect against this attack?

If the protocol executing the approve function for arbitrary ERC20 token, you should check the token address.

Uniswap approve function to transfer token. At that time, this bug happened!

■ Resources

https://github.com/Uniswap/v2-periphery/pull/26#issuecomment-647543138