EIP-7410: Decrease Allowance By Spender


This extension adds a update allowance mechanism to ERC-20 allowances, in which a spender can revoke or decrease a given allowance by a specific address. This EIP extends EIP-20.


Currently, ERC-20 tokens offer allowances, enabling token owners to authorize spenders to use a designated amount of tokens on their behalf. However, the process of decreasing an allowance is limited to the owner’s side, which can be problematic if the token owner is a treasury wallet or a multi-signature wallet that has granted an excessive allowance to a spender. In such cases, reducing the allowance from the owner’s perspective can be time-consuming and challenging.

To address this issue and enhance security measures, this EIP proposes allowing spenders to decrease or revoke the granted allowance from their end. This feature provides an additional layer of security in the event of a potential hack in the future. It also eliminates the need for a consensus or complex procedures to decrease the allowance from the token owner’s side.

Interface implementation

pragma solidity ^0.8.0;

 * @title ERC-20 Update Allowance By Spender Extension
 * Note: the ERC-165 identifier for this interface is 0x2d474b5c
interface IERC20ApproveBySpender is IERC20 {

     * @notice Updates any allowance by `owner` address for caller.
     * Emits an {IERC20-Approval} event.
     * Requirements:
     * - `owner` cannot be the caller.
     * - `amount` should be less than or equal to current allowance of `owner` for caller.
    function approveBySpender(address owner, uint256 amount) external;


The approveBySpender(address owner, uint256 amount) function MUST be either public or external.

The Approval event MUST be emitted when approveBySpender is called.

The supportsInterface method MUST return true when called with 0x2d474b5c.


The name “EIP-20 Approval By Spender Extension” was chosen because it is a succinct description of this EIP. Spenders can decrease or revoke their allowance by amount from owners.

By having a way to approve and revoke in a manner similar to EIP-20, the trust level can be more directly managed by spender:

  • Using the approveBySpender function, spenders can revoke or decrease their allowance to spend an amount.

The EIP-20 name patterns were used due to similarities with EIP-20 approvals.

Backwards Compatibility

This standard is compatible with EIP-20.


if I have allowance couldnt I just transferfrom(from, from, amount)?

1 Like

Yes, but in that case the from should have amount in his balance. amount can be greater than owner balance.


I understand the use case.

Yet, I am not in favour of this form.

The ERC 20 approve of the absolute value was a mistake resulting in losses.

The suggested workaround is to first set allowance to 0, then to new value , or by having extension providing increaseAllowance / decreaseAllowance - i.e. working with deltas.

I suggest this ERC would be changed to decreaseAllowanceBySpender(owner, amount), where whatever amount larger than current allowance would effectively revoke allowance. This would be reflected also for amount = type(uint256).max which would nullify commonly used unlimited approval when set to max uint.

“Decrease” allowance in the EIP name would also make it semantically clear that this function cannot set allowance arbitrarily ( as could be understood using “Update” word.


I agree. This improve clarity for the name.

This has another impact - you are effectively doing transfer and emitting Transfer event.
This might not be desired by the use case.


thanks for the update.

Additionally, Is this validation really required?

 * Requirements:
 * - `owner` cannot be the caller.

ERC20 standard does not have such limitation. So no validation code is required.

1 Like

I would reflect my above mentioned points replacing this

* - `subtractedValue` should be less than or equal to current allowance of `owner` for caller.


* - when `subtractedValue` is equal or higher than current allowance of spender the new allowance is set to 0.
* Nullification also MUST be reflected for current allowance being type(uint256).max.
1 Like

Thanks for your feedback again, updated.