Explain the practical use of increaseAllowance and decreaseAllowance functions on ERC20

Hi,

I used the ERC20 implementation of openzeppelin contracts on my test token and I've found two functions which really confused me: increaseAllowance and decreaseAllowance

:1234: The Code

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public  virtual returns (bool) {
        _approve( _msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero" );
        unchecked {
            _approve(_msgSender(), spender, currentAllowance - subtractedValue);
        }
        return true;
    }

Someone please explain the practical utility of this function in a renounced contract.

Thanks.

Hi, for example, if Alice approves Bob to spend 100 token at first, but later, Alice would like to only approve Bob to spend 50 token, so Alice will send two transfer:

  • Alice approves Bob 100 token. (token.approve(Bob_Address, 100))
  • Alice approves Bob 50 token. (token.approve(Bob_Address, 50))

So if Bob finds these two transactions, he can make a transaction between these two transactions to spend more 100 token. That is:

  • Alice approves Bob 100 token. (token.approve(Bob_Address, 100))
  • Bob spends Alice 100 token. (token.transferFrom(Alice_Address, Bob_Address, 100))
  • Alice approves Bob 50 token. (token.approve(Bob_Address, 50))
  • Bob spends Alice 100 token. (token.transferFrom(Alice_Address, Bob_Address, 50))

So for Alice, she only wants to approve Bob 50 token actually, but Bob finally get 150 token, so the function increaseAllowance and decreaseAllowance come.

And for more details, I think you can have a look at the discuss at here: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729

In the general case of an ERC-20 token, the approvers are uniswap / pancake routers and they probably don't use these functions, right ?

They just approve a large number as allowance so the user could buy more and not have to allow the uniswap protocol after every buy.

Please correct if my understanding is wrong.

Yes, you are right. Just approve a large number

So, in general erc-20 / bep-20 tokens coming up on these exchanges, the increaseAllowance and decreaseAllowance functions are not used. :joy:

But I think the front-running protection concept using these functions still seem theoretical.

Emmmm, they can use increaseAllowance and decreaseAllowance, but some tokens can not increase form a non-zero value.
If user want to swap some USDT to get 1 Eth, assume 1 eth = 100 USDT, cause there will be slippage, so you are expect to approve a larger amount, maybe call increaseAllowance(110), but actually, you only spend 105 USDT to get 1 ETH, so now, the allowance becomes to 5, and then you want to do this again, so you call increaseAllowance(110) again, but for this time, it will fail, cause it can not approve form a non-zero value to another non-zero value, so for these tokens, if you still want to use increaseAllowance(), you need some extra logic. It will be more complex, so just approve max is convenient.
You can use increaseAllowance and decreaseAllowance, but need more logic to solve such situation.

Hope I have made myself clear.

1 Like