harden: bound the total network fee by gasLimit × fee, on both send paths (closes #399) #411

Merged
clawbot merged 1 commits from issue-399-total-fee-bound into next 2026-09-21 21:45:35 +02:00
Collaborator

The two absolute fee ceilings in src/shared/approvalVerify.js were checked one field at a time, but the fee a validator is actually paid is the gas limit times the fee per gas. A gas limit and a fee that were each under their own ceiling still multiplied to thousands of ETH — a fee a gas-consuming contract really collects — so the stated backstop did not do what its own comment claimed.

assertWithinCeilings now also bounds that product against a new MAX_TOTAL_FEE constant of 1 ETH, set beside the existing ceilings. Both places that already call it — where the dApp transaction is populated (approvalTx.js) and where the signed artifact is verified — refuse an over-bound transaction with a full sentence naming the fee and the limit. The per-field ceilings are unchanged.

The wallet's own send in src/popup/views/confirmTx.js pinned no fee fields, so ethers filled them from whatever the configured node answered, with nothing bounding them. It now populates the transaction and runs the same check before signing, showing the same full-sentence error in the confirmation screen's existing reserved errors box, so nothing on screen moves.

What a reader should know: 1 ETH is a plain constant, one line to change; a full 30M-gas block at 33 gwei reaches it, which no ordinary transaction approaches. Comparing a supplied fee against the node's own suggested fee is deliberately out of scope, as the plan on #399 records — the absolute bound already closes the balance-draining case.

Tests drive both paths with a fee within each field's ceiling but over the product bound (refused) and just under it (accepted).

Model: opus-4-8

The two absolute fee ceilings in `src/shared/approvalVerify.js` were checked one field at a time, but the fee a validator is actually paid is the gas limit times the fee per gas. A gas limit and a fee that were each under their own ceiling still multiplied to thousands of ETH — a fee a gas-consuming contract really collects — so the stated backstop did not do what its own comment claimed. `assertWithinCeilings` now also bounds that product against a new `MAX_TOTAL_FEE` constant of 1 ETH, set beside the existing ceilings. Both places that already call it — where the dApp transaction is populated (`approvalTx.js`) and where the signed artifact is verified — refuse an over-bound transaction with a full sentence naming the fee and the limit. The per-field ceilings are unchanged. The wallet's own send in `src/popup/views/confirmTx.js` pinned no fee fields, so ethers filled them from whatever the configured node answered, with nothing bounding them. It now populates the transaction and runs the same check before signing, showing the same full-sentence error in the confirmation screen's existing reserved errors box, so nothing on screen moves. What a reader should know: 1 ETH is a plain constant, one line to change; a full 30M-gas block at 33 gwei reaches it, which no ordinary transaction approaches. Comparing a supplied fee against the node's own suggested fee is deliberately out of scope, as the plan on https://git.eeqj.de/sneak/AutistMask/issues/399 records — the absolute bound already closes the balance-draining case. Tests drive both paths with a fee within each field's ceiling but over the product bound (refused) and just under it (accepted). Model: opus-4-8
clawbot added 1 commit 2026-09-21 21:13:33 +02:00
harden: bound the total network fee by gasLimit × fee, on both send paths (closes #399)
e2e / e2e-chrome (push) Failing after 1s
e2e / e2e-firefox (push) Failing after 0s
check / check (push) Successful in 1m4s
dfd197b93b
The two per-field ceilings in approvalVerify.js were checked independently,
but the fee a validator is paid is gasLimit × fee per gas: a gas limit and a
fee each under their own ceiling still multiply to thousands of ETH, which a
gas-consuming contract really collects. assertWithinCeilings now also bounds
that product against MAX_TOTAL_FEE (1 ETH), so both callers — populating the
dApp transaction and verifying the signed artifact — refuse it with a full
sentence naming the fee and the limit.

The wallet's own send in confirmTx.js pinned no fee fields, so ethers filled
them from the node with no bound; it now populates the transaction and runs the
same check before signing, showing the same error in the confirmation screen's
reserved errors box so nothing on screen moves.

Model: opus-4-8
clawbot added the needs-review label 2026-09-21 21:13:42 +02:00
clawbot self-assigned this 2026-09-21 21:13:42 +02:00
clawbot added this to the 1.0.0 milestone 2026-09-21 21:13:43 +02:00
Author
Collaborator

PASS — the combined bound (gas limit times fee per gas, or gas price for a type 0/1 transaction) is enforced where the dApp transaction is populated, where the signed artifact is verified, and on the wallet's own send in src/popup/views/confirmTx.js before signing; each path's tests fail when the check is removed, an over-bound fee is refused with a full-sentence message in the confirmation screen's reserved (min-height) errors box so nothing on screen moves, missing/type-2 versus legacy fee fields are handled without integer mistakes, and my make check is green on the branch rebased onto the current next.

Model: opus-4-8

PASS — the combined bound (gas limit times fee per gas, or gas price for a type 0/1 transaction) is enforced where the dApp transaction is populated, where the signed artifact is verified, and on the wallet's own send in `src/popup/views/confirmTx.js` before signing; each path's tests fail when the check is removed, an over-bound fee is refused with a full-sentence message in the confirmation screen's reserved (min-height) errors box so nothing on screen moves, missing/type-2 versus legacy fee fields are handled without integer mistakes, and my `make check` is green on the branch rebased onto the current `next`. Model: opus-4-8
clawbot merged commit 33fa25adca into next 2026-09-21 21:45:35 +02:00
clawbot deleted branch issue-399-total-fee-bound 2026-09-21 21:45:35 +02:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/AutistMask#411