@black-market/sdk 0.3.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +102 -129
  2. package/assets/splash.png +0 -0
  3. package/dist/addresses.d.ts +3 -1
  4. package/dist/addresses.d.ts.map +1 -1
  5. package/dist/addresses.js +23 -17
  6. package/dist/addresses.js.map +1 -1
  7. package/dist/client.js +2 -2
  8. package/dist/client.js.map +1 -1
  9. package/dist/launch-api.d.ts +2 -1
  10. package/dist/launch-api.d.ts.map +1 -1
  11. package/dist/launch-api.js +2 -1
  12. package/dist/launch-api.js.map +1 -1
  13. package/dist/launch.d.ts +1 -1
  14. package/dist/launch.d.ts.map +1 -1
  15. package/dist/launch.js +1 -1
  16. package/dist/launch.js.map +1 -1
  17. package/dist/lifecycle/abi.d.ts +1191 -248
  18. package/dist/lifecycle/abi.d.ts.map +1 -1
  19. package/dist/lifecycle/abi.js +119 -21
  20. package/dist/lifecycle/abi.js.map +1 -1
  21. package/dist/lifecycle/markets.d.ts +1 -1
  22. package/dist/lifecycle/markets.d.ts.map +1 -1
  23. package/dist/lifecycle/markets.js +10 -8
  24. package/dist/lifecycle/markets.js.map +1 -1
  25. package/dist/lifecycle/planner.d.ts.map +1 -1
  26. package/dist/lifecycle/planner.js +8 -5
  27. package/dist/lifecycle/planner.js.map +1 -1
  28. package/dist/lifecycle/progress.d.ts +8 -1
  29. package/dist/lifecycle/progress.d.ts.map +1 -1
  30. package/dist/lifecycle/progress.js +37 -29
  31. package/dist/lifecycle/progress.js.map +1 -1
  32. package/dist/lifecycle/schema.d.ts +3 -32
  33. package/dist/lifecycle/schema.d.ts.map +1 -1
  34. package/dist/lifecycle/schema.js +6 -9
  35. package/dist/lifecycle/schema.js.map +1 -1
  36. package/docs/launch-lifecycle.md +230 -21
  37. package/package.json +8 -3
  38. package/src/addresses.ts +25 -18
  39. package/src/client.ts +2 -2
  40. package/src/launch-api.ts +3 -2
  41. package/src/launch.ts +1 -1
  42. package/src/lifecycle/abi.ts +120 -21
  43. package/src/lifecycle/markets.ts +9 -8
  44. package/src/lifecycle/planner.ts +7 -4
  45. package/src/lifecycle/progress.ts +39 -28
  46. package/src/lifecycle/schema.ts +7 -11
@@ -85,6 +85,10 @@ export const lifecycleRegistryAbi = [
85
85
  { name: "envelope", type: "tuple", components: launchEnvelopeV2Components },
86
86
  { name: "nonce", type: "uint256" }, { name: "deadline", type: "uint256" }, { name: "authorization", type: "bytes" },
87
87
  ], outputs: [] },
88
+ { type: "function", name: "registerAbyssProfile", stateMutability: "nonpayable", inputs: [
89
+ { name: "variant", type: "uint8" },
90
+ { name: "registration", type: "tuple", components: profileRegistrationV1Components },
91
+ ], outputs: [] },
88
92
  { type: "function", name: "authorPayout", stateMutability: "view", inputs: [{ type: "address" }], outputs: [{ type: "address" }] },
89
93
  { type: "function", name: "setAuthorPayout", stateMutability: "nonpayable", inputs: [{ name: "authorId", type: "address" }, { name: "payout", type: "address" }], outputs: [] },
90
94
  { type: "function", name: "authorHubCount", stateMutability: "view", inputs: [{ type: "address" }], outputs: [{ type: "uint256" }] },
@@ -108,21 +112,21 @@ export const lifecycleAdapterAbi = [
108
112
  { type: "function", name: "readPosition", stateMutability: "view", inputs: [{ type: "tuple", components: positionIdentityV1Components }], outputs: [{ type: "uint128" }, { type: "address" }] },
109
113
  ] as const;
110
114
 
111
- const reviewedV4AdapterMetadataAbi = [
115
+ const v4AdapterMetadataAbi = [
112
116
  ...lifecycleAdapterAbi,
113
117
  { type: "function", name: "PROFILE_ID", stateMutability: "view", inputs: [], outputs: [{ type: "bytes32" }] },
114
118
  { type: "function", name: "CONFIG_SCHEMA", stateMutability: "view", inputs: [], outputs: [{ type: "bytes32" }] },
115
119
  { type: "function", name: "CONFIG_VERSION", stateMutability: "view", inputs: [], outputs: [{ type: "uint32" }] },
116
120
  { type: "function", name: "implementationRegistry", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
117
121
  { type: "function", name: "poolManager", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
118
- { type: "function", name: "hookRoot", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
119
122
  { type: "function", name: "oracleFactory", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
120
123
  { type: "function", name: "locker", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
121
124
  { type: "function", name: "collectorFactory", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
122
125
  { type: "function", name: "hookDeployer", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
123
126
  ] as const;
124
- export const reviewedSharedV4MarketAdapterV1Abi = [
125
- ...reviewedV4AdapterMetadataAbi,
127
+ export const sharedMarketAdapterV1Abi = [
128
+ ...v4AdapterMetadataAbi,
129
+ { type: "function", name: "hookRoot", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
126
130
  { type: "constructor", stateMutability: "nonpayable", inputs: [
127
131
  { name: "core_", type: "address" }, { name: "manager_", type: "address" }, { name: "root_", type: "address" },
128
132
  { name: "locker_", type: "address" }, { name: "helper_", type: "address" }, { name: "registry_", type: "address" },
@@ -136,8 +140,9 @@ export const abyssLifecycleAdapterAbi = [
136
140
  { type: "function", name: "profileId", stateMutability: "view", inputs: [{ type: "uint8" }], outputs: [{ type: "bytes32" }] },
137
141
  { type: "function", name: "factory", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
138
142
  ] as const;
139
- export const reviewedPoolBoundV4MarketAdapterV1Abi = [
140
- ...reviewedV4AdapterMetadataAbi,
143
+ export const poolMarketAdapterV1Abi = [
144
+ ...v4AdapterMetadataAbi,
145
+ { type: "function", name: "hookRoot", stateMutability: "pure", inputs: [], outputs: [{ type: "address" }] },
141
146
  { type: "constructor", stateMutability: "nonpayable", inputs: [
142
147
  { name: "core_", type: "address" }, { name: "manager_", type: "address" }, { name: "oracleFactory_", type: "address" },
143
148
  { name: "locker_", type: "address" }, { name: "deployer_", type: "address" }, { name: "helper_", type: "address" },
@@ -151,7 +156,7 @@ export const reviewedPoolBoundV4MarketAdapterV1Abi = [
151
156
  ] },
152
157
  ] as const;
153
158
  const boundParametersInput = { name: "parameters", type: "tuple", components: poolBoundHookParametersV1Components } as const;
154
- export const reviewedPoolBoundHookDeployerV1Abi = [
159
+ export const poolHookDeployerV1Abi = [
155
160
  { type: "constructor", stateMutability: "nonpayable", inputs: [{ name: "creationCode", type: "bytes" }] },
156
161
  { type: "function", name: "creationCodeHash", stateMutability: "view", inputs: [], outputs: [{ type: "bytes32" }] },
157
162
  { type: "function", name: "codeChunk0", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
@@ -162,7 +167,7 @@ export const reviewedPoolBoundHookDeployerV1Abi = [
162
167
  { type: "function", name: "validHookAddress", stateMutability: "pure", inputs: [{ type: "address" }], outputs: [{ type: "bool" }] },
163
168
  { type: "function", name: "deploy", stateMutability: "nonpayable", inputs: [boundParametersInput, { name: "salt", type: "bytes32" }], outputs: [{ name: "hook", type: "address" }] },
164
169
  ] as const;
165
- export const reviewedSharedHookDeployerV1Abi = [
170
+ export const sharedHookDeployerV1Abi = [
166
171
  { type: "constructor", stateMutability: "nonpayable", inputs: [{ name: "creationCode", type: "bytes" }] },
167
172
  { type: "function", name: "creationCodeHash", stateMutability: "view", inputs: [], outputs: [{ type: "bytes32" }] },
168
173
  { type: "function", name: "codeChunk0", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
@@ -201,17 +206,78 @@ export const lifecycleV4HookAbi = [
201
206
  { type: "function", name: "pendingFees", stateMutability: "view", inputs: [{ type: "bytes32" }, { type: "address" }], outputs: [{ type: "uint256" }] },
202
207
  { type: "function", name: "settledFees", stateMutability: "view", inputs: [{ type: "bytes32" }, { type: "address" }], outputs: [{ type: "uint256" }] },
203
208
  ] as const;
204
- export const poolBoundLaunchFeeHookV1Abi = [
205
- ...lifecycleV4HookAbi,
206
- { type: "constructor", stateMutability: "nonpayable", inputs: [boundParametersInput] },
207
- { type: "function", name: "boundPoolId", stateMutability: "view", inputs: [], outputs: [{ type: "bytes32" }] },
208
- { type: "function", name: "deploymentConfigHash", stateMutability: "view", inputs: [], outputs: [{ type: "bytes32" }] },
209
- { type: "function", name: "marketCommitment", stateMutability: "view", inputs: [], outputs: [{ type: "bytes32" }] },
210
- { type: "function", name: "core", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
211
- { type: "function", name: "liquidityLocker", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
212
- { type: "function", name: "token", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
213
- { type: "function", name: "openingSqrtPriceX96", stateMutability: "view", inputs: [], outputs: [{ type: "uint160" }] },
214
- { type: "function", name: "expectedPositionCount", stateMutability: "view", inputs: [], outputs: [{ type: "uint32" }] },
209
+ /** Complete mined FixedFeePoolHookV1 ABI (pool-launch-v1, 20261005T053747Z-b5a7b88).
210
+ * Compiler-only internalType annotations are omitted; the constructor is one 18-field tuple. */
211
+ export const fixedFeePoolHookV1Abi = [
212
+ { type: "constructor", inputs: [boundParametersInput], stateMutability: "nonpayable" },
213
+ { type: "function", name: "ALL_HOOK_MASK", inputs: [], outputs: [{ name: "", type: "uint160" }], stateMutability: "view" },
214
+ { type: "function", name: "MAX_ORACLE_CARDINALITY", inputs: [], outputs: [{ name: "", type: "uint16" }], stateMutability: "view" },
215
+ { type: "function", name: "PIPS_DENOMINATOR", inputs: [], outputs: [{ name: "", type: "uint24" }], stateMutability: "view" },
216
+ { type: "function", name: "REQUIRED_HOOK_FLAGS", inputs: [], outputs: [{ name: "", type: "uint160" }], stateMutability: "view" },
217
+ { type: "function", name: "afterDonate", inputs: [{ name: "", type: "address" }, { name: "key", type: "tuple", components: lifecycleV4PoolKeyComponents }, { name: "", type: "uint256" }, { name: "", type: "uint256" }, { name: "", type: "bytes" }], outputs: [{ name: "", type: "bytes4" }], stateMutability: "nonpayable" },
218
+ { type: "function", name: "afterInitialize", inputs: [{ name: "sender", type: "address" }, { name: "key", type: "tuple", components: lifecycleV4PoolKeyComponents }, { name: "sqrtPriceX96", type: "uint160" }, { name: "tick", type: "int24" }], outputs: [{ name: "", type: "bytes4" }], stateMutability: "nonpayable" },
219
+ { type: "function", name: "afterSwap", inputs: [{ name: "", type: "address" }, { name: "key", type: "tuple", components: lifecycleV4PoolKeyComponents }, { name: "params", type: "tuple", components: [{ name: "zeroForOne", type: "bool" }, { name: "amountSpecified", type: "int256" }, { name: "sqrtPriceLimitX96", type: "uint160" }] }, { name: "delta", type: "int256" }, { name: "", type: "bytes" }], outputs: [{ name: "", type: "bytes4" }, { name: "", type: "int128" }], stateMutability: "nonpayable" },
220
+ { type: "function", name: "aggregateLiabilities", inputs: [{ name: "asset", type: "address" }], outputs: [{ name: "", type: "uint256" }], stateMutability: "view" },
221
+ { type: "function", name: "aggregateManagerClaims", inputs: [{ name: "asset", type: "address" }], outputs: [{ name: "", type: "uint256" }], stateMutability: "view" },
222
+ { type: "function", name: "beforeAddLiquidity", inputs: [{ name: "sender", type: "address" }, { name: "key", type: "tuple", components: lifecycleV4PoolKeyComponents }, { name: "params", type: "tuple", components: [{ name: "tickLower", type: "int24" }, { name: "tickUpper", type: "int24" }, { name: "liquidityDelta", type: "int256" }, { name: "salt", type: "bytes32" }] }, { name: "", type: "bytes" }], outputs: [{ name: "", type: "bytes4" }], stateMutability: "nonpayable" },
223
+ { type: "function", name: "beforeDonate", inputs: [{ name: "", type: "address" }, { name: "key", type: "tuple", components: lifecycleV4PoolKeyComponents }, { name: "amount0", type: "uint256" }, { name: "amount1", type: "uint256" }, { name: "", type: "bytes" }], outputs: [{ name: "", type: "bytes4" }], stateMutability: "nonpayable" },
224
+ { type: "function", name: "beforeRemoveLiquidity", inputs: [{ name: "sender", type: "address" }, { name: "key", type: "tuple", components: lifecycleV4PoolKeyComponents }, { name: "params", type: "tuple", components: [{ name: "tickLower", type: "int24" }, { name: "tickUpper", type: "int24" }, { name: "liquidityDelta", type: "int256" }, { name: "salt", type: "bytes32" }] }, { name: "", type: "bytes" }], outputs: [{ name: "", type: "bytes4" }], stateMutability: "nonpayable" },
225
+ { type: "function", name: "beforeSwap", inputs: [{ name: "", type: "address" }, { name: "key", type: "tuple", components: lifecycleV4PoolKeyComponents }, { name: "params", type: "tuple", components: [{ name: "zeroForOne", type: "bool" }, { name: "amountSpecified", type: "int256" }, { name: "sqrtPriceLimitX96", type: "uint160" }] }, { name: "", type: "bytes" }], outputs: [{ name: "", type: "bytes4" }, { name: "", type: "int256" }, { name: "", type: "uint24" }], stateMutability: "nonpayable" },
226
+ { type: "function", name: "boundPoolId", inputs: [], outputs: [{ name: "", type: "bytes32" }], stateMutability: "view" },
227
+ { type: "function", name: "collectFees", inputs: [{ name: "key", type: "tuple", components: lifecycleV4PoolKeyComponents }], outputs: [{ name: "amount0", type: "uint256" }, { name: "amount1", type: "uint256" }], stateMutability: "nonpayable" },
228
+ { type: "function", name: "completePoolOpening", inputs: [{ name: "key", type: "tuple", components: lifecycleV4PoolKeyComponents }], outputs: [], stateMutability: "nonpayable" },
229
+ { type: "function", name: "core", inputs: [], outputs: [{ name: "", type: "address" }], stateMutability: "view" },
230
+ { type: "function", name: "deploymentConfigHash", inputs: [], outputs: [{ name: "", type: "bytes32" }], stateMutability: "view" },
231
+ { type: "function", name: "expectedPositionCount", inputs: [], outputs: [{ name: "", type: "uint32" }], stateMutability: "view" },
232
+ { type: "function", name: "increaseObservationCardinalityNext", inputs: [{ name: "id", type: "bytes32" }, { name: "requested", type: "uint16" }], outputs: [], stateMutability: "nonpayable" },
233
+ { type: "function", name: "initialized", inputs: [{ name: "id", type: "bytes32" }], outputs: [{ name: "", type: "bool" }], stateMutability: "view" },
234
+ { type: "function", name: "liquidityLocker", inputs: [], outputs: [{ name: "", type: "address" }], stateMutability: "view" },
235
+ { type: "function", name: "marketCommitment", inputs: [], outputs: [{ name: "", type: "bytes32" }], stateMutability: "view" },
236
+ { type: "function", name: "observations", inputs: [{ name: "id", type: "bytes32" }, { name: "index", type: "uint256" }], outputs: [{ name: "blockTimestamp", type: "uint32" }, { name: "tickCumulative", type: "int56" }, { name: "secondsPerLiquidityCumulativeX128", type: "uint160" }, { name: "observationInitialized", type: "bool" }], stateMutability: "view" },
237
+ { type: "function", name: "observeTruncated", inputs: [{ name: "id", type: "bytes32" }, { name: "secondsAgos", type: "uint32[]" }], outputs: [{ name: "tickCumulatives", type: "int56[]" }, { name: "secondsPerLiquidityCumulativeX128s", type: "uint160[]" }], stateMutability: "view" },
238
+ { type: "function", name: "openingCompletedAt", inputs: [{ name: "id", type: "bytes32" }], outputs: [{ name: "", type: "uint256" }], stateMutability: "view" },
239
+ { type: "function", name: "openingSqrtPriceX96", inputs: [], outputs: [{ name: "", type: "uint160" }], stateMutability: "view" },
240
+ { type: "function", name: "oracleFactory", inputs: [], outputs: [{ name: "", type: "address" }], stateMutability: "view" },
241
+ { type: "function", name: "oracleInitializedAt", inputs: [{ name: "id", type: "bytes32" }], outputs: [{ name: "", type: "uint256" }], stateMutability: "view" },
242
+ { type: "function", name: "oracleState", inputs: [{ name: "id", type: "bytes32" }], outputs: [{ name: "index", type: "uint16" }, { name: "cardinality", type: "uint16" }, { name: "cardinalityNext", type: "uint16" }, { name: "tick", type: "int24" }, { name: "lastBlock", type: "uint64" }, { name: "initializedAt", type: "uint64" }, { name: "maxAbsTickMove", type: "int24" }, { name: "cardinalityCap", type: "uint16" }], stateMutability: "view" },
243
+ { type: "function", name: "pendingFees", inputs: [{ name: "id", type: "bytes32" }, { name: "asset", type: "address" }], outputs: [{ name: "", type: "uint256" }], stateMutability: "view" },
244
+ { type: "function", name: "pendingTreasurySweeps", inputs: [{ name: "id", type: "bytes32" }, { name: "asset", type: "address" }], outputs: [{ name: "", type: "uint256" }], stateMutability: "view" },
245
+ { type: "function", name: "poolConfig", inputs: [{ name: "id", type: "bytes32" }], outputs: [{ name: "", type: "tuple", components: lifecycleV4HookPoolConfigComponents }], stateMutability: "view" },
246
+ { type: "function", name: "poolKey", inputs: [{ name: "id", type: "bytes32" }], outputs: [{ name: "", type: "tuple", components: lifecycleV4PoolKeyComponents }], stateMutability: "view" },
247
+ { type: "function", name: "poolManager", inputs: [], outputs: [{ name: "", type: "address" }], stateMutability: "view" },
248
+ { type: "function", name: "pools", inputs: [], outputs: [{ name: "ids", type: "bytes32[]" }], stateMutability: "view" },
249
+ { type: "function", name: "registerPool", inputs: [{ name: "key", type: "tuple", components: lifecycleV4PoolKeyComponents }, { name: "config", type: "tuple", components: lifecycleV4HookPoolConfigComponents }], outputs: [], stateMutability: "nonpayable" },
250
+ { type: "function", name: "registered", inputs: [{ name: "id", type: "bytes32" }], outputs: [{ name: "", type: "bool" }], stateMutability: "view" },
251
+ { type: "function", name: "registrar", inputs: [], outputs: [{ name: "", type: "address" }], stateMutability: "view" },
252
+ { type: "function", name: "settledFees", inputs: [{ name: "id", type: "bytes32" }, { name: "asset", type: "address" }], outputs: [{ name: "", type: "uint256" }], stateMutability: "view" },
253
+ { type: "function", name: "token", inputs: [], outputs: [{ name: "", type: "address" }], stateMutability: "view" },
254
+ { type: "function", name: "unlockCallback", inputs: [{ name: "data", type: "bytes" }], outputs: [{ name: "", type: "bytes" }], stateMutability: "nonpayable" },
255
+ { type: "function", name: "validateCollector", inputs: [{ name: "key", type: "tuple", components: lifecycleV4PoolKeyComponents }, { name: "collector", type: "address" }, { name: "locker", type: "address" }], outputs: [], stateMutability: "view" },
256
+ { type: "function", name: "validateOracleConfig", inputs: [{ name: "oracleConfigId", type: "bytes32" }], outputs: [{ name: "maxAbsTickMove", type: "uint24" }, { name: "cardinality", type: "uint16" }], stateMutability: "view" },
257
+ { type: "event", name: "FeeAccrued", inputs: [{ name: "poolId", type: "bytes32", indexed: true }, { name: "asset", type: "address", indexed: true }, { name: "gross", type: "uint256", indexed: false }, { name: "treasury", type: "uint256", indexed: false }], anonymous: false },
258
+ { type: "event", name: "FeesCollected", inputs: [{ name: "poolId", type: "bytes32", indexed: true }, { name: "collector", type: "address", indexed: true }, { name: "amount0", type: "uint256", indexed: false }, { name: "amount1", type: "uint256", indexed: false }], anonymous: false },
259
+ { type: "event", name: "IncreaseObservationCardinalityNext", inputs: [{ name: "poolId", type: "bytes32", indexed: true }, { name: "cardinalityNextOld", type: "uint16", indexed: false }, { name: "cardinalityNextNew", type: "uint16", indexed: false }], anonymous: false },
260
+ { type: "event", name: "LpFeesCheckpointed", inputs: [{ name: "poolId", type: "bytes32", indexed: true }, { name: "locker", type: "address", indexed: true }, { name: "amount0", type: "uint256", indexed: false }, { name: "amount1", type: "uint256", indexed: false }], anonymous: false },
261
+ { type: "event", name: "OpeningCompleted", inputs: [{ name: "poolId", type: "bytes32", indexed: true }, { name: "completedAt", type: "uint256", indexed: true }], anonymous: false },
262
+ { type: "event", name: "PoolInitialized", inputs: [{ name: "poolId", type: "bytes32", indexed: true }], anonymous: false },
263
+ { type: "event", name: "PoolRegistered", inputs: [{ name: "poolId", type: "bytes32", indexed: true }, { name: "collector", type: "address", indexed: true }, { name: "locker", type: "address", indexed: true }], anonymous: false },
264
+ { type: "error", name: "AlreadyRegistered", inputs: [] },
265
+ { type: "error", name: "ClaimMismatch", inputs: [] },
266
+ { type: "error", name: "ExternalLiquidityDisabled", inputs: [] },
267
+ { type: "error", name: "FeeSettlementRequired", inputs: [] },
268
+ { type: "error", name: "FeeTooLarge", inputs: [] },
269
+ { type: "error", name: "IncompleteFill", inputs: [] },
270
+ { type: "error", name: "InexactTransfer", inputs: [] },
271
+ { type: "error", name: "InvalidCallback", inputs: [] },
272
+ { type: "error", name: "InvalidConfiguration", inputs: [] },
273
+ { type: "error", name: "InvalidHookAddress", inputs: [] },
274
+ { type: "error", name: "InvalidObservationState", inputs: [] },
275
+ { type: "error", name: "InvalidPool", inputs: [] },
276
+ { type: "error", name: "ObservationTooOld", inputs: [] },
277
+ { type: "error", name: "OpeningAlreadyComplete", inputs: [] },
278
+ { type: "error", name: "OpeningNotComplete", inputs: [] },
279
+ { type: "error", name: "Reentrancy", inputs: [] },
280
+ { type: "error", name: "Unauthorized", inputs: [] },
215
281
  ] as const;
216
282
  export const lifecycleV4LockerAbi = [
217
283
  { type: "function", name: "poolManager", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
@@ -219,14 +285,14 @@ export const lifecycleV4LockerAbi = [
219
285
  { type: "function", name: "positionCount", stateMutability: "view", inputs: [{ type: "bytes32" }], outputs: [{ type: "uint256" }] },
220
286
  { type: "function", name: "isSealed", stateMutability: "view", inputs: [{ type: "bytes32" }], outputs: [{ type: "bool" }] },
221
287
  ] as const;
222
- export const reviewedV4FeeCollectorFactoryV1Abi = [
288
+ export const poolFeeCollectorFactoryV1Abi = [
223
289
  { type: "function", name: "collectorDeployer", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
224
290
  { type: "function", name: "poolBoundHookParameters", stateMutability: "view", inputs: [
225
291
  { name: "registrar", type: "address" }, { name: "token", type: "address" }, { name: "market", type: "tuple", components: lifecycleMarketComponents },
226
292
  ], outputs: [boundParametersInput, { name: "salt", type: "bytes32" }] },
227
293
  { type: "function", name: "decodeAndValidate", stateMutability: "view", inputs: [{ type: "address" }, { type: "address" }, { type: "tuple", components: lifecycleMarketComponents }], outputs: [{ type: "tuple", components: v4LifecycleMarketComponents }] },
228
294
  { type: "function", name: "poolBoundDeploymentMetadata", stateMutability: "view", inputs: [{ type: "address" }, { type: "address" }, { type: "tuple", components: lifecycleMarketComponents }], outputs: [{ type: "address" }, { type: "bytes32" }, { type: "bytes32" }, { type: "address" }] },
229
- { type: "function", name: "reviewedDependencyDigest", stateMutability: "view", inputs: [{ type: "address" }], outputs: [{ type: "bytes32" }] },
295
+ { type: "function", name: "dependencyDigest", stateMutability: "view", inputs: [{ type: "address" }], outputs: [{ type: "bytes32" }] },
230
296
  { type: "function", name: "create", stateMutability: "nonpayable", inputs: [{ type: "address" }, { type: "address" }, { type: "tuple", components: lifecycleV4PoolKeyComponents }, { type: "uint256" }], outputs: [{ type: "address" }] },
231
297
  ] as const;
232
298
  export const lifecycleDirectoryAbi = [
@@ -245,6 +311,39 @@ export const lifecycleErc20Abi = [
245
311
  { type: "function", name: "allowance", stateMutability: "view", inputs: [{ type: "address" }, { type: "address" }], outputs: [{ type: "uint256" }] },
246
312
  { type: "function", name: "approve", stateMutability: "nonpayable", inputs: [{ type: "address" }, { type: "uint256" }], outputs: [{ type: "bool" }] },
247
313
  ] as const;
314
+ /** Shared immutable bindings and terminal state of LaunchERC20V1 / LaunchERC404V1. */
315
+ export const lifecycleTokenContextAbi = [
316
+ { type: "function", name: "authority", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
317
+ { type: "function", name: "tokenFactory", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
318
+ { type: "function", name: "launchId", stateMutability: "view", inputs: [], outputs: [{ type: "bytes32" }] },
319
+ { type: "function", name: "rewardMode", stateMutability: "view", inputs: [], outputs: [{ type: "uint8" }] },
320
+ { type: "function", name: "initialSupply", stateMutability: "view", inputs: [], outputs: [{ type: "uint256" }] },
321
+ { type: "function", name: "burnOnCancel", stateMutability: "view", inputs: [], outputs: [{ type: "bool" }] },
322
+ { type: "function", name: "active", stateMutability: "view", inputs: [], outputs: [{ type: "bool" }] },
323
+ { type: "function", name: "cancelled", stateMutability: "view", inputs: [], outputs: [{ type: "bool" }] },
324
+ { type: "function", name: "exclusionsFinalized", stateMutability: "view", inputs: [], outputs: [{ type: "bool" }] },
325
+ { type: "function", name: "feeHub", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
326
+ { type: "function", name: "rewardModule", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
327
+ ] as const;
328
+ export const lifecycleErc404Abi = [
329
+ ...lifecycleTokenContextAbi,
330
+ { type: "function", name: "unit", stateMutability: "view", inputs: [], outputs: [{ type: "uint256" }] },
331
+ { type: "function", name: "baseURI", stateMutability: "view", inputs: [], outputs: [{ type: "string" }] },
332
+ { type: "function", name: "mirrorERC721", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
333
+ ] as const;
334
+ export const lifecycleErc404MirrorAbi = [
335
+ { type: "function", name: "baseERC20", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
336
+ ] as const;
337
+ export const lifecycleTokenFactoryAbi = [
338
+ { type: "function", name: "core", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
339
+ { type: "function", name: "tokenOfLaunch", stateMutability: "view", inputs: [{ type: "bytes32" }], outputs: [{ type: "address" }] },
340
+ { type: "function", name: "launchOfToken", stateMutability: "view", inputs: [{ type: "address" }], outputs: [{ type: "bytes32" }] },
341
+ { type: "event", name: "TokenDeployed", anonymous: false, inputs: [
342
+ { name: "launchId", type: "bytes32", indexed: true }, { name: "token", type: "address", indexed: true },
343
+ { name: "kind", type: "uint8", indexed: false },
344
+ ] },
345
+ ] as const;
346
+
248
347
  export const lifecycleOracleFactoryAbi = [
249
348
  { type: "function", name: "oracleConfigs", stateMutability: "view", inputs: [{ type: "bytes32" }], outputs: [{ type: "uint24" }, { type: "uint16" }] },
250
349
  ] as const;
@@ -39,7 +39,7 @@ export function decodeV4LifecycleMarketConfig(encoded: Hex): V4LifecycleMarketCo
39
39
  export type V4PoolBoundLifecycleMarketConfig = Omit<V4LifecycleMarketConfig, "version"> & { version: 5; hookSalt: Hex };
40
40
  export const V4_LIFECYCLE_CONFIG_SCHEMA = keccak256(stringToHex("(uint16,uint24,int24,uint160,uint24,uint8,uint8,address,bool,bytes32,bytes32,bytes32,address,uint16,(int24,int24,uint128,bytes32,uint256)[])"));
41
41
  export const V4_POOL_BOUND_LIFECYCLE_CONFIG_SCHEMA = keccak256(stringToHex("(uint16,uint24,int24,uint160,uint24,uint8,uint8,address,bool,bytes32,bytes32,bytes32,bytes32,address,uint16,(int24,int24,uint128,bytes32,uint256)[])"));
42
- export const V4_POOL_BOUND_MARKET_ECONOMICS_DOMAIN = keccak256(stringToHex("black-market.reviewed-pool-bound-market-economics.v1"));
42
+ export const V4_POOL_BOUND_MARKET_ECONOMICS_DOMAIN = keccak256(stringToHex("black-market.pool-bound-market-economics.v1"));
43
43
  export const V4_LIFECYCLE_HOOK_PERMISSION_MASK = 0x3fffn;
44
44
  export const V4_LIFECYCLE_HOOK_PERMISSIONS = 0x1afcn;
45
45
  export const poolBoundV4LifecycleMarketComponents = [
@@ -65,7 +65,7 @@ export function decodePoolBoundV4LifecycleMarketConfig(encoded: Hex): V4PoolBoun
65
65
  }
66
66
 
67
67
  /** Exact pending-source admission terms; author identity is never the live payout address. */
68
- export function validateReviewedV4LifecycleMarket(options: {
68
+ export function validateV4LifecycleMarket(options: {
69
69
  market: MarketConfigV1; config: V4LifecycleMarketConfig | V4PoolBoundLifecycleMarketConfig; profile: LifecycleProfile; token: Address;
70
70
  }): void {
71
71
  const { market, config, profile, token } = options;
@@ -83,19 +83,20 @@ export function validateReviewedV4LifecycleMarket(options: {
83
83
  config.developerBeneficiary.toLowerCase() !== terms.beneficiary.toLowerCase() ||
84
84
  BigInt(config.developerBeneficiary) === 0n || config.developerBeneficiary.toLowerCase() === token.toLowerCase() ||
85
85
  config.developerBeneficiary.toLowerCase() === market.quoteAsset.toLowerCase()) {
86
- throw new LifecyclePlanningError("REVIEWED_TERMS_MISMATCH", "Market must explicitly bind the admitted profile, frozen terms and stable author identity");
86
+ throw new LifecyclePlanningError("PROFILE_TERMS_MISMATCH", "Market must explicitly bind the admitted profile, frozen terms and stable author identity");
87
87
  }
88
88
  if (!Number.isInteger(config.developerFeeBps) || config.developerFeeBps < 0 ||
89
89
  config.developerFeeBps > envelope.maximumDeveloperFeeBps || config.developerFeeBps > terms.maximumDeveloperFeeBps ||
90
90
  config.developerFeeBps > protocolCeiling) throw new LifecyclePlanningError("DEVELOPER_FEE_CEILING", "Explicit developer fee exceeds the reviewed or protocol ceiling");
91
91
  const b = envelope.bounds;
92
+ if (config.oracleConfigId.toLowerCase() === zeroHash) throw new LifecyclePlanningError("INVALID_ORACLE_CONFIG", "Market oracle configuration must be nonzero");
92
93
  if (config.treasury.toLowerCase() !== envelope.protocolTreasury.toLowerCase() ||
93
- config.protocolFeeDenominator !== envelope.protocolFeeDenominator || config.hookFeePips > b.maximumHookFeePips ||
94
- config.lpFeePips > b.maximumLpFeePips || !Number.isInteger(config.feeMode) || config.feeMode < 0 || config.feeMode > 1 || (b.feeModeFlags & (1 << config.feeMode)) === 0 ||
94
+ config.protocolFeeDenominator !== envelope.protocolFeeDenominator || !Number.isInteger(config.hookFeePips) || config.hookFeePips < 0 || config.hookFeePips >= 1000000 ||
95
+ !Number.isInteger(config.lpFeePips) || config.lpFeePips < 0 || config.lpFeePips >= 1000000 ||
96
+ !Number.isInteger(config.feeMode) || config.feeMode < 0 || config.feeMode > 1 || (b.feeModeFlags & (1 << config.feeMode)) === 0 ||
95
97
  config.tickSpacing < b.minimumTickSpacing || config.tickSpacing > b.maximumTickSpacing ||
96
- config.positions.length === 0 || config.positions.length > b.maximumPositions || config.externalLiquidityDisabled !== b.externalLiquidityDisabled ||
97
- config.oracleConfigId.toLowerCase() !== b.oracleConfigId.toLowerCase()) {
98
- throw new LifecyclePlanningError("REVIEWED_BOUNDS_MISMATCH", "Market economics exceed or differ from the exact admitted envelope bounds");
98
+ config.positions.length === 0 || config.positions.length > b.maximumPositions) {
99
+ throw new LifecyclePlanningError("PROFILE_BOUNDS_MISMATCH", "Market economics exceed or differ from the exact admitted envelope bounds");
99
100
  }
100
101
  }
101
102
 
@@ -1,8 +1,8 @@
1
1
  import { encodeAbiParameters, encodeFunctionData, keccak256, toHex, zeroAddress, type Address, type Hex } from "viem";
2
2
  import { launchLifecycleAbi, lifecycleAdapterAbi, lifecycleErc20Abi, lifecycleFundingEscrowAbi, lifecycleRegistryAbi } from "./abi.js";
3
3
  import { hashLaunchIdentity, hashLaunchPlan, LifecycleFundingKind, LifecycleMode, LifecyclePhase, LifecycleRewardMode, LifecycleTokenKind, LifecycleVenue, LIFECYCLE_ERC404_CAPABILITY, LIFECYCLE_MAX_REWARD_ERC20_SUPPLY, LIFECYCLE_MAX_ERC404_SUPPLY, LIFECYCLE_MULTI_POSITION_CAPABILITY, LIFECYCLE_REQUIRED_CAPABILITIES, marketIdentityV1Components, parseLaunchPlan, serializeLaunchPlan, type LaunchPlanV1, type MarketIdentityV1 } from "./schema.js";
4
- import { ABYSS_LIFECYCLE_CONFIG_SCHEMA, readLaunchProgress, readLifecycleProfiles, readPoolBoundHookDeployment, validateLifecycleMarketIdentity } from "./progress.js";
5
- import { decodeAbyssLifecycleMarketConfig, decodePoolBoundV4LifecycleMarketConfig, decodeV4LifecycleMarketConfig, encodePoolBoundV4LifecycleMarketConfig, hasLifecycleV4HookPermissions, minePoolBoundHookSalt, predictPoolBoundHookAddress, validateReviewedV4LifecycleMarket, V4_LIFECYCLE_CONFIG_SCHEMA, V4_POOL_BOUND_LIFECYCLE_CONFIG_SCHEMA, type V4LifecycleMarketConfig, type V4PoolBoundLifecycleMarketConfig } from "./markets.js";
4
+ import { ABYSS_LIFECYCLE_CONFIG_SCHEMA, readLaunchProgress, readLifecycleProfiles, readPoolBoundHookDeployment, validateLifecycleMarketIdentity, validateV4LifecycleOracle } from "./progress.js";
5
+ import { decodeAbyssLifecycleMarketConfig, decodePoolBoundV4LifecycleMarketConfig, decodeV4LifecycleMarketConfig, encodePoolBoundV4LifecycleMarketConfig, hasLifecycleV4HookPermissions, minePoolBoundHookSalt, predictPoolBoundHookAddress, validateV4LifecycleMarket, V4_LIFECYCLE_CONFIG_SCHEMA, V4_POOL_BOUND_LIFECYCLE_CONFIG_SCHEMA, type V4LifecycleMarketConfig, type V4PoolBoundLifecycleMarketConfig } from "./markets.js";
6
6
  import { assertLifecycleBlock, lifecycleRpc, readLifecycleBlock, readLifecycleContract, resolveLifecycleLimits, rpcHex, rpcQuantity } from "./rpc.js";
7
7
  import { simulateLaunchTransactions } from "./simulation.js";
8
8
  import { LifecyclePlanningError, type BuildNextTransactionOptions, type CanonicalLaunchProgress, type LifecycleBlock, type LifecycleFundingPrerequisite, type LifecyclePoolBoundHookDeployment, type LifecycleProfile, type LifecycleRpcClient, type LifecycleSimulation, type LifecycleTransaction, type PlannedLaunch, type PlanLaunchOptions, type PoolBoundLifecyclePreparationProgress, type SimulateLaunchPlanOptions } from "./types.js";
@@ -40,7 +40,7 @@ function validatePlanShape(plan: LaunchPlanV1): void {
40
40
  if (market.configVersion === 4) config = decodeV4LifecycleMarketConfig(market.config);
41
41
  else if (market.configVersion === 5) config = decodePoolBoundV4LifecycleMarketConfig(market.config);
42
42
  if (config !== undefined) {
43
- if (config.profileId.toLowerCase() !== market.profileId.toLowerCase()) throw new LifecyclePlanningError("REVIEWED_TERMS_MISMATCH", "Inner config profile differs from the committed market profile");
43
+ if (config.profileId.toLowerCase() !== market.profileId.toLowerCase()) throw new LifecyclePlanningError("PROFILE_TERMS_MISMATCH", "Inner config profile differs from the committed market profile");
44
44
  const quote = market.quoteAsset.toLowerCase();
45
45
  if (v4Quotes.has(quote)) throw new LifecyclePlanningError("DUPLICATE_V4_QUOTE", "Only one V4 market per quote asset is allowed across shared and pool-bound offerings; put multiple positions in that market");
46
46
  v4Quotes.add(quote);
@@ -137,7 +137,10 @@ async function validatePendingInputs(client: LifecycleRpcClient, planned: Planne
137
137
  const schema = profile.registration.configSchema.toLowerCase();
138
138
  const config = schema === V4_LIFECYCLE_CONFIG_SCHEMA.toLowerCase() ? decodeV4LifecycleMarketConfig(market.config) : schema === V4_POOL_BOUND_LIFECYCLE_CONFIG_SCHEMA.toLowerCase() ? decodePoolBoundV4LifecycleMarketConfig(market.config) : schema === ABYSS_LIFECYCLE_CONFIG_SCHEMA.toLowerCase() ? decodeAbyssLifecycleMarketConfig(market.config) : undefined;
139
139
  if (config === undefined) throw new LifecyclePlanningError("UNSUPPORTED_SCHEMA", `Unsupported lifecycle config schema ${profile.registration.configSchema}`);
140
- if ("developerFeeBps" in config) validateReviewedV4LifecycleMarket({ market, config, profile, token: planned.predictedToken });
140
+ if ("developerFeeBps" in config) {
141
+ validateV4LifecycleMarket({ market, config, profile, token: planned.predictedToken });
142
+ if (config.version === 4) await validateV4LifecycleOracle({ client, envelope: profile.envelope!, oracleConfigId: config.oracleConfigId, block });
143
+ }
141
144
  if (config.positions.length === 0 || config.positions.length > 32 || positionCount + config.positions.length > 32) throw new LifecyclePlanningError("INVALID_POSITION_COUNT", "A launch commits at most 32 positive positions across every market/venue");
142
145
  positionCount += config.positions.length;
143
146
  const rewards = progress.canonical.rewards === zeroAddress && plan.token.rewardMode === LifecycleRewardMode.Dividends ? planned.predictedToken : progress.canonical.rewards;
@@ -1,6 +1,6 @@
1
1
  import { concatHex, decodeFunctionData, encodeAbiParameters, encodeFunctionData, keccak256, stringToHex, toHex, zeroAddress, zeroHash, type Address, type Hash, type Hex } from "viem";
2
- import { abyssLifecycleAdapterAbi, launchLifecycleAbi, lifecycleAdapterAbi, lifecycleDirectoryAbi, lifecycleErc20Abi, lifecycleOracleFactoryAbi, lifecycleRegistryAbi, reviewedV4FeeCollectorFactoryV1Abi, lifecycleV4HookAbi, lifecycleV4LockerAbi, reviewedPoolBoundHookDeployerV1Abi, reviewedSharedHookDeployerV1Abi, poolBoundLaunchFeeHookV1Abi, reviewedPoolBoundV4MarketAdapterV1Abi, reviewedSharedV4MarketAdapterV1Abi } from "./abi.js";
3
- import { decodePoolBoundV4LifecycleMarketConfig, encodePoolBoundHookParameters, hasLifecycleV4HookPermissions, hashPoolBoundV4MarketCommitment, poolBoundHookInitCodeHash, predictPoolBoundHookAddress, validateReviewedV4LifecycleMarket, V4_LIFECYCLE_CONFIG_SCHEMA, V4_POOL_BOUND_LIFECYCLE_CONFIG_SCHEMA, type PoolBoundHookParametersV1 } from "./markets.js";
2
+ import { abyssLifecycleAdapterAbi, launchLifecycleAbi, lifecycleAdapterAbi, lifecycleDirectoryAbi, lifecycleErc20Abi, lifecycleOracleFactoryAbi, lifecycleRegistryAbi, poolFeeCollectorFactoryV1Abi, lifecycleV4HookAbi, lifecycleV4LockerAbi, poolHookDeployerV1Abi, sharedHookDeployerV1Abi, fixedFeePoolHookV1Abi, poolMarketAdapterV1Abi, sharedMarketAdapterV1Abi } from "./abi.js";
3
+ import { decodePoolBoundV4LifecycleMarketConfig, encodePoolBoundHookParameters, hasLifecycleV4HookPermissions, hashPoolBoundV4MarketCommitment, poolBoundHookInitCodeHash, predictPoolBoundHookAddress, validateV4LifecycleMarket, V4_LIFECYCLE_CONFIG_SCHEMA, V4_POOL_BOUND_LIFECYCLE_CONFIG_SCHEMA, type PoolBoundHookParametersV1 } from "./markets.js";
4
4
  import { hashLaunchIdentity, hashLaunchPlan, hashLaunchBounds, hashLaunchDependencies, hashLifecycleProfile, launchProgressV1Components, LifecycleMode, LifecyclePhase, LifecycleVenue, LIFECYCLE_REQUIRED_CAPABILITIES, LIFECYCLE_ERC404_CAPABILITY, LIFECYCLE_MULTI_POSITION_CAPABILITY, type AdapterRegistrationV1, type LaunchPlanV1, type LaunchProgressV1, type MarketIdentityV1, type MarketLiveStateV1, type PreparedMarketV1, type ProfileRegistrationV1, type ProfileTopologyV1, type LaunchEnvelopeV2, type LifecycleDeveloperTerms } from "./schema.js";
5
5
  import { assertLifecycleBlock, lifecycleRpc, readLifecycleBlock, readLifecycleContract, readLifecycleProfileTopology, rpcHex, rpcObject, rpcQuantity } from "./rpc.js";
6
6
  import { LifecyclePlanningError, type CanonicalLaunchProgress, type LifecycleBlock, type LifecycleMarketProgress, type LifecycleProfile, type LifecycleReceiptReference, type LifecycleReceiptStatus, type LifecycleRpcClient, type PoolBoundHookDeployment, type ReadLaunchProgressOptions } from "./types.js";
@@ -52,14 +52,14 @@ async function certifyLifecycleProfile(client: LifecycleRpcClient, orchestrator:
52
52
  hashLaunchBounds(envelope.bounds).toLowerCase() !== envelope.configBoundsDigest.toLowerCase() ||
53
53
  envelope.capabilities !== registration.capabilities || envelope.capabilities !== adapter.capabilities ||
54
54
  (envelope.capabilities & ~(LIFECYCLE_REQUIRED_CAPABILITIES | LIFECYCLE_ERC404_CAPABILITY | LIFECYCLE_MULTI_POSITION_CAPABILITY)) !== 0n) {
55
- throw new LifecyclePlanningError("REVIEWED_ENVELOPE", "Frozen reviewed profile identity, bounds, capabilities or economic version differs from registry admission");
55
+ throw new LifecyclePlanningError("PROFILE_ENVELOPE", "Frozen reviewed profile identity, bounds, capabilities or economic version differs from registry admission");
56
56
  }
57
57
  const b = envelope.bounds;
58
- if (b.maximumHookFeePips >= 1000000 || b.maximumLpFeePips >= 1000000 || b.minimumTickSpacing < 1 ||
58
+ if (b.minimumTickSpacing < 1 ||
59
59
  b.maximumTickSpacing > 32767 || b.minimumTickSpacing > b.maximumTickSpacing || b.maximumPositions < 1 || b.maximumPositions > 32 ||
60
60
  b.maximumOracleCardinality < 2 || b.maximumOracleCardinality > 4096 || b.feeModeFlags === 0 || (b.feeModeFlags & ~3) !== 0 ||
61
- envelope.protocolTreasury === zeroAddress || (envelope.protocolFeeDenominator !== 0 && (envelope.protocolFeeDenominator < 4 || envelope.protocolFeeDenominator > 10))) throw new LifecyclePlanningError("REVIEWED_BOUNDS", "Registry envelope has unsupported executable bounds");
62
- const abi = bound ? reviewedPoolBoundV4MarketAdapterV1Abi : reviewedSharedV4MarketAdapterV1Abi;
61
+ envelope.protocolTreasury === zeroAddress || (envelope.protocolFeeDenominator !== 0 && (envelope.protocolFeeDenominator < 4 || envelope.protocolFeeDenominator > 10))) throw new LifecyclePlanningError("PROFILE_BOUNDS", "Registry envelope has unsupported executable bounds");
62
+ const abi = bound ? poolMarketAdapterV1Abi : sharedMarketAdapterV1Abi;
63
63
  for (const [getter, expected] of [["PROFILE_ID", id], ["CONFIG_SCHEMA", registration.configSchema], ["implementationRegistry", registry]] as const) {
64
64
  const actual = await readLifecycleContract<Hex>(client, adapter.implementation, abi, getter, [], block);
65
65
  if (actual.toLowerCase() !== expected.toLowerCase()) throw new LifecyclePlanningError("PROFILE_DEPENDENCY", "Reviewed adapter metadata differs from registry certification");
@@ -77,12 +77,12 @@ async function certifyLifecycleProfile(client: LifecycleRpcClient, orchestrator:
77
77
  [g.hookDeployer, g.hookDeployerCodeHash]] as const) {
78
78
  if (keccak256(await readDependencyCode(client, address, block)).toLowerCase() !== expectedHash.toLowerCase()) throw new LifecyclePlanningError("PROFILE_CODE_HASH", "Live runtime differs from the frozen reviewed graph hash");
79
79
  }
80
- const collectorDeployer = await readLifecycleContract<Address>(client, g.collectorFactory, reviewedV4FeeCollectorFactoryV1Abi, "collectorDeployer", [], block);
80
+ const collectorDeployer = await readLifecycleContract<Address>(client, g.collectorFactory, poolFeeCollectorFactoryV1Abi, "collectorDeployer", [], block);
81
81
  const launcher = await readLifecycleContract<Address>(client, g.locker, lifecycleV4LockerAbi, "launcher", [], block);
82
82
  const lockerManager = await readLifecycleContract<Address>(client, g.locker, lifecycleV4LockerAbi, "poolManager", [], block);
83
83
  if (collectorDeployer.toLowerCase() !== g.collectorDeployer.toLowerCase() || launcher.toLowerCase() !== adapter.implementation.toLowerCase() ||
84
84
  lockerManager.toLowerCase() !== g.manager.toLowerCase() || g.locker.toLowerCase() === g.manager.toLowerCase() || g.locker.toLowerCase() === g.hookRoot.toLowerCase()) throw new LifecyclePlanningError("PROFILE_DEPENDENCY", "Reviewed collector or locker authority differs from the frozen graph");
85
- const deployerAbi = shared ? reviewedSharedHookDeployerV1Abi : reviewedPoolBoundHookDeployerV1Abi;
85
+ const deployerAbi = shared ? sharedHookDeployerV1Abi : poolHookDeployerV1Abi;
86
86
  const creationCodeHash = await readLifecycleContract<Hex>(client, g.hookDeployer, deployerAbi, "creationCodeHash", [], block);
87
87
  const chunk0 = await readLifecycleContract<Address>(client, g.hookDeployer, deployerAbi, "codeChunk0", [], block);
88
88
  const chunk1 = await readLifecycleContract<Address>(client, g.hookDeployer, deployerAbi, "codeChunk1", [], block);
@@ -101,7 +101,7 @@ async function certifyLifecycleProfile(client: LifecycleRpcClient, orchestrator:
101
101
  const recordedHash = await readLifecycleContract<Hex>(client, g.hookDeployer, deployerAbi, "deployedCodeHash", [g.hookRoot], block);
102
102
  const initCodeHash = keccak256(concatHex([creationCode, encodeAbiParameters([{ type: "address" }, { type: "address" }, { type: "address" }], [g.manager, adapter.implementation, g.oracleFactory])]));
103
103
  const prediction = predictPoolBoundHookAddress({ deployer: g.hookDeployer, initCodeHash, salt: g.sharedHookSalt });
104
- const remotePrediction = await readLifecycleContract<Address>(client, g.hookDeployer, reviewedSharedHookDeployerV1Abi, "predict", [g.manager, adapter.implementation, g.oracleFactory, g.sharedHookSalt], block);
104
+ const remotePrediction = await readLifecycleContract<Address>(client, g.hookDeployer, sharedHookDeployerV1Abi, "predict", [g.manager, adapter.implementation, g.oracleFactory, g.sharedHookSalt], block);
105
105
  if (recordedHash === zeroHash || recordedHash.toLowerCase() !== g.hookRuntimeCodeHash.toLowerCase() || keccak256(rootCode).toLowerCase() !== recordedHash.toLowerCase() ||
106
106
  !hasLifecycleV4HookPermissions(g.hookRoot) || prediction.toLowerCase() !== g.hookRoot.toLowerCase() || remotePrediction.toLowerCase() !== prediction.toLowerCase()) throw new LifecyclePlanningError("PROFILE_DEPENDENCY", "Shared root lacks exact typed-deployer runtime and constructor/salt provenance");
107
107
  for (const [getter, expected] of [["registrar", adapter.implementation], ["poolManager", g.manager], ["oracleFactory", g.oracleFactory]] as const) {
@@ -110,12 +110,22 @@ async function certifyLifecycleProfile(client: LifecycleRpcClient, orchestrator:
110
110
  if (await readLifecycleContract<bigint>(client, g.hookRoot, lifecycleV4HookAbi, "REQUIRED_HOOK_FLAGS", [], block) !== 0x1afcn ||
111
111
  await readLifecycleContract<bigint>(client, g.hookRoot, lifecycleV4HookAbi, "ALL_HOOK_MASK", [], block) !== 0x3fffn) throw new LifecyclePlanningError("PROFILE_DEPENDENCY", "Shared hook callbacks differ from admission");
112
112
  } else if (g.hookRoot !== zeroAddress || g.hookRuntimeCodeHash !== zeroHash || g.sharedHookSalt !== zeroHash) throw new LifecyclePlanningError("PROFILE_DEPENDENCY", "Bound topology cannot reuse a shared root");
113
- if ([zeroAddress, orchestrator, registry, adapter.implementation, g.manager, g.hookRoot, g.locker, g.collectorFactory, g.collectorDeployer, g.hookDeployer].some((address) => address.toLowerCase() === envelope.beneficiary.toLowerCase())) throw new LifecyclePlanningError("REVIEWED_TERMS", "Stable author identity is an excluded reviewed graph destination");
114
- const [move, cardinality] = await readLifecycleContract<readonly [number, number]>(client, g.oracleFactory, lifecycleOracleFactoryAbi, "oracleConfigs", [b.oracleConfigId], block);
115
- if (move === 0 || move > 887272 || cardinality < 2 || cardinality > b.maximumOracleCardinality) throw new LifecyclePlanningError("REVIEWED_BOUNDS", "Reviewed oracle configuration exceeds the admitted bounds");
113
+ if ([zeroAddress, orchestrator, registry, adapter.implementation, g.manager, g.hookRoot, g.locker, g.collectorFactory, g.collectorDeployer, g.hookDeployer].some((address) => address.toLowerCase() === envelope.beneficiary.toLowerCase())) throw new LifecyclePlanningError("PROFILE_TERMS", "Stable author identity is an excluded reviewed graph destination");
116
114
  return { topology, boundGraph: bound ? { manager: g.manager, oracleFactory: g.oracleFactory, locker: g.locker, collectorFactory: g.collectorFactory, deployer: g.hookDeployer, creationCode } : undefined };
117
115
  }
118
116
 
117
+ /** Validate the market-selected registered oracle against the certified factory at the pinned block. */
118
+ export async function validateV4LifecycleOracle(options: {
119
+ client: LifecycleRpcClient; envelope: LaunchEnvelopeV2; oracleConfigId: Hex; block: LifecycleBlock;
120
+ }): Promise<void> {
121
+ const { client, envelope, oracleConfigId, block } = options;
122
+ if (oracleConfigId.toLowerCase() === zeroHash) throw new LifecyclePlanningError("INVALID_ORACLE_CONFIG", "Market oracle configuration must be nonzero");
123
+ const [move, cardinality] = await readLifecycleContract<readonly [number, number]>(client, envelope.graph.oracleFactory, lifecycleOracleFactoryAbi, "oracleConfigs", [oracleConfigId], block);
124
+ if (move <= 0 || move > 887272 || cardinality < 2 || cardinality > envelope.bounds.maximumOracleCardinality) {
125
+ throw new LifecyclePlanningError("INVALID_ORACLE_CONFIG", "Selected market oracle is unregistered or exceeds the admitted cardinality bounds");
126
+ }
127
+ }
128
+
119
129
  export async function readLifecycleProfiles(options: { client: LifecycleRpcClient; orchestrator: Address; profileIds?: readonly Hex[]; offset?: bigint; limit?: bigint }, pinnedBlock?: LifecycleBlock): Promise<LifecycleProfile[]> {
120
130
  const block = pinnedBlock ?? await readLifecycleBlock(options.client);
121
131
  const chainId = rpcQuantity(await lifecycleRpc(options.client, "eth_chainId"), "chain ID");
@@ -143,7 +153,7 @@ export async function readLifecycleProfiles(options: { client: LifecycleRpcClien
143
153
  developerTerms = { adapter: implementation, beneficiary, maximumDeveloperFeeBps, termsDigest, enabled };
144
154
  if (implementation.toLowerCase() !== adapter.implementation.toLowerCase() || beneficiary.toLowerCase() !== envelope.beneficiary.toLowerCase() ||
145
155
  termsDigest.toLowerCase() !== envelope.termsDigest.toLowerCase() || maximumDeveloperFeeBps !== envelope.maximumDeveloperFeeBps ||
146
- maximumDeveloperFeeBps > protocolMaximumDeveloperFeeBps) throw new LifecyclePlanningError("REVIEWED_TERMS", "Registry developer terms differ from the frozen reviewed envelope");
156
+ maximumDeveloperFeeBps > protocolMaximumDeveloperFeeBps) throw new LifecyclePlanningError("PROFILE_TERMS", "Registry developer terms differ from the frozen reviewed envelope");
147
157
  }
148
158
  await certifyLifecycleProfile(options.client, options.orchestrator, registry, id, registration, adapter, topology, envelope, block, chainId);
149
159
  const eligible = await readLifecycleContract<Address>(options.client, registry, lifecycleRegistryAbi, "requireEligible", [registration.adapterId, id, topology.configVersion, LIFECYCLE_REQUIRED_CAPABILITIES], block);
@@ -175,11 +185,12 @@ async function readPoolBoundHookDeploymentDetails(options: { client: LifecycleRp
175
185
  if (boundGraph === undefined) throw new LifecyclePlanningError("UNCERTIFIED_TOPOLOGY", "Market does not have a certified pool-bound deployer graph");
176
186
  const token = await readLifecycleContract<Address>(client, plan.orchestrator, launchLifecycleAbi, "predictToken", [plan], block);
177
187
  const config = decodePoolBoundV4LifecycleMarketConfig(market.config);
178
- validateReviewedV4LifecycleMarket({ market, config, token, profile: {
188
+ validateV4LifecycleMarket({ market, config, token, profile: {
179
189
  id: market.profileId, registration, adapter, topology: recorded, envelope,
180
190
  developerTerms: { adapter: implementation, beneficiary, maximumDeveloperFeeBps, termsDigest, enabled },
181
191
  protocolMaximumDeveloperFeeBps, venueKind: "uniswap-v4", admitted: enabled,
182
192
  } });
193
+ await validateV4LifecycleOracle({ client, envelope, oracleConfigId: config.oracleConfigId, block });
183
194
  const expected: PoolBoundHookParametersV1 = {
184
195
  poolManager: boundGraph.manager, registrar: adapter.implementation, oracleFactory: boundGraph.oracleFactory, core: plan.orchestrator,
185
196
  liquidityLocker: boundGraph.locker, token, quoteCurrency: market.quoteAsset, lpFeePips: config.lpFeePips, tickSpacing: config.tickSpacing,
@@ -188,33 +199,33 @@ async function readPoolBoundHookDeploymentDetails(options: { client: LifecycleRp
188
199
  marketCommitment: hashPoolBoundV4MarketCommitment({ chainId, core: plan.orchestrator, registrar: adapter.implementation, token, market }),
189
200
  expectedPositionCount: config.positions.length,
190
201
  };
191
- const [parameters, parameterSalt] = await readLifecycleContract<readonly [PoolBoundHookParametersV1, Hex]>(client, boundGraph.collectorFactory, reviewedV4FeeCollectorFactoryV1Abi, "poolBoundHookParameters", [adapter.implementation, token, market], block);
192
- const [deployer, initCodeHash, salt, predictedHook] = await readLifecycleContract<readonly [Address, Hex, Hex, Address]>(client, adapter.implementation, reviewedPoolBoundV4MarketAdapterV1Abi, "hookDeploymentMetadata", [token, market], block);
193
- const remoteInitCodeHash = await readLifecycleContract<Hex>(client, boundGraph.deployer, reviewedPoolBoundHookDeployerV1Abi, "initCodeHash", [expected], block);
194
- const remotePrediction = await readLifecycleContract<Address>(client, boundGraph.deployer, reviewedPoolBoundHookDeployerV1Abi, "predict", [expected, config.hookSalt], block);
202
+ const [parameters, parameterSalt] = await readLifecycleContract<readonly [PoolBoundHookParametersV1, Hex]>(client, boundGraph.collectorFactory, poolFeeCollectorFactoryV1Abi, "poolBoundHookParameters", [adapter.implementation, token, market], block);
203
+ const [deployer, initCodeHash, salt, predictedHook] = await readLifecycleContract<readonly [Address, Hex, Hex, Address]>(client, adapter.implementation, poolMarketAdapterV1Abi, "hookDeploymentMetadata", [token, market], block);
204
+ const remoteInitCodeHash = await readLifecycleContract<Hex>(client, boundGraph.deployer, poolHookDeployerV1Abi, "initCodeHash", [expected], block);
205
+ const remotePrediction = await readLifecycleContract<Address>(client, boundGraph.deployer, poolHookDeployerV1Abi, "predict", [expected, config.hookSalt], block);
195
206
  const localInitCodeHash = poolBoundHookInitCodeHash(boundGraph.creationCode, expected);
196
207
  const localPrediction = predictPoolBoundHookAddress({ deployer: boundGraph.deployer, initCodeHash: localInitCodeHash, salt: config.hookSalt });
197
208
  if (encodePoolBoundHookParameters(parameters).toLowerCase() !== encodePoolBoundHookParameters(expected).toLowerCase() || parameterSalt.toLowerCase() !== config.hookSalt.toLowerCase() || salt.toLowerCase() !== config.hookSalt.toLowerCase() || deployer.toLowerCase() !== boundGraph.deployer.toLowerCase() || initCodeHash.toLowerCase() !== localInitCodeHash.toLowerCase() || remoteInitCodeHash.toLowerCase() !== localInitCodeHash.toLowerCase() || predictedHook.toLowerCase() !== localPrediction.toLowerCase() || remotePrediction.toLowerCase() !== localPrediction.toLowerCase()) throw new LifecyclePlanningError("HOOK_DEPLOYMENT_CHANGED", "Bound hook metadata differs from the exact certified constructor economics, factory, initcode, salt or CREATE2 prediction");
198
209
  const hookCode = rpcHex(await lifecycleRpc(client, "eth_getCode", [predictedHook, toHex(block.number)]), "bound hook code");
199
210
  if (hookCode !== "0x") {
200
- const deployedCodeHash = await readLifecycleContract<Hex>(client, deployer, reviewedPoolBoundHookDeployerV1Abi, "deployedCodeHash", [predictedHook], block);
211
+ const deployedCodeHash = await readLifecycleContract<Hex>(client, deployer, poolHookDeployerV1Abi, "deployedCodeHash", [predictedHook], block);
201
212
  if ((hookCode.length - 2) / 2 > 24576 || deployedCodeHash === zeroHash || deployedCodeHash.toLowerCase() !== keccak256(hookCode).toLowerCase()) throw new LifecyclePlanningError("HOOK_DEPLOYMENT_CHANGED", "Existing hook lacks this exact typed deployer's bounded runtime-code provenance");
202
213
  for (const [getter, expectedAddress] of [
203
214
  ["poolManager", expected.poolManager], ["registrar", expected.registrar], ["oracleFactory", expected.oracleFactory],
204
215
  ["core", expected.core], ["liquidityLocker", expected.liquidityLocker], ["token", expected.token],
205
216
  ] as const) {
206
- const actual = await readLifecycleContract<Address>(client, predictedHook, poolBoundLaunchFeeHookV1Abi, getter, [], block);
217
+ const actual = await readLifecycleContract<Address>(client, predictedHook, fixedFeePoolHookV1Abi, getter, [], block);
207
218
  if (actual.toLowerCase() !== expectedAddress.toLowerCase()) throw new LifecyclePlanningError("HOOK_DEPLOYMENT_CHANGED", "Existing hook immutable dependency graph differs from the committed constructor");
208
219
  }
209
- if (await readLifecycleContract<bigint>(client, predictedHook, poolBoundLaunchFeeHookV1Abi, "REQUIRED_HOOK_FLAGS", [], block) !== 0x1afcn ||
210
- await readLifecycleContract<bigint>(client, predictedHook, poolBoundLaunchFeeHookV1Abi, "ALL_HOOK_MASK", [], block) !== 0x3fffn) throw new LifecyclePlanningError("HOOK_DEPLOYMENT_CHANGED", "Existing bound hook callback declarations differ from the reviewed envelope");
220
+ if (await readLifecycleContract<bigint>(client, predictedHook, fixedFeePoolHookV1Abi, "REQUIRED_HOOK_FLAGS", [], block) !== 0x1afcn ||
221
+ await readLifecycleContract<bigint>(client, predictedHook, fixedFeePoolHookV1Abi, "ALL_HOOK_MASK", [], block) !== 0x3fffn) throw new LifecyclePlanningError("HOOK_DEPLOYMENT_CHANGED", "Existing bound hook callback declarations differ from the reviewed envelope");
211
222
  const [currency0, currency1] = BigInt(token) < BigInt(market.quoteAsset) ? [token, market.quoteAsset] : [market.quoteAsset, token];
212
223
  const expectedPoolId = keccak256(encodeAbiParameters([{ type: "address" }, { type: "address" }, { type: "uint24" }, { type: "int24" }, { type: "address" }], [currency0, currency1, config.lpFeePips, config.tickSpacing, predictedHook]));
213
- const actualPoolId = await readLifecycleContract<Hex>(client, predictedHook, poolBoundLaunchFeeHookV1Abi, "boundPoolId", [], block);
214
- const deploymentConfigHash = await readLifecycleContract<Hex>(client, predictedHook, poolBoundLaunchFeeHookV1Abi, "deploymentConfigHash", [], block);
215
- const marketCommitment = await readLifecycleContract<Hex>(client, predictedHook, poolBoundLaunchFeeHookV1Abi, "marketCommitment", [], block);
216
- const opening = await readLifecycleContract<bigint>(client, predictedHook, poolBoundLaunchFeeHookV1Abi, "openingSqrtPriceX96", [], block);
217
- const positions = await readLifecycleContract<number>(client, predictedHook, poolBoundLaunchFeeHookV1Abi, "expectedPositionCount", [], block);
224
+ const actualPoolId = await readLifecycleContract<Hex>(client, predictedHook, fixedFeePoolHookV1Abi, "boundPoolId", [], block);
225
+ const deploymentConfigHash = await readLifecycleContract<Hex>(client, predictedHook, fixedFeePoolHookV1Abi, "deploymentConfigHash", [], block);
226
+ const marketCommitment = await readLifecycleContract<Hex>(client, predictedHook, fixedFeePoolHookV1Abi, "marketCommitment", [], block);
227
+ const opening = await readLifecycleContract<bigint>(client, predictedHook, fixedFeePoolHookV1Abi, "openingSqrtPriceX96", [], block);
228
+ const positions = await readLifecycleContract<number>(client, predictedHook, fixedFeePoolHookV1Abi, "expectedPositionCount", [], block);
218
229
  if (actualPoolId.toLowerCase() !== expectedPoolId.toLowerCase() || deploymentConfigHash.toLowerCase() !== keccak256(encodePoolBoundHookParameters(expected)).toLowerCase() || marketCommitment.toLowerCase() !== expected.marketCommitment.toLowerCase() || opening !== expected.sqrtPriceX96 || positions !== expected.expectedPositionCount) throw new LifecyclePlanningError("HOOK_DEPLOYMENT_CHANGED", "Existing hook key, economic commitment or immutable opening geometry changed");
219
230
  }
220
231
  return { deployment: { deployer, initCodeHash, salt, predictedHook }, parameters: expected };
@@ -238,7 +249,7 @@ export async function buildPoolBoundHookDeploymentTransaction(options: { client:
238
249
  if (!hasLifecycleV4HookPermissions(deployment.predictedHook)) throw new LifecyclePlanningError("INVALID_HOOK_BITS", "Finalize a salt with the exact lifecycle hook permissions before predeployment");
239
250
  if (hashLaunchPlan(options.plan) !== commitment) throw new LifecyclePlanningError("PLAN_MUTATED", "Economic plan changed while constructing hook deployment calldata");
240
251
  await assertLifecycleBlock(options.client, block);
241
- return { to: deployment.deployer, data: encodeFunctionData({ abi: reviewedPoolBoundHookDeployerV1Abi, functionName: "deploy", args: [parameters, deployment.salt] }), value: 0n, deployment };
252
+ return { to: deployment.deployer, data: encodeFunctionData({ abi: poolHookDeployerV1Abi, functionName: "deploy", args: [parameters, deployment.salt] }), value: 0n, deployment };
242
253
  }
243
254
 
244
255
  export function validateLifecycleMarketIdentity(identity: MarketIdentityV1, plan: LaunchPlanV1, token: Address, marketIndex: number): void {
@@ -71,9 +71,8 @@ export type MarketLiveStateV1 = {
71
71
  };
72
72
 
73
73
  export type LaunchBoundsV2 = {
74
- maximumHookFeePips: number; maximumLpFeePips: number; minimumTickSpacing: number; maximumTickSpacing: number;
74
+ minimumTickSpacing: number; maximumTickSpacing: number;
75
75
  maximumPositions: number; maximumOracleCardinality: number; feeModeFlags: number;
76
- externalLiquidityDisabled: boolean; oracleConfigId: Hex;
77
76
  };
78
77
  export type LaunchGraphV2 = {
79
78
  manager: Address; hookRoot: Address; oracleFactory: Address; locker: Address; collectorFactory: Address;
@@ -96,11 +95,9 @@ export type SourceTermsV3 = {
96
95
  maximumDeveloperFeeBps: number; developerFeeBps: number;
97
96
  };
98
97
  export const launchBoundsV2Components = [
99
- { name: "maximumHookFeePips", type: "uint24" }, { name: "maximumLpFeePips", type: "uint24" },
100
98
  { name: "minimumTickSpacing", type: "int24" }, { name: "maximumTickSpacing", type: "int24" },
101
99
  { name: "maximumPositions", type: "uint16" }, { name: "maximumOracleCardinality", type: "uint16" },
102
- { name: "feeModeFlags", type: "uint8" }, { name: "externalLiquidityDisabled", type: "bool" },
103
- { name: "oracleConfigId", type: "bytes32" },
100
+ { name: "feeModeFlags", type: "uint8" },
104
101
  ] as const;
105
102
  export const launchGraphV2Components = [
106
103
  { name: "manager", type: "address" }, { name: "hookRoot", type: "address" },
@@ -154,7 +151,7 @@ export function hashLifecycleProfile(envelope: LaunchEnvelopeV2): Hex {
154
151
  return keccak256(encodeAbiParameters([
155
152
  { type: "bytes32" }, { type: "bytes32" }, { type: "bytes32" }, { type: "bytes32" }, { type: "bytes32" },
156
153
  { type: "uint8" }, { type: "uint32" }, { type: "uint32" }, { type: "address" }, { type: "uint16" }, { type: "uint64" },
157
- ], [keccak256(stringToHex("black-market.reviewed-launch-profile.v2")), envelope.artifactDigest,
154
+ ], [keccak256(stringToHex("black-market.launch-profile.v2")), envelope.artifactDigest,
158
155
  envelope.reviewManifestDigest, envelope.configBoundsDigest, envelope.termsDigest, envelope.topology,
159
156
  envelope.configVersion, envelope.economicVersion, envelope.beneficiary, envelope.maximumDeveloperFeeBps, envelope.capabilities]));
160
157
  }
@@ -170,7 +167,7 @@ export function hashLaunchDependencies(options: {
170
167
  { type: "address" }, { type: "bytes32" }, { type: "address" }, { type: "bytes32" },
171
168
  { type: "address" }, { type: "bytes32" }, { type: "address" }, { type: "bytes32" }, { type: "bytes32" },
172
169
  { type: "address" }, { type: "bytes32" }, { type: "address" }, { type: "bytes32" },
173
- ], [keccak256(stringToHex("black-market.reviewed-v4-dependencies.v2")), chainId, core, g.coreCodeHash,
170
+ ], [keccak256(stringToHex("black-market.v4-dependencies.v2")), chainId, core, g.coreCodeHash,
174
171
  registry, registrar, g.manager, g.managerCodeHash, g.hookRoot, g.hookRuntimeCodeHash,
175
172
  g.oracleFactory, g.oracleFactoryCodeHash, g.locker, g.lockerCodeHash, g.collectorFactory, g.collectorFactoryCodeHash,
176
173
  g.collectorDeployer, g.collectorDeployerCodeHash, g.hookDeployer, g.hookDeployerCodeHash,
@@ -182,10 +179,9 @@ export const LIFECYCLE_PERMANENT_CUSTODY_CAPABILITY = 8n;
182
179
  export const LIFECYCLE_CANONICAL_FEES_CAPABILITY = 16n;
183
180
  export const LIFECYCLE_ERC404_CAPABILITY = 32n;
184
181
  export const LIFECYCLE_MULTI_POSITION_CAPABILITY = 64n;
185
- /** TOKEN_ONLY|EMPTY_PREPARE|PERMANENT_CUSTODY|CANONICAL_FEES. The retired POOL_GATE bit
186
- * is never requested: preactivation safety is token transfer restrictions plus the
187
- * activation-time canonical opening-state verification on both canonical venues. Atomic
188
- * and staged share this mask; mode changes execution grouping, never venue eligibility. */
182
+ /** TOKEN_ONLY|EMPTY_PREPARE|PERMANENT_CUSTODY|CANONICAL_FEES. Preactivation safety
183
+ * uses token transfer restrictions and activation-time canonical opening-state
184
+ * verification on both venues. Atomic and staged share this capability mask. */
189
185
  export const LIFECYCLE_REQUIRED_CAPABILITIES = LIFECYCLE_TOKEN_ONLY_CAPABILITY | LIFECYCLE_EMPTY_PREPARE_CAPABILITY | LIFECYCLE_PERMANENT_CUSTODY_CAPABILITY | LIFECYCLE_CANONICAL_FEES_CAPABILITY;
190
186
  export const LIFECYCLE_MAX_ERC20_SUPPLY = (1n << 256n) - 1n;
191
187
  export const LIFECYCLE_MAX_REWARD_ERC20_SUPPLY = 10n ** 77n;