Skip to content

Conversation

@khanti42
Copy link
Contributor

@khanti42 khanti42 commented Jan 13, 2026

Explanation

This PR fixes a UX issue where, in fully sponsored transactions involving the native token, the displayed balance change incorrectly included gas fees that were not actually paid by the user.

References

For testing and validation, please refer to this hotfix PR, which includes the same changes applied as a patch:
MetaMask/metamask-extension#39219

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

Note

Ensures native balance changes are accurate for gas‑sponsored transactions by excluding gas costs during simulation.

  • Fetch gasFeeTokens before simulation and determine isGasFeeSponsored in TransactionController
  • Pass isGasFeeSponsored to getBalanceChanges and set simulateTransactions withGas to false when sponsored
  • Simplify getSimulationBalanceChange to use state diffs directly (remove gas offset) and switch offset to BN
  • Update tests to assert isGasFeeSponsored plumbed through and correct balance diffs; add expectations for withGas behavior
  • Update CHANGELOG.md entry under Unreleased

Written by Cursor Bugbot for commit d5234ea. This will update automatically on new commits. Configure here.

@khanti42 khanti42 marked this pull request as ready for review January 14, 2026 13:33
@khanti42 khanti42 requested review from a team as code owners January 14, 2026 13:33
return getSimulationBalanceChange(
previousBalance,
newBalance,
transactionResponse.gasCost,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we not want to keep the gas cost in for non-sponsored here?

getSimulationConfig,
transactions,
withGas: true,
withGas: !request.isGasFeeSponsored,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We specify gas here to ensure a more accurate simulation that can't be as easily detected.

Why exactly would we not want that if sponsored if we mock the native balance below if insufficient?

offset: BN = new BN(0),
): SimulationBalanceChange | undefined {
const newBalanceBN = hexToBN(newBalance).add(new BN(offset));
const newBalanceBN = hexToBN(newBalance).add(offset);
Copy link
Member

@matthewwalsh0 matthewwalsh0 Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The purpose of this offset is to remove any gas costs from the native balance change.

Do we know why this calculation isn't working if sponsored?

Is that the root of the issue rather than the withGas option?

Is the gasCost property still correct?

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.

3 participants