fix: Charts pair 24h Vol (token) still formatNum(raw) after #540/#544 #565
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:implement
agent:implement
agent:open_issues
agent:ready
agent:research
agent:security_audit
agent:verify
architecture
backend
blocker:hybrid
blocker:launch
blocker:limit-orders
blocker:v2
block:log_only
block:security
bug
ci
contracts
correctness
deploy
dev
devops
docs
documentation
duplicate
e2e
enhancement
epic
feature
frontend
functional-completion
gas
good first issue
governance
help wanted
high-risk
hooks
hybrid
indexer
infra
infrastructure
integrators
invalid
launch-blocker
limit-orders
localnet
localterra
low priority
missing-implementation
needs-design
ops
performance
priority
high
priority
medium
product
qa
QA
question
ready
ready
research
scripts
security
security-hardening
smartcontracts
tech-debt
testing
ux
UX
v2
verification
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
code/cl8y-dex-terraclassic#565
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
On Charts & Analytics pair detail (
https://dex.cl8y.com/charts→ select UST1/cUSTC), the 24h Stats strip still compact-formats rawvolume_base/volume_quotewithformatNum. Retail sees Vol (UST1) = 847.0M and Vol (cUSTC) = 157.5B for ~847 UST1 /157K cUSTC ($763 USD already on the JSON).This is the same
formatNum(raw)class as tape Amount in/out (#557), picker volume (#534), and overview USD (#548). Pair-level Vol (token) was explicitly out of scope of #548 and assigned to closed #540 / #544 AC4, butChartsPage.tsxnever changed those twoStatBoxes (git log -S 'formatNum(stats.volume_base)'is still the original charts commit).Observed (columbus-5, 2026-08-18):
GET /api/v1/pairs/terra1ceprjsxp86ggftf5e38wwt34l83e5gq7penkdnv4wsatkwcs8v6qccw55f/statsformatNum)volume_base847004054volume_quote157465643310volume_usd763.35…trade_count41UST1/USTR (6/18) is worse: raw quote volume compact-formats as
T.Related: tape Amount in/out is #557 (do not duplicate here). Overview 24h USD is #548 (done). Picker/pool USD badges are #544 (closed; this issue is the leftover Charts pair-stats strip only).
Current codebase
Frontend — two raw token vols, no USD
frontend-dapp/src/pages/ChartsPage.tsx24h Stats (when a pair is selected):formatNumis a human compact formatter (K/M/B/T). Indexervolume_base/volume_quotestay raw chain integers (swap_orientation.rs: “Volume buckets stay in raw chain units”).USD OHLC boxes on the same grid already use
high_usd/low_usd/ … viapairStatsUsdField(#522). Volume USD is ignored.IndexerPairStatsomitsvolume_usdeven thoughPairStatsResponsereturns it (Option<String>, human USD, P522-Q / hub catalog after #548/#556). Charts tests mock stats withoutvolume_usdand never assert the Vol boxes (ChartsPage.test.tsx).Helpers already exist:
formatTokenAmount(raw, decimals)— human token compact ("1000000"+ 6 →"1.000")formatIndexedVolumeUsd(usd, trades)—$+ compact;—when unpriced and trades > 0;$0only when idle (#548 / #553)activePair.asset_0.decimals/asset_1.decimalsare already on the pair JSON (do not match decimals by symbol).Indexer — already has the numbers
GET /api/v1/pairs/{addr}/stats(PairStatsResponse):volume_base/volume_quote: raw oriented sums (unchanged; integrators / CG)volume_usd: human USDSUM(swap_events.volume_usd)for the 24h windowtrade_count, USD OHLC, humanhigh/lowquote-per-baseNo indexer schema change is required for the default USD box. Token secondary vols can be scaled in the dApp from pair-leg decimals.
Why the new implementation is needed
volume_usd ≈ $763is on the live stats JSON. The UI types dropped it.T. 18-dec quote raw throughformatNumreprints the #534 / #544 impossible-trillions bug on the pair-detail strip.Constraints / guardrails
24h volume in USD). Do not imply a peg.formatIndexedVolumeUsd. Do not invent a third USD formatter. Unpriced / invalid / negative →—. Trades > 0 and USD missing/0→—, not$0. Idle (trade_count === 0) may show$0or—— pick one and test it.formatNumrawvolume_base/volume_quote. If token vols remain as secondary, useformatTokenAmount(raw, asset_N.decimals)from that pair’s legs (activePair.pair_addressmust match). Missing decimals →—, never assume 6.volume_base/volume_quote. Do not humanize those fields in the indexer.volume_usdstays human USD.stats.volume_usdas-is. Do not add candle volumes, limit fills, or pool+book legs.base_volume/target_volume; settlement/fee math.make verify-issue-<iid>in the same MR. Updatedocs/frontend.md(pair-level Vol was “out of scope #540/#544”) and the Charts overview skill cross-link.Relevant files
frontend-dapp/src/pages/ChartsPage.tsxStatBoxesfrontend-dapp/src/pages/ChartsPage.test.tsxfrontend-dapp/src/types/index.tsIndexerPairStatsmissingvolume_usdfrontend-dapp/src/services/indexer/client.tsgetPairStatsparsefrontend-dapp/src/utils/chartsOverviewStats.tsformatIndexedVolumeUsdfrontend-dapp/src/utils/formatAmount.tsformatTokenAmount/formatNumindexer/src/api/pairs.rsPairStatsResponse(already hasvolume_usd)docs/frontend.mdskills/AGENTS_FRONTEND_CHARTS_OVERVIEW.mdRecommended direction
volume_usd?: string | nulltoIndexerPairStatsand pass throughgetPairStats.formatIndexedVolumeUsd(stats.volume_usd, stats.trade_count)withdata-testid="charts-pair-volume-usd".formatTokenAmount(stats.volume_base, activePair.asset_0.decimals)and quote likewise. Labels keepVol ({symbol}). Prefer demoting them (smaller / second row) so USD is the default read. If space is tight, USD only is acceptable (V544-1).ChartsPage.tsxmust not containformatNum(stats.volume_base)orformatNum(stats.volume_quote).847004054→ not847.0M); UST1/USTR 6/18 (raw 18-dec quote → notT); missingvolume_usd+trade_count > 0→—; HTML/NaN/1e309→—.make verify-issue-<iid>: vitest ChartsPage + grep + docs mention.Acceptance criteria
/chartspair 24h stats primary volume is USD ($+ compact), matchingGET /api/v1/pairs/{addr}/statsvolume_usd(rollup lag OK). UST1/cUSTC production ~$763class, not847.0M/157.5B.T.formatTokenAmount+ that leg’s decimals) and labeled with the token. Missing decimals →—.trade_count > 0→—, not$0and notformatNum(raw)fallback.#524invert does not change the USD figure or swap base/quote raw onto the wrong decimals.volume_base/volume_quoteremain raw. CG/CMC unchanged.make verify-issue-<iid>+ docs/skill cross-link.Test plan — functional paths
Frontend RTL / unit
volume_base=847004054,volume_quote=157465643310,volume_usd=763.35,trade_count=41→ Vol (USD) matches/^\$/and does not match/847\.0M|157\.5B/.volume_quote=19300000000000000000+ 18-dec pair → no/T$/on the stats strip; USD path used whenvolume_usdpresent.volume_usdnull/0/''andtrade_count > 0→—.trade_count === 0and USD0→ documented$0or—.NaN,"><script>", 200-char string, negative) →—; no exception; no HTML inject.formatTokenAmountpath; 6-dec1000000→1class; missing decimals →—.Indexer (regression only)
GET /api/v1/pairs/{addr}/statsstill returns rawvolume_base/volume_quoteand humanvolume_usd. No new scan on the hot path.Manual / production
https://dex.cl8y.com/chartsUST1/cUSTC 24h Stats: Vol (USD) ≈ curlvolume_usd; token vols (if shown) ≈ raw ÷ 10^6.Ton the strip.Test plan — attack, hack, and abuse
volume_quoteasset_0/asset_1rows only. Wrong-leg scale must fail the test.UST1label={Vol (${symbol})}.volume_usdby 1e6volume_usdis human dollars.volume_baseafter pill flipvolume_usd/ symboldangerouslySetInnerHTML.formatTokenAmountBigInt path; USD helper length cap (#548 A4). No tab lock.$0lie — catalog USD NULL while trades exist—, never$0and never rawTfallback.volume_quoteor fill rows into the boxstats.volume_usdonly (L10).activePair.pair_addressis the selected pair that fetched stats.—.Verification criteria
Issue is done when a reviewer on dex.cl8y.com (or LocalTerra) opens
/chartsUST1/cUSTC and sees 24h volume in USD (and optional human token vols), matchingGET /api/v1/pairs/{addr}/stats, not847.0MUST1.Out of scope
marked as related to #540
marked as related to #544
marked as related to #548
marked as related to #557
mentioned in merge request !1089
mentioned in merge request !1093
mentioned in commit
975e062004mentioned in commit
17790e7db4mentioned in issue #564
Post-merge note (!1089 on main, stacked on !1088 / #564). V1–V7 Vol (USD) primary + human token vols are on
main. TWAP/histogram from #564 kept. Combined UI: row 1 Vol USD / Trades / Change / USD OHLC; row 2 token vols; TWAP section retained.Remaining:
dex.cl8y.com/chartsUST1/cUSTC Vol (USD) ≈ curlvolume_usd; UST1/USTR strip has noT; overview (#548) unchanged.make verify-issue-565andmake verify-issue-564.mentioned in issue #573
marked as related to #573
mentioned in issue #576
mentioned in issue #664
mentioned in issue #666
marked as related to #666
mentioned in issue #680
mentioned in issue #692
marked as related to #692