Skip to content

release(runway): cherry-pick fix: swaps stale dest exchange rates - #45011

Merged
sleepytanya merged 2 commits into
release/13.42.0from
cherry-pick-13-42-0-c1a5d29
Jul 30, 2026
Merged

sleepytanya merged 2 commits into
release/13.42.0from
cherry-pick-13-42-0-c1a5d29

Conversation

@runway-github

@runway-github runway-github Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Description

Removes condition that prevents fetching token prices when cached values
exist in the asset controller states. Token prices will now be fetched
on each quote fetch to prevent displaying stale fiat amounts

Changelog

CHANGELOG entry: chore: bump bridge controllers to fix stale dest
exchange rates

Related issues

Fixes https://consensyssoftware.atlassian.net/browse/SWAPS-4851

Manual testing steps

Feature: swap destination amount price

  Scenario: user requests a USDC->ETH quote
    Given they get a quote

    When user switches the assets (note the dest fiat amount)
    Then the src fiat amount matches the previous dest amount
    When user switches the assets again (note the dest fiat amount)
    Then the src fiat amount matches the previous dest amount

Screenshots/Recordings

Before

After

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

Medium Risk
Changes swap/bridge pricing behavior and controller messenger
permissions; impact is localized to bridge UI and exchange-rate
fetching, but incorrect rates would mislead users on fiat amounts.

Overview
Fixes stale destination fiat amounts when swapping by always
refreshing source-token exchange rates instead of reusing cached market
data.

useBridgeExchangeRates now dispatches setSrcTokenExchangeRates
whenever a source token is selected, removing the guard that skipped the
fetch when exchangeRateFromMarketData already had a value.

Bridge controller packages are bumped
(@metamask/bridge-controller 78.0.1,
@metamask/bridge-status-controller 74.6.0), with related
transitive updates (keyring-api, keyring-utils). The bridge
controller messenger stops delegating
TokenRatesController:getState and
MultichainAssetsRatesController:getState, aligning with the updated
controllers’ use of AssetsController:getExchangeRatesForBridge.

LavaMoat webpack policies are updated for the
@metamask/keyring-api>@metamask/keyring-utils dependency path.

Reviewed by Cursor Bugbot for commit
3df4a4d. Bugbot is set up for automated
code reviews on this repo. Configure
here.


Co-authored-by: MetaMask Bot metamaskbot@users.noreply.github.com c1a5d29

<!--
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.
-->

Removes condition that prevents fetching token prices when cached values
exist in the asset controller states. Token prices will now be fetched
on each quote fetch to prevent displaying stale fiat amounts

<!--
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?
-->

<!--
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: chore: bump bridge controllers to fix stale dest
exchange rates

Fixes https://consensyssoftware.atlassian.net/browse/SWAPS-4851

```gherkin
Feature: swap destination amount price

  Scenario: user requests a USDC->ETH quote
    Given they get a quote

    When user switches the assets (note the dest fiat amount)
    Then the src fiat amount matches the previous dest amount
    When user switches the assets again (note the dest fiat amount)
    Then the src fiat amount matches the previous dest amount

```

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

<!-- [screenshots/recordings] -->

<!-- [screenshots/recordings] -->

- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

- [ ] 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 swap/bridge pricing behavior and controller messenger
permissions; impact is localized to bridge UI and exchange-rate
fetching, but incorrect rates would mislead users on fiat amounts.
>
> **Overview**
> Fixes **stale destination fiat amounts** when swapping by always
refreshing source-token exchange rates instead of reusing cached market
data.
>
> **`useBridgeExchangeRates`** now dispatches `setSrcTokenExchangeRates`
whenever a source token is selected, removing the guard that skipped the
fetch when `exchangeRateFromMarketData` already had a value.
>
> **Bridge controller packages** are bumped
(`@metamask/bridge-controller` **78.0.1**,
`@metamask/bridge-status-controller` **74.6.0**), with related
transitive updates (`keyring-api`, `keyring-utils`). The bridge
controller messenger **stops delegating**
`TokenRatesController:getState` and
`MultichainAssetsRatesController:getState`, aligning with the updated
controllers’ use of **`AssetsController:getExchangeRatesForBridge`**.
>
> LavaMoat webpack policies are updated for the
**`@metamask/keyring-api>@metamask/keyring-utils`** dependency path.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
3df4a4d. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com>
@runway-github
runway-github Bot requested review from a team as code owners July 29, 2026 23:47
@metamask-ci metamask-ci Bot added the team-bots Bot team (for MetaMask Bot, Runway Bot, etc.) label Jul 29, 2026
sleepytanya
sleepytanya previously approved these changes Jul 29, 2026
@sleepytanya
sleepytanya enabled auto-merge (squash) July 29, 2026 23:52
@sonarqubecloud

Copy link
Copy Markdown

@metamask-ci

metamask-ci Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor
Builds ready [31a60bd]
⚡ Performance Benchmarks (Total: 🟢 18 pass · 🟡 5 warn · 🔴 0 fail)

Baseline (latest main): 171ed20 | Date: 7/28/2026 | Pipeline: 30501615666 | Baseline logs

Interaction Benchmarks · Samples: 5
Benchmarkchrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
confirmTx
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
bridgeUserActions
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]

📈 Results compared to the previous 5 runs on main

  • ↑ bridgeUserActions/bridge_load_page: +110%
  • ↓ bridgeUserActions/bridge_load_asset_picker: -12%
  • ↑ bridgeUserActions/longTaskCount: +11%
  • ↑ bridgeUserActions/inp: +15%
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]

📈 Results compared to the previous 5 runs on main

  • ↓ startupStandardHome/domInteractive: -29%
  • ↓ startupStandardHome/fcp: -26%
User Journey Benchmarks · Samples: 5 · mock API
Benchmarkchrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
onboardingNewWallet
[Sentry log · main/release]
🟢 [CI log]
🔴 total
🟡 [CI log]
🟡 total
assetDetails
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
solanaAssetDetails
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
importSrpHome
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
sendTransactions
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
swap
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • ↓ onboardingImportWallet/srpButtonToSrpForm: -10%
  • ↓ onboardingImportWallet/confirmSrpToPwForm: -16%
  • ↓ onboardingImportWallet/pwFormToMetricsScreen: -26%
  • ↓ onboardingImportWallet/metricsToWalletReadyScreen: -26%
  • ↓ onboardingImportWallet/doneButtonToHomeScreen: -87%
  • ↓ onboardingImportWallet/openAccountMenuToAccountListLoaded: -77%
  • ↓ onboardingImportWallet/longTaskCount: -100%
  • ↓ onboardingImportWallet/longTaskTotalDuration: -100%
  • ↓ onboardingImportWallet/longTaskMaxDuration: -100%
  • ↓ onboardingImportWallet/tbt: -100%
  • ↓ onboardingImportWallet/total: -87%
  • ↓ onboardingNewWallet/srpButtonToPwForm: -12%
  • ↓ onboardingNewWallet/agreeButtonToOnboardingSuccess: -15%
  • ↓ onboardingNewWallet/longTaskCount: -69%
  • ↓ onboardingNewWallet/longTaskTotalDuration: -75%
  • ↓ onboardingNewWallet/longTaskMaxDuration: -42%
  • ↓ onboardingNewWallet/tbt: -88%
  • ↓ solanaAssetDetails/assetClickToPriceChart: -41%
  • ↓ solanaAssetDetails/longTaskCount: -100%
  • ↓ solanaAssetDetails/longTaskTotalDuration: -100%
  • ↓ solanaAssetDetails/longTaskMaxDuration: -100%
  • ↓ solanaAssetDetails/tbt: -100%
  • ↓ solanaAssetDetails/total: -41%
  • ↑ solanaAssetDetails/fcp: +12%
  • ↓ importSrpHome/loginToHomeScreen: -35%
  • ↓ importSrpHome/homeAfterImportWithNewWallet: -58%
  • ↓ importSrpHome/longTaskCount: -65%
  • ↓ importSrpHome/longTaskTotalDuration: -65%
  • ↓ importSrpHome/longTaskMaxDuration: -28%
  • ↓ importSrpHome/tbt: -65%
  • ↓ importSrpHome/total: -54%
  • ↓ importSrpHome/inp: -38%
  • ↓ importSrpHome/fcp: -23%
  • ↓ importSrpHome/lcp: -10%
  • ↓ importSrpHome/cls: -15%
  • ↓ sendTransactions/openSendPageFromHome: -36%
  • ↓ sendTransactions/selectTokenToSendFormLoaded: -12%
  • ↓ sendTransactions/reviewTransactionToConfirmationPage: -98%
  • ↓ sendTransactions/longTaskCount: -100%
  • ↓ sendTransactions/longTaskTotalDuration: -100%
  • ↓ sendTransactions/longTaskMaxDuration: -100%
  • ↓ sendTransactions/tbt: -100%
  • ↓ sendTransactions/total: -96%
  • ↓ sendTransactions/inp: -26%
  • ↓ sendTransactions/lcp: -63%
  • ↑ sendTransactions/cls: +171%
  • ↓ swap/openSwapPageFromHome: -31%
  • ↑ swap/fetchAndDisplaySwapQuotes: +85%
  • ↓ swap/longTaskCount: -100%
  • ↓ swap/longTaskTotalDuration: -100%
  • ↓ swap/longTaskMaxDuration: -100%
  • ↓ swap/tbt: -100%
  • ↑ swap/total: +83%
  • ↓ swap/lcp: -72%
  • ↓ swap/cls: -92%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 solanaAssetDetails/FCP: p75 2.0s
  • 🟡 importSrpHome/FCP: p75 1.9s
  • 🟡 sendTransactions/FCP: p75 2.0s
  • 🟡 swap/FCP: p75 1.9s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: -25.95 KiB (-0.18%)
  • ui: 1.45 KiB (0.01%)
  • common: 0 Bytes (0%)
  • other: 0 Bytes (0%)
  • contentScripts: 430 Bytes (0.02%)
  • zip: -6.11 MiB (-22.5%)

@sleepytanya
sleepytanya merged commit cd5a5de into release/13.42.0 Jul 30, 2026
683 of 706 checks passed
@sleepytanya
sleepytanya deleted the cherry-pick-13-42-0-c1a5d29 branch July 30, 2026 04:49
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 30, 2026
@metamaskbot metamaskbot added the release-13.42.0 Issue or pull request that will be included in release 13.42.0 label Jul 30, 2026
@gauthierpetetin

Copy link
Copy Markdown
Contributor

No release label on PR. Adding release label release-13.42.0 on PR, as PR was cherry-picked in branch 13.42.0.

This branch was previously deployed

1 inactive deployment
pr-comment — 31a60bd8 Deployed Jul 30, 2026 by metamaskbot via Publish prerelease / Publish prerelease #155602
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-13.42.0 Issue or pull request that will be included in release 13.42.0 risk:medium team-bots Bot team (for MetaMask Bot, Runway Bot, etc.)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants