Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1af7c32b02 |
@@ -3061,11 +3061,7 @@ Currently supported:
|
|||||||
token from the router (`payerIsUser` false). Such steps also spend all the
|
token from the router (`payerIsUser` false). Such steps also spend all the
|
||||||
WETH a `WRAP_ETH` paid the router once together they spend the amount the
|
WETH a `WRAP_ETH` paid the router once together they spend the amount the
|
||||||
`WRAP_ETH` states, as a swap paid in ETH does; a `SETTLE` of `OPEN_DELTA`
|
`WRAP_ETH` states, as a swap paid in ETH does; a `SETTLE` of `OPEN_DELTA`
|
||||||
(zero) from the router counts as spending what its step's swap spends only
|
(zero) counts as spending what its step's swap spends. So the rest of a V4
|
||||||
when it is the step's only `SETTLE` or `SETTLE_ALL` of that token, comes after
|
|
||||||
every swap action in the step, and no swap action in the step buys that token,
|
|
||||||
because the router pays only what the step still owes of that token when the
|
|
||||||
`SETTLE` runs; otherwise it counts as spending nothing. So the rest of a V4
|
|
||||||
`SETTLE` of more than its swap spends, taken to the router, the WETH of a
|
`SETTLE` of more than its swap spends, taken to the router, the WETH of a
|
||||||
`WRAP_ETH`, and a token a swap pays the router on the way to the output, each
|
`WRAP_ETH`, and a token a swap pays the router on the way to the output, each
|
||||||
stays in the router when later steps do not spend all of it, where anyone can
|
stays in the router when later steps do not spend all of it, where anyone can
|
||||||
|
|||||||
+5
-33
@@ -887,9 +887,7 @@ function totalAmount(amounts) {
|
|||||||
// a share of the currency, so it does not name the output side as TAKE does.
|
// a share of the currency, so it does not name the output side as TAKE does.
|
||||||
// `recipientUnread` is set when the step has a payout this decoder did not
|
// `recipientUnread` is set when the step has a payout this decoder did not
|
||||||
// read. `settledFromRouter` is every SETTLE that the router pays from its own
|
// read. `settledFromRouter` is every SETTLE that the router pays from its own
|
||||||
// balance (`payerIsUser` false), as the currency, the amount as written and
|
// balance (`payerIsUser` false), as the currency and the amount as written.
|
||||||
// its index among the step's actions, except that a SETTLE of OPEN_DELTA
|
|
||||||
// whose payment this decoder cannot follow has no amount (null; see below).
|
|
||||||
function decodeV4Swap(input) {
|
function decodeV4Swap(input) {
|
||||||
try {
|
try {
|
||||||
const d = coder.decode(["bytes", "bytes[]"], input);
|
const d = coder.decode(["bytes", "bytes[]"], input);
|
||||||
@@ -900,10 +898,6 @@ function decodeV4Swap(input) {
|
|||||||
let takeToken = null;
|
let takeToken = null;
|
||||||
const takes = [];
|
const takes = [];
|
||||||
const settledFromRouter = [];
|
const settledFromRouter = [];
|
||||||
// The currency of every SETTLE and SETTLE_ALL, in order.
|
|
||||||
const settledCurrencies = [];
|
|
||||||
// The index of the step's last swap action, read or not, or -1.
|
|
||||||
let lastSwapAction = -1;
|
|
||||||
let recipientUnread = false;
|
let recipientUnread = false;
|
||||||
// The step's swap actions that could be read, as decodeV4SwapAction()
|
// The step's swap actions that could be read, as decodeV4SwapAction()
|
||||||
// reads them.
|
// reads them.
|
||||||
@@ -923,19 +917,16 @@ function decodeV4Swap(input) {
|
|||||||
params[i],
|
params[i],
|
||||||
);
|
);
|
||||||
settleToken = s[0];
|
settleToken = s[0];
|
||||||
settledCurrencies.push(s[0]);
|
|
||||||
if (!s[2]) {
|
if (!s[2]) {
|
||||||
settledFromRouter.push({
|
settledFromRouter.push({
|
||||||
currency: s[0],
|
currency: s[0],
|
||||||
amount: s[1],
|
amount: s[1],
|
||||||
index: i,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (actionId === V4_SETTLE_ALL) {
|
} else if (actionId === V4_SETTLE_ALL) {
|
||||||
// SETTLE_ALL: (address currency, uint256 maxAmount)
|
// SETTLE_ALL: (address currency, uint256 maxAmount)
|
||||||
const s = coder.decode(["address", "uint256"], params[i]);
|
const s = coder.decode(["address", "uint256"], params[i]);
|
||||||
settleToken = s[0];
|
settleToken = s[0];
|
||||||
settledCurrencies.push(s[0]);
|
|
||||||
} else if (actionId === V4_TAKE) {
|
} else if (actionId === V4_TAKE) {
|
||||||
// TAKE: (address currency, address recipient, uint256 amount)
|
// TAKE: (address currency, address recipient, uint256 amount)
|
||||||
const t = coder.decode(
|
const t = coder.decode(
|
||||||
@@ -962,7 +953,6 @@ function decodeV4Swap(input) {
|
|||||||
actionId === V4_SWAP_EXACT_OUT_SINGLE ||
|
actionId === V4_SWAP_EXACT_OUT_SINGLE ||
|
||||||
actionId === V4_SWAP_EXACT_OUT
|
actionId === V4_SWAP_EXACT_OUT
|
||||||
) {
|
) {
|
||||||
lastSwapAction = i;
|
|
||||||
try {
|
try {
|
||||||
swaps.push(decodeV4SwapAction(actionId, params[i]));
|
swaps.push(decodeV4SwapAction(actionId, params[i]));
|
||||||
} catch {
|
} catch {
|
||||||
@@ -985,24 +975,6 @@ function decodeV4Swap(input) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A SETTLE of OPEN_DELTA (zero) paid from the router pays what the
|
|
||||||
// step still owes of its currency when it runs. That is what the
|
|
||||||
// step's swap actions spend of it only when the SETTLE is the step's
|
|
||||||
// one SETTLE or SETTLE_ALL of that currency, comes after every swap
|
|
||||||
// action, and no swap action buys that currency (an unread one may).
|
|
||||||
// Any other such SETTLE pays an amount this decoder cannot tell.
|
|
||||||
for (const s of settledFromRouter) {
|
|
||||||
const paysWhatSwapsSpend =
|
|
||||||
settledCurrencies.filter((c) => c === s.currency).length ===
|
|
||||||
1 &&
|
|
||||||
s.index > lastSwapAction &&
|
|
||||||
!swapUndecoded &&
|
|
||||||
!swaps.some((w) => w.tokenOut === s.currency);
|
|
||||||
if (s.amount === 0n && !paysWhatSwapsSpend) {
|
|
||||||
s.amount = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rule 3.
|
// Rule 3.
|
||||||
if (swapUndecoded) {
|
if (swapUndecoded) {
|
||||||
return {
|
return {
|
||||||
@@ -1457,10 +1429,10 @@ function decode(data, toAddress, chainId, sources, fromAddress) {
|
|||||||
} else if (command === "V4_SWAP") {
|
} else if (command === "V4_SWAP") {
|
||||||
const v4 = decodeV4Swap(inputs[i]);
|
const v4 = decodeV4Swap(inputs[i]);
|
||||||
if (v4) {
|
if (v4) {
|
||||||
// A SETTLE of OPEN_DELTA (zero) that decodeV4Swap()
|
// A SETTLE of OPEN_DELTA (zero) pays what the step's
|
||||||
// left at zero pays what the step's swap actions
|
// swap actions spend of its currency, which the step
|
||||||
// spend of its currency, which the step states as its
|
// states as its amount when that currency is its
|
||||||
// amount when that currency is its Token In.
|
// Token In.
|
||||||
for (const s of v4.settledFromRouter) {
|
for (const s of v4.settledFromRouter) {
|
||||||
let amount = s.amount;
|
let amount = s.amount;
|
||||||
if (amount === 0n) {
|
if (amount === 0n) {
|
||||||
|
|||||||
@@ -650,65 +650,6 @@ describe("any token left in the router is not received", () => {
|
|||||||
),
|
),
|
||||||
left: tokenLine(WETH, "WETH"),
|
left: tokenLine(WETH, "WETH"),
|
||||||
},
|
},
|
||||||
// A SETTLE of OPEN_DELTA from the router pays only what the step
|
|
||||||
// still owes of its currency when it runs.
|
|
||||||
{
|
|
||||||
kind: "a WRAP_ETH of 1 ETH into the router, then a V4 swap of 0.5 WETH with two SETTLEs of OPEN_DELTA from the router",
|
|
||||||
data: execute(
|
|
||||||
wrapEth(ADDRESS_THIS, ONE_WETH),
|
|
||||||
v4Swap(
|
|
||||||
swapExactInSingle(WETH, USDC, ONE_WETH / 2n, USDC_1990),
|
|
||||||
settle(WETH, 0n, false),
|
|
||||||
settle(WETH, 0n, false),
|
|
||||||
takeAll(USDC),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
left: tokenLine(WETH, "WETH"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
kind: "a WRAP_ETH of 1 ETH into the router, then a V4 swap of 0.75 WETH with a SETTLE of 0.25 WETH and one of OPEN_DELTA from the router",
|
|
||||||
data: execute(
|
|
||||||
wrapEth(ADDRESS_THIS, ONE_WETH),
|
|
||||||
v4Swap(
|
|
||||||
swapExactInSingle(
|
|
||||||
WETH,
|
|
||||||
USDC,
|
|
||||||
(ONE_WETH * 3n) / 4n,
|
|
||||||
USDC_1990,
|
|
||||||
),
|
|
||||||
settle(WETH, ONE_WETH / 4n, false),
|
|
||||||
settle(WETH, 0n, false),
|
|
||||||
takeAll(USDC),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
left: tokenLine(WETH, "WETH"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
kind: "a WRAP_ETH of 1 ETH into the router, then a V4 step that also buys WETH back, with a SETTLE of OPEN_DELTA from the router",
|
|
||||||
data: execute(
|
|
||||||
wrapEth(ADDRESS_THIS, ONE_WETH),
|
|
||||||
v4Swap(
|
|
||||||
swapExactInSingle(WETH, USDC, ONE_WETH, USDC_1990),
|
|
||||||
swapExactInSingle(USDC, WETH, 1000000n, 1n),
|
|
||||||
settle(WETH, 0n, false),
|
|
||||||
takeAll(USDC),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
left: tokenLine(WETH, "WETH"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
kind: "a WRAP_ETH of 1 ETH into the router, then a V4 SETTLE of OPEN_DELTA from the router before the swap, which the user settles",
|
|
||||||
data: execute(
|
|
||||||
wrapEth(ADDRESS_THIS, ONE_WETH),
|
|
||||||
v4Swap(
|
|
||||||
settle(WETH, 0n, false),
|
|
||||||
swapExactInSingle(WETH, USDC, ONE_WETH, USDC_1990),
|
|
||||||
settle(WETH, 0n, true),
|
|
||||||
takeAll(USDC),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
left: tokenLine(WETH, "WETH"),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
kind: "a swap paying WETH to the router, a TRANSFER of 1 wei of it to the WETH/USDC pair, then a V2 swap of what the pair holds",
|
kind: "a swap paying WETH to the router, a TRANSFER of 1 wei of it to the WETH/USDC pair, then a V2 swap of what the pair holds",
|
||||||
data: execute(
|
data: execute(
|
||||||
|
|||||||
Reference in New Issue
Block a user