Compare commits

..

1 Commits

Author SHA1 Message Date
user
5cac49e430 test: add V4 swap ERC20→ERC20 decoder regression test
Some checks failed
check / check (push) Has been cancelled
Adds a test that constructs a Uniswap V4 USDT→USDC swap using
SETTLE/SWAP_EXACT_IN_SINGLE/TAKE sub-actions inside a V4_SWAP command.
Without decodeV4Swap(), the output token would be unresolvable and the
swap name would not show 'USDT → USDC'. This test fails on the old code
and passes with the decodeV4Swap() fix.

Refs: #59
2026-02-28 11:22:06 -08:00
4 changed files with 6186 additions and 42 deletions

1
.gitignore vendored
View File

@@ -25,4 +25,3 @@ dist/
# Yarn
.yarn-integrity
package-lock.json

6175
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -78,12 +78,10 @@ function decodeCalldata(data, toAddress) {
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
);
const isUnlimited = rawAmount === maxUint;
const amountRaw = isUnlimited
? "Unlimited"
: formatTxValue(formatUnits(rawAmount, tokenDecimals));
const amountStr = isUnlimited
? "Unlimited"
: amountRaw + (tokenSymbol ? " " + tokenSymbol : "");
: formatTxValue(formatUnits(rawAmount, tokenDecimals)) +
(tokenSymbol ? " " + tokenSymbol : "");
return {
name: "Token Approval",
@@ -102,11 +100,7 @@ function decodeCalldata(data, toAddress) {
value: spender,
address: spender,
},
{
label: "Amount",
value: amountStr,
rawValue: amountRaw,
},
{ label: "Amount", value: amountStr },
],
};
}
@@ -114,11 +108,9 @@ function decodeCalldata(data, toAddress) {
if (parsed.name === "transfer") {
const to = parsed.args[0];
const rawAmount = parsed.args[1];
const amountRaw = formatTxValue(
formatUnits(rawAmount, tokenDecimals),
);
const amountStr =
amountRaw + (tokenSymbol ? " " + tokenSymbol : "");
formatTxValue(formatUnits(rawAmount, tokenDecimals)) +
(tokenSymbol ? " " + tokenSymbol : "");
return {
name: "Token Transfer",
@@ -133,11 +125,7 @@ function decodeCalldata(data, toAddress) {
isToken: true,
},
{ label: "Recipient", value: to, address: to },
{
label: "Amount",
value: amountStr,
rawValue: amountRaw,
},
{ label: "Amount", value: amountStr },
],
};
}
@@ -167,31 +155,20 @@ function showTxApproval(details) {
tokenSymbol: token ? token.symbol : null,
};
// If this is an ERC-20 call or a swap, extract the real recipient, amount, and token info
// If this is an ERC-20 call, try to extract the real recipient and amount
const decoded = decodeCalldata(details.txParams.data, toAddr || "");
if (decoded && decoded.details) {
let decodedTokenSymbol = null;
let decodedTokenAddress = null;
for (const d of decoded.details) {
if (d.label === "Recipient" && d.address) {
pendingTxDetails.to = d.address;
}
if (d.label === "Amount") {
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;
pendingTxDetails.amount = d.value;
}
}
if (token) {
pendingTxDetails.token = toAddr;
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,19 +445,12 @@ function decode(data, toAddress) {
const maxUint160 = BigInt(
"0xffffffffffffffffffffffffffffffffffffffff",
);
const rawAmount =
inputAmount >= maxUint160
? "Unlimited"
: formatAmount(inputAmount, inInfo.decimals);
const amountStr =
inputAmount >= maxUint160
? "Unlimited"
: rawAmount + (inSymbol ? " " + inSymbol : "");
details.push({
label: "Amount",
value: amountStr,
rawValue: rawAmount,
});
: formatAmount(inputAmount, inInfo.decimals) +
(inSymbol ? " " + inSymbol : "");
details.push({ label: "Amount", value: amountStr });
}
if (outSymbol) {