Skip to content

release(runway): cherry-pick fix(perps): percent issue on markets page cp-13.28.0#41969

Merged
chloeYue merged 1 commit intorelease/13.28.0from
runway-cherry-pick-13.28.0-1776703013
Apr 20, 2026
Merged

release(runway): cherry-pick fix(perps): percent issue on markets page cp-13.28.0#41969
chloeYue merged 1 commit intorelease/13.28.0from
runway-cherry-pick-13.28.0-1776703013

Conversation

@runway-github
Copy link
Copy Markdown
Contributor

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

Description

The 24h percentage change on the perps markets list was sometimes
displayed without the % suffix. This happened because the WebSocket
live-price stream can emit percentChange24h values without a trailing
% (e.g. +2.84 instead of +2.84%). usePerpsLiveMarketListData
merges that value directly into market.change24hPercent with no
normalization, and MarketRow was rendering the raw string.

The detail page and market cards already guard against this using
formatChangePercent / formatSignedChangePercent from utils.ts.
This fix applies the same formatSignedChangePercent normalization
inside MarketRow — both for the right-side change column and for the
secondary priceChange metric display — so the % symbol is always
present regardless of whether the value came from REST or WebSocket.

Changelog

CHANGELOG entry: Fixed a bug where the 24h percentage change on the
perps markets page was sometimes displayed without the % symbol.

Related issues

Fixes:

Manual testing steps

  1. Open the MetaMask extension and navigate to the Perps section.
  2. Open the Markets list page.
  3. Observe the 24h change column — all values should display with a %
    suffix (e.g. +2.84%, -1.23%).
  4. Wait for the WebSocket live-price stream to push updates and confirm
    the % remains present after a live update.

Screenshots/Recordings

Before

After

Screenshot 2026-04-20 at 13 43 56

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 UI formatting change that only normalizes the
change24hPercent string; limited to display logic plus a small test
addition.

Overview
Ensures the perps markets list always shows a properly formatted 24h
change percent by routing market.change24hPercent through
formatSignedChangePercent (adds missing % and normalizes sign) in
MarketRow, including the secondary priceChange metric.

Adds a regression test covering the live-stream case where the percent
value arrives without a trailing %.

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

[9642b58](https://github.com/MetaMask/metamask-extension/commit/9642b5854c26e923911ac19b6d7e238e60531094)

…e cp-13.28.0 (#41941)

## **Description**

The 24h percentage change on the perps markets list was sometimes
displayed without the `%` suffix. This happened because the WebSocket
live-price stream can emit `percentChange24h` values without a trailing
`%` (e.g. `+2.84` instead of `+2.84%`). `usePerpsLiveMarketListData`
merges that value directly into `market.change24hPercent` with no
normalization, and `MarketRow` was rendering the raw string.

The detail page and market cards already guard against this using
`formatChangePercent` / `formatSignedChangePercent` from `utils.ts`.
This fix applies the same `formatSignedChangePercent` normalization
inside `MarketRow` — both for the right-side change column and for the
secondary `priceChange` metric display — so the `%` symbol is always
present regardless of whether the value came from REST or WebSocket.

## **Changelog**

CHANGELOG entry: Fixed a bug where the 24h percentage change on the
perps markets page was sometimes displayed without the `%` symbol.

## **Related issues**

Fixes:

## **Manual testing steps**

1. Open the MetaMask extension and navigate to the Perps section.
2. Open the Markets list page.
3. Observe the 24h change column — all values should display with a `%`
suffix (e.g. `+2.84%`, `-1.23%`).
4. Wait for the WebSocket live-price stream to push updates and confirm
the `%` remains present after a live update.


## **Screenshots/Recordings**

### **Before**

### **After**
<img width="492" height="971" alt="Screenshot 2026-04-20 at 13 43 56"
src="https://github.com/user-attachments/assets/10450641-1516-402e-8332-27e551c6c824"
/>


## **Pre-merge author checklist**

- [ ] 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.

## **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]
> **Low Risk**
> Low risk UI formatting change that only normalizes the
`change24hPercent` string; limited to display logic plus a small test
addition.
> 
> **Overview**
> Ensures the perps markets list always shows a properly formatted 24h
change percent by routing `market.change24hPercent` through
`formatSignedChangePercent` (adds missing `%` and normalizes sign) in
`MarketRow`, including the secondary `priceChange` metric.
> 
> Adds a regression test covering the live-stream case where the percent
value arrives without a trailing `%`.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
b4e7856. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@runway-github runway-github Bot requested a review from a team as a code owner April 20, 2026 16:37
@github-actions
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 20, 2026
Copy link
Copy Markdown
Contributor

@chloeYue chloeYue left a comment

Choose a reason for hiding this comment

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

LGTM

@sonarqubecloud
Copy link
Copy Markdown

@metamaskbotv2
Copy link
Copy Markdown
Contributor

metamaskbotv2 Bot commented Apr 20, 2026

Builds ready [7c60d78]
⚡ Performance Benchmarks (Total: 🟢 7 pass · 🟡 12 warn · 🔴 0 fail)

Baseline (latest main): 71bd826 | Date: 10/14/58243 | Pipeline: 24678411635 | Baseline logs

Interaction Benchmarks · Samples: 5
Benchmarkchrome-browserify
loadNewAccount🟡 [Show logs]
confirmTx🟡 [Show logs]
bridgeUserActions🟡 [Show logs]

📈 Results compared to the previous 5 runs on main

  • loadNewAccount/load_new_account: -20%
  • loadNewAccount/total: -20%
  • bridgeUserActions/bridge_load_asset_picker: -50%
  • bridgeUserActions/total: -16%

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

  • 🟡 loadNewAccount/FCP: p75 2.6s
  • 🟡 confirmTx/FCP: p75 2.6s
  • 🟡 bridgeUserActions/FCP: p75 2.6s
Startup Benchmarks · Samples: 100
Benchmarkchrome-browserifychrome-webpackfirefox-browserifyfirefox-webpack
startupStandardHome🟢 [Show logs]🟢 [Show logs]🟢 [Show logs]🟢 [Show logs]
startupPowerUserHome🟡 [Show logs]🟡 [Show logs]🟡 [Show logs]🟡 [Show logs]

📈 Results compared to the previous 5 runs on main

  • startupStandardHome/uiStartup: -23%
  • startupStandardHome/load: -12%
  • startupStandardHome/domContentLoaded: -12%
  • startupStandardHome/initialActions: -33%
  • startupStandardHome/loadScripts: -14%
  • startupStandardHome/numNetworkReqs: -37%
  • startupPowerUserHome/uiStartup: -29%
  • startupPowerUserHome/domInteractive: -12%
  • startupPowerUserHome/backgroundConnect: +93%
  • startupPowerUserHome/numNetworkReqs: -53%
  • startupStandardHome/uiStartup: -19%
  • startupStandardHome/load: -14%
  • startupStandardHome/domContentLoaded: -13%
  • startupStandardHome/backgroundConnect: -32%
  • startupStandardHome/firstReactRender: -23%
  • startupStandardHome/loadScripts: -13%
  • startupStandardHome/setupStore: -13%
  • startupStandardHome/numNetworkReqs: -44%
  • startupPowerUserHome/uiStartup: -37%
  • startupPowerUserHome/load: -17%
  • startupPowerUserHome/domContentLoaded: -17%
  • startupPowerUserHome/domInteractive: -29%
  • startupPowerUserHome/backgroundConnect: -18%
  • startupPowerUserHome/firstReactRender: -25%
  • startupPowerUserHome/loadScripts: -17%
  • startupPowerUserHome/setupStore: -13%
  • startupPowerUserHome/numNetworkReqs: +44%
  • startupStandardHome/uiStartup: -11%
  • startupStandardHome/domInteractive: -55%
  • startupStandardHome/backgroundConnect: +13%
  • startupStandardHome/initialActions: -33%
  • startupStandardHome/numNetworkReqs: -34%
  • startupPowerUserHome/uiStartup: -32%
  • startupPowerUserHome/domInteractive: +14%
  • startupPowerUserHome/backgroundConnect: -21%
  • startupPowerUserHome/setupStore: +26%
  • startupStandardHome/uiStartup: -21%
  • startupStandardHome/load: -13%
  • startupStandardHome/domContentLoaded: -13%
  • startupStandardHome/domInteractive: -68%
  • startupStandardHome/initialActions: -43%
  • startupStandardHome/loadScripts: -14%
  • startupStandardHome/setupStore: -60%
  • startupStandardHome/numNetworkReqs: -34%
  • startupPowerUserHome/uiStartup: -28%
  • startupPowerUserHome/backgroundConnect: -19%
  • startupPowerUserHome/setupStore: +12%

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

  • 🔴 startupPowerUserHome/INP: p75 696ms
  • 🔴 startupPowerUserHome/INP: p75 624ms
  • 🟡 startupPowerUserHome/LCP: p75 3.7s
  • 🟡 startupPowerUserHome/LCP: p75 3.6s
User Journey Benchmarks · Samples: 5 · mock API
Benchmarkchrome-browserify
onboardingImportWallet🟢 [Show logs]
onboardingNewWallet🟢 [Show logs]
assetDetails🟡 [Show logs]
solanaAssetDetails🟡 [Show logs]
importSrpHome🟡 [Show logs]
sendTransactions🟡 [Show logs]
swap🟡 [Show logs]

📈 Results compared to the previous 5 runs on main

  • onboardingImportWallet/srpButtonToSrpForm: -84%
  • onboardingImportWallet/doneButtonToHomeScreen: -78%
  • onboardingImportWallet/openAccountMenuToAccountListLoaded: +27%
  • onboardingImportWallet/total: -43%
  • onboardingNewWallet/srpButtonToPwForm: -79%
  • onboardingNewWallet/skipBackupToMetricsScreen: -67%
  • onboardingNewWallet/doneButtonToAssetList: -23%
  • onboardingNewWallet/total: -25%
  • assetDetails/assetClickToPriceChart: -38%
  • assetDetails/total: -38%
  • solanaAssetDetails/assetClickToPriceChart: -68%
  • solanaAssetDetails/total: -68%
  • importSrpHome/openAccountMenuAfterLogin: -76%
  • importSrpHome/homeAfterImportWithNewWallet: -70%
  • importSrpHome/total: -60%
  • sendTransactions/openSendPageFromHome: -22%
  • sendTransactions/selectTokenToSendFormLoaded: -31%
  • sendTransactions/reviewTransactionToConfirmationPage: +33%
  • sendTransactions/total: +31%
  • swap/openSwapPageFromHome: -97%
  • swap/fetchAndDisplaySwapQuotes: +31%
  • swap/total: +10%

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

  • 🟡 assetDetails/INP: p75 216ms
  • 🟡 assetDetails/FCP: p75 2.5s
  • 🟡 solanaAssetDetails/FCP: p75 2.5s
  • 🟡 importSrpHome/FCP: p75 2.7s
  • 🟡 sendTransactions/INP: p75 216ms
  • 🟡 sendTransactions/FCP: p75 2.5s
  • 🟡 swap/FCP: p75 2.5s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-browserify
dappPageLoad🟢 [Show logs]
Bundle size diffs [🚨 Warning! Bundle size has increased!]
  • background: 6.01 MiB (100%)
  • ui: 8.31 MiB (100%)
  • common: 13.15 MiB (100%)

@chloeYue chloeYue merged commit 2e172ac into release/13.28.0 Apr 20, 2026
373 of 391 checks passed
@chloeYue chloeYue deleted the runway-cherry-pick-13.28.0-1776703013 branch April 20, 2026 19:43
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 20, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

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