ByAUJay
EIP-7702 Gas Estimation: Why Your Simulations Lie and How to Fix Them
Short summary: EIP-7702 shipped to Ethereum mainnet with Pectra on May 7, 2025 and changes how gas is charged and “warmed” when EOAs delegate to smart contracts. If you simulate the old way, your eth_estimateGas will routinely mis-price 7702 flows—this post pinpoints the failure modes and gives step-by-step fixes, with concrete configs, formulas, and RPC payloads. (blog.ethereum.org)
What changed on mainnet (and why your mental model is now wrong)
EIP-7702 adds a new transaction type (0x04) that lets an EOA permanently set “code” to a delegation indicator: 0xef0100 || delegate_address. Calls to the EOA execute the delegate’s code in the EOA’s storage/balance context. This shipped with Pectra on May 7, 2025. (eips.ethereum.org)
Key mechanics that affect gas:
- A type 0x04 transaction carries an authorization_list of tuples [chain_id, address, nonce, y_parity, r, s]. The client processes this list before execution begins (after incrementing the sender nonce). (eips.ethereum.org)
- Intrinsic gas: 21000 + calldata/data/access-list costs from EIP-2930, plus PER_EMPTY_ACCOUNT_COST (25,000) per authorization. If the “authority” account already exists, the protocol refunds PER_EMPTY_ACCOUNT_COST − PER_AUTH_BASE_COST (25,000 − 12,500) later, netting 12,500 per auth. Many simulators miss this refund path. (eips.ethereum.org)
- During delegated execution, CODESIZE/CODECOPY operate on the real code; EXTCODESIZE on the authority returns 23 (size of the delegation indicator), breaking “isContract” heuristics and some gas assumptions. (eips.ethereum.org)
- Following the delegation may incur a cold account read (2,600 gas) the first time the delegate’s code is resolved; warm hits cost 100. Incorrect warm/cold modeling causes over/underestimates. (eips.ethereum.org)
- Crucially: even if the execution reverts, processed delegation indicators are not rolled back. Your eth_call simulations won’t persist that state, but the onchain reality will. Plan gas and flows accordingly. (eips.ethereum.org)
Pectra made this live network-wide—if your tooling still assumes pre-Pectra semantics, your numbers will be off. (blog.ethereum.org)
Seven concrete reasons your gas simulations lie today
- Your client/SDK doesn’t fully implement 7702
- Many ecosystems only recently added 7702 support. Foundry added developer support in 2024 (now stable in v1.0; anvil --hardfork prague). Some toolchains and plugins still lag (e.g., Hardhat Ledger plugin notes no 7702 support yet), which breaks signing/serialization and, by extension, estimation. (paradigm.xyz)
- You’re ignoring the per-authorization intrinsic charge and refund
- The protocol charges PER_EMPTY_ACCOUNT_COST (25,000) for each authorization up front, but if the authority isn’t an “empty” account you later get a refund that reduces the net to 12,500. Simulators that don’t model this overestimate by ~12.5k per auth. (eips.ethereum.org)
- You’re not modeling warm/cold costs introduced by delegated code resolution
- First-time resolution to the delegate may be a cold account read (2,600); once warmed, accesses are 100. If your simulator treats every resolution as warm (or cold), your first-call gas is wrong by ~2,500. (eips.ethereum.org)
- You simulate without the 7702 “pre-warm”
- When a transaction’s destination has a delegation indicator, clients add the delegate target to accessed_addresses (warm). If your local simulator doesn’t, you overpay by the cold-to-warm delta. (eips.ethereum.org)
- You assume eth_estimateGas catches internal OOG—binary search + 63/64 forward breaks that
- Clients binary-search the minimum gas that makes the top-level call succeed. If your delegated wallet does a CALL near the 63/64 threshold or uses gasleft() for internal budgeting, the top-level can succeed while inner work silently runs out of gas—estimation under-shoots and production fails. (arkis.xyz)
- Your RPC has a gas cap
- Hosted endpoints often cap eth_call/eth_estimateGas (e.g., “10× block gas limit” in MetaMask infra; Chainstack caps via rpc.gascap), causing misleading failures or truncated estimates on heavy batches. (docs.metamask.io)
- You treat mempool state as static
- 7702 breaks prior mempool invariants; clients may accept just one pending tx for a delegated EOA because any call to it can reduce its balance. Simulating a second tx “as if it would land” can be nonsense. (eips.ethereum.org)
The fix: a pragmatic, production-ready playbook
Below is what we’ve implemented for clients to get reliable numbers post‑Pectra.
1) Run a Pectra-aware dev stack and enable 7702 paths
- Use an anvil instance with the Prague/Pectra fork: anvil --hardfork prague. Foundry v1.0 ships 7702 cheatcodes to sign/attach authorizations for testing. (paradigm.xyz)
- If you rely on Hardhat + hardware wallets, check plugin readiness (e.g., hardhat-ledger currently flags 7702 unsupported). For estimation, use a software signer or Foundry until plugins catch up. (hardhat.org)
2) Use the right RPCs for AA stacks—don’t coerce 7702 into legacy calls
- For ERC‑4337 flows, estimate via eth_estimateUserOperationGas and include the 7702 authorization object (eip7702Auth). Bundlers that implement EntryPoint v0.7/0.8 accept this field explicitly. Example schemas are documented by MetaMask and Candide. (docs.metamask.io)
Example (abbreviated) userOp payload with eip7702Auth:
{ "jsonrpc": "2.0", "id": 1, "method": "eth_estimateUserOperationGas", "params": [{ "sender": "0xYourEOA", "callData": "0x...", "eip7702Auth": { "address": "0xDelegateImpl", "chainId": "0x1", "nonce": "0x2a", "r": "0x...", "s": "0x...", "v": "0x1b", "yParity": "0x01" } }, "0xEntryPoint", "latest"] }
This makes the bundler simulate with the actual 7702 state transition semantics. (docs.metamask.io)
- When estimating type 0x04 “set code” transactions directly, your simulation must include authorization_list; libraries and docs from Alchemy/MetaMask demonstrate the needed shape and minimum versions. (alchemy.com)
3) Model the per-authorization costs and refunds explicitly
- Budget baseline intrinsic = 21,000 + calldata cost + EIP‑2930 access list cost.
- Add PER_EMPTY_ACCOUNT_COST × nAuthorizations to the intrinsic; if authorities are not “empty,” net cost is 12,500 × nAuthorizations after refunds. Use 25,000 for the first-ever delegation to an EOA you don’t control; use 12,500 for subsequent upgrades. (eips.ethereum.org)
Rule of thumb we use in production quoting:
- First-time upgrade for an unknown EOA: add 25,000 per auth.
- Repeat upgrades (same EOA, non-empty): add 12,500 per auth. We still cap final quotes conservatively (see Step 7).
4) Get warm/cold right—use access lists and the protocol’s pre-warming
- The protocol warms the delegate target in accessed_addresses when tx.to has a delegation indicator. Still, any downstream contracts you call should be pre-warmed via an EIP‑2930 access list to avoid 2,600-gas cold reads (warm = 100). You can generate an access list with eth_createAccessList before sending the real tx. (eips.ethereum.org)
Quick math:
- Pre-warming one address via access list costs 2,400 gas. It commonly saves ~2,500 vs a cold read on first touch (net ~100 gas saved) and can save much more if you touch several storage keys under the same address. For multi-hop batches, access lists materially stabilize estimates. (eips.ethereum.org)
Access-list example:
{ "jsonrpc": "2.0", "id": 1, "method": "eth_createAccessList", "params": [{ "from": "0xYourEOA", "to": "0xRouter", "data": "0xYourCalldata", "value": "0x0" }, "latest"] }
Use the returned accessList in your type 0x04 tx’s access_list field. (drpc.org)
5) Stop trusting “gasleft()” in delegates; force overestimation rather than under
- eth_estimateGas binary-searches for the minimum gas that makes the top level succeed; if an inner CALL runs out of gas, estimation can still “pass.” Adopt the proven pattern: when you’re close to internal OOG, revert at the top level to force the estimator to overestimate. This avoids 1%‑case production failures with 63/64 forwarding. (arkis.xyz)
6) Raise or avoid RPC gas caps during estimation
- If you see inexplicable “estimation failed” on large batches, you might be hitting infra caps (e.g., eth_estimateGas gas cap set to 10× block gas in some providers; Chainstack caps via rpc.gascap by default). Either run your own node with a higher rpc.gascap, split batches, or use a bundler that simulates server-side. (docs.metamask.io)
7) Quote conservatively with deterministic adders
Even with the above, production conditions vary. Add deterministic margins:
- +12,500 per authorization if you cannot confidently classify the account as non-empty.
- +2,600 once per previously-untouched delegate target unless you’re certain it will be warm or pre-warmed via access list.
- +1–3% for 63/64 headroom if your delegate makes nested external calls. These are tiny compared to end-user slippage costs and will eliminate “ran out of gas” flakiness.
Practical: end-to-end estimation for a first-time 7702 upgrade + batched swap
Scenario
- A user upgrades their EOA to a standard 7702 proxy and then executes approve+swap in one batch via the delegate. You’ll send a type 0x04 tx with one authorization (the proxy implementation), and call into the delegate to perform approve+swap. We want a realistic upper-bound gas.
Inputs and assumptions
- First-ever delegation for this EOA (treat as “empty” for cost). One authorization. No pre-existing access list. One new downstream address (router) touched multiple times. (eips.ethereum.org)
- You will include an EIP‑2930 access list for the router. (eips.ethereum.org)
Compute:
- Intrinsic
- 21,000 base + calldata bytes (roughly 4–16 gas per byte as per EIP-2930 weights) + access list cost:
- Access list with one address ≈ 2,400 gas. (eips.ethereum.org)
- Authorization overhead
- First-time: PER_EMPTY_ACCOUNT_COST = 25,000 (no refund to 12,500 since we’re assuming empty to be safe). (eips.ethereum.org)
- Delegate resolution
- First call to delegated code: if you include the delegate target in accessed_addresses (protocol does when tx.to is delegated), it’s warm; otherwise budget +2,600 once. For safety, add +2,600 unless you verified warm behavior end-to-end in your stack. (eips.ethereum.org)
- Downstream calls
- Because you pre-warmed the router with an access list, you avoid the initial 2,600 cold penalty (warm = 100). Without access list, add +2,600 for the first touch. (eips.ethereum.org)
- Core execution
- Approve+swap on a modern DEX router typically falls in the 90–130k range depending on path/hops/tokens; your internal historical median should dominate here. Apply a 2–3% 63/64 safety bump if your delegate does nested calls. (The 63/64 rationale is documented in gas-estimation failure analyses.) (arkis.xyz)
Rule-of-thumb upper bound for first-time users we quote:
- 21,000 (base)
-
- ~2,400 (access list for router)
-
- 25,000 (first authorization)
-
- 2,600 (delegate resolution cold safety)
-
- 120,000 (example approve+swap payload)
-
- 3% margin (nested CALL safety) Total budget ≈ 173,000–180,000 gas before data-size costs. Calldata and any extra access-list storage keys will add on top. Validate with a Pectra-aware simulator (Foundry/anvil prague) using the exact calldata and authorization_list. (paradigm.xyz)
Don’t forget the footguns that flip control flow (and gas)
- EXTCODESIZE on a delegated EOA returns 23. Any “isContract” branch will now treat the EOA as a contract, changing execution path and gas. Audit these code paths. (eips.ethereum.org)
- destination cannot be null on a 0x04 transaction—your legacy “send-to-null” probes for estimation will fail. (eips.ethereum.org)
- Delegation persists even if execution reverts; your eth_call won’t persist it. If you simulate a revert and then assume “state unchanged,” production will differ. This also matters for how you batch follow-up calls and their gas. (eips.ethereum.org)
- Mempool behavior for delegated EOAs is stricter; don’t compute estimations that assume multiple pendings will co-exist for the same EOA. (eips.ethereum.org)
Implementation snippets you can lift today
A) Foundry: build and send a 7702 tx with an access list
Foundry v1.0 includes helpers to sign 7702 authorizations and attach them. You can also have cast build transactions with an authorization list and create an access list on the fly (via eth_createAccessList) before sending. (paradigm.xyz)
# Create an access list (rpc must be Pectra-aware) cast access-list --rpc-url $RPC \ --from 0xYourEOA \ --to 0xRouter \ --data 0xCalldata > accesslist.json # Sign a 7702 authorization (see Foundry cheatcodes / CAST helpers) cast sign-delegation --chain-id 1 \ --address 0xDelegateImpl \ --nonce $(cast nonce 0xYourEOA --rpc-url $RPC) \ --private-key $PK > auth.rlp # Build a type-4 tx with --authorization-list and --access-list cast mktx --type 4 \ --to 0xYourEOA \ --authorization-list $(cat auth.rlp) \ --access-list $(cat accesslist.json) \ --data 0xCallToDelegate \ --value 0 \ --gas-limit 180000
B) Bundler estimation with 7702 (MetaMask/Candide schema)
eth_estimateUserOperationGas with eip7702Auth ensures the bundler simulates with 7702 semantics. Don’t forget to bump for first-time PER_EMPTY_ACCOUNT_COST if the wallet hasn’t delegated on that chain yet. (docs.metamask.io)
Emerging best practices we see across leading stacks
- Always ship with a “7702-aware” gas estimator:
- Add 12.5k–25k per auth (depending on emptiness), +2,600 cold deltas as needed, and a 1–3% CALL safety headroom. Bake this into your quoting pipeline to avoid UX churn. (eips.ethereum.org)
- Prefer access lists for multi-hop batches and when touching multiple storage keys on hot contracts. They stabilize estimates and reduce cold surprises. (eips.ethereum.org)
- Use modern SDKs and versions explicitly tested for 7702:
- Foundry v1.0 (development/simulation), MetaMask Smart Accounts Kit quickstarts (Viem-based), and Alchemy’s 7702 docs all outline the necessary request shapes and minimum versions. (paradigm.xyz)
- Validate wallet/tool readiness:
- MetaMask’s 7702 Readiness DApp is a quick way to confirm end-to-end support on a given chain. If this fails, your gas estimates will be junk. (github.com)
- Standardize delegate implementations:
- Use audited proxies (e.g., 7702 proxy patterns) and avoid gasleft()-sensitive logic. Small code differences (e.g., re-entrancy patterns or precompile usage) move gas by thousands in batched flows. (github.com)
- Avoid chainId = 0 in authorizations unless you fully understand the replay/security tradeoffs. It doesn’t fix gas, but it will wreck your assumptions across chains and make estimation/debugging harder. (aicoin.com)
Common troubleshooting checklist (copy/paste into your runbook)
- Does your simulator or RPC endpoint actually support type 0x04 and authorization_list? If not, upgrade or switch. (eips.ethereum.org)
- Did you include eip7702Auth when estimating user operations with a bundler? If not, your numbers are meaningless. (docs.metamask.io)
- Are you hitting a gas cap on estimation? Try your own node with a higher rpc.gascap or split the batch. (docs.metamask.io)
- Did you pre-warm downstream addresses via access lists? If not, pad +2,600 per first touch or add the list. (eips.ethereum.org)
- First-time upgrade for this EOA on this chain? Add a full 25,000 per auth. (eips.ethereum.org)
- Does the delegate rely on gasleft() or tight CALL budgets? Implement the “revert-to-overestimate” pattern. (arkis.xyz)
- Are you simulating a second pending tx for a delegated EOA? Don’t. Clients may only accept one pending; your simulation likely doesn’t map to reality. (eips.ethereum.org)
Why this matters to decision‑makers
- Reliability gap → conversion loss: Underpriced txs that revert waste time, block slots, and user patience. Fixing estimation removes a silent, compounding funnel leak.
- Security perception → adoption: Post‑Pectra, “batch everything” UX is only safe if gas/flow simulation is faithful; otherwise users see unexplained reverts and opt out. (theblock.co)
- Team velocity: A small set of deterministic adders and access lists reduces on‑call churn and lets product teams ship 7702 features (sponsored gas, batching) confidently this quarter—not “after infra matures.” (alchemy.com)
What 7Block Labs can do for you
- Implement a 7702‑aware estimator pipeline for your stack in one sprint: Foundry‑based golden simulations + bundler paths + access‑list generation + deterministic adders.
- Retrofit your delegate to remove gasleft()-based brittleness and add safety backstops for estimation. (arkis.xyz)
- Certify your toolchain readiness (SDK versions, wallet compatibility, RPC caps) using MetaMask’s 7702 Readiness and our internal test suites. (github.com)
If you want zero‑surprise rollouts of 7702 features for your users, we’re ready to help.
References and specs:
- EIP‑7702 specification (transaction type 0x04; PER_AUTH_BASE_COST = 12,500; PER_EMPTY_ACCOUNT_COST = 25,000; warm/cold account semantics; EXTCODESIZE = 23 on delegated EOAs; non‑rollback of delegation on revert). (eips.ethereum.org)
- Pectra mainnet activation (May 7, 2025). (blog.ethereum.org)
- Access lists (EIP‑2930) and cost model. (eips.ethereum.org)
- eth_estimateGas pitfalls and 63/64 forward guidance. (arkis.xyz)
- RPC gas caps in hosted infra. (docs.metamask.io)
- Bundler estimation with eip7702Auth (EntryPoint v0.7/0.8). (docs.metamask.io)
- Dev tooling readiness (Foundry v1.0; Hardhat plugin caveat). (paradigm.xyz)
Like what you're reading? Let's build together.
Get a free 30‑minute consultation with our engineering team.

