diff --git a/.changeset/ink-dutchv3-mappings.md b/.changeset/ink-dutchv3-mappings.md new file mode 100644 index 000000000..3dbaf96d3 --- /dev/null +++ b/.changeset/ink-dutchv3-mappings.md @@ -0,0 +1,14 @@ +--- +'@uniswap/uniswapx-sdk': patch +--- + +Add Ink (chainId 57073) DutchV3 support. The reactor and OrderQuoter are deployed and source-verified on Ink; these are the mapping entries that let the SDK resolve them. + +- `REACTOR_ADDRESS_MAPPING[57073][Dutch_V3]` → `0x000000007A1C8e570011EeDF86A2A35593013cBA`. This is the same address as Robinhood (4663), as chains 130/196/1868 already share `0x000000005aF6…`; `REVERSE_REACTOR_MAPPING` collapses shared addresses to one key, which is correct since both are `Dutch_V3`. +- `UNISWAPX_ORDER_QUOTER_MAPPING[57073]` → canonical `0x00000000a3db63Df9078cBF3dF88B4CAdD5a7F58`. Required: `constructSameAddressMap` only seeds the five `NETWORKS_WITH_SAME_ADDRESS` chains, so without an explicit entry the lookup is `undefined` and `UniswapXOrderQuoter`'s constructor throws `MissingConfiguration("quoter", "57073")`. +- `PERMIT2_MAPPING[57073]` → canonical Permit2, verified on-chain (9,152 bytes, non-zero `DOMAIN_SEPARATOR()`). +- `EXCLUSIVE_FILLER_VALIDATION_MAPPING[57073]` → zero address, matching every other V3-only chain. Required, and the quieter of the two: without an entry the lookup is `undefined`, and `encodeExclusiveFillerData` assigns it into `ValidationInfo.additionalValidationContract` unguarded, so `undefined` propagates into order construction instead of throwing. Exclusivity itself is reactor-enforced via `ExclusivityLib`; the zero address makes the hook correctly inert. + +No entry is added for `Priority`, `Dutch_V2`, `Hybrid`, or the `UNISWAPX_V4_*` mappings — no such reactors are deployed on Ink, and the absence is what makes x-service's `OffChainUniswapXOrderValidator.validateReactorAddress` reject those order types for the chain. + +Ink needs no chain-specific order-construction handling: it is a standard OP-stack L2 with 1s blocks, a real dynamic EIP-1559 basefee, and native ETH, so `adjustmentPerGweiBaseFee` keeps its normal non-zero treatment and the native sentinel is usable. `@uniswap/sdk-core` already has full Ink coverage (`ChainId.INK`, `INK_ADDRESSES`, `WETH9[57073]`, 1s block time). diff --git a/sdks/uniswapx-sdk/src/builder/V3DutchOrderBuilder.test.ts b/sdks/uniswapx-sdk/src/builder/V3DutchOrderBuilder.test.ts index 2511aa390..7e162bda3 100644 --- a/sdks/uniswapx-sdk/src/builder/V3DutchOrderBuilder.test.ts +++ b/sdks/uniswapx-sdk/src/builder/V3DutchOrderBuilder.test.ts @@ -665,14 +665,15 @@ describe("V3DutchOrderBuilder", () => { ); }); - // DutchV3 rollout: Robinhood (4663) and Arc (5042). decayBlocks is the - // chain-realistic V3 decay window (~30s wallclock): 60 blocks at Arc's - // 500ms, 120 blocks at Robinhood's ~250ms under load. Confirms the reactor - // resolves from REACTOR_ADDRESS_MAPPING and an order decaying over that - // window builds. + // DutchV3 rollout: Robinhood (4663), Arc (5042), Ink (57073). decayBlocks is + // the chain-realistic V3 decay window (~30s wallclock): 60 blocks at Arc's + // 500ms, 120 blocks at Robinhood's ~250ms under load, 30 blocks at Ink's 1s. + // Confirms the reactor resolves from REACTOR_ADDRESS_MAPPING and an order + // decaying over that window builds. describe.each([ { name: "Robinhood", chainId: 4663, reactor: "0x000000007A1C8e570011EeDF86A2A35593013cBA", decayBlocks: 120 }, { name: "Arc", chainId: 5042, reactor: "0x0000000015134054eA82AE0bb9fda66b36402C36", decayBlocks: 60 }, + { name: "Ink", chainId: 57073, reactor: "0x000000007A1C8e570011EeDF86A2A35593013cBA", decayBlocks: 30 }, ])("DutchV3 rollout: $name ($chainId)", ({ chainId, reactor, decayBlocks }) => { it("resolves the reactor without an explicit address", () => { const b = new V3DutchOrderBuilder(chainId); diff --git a/sdks/uniswapx-sdk/src/constants.test.ts b/sdks/uniswapx-sdk/src/constants.test.ts index 7cb73c6c8..f2a3419ac 100644 --- a/sdks/uniswapx-sdk/src/constants.test.ts +++ b/sdks/uniswapx-sdk/src/constants.test.ts @@ -11,14 +11,17 @@ const CANONICAL_PERMIT2 = "0x000000000022D473030F116dDEE9F6B43aC78BA3"; const CANONICAL_QUOTER = "0x00000000a3db63Df9078cBF3dF88B4CAdD5a7F58"; const ZERO = "0x0000000000000000000000000000000000000000"; -// DutchV3 rollout to Robinhood (4663) and Arc (5042). These guard against the -// two ways the mappings would otherwise silently misresolve: the quoter -// falling through to the legacy default (0x5453…) and the exclusive-filler -// validator falling through to 0x8A66… (a contract that doesn't exist on -// either chain). +// DutchV3 rollout to Robinhood (4663), Arc (5042), and Ink (57073). +// constructSameAddressMap only seeds the five NETWORKS_WITH_SAME_ADDRESS +// chains, so a chain with no explicit entry reads back `undefined` rather than +// a wrong-but-plausible default. These guard the two consequences: the quoter +// lookup makes UniswapXOrderQuoter's constructor throw MissingConfiguration, +// and the exclusive-filler lookup silently puts `undefined` into the +// ValidationInfo that encodeExclusiveFillerData returns. describe.each([ { name: "Robinhood", chainId: 4663, reactor: "0x000000007A1C8e570011EeDF86A2A35593013cBA" }, { name: "Arc", chainId: 5042, reactor: "0x0000000015134054eA82AE0bb9fda66b36402C36" }, + { name: "Ink", chainId: 57073, reactor: "0x000000007A1C8e570011EeDF86A2A35593013cBA" }, ])("DutchV3 rollout: $name ($chainId)", ({ chainId, reactor }) => { it("getReactor resolves the deployed Dutch_V3 reactor", () => { expect(getReactor(chainId, OrderType.Dutch_V3).toLowerCase()).toEqual(reactor.toLowerCase()); @@ -122,6 +125,9 @@ describe("REACTOR_ADDRESS_MAPPING", () => { "56": { "Dutch_V3": "0x00000000a55e50C71b70Db3C8B58749cd1E18eB2", }, + "57073": { + "Dutch_V3": "0x000000007A1C8e570011EeDF86A2A35593013cBA", + }, "7777777": { "Dutch_V3": "0x000000002C9A3812e15cf233190992E9a57EDB56", }, diff --git a/sdks/uniswapx-sdk/src/constants.ts b/sdks/uniswapx-sdk/src/constants.ts index 48bfb66cd..8bc10392c 100644 --- a/sdks/uniswapx-sdk/src/constants.ts +++ b/sdks/uniswapx-sdk/src/constants.ts @@ -45,6 +45,7 @@ export const PERMIT2_MAPPING: AddressMap = { 42161, // arbitrum 42220, // celo 43114, // avalanche + 57073, // ink 59144, // linea 81457, // blast 84532, // base sepolia @@ -82,6 +83,7 @@ export const UNISWAPX_ORDER_QUOTER_MAPPING: AddressMap = { 5042: "0x00000000a3db63Df9078cBF3dF88B4CAdD5a7F58", 42220: "0x00000000a3db63Df9078cBF3dF88B4CAdD5a7F58", 43114: "0x00000000a3db63Df9078cBF3dF88B4CAdD5a7F58", + 57073: "0x00000000a3db63Df9078cBF3dF88B4CAdD5a7F58", 81457: "0x00000000a3db63Df9078cBF3dF88B4CAdD5a7F58", 7777777: "0x00000000a3db63Df9078cBF3dF88B4CAdD5a7F58", }; @@ -118,6 +120,7 @@ export const EXCLUSIVE_FILLER_VALIDATION_MAPPING: AddressMap = { 5042: "0x0000000000000000000000000000000000000000", 42220: "0x0000000000000000000000000000000000000000", 43114: "0x0000000000000000000000000000000000000000", + 57073: "0x0000000000000000000000000000000000000000", 81457: "0x0000000000000000000000000000000000000000", 7777777: "0x0000000000000000000000000000000000000000", }; @@ -236,6 +239,9 @@ export const REACTOR_ADDRESS_MAPPING: ReactorMapping = { 43114: { [OrderType.Dutch_V3]: "0x00000000862cCF095823fc7576Fa6C7e6b7385ef", }, + 57073: { + [OrderType.Dutch_V3]: "0x000000007A1C8e570011EeDF86A2A35593013cBA", + }, 81457: { [OrderType.Dutch_V3]: "0x0000000086f50C5E1a2500602183D4390A7FFc98", },