Skip to content

fix: account for the domain tag when estimating gas - #964

Open
Ruzzgar wants to merge 1 commit into
ProjectOpenSea:mainfrom
Ruzzgar:fix/estimate-gas-domain-tag
Open

fix: account for the domain tag when estimating gas#964
Ruzzgar wants to merge 1 commit into
ProjectOpenSea:mainfrom
Ruzzgar:fix/estimate-gas-domain-tag

Conversation

@Ruzzgar

@Ruzzgar Ruzzgar commented Aug 16, 2026

Copy link
Copy Markdown

What happened

With a domain set, buildTransaction appends its four byte tag to the calldata, and transact sends exactly that. estimateGas never goes through it, it calls the contract method with the encoded arguments only, so those four bytes are not part of what gets measured.

Calldata is charged per byte, so the number comes back short. On a validate() call:

estimateGas()   65562
gasUsed         65626

Feed that estimate straight back in as a gas limit, which is the usual reason to ask for one, and the transaction runs out of gas.

The fix

When a domain is set, estimate the transaction buildTransaction produces, so the calldata being measured is the calldata being sent. Without a domain the call goes through the contract method exactly as before.

Scope

staticCall has the same gap, but Seaport ignores the trailing bytes and returns the same result either way, so I left it alone rather than change something with no observable effect.

Testing

test/estimate-gas.spec.ts: one test asserts the estimate covers gasUsed on a tagged call, one does the same for an untagged call as a control. The first fails on main, the second passes either way. Suite green at 174.

When a domain is passed, getTransactionMethods appends its four byte tag to
the calldata inside buildTransaction, and transact sends exactly that. But
estimateGas called the contract method with the encoded arguments only, so
the tag was missing from what it measured.

Calldata is charged per byte, so the returned estimate lands below what the
transaction actually consumes. On a validate() call:

  estimateGas() -> 65562
  gasUsed       -> 65626

A caller passing the estimate straight through as a gas limit, which is the
normal reason to ask for one, runs out of gas.

Estimate the transaction buildTransaction produces whenever a domain is set,
so the measured calldata is the calldata that gets sent. Calls without a
domain keep going through the contract method unchanged.

staticCall has the same gap but no visible symptom, since Seaport ignores
the trailing bytes and returns the same result either way, so it is left
alone.
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