Crypto Training

EIP-4337 Evolution Deep Dive: v0.6 -> v0.7 -> v0.8 -> v0.9

A code-first evolution map of ERC-4337 EntryPoint releases: what changed in each version, why it changed, what new risks were introduced, what audits fixed, and what 'battle-tested' really means in practice.

Crypto Training2026-02-1717 min read

ERC-4337 has not evolved as a single "finished" design. It has evolved as a living security system under real adversarial pressure.

This post traces that evolution from v0.6.0 to v0.9.0 using:

  • local source snapshots for each tagged eth-infinitism/account-abstraction release
  • official release notes
  • ERC text updates
  • bundled audit reports (OpenZeppelin + Spearbit)

The goal is not just "what changed". The goal is:

  • what changed
  • why it changed
  • what new risks each change introduced
  • what was actually fixed vs what remains operationally risky

Scope and references#

Core code and release references:

Helpful ecosystem references:

Primary contract links by version:

TLDR timeline#

VersionRelease dateCanonical EntryPoint in release notesCore theme
v0.6.02023-03-290x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789First production generation
v0.7.02024-03-270x0000000071727de22e5e9d8baf0edac6f37da032Gas/accounting refactor + simulation model shift
v0.8.02025-03-260x4337084d9e255ff0702461cf8895ce9e3b5ff108EIP-7702 + EIP-712 hash model
v0.9.02025-11-170x433709009b8330b5d5a6d4e97c25f2f1f189e4e4Paymaster signature + EOF-safe reentrancy model
flowchart LR A[v0.6 prod baseline] --> B[v0.7 packed userOp and split gas] B --> C[v0.8 EIP-7702 and EIP-712] C --> D[v0.9 paymasterSignature and new reentrancy guard]

Baseline architecture that stayed stable#

Even with major version jumps, the core two-phase execution pattern stayed consistent.

sequenceDiagram participant U as User participant B as Bundler participant EP as EntryPoint participant A as Account participant P as Paymaster U->>B: send UserOperation B->>B: off-chain validation and policy checks B->>EP: handleOps(ops, beneficiary) EP->>A: validateUserOp EP->>P: validatePaymasterUserOp (optional) EP->>A: execute callData or executeUserOp EP->>P: postOp (optional) EP->>B: compensate beneficiary
flowchart TD X[Verification loop] --> Y[Execution loop] Y --> Z[Collect fees and pay beneficiary]

The complexity did not come from changing this shape. Complexity came from tightening every edge case around this shape.

v0.6.0: first production generation#

What was added or stabilized#

Main additions around the v0.6 line included:

  • first widely adopted production EntryPoint generation
  • aggregator support model stabilized
  • nonce validation moved/strengthened in EntryPoint path
  • recursive handleOps prevention hardening
  • request hash consistency fixes

Examples from code history and release commits:

  • AA-159 prevent recursive call into handleOps
  • AA-161 validate Nonce in EntryPoint
  • AA-162 Inconsistent userOpHash

Why those changes were needed#

Because the system moved from concept to production mempool economics:

  • malformed nonce handling or hash ambiguity breaks replay safety
  • recursive execution paths can become denial primitives
  • hash mismatches break signer interoperability and simulation reproducibility

Security findings and fixes in this generation#

From the OpenZeppelin incremental audit (published 2023-02-23):

  • client-reported "Detect warm storage accesses" simulation mismatch risk (bundler pays on-chain failure)
  • client-reported basefee leakage path
  • replay weaknesses in sample verifying paymaster
  • self-destruct risk in sample Gnosis manager path
  • revert-reason bombing risk in EntryPoint call sites

The report explicitly marked "Revert reason bombing" as only partially resolved at that time.

flowchart TD A[v0.6 production rollout] --> B[Audited attack surface expansion] B --> C[Simulation mismatch risks] B --> D[Replay and auth scoping bugs in samples] B --> E[Revert-data griefing vector]

Risks introduced by this generation#

v0.6 brought production viability, but it also exposed a hard truth:

  • the biggest risks are often not direct fund drains
  • the biggest risks are bundler-loss and mempool-griefing paths that become DoS multipliers

v0.7.0: accounting and validation architecture rewrite#

This was the most structurally important jump.

Major feature changes#

  1. UserOperation -> PackedUserOperation and packed gas fields.
  2. paymasterVerificationGasLimit and paymasterPostOpGasLimit split out from one shared verification limit.
  3. EntryPointSimulations separated from deployed EntryPoint path.
  4. second-paymaster-postOp path removed.
  5. unused gas penalty logic introduced.
  6. ERC-165 support and richer revert/error model.

Code references:

flowchart LR A[v0.6 single-style gas accounting] --> B[v0.7 split gas lanes] B --> C[account validation gas] B --> D[paymaster validation gas] B --> E[paymaster postOp gas]
flowchart TD A[pre-v0.7 simulation logic in EntryPoint] --> B[v0.7 simulation contract split] B --> C[leaner on-chain EntryPoint] B --> D[new integration risk for bundler simulation config]

Why these changes happened#

Two main reasons:

  • gas accounting correctness under adversarial limits
  • reducing "simulation says pass, chain says fail" mismatches

Audit and bug-fix pressure in this cycle#

OpenZeppelin incremental audit for this cycle (published 2024-02-20) highlighted:

  • M-01 operations can throttle paymasters (simulation aggregation semantics)
  • M-02 ineffective unused-gas penalty edge case
  • M-03 unattributable paymaster fault path (decode/tracing attribution)
  • client-reported CR-03 insufficient prefund condition that could revert the whole bundle at bundler expense

All were marked resolved in follow-up PRs (including PRs #406, #407, #429, #441, #449).

New risks introduced by the new features#

The upgrades were necessary, but they introduced operational sharp edges:

  • packed encoding increased implementation complexity for SDKs and bundlers
  • simulation contract split required consistent off-chain tooling behavior
  • removing second postOp made paymaster design stricter: one cleanup chance
  • penalty logic itself created new economic-griefing edge cases if not perfectly aligned
sequenceDiagram participant U as UserOp participant B as Bundler participant EP as EntryPoint participant PM as Paymaster B->>EP: simulate and include op EP->>PM: validatePaymasterUserOp EP->>EP: execute user call EP->>PM: single postOp PM-->>EP: revert or malformed response EP-->>B: attribution path is critical

v0.8.0: EIP-7702 and hash model expansion#

v0.8 is where ERC-4337 began serious EIP-7702 coexistence.

Major feature changes#

  1. EIP-7702 support in EntryPoint hashing and sender-init path.
  2. EIP-712 typed hash path for getUserOpHash.
  3. stronger/cleaner packed hashing semantics.
  4. ReentrancyGuardTransient based non-reentrancy model.
  5. additional hardening and error cleanup around paymaster and malformed data.

Code references:

flowchart TD A[UserOp with potential 7702 init marker] --> B[EntryPoint hash path] B --> C[EIP-712 domain hash] B --> D[Eip7702Support override initCode hash] C --> E[userOpHash] D --> E

Why these changes happened#

  • network-level trajectory toward 7702 compatibility
  • need for a deterministic, explicit typed-data hashing path
  • pressure to unify account abstraction flows without forcing one account model

Security and review pressure#

The bundled Spearbit 2024/2025 review stream around this generation called out multiple issues, including:

  • mass-invalidation attack surface via missing opcode restrictions (BLOBHASH / BLOBBASEFEE) in the ERC-7562 rule model
  • several bundler and spec consistency footguns around validation phases and gas assumptions

These are not always "contract exploit" issues. They are often "network-level bundler loss / DoS" issues.

New risks introduced by this generation#

  • EIP-7702 path introduced delegate-code trust and init semantics complexity
  • 7702 hash override semantics can be mis-implemented by third-party tooling
  • EIP-712 migration can create signer mismatch bugs across clients
  • transient-storage based reentrancy model created compatibility assumptions later challenged by EOF execution behavior
flowchart LR A[new capability: 7702 support] --> B[new threat: delegate/account-model confusion] A --> C[new threat: hash mismatch across tooling] A --> D[new threat: compatibility assumptions in guard logic]

v0.9.0: making v0.8 assumptions explicit and safer#

v0.9 is less about broad architecture change and more about hardening the edges exposed by v0.8.

Major feature changes#

  1. Paymaster signature extension in paymasterAndData.
  2. Parallel signing flow (account signature and paymaster signature can be produced independently).
  3. getCurrentUserOpHash() support via transient state.
  4. Block-number validity mode (in addition to timestamp mode).
  5. new events for ignored init code and 7702 account initialization.
  6. reentrancy guard model changed away from transient-guard dependency.
  7. stake handling abstraction via new Stakeable helper + BasePaymaster refactor.

Code references:

Paymaster signature encoding in v0.9#

flowchart LR A[paymasterAndData base payload] --> B[append paymasterSignature bytes] B --> C[append uint16 signatureLength] C --> D[append magic 0x22e325a297439656] D --> E[EntryPoint and libs parse suffix]
flowchart TD A[userOpHash] --> B[includes paymasterAndData except paymasterSignature suffix] C[account signature] --> D[can be done in parallel] E[paymaster signature] --> D B --> D

Why these changes happened#

  • to reduce coordination friction between account signer and paymaster signer
  • to expose current op context to AA-aware contracts (getCurrentUserOpHash)
  • to support both timestamp and block-number validity windows
  • to patch compatibility hazards discovered after v0.8 guard choices

Important v0.9 security motive: reentrancy guard change#

Release notes explicitly state ReentrancyGuardTransient assumptions could break under EOF transaction behavior in ways that can bypass intended protection. v0.9 switched to an explicit guard (tx.origin == msg.sender && msg.sender.code.length == 0) for entry functions.

That is not a cosmetic change. That is "we learned a lower-level execution assumption was too optimistic".

stateDiagram-v2 [*] --> v08_guard v08_guard: ReentrancyGuardTransient v08_guard --> risk_found: EOF interaction caveat risk_found --> v09_guard v09_guard: explicit caller constraint modifier v09_guard --> [*]

New risks introduced by v0.9 features#

  • paymaster signature not covered by user signature means application designers must treat paymaster policy data carefully
  • block-range flag encoding is powerful but parser bugs become consensus-fragmentation risk for tooling
  • the new nonReentrant caller constraint changes assumptions for non-EOA callers and integration test setups

UserOperation struct evolution: what changed and why#

flowchart TD A[v0.6 UserOperation fields] --> B[v0.7 PackedUserOperation] B --> C[v0.8 typed hash + 7702-aware hash override] C --> D[v0.9 paymaster signature suffix handling]

Core differences at a glance#

Topicv0.6v0.7v0.8v0.9
Struct modelUserOperationPackedUserOperationsame packed modelsame packed model + richer semantics
Hash pathlegacy pack hashpacked hashEIP-712 + 7702 overridesame + paymaster-signature exclusion logic
Paymaster gasmonolithic-ish pathsplit verification/postOpsame + hardeningsame + signature suffix support
Simulation splitmostly on EntryPointexplicit simulation contract modelretainedretained with extra cleanup
Reentrancy modelOZ guardOZ guardtransient guardexplicit custom guard

DoS and griefing timeline: old versions and what was learned#

The most important failures in this system have repeatedly been economic DoS and simulation mismatch issues.

flowchart TD A[2023-02 OpenZeppelin incremental audit] --> A1[Warm and cold access mismatch risk] A --> A2[Revert reason bombing highlighted] B[2024-02 OpenZeppelin incremental audit] --> B1[Paymaster throttling semantics bug] B --> B2[Ineffective unused gas penalty edge case] B --> B3[Insufficient prefund bundle-loss vector] C[2025-03 Spearbit security review] --> C1[BLOBHASH and BLOBBASEFEE mass invalidation vector] C --> C2[Spec and bundler rule mismatches tightened] D[2025-11 v0.9 release] --> D1[Reentrancy model changed after EOF caveat] D --> D2[Paymaster signature flow introduced]

"Recent DoS problems" to explicitly remember#

  1. Mass invalidation vectors

    • highlighted in 2025 review context (e.g., opcode-based env leakage paths such as BLOBHASH/BLOBBASEFEE in rule sets)
    • impact: bundlers include ops that later fail, paying gas and losing throughput
  2. Insufficient prefund edge

    • identified as CR-03 in 2024 incremental audit update process
    • impact: full bundle can revert at bundler expense under edge accounting conditions
  3. Attribution failures (FailedOp quality)

    • malformed or unattributable paymaster/account errors increase triage cost and delay mitigation
    • impact: operational DoS even without direct exploit
  4. Revert-data griefing lineage

    • old large revert payload handling has long been a griefing axis
    • partial early fixes, then repeated hardening
flowchart TD A[Attacker crafts operation] --> B[Passes shallow simulation] B --> C[Fails deeper path on-chain or bundle simulation] C --> D[Bundler pays or wastes compute] D --> E[Mempool throughput drops] E --> F[Legit ops delayed]

Deep code-diff view across versions#

From local snapshot diffs across contracts/:

  • v0.6 -> v0.7: 64 files changed, +2670 / -1699
  • v0.7 -> v0.8: 71 files changed, +1504 / -3176
  • v0.8 -> v0.9: 46 files changed, +663 / -206

This confirms what the architecture narrative already suggested:

  • v0.7 and v0.8 were structural rewrites
  • v0.9 was a focused hardening and semantics-tightening release
flowchart LR A[v0.6 to v0.7 diff] --> A1[64 files touched] A --> A2[packed userOp and accounting refactor] B[v0.7 to v0.8 diff] --> B1[71 files touched] B --> B2[7702 and hash model transition] C[v0.8 to v0.9 diff] --> C1[46 files touched] C --> C2[targeted hardening and new semantics]

New files and interface surface expansion by jump#

v0.6 -> v0.7 notable additions:

  • contracts/core/EntryPointSimulations.sol
  • contracts/core/UserOperationLib.sol
  • contracts/interfaces/PackedUserOperation.sol
  • contracts/interfaces/IEntryPointSimulations.sol
  • contracts/interfaces/IAccountExecute.sol

v0.7 -> v0.8 notable additions:

  • contracts/core/Eip7702Support.sol
  • contracts/accounts/Simple7702Account.sol
  • contracts/legacy/v06/* compatibility interfaces

v0.8 -> v0.9 notable additions:

  • contracts/core/Stakeable.sol
  • contracts/test/TestCurrentUserOpHash.sol
  • contracts/test/TestPaymasterWithSig.sol

Why this matters for auditors#

When file count explodes, variant risk explodes:

  • every new encoding helper can create mismatch classes
  • every new optional path (e.g., 7702, paymaster signatures) creates parser split risk
  • every "legacy compatibility" interface can preserve old assumptions accidentally

Audit-fix matrix by generation#

PeriodFinding classImpact styleFix status direction
2023 incremental audit (v0.6 era)warm/cold simulation mismatchbundler gas-loss DoSfixed by redesigning validation flow in later generations
2023 incremental audit (v0.6 era)revert reason bombinggriefing and attribution costpartially fixed first, then hardened over later releases
2024 incremental audit (v0.7 cycle)paymaster throttling semantics (M-01)false reputation damage and throttlingfixed (#406)
2024 incremental audit (v0.7 cycle)ineffective unused gas penalty (M-02)economic bundle-space griefingfixed (#407)
2024 incremental audit (v0.7 cycle)unattributable paymaster fault (M-03)operational triage DoSfixed via tracing-first approach (#429)
2024 incremental audit (v0.7 cycle)insufficient prefund (CR-03)bundle revert at bundler expensefixed (#441, #449)
2025 Spearbit review (v0.8/v0.9 transition)BLOBHASH and BLOBBASEFEE mass invalidation vectorbroad bundler gas-loss DoSfixed in rule/docs + bundler updates (#901, bundler updates)
2025 Spearbit review7702/accounting/spec mismatch footgunsinconsistent client behaviorfixed across multiple PRs before v0.9 line
flowchart TD A[Audit finding] --> B[Code fix] A --> C[Spec fix] A --> D[Bundler policy fix] B --> E[On-chain behavior tighter] C --> F[Cross-client alignment] D --> G[Lower gas-loss DoS exposure] E --> H[Still requires operational discipline] F --> H G --> H

The key pattern in all fixes#

Most "DoS" fixes were not one-line contract patches. They were three-layer patches:

  1. EntryPoint behavior correction
  2. ERC text correction
  3. Bundler simulation and policy correction

That three-layer dependency is why old versions can remain "battle-tested" but still operationally dangerous under modern traffic and adversarial behavior.

Deployment and compatibility pressure across versions#

Each version changed not only code but ecosystem assumptions:

  • bundlers had to support the right EntryPoint addresses per network/version
  • SDKs had to serialize the right packed fields and optional suffixes
  • simulation tooling had to remain aligned with validation semantics
flowchart TD A[EntryPoint version bump] --> B[Bundler RPC and simulation updates] A --> C[SDK serialization updates] A --> D[Paymaster service updates] A --> E[Wallet signing domain updates] B --> F[If lagging then simulation mismatch risk] C --> F D --> F E --> F

This is also why external tooling docs (for example viem and ERC-4337 docs pages) matter operationally, even though canonical behavior is still defined by EntryPoint code and ERC text.

Battle-tested vs "fixed all old problems"#

These are not the same claim.

flowchart LR A[battle-tested] --> B[seen in production] A --> C[audited repeatedly] A --> D[major incidents known] E[fixed all old problems] --> F[requires complete closure of old and newly induced classes] E --> G[requires no new complexity regressions] A -. does not imply .-> E

Practical interpretation#

  • v0.6 is battle-tested but carries old design assumptions and known rough edges.
  • v0.7 fixed major accounting/simulation issues but introduced new complexity in split gas + bundler logic.
  • v0.8 enabled critical future compatibility (7702) but created fresh assumptions that needed v0.9 hardening.
  • v0.9 is the current "security posture upgrade", not the end of evolution.

So the right mental model is:

  • battle-tested means "we now know many failure modes"
  • not "failure modes are exhausted"

Feature-by-feature: what was added when and why#

1. Packed UserOp (v0.7)#

Why:

  • lower calldata overhead
  • cleaner gas field structure

Risk introduced:

  • tooling encoding/parsing mismatch risk

2. Split paymaster gas limits (v0.7)#

Why:

  • decouple verification and postOp accounting
  • improve fee predictability

Risk introduced:

  • incorrect bundler defaults can still over/under-estimate cost

3. Unused gas penalty (v0.7, hardened later)#

Why:

  • prevent bundle-space hoarding by over-reserving gas

Risk introduced:

  • penalty-edge economic weirdness if exclusions exist

4. EIP-7702 support (v0.8)#

Why:

  • converge AA infra with 7702 delegation model

Risk introduced:

  • delegate trust and hashing complexity

5. EIP-712 hash path (v0.8)#

Why:

  • standard typed-data hash semantics

Risk introduced:

  • signer domain mismatch across clients

6. Paymaster signature suffix (v0.9)#

Why:

  • allow account and paymaster signatures in parallel
  • lower integration latency and coordination friction

Risk introduced:

  • user signature no longer commits paymaster signature bytes
  • app-level policy binding must be explicit

7. Block-range validity flag (v0.9)#

Why:

  • support both timestamp and block-based validity

Risk introduced:

  • parser inconsistency risk across clients and bundlers

Code map for auditors and integrators#

If you are auditing or integrating today, these are the highest-signal files:

  • EntryPoint.sol across tags:
    • v0.6: foundational behavior
    • v0.7: packed ops + accounting shifts
    • v0.8: 7702 + EIP-712 path
    • v0.9: nonReentrant rewrite, current op hash, block validity mode
  • UserOperationLib.sol (v0.9): paymaster signature parsing and encoding
  • Helpers.sol (v0.9): paymaster data keccak excluding dynamic suffix
  • EntryPointSimulations.sol: simulation model assumptions and mismatch defenses
  • BasePaymaster.sol and Stakeable.sol (v0.9): staking and ownership model evolution
flowchart TD A[High signal files] --> B[EntryPoint.sol] A --> C[UserOperationLib.sol] A --> D[Helpers.sol] A --> E[EntryPointSimulations.sol] A --> F[BasePaymaster.sol and Stakeable.sol] B --> B1[Validation loop] B --> B2[Execution loop] B --> B3[Gas accounting] B --> B4[Reentrancy model] C --> C1[Packed encoding] C --> C2[Hash rules] C --> C3[paymasterSignature suffix] D --> D1[paymasterDataKeccak] E --> E1[Simulation-only logic] E --> E2[DoS-sensitive assumptions] F --> F1[Ownership model] F --> F2[Stake lifecycle]

Migration strategy: choosing your target#

flowchart TD A[Running v0.6 or v0.7?] --> B[Need 7702 support?] B -->|Yes| C[Target v0.9] B -->|No| D[Need paymaster signature parallel flow?] D -->|Yes| C D -->|No| E[Still target v0.9 for guard hardening] C --> F[Re-test simulation pipeline] F --> G[Re-test paymaster encoding] G --> H[Re-test signer domain and hash assumptions]

Closing: the real evolution pattern#

EIP-4337 version evolution is not linear feature accumulation. It is iterative adversarial hardening.

  • v0.6: production baseline
  • v0.7: accounting/simulation correction wave
  • v0.8: 7702 and hash expansion
  • v0.9: compatibility and hardening corrections to v0.8 assumptions

The biggest strategic takeaway is this:

battle-tested should increase your confidence in known failure handling, not make you dismiss new failure classes introduced by new capability.

If you are building on 4337 now, operate like this:

  1. track EntryPoint version semantics explicitly
  2. treat bundler simulation rules as part of your security boundary
  3. model paymaster griefing and attribution quality as first-class
  4. pin hash/signature assumptions end-to-end in tests
flowchart LR A[Version adoption] --> B[Threat model refresh] B --> C[Simulation conformance tests] C --> D[On-chain and off-chain hash parity tests] D --> E[Paymaster griefing tests] E --> F[Production rollout]