Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89e5ccfbb2 |
@@ -3566,10 +3566,14 @@ Currently supported:
|
|||||||
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
|
||||||
`Token moved into the router` line already give the amount, the token and
|
`Token moved into the router` line already give the amount, the token and
|
||||||
where it goes, and so its amount is shown once. Every `PERMIT2_PERMIT` whose
|
where it goes, and so its amount is shown once. For a move of the zero
|
||||||
amount does not stand as the `Amount` figure, before the step that sets the
|
address, `Moved from the sender` gives the amount in base units and
|
||||||
input side or after it, gives three lines, in step order, after those for each
|
`Token moved` gives the zero address. For such a move into the router, the
|
||||||
`PERMIT2_TRANSFER_FROM`: `Permit2 allowance`, its amount, for example
|
`Paid to` line gives the amount in base units and
|
||||||
|
`Token moved into the router` gives the zero address. Every `PERMIT2_PERMIT`
|
||||||
|
whose amount does not stand as the `Amount` figure, before the step that sets
|
||||||
|
the input side or after it, gives three lines, in step order, after those for
|
||||||
|
each `PERMIT2_TRANSFER_FROM`: `Permit2 allowance`, its amount, for example
|
||||||
`5000.0000 DAI`, or `Unlimited` for Permit2's maximum; `Allowance token`,
|
`5000.0000 DAI`, or `Unlimited` for Permit2's maximum; `Allowance token`,
|
||||||
giving the token's address as the `Token In` line does; and
|
giving the token's address as the `Token In` line does; and
|
||||||
`Allowance spender`, the address it lets take the token. Only a permit whose
|
`Allowance spender`, the address it lets take the token. Only a permit whose
|
||||||
|
|||||||
+36
-45
@@ -479,6 +479,17 @@ function tokenInfo(address, sources) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The token of a Permit2 allowance or of a PERMIT2_TRANSFER_FROM, in the
|
||||||
|
// shape tokenInfo() gives. Permit2 has no allowance of ETH and moves no ETH.
|
||||||
|
// The zero address there reads as a token nothing knows: its amount in base
|
||||||
|
// units, and the zero address as its token.
|
||||||
|
function permit2TokenInfo(address, sources) {
|
||||||
|
if (address === "0x0000000000000000000000000000000000000000") {
|
||||||
|
return { symbol: null, decimals: null, address };
|
||||||
|
}
|
||||||
|
return tokenInfo(address, sources);
|
||||||
|
}
|
||||||
|
|
||||||
// A swap amount line. With a scale it is the token quantity; with none it is
|
// A swap amount line. With a scale it is the token quantity; with none it is
|
||||||
// the base-unit integer with the unknown scale stated, the same refusal the
|
// the base-unit integer with the unknown scale stated, the same refusal the
|
||||||
// ERC-20 amount line makes, so the screen has one way of saying it. `display`
|
// ERC-20 amount line makes, so the screen has one way of saying it. `display`
|
||||||
@@ -497,16 +508,18 @@ function amountText(raw, info) {
|
|||||||
|
|
||||||
// The line giving a moved token, or the token of a permit, under `label`, in
|
// The line giving a moved token, or the token of a permit, under `label`, in
|
||||||
// the shape of the Token In line, so the screens show it as they show that
|
// the shape of the Token In line, so the screens show it as they show that
|
||||||
// one. ETH has no address.
|
// one. `info` is what tokenInfo() or permit2TokenInfo() gives for the token.
|
||||||
function tokenMovedLine(label, token, sources) {
|
// ETH has no address.
|
||||||
const info = tokenInfo(token, sources);
|
function tokenMovedLine(label, info) {
|
||||||
if (!present(info.address)) {
|
if (!present(info.address)) {
|
||||||
return { label, value: info.symbol };
|
return { label, value: info.symbol };
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
label,
|
label,
|
||||||
value: info.symbol ? info.symbol + " (" + token + ")" : token,
|
value: info.symbol
|
||||||
address: token,
|
? info.symbol + " (" + info.address + ")"
|
||||||
|
: info.address,
|
||||||
|
address: info.address,
|
||||||
isToken: true,
|
isToken: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -2329,7 +2342,9 @@ function decode(data, toAddress, chainId, sources, fromAddress) {
|
|||||||
: UNDECODED_CURRENCY,
|
: UNDECODED_CURRENCY,
|
||||||
});
|
});
|
||||||
if (present(s.token)) {
|
if (present(s.token)) {
|
||||||
details.push(tokenMovedLine("Token moved", s.token, sources));
|
details.push(
|
||||||
|
tokenMovedLine("Token moved", tokenInfo(s.token, sources)),
|
||||||
|
);
|
||||||
details.push({
|
details.push({
|
||||||
label: "Moved to",
|
label: "Moved to",
|
||||||
value: "The swap step that spends it",
|
value: "The swap step that spends it",
|
||||||
@@ -2340,12 +2355,12 @@ function decode(data, toAddress, chainId, sources, fromAddress) {
|
|||||||
// What each PERMIT2_TRANSFER_FROM moves: its amount, its token and
|
// What each PERMIT2_TRANSFER_FROM moves: its amount, its token and
|
||||||
// where it goes, an address on a line of its own.
|
// where it goes, an address on a line of its own.
|
||||||
for (const m of movedFromSender) {
|
for (const m of movedFromSender) {
|
||||||
|
const info = permit2TokenInfo(m.token, sources);
|
||||||
details.push({
|
details.push({
|
||||||
label: "Moved from the sender",
|
label: "Moved from the sender",
|
||||||
value: amountText(m.amount, tokenInfo(m.token, sources))
|
value: amountText(m.amount, info).display,
|
||||||
.display,
|
|
||||||
});
|
});
|
||||||
details.push(tokenMovedLine("Token moved", m.token, sources));
|
details.push(tokenMovedLine("Token moved", info));
|
||||||
details.push(
|
details.push(
|
||||||
present(m.to)
|
present(m.to)
|
||||||
? { label: "Moved to", value: m.to }
|
? { label: "Moved to", value: m.to }
|
||||||
@@ -2375,36 +2390,15 @@ function decode(data, toAddress, chainId, sources, fromAddress) {
|
|||||||
});
|
});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Permit2 has no allowance of ETH. An allowance of the zero
|
const info = permit2TokenInfo(p.token, sources);
|
||||||
// address reads as one of a token nothing knows: its amount in
|
details.push({
|
||||||
// base units, and the zero address as its token.
|
label: "Permit2 allowance",
|
||||||
if (p.token === "0x0000000000000000000000000000000000000000") {
|
value:
|
||||||
details.push({
|
p.amount >= MAX_UINT160
|
||||||
label: "Permit2 allowance",
|
? "Unlimited"
|
||||||
value:
|
: amountText(p.amount, info).display,
|
||||||
p.amount >= MAX_UINT160
|
});
|
||||||
? "Unlimited"
|
details.push(tokenMovedLine("Allowance token", info));
|
||||||
: unknownDecimalsAmount(p.amount),
|
|
||||||
});
|
|
||||||
details.push({
|
|
||||||
label: "Allowance token",
|
|
||||||
value: p.token,
|
|
||||||
address: p.token,
|
|
||||||
isToken: true,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
details.push({
|
|
||||||
label: "Permit2 allowance",
|
|
||||||
value:
|
|
||||||
p.amount >= MAX_UINT160
|
|
||||||
? "Unlimited"
|
|
||||||
: amountText(p.amount, tokenInfo(p.token, sources))
|
|
||||||
.display,
|
|
||||||
});
|
|
||||||
details.push(
|
|
||||||
tokenMovedLine("Allowance token", p.token, sources),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
details.push({
|
details.push({
|
||||||
label: "Allowance spender",
|
label: "Allowance spender",
|
||||||
value: p.spender,
|
value: p.spender,
|
||||||
@@ -2462,7 +2456,7 @@ function decode(data, toAddress, chainId, sources, fromAddress) {
|
|||||||
paidTo.push({ label: "Paid to", value: PAID_TO_BRIDGE });
|
paidTo.push({ label: "Paid to", value: PAID_TO_BRIDGE });
|
||||||
}
|
}
|
||||||
for (const m of movedIntoRouter) {
|
for (const m of movedIntoRouter) {
|
||||||
const info = tokenInfo(m.token, sources);
|
const info = permit2TokenInfo(m.token, sources);
|
||||||
paidTo.push({
|
paidTo.push({
|
||||||
label: "Paid to",
|
label: "Paid to",
|
||||||
value:
|
value:
|
||||||
@@ -2470,9 +2464,7 @@ function decode(data, toAddress, chainId, sources, fromAddress) {
|
|||||||
amountText(m.amount, info).display +
|
amountText(m.amount, info).display +
|
||||||
" from the sender (later steps may not spend all of it)",
|
" from the sender (later steps may not spend all of it)",
|
||||||
});
|
});
|
||||||
paidTo.push(
|
paidTo.push(tokenMovedLine("Token moved into the router", info));
|
||||||
tokenMovedLine("Token moved into the router", m.token, sources),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (outputHeld) {
|
if (outputHeld) {
|
||||||
paidTo.push({ label: "Paid to", value: STAYS_IN_ROUTER });
|
paidTo.push({ label: "Paid to", value: STAYS_IN_ROUTER });
|
||||||
@@ -2489,8 +2481,7 @@ function decode(data, toAddress, chainId, sources, fromAddress) {
|
|||||||
paidTo.push(
|
paidTo.push(
|
||||||
tokenMovedLine(
|
tokenMovedLine(
|
||||||
"Token moved into the router",
|
"Token moved into the router",
|
||||||
getAddress(token),
|
tokenInfo(getAddress(token), sources),
|
||||||
sources,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3440,6 +3440,82 @@ describe("uniswap decoder", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// https://git.eeqj.de/sneak/AutistMask/issues/685 — Permit2 moves no
|
||||||
|
// ETH, so a PERMIT2_TRANSFER_FROM of the zero address reads as a move
|
||||||
|
// of a token nothing knows. On next at ec6b6b5 its lines read ETH,
|
||||||
|
// with an ETH figure.
|
||||||
|
describe("a PERMIT2_TRANSFER_FROM of the zero address", () => {
|
||||||
|
const MOVED_AMOUNT =
|
||||||
|
"1000000000000000000 base units (decimals unknown)";
|
||||||
|
|
||||||
|
test("to another address names the address", () => {
|
||||||
|
const result = decodeSteps(
|
||||||
|
[0x00, 0x02],
|
||||||
|
[V3_600, transfer(ZERO_ADDR, OTHER_ADDR, ONE_WETH)],
|
||||||
|
);
|
||||||
|
expect(linesBetweenTokens(result)).toEqual([
|
||||||
|
["Amount", "600.0000 USDT"],
|
||||||
|
["Moved from the sender", MOVED_AMOUNT],
|
||||||
|
["Token moved", ZERO_ADDR],
|
||||||
|
["Moved to", OTHER_ADDR],
|
||||||
|
]);
|
||||||
|
expect(detail(result, "Token moved").address).toBe(ZERO_ADDR);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("into the router names the address", () => {
|
||||||
|
const result = decodeSteps(
|
||||||
|
[0x02, 0x00],
|
||||||
|
[transfer(ZERO_ADDR, ROUTER_ADDR, ONE_WETH), V3_600],
|
||||||
|
);
|
||||||
|
expect(detail(result, "Paid to").value).toBe(
|
||||||
|
"The router, " +
|
||||||
|
MOVED_AMOUNT +
|
||||||
|
" from the sender (later steps may not spend all of it)",
|
||||||
|
);
|
||||||
|
expect(detail(result, "Token moved into the router")).toEqual({
|
||||||
|
label: "Token moved into the router",
|
||||||
|
value: ZERO_ADDR,
|
||||||
|
address: ZERO_ADDR,
|
||||||
|
isToken: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// The V4 step's SETTLE names the user as payer and states no
|
||||||
|
// amount. The step's lines say that the ETH amount is not known.
|
||||||
|
test("after a V4 exact-out step of ETH, also shows that the ETH amount is not known", () => {
|
||||||
|
const v4EthExactOut = encodeV4Swap(
|
||||||
|
new Uint8Array([
|
||||||
|
V4_SWAP_EXACT_OUT_SINGLE_ID,
|
||||||
|
V4_SETTLE_ID,
|
||||||
|
V4_TAKE_ALL_ID,
|
||||||
|
]),
|
||||||
|
[
|
||||||
|
encodeV4ExactOutSingle(
|
||||||
|
ZERO_ADDR,
|
||||||
|
USDC_ADDR,
|
||||||
|
590000000n,
|
||||||
|
ONE_WETH,
|
||||||
|
),
|
||||||
|
encodeV4Settle(ZERO_ADDR),
|
||||||
|
encodeV4TakeAll(USDC_ADDR, 0n),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
const result = decodeSteps(
|
||||||
|
[0x10, 0x02],
|
||||||
|
[v4EthExactOut, transfer(ZERO_ADDR, OTHER_ADDR, ONE_WETH)],
|
||||||
|
);
|
||||||
|
expect(detail(result, "Token In").value).toBe("ETH (native)");
|
||||||
|
expect(linesBetweenTokens(result)).toEqual([
|
||||||
|
["Moved from the sender", UNDECODED],
|
||||||
|
["Token moved", "ETH"],
|
||||||
|
["Moved to", "The swap step that spends it"],
|
||||||
|
["Moved from the sender", MOVED_AMOUNT],
|
||||||
|
["Token moved", ZERO_ADDR],
|
||||||
|
["Moved to", OTHER_ADDR],
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// https://git.eeqj.de/sneak/AutistMask/issues/682 — V4 pays a SETTLE
|
// https://git.eeqj.de/sneak/AutistMask/issues/682 — V4 pays a SETTLE
|
||||||
// of ETH from the router's own ETH, whichever payer the SETTLE names,
|
// of ETH from the router's own ETH, whichever payer the SETTLE names,
|
||||||
// and the router holds the transaction's value. On next at 36b2002 a
|
// and the router holds the transaction's value. On next at 36b2002 a
|
||||||
|
|||||||
Reference in New Issue
Block a user