From 58817738299f578d13d76ec4eb8c5108d59c3585 Mon Sep 17 00:00:00 2001 From: pucedoteth <119044801+pucedoteth@users.noreply.github.com> Date: Tue, 15 Sep 2026 20:45:42 +0200 Subject: [PATCH] fix(symbolConverter): return 0 szDecimals for outcome markets Outcome shares trade in whole units. The Hyperliquid app formats outcome markets with szDecimals 0, and live mainnet outcome trades, open orders and balances all have integer sizes. Reporting 5 let formatSize keep fractional share sizes and made formatPrice cap prices at 1 decimal (perp) or 3 decimals (spot), so a 0.29128 quote was truncated to 0.2 or 0.291. Co-Authored-By: Claude Opus 5 --- docs/utilities.md | 3 ++- src/utils/_symbolConverter.ts | 6 +++--- tests/utils/symbolConverter.test.ts | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/utilities.md b/docs/utilities.md index 631c7b7d..e4c57481 100644 --- a/docs/utilities.md +++ b/docs/utilities.md @@ -148,7 +148,8 @@ formatSize("0.00123456789", szDecimals); // "0.00123" For spot markets, `getSzDecimals` returns the `szDecimals` of the **base** token — which is what both formatters expect for an order on that pair. -Outcome markets carry no `szDecimals` metadata, so `getSzDecimals` always returns `5` for them. +Outcome markets carry no `szDecimals` metadata. Their shares trade in whole units, so `getSzDecimals` always returns `0` +for them. ### Spot pair IDs diff --git a/src/utils/_symbolConverter.ts b/src/utils/_symbolConverter.ts index 764da539..ba257824 100644 --- a/src/utils/_symbolConverter.ts +++ b/src/utils/_symbolConverter.ts @@ -221,8 +221,8 @@ export class SymbolConverter { if (!slug) return; this._nameToAssetId.set(slug, 100000000 + 10 * outcome.outcome + sideIdx); - // Outcome markets are absent from szDecimals metadata; they are all 5 - this._nameToSzDecimals.set(slug, 5); + // Outcome markets are absent from szDecimals metadata; shares trade in whole units + this._nameToSzDecimals.set(slug, 0); }); }); } @@ -355,7 +355,7 @@ export class SymbolConverter { * converter.getSzDecimals("BTC"); // → 5 * converter.getSzDecimals("HYPE/USDC"); // → 2 * converter.getSzDecimals("test:ABC"); // → 0 - * converter.getSzDecimals("btc-above-61720-yes-jun-08-0600"); // → 5 + * converter.getSzDecimals("btc-above-61720-yes-jun-08-0600"); // → 0 * ``` */ getSzDecimals(name: string): number | undefined { diff --git a/tests/utils/symbolConverter.test.ts b/tests/utils/symbolConverter.test.ts index 46a73d7c..fbdda917 100644 --- a/tests/utils/symbolConverter.test.ts +++ b/tests/utils/symbolConverter.test.ts @@ -293,7 +293,7 @@ Deno.test("SymbolConverter outcome markets", async (t) => { }); await t.step("getSzDecimals()", () => { - assertEquals(converter.getSzDecimals("nba-finals-game-3-san-antonio"), 5); - assertEquals(converter.getSzDecimals("2026-world-cup-champion-argentina-yes"), 5); + assertEquals(converter.getSzDecimals("nba-finals-game-3-san-antonio"), 0); + assertEquals(converter.getSzDecimals("2026-world-cup-champion-argentina-yes"), 0); }); });