Repository navigation
Default nonce key (Date.now()) costs ~99k extra gas per userOp after Glamsterdam (EIP-8037): default to a reused key? #5198
Unanswered
PyraVim
asked this question in
Idea / Feature Request
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Summary
toSmartAccountdefaultsnonceKeyManagertocreateNonceManager({ source: { get() { return Date.now() } } })(account-abstraction/accounts/toSmartAccount.ts, viem 2.57.3), andgetNonceusesnonceKeyManager.consume(...)as the key when the caller passes none.consumereturnsDate.now()or the previous value plus one, so every userOp gets a key that has never been used, with sequence 0.In EntryPoint v0.7 the first use of a key writes a new storage slot (
nonceSequenceNumber[sender][key]). Under EIP-8037 (Glamsterdam, live on Sepolia since 2026-10-06 13:53:36 UTC) a new slot costs 97,920 state gas. So with the default, every userOp now pays about 99k gas more for its nonce update than it would on a reused key. Before the fork the difference was about 17k. Each op also leaves a permanent slot in the EntryPoint, which is the state growth EIP-8037 prices.This is a cost increase, not a failure, as long as verificationGasLimit is estimated per op on an Amsterdam node: bundler simulations include the nonce update. It turns into AA26 failures when an app hardcodes or caches verificationGasLimit.
Account implementations that pass the key through (for example permissionless.js
toSafeSmartAccount,toSimpleSmartAccount,toBiconomySmartAccount,toThirdwebSmartAccount,toTrustSmartAccount,toLightSmartAccount:key: nonceKey ?? args?.key) inherit this default.Measurement (Sepolia, EntryPoint v0.7 0x0000000071727De22E5E9d8BAf0edAc6f37da032)
EntryPoint.incrementNonce(uint192 key)performs the same storage write as a userOp's nonce update. Estimated from a fresh address, for a new key and for the same key with its sequence already at 1 (state override onnonceSequenceNumber[caller][key], mapping at base slot 1):Requests (results above from rpc.sepolia.ethpandaops.io, 2026-10-06T17:54:31.486Z). The "latest" requests work on any Sepolia node; the block 0xb4e9cf ones need a node that still has state for that block.
0x72651d863e1b78ea4ef669c99b51c4e6d92dfd7d1d72d755e72fde72b599deb5iskeccak256(abi.encode(key, keccak256(abi.encode(caller, 1)))). The override dropping the estimate to 28438 confirms the slot.Suggestion
Default to a reused key (for example key 0, or one stable key per account) when the caller does not ask for parallel nonces, and keep the timestamp key as an opt-in for parallel userOps. The timestamp default lets an app send several userOps without waiting, so this is a tradeoff. If the default stays, documenting that it opens a new nonce slot on every op and what that costs on Glamsterdam chains would help.
Disclosure: prepared with the help of an AI assistant (Claude). The measurements and requests above were run against Sepolia and the output is pasted unedited.
All reactions