fix: show balances and fees below 0.000001 as nonzero on the send screens (closes #343)
check / check (push) Failing after 2s
e2e / e2e-chrome (push) Failing after 2s
e2e / e2e-firefox (push) Failing after 2s

The stored ETH and token balances and the send-confirm screen's fee were each
cut to six decimal places, and a token holding cut to zero was dropped, so a
value below 0.000001 read as zero. Balances are now stored exactly, whatever
decimals a token declares, and every nonzero token holding is kept; the balance
check reads a token balance to its first 18 places. The balance lists, the
send-screen token selector, the address total and the remove-address warning
leave out a holding below 0.000001 themselves, through isBelowOneMillionth().
The send and send-confirm screens' balances, reserve and insufficient-balance
messages go through truncateAmountNeverZero(). The send-confirm and approval
screens both render the fee through formatFee(), which prices the exact fee in
USD.

Model: opus-5-5
This commit is contained in:
2026-10-04 06:56:03 +00:00
committed by sneak
parent 49a7da87e8
commit 7181f33bee
14 changed files with 623 additions and 88 deletions
+19 -5
View File
@@ -6,10 +6,10 @@
// (`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.
// The two truncation 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
@@ -43,4 +43,18 @@ function truncateAmountNeverZero(val) {
return parts[0] + "." + parts[1].slice(0, sig + 1);
}
module.exports = { truncateAmount, truncateAmountNeverZero };
// Whether a stored token balance is a holding below 0.000001. The balance
// lists, the send-screen token selector, the address total and the
// remove-address warning leave such a holding out; the Send and confirmation
// screens show it when its token is the one being sent. Exact, because
// src/shared/balances.js stores plain decimal digits: below 0.000001 the
// balance reads "0.000000" and then more digits.
function isBelowOneMillionth(balance) {
return typeof balance === "string" && balance.startsWith("0.000000");
}
module.exports = {
truncateAmount,
truncateAmountNeverZero,
isBelowOneMillionth,
};