fix: a PERMIT2_TRANSFER_FROM shows the swap's unknown first take beside its figure (closes #634)
check / check (push) Canceled after 0s
e2e / e2e-chrome (push) Canceled after 0s
e2e / e2e-firefox (push) Canceled after 0s

When the step that sets the input side states no amount, a
PERMIT2_TRANSFER_FROM of the same token still showed its own figure,
which was then the only amount of that token on the screen. The rule
that adds the line saying the first take is not known now also applies
when such a move gives a figure of that token, before or after the
swap step. A move of another token, and a move into the router, read as
before.

Model: opus-5-5
This commit is contained in:
2026-10-20 08:14:33 +00:00
parent 657dc14f04
commit c13385b270
3 changed files with 62 additions and 7 deletions
+50
View File
@@ -2423,6 +2423,56 @@ describe("uniswap decoder", () => {
},
);
// https://git.eeqj.de/sneak/AutistMask/issues/634 — a
// PERMIT2_TRANSFER_FROM of the token the V4 exact-out step spends,
// before or after it, shows its own figure, so the step's amount is
// shown as not known beside it, and the 400 USDT cannot read as all
// that leaves. On next only the 400 USDT was shown.
const transferTo = (token, amount) =>
coder.encode(
["address", "address", "uint160"],
[token, OTHER_ADDR, amount],
);
const MOVED_400_USDT = [
["Moved from the sender", "400.0000 USDT"],
["Token moved", "USDT (" + USDT_ADDR + ")"],
["Moved to", OTHER_ADDR],
];
test.each([
{
kind: "a V4 exact-out step of at most 600 USDT, then a PERMIT2_TRANSFER_FROM of 400 USDT to another address",
commands: [0x10, 0x02],
inputs: [V4_EXACT_OUT_600, transferTo(USDT_ADDR, USDT_400)],
},
{
kind: "a PERMIT2_TRANSFER_FROM of 400 USDT to another address, then a V4 exact-out step of at most 600 USDT",
commands: [0x02, 0x10],
inputs: [transferTo(USDT_ADDR, USDT_400), V4_EXACT_OUT_600],
},
])(
"$kind, paid by the user, shows that the step's amount is not known",
({ commands, inputs }) => {
const result = decodeSteps(commands, inputs);
expect(linesBetweenTokens(result)).toEqual([
...UNKNOWN_USDT,
...MOVED_400_USDT,
]);
},
);
// A move of another token says nothing of how much USDT leaves.
test("a V4 exact-out step of at most 600 USDT, then a PERMIT2_TRANSFER_FROM of 400 DAI, shows only the DAI moved", () => {
const result = decodeSteps(
[0x10, 0x02],
[V4_EXACT_OUT_600, transferTo(DAI_ADDR, DAI_400)],
);
expect(linesBetweenTokens(result)).toEqual([
["Moved from the sender", "400.0000 DAI"],
["Token moved", "DAI (" + DAI_ADDR + ")"],
["Moved to", OTHER_ADDR],
]);
});
// A V2 exact-out step makes every amount the swap steps spend a maximum,
// the total included.
test("a split with a V2 exact-out step the user pays for shows the total as a maximum", () => {