Skip to content

fix(perps): incorrect decimals on limit price for open orders#30615

Merged
abretonc7s merged 4 commits into
mainfrom
fix/tat-3178-fix-limit-price-decimals
May 27, 2026
Merged

fix(perps): incorrect decimals on limit price for open orders#30615
abretonc7s merged 4 commits into
mainfrom
fix/tat-3178-fix-limit-price-decimals

Conversation

@abretonc7s
Copy link
Copy Markdown
Contributor

@abretonc7s abretonc7s commented May 26, 2026

Description

Fix limit order price formatting on Perps home order card, order detail screen, and wallet home. These screens used PRICE_RANGES_MINIMAL_VIEW (threshold-based, max 2 decimals) instead of PRICE_RANGES_UNIVERSAL (adaptive significant digits), causing low-price assets like PUMP to display <$0.01 instead of the actual price $0.001.

Changelog

CHANGELOG entry: Fixed limit order price displaying <$0.01 instead of actual price on order cards and detail screens

Related issues

Fixes: TAT-3178

Manual testing steps

Feature: Limit order price formatting

  Scenario: user views limit order price on low-price asset
    Given wallet is unlocked and Perps is ready to trade

    When user places a limit order on PUMP at $0.001
    Then Perps home order card shows $0.001 (not <$0.01)
    And order detail screen shows Price: $0.001
    And wallet home shows $0.001 for the order

Screenshots/Recordings

Limit order price now shows adaptive sig-dig ($0.001) instead of threshold (<$0.01) on all 3 screens.

AC1: Perps home order card price (<$0.01 → $0.001)
Before
before
After
after
AC2: Order detail screen price (<$0.01 → $0.001)
Before
before
After
after
AC3: Wallet home order price (<$0.01 → $0.001)
Before
before
After
after

Video evidence — drag-and-drop into PR if needed:

  • Before: .task/fix/tat-3178-0526-095542/artifacts/before.mp4
  • After: .task/fix/tat-3178-0526-095542/artifacts/after.mp4

Pre-merge author checklist

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 to import wallets with many accounts and tokens
  • I've instrumented key operations with Sentry traces for production performance metrics

For performance guidelines and tooling, see the Performance Guide.

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.

Validation Recipe

recipe.json
{
  "title": "Verify limit order price uses adaptive sig-dig on all screens",
  "jira": "TAT-3178",
  "acceptance_criteria": [
    "AC1: Perps home order card displays limit price with adaptive sig-dig (not <$0.01)",
    "AC2: Order detail screen displays limit price with adaptive sig-dig",
    "AC3: Wallet home displays limit order price with adaptive sig-dig"
  ],
  "initial_conditions": { "testnet": false },
  "validate": {
    "workflow": {
      "pre_conditions": ["wallet.unlocked", "perps.ready_to_trade"],
      "entry": "setup-place-order",
      "nodes": {
        "setup-place-order": {
          "action": "call",
          "ref": "perps/order-limit-place",
          "params": { "symbol": "PUMP", "side": "long", "usdAmount": "11", "limitPrice": "0.001" },
          "next": "setup-wait"
        },
        "setup-wait": { "action": "wait", "ms": 4000, "next": "ac1-nav-perps-home" },
        "ac1-nav-perps-home": { "action": "navigate", "target": "PerpsMarketListView", "next": "ac1-wait-orders-loaded" },
        "ac1-wait-orders-loaded": { "action": "wait_for", "expression": "...wait for '11000' in fiber tree...", "timeout_ms": 20000, "next": "ac1-scroll-to-orders" },
        "ac1-scroll-to-orders": { "action": "eval_sync", "expression": "...scrollTo({y:350})...", "next": "ac1-scroll-settle" },
        "ac1-scroll-settle": { "action": "wait", "ms": 500, "next": "ac1-eval-no-bug" },
        "ac1-eval-no-bug": { "action": "eval_sync", "expression": "...assert <$0.01 absent...", "assert": { "operator": "eq", "field": "buggy", "value": false }, "next": "ac1-screenshot" },
        "ac1-screenshot": { "action": "screenshot", "filename": "evidence-ac1-perps-home-order-card.png", "next": "ac2-nav-market" },
        "ac2-nav-market": { "action": "navigate", "target": "PerpsMarketDetails", "next": "ac2-wait-market" },
        "ac2-wait-market": { "action": "wait_for", "test_id": "perps-compact-order-row-first", "next": "ac2-press-order" },
        "ac2-press-order": { "action": "press", "test_id": "perps-compact-order-row-first", "next": "ac2-wait-details" },
        "ac2-wait-details": { "action": "wait_for", "route": "PerpsOrderDetailsView", "next": "ac2-eval-no-bug" },
        "ac2-eval-no-bug": { "action": "eval_sync", "expression": "...assert <$0.01 absent...", "assert": { "operator": "eq", "field": "buggy", "value": false }, "next": "ac2-screenshot" },
        "ac2-screenshot": { "action": "screenshot", "filename": "evidence-ac2-order-details-price.png", "next": "ac3-nav-wallet" },
        "ac3-nav-wallet": { "action": "navigate", "target": "WalletView", "next": "ac3-wait-orders-loaded" },
        "ac3-wait-orders-loaded": { "action": "wait_for", "expression": "...wait for '11000' in fiber tree...", "timeout_ms": 20000, "next": "ac3-scroll-to-orders" },
        "ac3-scroll-to-orders": { "action": "eval_sync", "expression": "...scrollTo({y:600})...", "next": "ac3-scroll-settle" },
        "ac3-scroll-settle": { "action": "wait", "ms": 500, "next": "ac3-eval-no-bug" },
        "ac3-eval-no-bug": { "action": "eval_sync", "expression": "...assert <$0.01 absent...", "assert": { "operator": "eq", "field": "buggy", "value": false }, "next": "ac3-screenshot" },
        "ac3-screenshot": { "action": "screenshot", "filename": "evidence-ac3-wallet-home-order-price.png", "next": "teardown-cancel-order" },
        "teardown-cancel-order": { "action": "call", "ref": "perps/order-limit-cancel", "params": { "symbol": "PUMP" }, "next": "teardown-done" },
        "teardown-done": { "action": "end", "status": "pass" }
      }
    }
  }
}

Recipe Workflow

workflow.mmd
flowchart TD
  %% Verify limit order price uses adaptive sig-dig on all screens
  __entry__(["ENTRY"]) --> node_setup_place_order
  node_setup_place_order[["setup-place-order<br/>perps/order-limit-place"]]
  node_setup_wait["setup-wait<br/>wait"]
  node_ac1_nav_perps_home["ac1-nav-perps-home<br/>navigate"]
  node_ac1_wait_orders_loaded["ac1-wait-orders-loaded<br/>wait_for"]
  node_ac1_eval_no_bug["ac1-eval-no-bug<br/>eval_sync"]
  node_ac1_screenshot["ac1-screenshot<br/>screenshot"]
  node_ac2_nav_market["ac2-nav-market<br/>navigate"]
  node_ac2_wait_market["ac2-wait-market<br/>wait_for"]
  node_ac2_press_order["ac2-press-order<br/>press"]
  node_ac2_wait_details["ac2-wait-details<br/>wait_for"]
  node_ac2_eval_no_bug["ac2-eval-no-bug<br/>eval_sync"]
  node_ac2_screenshot["ac2-screenshot<br/>screenshot"]
  node_ac3_nav_wallet["ac3-nav-wallet<br/>navigate"]
  node_ac3_wait_orders_loaded["ac3-wait-orders-loaded<br/>wait_for"]
  node_ac3_eval_no_bug["ac3-eval-no-bug<br/>eval_sync"]
  node_ac3_screenshot["ac3-screenshot<br/>screenshot"]
  node_teardown_cancel_order[["teardown-cancel-order<br/>perps/order-limit-cancel"]]
  node_teardown_done(["teardown-done<br/>PASS"])
  node_setup_place_order --> node_setup_wait
  node_setup_wait --> node_ac1_nav_perps_home
  node_ac1_nav_perps_home --> node_ac1_wait_orders_loaded
  node_ac1_wait_orders_loaded --> node_ac1_eval_no_bug
  node_ac1_eval_no_bug --> node_ac1_screenshot
  node_ac1_screenshot --> node_ac2_nav_market
  node_ac2_nav_market --> node_ac2_wait_market
  node_ac2_wait_market --> node_ac2_press_order
  node_ac2_press_order --> node_ac2_wait_details
  node_ac2_wait_details --> node_ac2_eval_no_bug
  node_ac2_eval_no_bug --> node_ac2_screenshot
  node_ac2_screenshot --> node_ac3_nav_wallet
  node_ac3_nav_wallet --> node_ac3_wait_orders_loaded
  node_ac3_wait_orders_loaded --> node_ac3_eval_no_bug
  node_ac3_eval_no_bug --> node_ac3_screenshot
  node_ac3_screenshot --> node_teardown_cancel_order
  node_teardown_cancel_order --> node_teardown_done
Loading

Note

Low Risk
Display-only formatting change in Perps UI with targeted tests; no trading, auth, or data-path changes.

Overview
Limit order prices on Perps order cards and the order details screen now use PRICE_RANGES_UNIVERSAL (adaptive significant digits) instead of PRICE_RANGES_MINIMAL_VIEW, so low-priced assets (e.g. PUMP at $0.001) show the real price instead of a threshold like <$0.01.

PerpsOrderDetailsView passes universal ranges to formatPerpsFiat for limit price, trigger price, take profit, and stop loss. PerpsCard does the same for the order card’s displayed price. Tests assert the new formatting behavior.

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

Switch order price formatting from PRICE_RANGES_MINIMAL_VIEW to
PRICE_RANGES_UNIVERSAL in PerpsCard and PerpsOrderDetailsView so
low-price assets display the actual price (e.g. $0.001) instead of
the threshold fallback (<$0.01).
@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.

@metamaskbotv2 metamaskbotv2 Bot added the team-perps Perps team label May 26, 2026
@abretonc7s
Copy link
Copy Markdown
Contributor Author

abretonc7s commented May 26, 2026

Run Duration Model Nudges Grade Cost
41aa4e11 ? opus / claude 0 medium · 5 $0.1383
Worker report

TAT-3178: Incorrect decimals on limit price for open orders

Summary

Limit order prices on the Perps home order card, order detail screen, and wallet home used PRICE_RANGES_MINIMAL_VIEW (2-decimal threshold formatter) instead of PRICE_RANGES_UNIVERSAL (adaptive significant-digit formatter). For low-price assets like PUMP with a limit at $0.001, this produced <$0.01 instead of $0.001. Fixed by switching to PRICE_RANGES_UNIVERSAL in both affected components.

Root Cause

  • PerpsCard.tsx:81getOrderDisplayData() passed PRICE_RANGES_MINIMAL_VIEW to formatPerpsFiat() for order prices
  • PerpsOrderDetailsView.tsx:134,138,178,181 — called formatPerpsFiat() with no ranges parameter (defaults to MINIMAL_VIEW)

PRICE_RANGES_MINIMAL_VIEW has threshold: 0.01 in its catch-all range. When _formatWithThreshold(0.001, 0.01, ...) executes, |0.001| < 0.01 → returns <$0.01. PRICE_RANGES_UNIVERSAL has threshold: 0.000001 for its smallest range, so |0.001| >= 0.000001 → formats normally as $0.001.

The correct implementation was already visible in PerpsCompactOrderRow.tsx:51-52 which uses PRICE_RANGES_UNIVERSAL.

Reproduction Commit

SHA: 8ad2e74a65debug(tat-3178): add reproduction marker

Metro log excerpt:

DEBUG  [TAT-3178] BUG_MARKER: PerpsCard order price formatted with MINIMAL_VIEW {"priceValue": 0.001, "symbol": "PUMP", "valueText": "<$0.01"}

Changes

File Change
app/components/UI/Perps/components/PerpsCard/PerpsCard.tsx Import PRICE_RANGES_UNIVERSAL, use it for order price formatting
app/components/UI/Perps/Views/PerpsOrderDetailsView/PerpsOrderDetailsView.tsx Import PRICE_RANGES_UNIVERSAL, pass to all formatPerpsFiat calls for prices
app/components/UI/Perps/components/PerpsCard/PerpsCard.test.tsx Add test for low-price order formatting
app/components/UI/Perps/Views/PerpsOrderDetailsView/PerpsOrderDetailsView.test.tsx Add PRICE_RANGES_UNIVERSAL to mock, add test verifying ranges are passed

Test Plan

Automated:

  • Unit tests: 49/49 pass (21 PerpsCard + 28 PerpsOrderDetailsView)
  • Lint: pass
  • TypeScript: pass
  • Format: pass
  • Recipe: 17/17 nodes pass — places PUMP limit order at $0.001, verifies <$0.01 absent on all 3 screens
  • Coverage: PerpsCard.tsx 100%, PerpsOrderDetailsView.tsx 96.87%

Manual Gherkin:

  1. Given wallet is unlocked and Perps is ready
  2. When I place a limit order on PUMP at $0.001
  3. Then Perps home order card shows $0.001 (not <$0.01)
  4. And order detail screen shows Price: $0.001
  5. And wallet home shows $0.001 for the order

Evidence

  • before.mp4 — buggy state showing <$0.01
  • after.mp4 — fixed state showing $0.001
  • before-evidence-ac2-order-details-price.png — order detail with <$0.01
  • after-ac2-order-details-price.png — order detail with $0.001
  • after-ac3-wallet-home-order-price.png — wallet home with $0.001
  • recipe-coverage.md — 3/3 ACs PROVEN

Ticket

TAT-3178

@abretonc7s abretonc7s changed the title chore: prepare farmslot publication pkg-41aa4e11-mpm8zjf0 fix(perps): incorrect decimals on limit price for open orders May 26, 2026
@abretonc7s abretonc7s marked this pull request as ready for review May 26, 2026 06:23
@abretonc7s abretonc7s requested a review from a team as a code owner May 26, 2026 06:23
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokePerps, SmokeWalletPlatform, SmokeConfirmations
  • Selected Performance tags: None (no tests recommended)
  • Risk Level: low
  • AI Confidence: 95%
click to see 🤖 AI reasoning details

E2E Test Selection:
The changes are isolated to two Perps UI components:

  1. PerpsCard.tsx: Switches formatPerpsFiat from PRICE_RANGES_MINIMAL_VIEW to PRICE_RANGES_UNIVERSAL for order price display, fixing precision for low-priced assets (e.g., showing $0.001 instead of <$0.01).

  2. PerpsOrderDetailsView.tsx: Adds PRICE_RANGES_UNIVERSAL to four formatPerpsFiat calls (order price, trigger price, take profit price, stop loss price) for the same adaptive significant-digit formatting fix.

  3. Test files: Unit tests updated to verify the new formatting behavior.

These are purely UI formatting changes within the Perps feature. No controllers, navigation, shared infrastructure, or cross-cutting components are affected.

Tag rationale:

  • SmokePerps: Primary tag — changes are directly in Perps components (PerpsCard, PerpsOrderDetailsView) which are core to the Perps trading flow.
  • SmokeWalletPlatform: Required per SmokePerps description — "Perps is also a section inside the Trending tab (SmokeWalletPlatform); changes to Perps views (headers, lists, full views) affect Trending."
  • SmokeConfirmations: Required per SmokePerps description — "When selecting SmokePerps, also select SmokeConfirmations (Add Funds deposits are on-chain transactions)."

Performance Test Selection:
Changes are purely UI number formatting logic (switching price range configs for display). No rendering performance impact, no data loading changes, no state management changes, no list rendering changes. Performance tests are not warranted.

View GitHub Actions results

@sonarqubecloud
Copy link
Copy Markdown

@abretonc7s abretonc7s enabled auto-merge May 26, 2026 06:48
@abretonc7s abretonc7s added this pull request to the merge queue May 26, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 26, 2026
@michalconsensys michalconsensys added this pull request to the merge queue May 26, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 26, 2026
@abretonc7s abretonc7s added this pull request to the merge queue May 27, 2026
Merged via the queue into main with commit 4a41941 May 27, 2026
239 of 267 checks passed
@abretonc7s abretonc7s deleted the fix/tat-3178-fix-limit-price-decimals branch May 27, 2026 01:49
@github-actions github-actions Bot locked and limited conversation to collaborators May 27, 2026
@metamaskbotv2 metamaskbotv2 Bot added the release-7.80.0 Issue or pull request that will be included in release 7.80.0 label May 27, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.80.0 Issue or pull request that will be included in release 7.80.0 size-S team-perps Perps team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants