// The 4-decimal amount rule from README.md's Display Consistency section, and // the one exception to it, in one place. Three call sites had grown their own // copy of the truncation — the history and balance lists // (`src/shared/transactions.js`), the approval screen's ERC-20 amount line // (`src/popup/views/approval.js`) and its Uniswap swap detail lines // (`src/shared/uniswap.js`) — and a fix applied to one of them left the other // two showing a different number for the same value. // // The two functions below are the two policies, not two implementations of // one: summary lists truncate, and the screens that state what is being // authorized truncate with a floor. Keeping them adjacent is the point, so a // change to the rule cannot reach one screen and miss another. // Truncate to exactly four decimal places. Truncation, never rounding: an // amount must never be displayed as larger than it is, so 0.99999 stays // 0.9999. function truncateAmount(val) { const parts = val.split("."); if (parts.length === 1) return val + ".0000"; return parts[0] + "." + (parts[1] + "0000").slice(0, 4); } // The same rule, plus the invariant the approval and confirmation screens // hold: a nonzero amount never renders as zero. Truncating to four decimals // does exactly that to an amount below 0.0001 — one base unit of an 18-decimal // token, 500 of an 8-decimal one — and a real transfer or allowance then reads // as "nothing is being moved" on the screen whose whole job is to say what is // being authorized. // // When the truncated string carries no significant digit and the value does, // the amount is extended to its first significant digit instead. It stays in // token units, the same unit as the symbol printed beside it. A genuine zero // still renders 0.0000, and anything at or above the floor is untouched. function truncateAmountNeverZero(val) { const truncated = truncateAmount(val); // Tests the whole truncated string, integer part included: 1.00005 has a // significant digit already and stays 1.0000. if (/[1-9]/.test(truncated)) return truncated; const parts = val.split("."); if (parts.length === 1) return truncated; const sig = parts[1].search(/[1-9]/); if (sig === -1) return truncated; return parts[0] + "." + parts[1].slice(0, sig + 1); } module.exports = { truncateAmount, truncateAmountNeverZero };