Skip to content

[evm]: migrate SolverAccount to EntryPoint v0.9 #1366

Description

@seunlanlege

Background

SolverAccount is the contract solver wallets delegate to through EIP-7702. It inherits OpenZeppelin's Account, whose entryPoint() returns ERC4337Utils.ENTRYPOINT_V08. That address gates validateUserOp, authorises the EntryPoint to run ERC-7821 batches, and is where getNonce reads.

EntryPoint v0.9 (0x433709009B8330FDa32311DF1C2AFA402eD8D009) calls accounts through the same interface: IAccount and PackedUserOperation are unchanged from v0.8. The account never hashes an operation itself. It checks the hash the EntryPoint passes in, so the validation logic needs no change.

#816 depends on this move, and the paymaster moves with it in #1365.

Proposed change

  • Override entryPoint() to return the v0.9 address. OpenZeppelin contracts 5.4.0 has no v0.9 constant, so define it locally.
  • Leave the Budgets storage namespace as it is. The storage belongs to the solver's wallet, so limit-order tallies survive a re-delegation only if the slot stays the same.

Consequences

  • New deployment, and every solver re-delegates. The code is immutable and wallets point at its address.
  • Every bid is signed again. v0.9 keeps the same EIP-712 domain name, version and type hash, but the domain includes the EntryPoint address, so a v0.8 signature is not valid on v0.9.
  • Nonces start again. Each EntryPoint keeps its own nonces.

Decisions needed

  1. Ship with [evm]: Select UserOpHash instead of solver address in solver selection #816 or before it. [evm]: Select UserOpHash instead of solver address in solver selection #816 changes the selection call inside validateUserOp and the SelectOptions struct the account passes to the gateway. Each new SolverAccount costs every solver a re-delegation, so one deployment covering both is cheaper than two.
  2. Cutover or transition. A wallet can delegate to only one implementation, so serving v0.8 and v0.9 at the same time means one implementation that accepts both EntryPoints. If we do that, solvers must sign each bid for one EntryPoint only. A signature cannot be replayed across EntryPoints, but the same bid signed for both could execute once on each, because the nonces are separate.

Rollout

SolverAccount is configured on Ethereum, BNB Chain, Arbitrum, Base, Polygon, Optimism, Gnosis and Polkadot Hub, and on the BSC Chapel and Polygon Amoy testnets.

  • Confirm EntryPoint v0.9 exists on every chain. Confirmed with eth_getCode: Ethereum, BNB Chain, Arbitrum, Base, Polygon, Optimism, Gnosis, Soneium, BSC Chapel, Polygon Amoy, Gnosis Chiado, Arbitrum Sepolia, Optimism Sepolia and Base Sepolia. Not yet checked: Polkadot Hub, Paseo Asset Hub and Sepolia.
  • Deploy with DeploySolverAccount.s.sol on each chain
  • Update the SolverAccount addresses in the SDK chain config and the indexer config
  • Solvers re-delegate

Affected files

  • evm/src/apps/intentsv2/SolverAccount.sol
  • evm/script/DeploySolverAccount.s.sol
  • evm/tests/foundry/account/SolverAccountTest.sol, pinned to ENTRYPOINT_V08

Acceptance

  • Tests pass against the canonical v0.9 EntryPoint
  • A bid is selected and filled through a v0.9 bundler on a testnet
  • A limit order's tally survives the re-delegation

Activity

  1. added this to the EntryPoint v0.9 milestone on Oct 1, 2026
  2. seunlanlege commented on Oct 9, 2026

    @seunlanlege
    MemberAuthor

    closed in #1371

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions