fix: a V4 SETTLE of ETH paid from the router reads as moved from the sender (closes #682)
check / check (push) Waiting to run
e2e / e2e-chrome (push) Waiting to run
e2e / e2e-firefox (push) Waiting to run

V4Router pays a SETTLE of ETH from the router's own ETH, whichever payer it names, and the router holds the transaction's value. A V4 SETTLE of ETH that names the router as payer now counts as ETH the user pays. With no ETH left in the router by an earlier step, it reads as a SETTLE the user pays. When an earlier step left ETH there, it gets lines of its own reading Up to and the amount. When the amount is not known, as for CONTRACT_BALANCE, its Moved from the sender line reads Unknown (could not be decoded). No line now shows less ETH than such a SETTLE can take.

Model: opus-5-5
This commit was merged in pull request #686.
This commit is contained in:
2026-10-27 06:49:37 +01:00
parent 36b200247a
commit ec6b6b57a3
4 changed files with 315 additions and 111 deletions
+29 -9
View File
@@ -1661,9 +1661,18 @@ describe("any token left in the router is not received", () => {
),
min: "1990.0000 USDC",
},
{
kind: "a swap paying WETH to the router, an UNWRAP_WETH into the router, then a V4 swap settling all the ETH from the router",
data: execute(
])("$kind reads as a swap paid to the user", ({ data, min }) => {
const result = decode(data);
expect(labels(result)).toEqual(PAID_TO_USER);
expect(detail(result, "Min. received").value).toBe(min);
});
// https://git.eeqj.de/sneak/AutistMask/issues/682 — the SETTLE spends all
// the router's ETH, the transaction's value included, so the sender pays
// an amount the calldata does not state.
test("a swap paying WETH to the router, an UNWRAP_WETH into the router, then a V4 swap settling all the ETH from the router reads as a swap paid to the user", () => {
const result = decode(
execute(
swapToWeth(ADDRESS_THIS),
unwrapWeth(ADDRESS_THIS),
v4Swap(
@@ -1672,12 +1681,23 @@ describe("any token left in the router is not received", () => {
takeAll(USDC),
),
),
min: "1990.0000 USDC",
},
])("$kind reads as a swap paid to the user", ({ data, min }) => {
const result = decode(data);
expect(labels(result)).toEqual(PAID_TO_USER);
expect(detail(result, "Min. received").value).toBe(min);
);
expect(labels(result)).toEqual([
"Protocol",
"Token In",
"Amount",
"Moved from the sender",
"Token moved",
"Moved to",
"Token Out",
"Min. received",
"Steps",
"Deadline",
]);
expect(detail(result, "Moved from the sender").value).toBe(
"Unknown (could not be decoded)",
);
expect(detail(result, "Min. received").value).toBe("1990.0000 USDC");
});
});