fix: a permit shows on its own lines unless its amount is the Amount figure (closes #370)
check / check (push) Canceled after 0s
e2e / e2e-chrome (push) Canceled after 0s
e2e / e2e-firefox (push) Canceled after 0s

A PERMIT2_PERMIT read after a step had set the input side named Token
In, and its amount could stand as the Amount figure, so the approval
screen could show an allowance where the swap's own input belonged. A
permit before the swap steps whose spender was not the router, or that
the router may let fail, had no line naming its spender.

A permit after the input side now leaves Token In and Amount to the
swap. Every permit whose amount does not stand as the Amount figure
gets three lines of its own: Permit2 allowance, Allowance token and
Allowance spender. README Transaction Decoding and the TxApproval
element list match.

Model: opus-5-5
This commit is contained in:
2026-10-20 20:19:08 +00:00
parent a3da448f0d
commit 292ebe544e
4 changed files with 331 additions and 75 deletions
+19 -4
View File
@@ -2809,7 +2809,7 @@ describe("the allow-revert flag", () => {
mark: " (allowed to fail)",
},
])(
"on $router, a PERMIT2_PERMIT with the flag is listed as 'Permit2 Permit$mark', and the swap reads as without the flag",
"on $router, a PERMIT2_PERMIT with the flag is listed as 'Permit2 Permit$mark', and the swap's lines read as without the flag",
({ address, mark }) => {
const steps = [
permit2Permit(USDT, USDT_2000),
@@ -2824,9 +2824,24 @@ describe("the allow-revert flag", () => {
expect(detail(withFlag, "Steps").value).toBe(
"Permit2 Permit" + mark + " → V3 Swap (Exact In)",
);
const withoutSteps = (r) =>
r.details.filter((d) => d.label !== "Steps");
expect(withoutSteps(withFlag)).toEqual(withoutSteps(plain));
// The permit names the router at ROUTER as its spender, so its
// amount stands as the Amount figure only there, and only without
// the flag. With the flag it stands on no router and gets lines
// of its own.
const permitLines = [
"Permit2 allowance",
"Allowance token",
"Allowance spender",
];
const swapLines = (r) =>
r.details.filter(
(d) =>
d.label !== "Steps" && !permitLines.includes(d.label),
);
expect(swapLines(withFlag)).toEqual(swapLines(plain));
expect(
labels(withFlag).filter((l) => permitLines.includes(l)),
).toEqual(permitLines);
expect(detail(withFlag, "Min. received").value).toBe("1.0000 WETH");
},
);