fix: an allowance to another spender leaves no Amount figure for its token and no Min. received (closes #658)
Code that a step runs, such as a V4 pool's hook, can call a spender other than the router, which can then take up to its allowance from the user's wallet before the transaction ends. The Amount figure and Min. received took no account of it. In decode(), an allowance of Token In to a spender other than the router now leaves no Amount line, as an unread permit already did, so the swap steps' own takes get lines of their own. Any allowance to another spender, or a permit or batch the decoder cannot read, makes the minimum read Min. paid out. Permits to the router read as before. Model: opus-5-5
This commit was merged in pull request #666.
This commit is contained in:
@@ -1173,8 +1173,8 @@ fetched, without that cross-address check, and shows the row's figure.
|
||||
**Decoded amount lines on the transaction approval screen:** the `Amount` line
|
||||
of a decoded ERC-20 call, and the `Amount` and `Min. received` lines of a
|
||||
decoded swap (see TxApproval below; `Min. received` reads `Min. paid out` unless
|
||||
only the user is paid, see Transaction Decoding), do not always read as a
|
||||
number. They can read:
|
||||
only the user is paid and no allowance goes to a spender other than the router,
|
||||
see Transaction Decoding), do not always read as a number. They can read:
|
||||
|
||||
- A formatted quantity, e.g. `17.1900 USDT`, when the token's scale is known:
|
||||
truncated to four decimals, with the floor and the zero cases described above.
|
||||
@@ -3197,8 +3197,9 @@ Currently supported:
|
||||
`Min. paid out`, because the swap's minimum includes the fee. The minimum
|
||||
reads `Min. received` only when some step pays the transaction's sender (the
|
||||
From address on TxApproval, the sender the explorer reports on
|
||||
TransactionDetail) and no `Paid to` line is shown. `Paid to` lines after
|
||||
`Token Out` name each other address paid; one reads
|
||||
TransactionDetail), no `Paid to` line is shown, and no permit or batch grants
|
||||
an allowance to a spender other than the router (see below). `Paid to` lines
|
||||
after `Token Out` name each other address paid; one reads
|
||||
`The bridge, which pays the deposit's recipient on another network` for a
|
||||
bridge deposit; one reads, for example,
|
||||
`The router, 2000.0000 USDT from the sender (later steps may not spend all of it)`
|
||||
@@ -3252,7 +3253,8 @@ Currently supported:
|
||||
(listed at the end of this section), a step whose input it cannot read, in
|
||||
whole or in part, and a step it fails on. Every other `PERMIT2_PERMIT`, before
|
||||
the step that sets the input side or after it, leaves `Token In` and the
|
||||
`Amount` line as they read with no permit: a permit of 5,000 DAI to another
|
||||
`Amount` line as they read with no permit, unless it lets a spender other than
|
||||
the router take `Token In` (see below): a permit of 5,000 DAI to another
|
||||
address and then a V3 exact-in of 600 USDT read `Swap USDT → USDC` with
|
||||
`Amount 600.0000 USDT`, and so do that exact-in and then a permit of 5,000 DAI
|
||||
to the router. When a permit's amount stands and the step that sets the input
|
||||
@@ -3319,19 +3321,26 @@ Currently supported:
|
||||
`PERMIT2_PERMIT` or `PERMIT2_PERMIT_BATCH` whose input the decoder cannot
|
||||
read, such as one whose token or spender word has a nonzero top byte, may let
|
||||
any spender take any amount of any token: it gives one `Permit2 allowance`
|
||||
line alone, reading `Unknown (could not be decoded)`, and leaves no `Amount`
|
||||
line, whose figure might be too low. These lines change neither the `Paid to`
|
||||
lines nor the minimum's label: a permit or batch pays nobody. A step goes
|
||||
unread when its recipient does not decode as an address, when it is a V3 swap
|
||||
step whose path is shorter than one token address or has bytes after its last
|
||||
hop, or when it is a command the decoder does not read: every command other
|
||||
than `PERMIT2_PERMIT`, `PERMIT2_PERMIT_BATCH`, `PERMIT2_TRANSFER_FROM`,
|
||||
`V2_SWAP_EXACT_IN`, `V2_SWAP_EXACT_OUT`, `V3_SWAP_EXACT_IN`,
|
||||
`V3_SWAP_EXACT_OUT`, `V4_SWAP`, `SWEEP`, `TRANSFER`, `PAY_PORTION`,
|
||||
`PAY_PORTION_FULL_PRECISION`, `ACROSS_V4_DEPOSIT_V3`, `WRAP_ETH`,
|
||||
`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.
|
||||
line alone, reading `Unknown (could not be decoded)`. These lines change no
|
||||
`Paid to` line: a permit or batch pays nobody. But code that a step runs, such
|
||||
as a V4 pool's hook or a token's own code, can call a spender other than the
|
||||
router, which can then take up to its allowance from the user's wallet before
|
||||
the transaction ends. So an allowance to any spender but the router, or a
|
||||
permit or batch the decoder cannot read, makes the minimum read
|
||||
`Min. paid out`, and when its token is `Token In`, or the decoder does not
|
||||
know its token or `Token In`, it leaves no `Amount` line, whose figure might
|
||||
be too low: a permit of 5,000 USDT to another address and then a V3 exact-in
|
||||
of 600 USDT read with no `Amount` line, and the 600 USDT gets lines of its
|
||||
own. A step goes unread when its recipient does not decode as an address, when
|
||||
it is a V3 swap step whose path is shorter than one token address or has bytes
|
||||
after its last hop, or when it is a command the decoder does not read: every
|
||||
command other than `PERMIT2_PERMIT`, `PERMIT2_PERMIT_BATCH`,
|
||||
`PERMIT2_TRANSFER_FROM`, `V2_SWAP_EXACT_IN`, `V2_SWAP_EXACT_OUT`,
|
||||
`V3_SWAP_EXACT_IN`, `V3_SWAP_EXACT_OUT`, `V4_SWAP`, `SWEEP`, `TRANSFER`,
|
||||
`PAY_PORTION`, `PAY_PORTION_FULL_PRECISION`, `ACROSS_V4_DEPOSIT_V3`,
|
||||
`WRAP_ETH`, `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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user