Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e8691a3f6 |
No files matched your search
@@ -3469,19 +3469,20 @@ Currently supported:
|
|||||||
spends the output token drops earlier steps from the sum. A V4 step spends
|
spends the output token drops earlier steps from the sum. A V4 step spends
|
||||||
each token that its swap actions spend. A V4 `SETTLE` or `SETTLE_ALL` of the
|
each token that its swap actions spend. A V4 `SETTLE` or `SETTLE_ALL` of the
|
||||||
output token also drops earlier steps. A `PERMIT2_TRANSFER_FROM` of the output
|
output token also drops earlier steps. A `PERMIT2_TRANSFER_FROM` of the output
|
||||||
token drops earlier steps too. The `Amount` line gives the total the steps
|
token drops earlier steps too. A step after the step that sets the output side
|
||||||
take of `Token In`, from the step that sets the input side on: the first V2 or
|
drops nothing from the sum. The `Amount` line gives the total the steps take
|
||||||
V3 exact-in or exact-out, `WRAP_ETH` or V4 swap step that names an input token
|
of `Token In`, from the step that sets the input side on: the first V2 or V3
|
||||||
or amount. A V4 step with a swap action sets the input side when no earlier
|
exact-in or exact-out, `WRAP_ETH` or V4 swap step that names an input token or
|
||||||
step set it, even when it names neither (see Display Consistency). That step
|
amount. A V4 step with a swap action sets the input side when no earlier step
|
||||||
counts its own amount, whoever pays it: a V2 or V3 exact-out step its
|
set it, even when it names neither (see Display Consistency). That step counts
|
||||||
`amountInMax`, and a V4 step what it takes of its input token from the user's
|
its own amount, whoever pays it: a V2 or V3 exact-out step its `amountInMax`,
|
||||||
wallet, as below, or, when the user pays it none of that token, the `amountIn`
|
and a V4 step what it takes of its input token from the user's wallet, as
|
||||||
of the swap action that spends it. Each later V2 or V3 exact-in or exact-out
|
below, or, when the user pays it none of that token, the `amountIn` of the
|
||||||
step whose `payerIsUser` is true takes its amount, found in the same way, from
|
swap action that spends it. Each later V2 or V3 exact-in or exact-out step
|
||||||
the user's wallet. Every V4 step, with a swap action or without, takes from
|
whose `payerIsUser` is true takes its amount, found in the same way, from the
|
||||||
the user's wallet what its `SETTLE`s paid by the user (`payerIsUser` true) and
|
user's wallet. Every V4 step, with a swap action or without, takes from the
|
||||||
its `SETTLE_ALL`s pay, for each token on its own; what the step that sets the
|
user's wallet what its `SETTLE`s paid by the user (`payerIsUser` true) and its
|
||||||
|
`SETTLE_ALL`s pay, for each token on its own; what the step that sets the
|
||||||
input side takes of any other token counts as a later step's take. A `SETTLE`
|
input side takes of any other token counts as a later step's take. A `SETTLE`
|
||||||
of any amount but `OPEN_DELTA` pays that amount, and a `SETTLE` of
|
of any amount but `OPEN_DELTA` pays that amount, and a `SETTLE` of
|
||||||
`OPEN_DELTA` or a `SETTLE_ALL` pays what the step owes, as above. So a V4 step
|
`OPEN_DELTA` or a `SETTLE_ALL` pays what the step owes, as above. So a V4 step
|
||||||
|
|||||||
@@ -1477,14 +1477,18 @@ function decode(data, toAddress, chainId, sources, fromAddress) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
// Each swap step that paid the sender some of the token it bought,
|
// Each swap step that paid the sender some of the token it bought,
|
||||||
// as { step, token, amount, onlyToSender }: the step's index, that
|
// as { step, token, amount, onlyToSender }:
|
||||||
// token, the step's stated minimum, and whether the step paid all of
|
// - `step` is the step's index;
|
||||||
// that token to the sender. A later step that spends that token takes
|
// - `token` is that token;
|
||||||
// the step off this list (see dropFromSum()).
|
// - `amount` is the step's stated minimum;
|
||||||
|
// - `onlyToSender` is whether the step paid all of that token to the
|
||||||
|
// sender.
|
||||||
|
// A later step that spends that token takes the step off this list
|
||||||
|
// (see dropFromSum()).
|
||||||
let swapsPayingSender = [];
|
let swapsPayingSender = [];
|
||||||
// The step being read spends `token`, so it may spend what an earlier
|
// The step being read spends `token`, so it may spend what an earlier
|
||||||
// swap step paid the sender. Each step on swapsPayingSender that
|
// swap step paid the sender. Each step on swapsPayingSender that
|
||||||
// bought `token` leaves the list. These steps spend a token:
|
// bought `token` leaves the list. A step spends a token as follows:
|
||||||
// - a V2 or V3 swap step spends its input token;
|
// - a V2 or V3 swap step spends its input token;
|
||||||
// - a V4 step spends each token that one of its swap actions spends,
|
// - a V4 step spends each token that one of its swap actions spends,
|
||||||
// and each token that one of its SETTLEs or SETTLE_ALLs pays;
|
// and each token that one of its SETTLEs or SETTLE_ALLs pays;
|
||||||
|
|||||||
+114
-28
@@ -3743,25 +3743,54 @@ describe("uniswap decoder", () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
// The middle step spends the user's WETH, so the count of WETH
|
// The middle step swaps 0.3 of the user's WETH for USDC, so the
|
||||||
// starts again after it.
|
// sum of minimums starts again after it.
|
||||||
test("a step that spends WETH between them leaves the last step's minimum", () => {
|
test.each([
|
||||||
const result = decodeSteps(
|
{
|
||||||
[0x00, 0x00, 0x08],
|
kind: "a V3 exact-in",
|
||||||
[
|
command: 0x00,
|
||||||
V3_TO_WETH,
|
input: encodeV3SwapExactIn(USER_ADDR, WETH_03, 1n, [
|
||||||
encodeV3SwapExactIn(USER_ADDR, WETH_03, 1n, [
|
WETH_ADDR,
|
||||||
WETH_ADDR,
|
USDC_ADDR,
|
||||||
USDC_ADDR,
|
]),
|
||||||
]),
|
},
|
||||||
V2_TO_WETH,
|
{
|
||||||
],
|
kind: "a V2 exact-in",
|
||||||
);
|
command: 0x08,
|
||||||
expect(minimum(result)).toEqual([
|
input: encodeV2SwapExactIn(USER_ADDR, WETH_03, 1n, [
|
||||||
"Min. received",
|
WETH_ADDR,
|
||||||
"0.2000 WETH",
|
USDC_ADDR,
|
||||||
]);
|
]),
|
||||||
});
|
},
|
||||||
|
{
|
||||||
|
kind: "a V2 exact-out",
|
||||||
|
command: 0x09,
|
||||||
|
input: encodeV2SwapExactOut(USER_ADDR, 1n, WETH_03, [
|
||||||
|
WETH_ADDR,
|
||||||
|
USDC_ADDR,
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: "a V3 exact-out",
|
||||||
|
command: 0x01,
|
||||||
|
input: encodeV3SwapExactOut(USER_ADDR, 1n, WETH_03, [
|
||||||
|
USDC_ADDR,
|
||||||
|
WETH_ADDR,
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
])(
|
||||||
|
"$kind that spends WETH between them leaves the last step's minimum",
|
||||||
|
({ command, input }) => {
|
||||||
|
const result = decodeSteps(
|
||||||
|
[0x00, command, 0x08],
|
||||||
|
[V3_TO_WETH, input, V2_TO_WETH],
|
||||||
|
);
|
||||||
|
expect(minimum(result)).toEqual([
|
||||||
|
"Min. received",
|
||||||
|
"0.2000 WETH",
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// The middle step swaps 0.3 WETH and 400 DAI for USDC, both paid
|
// The middle step swaps 0.3 WETH and 400 DAI for USDC, both paid
|
||||||
// by the user. It spends WETH whichever SETTLE comes last.
|
// by the user. It spends WETH whichever SETTLE comes last.
|
||||||
@@ -3807,26 +3836,83 @@ describe("uniswap decoder", () => {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// The middle step has no swap action. Its SETTLE pays 0.3 WETH
|
// The middle step's swap actions buy WETH with the user's USDT,
|
||||||
// from the user, and its TAKE pays that WETH to another address.
|
// then swap all of that WETH for USDC.
|
||||||
test("a V4 step whose SETTLE pays WETH between them leaves the last step's minimum", () => {
|
test("a V4 step that swaps through WETH between them leaves the last step's minimum", () => {
|
||||||
const wethToOther = encodeV4Swap(
|
const usdtToUsdcThroughWeth = encodeV4Swap(
|
||||||
new Uint8Array([V4_SETTLE_ID, V4_TAKE_ID]),
|
new Uint8Array([
|
||||||
|
V4_SWAP_EXACT_IN_SINGLE_ID,
|
||||||
|
V4_SWAP_EXACT_IN_SINGLE_ID,
|
||||||
|
V4_SETTLE_ID,
|
||||||
|
V4_TAKE_ALL_ID,
|
||||||
|
]),
|
||||||
[
|
[
|
||||||
settle(WETH_ADDR, WETH_03, true),
|
encodeV4ExactInSingle(
|
||||||
take(WETH_ADDR, OTHER_ADDR, 0n),
|
USDT_ADDR,
|
||||||
|
WETH_ADDR,
|
||||||
|
USDT_400,
|
||||||
|
WETH_01,
|
||||||
|
),
|
||||||
|
encodeV4ExactInSingle(WETH_ADDR, USDC_ADDR, 0n, 1n),
|
||||||
|
encodeV4Settle(USDT_ADDR), // paid by the user
|
||||||
|
encodeV4TakeAll(USDC_ADDR, 0n),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
const result = decodeSteps(
|
const result = decodeSteps(
|
||||||
[0x00, 0x10, 0x08],
|
[0x00, 0x10, 0x08],
|
||||||
[V3_TO_WETH, wethToOther, V2_TO_WETH],
|
[V3_TO_WETH, usdtToUsdcThroughWeth, V2_TO_WETH],
|
||||||
);
|
);
|
||||||
expect(minimum(result)).toEqual([
|
expect(minimum(result)).toEqual([
|
||||||
"Min. paid out",
|
"Min. received",
|
||||||
"0.2000 WETH",
|
"0.2000 WETH",
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// The middle step has no swap action. Its SETTLE or SETTLE_ALL
|
||||||
|
// pays 0.3 WETH, and its TAKE pays that WETH to another address.
|
||||||
|
test.each([
|
||||||
|
{
|
||||||
|
payment: "a SETTLE of WETH paid by the user",
|
||||||
|
actions: [V4_SETTLE_ID, V4_TAKE_ID],
|
||||||
|
params: [
|
||||||
|
settle(WETH_ADDR, WETH_03, true),
|
||||||
|
take(WETH_ADDR, OTHER_ADDR, 0n),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
payment: "a SETTLE of WETH paid from the router",
|
||||||
|
actions: [V4_SETTLE_ID, V4_TAKE_ID],
|
||||||
|
params: [
|
||||||
|
settle(WETH_ADDR, WETH_03, false),
|
||||||
|
take(WETH_ADDR, OTHER_ADDR, 0n),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
payment: "a SETTLE_ALL of WETH",
|
||||||
|
actions: [V4_TAKE_ID, V4_SETTLE_ALL_ID],
|
||||||
|
params: [
|
||||||
|
take(WETH_ADDR, OTHER_ADDR, WETH_03),
|
||||||
|
encodeV4SettleAll(WETH_ADDR, WETH_03),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
])(
|
||||||
|
"a V4 step with $payment between them leaves the last step's minimum",
|
||||||
|
({ actions, params }) => {
|
||||||
|
const wethToOther = encodeV4Swap(
|
||||||
|
new Uint8Array(actions),
|
||||||
|
params,
|
||||||
|
);
|
||||||
|
const result = decodeSteps(
|
||||||
|
[0x00, 0x10, 0x08],
|
||||||
|
[V3_TO_WETH, wethToOther, V2_TO_WETH],
|
||||||
|
);
|
||||||
|
expect(minimum(result)).toEqual([
|
||||||
|
"Min. paid out",
|
||||||
|
"0.2000 WETH",
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
test("a PERMIT2_TRANSFER_FROM of WETH between them leaves the last step's minimum", () => {
|
test("a PERMIT2_TRANSFER_FROM of WETH between them leaves the last step's minimum", () => {
|
||||||
const result = decodeSteps(
|
const result = decodeSteps(
|
||||||
[0x00, 0x02, 0x08],
|
[0x00, 0x02, 0x08],
|
||||||
|
|||||||
Reference in new issue
Block a user