Compare commits

..

2 Commits

Author SHA1 Message Date
user
1df770d3b6 fix: prevent double symbol display on swap tx broadcast/status views
All checks were successful
check / check (push) Successful in 22s
For Uniswap swaps, the decoded Amount value includes the token symbol
(e.g. '2.0000 USDT'). The tx status view then appended 'ETH' because
pendingTxDetails.token remained 'ETH' (router address is not a token).

Fix:
- Add rawValue (numeric-only) to uniswap decoder's Amount detail
- Extract Token In address from decoded details in approval.js to set
  the correct token/tokenSymbol on pendingTxDetails for swaps
- The existing d.rawValue || d.value pattern now picks up the clean
  numeric value, and symbol comes from tokenSymbol
2026-02-28 11:30:44 -08:00
clawbot
607d2349b0 fix: prevent double symbol display on tx broadcast status views
All checks were successful
check / check (push) Successful in 22s
The decodeCalldata function in approval.js was embedding the token symbol
into the Amount value string (e.g. '2.0000 USDT'). This value was then
assigned to pendingTxDetails.amount, and txStatus.js would append the
symbol again, producing '2.0000 USDT ETH' (or '2.0000 USDT USDT' when
the token was in TOKEN_BY_ADDRESS).

Fix: decodeCalldata now provides a rawValue field (numeric only) on
Amount details. pendingTxDetails.amount uses rawValue when available,
so txStatus.js can append the correct symbol exactly once.

Affected paths:
- approve() decoded amount (approve calldata)
- transfer() decoded amount (transfer calldata)
- pendingTxDetails.amount assignment

Audited all other amount+symbol display sites:
- txStatus.js showWait/showSuccess/showError: correctly derive symbol
  from txInfo.token, no duplication
- confirmTx.js show(): builds symbol independently, amount is raw — OK
- send.js: amount is raw user input — OK
- addressToken.js: uses balanceLine helper — OK
- transactions.js parseTx/parseTokenTransfer: separate value/symbol — OK

Fixes #59
2026-02-28 11:27:26 -08:00
2 changed files with 41 additions and 11 deletions

View File

@@ -78,10 +78,12 @@ function decodeCalldata(data, toAddress) {
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
); );
const isUnlimited = rawAmount === maxUint; const isUnlimited = rawAmount === maxUint;
const amountRaw = isUnlimited
? "Unlimited"
: formatTxValue(formatUnits(rawAmount, tokenDecimals));
const amountStr = isUnlimited const amountStr = isUnlimited
? "Unlimited" ? "Unlimited"
: formatTxValue(formatUnits(rawAmount, tokenDecimals)) + : amountRaw + (tokenSymbol ? " " + tokenSymbol : "");
(tokenSymbol ? " " + tokenSymbol : "");
return { return {
name: "Token Approval", name: "Token Approval",
@@ -100,7 +102,11 @@ function decodeCalldata(data, toAddress) {
value: spender, value: spender,
address: spender, address: spender,
}, },
{ label: "Amount", value: amountStr }, {
label: "Amount",
value: amountStr,
rawValue: amountRaw,
},
], ],
}; };
} }
@@ -108,9 +114,11 @@ function decodeCalldata(data, toAddress) {
if (parsed.name === "transfer") { if (parsed.name === "transfer") {
const to = parsed.args[0]; const to = parsed.args[0];
const rawAmount = parsed.args[1]; const rawAmount = parsed.args[1];
const amountRaw = formatTxValue(
formatUnits(rawAmount, tokenDecimals),
);
const amountStr = const amountStr =
formatTxValue(formatUnits(rawAmount, tokenDecimals)) + amountRaw + (tokenSymbol ? " " + tokenSymbol : "");
(tokenSymbol ? " " + tokenSymbol : "");
return { return {
name: "Token Transfer", name: "Token Transfer",
@@ -125,7 +133,11 @@ function decodeCalldata(data, toAddress) {
isToken: true, isToken: true,
}, },
{ label: "Recipient", value: to, address: to }, { label: "Recipient", value: to, address: to },
{ label: "Amount", value: amountStr }, {
label: "Amount",
value: amountStr,
rawValue: amountRaw,
},
], ],
}; };
} }
@@ -155,20 +167,31 @@ function showTxApproval(details) {
tokenSymbol: token ? token.symbol : null, tokenSymbol: token ? token.symbol : null,
}; };
// If this is an ERC-20 call, try to extract the real recipient and amount // If this is an ERC-20 call or a swap, extract the real recipient, amount, and token info
const decoded = decodeCalldata(details.txParams.data, toAddr || ""); const decoded = decodeCalldata(details.txParams.data, toAddr || "");
if (decoded && decoded.details) { if (decoded && decoded.details) {
let decodedTokenSymbol = null;
let decodedTokenAddress = null;
for (const d of decoded.details) { for (const d of decoded.details) {
if (d.label === "Recipient" && d.address) { if (d.label === "Recipient" && d.address) {
pendingTxDetails.to = d.address; pendingTxDetails.to = d.address;
} }
if (d.label === "Amount") { if (d.label === "Amount") {
pendingTxDetails.amount = d.value; pendingTxDetails.amount = d.rawValue || d.value;
}
if (d.label === "Token In" && !decodedTokenSymbol) {
// Extract token symbol and address from decoded details
decodedTokenSymbol = d.value;
if (d.address) decodedTokenAddress = d.address;
} }
} }
if (token) { if (token) {
pendingTxDetails.token = toAddr; pendingTxDetails.token = toAddr;
pendingTxDetails.tokenSymbol = token.symbol; pendingTxDetails.tokenSymbol = token.symbol;
} else if (decodedTokenAddress) {
// For swaps through routers: use the input token info
pendingTxDetails.token = decodedTokenAddress;
pendingTxDetails.tokenSymbol = decodedTokenSymbol;
} }
} }

View File

@@ -445,12 +445,19 @@ function decode(data, toAddress) {
const maxUint160 = BigInt( const maxUint160 = BigInt(
"0xffffffffffffffffffffffffffffffffffffffff", "0xffffffffffffffffffffffffffffffffffffffff",
); );
const rawAmount =
inputAmount >= maxUint160
? "Unlimited"
: formatAmount(inputAmount, inInfo.decimals);
const amountStr = const amountStr =
inputAmount >= maxUint160 inputAmount >= maxUint160
? "Unlimited" ? "Unlimited"
: formatAmount(inputAmount, inInfo.decimals) + : rawAmount + (inSymbol ? " " + inSymbol : "");
(inSymbol ? " " + inSymbol : ""); details.push({
details.push({ label: "Amount", value: amountStr }); label: "Amount",
value: amountStr,
rawValue: rawAmount,
});
} }
if (outSymbol) { if (outSymbol) {