The router's execute() reverts the whole transaction when a step fails unless its allow-revert flag (0x80) is set, and dispatch() returns a failure only for some commands. In src/shared/uniswap.js, ROUTER_ADDRESSES now gives each address its release (ROUTER_V1 and so on), holding the mask and that list, cited at the release's commit:
UniversalRouterV2, V2_1_1, V2_1_2: PERMIT2_PERMIT, PERMIT2_PERMIT_BATCH, BALANCE_CHECK_ERC20, the position manager calls, V4_INITIALIZE_POOL, EXECUTE_SUB_PLAN.
UniversalRouterV1_2_V2Support: BALANCE_CHECK_ERC20, EXECUTE_SUB_PLAN, its NFT commands.
UniversalRouterV1: its NFT commands.
A flagged step of one of these reads (allowed to fail) on the Steps line. A minimum such a step states guarantees nothing, so it is read as zero: a flagged BALANCE_CHECK_ERC20 no longer replaces an earlier swap's minimum, and a flagged 0x10 on UniversalRouterV1 or UniversalRouterV1_2_V2Support (an NFT command there, still read as a V4 swap until #592 lands) reads None (no minimum guaranteed).
No swap, payment of ETH or an ERC-20 token, or V2 swap a hop pays into is on any list, so the flag on those has no effect; the tests check that each reads exactly as without it.
Disclosures:
Judgement call: the issue's first done item says a flagged swap, payout or hop never reads Min. received. The router reverts the whole transaction when such a step fails, flag or not, so its minimum still holds and still reads received.
Judgement call: a minimum stated by a flagged step the router lets fail is read as zero, rather than labelling a figure nothing guarantees as Min. paid out.
Model: opus-5-5
Implements https://git.eeqj.de/sneak/AutistMask/issues/602.
The router's `execute()` reverts the whole transaction when a step fails unless its allow-revert flag (`0x80`) is set, and `dispatch()` returns a failure only for some commands. In `src/shared/uniswap.js`, `ROUTER_ADDRESSES` now gives each address its release (`ROUTER_V1` and so on), holding the mask and that list, cited at the release's commit:
- `UniversalRouterV2`, `V2_1_1`, `V2_1_2`: `PERMIT2_PERMIT`, `PERMIT2_PERMIT_BATCH`, `BALANCE_CHECK_ERC20`, the position manager calls, `V4_INITIALIZE_POOL`, `EXECUTE_SUB_PLAN`.
- `UniversalRouterV1_2_V2Support`: `BALANCE_CHECK_ERC20`, `EXECUTE_SUB_PLAN`, its NFT commands.
- `UniversalRouterV1`: its NFT commands.
A flagged step of one of these reads `(allowed to fail)` on the Steps line. A minimum such a step states guarantees nothing, so it is read as zero: a flagged `BALANCE_CHECK_ERC20` no longer replaces an earlier swap's minimum, and a flagged `0x10` on `UniversalRouterV1` or `UniversalRouterV1_2_V2Support` (an NFT command there, still read as a V4 swap until https://git.eeqj.de/sneak/AutistMask/issues/592 lands) reads `None (no minimum guaranteed)`.
No swap, payment of ETH or an ERC-20 token, or V2 swap a hop pays into is on any list, so the flag on those has no effect; the tests check that each reads exactly as without it.
Disclosures:
- Judgement call: the issue's first done item says a flagged swap, payout or hop never reads `Min. received`. The router reverts the whole transaction when such a step fails, flag or not, so its minimum still holds and still reads received.
- Judgement call: a minimum stated by a flagged step the router lets fail is read as zero, rather than labelling a figure nothing guarantees as `Min. paid out`.
Model: opus-5-5
src/shared/uniswap.js, decode(), the 0x10 branch. On UniversalRouterV1 and UniversalRouterV1_2_V2Support, 0x10 is a command the router lets fail (it is on this PR's own lists for both), but the decoder still reads it as a V4 swap. With the allow-revert flag set, the step now reads V4 Swap (allowed to fail), and its minimum still reads Min. received. So the screen says the step may fail and still calls its minimum received, which is the case #602 rules out. Pointing to #592 leaves that on next until that issue lands. Acceptable: a step the router lets fail sets no minimum, read the way this PR reads a flagged balance check (as a zero one), so no minimum is ever called received next to (allowed to fail). Add a test on each of those two routers.
tests/uniswapRecipient.test.js, the allow-revert flag. No test covers UniversalRouterV1's list: there is no flagged step on that router that must read (allowed to fail). A wrong entry in that list would go unnoticed. Acceptable: for each router's list, at least one flagged step that must read (allowed to fail).
Judgement call: I took the PR's reading that a flagged swap, or a flagged payment of ETH or an ERC-20 token, keeps its minimum, because the cited router source reverts the whole transaction when such a step fails, flag or not. The first done item is measured against the steps the router lets fail.
Model: opus-5-5
**Review: FAIL (`needs-rework`)**
1. `src/shared/uniswap.js`, `decode()`, the `0x10` branch. On `UniversalRouterV1` and `UniversalRouterV1_2_V2Support`, `0x10` is a command the router lets fail (it is on this PR's own lists for both), but the decoder still reads it as a V4 swap. With the allow-revert flag set, the step now reads `V4 Swap (allowed to fail)`, and its minimum still reads `Min. received`. So the screen says the step may fail and still calls its minimum received, which is the case https://git.eeqj.de/sneak/AutistMask/issues/602 rules out. Pointing to https://git.eeqj.de/sneak/AutistMask/issues/592 leaves that on `next` until that issue lands. Acceptable: a step the router lets fail sets no minimum, read the way this PR reads a flagged balance check (as a zero one), so no minimum is ever called received next to `(allowed to fail)`. Add a test on each of those two routers.
2. `tests/uniswapRecipient.test.js`, `the allow-revert flag`. No test covers `UniversalRouterV1`'s list: there is no flagged step on that router that must read `(allowed to fail)`. A wrong entry in that list would go unnoticed. Acceptable: for each router's list, at least one flagged step that must read `(allowed to fail)`.
Judgement call: I took the PR's reading that a flagged swap, or a flagged payment of ETH or an ERC-20 token, keeps its minimum, because the cited router source reverts the whole transaction when such a step fails, flag or not. The first done item is measured against the steps the router lets fail.
Model: opus-5-5
Each Universal Router release now carries the command types its dispatch()
can return a failure for instead of reverting, read from its source; only a
step of one of those with the allow-revert flag (0x80) set can fail while the
transaction goes on. Such a step is listed with "(allowed to fail)". A minimum
such a step states guarantees nothing, so it is read as zero: a
BALANCE_CHECK_ERC20 then keeps an earlier step's minimum, and 0x10 on
UniversalRouterV1 and UniversalRouterV1_2_V2Support, an NFT call there still
read as a V4 swap, states no minimum. Every swap and every payment of ETH or an
ERC-20 token succeeds or reverts the whole transaction, so the flag on them has
no effect.
Model: opus-5-5
A minimum stated by a flagged step the router lets fail is now read as zero, as a flagged balance check's is, so a flagged 0x10 on UniversalRouterV1 and UniversalRouterV1_2_V2Support reads None (no minimum guaranteed) beside V4 Swap (allowed to fail); a test on each of the two routers, and the README says so.
Added one flagged command from each router's list that must read (allowed to fail): FOUNDATION on UniversalRouterV1 (beside its 0x10 above), ELEMENT_MARKET on UniversalRouterV1_2_V2Support, PERMIT2_PERMIT_BATCH on UniversalRouterV2, V4_INITIALIZE_POOL on UniversalRouterV2_1_1, V4_POSITION_MANAGER_CALL on UniversalRouterV2_1_2.
Model: opus-5-5
1. A minimum stated by a flagged step the router lets fail is now read as zero, as a flagged balance check's is, so a flagged `0x10` on `UniversalRouterV1` and `UniversalRouterV1_2_V2Support` reads `None (no minimum guaranteed)` beside `V4 Swap (allowed to fail)`; a test on each of the two routers, and the README says so.
2. Added one flagged command from each router's list that must read `(allowed to fail)`: `FOUNDATION` on `UniversalRouterV1` (beside its `0x10` above), `ELEMENT_MARKET` on `UniversalRouterV1_2_V2Support`, `PERMIT2_PERMIT_BATCH` on `UniversalRouterV2`, `V4_INITIALIZE_POOL` on `UniversalRouterV2_1_1`, `V4_POSITION_MANAGER_CALL` on `UniversalRouterV2_1_2`.
Model: opus-5-5
The rework meets both findings of #612 (comment): a flagged step the router lets fail never has its minimum read as received, on UniversalRouterV1 and UniversalRouterV1_2_V2Support included, and each router's list has a test.
Model: opus-5-5
**Review: PASS**
The rework meets both findings of https://git.eeqj.de/sneak/AutistMask/pulls/612#issuecomment-148401: a flagged step the router lets fail never has its minimum read as received, on `UniversalRouterV1` and `UniversalRouterV1_2_V2Support` included, and each router's list has a test.
Model: opus-5-5
clawbot
merged commit c99772a520 into next2026-10-19 15:24:14 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Implements #602.
The router's
execute()reverts the whole transaction when a step fails unless its allow-revert flag (0x80) is set, anddispatch()returns a failure only for some commands. Insrc/shared/uniswap.js,ROUTER_ADDRESSESnow gives each address its release (ROUTER_V1and so on), holding the mask and that list, cited at the release's commit:UniversalRouterV2,V2_1_1,V2_1_2:PERMIT2_PERMIT,PERMIT2_PERMIT_BATCH,BALANCE_CHECK_ERC20, the position manager calls,V4_INITIALIZE_POOL,EXECUTE_SUB_PLAN.UniversalRouterV1_2_V2Support:BALANCE_CHECK_ERC20,EXECUTE_SUB_PLAN, its NFT commands.UniversalRouterV1: its NFT commands.A flagged step of one of these reads
(allowed to fail)on the Steps line. A minimum such a step states guarantees nothing, so it is read as zero: a flaggedBALANCE_CHECK_ERC20no longer replaces an earlier swap's minimum, and a flagged0x10onUniversalRouterV1orUniversalRouterV1_2_V2Support(an NFT command there, still read as a V4 swap until #592 lands) readsNone (no minimum guaranteed).No swap, payment of ETH or an ERC-20 token, or V2 swap a hop pays into is on any list, so the flag on those has no effect; the tests check that each reads exactly as without it.
Disclosures:
Min. received. The router reverts the whole transaction when such a step fails, flag or not, so its minimum still holds and still reads received.Min. paid out.Model: opus-5-5
clawbot referenced this pull request2026-10-19 14:37:27 +02:00
Review: FAIL (
needs-rework)src/shared/uniswap.js,decode(), the0x10branch. OnUniversalRouterV1andUniversalRouterV1_2_V2Support,0x10is a command the router lets fail (it is on this PR's own lists for both), but the decoder still reads it as a V4 swap. With the allow-revert flag set, the step now readsV4 Swap (allowed to fail), and its minimum still readsMin. received. So the screen says the step may fail and still calls its minimum received, which is the case #602 rules out. Pointing to #592 leaves that onnextuntil that issue lands. Acceptable: a step the router lets fail sets no minimum, read the way this PR reads a flagged balance check (as a zero one), so no minimum is ever called received next to(allowed to fail). Add a test on each of those two routers.tests/uniswapRecipient.test.js,the allow-revert flag. No test coversUniversalRouterV1's list: there is no flagged step on that router that must read(allowed to fail). A wrong entry in that list would go unnoticed. Acceptable: for each router's list, at least one flagged step that must read(allowed to fail).Judgement call: I took the PR's reading that a flagged swap, or a flagged payment of ETH or an ERC-20 token, keeps its minimum, because the cited router source reverts the whole transaction when such a step fails, flag or not. The first done item is measured against the steps the router lets fail.
Model: opus-5-5
14794a3931to70af00417c0x10onUniversalRouterV1andUniversalRouterV1_2_V2SupportreadsNone (no minimum guaranteed)besideV4 Swap (allowed to fail); a test on each of the two routers, and the README says so.(allowed to fail):FOUNDATIONonUniversalRouterV1(beside its0x10above),ELEMENT_MARKETonUniversalRouterV1_2_V2Support,PERMIT2_PERMIT_BATCHonUniversalRouterV2,V4_INITIALIZE_POOLonUniversalRouterV2_1_1,V4_POSITION_MANAGER_CALLonUniversalRouterV2_1_2.Model: opus-5-5
Review: PASS
The rework meets both findings of #612 (comment): a flagged step the router lets fail never has its minimum read as received, on
UniversalRouterV1andUniversalRouterV1_2_V2Supportincluded, and each router's list has a test.Model: opus-5-5