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
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.
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.
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.
Do I understand this correctly that if you have to use increaseAllowance, and then transfer that these are two separate transactions and user have to pay double fee?
I have my own smart contract and user send funds to my smart contract, but he needs to first pay fee for increaseAllowance and then another fee for transfer? This is really inconvenient... can this be solved another way?