Amounts are truncated to four decimal places per README.md's Display Consistency rule. With the token's true scale resolved, an amount below 0.0001 still printed as 0.0000 — 1 base unit of an 18-decimal token, 500 base units of an 8-decimal one. On the dApp approval screen, and on the wait/success/error screens that carry the same string forward as txInfo.amount, a real transfer, allowance or swap was therefore stated as nothing. A swap's "Min. received" is the sharper case: a slippage floor shown as 0.0000 states that the swap may return nothing. That truncation existed in three separate copies — src/popup/views/approval.js (the ERC-20 amount, the ETH value, the max fee), src/shared/uniswap.js (the swap's Amount and Min. received lines, on that same screen) and src/shared/transactions.js (history and balance lists). They now share src/shared/amountDisplay.js, which holds the rule and its one exception side by side: truncateAmount() truncates, truncateAmountNeverZero() truncates with the nonzero floor. approval.js and uniswap.js take the floored function, so every amount those screens display or hand to the confirmation screens obeys the invariant. When the truncated string would carry no digit from 1 to 9 and the value does, the amount is extended to its first significant digit: 0.000000000000000001 DAI, not 0.0000 DAI. It stays in token units, the same unit as the symbol beside it; the base-unit rendering already on this screen means "the scale is unknown", and reusing it for a known scale would blur the two. A genuine zero still renders 0.0000, an amount at or above the floor is untouched, and truncation stays truncation — 0.99999 shows as 0.9999, never rounded up. transactions.js takes the unfloored function, keeping its current behaviour exactly: balance lists and history are out of scope by the issue's definition of done, and the transaction detail view already shows exact precision there. The code path is shared; the policy is not. tests/approvalDisplayFloor.test.js drives decodeCalldata() and uniswap.decode() and asserts both the displayed line and the rawValue the confirmation screens carry. Against this tree with src/shared/uniswap.js reverted to its previous formatAmount(), its two new swap cases fail: a 50-base-unit USDT input gives "0.0000 USDT" where "0.00005 USDT" is expected, and a 1-wei amountOutMin gives "0.0000 WETH" where "0.000000000000000001 WETH" is expected. A case pinning the list rule as unfloored is included so the shared module cannot drift into one policy. make check green: 42 suites, 848 tests; verify-build 39 cases; check-censored 153 files; eslint and prettier clean in the pinned container.
7.3 KiB
7.3 KiB