Skip to content

fix: ignore underpriced saved gas fee preferences - #9705

Merged
cloudonshore merged 2 commits into
fix/underpriced-dapp-gas-feesfrom
fix/underpriced-saved-gas-fees
Jul 30, 2026
Merged

fix: ignore underpriced saved gas fee preferences#9705
cloudonshore merged 2 commits into
fix/underpriced-dapp-gas-feesfrom
fix/underpriced-saved-gas-fees

Conversation

@cloudonshore

Copy link
Copy Markdown
Contributor

Note

Draft — there is a product decision to make here (see "The product decision" below). The mechanics are ready for review; the behavior on gate-fire (silently replace vs. replace + alert vs. warn-only) needs a product call before this leaves draft.

Explanation

Companion to #9704, which replaces underpriced dapp-suggested fees. This PR applies the same staleness gate to the other unguarded fee source: saved (advanced) gas fee preferences.

A saved custom preference is a static maxBaseFee captured at some point in the past. Network conditions move; the preference doesn't. Once the base fee rises past the saved value, every transaction priced from it is unlikely to be included before fee conditions change further, and typically ends up stuck as pending until timeout mechanisms mark it failed — with no actionable feedback. Unlike the dapp case, nothing else guards this source: #9704 deliberately excludes savedGasFees, and hasInitialGasFeeParams only protects transactions that carry explicit fee params (saved fees apply precisely when they don't).

This is increasingly relevant: clients are expanding saved-preference usage (e.g. per-account custom gas settings persisted from the confirmation flow, and #9682 extending saved fees to wallet-initiated transfers), which grows the surface a stale value can underprice.

Behavior (flag-gated, disabled by default):

  • After suggested fees are fetched, if the saved preference has a custom maxBaseFee below the current low estimate, the saved preference is ignored for this transaction and the suggested (medium) values are used instead.
  • Level-based saved preferences (low/medium/high) are never touched — they track current estimates by construction and are the recommended shape for persistent preferences.
  • userFeeLevel becomes medium instead of custom, which also opts the transaction into GasFeePoller refresh while unapproved.
  • Fail-open: flag off, non-EIP-1559, no low estimate, or no full replacement available → saved preference applies unchanged.
  • No fetch-path changes needed: transactions eligible for saved fees carry no fee params, so estimates (including the low level) are already fetched.

The product decision

Overriding a value the user saved is a stronger intervention than overriding a dapp's computed value, and there are three defensible behaviors when the gate fires:

  1. Silently use suggested fees (this PR's current behavior) — best transaction outcome, least transparency.
  2. Use suggested fees + surface an alert ("your saved gas setting is below current network fees; using market estimate") — same outcome, user learns their preference is stale.
  3. Keep the saved value + warn only — maximum autonomy, transaction remains likely to strand.

An argument that we should intervene (option 1 or 2) rather than defer entirely to the saved value: saved preferences already do not grant full autonomy. The controller already ignores them for swaps and bridges (SAVED_GAS_FEES_IGNORED_TRANSACTION_TYPES, #9401/#9682) — explicitly because a saved fee could underprice aggregator-priced transactions — and already yields them to explicit fee params (hasInitialGasFeeParams, #8993). The established principle is that saved preferences apply where they can work and yield where they would predictably break the transaction. A custom maxBaseFee below the current low estimate is the clearest possible instance of "would predictably break the transaction" — extending the same principle to it is consistent, not a new precedent.

The same known edge case as #9704 applies (fee bump vs. max-spend arithmetic); see the balance-clamp proposal there — it covers both gates.

References

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

@cloudonshore
cloudonshore merged commit 63124d2 into fix/underpriced-dapp-gas-fees Jul 30, 2026
105 of 122 checks passed
@cloudonshore
cloudonshore deleted the fix/underpriced-saved-gas-fees branch July 30, 2026 08:25
@cloudonshore

Copy link
Copy Markdown
Contributor Author

Note: this PR shows as "merged" because its base branch (#9704's branch) was fast-forwarded to include these commits — the two gates are now reviewed together in #9704, which also carries the product-decision section from this description.

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