fix: a swap split across steps the user pays for shows every amount it spends (closes #625)
The swap's Amount line took only the first swap step's amount. Each later V2, V3 or V4 swap step the user pays for now adds what it spends of Token In to that line, and one that spends another token gets Moved from the sender, Token moved and Moved to lines of its own. Steps paid from the router add nothing, and a PERMIT2_PERMIT keeps its own amount. Model: opus-5-5
This commit is contained in:
@@ -1189,14 +1189,8 @@ number. They can read:
|
||||
`amountOut`, the exact amount it buys.
|
||||
- `All available (V4 open delta)`: the swap's `Amount` line, when the amount it
|
||||
shows is a V4 exact-in `amountIn` of zero. V4 reads that zero as "use the
|
||||
whole open delta", so the calldata states no quantity. The line shows the
|
||||
amount of the step that sets the input side: the last `PERMIT2_PERMIT` step if
|
||||
there is one, otherwise the first V2 or V3 exact-in, V2 exact-out, `WRAP_ETH`
|
||||
or V4 swap step that names an input token or amount. A V4 step with a swap
|
||||
action sets the input side when no earlier step set it, even when it names
|
||||
neither, as described below. A V2 exact-out step gives its `amountInMax`, and
|
||||
a V4 swap step the `amountIn` of the swap action that spends its input
|
||||
currency.
|
||||
whole open delta", so the calldata states no quantity. Transaction Decoding
|
||||
below gives the steps whose amounts the line shows.
|
||||
- `Whatever an earlier step sent to the pair (V2 already paid)`: the swap's
|
||||
`Amount` line, when the amount it shows is a V2 exact-in `amountIn` of zero.
|
||||
The router reads that zero as "the pair already holds the input tokens": the
|
||||
@@ -2374,10 +2368,11 @@ view would leave a wallet one click from deletion.
|
||||
- Site origin (bold, scheme and port included) + "wants to send a
|
||||
transaction"
|
||||
- Decoded action (if calldata is recognized): action name, token details,
|
||||
amounts, what each `PERMIT2_TRANSFER_FROM` moves and where to, steps,
|
||||
deadline, and unless a swap pays only the From address, a `Paid to` line
|
||||
for each other address it pays, or saying that a token stays in the router
|
||||
or who it pays is unknown (see Transaction Decoding)
|
||||
amounts, what each swap step the user pays for spends of a token other
|
||||
than `Token In`, what each `PERMIT2_TRANSFER_FROM` moves and where to,
|
||||
steps, deadline, and unless a swap pays only the From address, a `Paid to`
|
||||
line for each other address it pays, or saying that a token stays in the
|
||||
router or who it pays is unknown (see Transaction Decoding)
|
||||
- From: color dot + full address + etherscan link
|
||||
- Contract: color dot + full address + etherscan link, token symbol label if
|
||||
known; for a contract creation, the same sentence as on WaitTx
|
||||
@@ -3127,24 +3122,48 @@ Currently supported:
|
||||
name); and one more reads `Unknown (could not be decoded)` when a step that
|
||||
may pay an address went unread. When no step pays anyone, a single line reads
|
||||
`Unknown (not named in the calldata)`. Wherever there is a `Paid to` line, the
|
||||
minimum reads `Min. paid out`. After the `Amount` line (after `Token In` when
|
||||
there is none), each `PERMIT2_TRANSFER_FROM` but one into the router, in step
|
||||
order, gives three lines: `Moved from the sender`, the amount it moves, for
|
||||
example `1000000.0000 USDT`; `Token moved`, giving the token's 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)`
|
||||
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
|
||||
`Token moved into the router` line already give the amount, the token and
|
||||
where it goes, and so its amount is shown once. These lines change neither the
|
||||
`Paid to` lines nor the minimum's label. A step goes unread when its recipient
|
||||
does not decode as an address, or when it is a command the decoder does not
|
||||
read: every command other than `PERMIT2_PERMIT`, `PERMIT2_TRANSFER_FROM`,
|
||||
`V2_SWAP_EXACT_IN`, `V2_SWAP_EXACT_OUT`, `V3_SWAP_EXACT_IN`, `V4_SWAP`,
|
||||
`SWEEP`, `TRANSFER`, `PAY_PORTION`, `PAY_PORTION_FULL_PRECISION`,
|
||||
`ACROSS_V4_DEPOSIT_V3`, `WRAP_ETH`, `UNWRAP_WETH` and `BALANCE_CHECK_ERC20`
|
||||
(`V3_SWAP_EXACT_OUT`, `PERMIT2_TRANSFER_FROM_BATCH`, `EXECUTE_SUB_PLAN` and
|
||||
the NFT commands among them), or a type its release names no command for.
|
||||
minimum reads `Min. paid out`. The `Amount` line gives the amount of the step
|
||||
that sets the input side: the last `PERMIT2_PERMIT` step if there is one,
|
||||
otherwise the first V2 or V3 exact-in, V2 exact-out, `WRAP_ETH` or V4 swap
|
||||
step that names an input token or amount. A V4 step with a swap action sets
|
||||
the input side when no earlier step set it, even when it names neither (see
|
||||
Display Consistency). A V2 exact-out step gives its `amountInMax`, and a V4
|
||||
swap step the `amountIn` of the swap action that spends its input currency.
|
||||
Each later swap step that the user pays for also takes its amount, found in
|
||||
the same way, from the user's wallet: a V2 or V3 exact-in or V2 exact-out step
|
||||
whose `payerIsUser` is true, or a V4 step with a swap action whose input
|
||||
currency a `SETTLE` paid by the user (`payerIsUser` true) or a `SETTLE_ALL`
|
||||
names. When it spends `Token In`, its amount is added to the line's, unless a
|
||||
`PERMIT2_PERMIT` set the input side, whose amount the line keeps. So a V3
|
||||
exact-in of 600 USDT and a V2 exact-in of 400 USDT, both paid by the user,
|
||||
read `1000.0000 USDT`. When either amount is not a quantity (a V4 open delta,
|
||||
`ALREADY_PAID`, or an amount the decoder did not read), the total is not known
|
||||
and there is no `Amount` line. A step paid from the router spends what the
|
||||
router holds and adds nothing, and so does a V2 exact-in whose `amountIn` is
|
||||
`ALREADY_PAID`, which takes nothing from the user. A step the user pays for
|
||||
that spends a token other than `Token In` gives three lines after the `Amount`
|
||||
line (after `Token In` when there is none), in step order:
|
||||
`Moved from the sender`, its amount, worded as the `Amount` line words one, or
|
||||
`Unknown (could not be decoded)` when the decoder read none; `Token moved`,
|
||||
giving the token's address as the `Token In` line does; and `Moved to`, which
|
||||
reads `The swap step that spends it`. Then each `PERMIT2_TRANSFER_FROM` but
|
||||
one into the router, in step order, gives three lines:
|
||||
`Moved from the sender`, the amount it moves, for example `1000000.0000 USDT`;
|
||||
`Token moved`, giving the token's 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)` 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 `Token moved into the router` line already give
|
||||
the amount, the token and where it goes, and so its amount is shown once.
|
||||
These lines change neither the `Paid to` lines nor the minimum's label. A step
|
||||
goes unread when its recipient does not decode as an address, or when it is a
|
||||
command the decoder does not read: every command other than `PERMIT2_PERMIT`,
|
||||
`PERMIT2_TRANSFER_FROM`, `V2_SWAP_EXACT_IN`, `V2_SWAP_EXACT_OUT`,
|
||||
`V3_SWAP_EXACT_IN`, `V4_SWAP`, `SWEEP`, `TRANSFER`, `PAY_PORTION`,
|
||||
`PAY_PORTION_FULL_PRECISION`, `ACROSS_V4_DEPOSIT_V3`, `WRAP_ETH`,
|
||||
`UNWRAP_WETH` and `BALANCE_CHECK_ERC20` (`V3_SWAP_EXACT_OUT`,
|
||||
`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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user