@hyperbridge/simplex 0.16.7 → 0.16.8

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.
@@ -214220,6 +214220,12 @@ function userOperationLogs(logs, entryPoint, userOpHash) {
214220
214220
  while (start >= 0 && !isBoundary(logs[start])) start--;
214221
214221
  return logs.slice(start + 1, end);
214222
214222
  }
214223
+ function escrowSlot(commitment, leg) {
214224
+ const byCommitment = keccak2563(
214225
+ encodeAbiParameters2([{ type: "bytes32" }, { type: "uint256" }], [commitment, ESCROW_MAPPING_SLOT])
214226
+ );
214227
+ return keccak2563(encodeAbiParameters2([{ type: "uint256" }, { type: "bytes32" }], [BigInt(leg), byCommitment]));
214228
+ }
214223
214229
  function destinationStateMachine(order) {
214224
214230
  return isHex3(order.destination) ? hexToString2(order.destination) : order.destination;
214225
214231
  }
@@ -214399,7 +214405,7 @@ function encodePhantomBidDeclaration(declaration) {
214399
214405
  }
214400
214406
  return u8aToHex(new Uint8Array(bytes4));
214401
214407
  }
214402
- var import_merge_race, __defProp3, __getOwnPropNames2, __esm2, __export2, node_exports, wasm, full_path, __dirname$1, cachedTextDecoder, cachedUint8ArrayMemory0, WASM_VECTOR_LEN, cachedTextEncoder, encodeString5, cachedDataViewMemory0, KeccakMergeFinalization, KeccakMerge, wasmPath, wasmBytes2, bindings, wasmModule, wasmInstance, __wasm, init_node11, RequestStatus, TimeoutStatus, IntentOrderStatus, ABI, evmHost_default, ABI2, handlerV2_default, polkadotAssetHubPaseo, polkadotHubMainnet, pharosMainnet, pharosAtlantic, tronNile, chainConfigs, configsByStateMachineId, getConfigByStateMachineId, getChainId3, getViemChain, hyperbridgeAddress, ABI3, IntentGatewayV2_default, ChainConfigService, ABI4, uniswapRouterV2_default, chains, DEFAULT_ADDRESS, EvmChain, REQUEST_COMMITMENTS_SLOT, RESPONSE_COMMITMENTS_SLOT, REQUEST_RECEIPTS_SLOT, STATE_COMMITMENTS_SLOT, MISSING_CONSENSUS_UPDATE_TIME_MESSAGE, MissingConsensusUpdateTimeError, TokenBucket, BATCHES_NOT_SUPPORTED_CODE, TOO_BIG_BATCH_REQUEST_CODE, DEFAULT_MAX_BATCH_SIZE, _endpoint2, _headers3, _limiter, _maxBatchSize, _batchingSupported, _pending2, _flushTimer, _flushing, _nextId, __BatchingHttpProvider_instances, scheduleFlush_fn, flushNow_fn, flush_fn, post_fn, settleBatch_fn, settle_fn, handleBatchRefusal_fn, requeue_fn, _a5, BatchingHttpProvider, OFFCHAIN_BID_PREFIX, HYPERBRIDGE_TYPES_BUNDLE, BASE_TIP, HTTP_CONNECT_TIMEOUT_MS, INCLUSION_TIMEOUT_MS, DEFAULT_RPC_MAX_RPS, rpcLimiters, BidCodec, PackedUserOperationCodec, IntentsCoprocessor, ReviveContractInfo, ReviveAccountType, ReviveAccountInfo, H256, EvmStateProof, SubstrateHashing, SubstrateStateMachineProof, BasicProof, LeafIndexAndPos, MmrProof, ConsensusStateId, ConsensusMessage, FraudProofMessage, StateMachine, StateMachineId, StateMachineHeight, Proof, PostRequest, PostResponse, GetRequest, StorageValue, GetResponse, Request3, Response2, RequestMessage, RequestResponse, ResponseMessage, TimeoutMessage, GetRequestsWithProof, Message, DEFAULT_CHILD_STORAGE_PREFIX, PharosProofNodeCodec, SiblingLeftmostLeafProofCodec, NonExistenceProofCodec, AccountProofDataCodec, PharosStateProof, DEFAULT_POLL_INTERVAL, ADDRESS_ZERO2, DEFAULT_GRAFFITI, DEFAULT_LOGGER, REQUEST_STATUS_WEIGHTS, TIMEOUT_STATUS_WEIGHTS, COMBINED_STATUS_WEIGHTS, CHAIN_ID_TO_COINGECKO_NATIVE, TESTNET_CHAINS, ORDER_STATUS, loadDriver, detectEnvironment, STORAGE_KEYS, LEGACY_STORAGE_KEYS, ABI5, uniswapV3Quoter_default, UNISWAP_V4_QUOTER_ABI, ABI6, universalRouter_default, PERMIT2_ABI, UniswapQuoteEngine, COMMON_FEE_TIERS, Swap, ABI7, erc7281_default, DEFAULT_GRAFFITI2, ERC7821_BATCH_MODE, BundlerMethod, SELECT_SOLVER_TYPEHASH, PACKED_USEROP_TYPEHASH, DOMAIN_TYPEHASH, CryptoUtils, FEE_TOKEN_CACHE_TTL_MS, OrderPlacer, TOKEN_KEYED_GATEWAY_ABI, keyingByClient, PARTIAL_FILLS_SLOT, USED_USEROPS_STORAGE_KEY, OrderExecutor, _a6, OrderCanceller, FILL_ORDER_SELECTOR, SUPPORTED_INTENTS_VERSION, CONTRACT_VERSION_ABI, CANONICAL_EVM_TOKEN, ENTRY_POINT_EVENT_ABI, BidImpl, BidManager, RELAYER_MESSAGE_GAS, NO_BUNDLER_FILL_GAS_BASE, NO_BUNDLER_FILL_GAS_PER_OUTPUT, NO_BUNDLER_PAYMASTER_VERIFICATION_GAS, NO_BUNDLER_PAYMASTER_POST_OP_GAS, GasEstimator, OrderStatusChecker, ORDERBOOK_URLS, ORDERBOOK_DECIMALS, ORDERBOOK_SCALE, OrderbookRequestError, RATE_FIELDS, TOP_OF_BOOK_QUERY, ROUTE_LIQUIDITY_QUERY, QUOTE_QUERY, QUOTE_PESSIMISTIC_QUERY, HyperFxOrderbook, UnsupportedLiquidityAssetError, UnsupportedLiquidityChainError, OrderbookQuoteNotConvergedError, MAX_EXACT_OUTPUT_ROUNDS, OrderbookMarket, ORDER_FEE_GAS_PRICE_BUMP_POLICY, IntentGateway, DECLARATION_V1, DECLARATION_V2, PAYMASTER_ADDRESS_BYTES, PAYMASTER_GAS_LIMIT_BYTES, PAYMASTER_DATA_OFFSET, PERMIT2_DATA_BYTES, PERMIT2_SPONSORSHIP_BYTES, MAX_DECLARED_ENTRIES, MAX_TOKEN_ID_BYTES, TeleportParams, MultiAccount;
214408
+ var import_merge_race, __defProp3, __getOwnPropNames2, __esm2, __export2, node_exports, wasm, full_path, __dirname$1, cachedTextDecoder, cachedUint8ArrayMemory0, WASM_VECTOR_LEN, cachedTextEncoder, encodeString5, cachedDataViewMemory0, KeccakMergeFinalization, KeccakMerge, wasmPath, wasmBytes2, bindings, wasmModule, wasmInstance, __wasm, init_node11, RequestStatus, TimeoutStatus, IntentOrderStatus, ABI, evmHost_default, ABI2, handlerV2_default, polkadotAssetHubPaseo, polkadotHubMainnet, pharosMainnet, pharosAtlantic, tronNile, chainConfigs, configsByStateMachineId, getConfigByStateMachineId, getChainId3, getViemChain, hyperbridgeAddress, ABI3, IntentGatewayV2_default, ChainConfigService, ABI4, uniswapRouterV2_default, chains, DEFAULT_ADDRESS, EvmChain, REQUEST_COMMITMENTS_SLOT, RESPONSE_COMMITMENTS_SLOT, REQUEST_RECEIPTS_SLOT, STATE_COMMITMENTS_SLOT, MISSING_CONSENSUS_UPDATE_TIME_MESSAGE, MissingConsensusUpdateTimeError, TokenBucket, BATCHES_NOT_SUPPORTED_CODE, TOO_BIG_BATCH_REQUEST_CODE, DEFAULT_MAX_BATCH_SIZE, _endpoint2, _headers3, _limiter, _maxBatchSize, _batchingSupported, _pending2, _flushTimer, _flushing, _nextId, __BatchingHttpProvider_instances, scheduleFlush_fn, flushNow_fn, flush_fn, post_fn, settleBatch_fn, settle_fn, handleBatchRefusal_fn, requeue_fn, _a5, BatchingHttpProvider, OFFCHAIN_BID_PREFIX, HYPERBRIDGE_TYPES_BUNDLE, BASE_TIP, HTTP_CONNECT_TIMEOUT_MS, INCLUSION_TIMEOUT_MS, DEFAULT_RPC_MAX_RPS, rpcLimiters, BidCodec, PackedUserOperationCodec, IntentsCoprocessor, ReviveContractInfo, ReviveAccountType, ReviveAccountInfo, H256, EvmStateProof, SubstrateHashing, SubstrateStateMachineProof, BasicProof, LeafIndexAndPos, MmrProof, ConsensusStateId, ConsensusMessage, FraudProofMessage, StateMachine, StateMachineId, StateMachineHeight, Proof, PostRequest, PostResponse, GetRequest, StorageValue, GetResponse, Request3, Response2, RequestMessage, RequestResponse, ResponseMessage, TimeoutMessage, GetRequestsWithProof, Message, DEFAULT_CHILD_STORAGE_PREFIX, PharosProofNodeCodec, SiblingLeftmostLeafProofCodec, NonExistenceProofCodec, AccountProofDataCodec, PharosStateProof, DEFAULT_POLL_INTERVAL, ADDRESS_ZERO2, DEFAULT_GRAFFITI, DEFAULT_LOGGER, REQUEST_STATUS_WEIGHTS, TIMEOUT_STATUS_WEIGHTS, COMBINED_STATUS_WEIGHTS, CHAIN_ID_TO_COINGECKO_NATIVE, TESTNET_CHAINS, ORDER_STATUS, loadDriver, detectEnvironment, STORAGE_KEYS, LEGACY_STORAGE_KEYS, ABI5, uniswapV3Quoter_default, UNISWAP_V4_QUOTER_ABI, ABI6, universalRouter_default, PERMIT2_ABI, UniswapQuoteEngine, COMMON_FEE_TIERS, Swap, ABI7, erc7281_default, DEFAULT_GRAFFITI2, ERC7821_BATCH_MODE, BundlerMethod, SELECT_SOLVER_TYPEHASH, PACKED_USEROP_TYPEHASH, DOMAIN_TYPEHASH, CryptoUtils, FEE_TOKEN_CACHE_TTL_MS, OrderPlacer, TOKEN_KEYED_GATEWAY_ABI, keyingByClient, PARTIAL_FILLS_SLOT, USED_USEROPS_STORAGE_KEY, OrderExecutor, _a6, OrderCanceller, FILL_ORDER_SELECTOR, SUPPORTED_INTENTS_VERSION, CONTRACT_VERSION_ABI, CANONICAL_EVM_TOKEN, ENTRY_POINT_EVENT_ABI, BidImpl, BidManager, RELAYER_MESSAGE_GAS, NO_BUNDLER_FILL_GAS_BASE, NO_BUNDLER_FILL_GAS_PER_OUTPUT, NO_BUNDLER_PAYMASTER_VERIFICATION_GAS, NO_BUNDLER_PAYMASTER_POST_OP_GAS, BID_PVG_ESTIMATION_ACCOUNT_CODE, SELECTED_BID_SIGNATURE_BYTES, BID_PVG_HEADROOM_PERCENT, ESCROW_MAPPING_SLOT, GasEstimator, OrderStatusChecker, ORDERBOOK_URLS, ORDERBOOK_DECIMALS, ORDERBOOK_SCALE, OrderbookRequestError, RATE_FIELDS, TOP_OF_BOOK_QUERY, ROUTE_LIQUIDITY_QUERY, QUOTE_QUERY, QUOTE_PESSIMISTIC_QUERY, HyperFxOrderbook, UnsupportedLiquidityAssetError, UnsupportedLiquidityChainError, OrderbookQuoteNotConvergedError, MAX_EXACT_OUTPUT_ROUNDS, OrderbookMarket, ORDER_FEE_GAS_PRICE_BUMP_POLICY, IntentGateway, DECLARATION_V1, DECLARATION_V2, PAYMASTER_ADDRESS_BYTES, PAYMASTER_GAS_LIMIT_BYTES, PAYMASTER_DATA_OFFSET, PERMIT2_DATA_BYTES, PERMIT2_SPONSORSHIP_BYTES, MAX_DECLARED_ENTRIES, MAX_TOKEN_ID_BYTES, TeleportParams, MultiAccount;
214403
214409
  var init_node10 = __esm({
214404
214410
  "../sdk/dist/node/index.js"() {
214405
214411
  "use strict";
@@ -227819,6 +227825,10 @@ query OrderStatus($commitment: String!) {
227819
227825
  NO_BUNDLER_FILL_GAS_PER_OUTPUT = 150000n;
227820
227826
  NO_BUNDLER_PAYMASTER_VERIFICATION_GAS = 250000n;
227821
227827
  NO_BUNDLER_PAYMASTER_POST_OP_GAS = 100000n;
227828
+ BID_PVG_ESTIMATION_ACCOUNT_CODE = "0x60003560e01c631626ba7e1460145760206000f35b631626ba7e60e01b60005260206000f3";
227829
+ SELECTED_BID_SIGNATURE_BYTES = 32 + 65 + 65;
227830
+ BID_PVG_HEADROOM_PERCENT = 10n;
227831
+ ESCROW_MAPPING_SLOT = 9n;
227822
227832
  GasEstimator = class {
227823
227833
  /**
227824
227834
  * @param ctx - Shared IntentsV2 context providing the source and destination
@@ -227897,6 +227907,7 @@ query OrderStatus($commitment: String!) {
227897
227907
  assetsForOverrides.push({ token: feeTokenAsBytes32, amount: 0n });
227898
227908
  }
227899
227909
  const isSameChain = souceStateMachineId === destStateMachineId;
227910
+ const commitment = orderCommitment(order);
227900
227911
  const [stateOverridesResult, crossChainFees] = await Promise.all([
227901
227912
  this.ctx.bundlerUrl ? this.buildStateOverride({
227902
227913
  accountAddress: solverAccountAddress,
@@ -227904,7 +227915,16 @@ query OrderStatus($commitment: String!) {
227904
227915
  outputAssets: assetsForOverrides,
227905
227916
  spenderAddress: intentGatewayV2Address,
227906
227917
  intentGatewayV2Address,
227907
- entryPointAddress
227918
+ entryPointAddress,
227919
+ // A fee quote runs before the order is placed, so nothing is escrowed under
227920
+ // its commitment yet. Cross-chain fills release escrow on the source chain.
227921
+ escrow: isSameChain ? {
227922
+ commitment,
227923
+ inputs: order.inputs.map((input) => ({
227924
+ token: normalizeAddressForEvmBytes32(input.token),
227925
+ amount: input.amount
227926
+ }))
227927
+ } : void 0
227908
227928
  }) : Promise.resolve({ viem: [], bundler: {} }),
227909
227929
  isSameChain ? Promise.resolve({ postRequestFee: 0n, relayerFeeInSourceFeeToken: 0n }) : this.estimateCrossChainFees(
227910
227930
  sourceFeeToken,
@@ -227933,10 +227953,8 @@ query OrderStatus($commitment: String!) {
227933
227953
  const maxFeeBumpPercent = params.maxFeePerGasBumpPercent ?? 10;
227934
227954
  let maxPriorityFeePerGas = gasPrice + gasPrice * BigInt(priorityFeeBumpPercent) / 100n;
227935
227955
  let maxFeePerGas = gasPrice + gasPrice * BigInt(maxFeeBumpPercent) / 100n;
227936
- const orderForEstimation = { ...order, session: solverAccountAddress };
227937
- const commitment = orderCommitment(orderForEstimation);
227938
227956
  await assertGatewayRelease(this.ctx.dest.client, intentGatewayV2Address);
227939
- const fillOrderCalldata = encodeFillOrder(transformOrderForContract(orderForEstimation), fillOptions);
227957
+ const fillOrderCalldata = encodeFillOrder(transformOrderForContract(order), fillOptions);
227940
227958
  let callGasLimit = 500000n;
227941
227959
  let verificationGasLimit = 100000n;
227942
227960
  let preVerificationGas = 100000n;
@@ -227948,7 +227966,7 @@ query OrderStatus($commitment: String!) {
227948
227966
  ...params.prependCalls ?? [],
227949
227967
  { target: intentGatewayV2Address, value: totalNativeValue, data: fillOrderCalldata }
227950
227968
  ]);
227951
- const accountGasLimits = CryptoUtils.packGasLimits(100000n, callGasLimit);
227969
+ const accountGasLimits = CryptoUtils.packGasLimits(0n, 0n);
227952
227970
  const gasFees = CryptoUtils.packGasFees(maxPriorityFeePerGas, maxFeePerGas);
227953
227971
  const nonce = 0n;
227954
227972
  const preliminaryUserOp = {
@@ -227957,7 +227975,7 @@ query OrderStatus($commitment: String!) {
227957
227975
  initCode: "0x",
227958
227976
  callData,
227959
227977
  accountGasLimits,
227960
- preVerificationGas: 100000n,
227978
+ preVerificationGas: 0n,
227961
227979
  gasFees,
227962
227980
  paymasterAndData: "0x",
227963
227981
  signature: "0x"
@@ -228087,6 +228105,53 @@ query OrderStatus($commitment: String!) {
228087
228105
  inputs
228088
228106
  };
228089
228107
  }
228108
+ /**
228109
+ * Asks the bundler for the `preVerificationGas` of the bid UserOperation that will
228110
+ * actually be signed, with every funding call, approval and signature byte in it.
228111
+ *
228112
+ * On an L2, `preVerificationGas` also pays the L1 data fee for the op's bytes, a fixed
228113
+ * amount of wei that the bundler converts to gas at the price the op pays. A bundler
228114
+ * admits an op priced at its `maxFeePerGas`, but bundles it at the base fee plus its
228115
+ * priority fee, where the same wei costs more gas. An op sized only for admission is
228116
+ * accepted and then skipped in every bundle until it expires. The estimate is taken
228117
+ * at the bundle's price: the latest base fee plus the op's priority fee, capped at its
228118
+ * `maxFeePerGas`.
228119
+ *
228120
+ * The solver account's code is overridden with {@link BID_PVG_ESTIMATION_ACCOUNT_CODE}
228121
+ * for the call, so only the bytes are priced and the fill itself is not simulated.
228122
+ *
228123
+ * @param params - The bid's fields as they will be signed.
228124
+ * @returns The `preVerificationGas` to sign, with {@link BID_PVG_HEADROOM_PERCENT} added.
228125
+ * @throws If no bundler is configured or the bundler rejects the estimate.
228126
+ */
228127
+ async estimateBidPreVerificationGas(params) {
228128
+ const { solverAccount, maxFeePerGas, maxPriorityFeePerGas } = params;
228129
+ const latestBlock = await this.ctx.dest.client.getBlock({ blockTag: "latest" });
228130
+ const baseFeePerGas = latestBlock.baseFeePerGas;
228131
+ const bundlePrice = baseFeePerGas == null || baseFeePerGas + maxPriorityFeePerGas > maxFeePerGas ? maxFeePerGas : baseFeePerGas + maxPriorityFeePerGas;
228132
+ const priorityFee = maxPriorityFeePerGas < bundlePrice ? maxPriorityFeePerGas : bundlePrice;
228133
+ const userOp = {
228134
+ sender: solverAccount,
228135
+ nonce: params.nonce,
228136
+ initCode: "0x",
228137
+ callData: params.callData,
228138
+ accountGasLimits: CryptoUtils.packGasLimits(params.verificationGasLimit, params.callGasLimit),
228139
+ // Bundlers return a non-zero preVerificationGas as given rather than estimating it.
228140
+ preVerificationGas: 0n,
228141
+ gasFees: CryptoUtils.packGasFees(priorityFee, bundlePrice),
228142
+ paymasterAndData: params.paymasterAndData ?? "0x",
228143
+ signature: `0x${"ff".repeat(SELECTED_BID_SIGNATURE_BYTES)}`
228144
+ };
228145
+ const estimate = await this.crypto.sendBundler(
228146
+ BundlerMethod.ETH_ESTIMATE_USER_OPERATION_GAS,
228147
+ [
228148
+ CryptoUtils.prepareBundlerCall(userOp),
228149
+ params.entryPointAddress,
228150
+ { [solverAccount]: { code: BID_PVG_ESTIMATION_ACCOUNT_CODE } }
228151
+ ]
228152
+ );
228153
+ return BigInt(estimate.preVerificationGas) * (100n + BID_PVG_HEADROOM_PERCENT) / 100n;
228154
+ }
228090
228155
  /**
228091
228156
  * Estimates the cross-chain ISMP POST request fee (the relayer fee for the
228092
228157
  * RedeemEscrow message), in both the source and destination fee tokens.
@@ -228139,20 +228204,38 @@ query OrderStatus($commitment: String!) {
228139
228204
  * @returns An object with `viem` and `bundler` state-override collections.
228140
228205
  */
228141
228206
  async buildStateOverride(params) {
228142
- const { accountAddress, chain: chain2, outputAssets, spenderAddress, intentGatewayV2Address, entryPointAddress } = params;
228143
- const testValue = toHex3(maxUint2563 / 2n, { size: 32 });
228207
+ const {
228208
+ accountAddress,
228209
+ chain: chain2,
228210
+ outputAssets,
228211
+ spenderAddress,
228212
+ intentGatewayV2Address,
228213
+ entryPointAddress,
228214
+ escrow
228215
+ } = params;
228216
+ const testValue = toHex3(2n ** 128n, { size: 32 });
228144
228217
  const viemOverrides = [];
228145
228218
  const bundlerOverrides = {};
228146
228219
  if (intentGatewayV2Address) {
228147
228220
  const paramsSlot5 = pad4(toHex3(5n), { size: 32 });
228148
228221
  const dispatcherAddress = this.ctx.dest.configService.getCalldispatcherAddress(chain2);
228149
228222
  const newSlot5Value = "0x" + "0".repeat(22) + "00" + dispatcherAddress.slice(2).toLowerCase();
228223
+ const gatewayDiffs = [{ slot: paramsSlot5, value: newSlot5Value }];
228224
+ for (const [leg, input] of (escrow?.inputs ?? []).entries()) {
228225
+ gatewayDiffs.push({
228226
+ slot: escrowSlot(escrow.commitment, leg),
228227
+ value: toHex3(input.amount, { size: 32 })
228228
+ });
228229
+ }
228230
+ const releasesNative = escrow?.inputs.some((input) => bytes32ToBytes20(input.token) === ADDRESS_ZERO2);
228150
228231
  viemOverrides.push({
228151
228232
  address: intentGatewayV2Address,
228152
- stateDiff: [{ slot: paramsSlot5, value: newSlot5Value }]
228233
+ ...releasesNative ? { balance: 2n ** 128n } : {},
228234
+ stateDiff: gatewayDiffs
228153
228235
  });
228154
228236
  bundlerOverrides[intentGatewayV2Address] = {
228155
- stateDiff: { [paramsSlot5]: newSlot5Value }
228237
+ ...releasesNative ? { balance: testValue } : {},
228238
+ stateDiff: Object.fromEntries(gatewayDiffs.map(({ slot, value }) => [slot, value]))
228156
228239
  };
228157
228240
  }
228158
228241
  if (entryPointAddress) {
@@ -228188,6 +228271,25 @@ query OrderStatus($commitment: String!) {
228188
228271
  bundlerOverrides[result.address] = { stateDiff: result.bundlerStateDiffs };
228189
228272
  }
228190
228273
  }
228274
+ if (intentGatewayV2Address && escrow) {
228275
+ const gatewayBalances = await Promise.all(
228276
+ escrow.inputs.map((input) => this.tokenBalanceSlot(input.token, intentGatewayV2Address, chain2))
228277
+ );
228278
+ for (const override of gatewayBalances) {
228279
+ if (!override) continue;
228280
+ const existing = viemOverrides.find((entry) => entry.address === override.address && entry.stateDiff);
228281
+ if (existing) existing.stateDiff.push({ slot: override.slot, value: testValue });
228282
+ else
228283
+ viemOverrides.push({
228284
+ address: override.address,
228285
+ stateDiff: [{ slot: override.slot, value: testValue }]
228286
+ });
228287
+ bundlerOverrides[override.address] = {
228288
+ ...bundlerOverrides[override.address],
228289
+ stateDiff: { ...bundlerOverrides[override.address]?.stateDiff, [override.slot]: testValue }
228290
+ };
228291
+ }
228292
+ }
228191
228293
  const solverAccountContract = this.ctx.dest.configService.getSolverAccountAddress(chain2);
228192
228294
  if (solverAccountContract) {
228193
228295
  try {
@@ -228210,6 +228312,21 @@ query OrderStatus($commitment: String!) {
228210
228312
  }
228211
228313
  return { viem: viemOverrides, bundler: bundlerOverrides };
228212
228314
  }
228315
+ /**
228316
+ * The balance slot of `holder` in an ERC-20 token, for overriding. `null` for the native
228317
+ * token or when the slot cannot be discovered.
228318
+ */
228319
+ async tokenBalanceSlot(tokenHex, holder, chain2) {
228320
+ const tokenAddress = bytes32ToBytes20(tokenHex);
228321
+ if (tokenAddress === ADDRESS_ZERO2) return null;
228322
+ try {
228323
+ const balanceData = "0x70a08231" + bytes20ToBytes32(holder).slice(2);
228324
+ const slot = await getOrFetchStorageSlot(this.ctx.dest.client, chain2, tokenAddress, balanceData);
228325
+ return slot ? { address: tokenAddress, slot } : null;
228326
+ } catch {
228327
+ return null;
228328
+ }
228329
+ }
228213
228330
  /**
228214
228331
  * Resolves the balance and allowance storage slot overrides for a single
228215
228332
  * ERC-20 token in parallel. Returns `null` for native-ETH tokens or when
@@ -229201,6 +229318,16 @@ query QuotePessimistic($route: RouteInput!, $amountIn: BigInt!) {
229201
229318
  async estimateFillOrder(params) {
229202
229319
  return this.gasEstimator.estimateFillOrder(params);
229203
229320
  }
229321
+ /**
229322
+ * Asks the bundler for the `preVerificationGas` of a bid as it will be signed, priced at
229323
+ * the gas price its bundle pays. Call it with the final calldata and `paymasterAndData`,
229324
+ * before {@link prepareSubmitBid} signs the op.
229325
+ *
229326
+ * Delegates to {@link GasEstimator.estimateBidPreVerificationGas}.
229327
+ */
229328
+ async estimateBidPreVerificationGas(params) {
229329
+ return this.gasEstimator.estimateBidPreVerificationGas(params);
229330
+ }
229204
229331
  /**
229205
229332
  * Quotes the solver fee for an order using the same policy {@link execute} /
229206
229333
  * {@link executeBest} apply when `order.fees` is `0n`.
@@ -329107,20 +329234,32 @@ var ContractInteractionService = class {
329107
329234
  } else {
329108
329235
  this.logger.warn({ reason: pmResult.reason }, "No paymaster for bid UserOp; relying on EntryPoint deposit");
329109
329236
  }
329110
- const userOp = await sdkHelper.prepareSubmitBid({
329111
- order,
329112
- fillOptions,
329237
+ const bidGas = {
329113
329238
  solverAccount: solverAccountAddress,
329114
- solverSigner: sdkSigningAccount(this.signer),
329115
329239
  nonce,
329116
329240
  entryPointAddress,
329117
329241
  callGasLimit,
329118
329242
  verificationGasLimit: cachedEstimate.verificationGasLimit,
329119
- preVerificationGas: cachedEstimate.preVerificationGas,
329120
329243
  maxFeePerGas: cachedEstimate.maxFeePerGas,
329121
329244
  maxPriorityFeePerGas: cachedEstimate.maxPriorityFeePerGas,
329122
329245
  callData,
329123
329246
  paymasterAndData
329247
+ };
329248
+ let preVerificationGas = cachedEstimate.preVerificationGas;
329249
+ try {
329250
+ preVerificationGas = await sdkHelper.estimateBidPreVerificationGas(bidGas);
329251
+ } catch (err) {
329252
+ this.logger.warn(
329253
+ { orderId: order.id, err, preVerificationGas: preVerificationGas.toString() },
329254
+ "Could not estimate the bid's preVerificationGas; using the fill estimate's"
329255
+ );
329256
+ }
329257
+ const userOp = await sdkHelper.prepareSubmitBid({
329258
+ ...bidGas,
329259
+ order,
329260
+ fillOptions,
329261
+ solverSigner: sdkSigningAccount(this.signer),
329262
+ preVerificationGas
329124
329263
  });
329125
329264
  const encodedUserOp = encodeUserOpScale(userOp);
329126
329265
  this.logger.info(
@@ -329129,6 +329268,7 @@ var ContractInteractionService = class {
329129
329268
  solverAccount: solverAccountAddress,
329130
329269
  nonce: nonce.toString(),
329131
329270
  callGasLimit: callGasLimit.toString(),
329271
+ preVerificationGas: preVerificationGas.toString(),
329132
329272
  maxFeePerGas: cachedEstimate.maxFeePerGas.toString()
329133
329273
  },
329134
329274
  "Prepared bid UserOp"
@@ -362910,10 +363050,6 @@ init_asset_registry();
362910
363050
  function limitOrderLegs(order) {
362911
363051
  return order.side === "BID" ? { input: order.base, output: order.quote } : { input: order.quote, output: order.base };
362912
363052
  }
362913
- function availableOn(order) {
362914
- const available = BigInt(order.remaining) - BigInt(order.reserved);
362915
- return available > 0n ? available : 0n;
362916
- }
362917
363053
  function matchLimitOrders(orders, incoming, resolve11, now = /* @__PURE__ */ new Date()) {
362918
363054
  const qualifying = orders.filter((order) => serves(order, incoming, resolve11, now)).map((order) => {
362919
363055
  const offer = offerFor({
@@ -362922,7 +363058,7 @@ function matchLimitOrders(orders, incoming, resolve11, now = /* @__PURE__ */ new
362922
363058
  price: BigInt(order.price),
362923
363059
  outputDecimals: incoming.outputDecimals
362924
363060
  });
362925
- const available = availableOn(order);
363061
+ const available = BigInt(order.remaining);
362926
363062
  return { order, offer, available, payout: offer < available ? offer : available };
362927
363063
  }).filter((candidate) => candidate.offer >= incoming.requestedOutput && candidate.payout > 0n).sort(byBestOfferFirst);
362928
363064
  return qualifying;
@@ -364836,48 +364972,42 @@ async function bootFiller(config5, options) {
364836
364972
  assertPairSymbolsResolve(config5.pairs, assetRegistry, configuredChainNames);
364837
364973
  }
364838
364974
  const adminStrategies = [];
364839
- const strategies = [];
364840
- let confirmationPolicy;
364841
- let tradingPairs;
364842
- let engine;
364843
- if (config5.pairs?.length) {
364844
- tradingPairs = config5.pairs.map((pair) => ({ token0: pair.token0, token1: pair.token1 }));
364845
- tradingPairs.forEach((pair, pairIndex) => {
364846
- adminStrategies.push({
364847
- index: pairIndex,
364848
- pairIndex,
364849
- exotic: `${pair.token0}/${pair.token1}`,
364850
- token0: pair.token0,
364851
- token1: pair.token1,
364852
- sameToken: normalizeSymbol(pair.token0) === normalizeSymbol(pair.token1)
364853
- });
364975
+ const tradingPairs = (config5.pairs ?? []).map((pair) => ({
364976
+ token0: pair.token0,
364977
+ token1: pair.token1
364978
+ }));
364979
+ tradingPairs.forEach((pair, pairIndex) => {
364980
+ adminStrategies.push({
364981
+ index: pairIndex,
364982
+ pairIndex,
364983
+ exotic: `${pair.token0}/${pair.token1}`,
364984
+ token0: pair.token0,
364985
+ token1: pair.token1,
364986
+ sameToken: normalizeSymbol(pair.token0) === normalizeSymbol(pair.token1)
364854
364987
  });
364855
- confirmationPolicy = assertConfirmationCoverage(
364856
- config5.confirmationPolicies,
364857
- resolvedChains.map((c6) => c6.chainId)
364858
- );
364859
- const fundingVenues = vaultVenue ? [vaultVenue] : [];
364860
- engine = new FXFiller(
364861
- runtimeSigner,
364862
- configService,
364863
- chainClientManager,
364864
- contractService,
364865
- tradingPairs,
364866
- assetRegistry,
364867
- { confirmationPolicy, fundingVenues, limitOrders: options.data.limitOrders }
364868
- );
364869
- logger8.info("Hydrating funding venue state...");
364870
- await engine.initialise();
364871
- strategies.push(engine);
364872
- }
364988
+ });
364989
+ const confirmationPolicy = assertConfirmationCoverage(
364990
+ config5.confirmationPolicies,
364991
+ resolvedChains.map((c6) => c6.chainId)
364992
+ );
364993
+ const fundingVenues = vaultVenue ? [vaultVenue] : [];
364994
+ const engine = new FXFiller(
364995
+ runtimeSigner,
364996
+ configService,
364997
+ chainClientManager,
364998
+ contractService,
364999
+ tradingPairs,
365000
+ assetRegistry,
365001
+ { confirmationPolicy, fundingVenues, limitOrders: options.data.limitOrders }
365002
+ );
365003
+ logger8.info("Hydrating funding venue state...");
365004
+ await engine.initialise();
365005
+ const strategies = [engine];
364873
365006
  const haltControls = strategies.map((engine2, index3) => ({
364874
365007
  index: index3,
364875
365008
  isHalted: () => engine2.isHalted(),
364876
365009
  resetHalt: () => engine2.resetHalt()
364877
365010
  }));
364878
- if (vaultVenue) {
364879
- await vaultVenue.initialise(runtimeSigner.address);
364880
- }
364881
365011
  let rebalancingService;
364882
365012
  const rebalancingConfig = configService.getRebalancingConfig();
364883
365013
  if (rebalancingConfig?.triggerPercentage !== void 0 && rebalancingConfig?.baseBalances) {
@@ -365403,8 +365533,8 @@ var MemoryLimitOrderStore = class {
365403
365533
  async reserve(id2, amount) {
365404
365534
  const order = this.orders.get(id2);
365405
365535
  if (!order || order.status !== "open") return false;
365536
+ if (BigInt(amount) > BigInt(order.remaining)) return false;
365406
365537
  const reserved = BigInt(order.reserved) + BigInt(amount);
365407
- if (reserved > BigInt(order.remaining)) return false;
365408
365538
  this.patch(id2, { reserved: reserved.toString() });
365409
365539
  return true;
365410
365540
  }
@@ -366163,10 +366293,7 @@ var PairController = class {
366163
366293
  * the pair's symbols have to resolve before the market can be hydrated.
366164
366294
  */
366165
366295
  async add(pair, options) {
366166
- const { engine, tradingPairs, assetRegistry, adminStrategies, balanceTokens, config: config5 } = this.runtime;
366167
- if (!engine || !tradingPairs) {
366168
- throw new Error("No trading engine is running \u2014 this filler was started without pairs");
366169
- }
366296
+ const { engine, assetRegistry, adminStrategies, balanceTokens, config: config5 } = this.runtime;
366170
366297
  const assets = options?.assets;
366171
366298
  const nextAssets = { ...config5.assets ?? {}, ...assets ?? {} };
366172
366299
  const nextPairs = [...this.pairs, pair];
@@ -366205,7 +366332,6 @@ var PairController = class {
366205
366332
  /** Closes a market. Orders already in flight against it still complete. */
366206
366333
  async remove(index3) {
366207
366334
  const { engine, tradingPairs, adminStrategies, config: config5 } = this.runtime;
366208
- if (!engine || !tradingPairs) throw new Error("No trading engine is running");
366209
366335
  if (index3 < 0 || index3 >= this.pairs.length) throw new Error(`Unknown pair ${index3}`);
366210
366336
  engine.removePair(tradingPairs[index3]);
366211
366337
  config5.pairs = this.pairs.filter((_5, i6) => i6 !== index3);
@@ -366217,7 +366343,7 @@ var PairController = class {
366217
366343
  await this.persist();
366218
366344
  }
366219
366345
  livePair(index3) {
366220
- const pair = this.runtime.tradingPairs?.[index3];
366346
+ const pair = this.runtime.tradingPairs[index3];
366221
366347
  if (!pair) throw new Error(`Unknown pair ${index3}`);
366222
366348
  return pair;
366223
366349
  }
@@ -366309,9 +366435,9 @@ var ChainController = class {
366309
366435
  throw error;
366310
366436
  }
366311
366437
  const curve = confirmationPolicies[String(chainId)];
366312
- if (curve) this.runtime.confirmationPolicy?.add(chainId, curve);
366313
- else if (!this.runtime.confirmationPolicy?.has(chainId)) {
366314
- this.runtime.confirmationPolicy?.adopt(chainId, resolvedPolicy);
366438
+ if (curve) this.runtime.confirmationPolicy.add(chainId, curve);
366439
+ else if (!this.runtime.confirmationPolicy.has(chainId)) {
366440
+ this.runtime.confirmationPolicy.adopt(chainId, resolvedPolicy);
366315
366441
  }
366316
366442
  this.runtime.resolvedChains.push(resolved);
366317
366443
  config5.chains = [...config5.chains, { rpcUrls: chain2.rpcUrls, bundlerUrl: chain2.bundlerUrl }];
@@ -366339,7 +366465,7 @@ var ChainController = class {
366339
366465
  await intentFiller.removeChain(chainId);
366340
366466
  if (this.ownsScanner) await this.scanner.removeChain(chainId);
366341
366467
  configService.removeChain(chainId);
366342
- this.runtime.confirmationPolicy?.remove(chainId);
366468
+ this.runtime.confirmationPolicy.remove(chainId);
366343
366469
  this.runtime.chainClientManager.invalidate(chainKey);
366344
366470
  this.runtime.resolvedChains.splice(index3, 1);
366345
366471
  config5.chains = config5.chains.filter((_5, i6) => i6 !== index3);
@@ -367375,8 +367501,8 @@ var SqliteLimitOrderStore = class {
367375
367501
  async reserve(id2, amount) {
367376
367502
  const order = this.read(id2);
367377
367503
  if (!order || order.status !== "open") return false;
367504
+ if (BigInt(amount) > BigInt(order.remaining)) return false;
367378
367505
  const reserved = BigInt(order.reserved) + BigInt(amount);
367379
- if (reserved > BigInt(order.remaining)) return false;
367380
367506
  const result = this.db.prepare(`
367381
367507
  UPDATE limit_orders SET reserved = ?, updated_at = datetime('now')
367382
367508
  WHERE id = ? AND reserved = ? AND status = 'open'