decision: a dApp-supplied gas limit is silently dropped, so the popup always re-estimates #207

Closed
opened 2026-08-11 14:28:48 +02:00 by clawbot · 2 comments
Collaborator

A gas field supplied by a dApp in eth_sendTransaction is discarded by ethers' copyRequest, so the popup always estimates the gas limit itself and the dApp's value never reaches the signed transaction.

Consequence: a dApp that deliberately raises the gas limit — common for contract calls whose estimate is unreliable, and for flows that would otherwise fail with out-of-gas — is silently overridden. The user sees no indication that the site asked for something different from what will be signed.

This is also why #174 does not compare the gas limit between approval and signature: there is nothing stable to compare. Honouring the request would let that field be verified for real, which is the stronger position.

Found while implementing #174; deliberately not fixed there.

Options

  • (a) Honour a dApp-supplied gas, subject to a sanity ceiling, display it on the approval screen, and compare it in approvalVerify. Most correct and most compatible; the gas limit becomes a verified field rather than an unverifiable one.
  • (b) Keep re-estimating, but disclose it — show on the approval screen that the site's requested gas limit was replaced, and with what.
  • (c) Keep the current silent behaviour.

Recommendation

(a). A wallet silently changing a transaction parameter the site asked for is the same category of problem the approval screen exists to prevent, and it currently leaves a consequential field permanently outside verification. (b) is honest but still breaks the dApp's intent. (c) leaves both the compatibility gap and the verification hole.

Assigning to you: this changes what the wallet signs relative to what a site requested, which is a product decision rather than a defect fix.

A `gas` field supplied by a dApp in `eth_sendTransaction` is discarded by ethers' `copyRequest`, so the popup always estimates the gas limit itself and the dApp's value never reaches the signed transaction. Consequence: a dApp that deliberately raises the gas limit — common for contract calls whose estimate is unreliable, and for flows that would otherwise fail with out-of-gas — is silently overridden. The user sees no indication that the site asked for something different from what will be signed. This is also why https://git.eeqj.de/sneak/AutistMask/issues/174 does not compare the gas limit between approval and signature: there is nothing stable to compare. Honouring the request would let that field be verified for real, which is the stronger position. Found while implementing https://git.eeqj.de/sneak/AutistMask/issues/174; deliberately not fixed there. ## Options - **(a) Honour a dApp-supplied `gas`**, subject to a sanity ceiling, display it on the approval screen, and compare it in `approvalVerify`. Most correct and most compatible; the gas limit becomes a verified field rather than an unverifiable one. - **(b) Keep re-estimating, but disclose it** — show on the approval screen that the site's requested gas limit was replaced, and with what. - **(c) Keep the current silent behaviour.** ## Recommendation **(a).** A wallet silently changing a transaction parameter the site asked for is the same category of problem the approval screen exists to prevent, and it currently leaves a consequential field permanently outside verification. (b) is honest but still breaks the dApp's intent. (c) leaves both the compatibility gap and the verification hole. Assigning to you: this changes what the wallet signs relative to what a site requested, which is a product decision rather than a defect fix.
sneak was assigned by clawbot 2026-08-11 14:28:48 +02:00
Author
Collaborator

Settled as recommended, option (a), and it turns out to be a small fix. The wallet already honours a site's gas limit when the request names it gasLimit: it is shown on the approval screen, held to the 100,000,000 ceiling, and compared with the signed transaction. What gets dropped is the field under its JSON-RPC name, gas, which is what sites send. Reading the field the specification defines is a defect fix, not a product change.

Plan: in src/shared/approvalTx.js, take a request's gas as its gas limit; a request carrying both gas and gasLimit with different values is refused with a full sentence. The existing ceiling, display and comparison then cover it. Tests: a site-supplied gas reaches the approval screen and the signed transaction; disagreeing fields are refused. README.md's TxApproval section says the site's gas limit is used when it gives one.

Model: opus-5-5

Settled as recommended, option (a), and it turns out to be a small fix. The wallet already honours a site's gas limit when the request names it `gasLimit`: it is shown on the approval screen, held to the 100,000,000 ceiling, and compared with the signed transaction. What gets dropped is the field under its JSON-RPC name, `gas`, which is what sites send. Reading the field the specification defines is a defect fix, not a product change. Plan: in `src/shared/approvalTx.js`, take a request's `gas` as its gas limit; a request carrying both `gas` and `gasLimit` with different values is refused with a full sentence. The existing ceiling, display and comparison then cover it. Tests: a site-supplied `gas` reaches the approval screen and the signed transaction; disagreeing fields are refused. `README.md`'s TxApproval section says the site's gas limit is used when it gives one. Model: opus-5-5
sneak was unassigned by clawbot 2026-10-14 03:59:19 +02:00
clawbot self-assigned this 2026-10-14 03:59:19 +02:00
Author
Collaborator

Built as planned in #543: a site's gas is now taken as the gas limit, and a request giving gas and gasLimit with different values is refused. One thing to know: with a gas limit supplied, ethers skips the gas estimate, so a call that would revert is no longer refused before the approval window opens. That was already true for gasLimit.

Model: opus-5-5

Built as planned in https://git.eeqj.de/sneak/AutistMask/pulls/543: a site's `gas` is now taken as the gas limit, and a request giving `gas` and `gasLimit` with different values is refused. One thing to know: with a gas limit supplied, ethers skips the gas estimate, so a call that would revert is no longer refused before the approval window opens. That was already true for `gasLimit`. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/AutistMask#207