Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
427d99e0a0 | ||
|
|
53551c6382 |
@@ -2820,6 +2820,9 @@ view would leave a wallet one click from deletion.
|
|||||||
- "Export Saved Data" button, and the read-only text box it fills
|
- "Export Saved Data" button, and the read-only text box it fills
|
||||||
- What erasing does and does not do, in bold: every wallet stored in this
|
- What erasing does and does not do, in bold: every wallet stored in this
|
||||||
browser is deleted; nothing on chain changes and no money is moved
|
browser is deleted; nothing on chain changes and no money is moved
|
||||||
|
- What a wallet can be added again from: a kept copy of its recovery phrase,
|
||||||
|
private key or extended private key. Without that copy or the exported
|
||||||
|
copy, everything the wallet holds is gone forever.
|
||||||
- A text input asking for `ERASE MY WALLET` to be typed back
|
- A text input asking for `ERASE MY WALLET` to be typed back
|
||||||
- Error line
|
- Error line
|
||||||
- "Erase Saved Data" button
|
- "Erase Saved Data" button
|
||||||
@@ -3488,52 +3491,54 @@ Currently supported:
|
|||||||
which it does only in the plain shape of Uniswap's own routes: it comes before
|
which it does only in the plain shape of Uniswap's own routes: it comes before
|
||||||
the step that sets the input side, it is the only `PERMIT2_PERMIT` in the
|
the step that sets the input side, it is the only `PERMIT2_PERMIT` in the
|
||||||
transaction and there is no `PERMIT2_PERMIT_BATCH`, its spender is the router,
|
transaction and there is no `PERMIT2_PERMIT_BATCH`, its spender is the router,
|
||||||
the router may not let it fail, no step before it takes its token, a
|
its token is not the zero address, the router may not let it fail, no step
|
||||||
`PERMIT2_TRANSFER_FROM` of it included, or a token the decoder does not know,
|
before it takes its token, a `PERMIT2_TRANSFER_FROM` of it included, or a
|
||||||
and the decoder reads every step after it in full. Permit2 then lets the
|
token the decoder does not know, and the decoder reads every step after it in
|
||||||
router take no more of the token than that amount, so the permit covers every
|
full. Permit2 then lets the router take no more of the token than that amount,
|
||||||
take of it. A step before the permit takes under whatever allowance the router
|
so the permit covers every take of it. Permit2 has no allowance of ETH, so a
|
||||||
already had, so it may take more than the permit's amount, which would then
|
permit on the zero address covers no take of ETH. A step before the permit
|
||||||
read lower than what leaves the user's wallet: a `PERMIT2_TRANSFER_FROM` of
|
takes under whatever allowance the router already had, so it may take more
|
||||||
2,000 USDT into the router, then a permit of 600 USDT to the router and a V3
|
than the permit's amount, which would then read lower than what leaves the
|
||||||
exact-in of 2,000 USDT paid from the router, read `Amount 2000.0000 USDT`. A
|
user's wallet: a `PERMIT2_TRANSFER_FROM` of 2,000 USDT into the router, then a
|
||||||
later permit or batch may raise what Permit2 lets the router take, and so may
|
permit of 600 USDT to the router and a V3 exact-in of 2,000 USDT paid from the
|
||||||
a step the decoder does not read in full: a command the decoder does not read
|
router, read `Amount 2000.0000 USDT`. A later permit or batch may raise what
|
||||||
(listed at the end of this section), a step whose input it cannot read, in
|
Permit2 lets the router take, and so may a step the decoder does not read in
|
||||||
whole or in part, and a step it fails on. Every other `PERMIT2_PERMIT`, before
|
full: a command the decoder does not read (listed at the end of this section),
|
||||||
the step that sets the input side or after it, leaves `Token In` and the
|
a step whose input it cannot read, in whole or in part, and a step it fails
|
||||||
`Amount` line as they read with no permit, unless it lets a spender other than
|
on. Every other `PERMIT2_PERMIT`, before the step that sets the input side or
|
||||||
the router take `Token In` (see below): a permit of 5,000 DAI to another
|
after it, leaves `Token In` and the `Amount` line as they read with no permit,
|
||||||
address and then a V3 exact-in of 600 USDT read `Swap USDT → USDC` with
|
unless it lets a spender other than the router take `Token In` (see below): a
|
||||||
`Amount 600.0000 USDT`, and so do that exact-in and then a permit of 5,000 DAI
|
permit of 5,000 DAI to another address and then a V3 exact-in of 600 USDT read
|
||||||
to the router. When a permit's amount stands and the step that sets the input
|
`Swap USDT → USDC` with `Amount 600.0000 USDT`, and so do that exact-in and
|
||||||
side spends a token other than the permit's, or one the decoder does not know,
|
then a permit of 5,000 DAI to the router. When a permit's amount stands and
|
||||||
that step's amount gets lines of its own, unless it states no amount and the
|
the step that sets the input side spends a token other than the permit's, or
|
||||||
user pays it none of its input token. Each take the total does not count gives
|
one the decoder does not know, that step's amount gets lines of its own,
|
||||||
three lines after the `Amount` line (after `Token In` when there is none): one
|
unless it states no amount and the user pays it none of its input token. Each
|
||||||
of a token other than `Token In`; one of `Token In` after an amount that is
|
take the total does not count gives three lines after the `Amount` line (after
|
||||||
not a quantity (a V4 open delta, `ALREADY_PAID`, which keep their wording on
|
`Token In` when there is none): one of a token other than `Token In`; one of
|
||||||
the `Amount` line, or no stated amount, as of a V4 exact-out step); and one
|
`Token In` after an amount that is not a quantity (a V4 open delta,
|
||||||
whose amount the decoder does not know. When there is no `Amount` line, each
|
`ALREADY_PAID`, which keep their wording on the `Amount` line, or no stated
|
||||||
take the total counts gets them too, so that every amount the decoder reads is
|
amount, as of a V4 exact-out step); and one whose amount the decoder does not
|
||||||
shown: the amount the step that sets the input side states, when it is a
|
know. When there is no `Amount` line, each take the total counts gets them
|
||||||
quantity and the user pays that step (a V2 or V3 step whose `payerIsUser` is
|
too, so that every amount the decoder reads is shown: the amount the step that
|
||||||
true, a V4 step the user pays some of its input token, or a `WRAP_ETH`, whose
|
sets the input side states, when it is a quantity and the user pays that step
|
||||||
ETH comes from the transaction's value), and each later take of `Token In`
|
(a V2 or V3 step whose `payerIsUser` is true, a V4 step the user pays some of
|
||||||
added to it. A step that sets the input side and is paid from the router takes
|
its input token, or a `WRAP_ETH`, whose ETH comes from the transaction's
|
||||||
nothing from the user's wallet and gets none. A `PERMIT2_PERMIT` the decoder
|
value), and each later take of `Token In` added to it. A step that sets the
|
||||||
cannot read, then V3 exact-ins of 600 USDT and 400 DAI paid by the user, give
|
input side and is paid from the router takes nothing from the user's wallet
|
||||||
lines for both amounts. When the step that sets the input side states no
|
and gets none. A `PERMIT2_PERMIT` the decoder cannot read, then V3 exact-ins
|
||||||
amount, the user pays it some of its input token, and there is no `Amount`
|
of 600 USDT and 400 DAI paid by the user, give lines for both amounts. When
|
||||||
line, that step gets them too whenever another take's lines give a figure, or
|
the step that sets the input side states no amount, the user pays it some of
|
||||||
a `PERMIT2_TRANSFER_FROM` of its token gives one, on the lines below or, into
|
its input token, and there is no `Amount` line, that step gets them too
|
||||||
the router, on its `Paid to` line, so that figure cannot read as all that
|
whenever another take's lines give a figure, or a `PERMIT2_TRANSFER_FROM` of
|
||||||
leaves. When it states no amount and the user pays it none of its input token,
|
its token gives one, on the lines below or, into the router, on its `Paid to`
|
||||||
as when the router pays it, that step takes none of that token from the user's
|
line, so that figure cannot read as all that leaves. When it states no amount
|
||||||
wallet and never gets them, with a permit or without. They come in step order,
|
and the user pays it none of its input token, as when the router pays it, that
|
||||||
except that the step that sets the input side comes first when it has them,
|
step takes none of that token from the user's wallet and never gets them, with
|
||||||
followed, when there is no `Amount` line, by the other takes the total counts:
|
a permit or without. They come in step order, except that the step that sets
|
||||||
`Moved from the sender`, its amount, worded as the `Amount` line words one, or
|
the input side comes first when it has them, followed, when there is no
|
||||||
|
`Amount` line, by the other takes the total counts: `Moved from the sender`,
|
||||||
|
its amount, worded as the `Amount` line words one, or
|
||||||
`Unknown (could not be decoded)` when the decoder does not know it;
|
`Unknown (could not be decoded)` when the decoder does not know it;
|
||||||
`Token moved`, giving the token's address as the `Token In` line does; and
|
`Token moved`, giving the token's address as the `Token In` line does; and
|
||||||
`Moved to`, which reads `The swap step that spends it`. A token the decoder
|
`Moved to`, which reads `The swap step that spends it`. A token the decoder
|
||||||
@@ -3566,30 +3571,32 @@ Currently supported:
|
|||||||
amount stands gives none: the `Amount` line gives its amount, `Token In` its
|
amount stands gives none: the `Amount` line gives its amount, `Token In` its
|
||||||
token, and its spender is the router. Each allowance a `PERMIT2_PERMIT_BATCH`
|
token, and its spender is the router. Each allowance a `PERMIT2_PERMIT_BATCH`
|
||||||
grants, one for each token it names, all for its one spender, gives the same
|
grants, one for each token it names, all for its one spender, gives the same
|
||||||
three lines, in step order with those of each `PERMIT2_PERMIT`. A
|
three lines, in step order with those of each `PERMIT2_PERMIT`. For an
|
||||||
`PERMIT2_PERMIT` or `PERMIT2_PERMIT_BATCH` whose input the decoder cannot
|
allowance of the zero address, `Permit2 allowance` gives the amount in base
|
||||||
read, such as one whose token or spender word has a nonzero top byte, may let
|
units and `Allowance token` gives the zero address. A `PERMIT2_PERMIT` or
|
||||||
any spender take any amount of any token: it gives one `Permit2 allowance`
|
`PERMIT2_PERMIT_BATCH` whose input the decoder cannot read, such as one whose
|
||||||
line alone, reading `Unknown (could not be decoded)`. These lines change no
|
token or spender word has a nonzero top byte, may let any spender take any
|
||||||
`Paid to` line: a permit or batch pays nobody. But code that a step runs, such
|
amount of any token: it gives one `Permit2 allowance` line alone, reading
|
||||||
as a V4 pool's hook or a token's own code, can call a spender other than the
|
`Unknown (could not be decoded)`. These lines change no `Paid to` line: a
|
||||||
router, which can then take up to its allowance from the user's wallet before
|
permit or batch pays nobody. But code that a step runs, such as a V4 pool's
|
||||||
the transaction ends. So an allowance to any spender but the router, or a
|
hook or a token's own code, can call a spender other than the router, which
|
||||||
permit or batch the decoder cannot read, makes the minimum read
|
can then take up to its allowance from the user's wallet before the
|
||||||
`Min. paid out`, and when its token is `Token In`, or the decoder does not
|
transaction ends. So an allowance to any spender but the router, or a permit
|
||||||
know its token or `Token In`, it leaves no `Amount` line, whose figure might
|
or batch the decoder cannot read, makes the minimum read `Min. paid out`, and
|
||||||
be too low: a permit of 5,000 USDT to another address and then a V3 exact-in
|
when its token is `Token In`, or the decoder does not know its token or
|
||||||
of 600 USDT read with no `Amount` line, and the 600 USDT gets lines of its
|
`Token In`, it leaves no `Amount` line, whose figure might be too low: a
|
||||||
own. A step goes unread when its recipient does not decode as an address, when
|
permit of 5,000 USDT to another address and then a V3 exact-in of 600 USDT
|
||||||
it is a V3 swap step whose path is shorter than one token address or has bytes
|
read with no `Amount` line, and the 600 USDT gets lines of its own. A step
|
||||||
after its last hop, or when it is a command the decoder does not read: every
|
goes unread when its recipient does not decode as an address, when it is a V3
|
||||||
command other than `PERMIT2_PERMIT`, `PERMIT2_PERMIT_BATCH`,
|
swap step whose path is shorter than one token address or has bytes after its
|
||||||
`PERMIT2_TRANSFER_FROM`, `V2_SWAP_EXACT_IN`, `V2_SWAP_EXACT_OUT`,
|
last hop, or when it is a command the decoder does not read: every command
|
||||||
`V3_SWAP_EXACT_IN`, `V3_SWAP_EXACT_OUT`, `V4_SWAP`, `SWEEP`, `TRANSFER`,
|
other than `PERMIT2_PERMIT`, `PERMIT2_PERMIT_BATCH`, `PERMIT2_TRANSFER_FROM`,
|
||||||
`PAY_PORTION`, `PAY_PORTION_FULL_PRECISION`, `ACROSS_V4_DEPOSIT_V3`,
|
`V2_SWAP_EXACT_IN`, `V2_SWAP_EXACT_OUT`, `V3_SWAP_EXACT_IN`,
|
||||||
`WRAP_ETH`, `UNWRAP_WETH` and `BALANCE_CHECK_ERC20`
|
`V3_SWAP_EXACT_OUT`, `V4_SWAP`, `SWEEP`, `TRANSFER`, `PAY_PORTION`,
|
||||||
(`PERMIT2_TRANSFER_FROM_BATCH`, `EXECUTE_SUB_PLAN` and the NFT commands among
|
`PAY_PORTION_FULL_PRECISION`, `ACROSS_V4_DEPOSIT_V3`, `WRAP_ETH`,
|
||||||
them), or a type its release names no command for.
|
`UNWRAP_WETH` and `BALANCE_CHECK_ERC20` (`PERMIT2_TRANSFER_FROM_BATCH`,
|
||||||
|
`EXECUTE_SUB_PLAN` and the NFT commands among them), or a type its release
|
||||||
|
names no command for.
|
||||||
|
|
||||||
### Non-Goals Forever
|
### Non-Goals Forever
|
||||||
|
|
||||||
|
|||||||
@@ -1994,10 +1994,11 @@
|
|||||||
>Erasing the saved data deletes every wallet stored in
|
>Erasing the saved data deletes every wallet stored in
|
||||||
this browser.</strong
|
this browser.</strong
|
||||||
>
|
>
|
||||||
Nothing on the blockchain changes and no money is moved, but
|
Nothing on the blockchain changes and no money is moved. If
|
||||||
without the exported copy above, or the recovery phrase for
|
you kept a copy of a wallet's recovery phrase, private key
|
||||||
each wallet written down, everything they hold is gone
|
or extended private key, you can add that wallet again.
|
||||||
forever.
|
Without that copy or the exported copy above, everything the
|
||||||
|
wallet holds is gone forever.
|
||||||
</p>
|
</p>
|
||||||
<p class="text-xs mb-1">
|
<p class="text-xs mb-1">
|
||||||
To confirm, type
|
To confirm, type
|
||||||
|
|||||||
+41
-17
@@ -2023,14 +2023,16 @@ function decode(data, toAddress, chainId, sources, fromAddress) {
|
|||||||
// plain shape of Uniswap's own routes: it comes before the step that
|
// plain shape of Uniswap's own routes: it comes before the step that
|
||||||
// set the input side, it is the only PERMIT2_PERMIT in the
|
// set the input side, it is the only PERMIT2_PERMIT in the
|
||||||
// transaction and there is no PERMIT2_PERMIT_BATCH, its spender is
|
// transaction and there is no PERMIT2_PERMIT_BATCH, its spender is
|
||||||
// the router, the router may not let it fail, no step before it took
|
// the router, its token is not the zero address, the router may not
|
||||||
// its token or one not known (a PERMIT2_TRANSFER_FROM of its token
|
// let it fail, no step before it took its token or one not known (a
|
||||||
// included), and this decoder read every step after it in full (see
|
// PERMIT2_TRANSFER_FROM of its token included), and this decoder read
|
||||||
// stepsUnread). Permit2 then lets the router take no more of the token
|
// every step after it in full (see stepsUnread). Permit2 then lets the
|
||||||
// than that amount, so the permit covers every take of it. A step
|
// router take no more of the token than that amount, so the permit
|
||||||
// before it takes under whatever allowance the router already had, so
|
// covers every take of it. Permit2 has no allowance of ETH, so a
|
||||||
// it may take more. A later permit or batch, or a later step this
|
// permit on the zero address covers no take of ETH. A step before it
|
||||||
// decoder did not read, may raise what Permit2 lets the router take.
|
// takes under whatever allowance the router already had, so it may
|
||||||
|
// take more. A later permit or batch, or a later step this decoder
|
||||||
|
// did not read, may raise what Permit2 lets the router take.
|
||||||
// Every other PERMIT2_PERMIT leaves Token In and the Amount line as
|
// Every other PERMIT2_PERMIT leaves Token In and the Amount line as
|
||||||
// they read with no permit, and gets lines of its own below. A step
|
// they read with no permit, and gets lines of its own below. A step
|
||||||
// that may take from the sender what this decoder did not read leaves
|
// that may take from the sender what this decoder did not read leaves
|
||||||
@@ -2047,6 +2049,7 @@ function decode(data, toAddress, chainId, sources, fromAddress) {
|
|||||||
stepCommands.filter((c) => c === "PERMIT2_PERMIT").length === 1 &&
|
stepCommands.filter((c) => c === "PERMIT2_PERMIT").length === 1 &&
|
||||||
!stepCommands.includes("PERMIT2_PERMIT_BATCH") &&
|
!stepCommands.includes("PERMIT2_PERMIT_BATCH") &&
|
||||||
sameAddress(permit.spender, toAddress) &&
|
sameAddress(permit.spender, toAddress) &&
|
||||||
|
permit.token !== "0x0000000000000000000000000000000000000000" &&
|
||||||
!permit.allowedToFail &&
|
!permit.allowedToFail &&
|
||||||
permit.beforeEveryTake &&
|
permit.beforeEveryTake &&
|
||||||
!stepsUnread.some((step) => step > permit.step);
|
!stepsUnread.some((step) => step > permit.step);
|
||||||
@@ -2315,15 +2318,36 @@ function decode(data, toAddress, chainId, sources, fromAddress) {
|
|||||||
});
|
});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
details.push({
|
// Permit2 has no allowance of ETH. An allowance of the zero
|
||||||
label: "Permit2 allowance",
|
// address reads as one of a token nothing knows: its amount in
|
||||||
value:
|
// base units, and the zero address as its token.
|
||||||
p.amount >= MAX_UINT160
|
if (p.token === "0x0000000000000000000000000000000000000000") {
|
||||||
? "Unlimited"
|
details.push({
|
||||||
: amountText(p.amount, tokenInfo(p.token, sources))
|
label: "Permit2 allowance",
|
||||||
.display,
|
value:
|
||||||
});
|
p.amount >= MAX_UINT160
|
||||||
details.push(tokenMovedLine("Allowance token", p.token, sources));
|
? "Unlimited"
|
||||||
|
: 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,
|
||||||
|
|||||||
@@ -23,6 +23,9 @@
|
|||||||
// version field, and showing those users a wipe prompt would be a worse defect
|
// version field, and showing those users a wipe prompt would be a worse defect
|
||||||
// than the one being fixed. It is migrated in place and keeps working.
|
// than the one being fixed. It is migrated in place and keeps working.
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
const {
|
const {
|
||||||
bootPopup,
|
bootPopup,
|
||||||
cleanupPopup,
|
cleanupPopup,
|
||||||
@@ -148,6 +151,29 @@ describe("the destructive reset on the recovery screen", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// A key or xprv wallet has no recovery phrase, so the erase warning names all
|
||||||
|
// three backups (https://git.eeqj.de/sneak/AutistMask/issues/593). The boot
|
||||||
|
// harness holds no static text, so this reads the markup itself.
|
||||||
|
describe("the erase warning on the recovery screen", () => {
|
||||||
|
test("names the recovery phrase, the private key and the extended private key", () => {
|
||||||
|
const html = fs.readFileSync(
|
||||||
|
path.join(__dirname, "..", "src", "popup", "index.html"),
|
||||||
|
"utf8",
|
||||||
|
);
|
||||||
|
const start = html.indexOf('id="view-state-recovery"');
|
||||||
|
const end = html.indexOf('id="btn-state-recovery-reset"', start);
|
||||||
|
const screenText = html
|
||||||
|
.slice(start, end)
|
||||||
|
.replace(/<[^>]*>/g, " ")
|
||||||
|
.replace(/\s+/g, " ");
|
||||||
|
|
||||||
|
expect(screenText).toContain(
|
||||||
|
"If you kept a copy of a wallet's recovery phrase, private key or " +
|
||||||
|
"extended private key, you can add that wallet again.",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("a popup already open when the stored profile becomes unreadable", () => {
|
describe("a popup already open when the stored profile becomes unreadable", () => {
|
||||||
// https://git.eeqj.de/sneak/AutistMask/issues/373. The popup used to stay
|
// https://git.eeqj.de/sneak/AutistMask/issues/373. The popup used to stay
|
||||||
// on the wallet list with the last good balances, and only a reopen
|
// on the wallet list with the last good balances, and only a reopen
|
||||||
|
|||||||
@@ -3310,6 +3310,98 @@ describe("uniswap decoder", () => {
|
|||||||
|
|
||||||
expect(detail(result, "Amount").value).toBe("Up to 1000.0000 USDT");
|
expect(detail(result, "Amount").value).toBe("Up to 1000.0000 USDT");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// https://git.eeqj.de/sneak/AutistMask/issues/660 — Permit2 has no
|
||||||
|
// allowance of ETH, so a permit on the zero address reads as one on a
|
||||||
|
// token nothing knows. On next at 53551c6 such a permit's Allowance
|
||||||
|
// token line read ETH. A permit of 1 wei of the zero address before a
|
||||||
|
// V4 step of 5 ETH made the Amount line read 0.000000000000000001 ETH.
|
||||||
|
describe("a permit on the zero address", () => {
|
||||||
|
const FIVE_ETH = 5000000000000000000n;
|
||||||
|
// The lines of a permit of `amount` base units of the zero
|
||||||
|
// address for the router.
|
||||||
|
const zeroAddressLines = (amount) => [
|
||||||
|
[
|
||||||
|
"Permit2 allowance",
|
||||||
|
amount + " base units (decimals unknown)",
|
||||||
|
],
|
||||||
|
["Allowance token", ZERO_ADDR],
|
||||||
|
["Allowance spender", getAddress(ROUTER_ADDR)],
|
||||||
|
];
|
||||||
|
|
||||||
|
test("a PERMIT2_PERMIT on the zero address names the address", () => {
|
||||||
|
const result = decodeSteps(
|
||||||
|
[0x00, 0x0a],
|
||||||
|
[
|
||||||
|
V3_600,
|
||||||
|
encodePermit2(
|
||||||
|
ZERO_ADDR,
|
||||||
|
1000000000000000000n,
|
||||||
|
ROUTER_ADDR,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
expect(linesBetweenTokens(result)).toEqual([
|
||||||
|
["Amount", "600.0000 USDT"],
|
||||||
|
...zeroAddressLines("1000000000000000000"),
|
||||||
|
]);
|
||||||
|
expect(detail(result, "Allowance token").address).toBe(
|
||||||
|
ZERO_ADDR,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("a PERMIT2_PERMIT_BATCH entry on the zero address names the address", () => {
|
||||||
|
const result = decodeSteps(
|
||||||
|
[0x03, 0x00],
|
||||||
|
[
|
||||||
|
encodePermit2Batch(
|
||||||
|
[
|
||||||
|
[USDT_ADDR, USDT_600],
|
||||||
|
[ZERO_ADDR, 1000000000000000000n],
|
||||||
|
],
|
||||||
|
ROUTER_ADDR,
|
||||||
|
),
|
||||||
|
V3_600,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
expect(linesBetweenTokens(result)).toEqual([
|
||||||
|
["Amount", "600.0000 USDT"],
|
||||||
|
...USDT_600_LINES,
|
||||||
|
...zeroAddressLines("1000000000000000000"),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("a PERMIT2_PERMIT of 1 wei of the zero address, then a V4 step of 5 ETH the user settles, shows the 5 ETH", () => {
|
||||||
|
const result = decodeSteps(
|
||||||
|
[0x0a, 0x10],
|
||||||
|
[
|
||||||
|
encodePermit2(ZERO_ADDR, 1n, ROUTER_ADDR),
|
||||||
|
encodeV4Swap(
|
||||||
|
new Uint8Array([
|
||||||
|
V4_SWAP_EXACT_IN_SINGLE_ID,
|
||||||
|
V4_SETTLE_ID,
|
||||||
|
V4_TAKE_ALL_ID,
|
||||||
|
]),
|
||||||
|
[
|
||||||
|
encodeV4ExactInSingle(
|
||||||
|
ZERO_ADDR,
|
||||||
|
USDC_ADDR,
|
||||||
|
FIVE_ETH,
|
||||||
|
1n,
|
||||||
|
),
|
||||||
|
settle(ZERO_ADDR, FIVE_ETH, true),
|
||||||
|
encodeV4TakeAll(USDC_ADDR, 1n),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
expect(detail(result, "Token In").value).toBe("ETH (native)");
|
||||||
|
expect(linesBetweenTokens(result)).toEqual([
|
||||||
|
["Amount", "5.0000 ETH"],
|
||||||
|
...zeroAddressLines("1"),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// https://git.eeqj.de/sneak/AutistMask/issues/359 — the output half, in
|
// https://git.eeqj.de/sneak/AutistMask/issues/359 — the output half, in
|
||||||
|
|||||||
Reference in New Issue
Block a user