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);
}
Due to this quirk, there's an edge case we aren't currently covering. If a user does the approve tx and then following transfer tx isn't successful, the lingering approval amount can cause problems (unless the user retries the transfer with the exact same amount right away, in which case the previous approval will get used).
From USDT's contract code in etherscan:
Due to this quirk, there's an edge case we aren't currently covering. If a user does the approve tx and then following transfer tx isn't successful, the lingering approval amount can cause problems (unless the user retries the transfer with the exact same amount right away, in which case the previous approval will get used).