fix: require EIP-7702 for direct mUSD vault batches#9240
Merged
Conversation
10 tasks
5994deb to
ebd0f54
Compare
OGPoyraz
approved these changes
Jun 24, 2026
runway-github Bot
added a commit
to MetaMask/metamask-mobile
that referenced
this pull request
Jun 24, 2026
…32253) ## **Description** Sponsored and gas-included transaction publishing depends on the EIP-7702 delegation relay path. Previously, when atomic EIP-7702 support was unavailable for the selected chain, the delegation publish hook returned an empty result, which allowed the publish pipeline to continue to later publication paths. This PR makes that path fail closed for sponsored and gas-included transactions by throwing a clear error when the chain does not support EIP-7702 atomic batching. Non-sponsored transactions keep the existing empty-result behavior when EIP-7702 is unavailable. ## **Changelog** CHANGELOG entry: Fixed sponsored and gas-included transactions falling back when EIP-7702 support is unavailable ## **Related issues** Refs: MetaMask/core#9240 ## **Manual testing steps** N/A - covered by unit tests for the transaction publish hook. ## **Screenshots/Recordings** N/A ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes transaction publish behavior for gas-sponsored and gas-included flows on chains without EIP-7702, blocking unsafe fallbacks instead of silently continuing. > > **Overview** > **Sponsored** and **gas-included** publishes must use the EIP-7702 delegation relay. When atomic batch support is missing for the chain, `Delegation7702PublishHook` used to return an empty result so later publish hooks could run. > > This change **throws** for `isGasFeeSponsored` or `isGasFeeIncluded` when the chain is not EIP-7702-capable, with a clear error (prefixed as `Gas Station 7702:`). Regular transactions still get the empty result and can fall through. > > Gas flags are normalized earlier (`Boolean` on `isGasFeeIncluded` / `isGasFeeSponsored`) and `includeTransfer` now keys off the same `isSponsored` flag. Unit tests cover sponsored and gas-included cases when atomic batch is unsupported. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 4e5dfa7. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
runway-github Bot
added a commit
to MetaMask/metamask-mobile
that referenced
this pull request
Jun 24, 2026
…32253) ## **Description** Sponsored and gas-included transaction publishing depends on the EIP-7702 delegation relay path. Previously, when atomic EIP-7702 support was unavailable for the selected chain, the delegation publish hook returned an empty result, which allowed the publish pipeline to continue to later publication paths. This PR makes that path fail closed for sponsored and gas-included transactions by throwing a clear error when the chain does not support EIP-7702 atomic batching. Non-sponsored transactions keep the existing empty-result behavior when EIP-7702 is unavailable. ## **Changelog** CHANGELOG entry: Fixed sponsored and gas-included transactions falling back when EIP-7702 support is unavailable ## **Related issues** Refs: MetaMask/core#9240 ## **Manual testing steps** N/A - covered by unit tests for the transaction publish hook. ## **Screenshots/Recordings** N/A ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes transaction publish behavior for gas-sponsored and gas-included flows on chains without EIP-7702, blocking unsafe fallbacks instead of silently continuing. > > **Overview** > **Sponsored** and **gas-included** publishes must use the EIP-7702 delegation relay. When atomic batch support is missing for the chain, `Delegation7702PublishHook` used to return an empty result so later publish hooks could run. > > This change **throws** for `isGasFeeSponsored` or `isGasFeeIncluded` when the chain is not EIP-7702-capable, with a clear error (prefixed as `Gas Station 7702:`). Regular transactions still get the empty result and can fall through. > > Gas flags are normalized earlier (`Boolean` on `isGasFeeIncluded` / `isGasFeeSponsored`) and `includeTransfer` now keys off the same `isSponsored` flag. Unit tests cover sponsored and gas-included cases when atomic batch is unsupported. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 4e5dfa7. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
runway-github Bot
pushed a commit
to MetaMask/metamask-mobile
that referenced
this pull request
Jun 24, 2026
…ed gas transactions (#32253) ## **Description** Sponsored and gas-included transaction publishing depends on the EIP-7702 delegation relay path. Previously, when atomic EIP-7702 support was unavailable for the selected chain, the delegation publish hook returned an empty result, which allowed the publish pipeline to continue to later publication paths. This PR makes that path fail closed for sponsored and gas-included transactions by throwing a clear error when the chain does not support EIP-7702 atomic batching. Non-sponsored transactions keep the existing empty-result behavior when EIP-7702 is unavailable. ## **Changelog** CHANGELOG entry: Fixed sponsored and gas-included transactions falling back when EIP-7702 support is unavailable ## **Related issues** Refs: MetaMask/core#9240 ## **Manual testing steps** N/A - covered by unit tests for the transaction publish hook. ## **Screenshots/Recordings** N/A ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes transaction publish behavior for gas-sponsored and gas-included flows on chains without EIP-7702, blocking unsafe fallbacks instead of silently continuing. > > **Overview** > **Sponsored** and **gas-included** publishes must use the EIP-7702 delegation relay. When atomic batch support is missing for the chain, `Delegation7702PublishHook` used to return an empty result so later publish hooks could run. > > This change **throws** for `isGasFeeSponsored` or `isGasFeeIncluded` when the chain is not EIP-7702-capable, with a clear error (prefixed as `Gas Station 7702:`). Regular transactions still get the empty result and can fall through. > > Gas flags are normalized earlier (`Boolean` on `isGasFeeIncluded` / `isGasFeeSponsored`) and `includeTransfer` now keys off the same `isSponsored` flag. Unit tests cover sponsored and gas-included cases when atomic batch is unsupported. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 4e5dfa7. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
10 tasks
pull Bot
pushed a commit
to Reality2byte/metamask-mobile
that referenced
this pull request
Jun 24, 2026
…sk#32253) ## **Description** Sponsored and gas-included transaction publishing depends on the EIP-7702 delegation relay path. Previously, when atomic EIP-7702 support was unavailable for the selected chain, the delegation publish hook returned an empty result, which allowed the publish pipeline to continue to later publication paths. This PR makes that path fail closed for sponsored and gas-included transactions by throwing a clear error when the chain does not support EIP-7702 atomic batching. Non-sponsored transactions keep the existing empty-result behavior when EIP-7702 is unavailable. ## **Changelog** CHANGELOG entry: Fixed sponsored and gas-included transactions falling back when EIP-7702 support is unavailable ## **Related issues** Refs: MetaMask/core#9240 ## **Manual testing steps** N/A - covered by unit tests for the transaction publish hook. ## **Screenshots/Recordings** N/A ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes transaction publish behavior for gas-sponsored and gas-included flows on chains without EIP-7702, blocking unsafe fallbacks instead of silently continuing. > > **Overview** > **Sponsored** and **gas-included** publishes must use the EIP-7702 delegation relay. When atomic batch support is missing for the chain, `Delegation7702PublishHook` used to return an empty result so later publish hooks could run. > > This change **throws** for `isGasFeeSponsored` or `isGasFeeIncluded` when the chain is not EIP-7702-capable, with a clear error (prefixed as `Gas Station 7702:`). Regular transactions still get the empty result and can fall through. > > Gas flags are normalized earlier (`Boolean` on `isGasFeeIncluded` / `isGasFeeSponsored`) and `includeTransfer` now keys off the same `isSponsored` flag. Unit tests cover sponsored and gas-included cases when atomic batch is unsupported. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 4e5dfa7. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
pull Bot
pushed a commit
to Reality2byte/core
that referenced
this pull request
Jun 24, 2026
…ct mUSD vault deposits (MetaMask#9250) ## Summary Adds `disableUpgrade: true` to the `addTransactionBatch` call in the direct mUSD Money Account vault deposit path. The Money Account is always already upgraded to EIP-7702 on Monad, so the upgrade check (`isAccountUpgradedToEIP7702`) is unnecessary and adds latency. This skips it entirely. Also updates the test assertion to explicitly verify `disableHook: true`, `disableSequential: true`, and `disableUpgrade: true` are passed to the batch. ## Related Builds on top of MetaMask#9240 (`disableHook: true`, `disableSequential: true`, `finally` block for `end()`). <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Narrow change to batch submission flags on a fiat path that already assumes a pre-upgraded Money Account; wrong assumption would only affect this deposit flow. > > **Overview** > Direct mUSD Money Account vault deposits now pass **`disableUpgrade: true`** on `TransactionController:addTransactionBatch`, alongside the existing `disableHook` and `disableSequential` flags. That skips the redundant EIP-7702 upgrade probe (`isAccountUpgradedToEIP7702`) because the Money Account is already upgraded on Monad. > > The direct mUSD vault test now asserts all three batch options explicitly, and the changelog records the fix under **Fixed**. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 84d28a3. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
sleepytanya
pushed a commit
to MetaMask/metamask-mobile
that referenced
this pull request
Jun 24, 2026
…ed gas transactions (#32307) - fix: cp-8.0.0 require EIP-7702 for sponsored gas transactions (#32253) ## **Description** Sponsored and gas-included transaction publishing depends on the EIP-7702 delegation relay path. Previously, when atomic EIP-7702 support was unavailable for the selected chain, the delegation publish hook returned an empty result, which allowed the publish pipeline to continue to later publication paths. This PR makes that path fail closed for sponsored and gas-included transactions by throwing a clear error when the chain does not support EIP-7702 atomic batching. Non-sponsored transactions keep the existing empty-result behavior when EIP-7702 is unavailable. ## **Changelog** CHANGELOG entry: Fixed sponsored and gas-included transactions falling back when EIP-7702 support is unavailable ## **Related issues** Refs: MetaMask/core#9240 ## **Manual testing steps** N/A - covered by unit tests for the transaction publish hook. ## **Screenshots/Recordings** N/A ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes transaction publish behavior for gas-sponsored and gas-included flows on chains without EIP-7702, blocking unsafe fallbacks instead of silently continuing. > > **Overview** > **Sponsored** and **gas-included** publishes must use the EIP-7702 delegation relay. When atomic batch support is missing for the chain, `Delegation7702PublishHook` used to return an empty result so later publish hooks could run. > > This change **throws** for `isGasFeeSponsored` or `isGasFeeIncluded` when the chain is not EIP-7702-capable, with a clear error (prefixed as `Gas Station 7702:`). Regular transactions still get the empty result and can fall through. > > Gas flags are normalized earlier (`Boolean` on `isGasFeeIncluded` / `isGasFeeSponsored`) and `includeTransfer` now keys off the same `isSponsored` flag. Unit tests cover sponsored and gas-included cases when atomic batch is unsupported. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 4e5dfa7. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [48adf87](48adf87) Co-authored-by: Matthew Walsh <matthew.walsh@consensys.net>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Explanation
Direct mUSD Money Account vault submission is intended to be an EIP-7702-only flow: the refreshed vault approve/deposit calls need to remain a sponsored atomic batch instead of being materialized as standalone child transactions. TransactionController previously preferred EIP-7702, but callers that depended on that path could still fall back to hook or sequential batch publishing when EIP-7702 was unavailable.
This PR makes that contract explicit.
TransactionPayControllersubmits direct mUSD vault batches with hook and sequential fallbacks disabled, whileTransactionControllernow fails closed for those EIP-7702-only batch requests when account or chain support is unavailable. The direct mUSD submit path also always stops collecting submitted transaction IDs after the batch attempt completes, preventing later retries from being associated with a failed parent transaction.References
Checklist
Note
Medium Risk
Changes batch routing and error behavior for EIP-7702-only internal flows (mUSD vault); incorrect handling could block deposits or leave stale transaction associations, but scope is limited to callers using both disable flags.
Overview
Direct mUSD vault deposits are now EIP-7702-only:
TransactionPayControllerpassesdisableHook: trueanddisableSequential: trueonaddTransactionBatch, so approve/deposit stay a sponsored atomic batch instead of falling back to hook or sequential publishing.TransactionController treats that flag combination as fail-closed: it throws when the account cannot use EIP-7702, and it no longer swallows a Chain does not support EIP-7702 error to continue on the hook path. Tests cover both account and chain rejection without creating transactions.
The direct mUSD submit path moves
end()for transaction-ID collection into afinallyblock so collection always stops after the batch attempt, including on failure—avoiding stray IDs on retries.Reviewed by Cursor Bugbot for commit c5e597d. Bugbot is set up for automated code reviews on this repo. Configure here.