Skip to content

fix: reject userOps exceeding the chain batch gas limit cap at quote time#214

Open
fichiokaku wants to merge 1 commit into
developfrom
fix/quote-time-batch-gas-cap
Open

fix: reject userOps exceeding the chain batch gas limit cap at quote time#214
fichiokaku wants to merge 1 commit into
developfrom
fix/quote-time-batch-gas-cap

Conversation

@fichiokaku

Copy link
Copy Markdown
Collaborator

Problem

Three production incidents share the same root cause: a userOp whose execution gas limit exceeds the chain's batcher.batchGasLimit cap (default 8M) is accepted at quote time, the payment userOp executes and charges the user, and then the batcher silently drops the execution userOp with "Invalid maxGasLimit" until its window expires.

  • Chiliz: 9.34M-gas op dropped after the user paid 23.88 CHZ (stx 0xc1a864...574258)
  • Ethereum mainnet: 8.55M-gas op dropped after the user paid 3.15 USDC (stx 0x20c988...cb3663)

The user pays for a supertransaction that can never execute, and the client gets no upfront signal.

Fix

Validate in getPackedMeeUserOpWithGasEstimates (both quote-time call sites go through it) that the userOp's execution gas limit fits the chain's batch cap, and fail the quote with a 400 and an explicit message:

UserOp gas limit (9336306) exceeds the maximum executable gas limit (8000000) on chain (88888)

Details:

  • The formula mirrors the batcher's check exactly: verificationGasLimit + callGasLimit + paymasterVerificationGasLimit + postOpGasLimit, with preVerificationGas excluded (not spent during execution). Same config sources (gasLimitOverrides, gas estimator config) as batcher.service.ts.
  • Trusted payment userOps are skipped (all gas limits are zeroed for them).
  • Applies both to simulated limits (simulate: true) and client-provided manual limits (simulate: false) - both were previously accepted and dropped.

No behavior change for any op that fits the cap. Ops over the cap change from "charged then silently dropped" to "rejected upfront with an actionable error".

Testing

  • typecheck and biome clean; unit suite passes (pre-existing failures only: the real-RPC gas-estimator test and the rpc-manager viem type error, both present on clean develop)
  • no unit test added: the check lives inside the DI-heavy getPackedMeeUserOpWithGasEstimates flow with no existing test harness; happy to add one if wanted

Related

Per-chain cap bumps (Ethereum 16M under the EIP-7825 tx cap, Chiliz 20M) are being applied via chain config secrets separately - this PR is the guard that makes cap overruns visible instead of billable.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant