fix: a zero-minimum balance check never sets the output side (closes #649)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run

A BALANCE_CHECK_ERC20 of the sender with a zero minimum, or one the router lets fail, no longer sets Token Out or the minimum. Before, it set both whenever the output side held no minimum, so after an UNWRAP_WETH that drops the minimum, a zero check of USDC named USDC as Token Out, a token the swap did not pay. A check with a positive minimum, not allowed to fail, sets the output side as before. Two existing tests that expected the wrong token are corrected, and README states the rule.

Model: opus-5-5
This commit was merged in pull request #690.
This commit is contained in:
2026-10-27 08:57:59 +01:00
parent fc6cffcaba
commit f550d8c8d2
4 changed files with 92 additions and 34 deletions
+13 -7
View File
@@ -4380,10 +4380,9 @@ describe("uniswap decoder", () => {
expect(detail(result, "Min. received").value).toBe("2.0000 USDC");
});
// With no minimum stated before it, a zero balance check is what sets the
// output side, and it guarantees nothing. No step pays anyone, so the
// minimum is not said to be received.
test("a zero balance check with no earlier minimum states no minimum", () => {
// A zero balance check sets neither Token Out nor the minimum. The route
// pays only the WRAP_ETH's WETH, to the router, where it stays.
test("a zero balance check after a WRAP_ETH into the router names no output token and no minimum", () => {
const data = buildExecute(
solidityPacked(["uint8", "uint8"], [0x0b, 0x0e]),
[
@@ -4396,9 +4395,16 @@ describe("uniswap decoder", () => {
const result = uniswap.decode(data, ROUTER_ADDR, "0x1", {}, USER_ADDR);
expect(result).not.toBeNull();
expect(detail(result, "Token Out").value).toContain("USDT");
expect(detail(result, "Min. paid out").value).toBe(
"None (no minimum guaranteed)",
expect(detail(result, "Token Out").value).toBe(
"Unknown (not named in the calldata)",
);
expect(detail(result, "Min. paid out")).toBeUndefined();
expect(detail(result, "Min. received")).toBeUndefined();
expect(detail(result, "Paid to").value).toBe(
"The router, where it stays (no later step pays it out)",
);
expect(detail(result, "Token moved into the router").address).toBe(
WETH_ADDR,
);
});