ERC-8255: Expiring Token Approvals

Discussion topic for EIP-8255

Update Log

  • 2026-05-06: initial draft

External Reviews

None as of 2026-05-06.

Outstanding Issues

None as of 2026-05-06.

1 Like

so a couple of quick thoughts after reading through the EIP:

  • The intention of the EIP is good and improves the current state. Approvals have always been a bug and not a feature (I’ve said this multiple times in the past, e.g. here). It’s too late now to fix this via a new token standard so we need to patch it.
  • We should never forget that people are retarded. I don’t say this lightly but having led SEAL 911 for 3 years now I can already see how projects will optimise for less friction. They will do something like uint32 public immutable maxApprovalDuration = type(uint32).max; _or_ if they use an underlying token with an maxApprovalDuration value they dislike, that will rewrap it into a new version.
  • The temporary approval proposal is security-wise probably better but even harder to get adoption ERC-7674: Temporary Approval Extension for ERC-20. Maybe we can merge that ERC with the this proposal?
  • Token-level patching is hard in practice. Even thought in theory the proposal is worth implementing, the projects will need to own it and historically this has been one of the biggest challenges.
  • If the industry adopted partial approvals alone, we could already eliminate a huge amount of risk without changing anything at the token level.
1 Like

Hi @moodysalem! thanks for putting this together.

I agree dormant approvals are a real problem worth solving at the token layer, and the spec captures the intent cleanly. Some thoughts:

Patching deployed tokens is hard. Agree with @pcaversaccio, USDT famously doesn’t ship permit, and the broader population of pre-2020 tokens that carry the largest dormant-approval risk will likewise never redeploy to add ERC-8255. The cohort that benefits is new tokens, though, they already have Permit, ERC-3009, and ERC-7674 to draw from.

Permit hasn’t curbed leftover allowances in practice. Its deadline bounds signature validity, not allowance lifetime, and dApps still optimize for less friction by requesting type(uint256).max. So a token-level mechanism that piggybacks on permit semantics inherits the same UX issues that brought us here.

ERC-7674 isn’t a complete substitute either. It only works inside a single transaction, which means the user has to batch (smart account / EIP-7702) or the spender has to be a router that pulls atomically. (And once you have batching, atomic approve + call + approve(0) is already on the table)

In every case the value lands at the user through some sort of interface, so the question is which shape integrates most cleanly. My read is that ERC-8255 is most useful as an additive extension: keep approve / permit semantics untouched, and offer approveForDuration (with allowanceAndExpiration) as the explicit expiring-allowance API. Wallets and apps that integrate it get the benefit; tokens and integrations that don’t aren’t silently changed. That also lowers the retrofit cost on already-deployed tokens, which I think is the practical adoption blocker for the current shape.

Would you consider scoping the spec to approveForDuration and dropping the requirements on approve / permit? The rest of the document remains sound imo

That said, is there a way to consistently detect that a token supports approveForDuration? Might be worth discussing, given any UI integration must be aware.

1 Like

No! It’s critical to this EIP that the default behavior changes. Otherwise we are left with exactly the status quo, which is that wallets and apps and smart contracts never adopt {batch approve+spend, temporary approve, or permit} which all are better than a separate approve transaction. Even Aave’s interface still does not use EIP-5792 for approve+supply.

Hi Moody - the expiring-approvals work here is relevant prior art for an envelope shape we’ve been drafting. PreparedTransaction is an off-chain envelope at the seam between producers (relayers, intent solvers, AI agents) and signing flows. The evm-batch kind aligns 1:1 with EIP-5792’s calls[] / atomicRequired / status codes, which is your standard.

We carry an envelope-level validity.notAfter field as a generalization of approval-only expiry - the Drift dormant-tx pattern motivated it. Curious whether that reads as a clean generalization or whether ERC-8255’s per-approval semantics should stay narrower. Draft + reference impl: txKit ERC v0.1 draft for community review - PreparedTransaction Envelope (pre-Magicians) Ā· GitHub .

Planning Magicians post Tue/Wed next week. Feedback before then would be very welcome if you have 10 min.

I think this ERC is a positive direction. The main concern I have is that changing the default approval behavior would make adoption too difficult, so I agree with @ernestognw, I’d consider changing ERC-8255 to be an additive extension.

Right now, ERC-8255 changes regular ERC20 approve() calls (that don’t specify a duration) to use maxApprovalDuration() as the default duration.

But consider code like this: metamorpho/src/MetaMorpho.sol at 15b44de99f28be53ab68c0783d4c6a530d718b81 Ā· morpho-org/metamorpho Ā· GitHub. There are a lot of protocols like this, where the contract max approves another protocol contract once in the constructor/initializer, and assumes the approval will remain valid indefinitely. This pattern would stop working if the approval expires. So these protocols would need to change their code, and immutable protocols that already have this behavior couldn’t support ERC-8255 tokens even if they wanted to.

This could maybe be addressed by making the default duration depend on whether msg.sender is an EOA or a contract, with contract-originated approvals remaining permanent by default. But this could have edge cases, for example during a contract’s constructor it will look like an EOA, and also smart accounts blur the EOA/contract distinction. IMO the most practical path for adoption is to leave standard approve() unchanged, even if it’s less ideal for fixing the status quo.

I agree that immutable contracts which approve once and assume the allowance remains live are the hardest case to handle.

I’ve updated the draft to add an explicit legacy-compatible spender mechanism. The default remains duration-limited, but a token implementation may designate specific spenders as legacy-compatible. For those spenders, allowanceAndExpiration(owner, spender) may return the current block.timestamp instead of the stored expiration, and allowance / transferFrom may treat the allowance as unexpired while the spender remains designated. Returning the current timestamp avoids introducing a fake far-future expiration that might fail validation rules.

The designation interface is intentionally not standardized. Implementations can make it token-admin controlled, spender self-controlled, or both. That means existing immutable integrations can be enabled by the token administrator, while integrations that know they need legacy behavior can opt themselves in if the token supports spender-controlled designation. Spenders are not legacy-compatible by default, so new integrations get the duration-limited behavior unless explicitly opted into the legacy path.

This does not make ERC-8255 purely additive, but it gives token implementations an adoption affordance: at worst, selected spenders can regress to current ERC-20 approval risk, while the default behavior for everyone else remains bounded approvals.

The edit to the text is here: Update ERC-8255: erc-8255 updates for legacy compatibility by moodysalem Ā· Pull Request #1758 Ā· ethereum/ERCs Ā· GitHub

1 Like