nachomazzara / SafeERC20

Library to standardize ERC20 methods calls
11 stars 3 forks source link

Support a way to clear approve first if token require it #1

Open nachomazzara opened 5 years ago

nachomazzara commented 5 years ago

Some ERC20 tokens as MANA require to clear the approval before setting a new value

/**
   * @dev Aprove 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, uint256 _value) returns (bool) {

    // 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);
    return true;
  }

The idea is to support this behaviour cleaning the approval first and the set it the new one

nachomazzara commented 5 years ago

Alternative:

function safeApprove(IERC20 _token, address _spender, uint256 _value) internal returns (bool) {
        uint256 prevAllowance = _token.allowance(address(this), _spender);

        if (prevAllowance > 0 && _value > 0) {
            // clear approve
            address(_token).call(
                abi.encodeWithSignature("approve(address,uint256)",_spender, 0)
            );
        }        

        address(_token).call(
            abi.encodeWithSignature("approve(address,uint256)",_spender, _value)
        );

        if (_token.allowance(address(this), _spender) != _value) {
            // Approve failed
            return false;
        }

        return true;
    }

We should update doc string