Portfolio page: realized P&L, cost basis, volume and fees are shown in raw base units and summed across pairs with different quote tokens #551

Closed
opened 2026-08-17 13:07:07 +00:00 by leonardocolucci · 19 comments
leonardocolucci commented 2026-08-17 13:07:07 +00:00 (Migrated from gitlab.com)

Where: /portfolio (and the public Trader page it links to) — the P&L Summary and Open Positions cards.

What's wrong:

  1. Per-pair values (realized P&L, cost basis, avg entry, volume, fees) are the indexer's raw integer amounts — no scaling by the quote token's decimals. A 6-decimal quote shows "38.29M" for what is 38.29 tokens; cLUNC-quoted rows show figures in the billions.
  2. The header totals ("Total realized P&L", "Total volume", "Total fees paid") add those raw per-pair numbers together even though each pair has a different quote token (e.g. cUSTC + a gem + UST1). The total is unitless and misleading — it reads like a large positive P&L when the underlying is cents.
  3. "Avg entry" on cLUNC-quoted pairs is the unscaled base-unit ratio (tens of thousands), not a price.

Repro: open Portfolio for any wallet that has swapped on both a 6-dec/6-dec pair (UST1/cUSTC) and cLUNC/UST1; compare the per-row values against the actual amounts in the wallet's tx history.

Likely cause: same class as #522 (price/chart/tape scaled and converted after launch) — the Portfolio/Trader views still consume the indexer's raw quote-exposure fields.

Suggested fix: scale each row by its quote token's decimals and label the quote symbol; only aggregate across pairs after converting to USD (or drop the cross-pair totals and show per-pair only). Worth doing before the page is used as a public trader leaderboard, since the current numbers rank by whoever traded the smallest-unit token.

**Where:** `/portfolio` (and the public Trader page it links to) — the P&L Summary and Open Positions cards. **What's wrong:** 1. Per-pair values (realized P&L, cost basis, avg entry, volume, fees) are the indexer's raw integer amounts — no scaling by the quote token's decimals. A 6-decimal quote shows "38.29M" for what is 38.29 tokens; cLUNC-quoted rows show figures in the billions. 2. The header totals ("Total realized P&L", "Total volume", "Total fees paid") add those raw per-pair numbers together even though each pair has a different quote token (e.g. cUSTC + a gem + UST1). The total is unitless and misleading — it reads like a large positive P&L when the underlying is cents. 3. "Avg entry" on cLUNC-quoted pairs is the unscaled base-unit ratio (tens of thousands), not a price. **Repro:** open Portfolio for any wallet that has swapped on both a 6-dec/6-dec pair (UST1/cUSTC) and cLUNC/UST1; compare the per-row values against the actual amounts in the wallet's tx history. **Likely cause:** same class as #522 (price/chart/tape scaled and converted after launch) — the Portfolio/Trader views still consume the indexer's raw quote-exposure fields. **Suggested fix:** scale each row by its quote token's decimals and label the quote symbol; only aggregate across pairs after converting to USD (or drop the cross-pair totals and show per-pair only). Worth doing before the page is used as a public trader leaderboard, since the current numbers rank by whoever traded the smallest-unit token.
PlasticDigits commented 2026-08-18 00:28:53 +00:00 (Migrated from gitlab.com)

mentioned in issue #556

mentioned in issue #556
PlasticDigits commented 2026-08-18 00:29:03 +00:00 (Migrated from gitlab.com)

mentioned in issue #557

mentioned in issue #557
PlasticDigits commented 2026-08-18 02:08:27 +00:00 (Migrated from gitlab.com)

mentioned in merge request !1082

mentioned in merge request !1082
PlasticDigits commented 2026-08-18 02:30:14 +00:00 (Migrated from gitlab.com)

mentioned in merge request !1083

mentioned in merge request !1083
PlasticDigits commented 2026-08-18 03:06:05 +00:00 (Migrated from gitlab.com)

mentioned in commit 0993d1926c

mentioned in commit 0993d1926c581eb6717276f194796bb581a8b6c1
PlasticDigits commented 2026-08-18 03:06:24 +00:00 (Migrated from gitlab.com)

mentioned in commit eed4be8d11

mentioned in commit eed4be8d114c26b3f92e2392eea8ba849ae6496d
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-08-18 03:06:25 +00:00
PlasticDigits commented 2026-08-18 03:08:39 +00:00 (Migrated from gitlab.com)

mentioned in commit da70fed37d

mentioned in commit da70fed37df41aaa111a242457875cfd9cf85ad6
PlasticDigits commented 2026-08-18 03:11:24 +00:00 (Migrated from gitlab.com)

Merged in !1082. Combined with !1081: header Total Volume (USD) uses catalog USD; fees / best / worst stay —; realized P&L is a USD sum of per-pair human base via P522-Q helper.

Shipped vs #551 AC: per-pair net/cost/P&L/avg entry scaled by decimals and labeled; avg entry is raw × 10^(d1−d0); missing decimals → — (never assume 6); JSON positions stay raw + asset_*_decimals.

USTR 2.5× comment on !1082: that invariant belongs to #556 / !1083 (USTR is market-priced from largest USD-TVL hub pool, not a fixed peg). Documented there (H3 + oracle runbook).

Problem remaining after !1083: /portfolio Total realized P&L USD still goes through frontend quoteTokenUsd (UST1 = $1, USTR = 2.5 × USTC) in traderPositionDisplay.ts, not GET /api/v1/hub-prices. Per-pair human token amounts are correct; the header USD total can disagree with hub marks. Follow-up issue after !1080–!1084.

Manual mixed-decimal /portfolio QA still needed after production indexer+frontend deploy.

Merged in !1082. Combined with !1081: header **Total Volume (USD)** uses catalog USD; fees / best / worst stay `—`; realized P&L is a USD sum of per-pair human base via P522-Q helper. **Shipped vs #551 AC:** per-pair net/cost/P&L/avg entry scaled by decimals and labeled; avg entry is `raw × 10^(d1−d0)`; missing decimals → `—` (never assume 6); JSON positions stay raw + `asset_*_decimals`. **USTR 2.5× comment on !1082:** that invariant belongs to #556 / !1083 (USTR is market-priced from largest USD-TVL hub pool, not a fixed peg). Documented there (H3 + oracle runbook). **Problem remaining after !1083:** `/portfolio` **Total realized P&L** USD still goes through frontend `quoteTokenUsd` (`UST1 = $1`, `USTR = 2.5 × USTC`) in `traderPositionDisplay.ts`, not `GET /api/v1/hub-prices`. Per-pair human token amounts are correct; the header USD total can disagree with hub marks. Follow-up issue after !1080–!1084. Manual mixed-decimal `/portfolio` QA still needed after production indexer+frontend deploy.
PlasticDigits commented 2026-08-18 03:12:08 +00:00 (Migrated from gitlab.com)

mentioned in issue #560

mentioned in issue #560
PlasticDigits commented 2026-08-18 03:12:08 +00:00 (Migrated from gitlab.com)

marked as related to #560

marked as related to #560
PlasticDigits commented 2026-08-18 03:12:53 +00:00 (Migrated from gitlab.com)

Post-merge follow-up: #560

Post-merge follow-up: #560
PlasticDigits commented 2026-08-18 03:14:34 +00:00 (Migrated from gitlab.com)

Post-merge review extras (after !1082 landed with !1081 volume USD):

  1. P551-5 glyph: Best/Worst still render N/A via PnlValue(null) (PnlValue.tsx), while fees use —. Invariant says em dash for mixed totals.
  2. Missing asset row drops the position: GET /traders/{addr}/positions uses filter_map + asset_map.get (traders.rs). A missing asset hides the row instead of returning it with empty decimals (UI would then show —).
  3. Header realized P&L is — until positions resolve (null vs empty array). Cosmetic.

Hub USD for that header is already on #560. Items 1–2 should be included there.

Post-merge review extras (after !1082 landed with !1081 volume USD): 1. **P551-5 glyph:** Best/Worst still render `N/A` via `PnlValue(null)` (`PnlValue.tsx`), while fees use `—`. Invariant says em dash for mixed totals. 2. **Missing asset row drops the position:** `GET /traders/{addr}/positions` uses `filter_map` + `asset_map.get` (`traders.rs`). A missing asset hides the row instead of returning it with empty decimals (UI would then show `—`). 3. Header realized P&L is `—` until positions resolve (null vs empty array). Cosmetic. Hub USD for that header is already on #560. Items 1–2 should be included there.
PlasticDigits commented 2026-08-18 12:13:08 +00:00 (Migrated from gitlab.com)

mentioned in issue #565

mentioned in issue #565
PlasticDigits commented 2026-08-19 01:12:33 +00:00 (Migrated from gitlab.com)

mentioned in merge request !1093

mentioned in merge request !1093
PlasticDigits commented 2026-08-22 03:10:05 +00:00 (Migrated from gitlab.com)

mentioned in issue #589

mentioned in issue #589
PlasticDigits commented 2026-08-26 01:11:06 +00:00 (Migrated from gitlab.com)

mentioned in issue #653

mentioned in issue #653
PlasticDigits commented 2026-08-26 03:08:08 +00:00 (Migrated from gitlab.com)

mentioned in issue #657

mentioned in issue #657
leonardocolucci commented 2026-08-26 21:37:47 +00:00 (Migrated from gitlab.com)

mentioned in issue #674

mentioned in issue #674
leonardocolucci commented 2026-08-26 22:01:09 +00:00 (Migrated from gitlab.com)

mentioned in issue #675

mentioned in issue #675
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-dex-terraclassic#551
No description provided.