Essay
ERC-8427: capped, revocable spending on Ethereum
ERC-8427 lets one signature authorize repeated spending of ETH and tokens under per-payment, rolling, and lifetime caps. Where it helps and why.
More software now needs to spend money on someone's behalf: an agent paying for services, an app collecting a recurring fee, an operations bot paying suppliers from a team account. The tools Ethereum offers for this are either too broad or too narrow. I have written a draft standard, ERC-8427: Portable Spend Grants, that gives account owners a better option, and I would like feedback from the people who would build on it.
The problem with approvals
The usual way to let someone else spend your tokens is an ERC-20 approve. In practice that is one token, often an unlimited amount, and no expiry. It says nothing about how much can go out per payment or per day, and it stays in place until you remember to remove it.
Some wallet permissions add recurring allowances that reset at a fixed boundary such as midnight UTC. A "100 per day" limit that resets at midnight lets someone spend 100 at 11:50 PM and another 100 at 12:10 AM. That is twice the limit in twenty minutes.
A delegate that needs ETH and two tokens means three separate permissions to sign and later revoke. And wallet permission APIs leave the meaning of a permission to each implementation, so two wallets can show the same hash and still disagree on how the window is counted or whether a second asset has its own limit. The owner also needs a way to cancel that does not depend on the delegate cooperating.
What a spend grant is
A spend grant is a signed statement from an account owner (the principal) to one address (the delegate). It says which assets the delegate may spend, and for each asset three limits: the most per payment, the most in a trailing window such as 24 hours, and the most over the grant's whole life. It also says who may be paid (one fixed address, or anyone) and the time range in which the grant is valid.
The owner signs it once as EIP-712 typed data. An immutable registry contract records what has been spent under each grant and which grants have been revoked; it never moves funds. A separate executor checks that the delegate authorized each payment, has the registry record it, and moves the funds from the owner's account in the same transaction. If either step fails, the whole transaction reverts. Existing tokens need no changes, zero never means unlimited, and the owner revokes by calling the registry directly.
What this makes possible
Every application below uses the same signed object. A wallet that learns to show one spend grant can show all of them, whatever app asked for it.
| Application | What is common today | What a spend grant changes |
|---|---|---|
| Agents that pay for things | Give the agent its own funded wallet, or an open-ended approval | The agent spends from your account, capped per payment, per window, and in total |
| Recurring payments to one payee | Allowances that reset at a calendar boundary | A true trailing window, locked to one recipient |
| Multi-asset budgets | One approval or permission per asset | Up to 16 assets in one grant, each with its own limits, and one revocation |
| Wallet display and review | Each wallet interprets permissions its own way | One canonical text form and JSON format that any tool can check |
| Smart accounts and EIP-7702 accounts | Permissions tied to one account setup | Grants that keep working when the account's setup changes |
Agents and automation that pay on your behalf
An agent or automated service needs to make many small payments without asking each time. Today the choice is usually between handing it a separate wallet with a budget in it, which moves the money out of your account and your reporting, or an approval that has no meaningful upper bound.
A spend grant makes it possible to leave the funds where they are and still bound the damage. If the agent's key is stolen, the most it can move is what is left in the current window, never more than the lifetime cap, and the owner can revoke without the agent's help.
Example. Say I want an agent to pay for data and API usage from my account for the next 90 days. I sign one grant naming the agent as delegate, with a stablecoin limited to 50 per payment, 200 in any 24 hours, and 2,000 in total. The agent asks the executor to pay a vendor. The executor confirms the request came from the agent, the registry checks the three limits and records the payment, and the stablecoin moves from my account to the vendor in the same transaction. I approve the executor for no more than the 2,000 the grant allows. If the agent tries to pay 60, or tries a fifth payment of 50 inside the same 24 hours, it fails. My wallet can show me how much the agent can spend right now and when more becomes available.
Recurring payments to a single payee
A subscription or retainer is a delegate who should be paid a bounded amount, repeatedly, and only to one address. Setting the recipient mode to a single address means the grant cannot pay anyone else, even if the delegate is compromised.
The trailing window matters here. A payment counts against the window for exactly the window length, then drops out, so there is no boundary to spend across twice. The lifetime cap never resets, so a twelve-month engagement can have a total that cannot be exceeded.
One budget across several assets
An operations wallet often needs native currency and one or more tokens. Today that means several approvals or permissions, each signed and revoked separately. A spend grant lists up to 16 assets, and each keeps its own remaining amounts. Spending one never draws down another.
The draft does not offer a shared budget across assets ("this much across A or B"), because that needs a price reference the standard does not define. The field is reserved so a later version can add it.
Wallets, auditors, and anyone reviewing terms
The draft defines an exact plain-text rendering of every grant and a strict JSON format for passing grants between tools. Any wallet or reviewer can compute a grant's hash and produce the same text as every other implementation, so a finance team or a second wallet can confirm what was signed without trusting the app that created it. After signing, the registry's views let a wallet show what can be spent now and when more frees up.
Smart accounts and EIP-7702 accounts
Contract accounts validate grants with ERC-1271. EIP-7702 accounts also accept a signature from their own key, so a grant keeps working if the owner later adopts, changes, or clears a 7702 delegation, instead of silently becoming invalid.
A common format for delegation frameworks
ERC-7710 standardizes how delegations are redeemed but leaves the permission itself opaque. A spend grant can be the concrete terms such a system carries, and an executor can accept authorization from a delegation framework it trusts. ERC-8427 does not depend on it.
A look at the interface
The signed object is two structs, taken from the ERC with one comment reworded:
struct AssetLimit {
address asset; // ERC-20, or NATIVE (ERC-7528) for this chain's native currency
uint256 maxPerCall; // one payment, raw units
uint256 maxPerWindow; // trailing window, raw units
uint256 maxTotal; // lifetime, never resets
}
struct SpendGrant {
address principal;
address delegate;
uint8 recipientMode; // 0 = one address, 1 = any
address recipient; // required nonzero if mode is 0; MUST be address(0) if mode is 1
uint8 assetCombine; // MUST be 0 (independent per-asset caps); other values reserved
uint64 windowSeconds; // trailing lookback; 86400 = 24 hours, not a UTC day
AssetLimit[] assets; // 1 to 16, unique, strictly ascending by uint160(asset)
uint64 validAfter; // inclusive unix seconds
uint64 validUntil; // exclusive unix seconds
uint256 salt;
}
On the registry, the owner calls revoke(grantHash) to cancel, wallets read usage, rollingUsage, and liveDebits to show what is left, and only the executor may call consume, the function that records a payment.
What to watch for
Anyone building on this should read the ERC's Security Considerations in full. The points I would stress:
- The token allowance is the real authority. For ERC-20s, the executor moves funds using the owner's allowance to it; the grant limits how it uses that allowance. Keep the allowance no higher than what outstanding grants can still spend.
- Choosing a registry is choosing an executor. Each registry has one fixed executor, and a faulty one could move funds without recording them. Wallets should show the executor before the owner signs.
- A grant is not a secret. It becomes public on first use, so the executor must check that the delegate authorized each payment. With recipient mode "any," an executor that skips this lets anyone who has seen the grant send the remaining budget to themselves.
- Revocation is final and has no admin. There is no pause. Until the owner revokes, the caps are what limit a stolen delegate.
- Some tokens do not behave. With fee-on-transfer or rebasing tokens, the recorded amount can differ from what left the account.
- The registry cannot be upgraded. A bug is permanent for that deployment, and a new registry means new signatures.
Where it stands
This is a draft, not a finished standard, and it is easier to change now than after wallets and executors implement it.
| Piece | Status |
|---|---|
| Specification | Draft; number 8427 assigned by the ERC editors; under review in ethereum/ERCs#2037 |
| Reference implementation | Solidity registry and executor with Foundry tests, a TypeScript package for hashing, rendering, and JSON, and golden test vectors; CC0; unaudited |
| Wallet display | A non-normative ERC-7730 descriptor so wallets can show a grant's terms clearly |
| Deployment | Registry and executor on Arc testnet; the repo says to deploy to testnets only |
One limit worth saying plainly: the reference executor only spends ERC-20 tokens. Spending native currency from the owner's account needs an account adapter, and the draft does not specify one.
How to weigh in
The most useful thing you can tell me is a real need. If you build wallets, agents, payment flows, or delegation frameworks and bounded spending is part of your product, I want to know whether this fits.
Discussion is on the Ethereum Magicians thread. I would especially like to hear:
- Wallet teams: what you would need to show a grant before signing and what is left afterward.
- Agent, app, and delegation framework builders: which assets, limits, and window lengths you would use, and whether this works as the terms your permissions carry.
- Everyone: what is missing, and what could be removed.
If you want to propose a change to the text or the reference code, fork the repository and open a pull request.
Related service: Web3 Advisory