Summary
Display-only rounding for blockchain amounts in the admin console. Amounts arrive as decimal strings with up to 18 fraction digits (lending returns toFixed(18)), so tables scrolled sideways and stat cards overflowed.
- New
formatDisplayAmount(admin/src/lib/format/display-amount.ts) and<Amount>(admin/src/components/amount.tsx), string-only, neverNumber(). - ROUND_DOWN (matches the backend and wallets: never show more than is held).
- Per-asset display decimals: fiat/stablecoins 2 (padded), BTC 8, ETH 6, SOL 4, others 6; crypto trims trailing zeros;
min(table, market.decimals)when known. - Values below 1 keep 4 significant digits (max 8 dp); dust shows
< 0.00000001/< 0.01; never-0. - When rounded, the
titlecarries the full value for reconciliation. - Applied to ramp (convert), lending (markets, market detail, risk) and cards/user detail. Removed the lossy
ramp-format.formatAmount(Number+Intl, lost digits past ~15).
Kept exact on purpose: forms and API payloads, market version diffs, audit, ramp fee band config, ramp rebalance shortfall and rail floor (ops acts on them), the lending withdraw "≤ available" hint.
Behaviour changes: card amounts were half-up at 2 dp, now round down. USDC/USDT/DAI lending markets show 2 dp instead of 6.
Test plan
-
pnpm test(571 tests),pnpm type-check,pnpm lint:check(0 errors) -
Mutation check: switching truncation to half-up fails 21 tests -
Opus review gate: PASS after 2 rounds (round 2 NITs fixed in 78559572) -
Local admin: lending markets / market detail / convert / cards render short amounts with full-value tooltips, no horizontal page overflow