Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce222d06f4 |
@@ -3180,16 +3180,15 @@ Currently supported:
|
|||||||
other than the one that sets the input side, whose input or one of whose
|
other than the one that sets the input side, whose input or one of whose
|
||||||
`SETTLE`s or `SETTLE_ALL`s it cannot read, which the router still runs; a V2
|
`SETTLE`s or `SETTLE_ALL`s it cannot read, which the router still runs; a V2
|
||||||
or V3 exact-in or V2 exact-out step or a `PERMIT2_TRANSFER_FROM` whose input
|
or V3 exact-in or V2 exact-out step or a `PERMIT2_TRANSFER_FROM` whose input
|
||||||
it cannot read; every `PERMIT2_TRANSFER_FROM_BATCH`; every
|
it cannot read; every `PERMIT2_TRANSFER_FROM_BATCH`; and, once the input side
|
||||||
`V3_SWAP_EXACT_OUT`, which the decoder does not read, wherever it stands; and
|
is set, every `V3_SWAP_EXACT_OUT`, which the decoder does not read, and every
|
||||||
every step it fails on. Each such step gives one `Moved from the sender` line
|
step it fails on. Each such step gives one `Moved from the sender` line among
|
||||||
among those, reading `Unknown (could not be decoded)`. That line, or any line
|
those, reading `Unknown (could not be decoded)`. That line, or any line for a
|
||||||
for a token the decoder does not know, leaves no `Amount` line, whose figure
|
token the decoder does not know, leaves no `Amount` line, whose figure might
|
||||||
might be too low, and such a step before a `PERMIT2_PERMIT` keeps the permit's
|
be too low. Then each `PERMIT2_TRANSFER_FROM` but one into the router, in step
|
||||||
amount from standing. Then each `PERMIT2_TRANSFER_FROM` but one into the
|
order, gives three lines: `Moved from the sender`, the amount it moves, for
|
||||||
router, in step order, gives three lines: `Moved from the sender`, the amount
|
example `1000000.0000 USDT`; `Token moved`, giving the token's address as the
|
||||||
it moves, for example `1000000.0000 USDT`; `Token moved`, giving the token's
|
`Token In` line does; and `Moved to`, which reads
|
||||||
address as the `Token In` line does; and `Moved to`, which reads
|
|
||||||
`The V2 pair the next swap spends` for a hop and `The sender` for `address(1)`
|
`The V2 pair the next swap spends` for a hop and `The sender` for `address(1)`
|
||||||
on every router but `UniversalRouterV1`, and otherwise gives the address. A
|
on every router but `UniversalRouterV1`, and otherwise gives the address. A
|
||||||
move into the router needs none of them, because its `Paid to` line and
|
move into the router needs none of them, because its `Paid to` line and
|
||||||
|
|||||||
+13
-13
@@ -1234,11 +1234,10 @@ function decode(data, toAddress, chainId, sources, fromAddress) {
|
|||||||
// V4 step, other than the one that sets the input side, whose input
|
// V4 step, other than the one that sets the input side, whose input
|
||||||
// or one of whose SETTLEs or SETTLE_ALLs it cannot read; a V2 or V3
|
// or one of whose SETTLEs or SETTLE_ALLs it cannot read; a V2 or V3
|
||||||
// exact-in or V2 exact-out step or PERMIT2_TRANSFER_FROM whose input
|
// exact-in or V2 exact-out step or PERMIT2_TRANSFER_FROM whose input
|
||||||
// it cannot read; a PERMIT2_TRANSFER_FROM_BATCH; a V3_SWAP_EXACT_OUT;
|
// it cannot read; a PERMIT2_TRANSFER_FROM_BATCH; and, once the input
|
||||||
// and a step it fails on. It is recorded with a null token and
|
// side is set, a V3_SWAP_EXACT_OUT or a step it fails on. It is
|
||||||
// amount: one line says so, there is no Amount line, whose figure may
|
// recorded with a null token and amount: one line says so, and there
|
||||||
// then be too low, and the amount of a permit after it does not stand
|
// is no Amount line, whose figure may then be too low.
|
||||||
// (see permitStands).
|
|
||||||
const spentUnread = () => {
|
const spentUnread = () => {
|
||||||
userPaid.push({ token: null, amount: null });
|
userPaid.push({ token: null, amount: null });
|
||||||
};
|
};
|
||||||
@@ -1490,11 +1489,11 @@ function decode(data, toAddress, chainId, sources, fromAddress) {
|
|||||||
} else if (command === "V3_SWAP_EXACT_OUT") {
|
} else if (command === "V3_SWAP_EXACT_OUT") {
|
||||||
// This decoder does not read it
|
// This decoder does not read it
|
||||||
// (https://git.eeqj.de/sneak/AutistMask/issues/601). It
|
// (https://git.eeqj.de/sneak/AutistMask/issues/601). It
|
||||||
// may pay any address and take from the sender, so
|
// may pay any address and take from the sender, so once
|
||||||
// wherever it stands it leaves no Amount figure.
|
// the input side is set it leaves no Amount figure.
|
||||||
payeeUnread = true;
|
payeeUnread = true;
|
||||||
stepsUnread.push(i);
|
stepsUnread.push(i);
|
||||||
spentUnread();
|
if (inputEstablished) spentUnread();
|
||||||
} else if (command === "V2_SWAP_EXACT_IN") {
|
} else if (command === "V2_SWAP_EXACT_IN") {
|
||||||
const s = decodeV2SwapExactIn(inputs[i]);
|
const s = decodeV2SwapExactIn(inputs[i]);
|
||||||
if (s) {
|
if (s) {
|
||||||
@@ -1750,7 +1749,7 @@ function decode(data, toAddress, chainId, sources, fromAddress) {
|
|||||||
// take from the sender.
|
// take from the sender.
|
||||||
payeeUnread = true;
|
payeeUnread = true;
|
||||||
stepsUnread.push(i);
|
stepsUnread.push(i);
|
||||||
spentUnread();
|
if (inputEstablished) spentUnread();
|
||||||
}
|
}
|
||||||
if (allowedToFail) {
|
if (allowedToFail) {
|
||||||
commandNames[i] += " (allowed to fail)";
|
commandNames[i] += " (allowed to fail)";
|
||||||
@@ -1775,10 +1774,11 @@ function decode(data, toAddress, chainId, sources, fromAddress) {
|
|||||||
// it in full (see stepsUnread). Permit2 then lets the router take no
|
// it in full (see stepsUnread). Permit2 then lets the router take no
|
||||||
// more of the token than that amount, so the permit covers every take
|
// more of the token than that amount, so the permit covers every take
|
||||||
// of it. A later step this decoder did not read may raise what Permit2
|
// of it. A later step this decoder did not read may raise what Permit2
|
||||||
// lets the router take, as a PERMIT2_PERMIT_BATCH can. A step that
|
// lets the router take, as a PERMIT2_PERMIT_BATCH can. A step this
|
||||||
// may take from the sender what this decoder did not read leaves no
|
// decoder does not read that may take from the sender leaves no
|
||||||
// figure, permit or not (see spentUnread()), and an EXECUTE_SUB_PLAN
|
// figure, permit or not, when it comes after the step that sets the
|
||||||
// step leaves both sides unknown (below).
|
// input side (see spentUnread()), and an EXECUTE_SUB_PLAN step leaves
|
||||||
|
// both sides unknown (below).
|
||||||
const stepCommands = Array.from(
|
const stepCommands = Array.from(
|
||||||
commandsBytes,
|
commandsBytes,
|
||||||
(b) => commands[b & commandTypeMask],
|
(b) => commands[b & commandTypeMask],
|
||||||
|
|||||||
+16
-62
@@ -1876,69 +1876,23 @@ describe("uniswap decoder", () => {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// A V3_SWAP_EXACT_OUT the user pays for, of at most `amountInMax`
|
|
||||||
// USDT for USDC. Its input is (recipient, amountOut, amountInMax,
|
|
||||||
// path, payerIsUser), laid out as encodeV3SwapExactIn() writes one;
|
|
||||||
// an exact-out path lists the token bought first.
|
|
||||||
const v3ExactOut = (amountInMax) =>
|
|
||||||
encodeV3SwapExactIn(USER_ADDR, 390000000n, amountInMax, [
|
|
||||||
USDC_ADDR,
|
|
||||||
USDT_ADDR,
|
|
||||||
]);
|
|
||||||
// A split exact-out route: a V3_SWAP_EXACT_OUT of at most 6,000 USDT
|
|
||||||
// and a V2_SWAP_EXACT_OUT of at most 4,000 USDT, both paid by the
|
|
||||||
// user, then a SWEEP of USDC to the user.
|
|
||||||
const EXACT_OUT_SPLIT = [
|
|
||||||
v3ExactOut(6000000000n),
|
|
||||||
encodeV2SwapExactOut(USER_ADDR, 390000000n, 4000000000n, [
|
|
||||||
USDT_ADDR,
|
|
||||||
USDC_ADDR,
|
|
||||||
]),
|
|
||||||
coder.encode(
|
|
||||||
["address", "address", "uint256"],
|
|
||||||
[USDC_ADDR, USER_ADDR, 0n],
|
|
||||||
),
|
|
||||||
];
|
|
||||||
// This decoder does not read a V3_SWAP_EXACT_OUT, so what one takes
|
// This decoder does not read a V3_SWAP_EXACT_OUT, so what one takes
|
||||||
// leaves no Amount figure wherever it stands, and a permit's amount
|
// after the step that sets the input side leaves no Amount figure.
|
||||||
// does not stand.
|
test("a V3 exact-in of 600 USDT, then a V3_SWAP_EXACT_OUT the user pays for, shows no Amount figure", () => {
|
||||||
test.each([
|
// Its input is (recipient, amountOut, amountInMax, path,
|
||||||
{
|
// payerIsUser), laid out as encodeV3SwapExactIn() writes one; an
|
||||||
kind: "a V3 exact-in of 600 USDT, then a V3_SWAP_EXACT_OUT",
|
// exact-out path lists the token bought first.
|
||||||
commands: [0x00, 0x01],
|
const exactOut = encodeV3SwapExactIn(
|
||||||
inputs: [V3_600, v3ExactOut(USDT_400)],
|
USER_ADDR,
|
||||||
},
|
390000000n,
|
||||||
{
|
USDT_400,
|
||||||
kind: "a PERMIT2_PERMIT of 10,000 USDT, then a V3_SWAP_EXACT_OUT, a V2_SWAP_EXACT_OUT and a SWEEP",
|
[USDC_ADDR, USDT_ADDR],
|
||||||
commands: [0x0a, 0x01, 0x09, 0x04],
|
);
|
||||||
inputs: [
|
const result = decodeSteps([0x00, 0x01], [V3_600, exactOut]);
|
||||||
encodePermit2(USDT_ADDR, 10000000000n, ROUTER_ADDR),
|
expect(linesBetweenTokens(result)).toEqual([
|
||||||
...EXACT_OUT_SPLIT,
|
["Moved from the sender", UNDECODED],
|
||||||
],
|
]);
|
||||||
},
|
});
|
||||||
{
|
|
||||||
kind: "a V3_SWAP_EXACT_OUT, a V2_SWAP_EXACT_OUT and a SWEEP",
|
|
||||||
commands: [0x01, 0x09, 0x04],
|
|
||||||
inputs: EXACT_OUT_SPLIT,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
kind: "a V3_SWAP_EXACT_OUT of at most 9,400 USDT, then a PERMIT2_PERMIT of 600 USDT and a V3 exact-in of 600 USDT",
|
|
||||||
commands: [0x01, 0x0a, 0x00],
|
|
||||||
inputs: [
|
|
||||||
v3ExactOut(9400000000n),
|
|
||||||
encodePermit2(USDT_ADDR, USDT_600, ROUTER_ADDR),
|
|
||||||
V3_600,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
])(
|
|
||||||
"$kind, all paid by the user, shows no Amount figure",
|
|
||||||
({ commands, inputs }) => {
|
|
||||||
const result = decodeSteps(commands, inputs);
|
|
||||||
expect(linesBetweenTokens(result)).toEqual([
|
|
||||||
["Moved from the sender", UNDECODED],
|
|
||||||
]);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// A later step's amount that cannot be added to the Amount line,
|
// A later step's amount that cannot be added to the Amount line,
|
||||||
// because the amount of the step that set the input side is not a
|
// because the amount of the step that set the input side is not a
|
||||||
|
|||||||
Reference in New Issue
Block a user