Frame Transactions Through a Statelessness Lens

How AA and EIP-8141 mempool strategies interact with stateless nodes in a post-ZKEVM world

The post-ZKEVM baseline

ZKEVMs replace re-execution with proof verification. Once a SNARK proof can validate a block in milliseconds, nodes no longer need full state to participate in consensus. The requirement that made every full node hold ~280 GB of state — re-execution — disappears. What remains is economic: builders, RPC providers, and searchers hold state because their business depends on it. Everyone else can stop.

The expected response is partial statefulness: nodes hold the full account trie (every account’s nonce, balance, codeHash, and storageRoot) plus selective storage for contracts they choose to track. A node serving a DeFi protocol tracks that protocol’s storage. A node focused on censorship resistance tracks nothing beyond accounts. This minimum — Validity-Only Partial Statelessness (VOPS) — costs roughly 10 GB for ~400M accounts. Partial statefulness (PS) sits above VOPS: same full account trie, plus full storage tries for selected contracts, following the chain tip via Block Access Lists (EIP-7928) instead of re-execution. See the EthCC 2026 presentation for a deeper treatment.

Why does this matter for transaction formats? Because mempool health is censorship resistance. A node that can validate transactions locally can maintain a mempool, propagate transactions to peers, and participate in FOCIL inclusion lists (EIP-7805). A node that cannot validate a transaction type cannot include it in an inclusion list, cannot enforce its inclusion, and censorship resistance for that class of transactions degrades silently. The fewer nodes that can validate, the easier it is to censor. In a post-ZKEVM world where most nodes are partially stateful, any new transaction format must be evaluated against this reality.

What frame transaction validation requires

Today, validating a transaction in the mempool is cheap. For legacy and EIP-1559 transactions, a node runs ecrecover on the signature to derive the sender, checks the sender’s nonce, and verifies the sender’s balance covers the transaction cost. This is pure computation plus a single account lookup. Any node with the account trie — including VOPS and PS nodes — can do this.

Frame transactions (EIP-8141) change this fundamentally. A frame transaction has no cryptographic signature in the traditional sense. Instead, the transaction declares its sender explicitly and breaks execution into ordered frames. One of these frames has mode VERIFY: it executes the sender’s account code, which must call the APPROVE opcode to authorize the transaction. The validation logic is arbitrary — it can implement any signature scheme (post-quantum, multisig, social recovery) by reading the sender’s storage and executing whatever verification logic the account code defines.

This means the validating node needs the sender’s bytecode and storage slots accessed during verification — not just the two fields (nonce, balance) in their account leaf. And the sender is a smart contract wallet: it could be any account on the network. Validation shifts from “look up two fields” to “execute arbitrary code against arbitrary account state.”

Figure: Legacy transaction validation requires only an account trie lookup (~3,000 gas, all node types). Frame transaction validation requires executing a VERIFY frame against the sender’s bytecode and storage (up to ~100k gas, only nodes with the relevant state).

The mempool strategies and what they assume

The mempool strategies document for EIP-8141 proposes three progressively more ambitious policies for which frame transactions the public mempool will accept. Each trades off permissionlessness against DoS protection. What matters here is what state each strategy requires from the validating node.

Strategy 1 (Self-Relay Only) accepts only self-funded frame transactions. Storage reads during VERIFY are restricted to tx.sender’s slots, and one pending frame transaction per sender is allowed. But “the sender’s code and storage” deserves careful unpacking — the actual state footprint depends on what kind of account the sender is.

Any account can send a frame transaction. The EIP specifies three validation paths:

  • Plain EOA (no code, no delegation). EIP-8141 defines “default code” that handles VERIFY by checking an ECDSA (secp256k1) or P256 signature against the sender’s address and calling APPROVE. No storage reads, no custom bytecode. This is as cheap to validate as a legacy transaction — any node with the account trie (including VOPS) can do it.

  • Contract account. The sender’s own deployed code runs during VERIFY, reading the sender’s own storage. Straightforward — the node needs the sender’s code and storage.

  • 7702-delegated EOA — the interesting case for AA. The account’s code field is a 23-byte delegation prefix (0xef0100 || delegate_address). When the EVM encounters this during the VERIFY frame, it follows the pointer and loads the delegate contract’s bytecode — but executes it in the sender’s context. address(this) returns the sender’s address. SLOAD reads the sender’s storage trie, not the delegate’s. This is semantically identical to how proxy contracts work: the delegate’s compiled storage layout (slot 0 = owner, slot 1 = nonce, etc.) is interpreted against the sender’s raw key-value storage. The delegate’s own storage is never touched.

The 7702-delegated case raises an immediate question: where does an EOA’s storage come from? EOAs traditionally have empty storage tries. The answer: once an EOA delegates via a SetCode transaction, subsequent transactions execute the delegated code in the EOA’s context — and SSTORE writes go to the EOA’s storage trie. The first interaction typically initializes key slots (owner address, guardian, nonce). From that point on, the EOA carries a real storage trie under its address in the state, structurally identical to a contract’s. The EIP provides no special initialization mechanism; it is left to the wallet implementation (e.g., a self-initializing pattern on first use, or a separate setup transaction).

Two further constraints shape the state access. First, the EIP-8141 rule “SLOAD restricted to tx.sender storage” is not redundant with 7702 — it constrains transitive calls. If the delegated code calls a helper library via CALL, that helper enters its own execution context where SLOAD would normally read the helper’s storage. The EIP-8141 rule forbids this: helpers reached via CALL can only perform pure computation (signature math, hashing, precompile calls). If the delegated code uses DELEGATECALL instead, the execution context stays the sender’s — SLOAD still reads the sender’s storage, which is permitted. Second, calling other 7702-delegated accounts during VERIFY is explicitly banned — their delegation targets are mutable, so one SetCode transaction could invalidate every pending frame transaction that depends on that account’s current behavior.

So the actual state footprint for Strategy 1 depends on the sender type:

Plain EOA (default code):

  • tx.sender’s account leaf (nonce, balance) — from the account trie

  • Nothing else. Signature verification is pure computation.

7702-delegated EOA (the common AA case):

  • tx.sender’s account leaf — nonce, balance, and the 23-byte delegation prefix

  • The delegate contract’s bytecode — the actual VERIFY logic, at a different address

  • tx.sender’s storage slots — read by the delegate code via SLOAD, resolved against the sender’s (EOA’s) storage trie

  • Helper library bytecodes — non-delegated, already-deployed contracts called for pure computation

Storage is bounded to one account. Bytecodes may span 2-3 contracts. No shared state across different senders.

Figure: State access pattern for Strategy 1 VERIFY execution. Storage reads (green arrows) always resolve to tx.sender’s trie, regardless of which code is executing. The delegate’s and helper’s storage tries are never accessed.


Strategy 2 (Canonical Paymaster) adds sponsored transactions through a standardized canonical paymaster contract. Where Strategy 1 uses self_verify (the sender calls APPROVE(0x3) to approve both execution and payment in one frame), Strategy 2 splits this into two frames via the only_verify → pay sequence.

The EIP-8141 APPROVE opcode takes a scope parameter that separates sender approval from payer approval. In Strategy 2’s sponsored flow, the only_verify frame targets tx.sender — the sender’s code runs (same 7702-delegation pattern as Strategy 1) and calls APPROVE to authorize execution without committing to pay. Then the pay frame targets the canonical paymaster contract — the paymaster’s code runs, checks its deposit balance, and calls APPROVE to authorize payment on the sender’s behalf.

The canonical paymaster is recognized by exact runtime code hash — nodes compare the deployed bytecode against a known hash. This is a mempool policy, not a consensus rule: transactions using non-canonical paymasters can still be included in blocks via private builder channels, they just cannot propagate through the public mempool. Anyone can deploy an instance of the canonical paymaster. Multiple instances can coexist, each with independent storage (its own deposit pool, withdrawal timestamps). The set of recognized bytecodes is also not permanently fixed — the EIP authors expect to add additional canonical paymasters over time (e.g., PQ-safe variants).

The paymaster’s safety relies on two structural constraints. First, delayed withdrawal: funds deposited into a canonical paymaster instance can only leave through gas payment or a time-locked withdrawal. A paymaster cannot deposit ETH, sponsor 1000 transactions, then instantly withdraw — the time lock prevents this mass-invalidation attack. Second, node-side pending balance tracking: nodes compute effective_balance = deposited - pending_gas_commitments per paymaster instance, where pending_gas_commitments is the sum of worst-case gas costs for all pending transactions using that instance. New transactions are rejected if the effective balance is insufficient.

During the pay frame, the canonical paymaster gets an exemption from the generic SLOAD restriction. While only_verify restricts storage reads to tx.sender only (same as Strategy 1), the pay frame can read the paymaster’s own storage — its deposit balances and withdrawal timestamps. This exemption exists because the canonical code is vetted and well-known; it is admitted “by code match rather than by requiring it to satisfy each generic validation rule individually.”

The state footprint for Strategy 2 is everything from Strategy 1, plus:

  • Canonical paymaster’s bytecode — to verify the code hash matches (or implement the check natively, since the code is known)

  • Canonical paymaster’s storage — deposit balance and withdrawal timestamps, exempted from the tx.sender-only SLOAD restriction

  • Node-local accounting — pending gas commitments per paymaster instance (not on-chain state)

This raises a question the spec does not address: instance proliferation. Since the canonical paymaster is recognized by code hash, anyone can deploy an instance. Each instance has independent storage. If there are 1-3 well-known instances per chain, the state burden is trivially bounded. If there are hundreds or thousands — each needing their deposit balance tracked — the state requirement grows with instance count. There is no protocol-level limit on the number of instances. In the worst case, this approaches Strategy 3’s unbounded state problem. The mitigating argument is economic: a paymaster with a large deposit pool is more useful than many small ones, so fragmentation is economically inefficient. But the protocol does not enforce this.

There is a second, arguably deeper risk: canonical paymaster adoption. Since the mempool policy is not a consensus rule, wallet providers are free to build non-canonical paymasters with richer feature sets — more flexible withdrawal logic, multi-token gas payment, programmable sponsorship policies. If these non-canonical implementations gain majority adoption, their transactions cannot enter the public mempool, cannot be picked up by arbitrary builders, and — critically — cannot be enforced by FOCIL. The censorship resistance story for AA transactions depends entirely on enough users routing through canonical, mempool-compliant paymasters. If the market routes around them, FOCIL becomes structurally toothless for account-abstracted transactions: it exists, but covers nothing. The EIP authors are confident Strategy 2 will be used, citing the strong incentive of public mempool access (any builder can include the tx, plus FOCIL enforcement). Whether that incentive outweighs the feature gap between canonical and non-canonical paymasters is an open question the market will answer.


Figure: Strategy 2 splits validation into two frames. The only_verify frame accesses sender state (same as Strategy 1). The pay frame accesses the canonical paymaster’s own storage (exempted from the sender-only SLOAD rule). Instance proliferation determines whether the paymaster state burden is bounded or not.

Strategy 3 (Full ERC-7562) allows arbitrary paymasters — any contract can act as a paymaster, gated by staking and a node-local reputation system. This is the most permissive strategy and the most demanding in terms of state.

Where Strategy 2 constrains the paymaster to a single canonical bytecode with known storage layout, Strategy 3 removes that constraint. Any contract willing to stake ETH can serve as a paymaster. Staked entities get relaxed validation rules: the SLOAD restriction to tx.sender storage is lifted, allowing staked paymasters to read their own storage and potentially storage of other contracts they interact with during validation. The banned opcode list is also relaxed for staked entities. The safety model shifts from structural constraints (known code, delayed withdrawal) to economic constraints (stake at risk, reputation tracking).

Nodes manage DoS risk through a reputation system: they track how often each staked entity’s transactions are invalidated, how much gas is wasted on failed simulations, and whether the entity causes cascading invalidations. Entities that misbehave get throttled or banned. This requires ongoing observation — the node must simulate transactions, observe their outcomes, and maintain per-entity statistics across blocks.

The state footprint for Strategy 3 is unbounded along multiple dimensions:

  • Arbitrary paymaster bytecodes — nodes must load and execute any paymaster’s code, not just one canonical bytecode. Each paymaster has different logic, different storage layouts, different validation behavior.

  • Cross-account storage reads — staked entities can read storage from contracts other than tx.sender during validation. A staked paymaster might check a whitelist contract, a price oracle, or an access control registry. Each of these is additional state the node must have.

  • Reputation database — nodes must maintain a local database of per-entity behavior (simulation success rate, gas wasted, invalidation frequency). This requires seeing and simulating all transactions involving staked entities — impossible if the node lacks the state to simulate them.

  • Cascading invalidation risk — one storage change in a shared contract can invalidate every pending transaction whose validation depends on that contract. Strategy 1 prevents this structurally (sender-only storage). Strategy 2 limits it to canonical paymaster instances. Strategy 3 has no structural bound — the invalidation surface is as wide as the staked entity’s storage access.

These strategies were designed with full nodes in mind. They implicitly assume the validating node has access to any account’s code and storage on demand.

FOCIL, AA-VOPS, and the eligibility bridge

The tension between frame transactions and partially stateful nodes is not just a mempool convenience problem — it directly affects censorship resistance through FOCIL.

Thomas Thiery’s proposal addresses this by defining an eligible subset of frame transactions that FOCIL can enforce, and introduces a concept directly relevant here: AA-VOPS. AA-VOPS extends VOPS by caching the first N storage slots per account (N in the range 2-4). Most smart wallets store their nonce, owner, and guardian in slots 0-3, so N slots covers the common validation pattern. The critical constraint (constraint 5 in the proposal): VERIFY may only read sender and payer account state plus their first N storage slots. Any read beyond this boundary renders the transaction ineligible — its omission is excused from FOCIL enforcement.

AA-VOPS partially solves the storage half of the problem for frame transaction validation. But as established in the Strategy 1 analysis above, validation also requires bytecodes — the delegate contract’s code (via 7702 delegation) and potentially helper library code. Constraint 5 bounds storage reads but does not address code availability. An AA-VOPS node caching N slots per account still cannot execute the VERIFY frame if it lacks the delegate’s bytecode. This is an open gap in the AA-VOPS design: either bytecodes must be obtained through some external mechanism, or FOCIL-eligible frame transactions must be limited to accounts whose delegate code is widely available (e.g., a small set of well-known wallet implementations).

The base-case tension: thin accounts vs. rich wallets

There is a more fundamental tension that applies regardless of strategy: account abstraction makes accounts heavier, and statelessness needs accounts to stay light.

VOPS’s 8.4 GB baseline rests on a specific assumption: EOAs are thin. An EOA today is ~40 bytes in the account trie — nonce, balance, empty codeHash, empty storageRoot. 400 million accounts at ~40 bytes yields roughly 10 GB. This number is the floor for censorship-resistance nodes: the minimum state needed to validate legacy transactions for any sender on the network.

Native AA changes the per-account weight through two paths. EIP-7702 delegation gives EOAs a non-empty code field and — as the delegated code transacts over time — a growing storage trie (owner key, wallet nonce, guardian, session keys, permissions). EIP-8141’s deploy frame can convert an address into a full contract with code and storage in a single transaction. Either way, accounts that were ~40 bytes acquire storage tries that persist and grow.

The AA-VOPS N-slot constraint bounds what VERIFY can read per validation, but it does not bound the aggregate state a node must hold to validate frame transactions from arbitrary senders. Every account that adopts AA adds N cached storage slots to the validation-critical state set. At N=4 with 64 bytes per slot: if 25% of accounts adopt AA wallets (60M accounts), that adds ~15 GB — nearly doubling the VOPS baseline. At full adoption across 400M accounts, AA-VOPS reaches ~62 GB — an 8x increase over today’s VOPS, though still well below the ~280 GB full state.å

Figure: Validation-critical state grows linearly with AA adoption. At N=4 cached slots per account, moderate adoption nearly doubles the VOPS baseline; full adoption yields an 8x increase. The full state (~280 GB) remains distant, but the VOPS “floor” rises substantially.

Thomas Thiery’s FOCIL proposal offers a partial answer through AA-VOPS: cache N=2-4 storage slots per account, restrict VERIFY to those slots, and excuse any transaction that reads beyond this bound from FOCIL enforcement. This solves the per-validation problem — a node knows exactly what to fetch for each transaction, and the fetch set is small and deterministic. It also creates an incentive for wallet implementations to minimize validation storage reads to remain FOCIL-eligible. But it does not solve the aggregate problem: a node wanting to be a universal validator still needs N slots cached for every AA-enabled account, and this total grows linearly with adoption.

The approach also creates a two-tier system. Transactions from simple wallets that fit within N slots and the VERIFY gas budget get full FOCIL censorship resistance. Transactions that need more — post-quantum signature verification (which already exceeds MAX_VERIFY_GAS_PER_FRAMETX), privacy protocol interactions, complex multi-guardian recovery — fall outside eligibility. Their omission is excused. The transactions most likely to need censorship resistance (novel cryptography, privacy-preserving protocols) are precisely the ones that may not fit within the eligible subset.

More fundamentally, we cannot predict whether N=2-4 storage slots will remain sufficient as wallet implementations evolve. Today’s smart wallets may need only an owner and a nonce for validation. Tomorrow’s may need session key registries, cross-chain state, or social recovery graphs. Shipping a system where censorship resistance for abstracted accounts is structurally bounded by a fixed N risks a future where new use cases outgrow the bound — and where the interaction between statelessness and censorship resistance becomes unworkable precisely when it matters most.

This is not a per-strategy concern. Strategy 1 requires sender storage for validation. Strategy 2 adds paymaster storage on top. Strategy 3 adds arbitrary contract storage. But the base cost — sender storage across all AA-adopting accounts — applies to all three. The strategies differ in how much additional state they require beyond this base. The tension is structural: statelessness wants the minimum viable node to hold less state over time, so more nodes can participate and censorship resistance improves. Account abstraction wants every account to carry richer state over time, so wallets can implement better security models. These goals are not contradictory — the bounded state access rule mediates between them — but the mediation has a cost denominated in gigabytes, and that cost scales with adoption.

Compatibility summary

Full Node PS (w/ paymaster) PS (no paymaster) VOPS AA-VOPS
Account nonce + balance Yes Yes Yes Yes
Delegate + helper bytecodes Yes If tracked If tracked No
Sender storage (N slots) Yes If tracked If tracked No
Paymaster storage Yes If tracked† No No
Arbitrary contract storage Yes No No No
Strategy 1 (self-relay) Yes Partial Partial No
Strategy 2 (canonical paymaster) Yes Partial–Yes† Partial No
Strategy 3 (ERC-7562) Yes No No No

* AA-VOPS caches N storage slots per account but not bytecodes. VERIFY execution requires the delegate’s code. How AA-VOPS nodes obtain bytecodes is an open question — soispoke’s proposal bounds storage access but does not address code availability.

† “If tracked” — PS nodes must explicitly track each canonical paymaster instance. Compatibility is strong when instances are few (1-3) and degrades with instance proliferation. See the instance proliferation discussion above.

Closing

Frame transactions are a powerful primitive for native account abstraction. But they carry two tensions that go deeper than mempool strategy selection.

The first is structural: statelessness needs accounts to stay thin, while account abstraction needs them to grow richer. The bounded state access rule (N slots per account) mediates this by capping per-validation reads, but the aggregate state grows linearly with AA adoption. Today’s ~10 GB VOPS baseline could reach ~20 GB at moderate adoption and past 60 GB at full adoption.

The second is economic: Strategy 2’s censorship resistance guarantees only apply to transactions using canonical, mempool-compliant paymasters. If wallet providers build richer non-canonical paymasters and users gravitate toward them, those transactions route through private builders, and FOCIL — designed to prevent censorship — covers nothing for the majority of AA transactions. The protocol decisions made around account abstraction will shape what “censorship resistant” means in practice, and whether the infrastructure we build for FOCIL inclusion of AA transactions has anyone to include.

The fear I have is that we take a decision without considering statelessness. Once ZKEVMs ship, a supermajority of nodes will be stateless or partially-stateful — and if the state needed for mempool validation has grown too large, almost nobody can keep the mempool healthy or participate in FOCIL. And if we get the canonical paymaster wrong — if wallet providers route around it because it doesn’t offer what users want — then even the nodes that can afford the state have nothing to enforce. FOCIL exists, but covers nobody. We greatly degrade the Censorship Resistance we have battled so much to finally have in Hegota.

4 Likes