harden: resolve or refuse the swap token scale instead of guessing 18 (closes #340)
All checks were successful
check / check (push) Successful in 29s
e2e / e2e-chrome (push) Successful in 1m47s
e2e / e2e-firefox (push) Successful in 31s

tokenInfo() returned decimals 18 for any token absent from the bundled list, so the swap approval line rendered a real 1000.00 of a 6-decimal token as 0.000000000001. The scale is now resolved from what the wallet already holds (bundled list, tracked tokens, explorer-reported decimals) or refused outright, matching the rule set for the ERC-20 path in #306. A refusal reuses unknownDecimalsAmount(), so it reads as "base units (decimals unknown)" with no decimal point and no symbol, and the same string propagates to rawValue so no downstream screen can render a figure the approval screen refused. No new network call on the approval path. Verified green on all three CI contexts: check, e2e-chrome, e2e-firefox.
This commit was merged in pull request #345.
This commit is contained in:
2026-08-23 16:20:22 +02:00
parent 769f6a5289
commit 43784cab3f
6 changed files with 271 additions and 23 deletions

View File

@@ -73,6 +73,14 @@ function tokenLabel(address) {
function decodeCalldata(data, toAddress) {
if (!data || data === "0x" || data.length < 10) return null;
// Where a token's scale is looked for, for every decoder below: the ERC-20
// amount line and the swap's Amount and Min. received lines resolve it the
// same way, and refuse to format the same way when it is nowhere.
const decimalsSources = {
trackedTokens: state.trackedTokens,
wallets: state.wallets,
};
// Try ERC-20 (approve / transfer)
try {
const parsed = erc20Iface.parseTransaction({ data });
@@ -84,10 +92,10 @@ function decodeCalldata(data, toAddress) {
// the wrong number, and for a token with fewer decimals than the
// guess it is the wrong number in the direction that reads as
// zero. See tokenAmountText().
const tokenDecimals = resolveTokenDecimals(toAddress, {
trackedTokens: state.trackedTokens,
wallets: state.wallets,
});
const tokenDecimals = resolveTokenDecimals(
toAddress,
decimalsSources,
);
const contractLabel = tokenSymbol
? tokenSymbol + " (" + toAddress + ")"
: toAddress;
@@ -167,7 +175,7 @@ function decodeCalldata(data, toAddress) {
}
// Try Uniswap Universal Router
const routerResult = uniswap.decode(data, toAddress);
const routerResult = uniswap.decode(data, toAddress, decimalsSources);
if (routerResult) return routerResult;
return null;