Skip to content

chore(runway): cherry-pick fix: prevent infinite quote request loop caused by token warning in unified swaps context cp-7.73.0#28366

Merged
chloeYue merged 1 commit into
release/7.73.0from
runway-cherry-pick-7.73.0-1775166539
Apr 3, 2026
Merged

chore(runway): cherry-pick fix: prevent infinite quote request loop caused by token warning in unified swaps context cp-7.73.0#28366
chloeYue merged 1 commit into
release/7.73.0from
runway-cherry-pick-7.73.0-1775166539

Conversation

@runway-github

@runway-github runway-github Bot commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

Description

When a destination token has a security warning (e.g. a Blockaid
malicious/suspicious flag), the unified swaps bridge view was entering
an infinite quote request loop.

Root cause: tokenWarning was included as a dependency of the
useMemo that builds the analytics context object in
useUnifiedSwapBridgeContext. tokenWarning is itself derived from
quote results (blockaid data returned by the bridge controller). This
created a feedback cycle:

Quote fetched → tokenWarning updates → context object recreates
→ updateQuoteParams identity changes → useEffect fires
→ new quote request → repeat ∞

Fix: Remove tokenWarning from the useMemo dependency array and
clear security_warnings to [] for now. The security_warnings field
will be populated properly in the bridge controller instead, removing
the React dependency cycle entirely.

Changelog

CHANGELOG entry: Fixed a bug that caused repeated quote requests when
swapping to a token with a security warning.

Related issues

Fixes:

Manual testing steps

Feature: Unified Swaps/Bridge quote fetching with token warnings

  Scenario: user swaps to a token with a Blockaid security warning
    Given the user has opened the Swap/Bridge screen
    And the user has selected a source token with sufficient balance

    When the user selects a destination token that has a Blockaid security warning
    And the user enters a valid source amount
    Then the app fetches a quote once
    And does not repeatedly fire additional quote requests
    And the security warning banner is displayed on screen

  Scenario: user swaps to a normal token (no warning)
    Given the user has opened the Swap/Bridge screen
    And the user has selected a source token with sufficient balance

    When the user selects a destination token with no security warning
    And the user enters a valid source amount
    Then the app fetches a quote once
    And quote results are displayed normally

Screenshots/Recordings

Before

N/A

After

Uploading Screen Recording 2026-04-02 at 4.24.51 PM.mov…

Pre-merge author checklist

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.

Note

Low Risk
Low risk: small change limited to analytics context memoization, but
it temporarily drops security_warnings data which could affect
warning-related telemetry until re-populated elsewhere.

Overview
Prevents an infinite bridge quote re-fetch loop by removing
destination token warning state from useUnifiedSwapBridgeContext’s
memoized context object.

security_warnings is now always an empty array (TODO) and the
useMemo dependency list no longer includes the warning selector,
stabilizing the context identity passed into
BridgeController.updateBridgeQuoteRequestParams.

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

[b155157](https://github.com/MetaMask/metamask-mobile/commit/b1551575dc9eb1bb434a30fcbd7fa6788d37b1ff)

…aused by token warning in unified swaps context cp-7.73.0 (#28361)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

When a destination token has a security warning (e.g. a Blockaid
malicious/suspicious flag), the unified swaps bridge view was entering
an infinite quote request loop.

**Root cause:** `tokenWarning` was included as a dependency of the
`useMemo` that builds the analytics `context` object in
`useUnifiedSwapBridgeContext`. `tokenWarning` is itself derived from
quote results (blockaid data returned by the bridge controller). This
created a feedback cycle:

```
Quote fetched → tokenWarning updates → context object recreates
→ updateQuoteParams identity changes → useEffect fires
→ new quote request → repeat ∞
```

**Fix:** Remove `tokenWarning` from the `useMemo` dependency array and
clear `security_warnings` to `[]` for now. The `security_warnings` field
will be populated properly in the bridge controller instead, removing
the React dependency cycle entirely.

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: Fixed a bug that caused repeated quote requests when
swapping to a token with a security warning.

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: Unified Swaps/Bridge quote fetching with token warnings

  Scenario: user swaps to a token with a Blockaid security warning
    Given the user has opened the Swap/Bridge screen
    And the user has selected a source token with sufficient balance

    When the user selects a destination token that has a Blockaid security warning
    And the user enters a valid source amount
    Then the app fetches a quote once
    And does not repeatedly fire additional quote requests
    And the security warning banner is displayed on screen

  Scenario: user swaps to a normal token (no warning)
    Given the user has opened the Swap/Bridge screen
    And the user has selected a source token with sufficient balance

    When the user selects a destination token with no security warning
    And the user enters a valid source amount
    Then the app fetches a quote once
    And quote results are displayed normally
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

N/A

### **After**


Uploading Screen Recording 2026-04-02 at 4.24.51 PM.mov…



## **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.

## **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.

<!-- Generated with the help of the pr-description AI skill -->

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: small change limited to analytics context memoization, but
it temporarily drops `security_warnings` data which could affect
warning-related telemetry until re-populated elsewhere.
> 
> **Overview**
> Prevents an infinite bridge quote re-fetch loop by removing
destination token warning state from `useUnifiedSwapBridgeContext`’s
memoized context object.
> 
> `security_warnings` is now always an empty array (*TODO*) and the
`useMemo` dependency list no longer includes the warning selector,
stabilizing the `context` identity passed into
`BridgeController.updateBridgeQuoteRequestParams`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
21dec81. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@runway-github runway-github Bot requested a review from a team as a code owner April 2, 2026 21:49
@github-actions

github-actions Bot commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the team-bots Bot team (for MetaMask Bot, Runway Bot, etc.) label Apr 2, 2026
@github-actions github-actions Bot added size-S risk-low Low testing needed · Low bug introduction risk labels Apr 2, 2026

@chloeYue chloeYue left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

@chloeYue chloeYue added the skip-smart-e2e-selection Skip Smart E2E selection, i.e. select all E2E tests to run label Apr 3, 2026
@github-actions github-actions Bot added risk-high Extensive testing required · High bug introduction risk and removed risk-low Low testing needed · Low bug introduction risk labels Apr 3, 2026
@github-actions

github-actions Bot commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

⏭️ Smart E2E selection skipped - skip-smart-e2e-selection label found

All E2E tests pre-selected.

View GitHub Actions results

@sonarqubecloud

sonarqubecloud Bot commented Apr 3, 2026

Copy link
Copy Markdown

@chloeYue

chloeYue commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

@metamaskbot update-mobile-fixture

1 similar comment
@chloeYue

chloeYue commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

@metamaskbot update-mobile-fixture

@github-actions

github-actions Bot commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

E2E Fixture Validation — Schema is up to date
17 value mismatches detected (expected — fixture represents an existing user).
View details

@chloeYue chloeYue merged commit 5bbfcec into release/7.73.0 Apr 3, 2026
314 of 319 checks passed
@chloeYue chloeYue deleted the runway-cherry-pick-7.73.0-1775166539 branch April 3, 2026 08:07
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 3, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

risk-high Extensive testing required · High bug introduction risk size-S skip-smart-e2e-selection Skip Smart E2E selection, i.e. select all E2E tests to run team-bots Bot team (for MetaMask Bot, Runway Bot, etc.)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants