Changes Merged Over Time and Why
Day 0 Fixes — January 29, 2026
PR #11205: Add missing elision of VERIFY frame data from signature hash
Author: fjl | Merged: Jan 29
- Bug: the original spec did not elide
frame.dataof VERIFY frames when computing the canonical signature hash - This was critical because VERIFY frames contain the signature itself; by definition it cannot be part of the signature hash
- Merged same day
PR #11209: Fix status field number
Author: kevaundray | Merged: Jan 29
- The TXPARAM table had an incorrect field number for the
statusparameter - Simple numbering fix, approved by fjl
APPROVE Relaxation — February 10, 2026
PR #11297: Relax requirement that APPROVE must be called by top level call frame
Author: lightclient | Merged: Feb 10
- Why: Existing smart accounts (especially proxy-based ones like Safe) can change their implementation code but NOT their outer proxy contract. The outer proxy uses
RETURN, notAPPROVE. Requiring top-levelAPPROVEmade adoption impossible for these accounts. - Change:
APPROVEbecame transaction-scoped, meaning it can be called from any depth and updatessender_approved/payer_approveddirectly, rather than requiring the top-level frame to exit with a special return code.
From lightclient's PR description:
This allows existing smart accounts to more easily adopt EIP-8141. Before, the requirement was that accounts must exit the top level frame with APPROVE. Since APPROVE only exists with 8141, not smart accounts today support it. More importantly, smart accounts who are deployed with proxies can change their smart account implementations, but still not the outer proxy which won't understand
APPROVE.
Bug Fixes & Clarifications — February-March 2026
PR #11344: Fix some issues with EIP-8141
Author: derekchiang | Merged: Mar 2
- Fixed CALLER vs ADDRESS: Changed
CALLER == frame.targettoADDRESS == frame.targetfor APPROVE. In VERIFY frames, CALLER is ENTRY_POINT, not frame.target. This was a bug introduced during refactoring. - Removed APPROVE restriction to VERIFY frames: lightclient wanted APPROVE available in any mode for private pool use cases (stateful approvals).
- Clarified frame reverts: Made explicit that a frame revert discards that frame's state changes but doesn't affect other frames.
- Notable discussion: nlordell asked about the TXPARAM numbering jump from 0x09 to 0x10; lightclient confirmed it was intentional to separate tx-level vs frame-level queries.
EOA Support — March 5-10, 2026
PR #11379: Add EOA support
Author: derekchiang | Merged: Mar 10
- Why: The biggest driver was adoption: if most users are on EOAs, frame transactions need to work for them natively, without requiring smart contract deployment.
- What changed: Added "default code" behavior for EOAs:
- In VERIFY mode: reads
frame.dataas a signature, supports SECP256K1 (0x0) and P256 (0x1) types, callsAPPROVE(scope) - In SENDER mode: reads
frame.dataas RLP-encoded calls[[target, value, data], ...]and executes them - In DEFAULT mode: reverts
- In VERIFY mode: reads
- Also initially added a
valuefield to frames (later removed; the default code handles value via call encoding)
Opcode Redesign — March 12, 2026
PR #11400: Clean up frame access opcodes
Author: fjl | Merged: Mar 12
- Why: Most TXPARAM values are 32 bytes or less, so
TXPARAMSIZE/TXPARAMCOPY(designed for variable-length data) were unnecessary for most fields. The only variable-size data is frame input data. - Change: Replaced
TXPARAMSIZE (0xb1)andTXPARAMCOPY (0xb2)with dedicatedFRAMEDATALOAD (0xb1)andFRAMEDATACOPY (0xb2). RenamedTXPARAMLOADto justTXPARAM (0xb0).
From fjl's PR description:
Most values returned by the TXPARAM opcode family is 32-bytes or less, so it makes no sense to be able to copy the data into memory. The only variable-size components of the transaction are the frame list and the input data of each frame. So I am defining specialized opcodes for reading the input data of the frame.
Approval Bits — March 12-13, 2026
PR #11401: Add approval bits to frame mode
Author: fjl | Merged: Mar 12
- Why: Users needed a way to specify their intended approval scope in the signed transaction data so that smart accounts don't have to extract scope from
frame.data(which is elided from the signature hash). Without this, accounts would need to computekeccak(sighash | scope), which is repetitive logic every account must implement. - Change: Added bits 9-10 of
frame.modeas approval scope constraints. These constrain whichAPPROVEscopes are valid for that frame. - Also shifted APPROVE scope values from 0-indexed (0x0, 0x1, 0x2) to 1-indexed (0x1, 0x2, 0x3) so that the mode bits can directly encode the constraint.
From fjl's PR description:
The primary motivation for adding these bits is allowing the user to specify to their own account what should be approved, while retaining the ability to sign directly over the sighash of the transaction. However, the concept of mode bits is going to be useful for other things we may have to put in later, and it also gives some security benefits.
PR #11402: Fix bit indices
Author: fjl | Merged: Mar 13
- Changed from 0-indexed to 1-indexed bit numbering (bits 9 and 10 instead of 8 and 9), since bits are "typically one-indexed."
Atomic Batching — March 11-25, 2026
PR #11395: Add support for atomic batching
Author: derekchiang | Merged: Mar 25
- Why: Users need "all-or-nothing" semantics for related operations (e.g., ERC-20 approve + swap). Without this, a revert in one frame leaves prior frames' state changes applied, creating dangerous intermediate states.
- Evolution: Originally proposed a
SENDER_ATOMICmode. After extensive discussion:- pedrouid argued for atomic-by-default
- derekchiang & frangio explained non-atomic is needed for paymasters
- 0xrcinus proposed explicit group IDs
- sm-stack suggested bit flags
- Final design: Bit 11 of
frame.modeas the "atomic batch" flag. Consecutive SENDER frames with the flag set form a batch. If any frame in the batch reverts, all preceding frames are reverted and remaining frames are skipped. - Additional change: Required
sender_approvedto be true before any SENDER frame can execute. This forbids APPROVE from being called in SENDER mode, preventing complexity where an atomic batch could revert a payment approval.
From derekchiang's PR description:
This PR also adds the explicit requirement that
SENDERframes can only be executed whensender_approvedandpayer_approvedhave been set totrue, which essentially forbidsapprovefrom being called inSENDERmodes. This is important because otherwise aSENDER_ATOMICframe canapprovegas payment, and then the payment frame may be reverted by otherSENDER_ATOMICframes, creating complexity for transaction validation.
Mempool Policy — March 16-25, 2026
PR #11415: Add mempool policy
Author: lightclient | Merged: Mar 25
- Why: Without clear mempool rules, node operators would each implement their own policies, creating inconsistency and potentially enabling DoS attacks. The policy section was inspired by ERC-7562 but simplified.
- Key innovations:
- Validation prefix: Only the frames up to
payer_approved = trueare subject to mempool rules. Post-payment frames are arbitrary. - Canonical paymaster: A standardized paymaster contract verified by runtime code match. Removes the entire reputation/staking system from ERC-7562.
- Non-canonical paymaster limit: At most 1 pending tx per non-canonical paymaster
- Banned opcodes: ORIGIN, GASPRICE, BLOCKHASH, COINBASE, TIMESTAMP, NUMBER, PREVRANDAO, GASLIMIT, BASEFEE, BLOBHASH, BLOBBASEFEE, GAS (with exceptions), CREATE, CREATE2 (with exceptions), INVALID, SELFDESTRUCT, BALANCE, SELFBALANCE, SSTORE, TLOAD, TSTORE
- MAX_VERIFY_GAS: 100,000 gas cap for validation prefix
- Four recognized validation prefixes: self-relay (basic & deploy), canonical paymaster (basic & deploy)
- Validation prefix: Only the frames up to
- Notable review feedback: jochem-brouwer provided detailed review of the canonical paymaster Solidity contract, catching PUSH0 optimization, stack order documentation, withdrawal overwrite handling, and chain ID checks.
From lightclient's PR description:
One important change vs. 7562 is relying on a canonical paymaster contract. This point is open for discussion generally, but by having a canonical contract, we can remove the complex reputation system around the staking. It's also possible to add more functionality here over time.
Default Code Update — March 26, 2026
PR #11448: Update default code to match latest spec
Author: derekchiang | Merged: Mar 26
- Why: The approval bits addition meant the default code could be simplified: the scope is now read from the mode bits instead of being encoded separately.
- Updated the default code Python reference implementation to match all recent spec changes.
Header Metadata Fix — April 8, 2026
PR #11251: Add EIP-1559 to requires header
Author: BonyHanter83 | Merged: Apr 8 (opened Feb 4)
- Why: The spec uses EIP-1559's
max_priority_fee_per_gasandmax_fee_per_gasfields and explicitly states thateffective_gas_priceis calculated per EIP-1559, but the header didn't list it as a dependency. - Change: Added
1559to therequiresheader field alongside2718and4844. - Approved by lightclient.
- This PR was open for over two months before being merged. It was a simple metadata fix that had no controversy.
Rejected/Closed PRs
PR #11404: Simplify approval bits (closed Mar 26)
Author: derekchiang
- Proposed an alternative approach to approval bit handling
- Superseded by the mode flags approach (PR #11401)
- Sparked useful discussion: 0xrcinus questioned whether bits were needed at all, Meyanis95 reviewed edge cases
PR #11408: Migrate EOA default code to EIP-7932 registry (closed Mar 21)
Author: SirSpudlington
- Proposed using EIP-7932's signature registry for default code, citing P256 malleability fixes
- lightclient rejected: "We want to reserve the ability to define custom behavior in 8141 default contract and we don't want to rely on another EIP/precompile like this."
PRs #11310, #11314, #11321: Fix broken links (all closed)
Author: marukai67
- Three separate PRs attempting to fix allegedly broken links in the spec (to ERC-7562, EIP-2718, and other references)
- All rejected by lightclient with variants of "It's not broken" / "Not broken, thanks though"
- The links use relative paths that work in the EIPs rendering system but may look broken locally
Active Open PRs (as of April 9, 2026)
These PRs represent active design proposals that may change the spec in the near future.
PR #11272: Disable EIP-3607 check for frame transactions (open since Feb 6)
Author: Thegaram
- Why: EIP-3607 rejects transactions from senders with deployed code, which would block frame transactions for smart accounts.
- Still open. lightclient's earlier review was dismissed on Apr 8, and the PR remains unresolved.
PR #11455: Small tweaks to default code for EIP-7392 compatibility (open since Mar 26)
Author: SirSpudlington
- Spiritual successor to the closed PR #11408
- Makes the default code values interoperable with EIP-7392 without introducing a dependency
- No reviews yet from core authors
PR #11481: Add signatures list to outer tx (open since Apr 2)
Author: lightclient
- Why: Forward-compatibility with PQ signature aggregation. PQ signatures are large, and aggregating them will be critical.
- Proposed change: Add a new
signaturesfield to the outer transaction object, containing signature objects with algorithm metadata, message, and signer. Signatures are verified before frame execution. - Significance: This is the most structurally significant open proposal; it would change the transaction format itself. In the future, block-level aggregated witnesses could elide individual signatures.
- All reviewers approved, but derekchiang raised a practical concern (Apr 9): smart contracts leveraging outer signatures don't know which index their signature is at. The contract can't hardcode an index because the transaction may have any number of signatures in arbitrary order, so the default code has to loop through the entire list to find the relevant entry. This is an ergonomic and gas-efficiency weakness that needs addressing.
From lightclient's PR description:
Any important goal of 8141 is to be forward compatible with signature aggregation techniques, especially with respect to PQ signatures. As those signatures are quite large, aggregating them may become very important as many users begin migrating.
PR #11482: Allow using precompiles for VERIFY frames (open since Apr 2)
Author: derekchiang
- Why: Allow both EOAs and contract accounts to use precompiles for verification, enabling key rotation and shared verification logic.
- Proposed change: Designate "signature precompiles" that VERIFY frames can target natively. The precompile reads the public key commitment from storage.
- Still being worked on. Extends the verification model significantly.
From derekchiang's PR description:
This will allow a contract account to use precompiles for verification, while still having code that serves other purpose (e.g. for execution). As a side benefit, this also enables key rotation, since the precompile reads the public key commitment from storage.
PR #11488: Fix spec inconsistencies (open since Apr 6)
Author: chiranjeev13
- Proposed changes:
- Add static VERIFY frame count check (
<= 2) to constraints, sincesender_approvedandpayer_approvedare one-shot flags - Fix stale APPROVE scope values in structural rules:
self_verify→APPROVE(0x3),only_verify→APPROVE(0x1),pay→APPROVE(0x2) - Remove
frame.target != tx.sendercheck from default VERIFY code to allow any EOA as paymaster
- Add static VERIFY frame count check (
- Inspired by node.cm's observations on the EthMagicians thread (posts #135-136)
- No reviews yet from core authors