mirror of
https://github.com/luxfi/explore.git
synced 2026-10-30 16:57:53 +00:00
LUX_DECIMALS was 6 in four separate files, each dividing a value the code itself names nanoLux. Nano is 10^-9. Every staking and balance figure the Lux explorer rendered was inflated by 1000. The validators page reported 2,500,000,000,000 LUX staked — against a total supply of ~2T. An impossible number, and it is reached from lux.cloud's own "View on explorer" link: an investor reads 2.5B on the dashboard, clicks through, and sees 2.5T. lux.cloud was right; this was wrong. Verified against live chain state (platform.getCurrentValidators): 500000000000000000 nLUX -> 500,000,000 LUX per validator 2500000000000000000 nLUX -> 2,500,000,000 LUX total across 5 Four copies of one constant, so the bug shipped four times: ui/validators/lux/utils.ts · ui/chains/ChainDetailPage.tsx ui/pages/NetworkOverview.tsx · ui/stats/lux/NetworkStats.tsx Each still owns its own copy; they should share one, which is the follow-up. Typecheck shows no new errors in these files (the existing _app.tsx and *.pw.tsx failures predate this change).
32 lines
1.3 KiB
TypeScript
32 lines
1.3 KiB
TypeScript
// Formatting helpers for Lux P-chain validator data.
|
||
|
||
// nLUX is NANO-LUX: 10^9 nLUX = 1 LUX. This was 6, which multiplied every
|
||
// staking figure on the page by 1000 — the validators page reported
|
||
// 2,500,000,000,000 LUX staked against a ~2T total supply, i.e. an
|
||
// arithmetically impossible number, reached from lux.cloud's own
|
||
// "View on explorer" link. The parameter below is named nanoLux; trust it.
|
||
const LUX_DECIMALS = 9;
|
||
const TRUNCATE_PREFIX_LEN = 12;
|
||
const TRUNCATE_SUFFIX_LEN = 6;
|
||
const UPTIME_FRACTION_DIGITS = 2;
|
||
const STAKE_FRACTION_DIGITS = 2;
|
||
|
||
export function formatStake(nanoLux: bigint | string): string {
|
||
const raw = typeof nanoLux === 'string' ? nanoLux : String(nanoLux);
|
||
const lux = Number(BigInt(raw)) / Math.pow(10, LUX_DECIMALS);
|
||
return lux.toLocaleString(undefined, { maximumFractionDigits: STAKE_FRACTION_DIGITS });
|
||
}
|
||
|
||
export function formatUptime(uptime: string): string {
|
||
// uptime is already in percentage format (0–100), no scaling needed
|
||
return `${ parseFloat(uptime).toFixed(UPTIME_FRACTION_DIGITS) }%`;
|
||
}
|
||
|
||
export function truncateNodeId(nodeId: string): string {
|
||
const minLength = TRUNCATE_PREFIX_LEN + TRUNCATE_SUFFIX_LEN + 3;
|
||
if (nodeId.length <= minLength) {
|
||
return nodeId;
|
||
}
|
||
return `${ nodeId.slice(0, TRUNCATE_PREFIX_LEN) }...${ nodeId.slice(-TRUNCATE_SUFFIX_LEN) }`;
|
||
}
|