fix(frontend): resolve fee-token decimals dynamically in FeeTransparency (GitLab #110) #379

Merged
Brouie merged 1 commit from fix/glab-110-fee-transparency-decimals into main 2026-05-07 12:00:07 +00:00
Brouie commented 2026-05-07 05:07:44 +00:00 (Migrated from gitlab.com)

closes #110.

what changed

frontend/src/components/FeeTransparency.tsx — replace hardcoded 18 dp on both the per-tx amount render and the per-sink shares formatting with a useReadContracts lookup keyed on the unique row.token addresses in the visible feesDistributed feed.

  1. new feeTokenAddrs memo deduplicates token addresses from the current feed page
  2. useReadContracts calls erc20Abi.decimals() for each unique address; gated on feeTokenAddrs.length > 0
  3. new feeTokenDecimalsByAddr map exposes address → decimals
  4. inline render: formatCompactFromRaw(rawToBigIntForFormat(row.amount), feeTokenDecimalsByAddr.get(row.token) ?? 18)
  5. formatFeeSharesJsonForDisplay signature gains a decimals: number parameter; caller passes feeTokenDecimalsByAddr.get(row.token) ?? 18
  6. inline comment at the feed map updated to document the new behavior

18 stays as the fallback for cold-load before the decimals reads resolve — preserves current display on the live CL8Y deployment which is 18-dp anyway. uses the existing erc20Abi (already exposes decimals() view returns (uint8)) — no new ABI added.

why

FeeRouter.distributeFees(IERC20 token, uint256 amount) is token-agnostic at the contract level — operators can route any ERC20 through it. before this MR, a future TimeCurve instance with a non-18-dp accepted asset (USDC at 6, etc.) would silently render 1.0 USDC as 0.000001 USDC — 12 orders of magnitude off. no crash, no onchain incorrectness, just silent display drift on a trust-sensitive panel. the existing acceptedAsset for the live YO deployment is configurable per-TimeCurve, so this is a multi-deployment concern even though today it does not bite.

per @PlasticDigits in #110: low priority for the current launch (CL8Y is 18-dp), but flagged as needing fix before launchpad conversion. landing it now while the change is small.

verification

  • npm run typecheck clean.
  • npm test -- --run — 50 files / 295 passed (no regressions, baseline unchanged).
  • npm run lint — 0 errors. one pre-existing fast-refresh warning in IndexerConnectivityContext.tsx untouched.

display behavior

  • live CL8Y deployment (18 dp): renders identically to pre-patch — fallback 18 hits during the brief window before the read resolves, then the read returns 18 too
  • non-18 dp future deployments: correct decimals applied per-token; no silent drift
  • multi-token feed pages (e.g. multiple TimeCurve instances or FeeRouter routing distinct ERC20s in one block range): each row uses its own token decimals, deduplicated via feeTokenAddrs so the read batch stays bounded by unique tokens not row count

cc @PlasticDigits

closes #110. ## what changed `frontend/src/components/FeeTransparency.tsx` — replace hardcoded `18` dp on both the per-tx `amount` render and the per-sink `shares` formatting with a `useReadContracts` lookup keyed on the unique `row.token` addresses in the visible `feesDistributed` feed. 1. new `feeTokenAddrs` memo deduplicates token addresses from the current feed page 2. `useReadContracts` calls `erc20Abi.decimals()` for each unique address; gated on `feeTokenAddrs.length > 0` 3. new `feeTokenDecimalsByAddr` map exposes `address → decimals` 4. inline render: `formatCompactFromRaw(rawToBigIntForFormat(row.amount), feeTokenDecimalsByAddr.get(row.token) ?? 18)` 5. `formatFeeSharesJsonForDisplay` signature gains a `decimals: number` parameter; caller passes `feeTokenDecimalsByAddr.get(row.token) ?? 18` 6. inline comment at the feed map updated to document the new behavior `18` stays as the fallback for cold-load before the decimals reads resolve — preserves current display on the live CL8Y deployment which is 18-dp anyway. uses the existing `erc20Abi` (already exposes `decimals() view returns (uint8)`) — no new ABI added. ## why `FeeRouter.distributeFees(IERC20 token, uint256 amount)` is token-agnostic at the contract level — operators can route any ERC20 through it. before this MR, a future TimeCurve instance with a non-18-dp accepted asset (USDC at 6, etc.) would silently render `1.0 USDC` as `0.000001 USDC` — 12 orders of magnitude off. no crash, no onchain incorrectness, just silent display drift on a trust-sensitive panel. the existing `acceptedAsset` for the live YO deployment is configurable per-TimeCurve, so this is a multi-deployment concern even though today it does not bite. per @PlasticDigits in #110: low priority for the current launch (CL8Y is 18-dp), but flagged as needing fix before launchpad conversion. landing it now while the change is small. ## verification - `npm run typecheck` clean. - `npm test -- --run` — 50 files / 295 passed (no regressions, baseline unchanged). - `npm run lint` — 0 errors. one pre-existing fast-refresh warning in `IndexerConnectivityContext.tsx` untouched. ## display behavior - live CL8Y deployment (18 dp): renders identically to pre-patch — fallback 18 hits during the brief window before the read resolves, then the read returns 18 too - non-18 dp future deployments: correct decimals applied per-token; no silent drift - multi-token feed pages (e.g. multiple TimeCurve instances or FeeRouter routing distinct ERC20s in one block range): each row uses its own token decimals, deduplicated via `feeTokenAddrs` so the read batch stays bounded by unique tokens not row count cc @PlasticDigits
PlasticDigits commented 2026-05-07 12:00:07 +00:00 (Migrated from gitlab.com)

mentioned in commit efb6e0bce7

mentioned in commit efb6e0bce768d9482972681b935f6ec753941040
PlasticDigits (Migrated from gitlab.com) merged commit efb6e0bce7 into main 2026-05-07 12:00:07 +00:00
PlasticDigits commented 2026-05-13 15:13:33 +00:00 (Migrated from gitlab.com)

mentioned in commit d6bf0f9b9d

mentioned in commit d6bf0f9b9d6c67ae51102cdd0521a6cb921a9585
Sign in to join this conversation.
No reviewers
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/yieldomega!379
No description provided.