@whetstone-research/doppler-sdk 1.0.26 → 1.0.28

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.
@@ -404,23 +404,23 @@ var DEFAULT_OPENING_DOPPLER_NUM_PD_SLUGS = DEFAULT_PD_SLUGS;
404
404
  var DEFAULT_OPENING_DOPPLER_FEE = FEE_TIERS.HIGH;
405
405
  var DEFAULT_OPENING_DOPPLER_TICK_SPACING = DOPPLER_MAX_TICK_SPACING;
406
406
  var DEFAULT_MULTICURVE_LOWER_TICKS = [
407
- -202100,
408
- -183100,
409
- -167e3
407
+ -887200,
408
+ -222200,
409
+ -176200
410
410
  ];
411
411
  var DEFAULT_MULTICURVE_UPPER_TICKS = [
412
- -188200,
413
- -172100,
414
- -156e3
412
+ -142200,
413
+ -116300,
414
+ -84100
415
415
  ];
416
416
  var DEFAULT_MULTICURVE_NUM_POSITIONS = [11, 11, 11];
417
417
  var DEFAULT_MULTICURVE_MAX_SUPPLY_SHARES = [
418
- viem.parseEther("0.05"),
419
- // 5% for LOW tier
420
- viem.parseEther("0.125"),
421
- // 12.5% for MEDIUM tier
422
- viem.parseEther("0.2")
423
- // 20% for HIGH tier
418
+ viem.parseEther("0.5"),
419
+ // 50% for LOW tier
420
+ viem.parseEther("0.25"),
421
+ // 25% for MEDIUM tier
422
+ viem.parseEther("0.24")
423
+ // 24% for HIGH tier
424
424
  ];
425
425
  var BASIS_POINTS = 1e4;
426
426
  var FLAG_MASK = BigInt(16383);
@@ -464,7 +464,7 @@ var CHAIN_IDS = {
464
464
  BASE: 8453,
465
465
  BASE_SEPOLIA: 84532,
466
466
  INK: 57073,
467
- TEMP: 4663,
467
+ ROBINHOOD: 4663,
468
468
  UNICHAIN: 130,
469
469
  UNICHAIN_SEPOLIA: 1301,
470
470
  MONAD_TESTNET: 10143,
@@ -736,48 +736,50 @@ var ADDRESSES = {
736
736
  weth: "0x4200000000000000000000000000000000000006",
737
737
  uniswapV4Quoter: "0x3972c00f7ed4885e145823eb7c655375d275a1c5"
738
738
  },
739
- [CHAIN_IDS.TEMP]: {
740
- airlock: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].Airlock,
739
+ [CHAIN_IDS.ROBINHOOD]: {
740
+ airlock: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].Airlock,
741
741
  tokenFactory: ZERO_ADDRESS,
742
742
  dopplerERC20V1Factory: getGeneratedAddress(
743
- CHAIN_IDS.TEMP,
743
+ CHAIN_IDS.ROBINHOOD,
744
744
  "DopplerERC20V1Factory"
745
745
  ),
746
746
  dopplerERC20V1Implementation: getGeneratedAddress(
747
- CHAIN_IDS.TEMP,
747
+ CHAIN_IDS.ROBINHOOD,
748
748
  "DopplerERC20V1"
749
749
  ),
750
- doppler404Factory: getGeneratedAddress(CHAIN_IDS.TEMP, "DN404Factory"),
750
+ doppler404Factory: getGeneratedAddress(CHAIN_IDS.ROBINHOOD, "DN404Factory"),
751
751
  v3Initializer: ZERO_ADDRESS,
752
752
  v3Quoter: "0x33e885ed0ec9bf04ecfb19341582aadcb4c8a9e7",
753
- lockableV3Initializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].LockableUniswapV3Initializer,
754
- v4Initializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].UniswapV4Initializer,
755
- dopplerHookInitializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].DopplerHookInitializer,
753
+ lockableV3Initializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].LockableUniswapV3Initializer,
754
+ v4Initializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].UniswapV4Initializer,
755
+ dopplerHookInitializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].DopplerHookInitializer,
756
756
  rehypeDopplerHookInitializer: getRehypeDopplerHookInitializerAddress(
757
- CHAIN_IDS.TEMP
757
+ CHAIN_IDS.ROBINHOOD
758
758
  ),
759
- rehypeDopplerHook: getRehypeDopplerHookInitializerAddress(CHAIN_IDS.TEMP),
760
- dopplerLens: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].DopplerLensQuoter,
761
- dopplerDeployer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].DopplerDeployer,
759
+ rehypeDopplerHook: getRehypeDopplerHookInitializerAddress(
760
+ CHAIN_IDS.ROBINHOOD
761
+ ),
762
+ dopplerLens: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].DopplerLensQuoter,
763
+ dopplerDeployer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].DopplerDeployer,
762
764
  poolManager: "0x8366a39cc670b4001a1121b8f6a443a643e40951",
763
765
  v2Migrator: ZERO_ADDRESS,
764
- v2MigratorSplit: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].UniswapV2MigratorSplit,
766
+ v2MigratorSplit: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].UniswapV2MigratorSplit,
765
767
  v4Migrator: ZERO_ADDRESS,
766
- dopplerHookMigrator: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].DopplerHookMigrator,
767
- rehypeDopplerHookMigrator: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].RehypeDopplerHookMigrator,
768
- noOpMigrator: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].NoOpMigrator,
769
- governanceFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].GovernanceFactory,
770
- noOpGovernanceFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].NoOpGovernanceFactory,
771
- launchpadGovernanceFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].LaunchpadGovernanceFactory,
768
+ dopplerHookMigrator: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].DopplerHookMigrator,
769
+ rehypeDopplerHookMigrator: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].RehypeDopplerHookMigrator,
770
+ noOpMigrator: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].NoOpMigrator,
771
+ governanceFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].GovernanceFactory,
772
+ noOpGovernanceFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].NoOpGovernanceFactory,
773
+ launchpadGovernanceFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].LaunchpadGovernanceFactory,
772
774
  streamableFeesLocker: ZERO_ADDRESS,
773
775
  streamableFeesLockerV2: getGeneratedAddress(
774
- CHAIN_IDS.TEMP,
776
+ CHAIN_IDS.ROBINHOOD,
775
777
  "StreamableFeesLockerV2"
776
778
  ),
777
- topUpDistributor: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].TopUpDistributor,
779
+ topUpDistributor: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].TopUpDistributor,
778
780
  universalRouter: "0x8876789976decbfcbbbe364623c63652db8c0904",
779
781
  permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
780
- bundler: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].Bundler,
782
+ bundler: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].Bundler,
781
783
  weth: "0x0bd7d308f8e1639fab988df18a8011f41eacad73",
782
784
  uniswapV2Factory: "0x8bceaa40b9acdfaedf85adf4ff01f5ad6517937f",
783
785
  uniswapV3Factory: "0x1f7d7550b1b028f7571e69a784071f0205fd2efa",
@@ -6675,6 +6677,92 @@ function getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1) {
6675
6677
  return amount1 * Q96 / diff;
6676
6678
  }
6677
6679
 
6680
+ // src/evm/utils/multicurveLiquidity.ts
6681
+ var MAX_UINT128 = (1n << 128n) - 1n;
6682
+ function getMaxLiquiditySafeMulticurveTickUpper(params) {
6683
+ if (params.tickUpper <= params.tickLower) {
6684
+ throw new Error(
6685
+ `Unable to find a uint128-safe multicurve max tick below ${params.tickUpper}`
6686
+ );
6687
+ }
6688
+ if (isCanonicalCurveLiquiditySafe(params)) return params.tickUpper;
6689
+ for (let candidate = params.tickUpper - params.tickSpacing; candidate > params.tickLower; candidate -= params.tickSpacing) {
6690
+ if (isCanonicalCurveLiquiditySafe({ ...params, tickUpper: candidate })) {
6691
+ return candidate;
6692
+ }
6693
+ }
6694
+ throw new Error(
6695
+ `Unable to find a uint128-safe multicurve max tick below ${params.tickUpper}`
6696
+ );
6697
+ }
6698
+ function isCanonicalCurveLiquiditySafe(params) {
6699
+ return isAdjustedCurveLiquiditySafe({
6700
+ ...params,
6701
+ isToken0: true
6702
+ }) && isAdjustedCurveLiquiditySafe({
6703
+ ...params,
6704
+ tickLower: -params.tickUpper,
6705
+ tickUpper: -params.tickLower,
6706
+ isToken0: false
6707
+ });
6708
+ }
6709
+ function isAdjustedCurveLiquiditySafe(params) {
6710
+ if (params.numPositions <= 0 || params.tickSpacing <= 0) {
6711
+ throw new Error("Multicurve positions and tick spacing must be positive");
6712
+ }
6713
+ const amountPerPosition = params.curveSupply / BigInt(params.numPositions);
6714
+ if (amountPerPosition <= 1n) return true;
6715
+ const amount = amountPerPosition - 1n;
6716
+ const maxLiquidityPerTick = getMaxLiquidityPerTick(params.tickSpacing);
6717
+ const liquidityByTick = /* @__PURE__ */ new Map();
6718
+ const farTick = params.isToken0 ? params.tickUpper : params.tickLower;
6719
+ const closeTick = params.isToken0 ? params.tickLower : params.tickUpper;
6720
+ const spread = params.tickUpper - params.tickLower;
6721
+ const farSqrtPriceX96 = getSqrtRatioAtTick(farTick);
6722
+ for (let i = 0; i < params.numPositions; i++) {
6723
+ const tickDelta = Number(
6724
+ BigInt(i) * BigInt(spread) / BigInt(params.numPositions)
6725
+ );
6726
+ const unalignedTick = params.isToken0 ? closeTick + tickDelta : closeTick - tickDelta;
6727
+ const startingTick = alignMulticurveTick(
6728
+ params.isToken0,
6729
+ unalignedTick,
6730
+ params.tickSpacing
6731
+ );
6732
+ if (startingTick === farTick) continue;
6733
+ const startingSqrtPriceX96 = getSqrtRatioAtTick(startingTick);
6734
+ const liquidity = params.isToken0 ? getLiquidityForAmount0(startingSqrtPriceX96, farSqrtPriceX96, amount) : getLiquidityForAmount1(farSqrtPriceX96, startingSqrtPriceX96, amount);
6735
+ if (liquidity > maxLiquidityPerTick) return false;
6736
+ const tickA = Math.min(farTick, startingTick);
6737
+ const tickB = Math.max(farTick, startingTick);
6738
+ if (!addTickLiquidity(liquidityByTick, tickA, liquidity, maxLiquidityPerTick)) {
6739
+ return false;
6740
+ }
6741
+ if (!addTickLiquidity(liquidityByTick, tickB, liquidity, maxLiquidityPerTick)) {
6742
+ return false;
6743
+ }
6744
+ }
6745
+ return true;
6746
+ }
6747
+ function getMaxLiquidityPerTick(tickSpacing) {
6748
+ const minTick = Math.trunc(MIN_TICK / tickSpacing) * tickSpacing;
6749
+ const maxTick = Math.trunc(MAX_TICK / tickSpacing) * tickSpacing;
6750
+ const numTicks = BigInt((maxTick - minTick) / tickSpacing + 1);
6751
+ return MAX_UINT128 / numTicks;
6752
+ }
6753
+ function addTickLiquidity(liquidityByTick, tick, liquidity, maxLiquidityPerTick) {
6754
+ const updatedLiquidity = (liquidityByTick.get(tick) ?? 0n) + liquidity;
6755
+ if (updatedLiquidity > maxLiquidityPerTick) return false;
6756
+ liquidityByTick.set(tick, updatedLiquidity);
6757
+ return true;
6758
+ }
6759
+ function alignMulticurveTick(isToken0, tick, tickSpacing) {
6760
+ if (isToken0) {
6761
+ return tick < 0 ? Math.trunc((tick - tickSpacing + 1) / tickSpacing) * tickSpacing : Math.trunc(tick / tickSpacing) * tickSpacing;
6762
+ }
6763
+ return tick < 0 ? Math.trunc(tick / tickSpacing) * tickSpacing : Math.trunc((tick + tickSpacing - 1) / tickSpacing) * tickSpacing;
6764
+ }
6765
+
6678
6766
  // src/evm/utils/computeOptimalGamma.ts
6679
6767
  function computeOptimalGamma(startTick, endTick, duration, epochLength, tickSpacing) {
6680
6768
  const totalEpochs = duration / epochLength;
@@ -6691,11 +6779,14 @@ function computeOptimalGamma(startTick, endTick, duration, epochLength, tickSpac
6691
6779
 
6692
6780
  // src/evm/utils/gasEstimate.ts
6693
6781
  async function resolveGasEstimate(request, fallback) {
6694
- if (typeof request?.gas === "bigint") {
6782
+ if (isGasEstimateRequest(request)) {
6695
6783
  return request.gas;
6696
6784
  }
6697
6785
  return await fallback();
6698
6786
  }
6787
+ function isGasEstimateRequest(request) {
6788
+ return typeof request === "object" && request !== null && "gas" in request && typeof request.gas === "bigint";
6789
+ }
6699
6790
 
6700
6791
  // src/evm/utils/isToken0Expected.ts
6701
6792
  function isToken0Expected(numeraire) {
@@ -6710,6 +6801,23 @@ function isToken0Expected(numeraire) {
6710
6801
  }
6711
6802
  }
6712
6803
 
6804
+ // src/evm/utils/beneficiaries.ts
6805
+ function sortBeneficiaries(beneficiaries) {
6806
+ const sorted = [...beneficiaries].sort((a, b) => {
6807
+ const aAddr = a.beneficiary.toLowerCase();
6808
+ const bAddr = b.beneficiary.toLowerCase();
6809
+ return aAddr < bAddr ? -1 : aAddr > bAddr ? 1 : 0;
6810
+ });
6811
+ for (let i = 1; i < sorted.length; i++) {
6812
+ if (sorted[i].beneficiary.toLowerCase() === sorted[i - 1].beneficiary.toLowerCase()) {
6813
+ throw new Error(
6814
+ `Duplicate beneficiary address: ${sorted[i].beneficiary}. Each beneficiary address must be unique \u2014 the contract requires strictly ascending addresses and reverts with UnorderedBeneficiaries() otherwise. Merge the entries into a single beneficiary with the combined shares.`
6815
+ );
6816
+ }
6817
+ }
6818
+ return sorted;
6819
+ }
6820
+
6713
6821
  // src/evm/types.ts
6714
6822
  var NO_OP_ENABLED_CHAIN_IDS = [
6715
6823
  CHAIN_IDS.MAINNET,
@@ -6718,7 +6826,7 @@ var NO_OP_ENABLED_CHAIN_IDS = [
6718
6826
  CHAIN_IDS.BASE_SEPOLIA,
6719
6827
  CHAIN_IDS.UNICHAIN,
6720
6828
  CHAIN_IDS.UNICHAIN_SEPOLIA,
6721
- CHAIN_IDS.TEMP,
6829
+ CHAIN_IDS.ROBINHOOD,
6722
6830
  CHAIN_IDS.MONAD_TESTNET,
6723
6831
  CHAIN_IDS.MONAD_MAINNET
6724
6832
  ];
@@ -6729,7 +6837,7 @@ var LAUNCHPAD_ENABLED_CHAIN_IDS = [
6729
6837
  CHAIN_IDS.MAINNET,
6730
6838
  CHAIN_IDS.BASE,
6731
6839
  CHAIN_IDS.BASE_SEPOLIA,
6732
- CHAIN_IDS.TEMP,
6840
+ CHAIN_IDS.ROBINHOOD,
6733
6841
  CHAIN_IDS.MONAD_MAINNET
6734
6842
  ];
6735
6843
  function isLaunchpadEnabledChain(chainId) {
@@ -7314,7 +7422,7 @@ function buildCurvesFromPresets(params) {
7314
7422
  }
7315
7423
 
7316
7424
  // src/evm/entities/DopplerFactory.ts
7317
- var MAX_UINT128 = (1n << 128n) - 1n;
7425
+ var MAX_UINT1282 = (1n << 128n) - 1n;
7318
7426
  var MAX_PROCEEDS_SPLIT_SHARE = WAD / 2n;
7319
7427
  var DERC20_V1_MAX_PREMINT_WAD = WAD * 8n / 10n;
7320
7428
  var ONE_MILLION = 1000000n;
@@ -8010,11 +8118,7 @@ var DopplerFactory = class {
8010
8118
  const hasBeneficiaries = params.pool.beneficiaries && params.pool.beneficiaries.length > 0;
8011
8119
  let poolInitializerData;
8012
8120
  if (hasBeneficiaries) {
8013
- const sortedBeneficiaries = params.pool.beneficiaries.slice().sort((a, b) => {
8014
- const aAddr = a.beneficiary.toLowerCase();
8015
- const bAddr = b.beneficiary.toLowerCase();
8016
- return aAddr < bAddr ? -1 : aAddr > bAddr ? 1 : 0;
8017
- });
8121
+ const sortedBeneficiaries = sortBeneficiaries(params.pool.beneficiaries);
8018
8122
  poolInitializerData = viem.encodeAbiParameters(
8019
8123
  [
8020
8124
  {
@@ -8094,14 +8198,20 @@ var DopplerFactory = class {
8094
8198
  const poolInitializerAddress = (() => {
8095
8199
  if (hasBeneficiaries) {
8096
8200
  const lockableInitializer = params.modules?.lockableV3Initializer ?? addresses.lockableV3Initializer;
8097
- if (!lockableInitializer) {
8201
+ if (!lockableInitializer || lockableInitializer === ZERO_ADDRESS) {
8098
8202
  throw new Error(
8099
8203
  "Lockable V3 initializer address not configured on this chain. Required when using beneficiaries."
8100
8204
  );
8101
8205
  }
8102
8206
  return lockableInitializer;
8103
8207
  }
8104
- return params.modules?.v3Initializer ?? addresses.v3Initializer;
8208
+ const standardInitializer = params.modules?.v3Initializer ?? addresses.v3Initializer;
8209
+ if (!standardInitializer || standardInitializer === ZERO_ADDRESS) {
8210
+ throw new Error(
8211
+ "UniswapV3Initializer address not configured on this chain. Use beneficiaries for lockable V3 support, provide an override via builder.withV3Initializer(...), or use a chain with standard V3 initializer support."
8212
+ );
8213
+ }
8214
+ return standardInitializer;
8105
8215
  })();
8106
8216
  const liquidityMigratorAddress = this.getMigratorAddress(
8107
8217
  params.migration,
@@ -8516,6 +8626,11 @@ var DopplerFactory = class {
8516
8626
  addresses
8517
8627
  });
8518
8628
  const poolInitializerAddress = params.modules?.v4Initializer ?? addresses.v4Initializer;
8629
+ if (!poolInitializerAddress || poolInitializerAddress === ZERO_ADDRESS) {
8630
+ throw new Error(
8631
+ "UniswapV4Initializer address not configured on this chain. Provide an override via builder.withV4Initializer(...) or use a chain with dynamic auction support."
8632
+ );
8633
+ }
8519
8634
  const liquidityMigratorAddress = this.getMigratorAddress(
8520
8635
  params.migration,
8521
8636
  params.modules
@@ -9846,13 +9961,7 @@ var DopplerFactory = class {
9846
9961
  if (!streamableFees) {
9847
9962
  return "0x";
9848
9963
  }
9849
- const beneficiaryData = [...streamableFees.beneficiaries].sort(
9850
- (a, b) => {
9851
- const addrA = a.beneficiary.toLowerCase();
9852
- const addrB = b.beneficiary.toLowerCase();
9853
- return addrA < addrB ? -1 : addrA > addrB ? 1 : 0;
9854
- }
9855
- );
9964
+ const beneficiaryData = sortBeneficiaries(streamableFees.beneficiaries);
9856
9965
  return viem.encodeAbiParameters(
9857
9966
  [
9858
9967
  { type: "uint24" },
@@ -9877,12 +9986,8 @@ var DopplerFactory = class {
9877
9986
  ]
9878
9987
  );
9879
9988
  case "uniswapV4Split": {
9880
- const beneficiaryData2 = [...config.streamableFees.beneficiaries].sort(
9881
- (a, b) => {
9882
- const addrA = a.beneficiary.toLowerCase();
9883
- const addrB = b.beneficiary.toLowerCase();
9884
- return addrA < addrB ? -1 : addrA > addrB ? 1 : 0;
9885
- }
9989
+ const beneficiaryData2 = sortBeneficiaries(
9990
+ config.streamableFees.beneficiaries
9886
9991
  );
9887
9992
  const proceedsRecipient = config.proceedsSplit?.recipient ?? ZERO_ADDRESS;
9888
9993
  const proceedsShare = config.proceedsSplit?.share ?? 0n;
@@ -9918,12 +10023,8 @@ var DopplerFactory = class {
9918
10023
  "dopplerHook migration cannot set both hook and rehype config. Use exactly one hook mode."
9919
10024
  );
9920
10025
  }
9921
- const beneficiaries = [...dopplerHookConfig.beneficiaries].sort(
9922
- (a, b) => {
9923
- const addrA = a.beneficiary.toLowerCase();
9924
- const addrB = b.beneficiary.toLowerCase();
9925
- return addrA < addrB ? -1 : addrA > addrB ? 1 : 0;
9926
- }
10026
+ const beneficiaries = sortBeneficiaries(
10027
+ dopplerHookConfig.beneficiaries
9927
10028
  );
9928
10029
  let dopplerHookAddress = ZERO_ADDRESS;
9929
10030
  let onInitializationCalldata = "0x";
@@ -10326,15 +10427,12 @@ var DopplerFactory = class {
10326
10427
  }
10327
10428
  const normalizedCurves = this.normalizeMulticurveCurves(
10328
10429
  params.pool.curves,
10329
- params.pool.tickSpacing
10430
+ params.pool.tickSpacing,
10431
+ params.sale.numTokensToSell
10330
10432
  );
10331
10433
  const addresses = getAddresses(this.chainId);
10332
- const sortedBeneficiaries = (params.pool.beneficiaries ?? []).slice().sort(
10333
- (a, b) => {
10334
- const aAddr = a.beneficiary.toLowerCase();
10335
- const bAddr = b.beneficiary.toLowerCase();
10336
- return aAddr < bAddr ? -1 : aAddr > bAddr ? 1 : 0;
10337
- }
10434
+ const sortedBeneficiaries = sortBeneficiaries(
10435
+ params.pool.beneficiaries ?? []
10338
10436
  );
10339
10437
  const initializerMode = this.resolveMulticurveInitializerMode(params);
10340
10438
  const useScheduledInitializer = initializerMode.type === "scheduled";
@@ -10809,7 +10907,7 @@ var DopplerFactory = class {
10809
10907
  /**
10810
10908
  * Normalize user-provided multicurve positions and ensure they satisfy SDK constraints
10811
10909
  */
10812
- normalizeMulticurveCurves(curves, tickSpacing) {
10910
+ normalizeMulticurveCurves(curves, tickSpacing, numTokensToSell) {
10813
10911
  if (tickSpacing <= 0) {
10814
10912
  throw new Error("Tick spacing must be positive");
10815
10913
  }
@@ -10856,25 +10954,19 @@ var DopplerFactory = class {
10856
10954
  if (fallbackTickLower === void 0) {
10857
10955
  throw new Error("Unable to determine fallback multicurve tick range");
10858
10956
  }
10859
- const fallbackTickUpper = this.roundMaxTickDown(tickSpacing);
10860
- if (fallbackTickLower >= fallbackTickUpper) {
10861
- const adjustedLower = fallbackTickUpper - tickSpacing;
10862
- if (adjustedLower < fallbackTickLower) {
10863
- return sanitizedCurves;
10864
- }
10865
- const fallbackCurve2 = {
10866
- tickLower: adjustedLower,
10867
- tickUpper: fallbackTickUpper,
10868
- numPositions: sanitizedCurves[sanitizedCurves.length - 1]?.numPositions ?? 1,
10869
- shares: missingShare
10870
- };
10871
- return [...sanitizedCurves, fallbackCurve2];
10872
- }
10957
+ const fallbackNumPositions = sanitizedCurves[sanitizedCurves.length - 1]?.numPositions ?? 1;
10958
+ const fallbackTickUpper = getMaxLiquiditySafeMulticurveTickUpper({
10959
+ tickLower: fallbackTickLower,
10960
+ tickUpper: this.roundMaxTickDown(tickSpacing),
10961
+ tickSpacing,
10962
+ numPositions: fallbackNumPositions,
10963
+ curveSupply: numTokensToSell * missingShare / WAD
10964
+ });
10873
10965
  const fallbackCurve = {
10874
10966
  // Extend from the most positive user tick out to the maximum supported tick bucket
10875
10967
  tickLower: fallbackTickLower,
10876
10968
  tickUpper: fallbackTickUpper,
10877
- numPositions: sanitizedCurves[sanitizedCurves.length - 1]?.numPositions ?? 1,
10969
+ numPositions: fallbackNumPositions,
10878
10970
  shares: missingShare
10879
10971
  };
10880
10972
  return [...sanitizedCurves, fallbackCurve];
@@ -11394,8 +11486,15 @@ var DopplerFactory = class {
11394
11486
  getMigratorAddress(config, overrides) {
11395
11487
  const addresses = getAddresses(this.chainId);
11396
11488
  switch (config.type) {
11397
- case "uniswapV2":
11398
- return overrides?.v2Migrator ?? addresses.v2Migrator;
11489
+ case "uniswapV2": {
11490
+ const v2Address = overrides?.v2Migrator ?? addresses.v2Migrator;
11491
+ if (!v2Address || v2Address === ZERO_ADDRESS) {
11492
+ throw new Error(
11493
+ "UniswapV2Migrator not deployed on this chain. Use uniswapV2Split migration or provide override via modules.v2Migrator."
11494
+ );
11495
+ }
11496
+ return v2Address;
11497
+ }
11399
11498
  case "uniswapV2Split": {
11400
11499
  const v2SplitAddress = overrides?.v2MigratorSplit ?? addresses.v2MigratorSplit;
11401
11500
  if (!v2SplitAddress || v2SplitAddress === ZERO_ADDRESS) {
@@ -11407,7 +11506,7 @@ var DopplerFactory = class {
11407
11506
  }
11408
11507
  case "uniswapV4": {
11409
11508
  const v4Address = overrides?.v4Migrator ?? addresses.v4Migrator;
11410
- if (v4Address === "0x0000000000000000000000000000000000000000") {
11509
+ if (!v4Address || v4Address === ZERO_ADDRESS) {
11411
11510
  throw new Error(
11412
11511
  "UniswapV4Migrator not deployed on this chain. Use uniswapV2 migration or provide override via modules.v4Migrator."
11413
11512
  );
@@ -11573,7 +11672,7 @@ var DopplerFactory = class {
11573
11672
  if (!allowZero && value === 0n) {
11574
11673
  throw new Error(`${paramName} must be greater than zero`);
11575
11674
  }
11576
- if (value > MAX_UINT128) {
11675
+ if (value > MAX_UINT1282) {
11577
11676
  throw new Error(`${paramName} exceeds uint128 range`);
11578
11677
  }
11579
11678
  }
@@ -12032,6 +12131,214 @@ var DopplerFactory = class {
12032
12131
  }
12033
12132
  };
12034
12133
  var MULTICURVE_BUNDLER_SELECTORS = ["0xe2e9faa1", "0x07087b06"];
12134
+ function parseAirlockPoolOrHook(rawAssetData, context = "Airlock getAssetData") {
12135
+ const rawPoolOrHook = readContractResultField(
12136
+ rawAssetData,
12137
+ ["poolOrHook", "pool"],
12138
+ 5,
12139
+ context
12140
+ );
12141
+ return parseAddress(rawPoolOrHook, context, "poolOrHook");
12142
+ }
12143
+ function parseAirlockLiquidityMigrator(rawAssetData, context = "Airlock getAssetData") {
12144
+ const rawLiquidityMigrator = readContractResultField(
12145
+ rawAssetData,
12146
+ ["liquidityMigrator"],
12147
+ 3,
12148
+ context
12149
+ );
12150
+ return parseAddress(rawLiquidityMigrator, context, "liquidityMigrator");
12151
+ }
12152
+ function normalizeDynamicHookState(rawState, context = "DopplerHook state") {
12153
+ return {
12154
+ totalTokensSold: parseBigIntField(rawState, "totalTokensSold", 2, context),
12155
+ totalProceeds: parseBigIntField(rawState, "totalProceeds", 3, context)
12156
+ };
12157
+ }
12158
+ function normalizeRehypeFeeDistributionInfo(rawInfo, context = "Rehype getFeeDistributionInfo") {
12159
+ return {
12160
+ assetFeesToAssetBuybackWad: parseBigIntField(
12161
+ rawInfo,
12162
+ "assetFeesToAssetBuybackWad",
12163
+ 0,
12164
+ context
12165
+ ),
12166
+ assetFeesToNumeraireBuybackWad: parseBigIntField(
12167
+ rawInfo,
12168
+ "assetFeesToNumeraireBuybackWad",
12169
+ 1,
12170
+ context
12171
+ ),
12172
+ assetFeesToBeneficiaryWad: parseBigIntField(
12173
+ rawInfo,
12174
+ "assetFeesToBeneficiaryWad",
12175
+ 2,
12176
+ context
12177
+ ),
12178
+ assetFeesToLpWad: parseBigIntField(rawInfo, "assetFeesToLpWad", 3, context),
12179
+ numeraireFeesToAssetBuybackWad: parseBigIntField(
12180
+ rawInfo,
12181
+ "numeraireFeesToAssetBuybackWad",
12182
+ 4,
12183
+ context
12184
+ ),
12185
+ numeraireFeesToNumeraireBuybackWad: parseBigIntField(
12186
+ rawInfo,
12187
+ "numeraireFeesToNumeraireBuybackWad",
12188
+ 5,
12189
+ context
12190
+ ),
12191
+ numeraireFeesToBeneficiaryWad: parseBigIntField(
12192
+ rawInfo,
12193
+ "numeraireFeesToBeneficiaryWad",
12194
+ 6,
12195
+ context
12196
+ ),
12197
+ numeraireFeesToLpWad: parseBigIntField(
12198
+ rawInfo,
12199
+ "numeraireFeesToLpWad",
12200
+ 7,
12201
+ context
12202
+ )
12203
+ };
12204
+ }
12205
+ function normalizeRehypeFeeSchedule(rawSchedule, context = "Rehype getFeeSchedule") {
12206
+ return {
12207
+ startingTime: parseNumberField(rawSchedule, "startingTime", 0, context),
12208
+ startFee: parseNumberField(rawSchedule, "startFee", 1, context),
12209
+ endFee: parseNumberField(rawSchedule, "endFee", 2, context),
12210
+ lastFee: parseNumberField(rawSchedule, "lastFee", 3, context),
12211
+ durationSeconds: parseNumberField(
12212
+ rawSchedule,
12213
+ "durationSeconds",
12214
+ 4,
12215
+ context
12216
+ )
12217
+ };
12218
+ }
12219
+ function normalizeRehypeHookFees(rawFees, context = "Rehype getHookFees") {
12220
+ return {
12221
+ fees0: parseBigIntField(rawFees, "fees0", 0, context),
12222
+ fees1: parseBigIntField(rawFees, "fees1", 1, context),
12223
+ beneficiaryFees0: parseBigIntField(rawFees, "beneficiaryFees0", 2, context),
12224
+ beneficiaryFees1: parseBigIntField(rawFees, "beneficiaryFees1", 3, context),
12225
+ airlockOwnerFees0: parseBigIntField(
12226
+ rawFees,
12227
+ "airlockOwnerFees0",
12228
+ 4,
12229
+ context
12230
+ ),
12231
+ airlockOwnerFees1: parseBigIntField(
12232
+ rawFees,
12233
+ "airlockOwnerFees1",
12234
+ 5,
12235
+ context
12236
+ ),
12237
+ customFee: parseNumberField(rawFees, "customFee", 6, context)
12238
+ };
12239
+ }
12240
+ function normalizeRehypePoolInfo(rawInfo, context = "Rehype getPoolInfo") {
12241
+ return {
12242
+ asset: parseAddressField(rawInfo, "asset", 0, context),
12243
+ numeraire: parseAddressField(rawInfo, "numeraire", 1, context),
12244
+ buybackDst: parseAddressField(rawInfo, "buybackDst", 2, context)
12245
+ };
12246
+ }
12247
+ function normalizeRehypePosition(rawPosition, context = "Rehype getPosition") {
12248
+ return {
12249
+ tickLower: parseNumberField(rawPosition, "tickLower", 0, context),
12250
+ tickUpper: parseNumberField(rawPosition, "tickUpper", 1, context),
12251
+ liquidity: parseBigIntField(rawPosition, "liquidity", 2, context),
12252
+ salt: parseHexField(rawPosition, "salt", 3, context)
12253
+ };
12254
+ }
12255
+ function parseAddressField(rawResult, fieldName, tupleIndex, context) {
12256
+ const rawField = readContractResultField(
12257
+ rawResult,
12258
+ [fieldName],
12259
+ tupleIndex,
12260
+ context
12261
+ );
12262
+ return parseAddress(rawField, context, fieldName);
12263
+ }
12264
+ function parseBigIntField(rawResult, fieldName, tupleIndex, context) {
12265
+ const rawField = readContractResultField(
12266
+ rawResult,
12267
+ [fieldName],
12268
+ tupleIndex,
12269
+ context
12270
+ );
12271
+ if (typeof rawField === "bigint") {
12272
+ return rawField;
12273
+ }
12274
+ if (typeof rawField === "number" && Number.isSafeInteger(rawField)) {
12275
+ return BigInt(rawField);
12276
+ }
12277
+ if (typeof rawField === "string" && rawField.trim() !== "") {
12278
+ try {
12279
+ return BigInt(rawField);
12280
+ } catch {
12281
+ throw new Error(`${context}: ${fieldName} must be bigint-compatible`);
12282
+ }
12283
+ }
12284
+ throw new Error(`${context}: ${fieldName} must be bigint-compatible`);
12285
+ }
12286
+ function parseNumberField(rawResult, fieldName, tupleIndex, context) {
12287
+ const rawField = readContractResultField(
12288
+ rawResult,
12289
+ [fieldName],
12290
+ tupleIndex,
12291
+ context
12292
+ );
12293
+ const numericField = typeof rawField === "bigint" || typeof rawField === "number" ? Number(rawField) : Number.NaN;
12294
+ if (!Number.isSafeInteger(numericField)) {
12295
+ throw new Error(`${context}: ${fieldName} must be a safe integer`);
12296
+ }
12297
+ return numericField;
12298
+ }
12299
+ function parseHexField(rawResult, fieldName, tupleIndex, context) {
12300
+ const rawField = readContractResultField(
12301
+ rawResult,
12302
+ [fieldName],
12303
+ tupleIndex,
12304
+ context
12305
+ );
12306
+ if (typeof rawField === "string" && viem.isHex(rawField)) {
12307
+ return rawField;
12308
+ }
12309
+ throw new Error(`${context}: ${fieldName} must be hex`);
12310
+ }
12311
+ function parseAddress(rawField, context, fieldName) {
12312
+ if (typeof rawField === "string" && viem.isAddress(rawField, { strict: false })) {
12313
+ return rawField;
12314
+ }
12315
+ throw new Error(`${context}: ${fieldName} must be an address`);
12316
+ }
12317
+ function readContractResultField(rawResult, fieldNames, tupleIndex, context) {
12318
+ if (Array.isArray(rawResult)) {
12319
+ if (tupleIndex < rawResult.length && rawResult[tupleIndex] !== void 0) {
12320
+ return rawResult[tupleIndex];
12321
+ }
12322
+ throw new Error(
12323
+ `${context}: missing tuple field ${fieldNames.join("/")} at index ${tupleIndex}`
12324
+ );
12325
+ }
12326
+ if (isRecord(rawResult)) {
12327
+ for (const fieldName of fieldNames) {
12328
+ const rawField = rawResult[fieldName];
12329
+ if (rawField !== void 0) {
12330
+ return rawField;
12331
+ }
12332
+ }
12333
+ throw new Error(`${context}: missing field ${fieldNames.join("/")}`);
12334
+ }
12335
+ throw new Error(`${context}: expected tuple or object result`);
12336
+ }
12337
+ function isRecord(rawResult) {
12338
+ return typeof rawResult === "object" && rawResult !== null;
12339
+ }
12340
+
12341
+ // src/evm/entities/auction/StaticAuction.ts
12035
12342
  var StaticAuction = class {
12036
12343
  client;
12037
12344
  poolAddress;
@@ -12087,13 +12394,7 @@ var StaticAuction = class {
12087
12394
  functionName: "getAssetData",
12088
12395
  args: [token0]
12089
12396
  });
12090
- let poolOrHook0;
12091
- if (Array.isArray(assetData)) {
12092
- poolOrHook0 = assetData[5];
12093
- } else if (assetData && typeof assetData === "object") {
12094
- poolOrHook0 = assetData.poolOrHook ?? assetData.pool;
12095
- }
12096
- const isToken0AuctionToken = poolOrHook0 && poolOrHook0 !== viem.zeroAddress;
12397
+ const isToken0AuctionToken = this.isRegisteredAirlockAsset(assetData);
12097
12398
  return {
12098
12399
  address: this.poolAddress,
12099
12400
  tokenAddress: isToken0AuctionToken ? token0 : token1,
@@ -12124,7 +12425,7 @@ var StaticAuction = class {
12124
12425
  functionName: "getAssetData",
12125
12426
  args: [tokenAddress]
12126
12427
  });
12127
- const liquidityMigrator = Array.isArray(assetData) ? assetData[3] : assetData?.liquidityMigrator;
12428
+ const liquidityMigrator = parseAirlockLiquidityMigrator(assetData);
12128
12429
  return liquidityMigrator === viem.zeroAddress;
12129
12430
  }
12130
12431
  /**
@@ -12133,18 +12434,11 @@ var StaticAuction = class {
12133
12434
  */
12134
12435
  async getCurrentPrice() {
12135
12436
  const poolInfo = await this.getPoolInfo();
12136
- const [token0] = await Promise.all([
12137
- this.rpc.readContract({
12138
- address: this.poolAddress,
12139
- abi: uniswapV3PoolAbi,
12140
- functionName: "token0"
12141
- }),
12142
- this.rpc.readContract({
12143
- address: this.poolAddress,
12144
- abi: uniswapV3PoolAbi,
12145
- functionName: "token1"
12146
- })
12147
- ]);
12437
+ const token0 = await this.rpc.readContract({
12438
+ address: this.poolAddress,
12439
+ abi: uniswapV3PoolAbi,
12440
+ functionName: "token0"
12441
+ });
12148
12442
  const sqrtPriceX96 = poolInfo.sqrtPriceX96;
12149
12443
  const Q962 = BigInt(2) ** BigInt(96);
12150
12444
  const sqrtPriceX96Squared = sqrtPriceX96 * sqrtPriceX96;
@@ -12166,6 +12460,13 @@ var StaticAuction = class {
12166
12460
  functionName: "liquidity"
12167
12461
  });
12168
12462
  }
12463
+ isRegisteredAirlockAsset(assetData) {
12464
+ try {
12465
+ return parseAirlockPoolOrHook(assetData) !== viem.zeroAddress;
12466
+ } catch {
12467
+ return false;
12468
+ }
12469
+ }
12169
12470
  };
12170
12471
  var DynamicAuction = class {
12171
12472
  client;
@@ -12251,11 +12552,11 @@ var DynamicAuction = class {
12251
12552
  const currentTime = BigInt(Math.floor(Date.now() / 1e3));
12252
12553
  const elapsedTime = currentTime > startingTime ? currentTime - startingTime : BigInt(0);
12253
12554
  const currentEpoch = epochLength > 0n ? Number(elapsedTime / epochLength) : 0;
12254
- const poolKey = this.normalizePoolKey(poolKeyRaw);
12555
+ const poolKey = normalizePoolKey(poolKeyRaw);
12255
12556
  const isToken0 = poolKey.currency0 !== viem.zeroAddress;
12256
12557
  const tokenAddress = isToken0 ? poolKey.currency0 : poolKey.currency1;
12257
12558
  const numeraireAddress = isToken0 ? poolKey.currency1 : poolKey.currency0;
12258
- const poolId = this.computePoolId(poolKey);
12559
+ const poolId = computePoolId(poolKey);
12259
12560
  return {
12260
12561
  hookAddress: this.hookAddress,
12261
12562
  tokenAddress,
@@ -12282,7 +12583,7 @@ var DynamicAuction = class {
12282
12583
  abi: dopplerHookAbi,
12283
12584
  functionName: "poolKey"
12284
12585
  });
12285
- const poolKey = this.normalizePoolKey(poolKeyRaw);
12586
+ const poolKey = normalizePoolKey(poolKeyRaw);
12286
12587
  const isToken0 = await this.rpc.readContract({
12287
12588
  address: this.hookAddress,
12288
12589
  abi: dopplerHookAbi,
@@ -12299,8 +12600,8 @@ var DynamicAuction = class {
12299
12600
  abi: dopplerHookAbi,
12300
12601
  functionName: "poolKey"
12301
12602
  });
12302
- const poolKey = this.normalizePoolKey(poolKeyRaw);
12303
- return this.computePoolId(poolKey);
12603
+ const poolKey = normalizePoolKey(poolKeyRaw);
12604
+ return computePoolId(poolKey);
12304
12605
  }
12305
12606
  /**
12306
12607
  * Check if the auction has graduated (ready for migration)
@@ -12315,7 +12616,7 @@ var DynamicAuction = class {
12315
12616
  functionName: "getAssetData",
12316
12617
  args: [tokenAddress]
12317
12618
  });
12318
- const liquidityMigrator = Array.isArray(assetData) ? assetData[3] : assetData?.liquidityMigrator;
12619
+ const liquidityMigrator = parseAirlockLiquidityMigrator(assetData);
12319
12620
  return liquidityMigrator === viem.zeroAddress;
12320
12621
  }
12321
12622
  /**
@@ -12343,8 +12644,7 @@ var DynamicAuction = class {
12343
12644
  * Returns the current tick based on the epoch and gamma parameters
12344
12645
  */
12345
12646
  async getCurrentPrice() {
12346
- const [_state, startingTick, endingTick, gamma, startingTime, epochLength] = await Promise.all([
12347
- this.readHookState(),
12647
+ const [startingTick, endingTick, gamma, startingTime, epochLength] = await Promise.all([
12348
12648
  this.rpc.readContract({
12349
12649
  address: this.hookAddress,
12350
12650
  abi: dopplerHookAbi,
@@ -12396,64 +12696,13 @@ var DynamicAuction = class {
12396
12696
  functionName: "earlyExit"
12397
12697
  });
12398
12698
  }
12399
- /**
12400
- * Compute V4 pool ID from pool key components
12401
- */
12402
- computePoolId(poolKey) {
12403
- const encoded = viem.encodeAbiParameters(
12404
- [
12405
- { type: "address" },
12406
- { type: "address" },
12407
- { type: "uint24" },
12408
- { type: "int24" },
12409
- { type: "address" }
12410
- ],
12411
- [
12412
- poolKey.currency0,
12413
- poolKey.currency1,
12414
- poolKey.fee,
12415
- poolKey.tickSpacing,
12416
- poolKey.hooks
12417
- ]
12418
- );
12419
- return viem.keccak256(encoded);
12420
- }
12421
- /**
12422
- * Read hook state with backward-compatible decoding.
12423
- * Falls back to legacy state() ABI if the latest ABI fails to decode.
12424
- */
12425
12699
  async readHookState() {
12426
- const result = await this.rpc.readContract({
12700
+ const rawState = await this.rpc.readContract({
12427
12701
  address: this.hookAddress,
12428
12702
  abi: dopplerHookAbi,
12429
12703
  functionName: "state"
12430
12704
  });
12431
- if (Array.isArray(result)) {
12432
- const [
12433
- lastEpoch,
12434
- tickAccumulator,
12435
- totalTokensSold,
12436
- totalProceeds,
12437
- totalTokensSoldLastEpoch,
12438
- feesAccrued
12439
- ] = result;
12440
- return {
12441
- lastEpoch,
12442
- tickAccumulator,
12443
- totalTokensSold,
12444
- totalProceeds,
12445
- totalTokensSoldLastEpoch,
12446
- feesAccrued
12447
- };
12448
- }
12449
- return result;
12450
- }
12451
- normalizePoolKey(value) {
12452
- if (Array.isArray(value)) {
12453
- const [currency0, currency1, fee, tickSpacing, hooks] = value;
12454
- return { currency0, currency1, fee, tickSpacing, hooks };
12455
- }
12456
- return value;
12705
+ return normalizeDynamicHookState(rawState);
12457
12706
  }
12458
12707
  };
12459
12708
  var ABSENT_POOL_ERROR_ABI = [
@@ -13208,29 +13457,7 @@ var RehypeDopplerHook = class {
13208
13457
  functionName: "getFeeDistributionInfo",
13209
13458
  args: [poolId]
13210
13459
  });
13211
- const info = result;
13212
- return {
13213
- assetFeesToAssetBuybackWad: BigInt(
13214
- info.assetFeesToAssetBuybackWad ?? info[0]
13215
- ),
13216
- assetFeesToNumeraireBuybackWad: BigInt(
13217
- info.assetFeesToNumeraireBuybackWad ?? info[1]
13218
- ),
13219
- assetFeesToBeneficiaryWad: BigInt(
13220
- info.assetFeesToBeneficiaryWad ?? info[2]
13221
- ),
13222
- assetFeesToLpWad: BigInt(info.assetFeesToLpWad ?? info[3]),
13223
- numeraireFeesToAssetBuybackWad: BigInt(
13224
- info.numeraireFeesToAssetBuybackWad ?? info[4]
13225
- ),
13226
- numeraireFeesToNumeraireBuybackWad: BigInt(
13227
- info.numeraireFeesToNumeraireBuybackWad ?? info[5]
13228
- ),
13229
- numeraireFeesToBeneficiaryWad: BigInt(
13230
- info.numeraireFeesToBeneficiaryWad ?? info[6]
13231
- ),
13232
- numeraireFeesToLpWad: BigInt(info.numeraireFeesToLpWad ?? info[7])
13233
- };
13460
+ return normalizeRehypeFeeDistributionInfo(result);
13234
13461
  }
13235
13462
  async getFeeRoutingMode(poolId) {
13236
13463
  const mode = await this.rpc.readContract({
@@ -13248,14 +13475,7 @@ var RehypeDopplerHook = class {
13248
13475
  functionName: "getFeeSchedule",
13249
13476
  args: [poolId]
13250
13477
  });
13251
- const schedule = result;
13252
- return {
13253
- startingTime: Number(schedule.startingTime ?? schedule[0] ?? 0),
13254
- startFee: Number(schedule.startFee ?? schedule[1] ?? 0),
13255
- endFee: Number(schedule.endFee ?? schedule[2] ?? 0),
13256
- lastFee: Number(schedule.lastFee ?? schedule[3] ?? 0),
13257
- durationSeconds: Number(schedule.durationSeconds ?? schedule[4] ?? 0)
13258
- };
13478
+ return normalizeRehypeFeeSchedule(result);
13259
13479
  }
13260
13480
  async getHookFees(poolId) {
13261
13481
  const result = await this.rpc.readContract({
@@ -13264,16 +13484,7 @@ var RehypeDopplerHook = class {
13264
13484
  functionName: "getHookFees",
13265
13485
  args: [poolId]
13266
13486
  });
13267
- const fees = result;
13268
- return {
13269
- fees0: BigInt(fees.fees0 ?? fees[0] ?? 0),
13270
- fees1: BigInt(fees.fees1 ?? fees[1] ?? 0),
13271
- beneficiaryFees0: BigInt(fees.beneficiaryFees0 ?? fees[2] ?? 0),
13272
- beneficiaryFees1: BigInt(fees.beneficiaryFees1 ?? fees[3] ?? 0),
13273
- airlockOwnerFees0: BigInt(fees.airlockOwnerFees0 ?? fees[4] ?? 0),
13274
- airlockOwnerFees1: BigInt(fees.airlockOwnerFees1 ?? fees[5] ?? 0),
13275
- customFee: Number(fees.customFee ?? fees[6] ?? 0)
13276
- };
13487
+ return normalizeRehypeHookFees(result);
13277
13488
  }
13278
13489
  async getPoolInfo(poolId) {
13279
13490
  const result = await this.rpc.readContract({
@@ -13282,12 +13493,7 @@ var RehypeDopplerHook = class {
13282
13493
  functionName: "getPoolInfo",
13283
13494
  args: [poolId]
13284
13495
  });
13285
- const info = result;
13286
- return {
13287
- asset: info.asset ?? info[0],
13288
- numeraire: info.numeraire ?? info[1],
13289
- buybackDst: info.buybackDst ?? info[2]
13290
- };
13496
+ return normalizeRehypePoolInfo(result);
13291
13497
  }
13292
13498
  };
13293
13499
 
@@ -13375,29 +13581,7 @@ var RehypeDopplerHookMigrator = class {
13375
13581
  functionName: "getFeeDistributionInfo",
13376
13582
  args: [poolId]
13377
13583
  });
13378
- const info = result;
13379
- return {
13380
- assetFeesToAssetBuybackWad: BigInt(
13381
- info.assetFeesToAssetBuybackWad ?? info[0]
13382
- ),
13383
- assetFeesToNumeraireBuybackWad: BigInt(
13384
- info.assetFeesToNumeraireBuybackWad ?? info[1]
13385
- ),
13386
- assetFeesToBeneficiaryWad: BigInt(
13387
- info.assetFeesToBeneficiaryWad ?? info[2]
13388
- ),
13389
- assetFeesToLpWad: BigInt(info.assetFeesToLpWad ?? info[3]),
13390
- numeraireFeesToAssetBuybackWad: BigInt(
13391
- info.numeraireFeesToAssetBuybackWad ?? info[4]
13392
- ),
13393
- numeraireFeesToNumeraireBuybackWad: BigInt(
13394
- info.numeraireFeesToNumeraireBuybackWad ?? info[5]
13395
- ),
13396
- numeraireFeesToBeneficiaryWad: BigInt(
13397
- info.numeraireFeesToBeneficiaryWad ?? info[6]
13398
- ),
13399
- numeraireFeesToLpWad: BigInt(info.numeraireFeesToLpWad ?? info[7])
13400
- };
13584
+ return normalizeRehypeFeeDistributionInfo(result);
13401
13585
  }
13402
13586
  async getFeeRoutingMode(poolId) {
13403
13587
  const mode = await this.rpc.readContract({
@@ -13415,16 +13599,7 @@ var RehypeDopplerHookMigrator = class {
13415
13599
  functionName: "getHookFees",
13416
13600
  args: [poolId]
13417
13601
  });
13418
- const fees = result;
13419
- return {
13420
- fees0: BigInt(fees.fees0 ?? fees[0] ?? 0),
13421
- fees1: BigInt(fees.fees1 ?? fees[1] ?? 0),
13422
- beneficiaryFees0: BigInt(fees.beneficiaryFees0 ?? fees[2] ?? 0),
13423
- beneficiaryFees1: BigInt(fees.beneficiaryFees1 ?? fees[3] ?? 0),
13424
- airlockOwnerFees0: BigInt(fees.airlockOwnerFees0 ?? fees[4] ?? 0),
13425
- airlockOwnerFees1: BigInt(fees.airlockOwnerFees1 ?? fees[5] ?? 0),
13426
- customFee: Number(fees.customFee ?? fees[6] ?? 0)
13427
- };
13602
+ return normalizeRehypeHookFees(result);
13428
13603
  }
13429
13604
  async getPoolInfo(poolId) {
13430
13605
  const result = await this.rpc.readContract({
@@ -13433,12 +13608,7 @@ var RehypeDopplerHookMigrator = class {
13433
13608
  functionName: "getPoolInfo",
13434
13609
  args: [poolId]
13435
13610
  });
13436
- const info = result;
13437
- return {
13438
- asset: info.asset ?? info[0],
13439
- numeraire: info.numeraire ?? info[1],
13440
- buybackDst: info.buybackDst ?? info[2]
13441
- };
13611
+ return normalizeRehypePoolInfo(result);
13442
13612
  }
13443
13613
  async getPosition(poolId) {
13444
13614
  const result = await this.rpc.readContract({
@@ -13447,13 +13617,7 @@ var RehypeDopplerHookMigrator = class {
13447
13617
  functionName: "getPosition",
13448
13618
  args: [poolId]
13449
13619
  });
13450
- const position = result;
13451
- return {
13452
- tickLower: Number(position.tickLower ?? position[0] ?? 0),
13453
- tickUpper: Number(position.tickUpper ?? position[1] ?? 0),
13454
- liquidity: BigInt(position.liquidity ?? position[2] ?? 0),
13455
- salt: position.salt ?? position[3]
13456
- };
13620
+ return normalizeRehypePosition(result);
13457
13621
  }
13458
13622
  };
13459
13623
  var OpeningAuctionPositionManager = class _OpeningAuctionPositionManager {
@@ -18570,9 +18734,16 @@ var MulticurveBuilder = class _MulticurveBuilder {
18570
18734
  tokenDecimals: config.tokenDecimals ?? 18,
18571
18735
  numeraireDecimals: config.numeraireDecimals ?? 18
18572
18736
  });
18737
+ const curveSupply = this.sale.numTokensToSell * curve.shares / WAD;
18738
+ const tickUpper = curve.marketCap.end === "max" ? getMaxLiquiditySafeMulticurveTickUpper({
18739
+ ...curveTicks,
18740
+ tickSpacing,
18741
+ numPositions: curve.numPositions,
18742
+ curveSupply
18743
+ }) : curveTicks.tickUpper;
18573
18744
  curves.push({
18574
18745
  tickLower: curveTicks.tickLower,
18575
- tickUpper: curveTicks.tickUpper,
18746
+ tickUpper,
18576
18747
  numPositions: curve.numPositions,
18577
18748
  shares: curve.shares
18578
18749
  });
@@ -18633,7 +18804,7 @@ var MulticurveBuilder = class _MulticurveBuilder {
18633
18804
  }
18634
18805
  dopplerHook = { ...dopplerHook, farTick };
18635
18806
  }
18636
- const initializer = this.initializer ?? (dopplerHook ? { type: "rehype", config: dopplerHook } : this.schedule ? { type: "scheduled", startTime: this.schedule.startTime } : { type: "standard" });
18807
+ const initializer = this.initializer?.type === "rehype" && dopplerHook ? { type: "rehype", config: dopplerHook } : this.initializer ?? (dopplerHook ? { type: "rehype", config: dopplerHook } : this.schedule ? { type: "scheduled", startTime: this.schedule.startTime } : { type: "standard" });
18637
18808
  if (initializer.type === "scheduled" && dopplerHook) {
18638
18809
  throw new Error(
18639
18810
  "Cannot combine scheduled multicurve with rehype initializer. Use exactly one initializer mode."
@@ -19461,6 +19632,7 @@ exports.getAmount0ForLiquidity = getAmount0ForLiquidity;
19461
19632
  exports.getAmount1ForLiquidity = getAmount1ForLiquidity;
19462
19633
  exports.getLiquidityForAmount0 = getLiquidityForAmount0;
19463
19634
  exports.getLiquidityForAmount1 = getLiquidityForAmount1;
19635
+ exports.getMaxLiquiditySafeMulticurveTickUpper = getMaxLiquiditySafeMulticurveTickUpper;
19464
19636
  exports.getMaxTickRounded = getMaxTickRounded;
19465
19637
  exports.getNearestUsableTick = getNearestUsableTick;
19466
19638
  exports.getSqrtRatioAtTick = getSqrtRatioAtTick;
@@ -19489,6 +19661,7 @@ exports.ratioToTick = ratioToTick;
19489
19661
  exports.rehypeDopplerHookAbi = rehypeDopplerHookAbi;
19490
19662
  exports.rehypeDopplerHookMigratorAbi = rehypeDopplerHookMigratorAbi;
19491
19663
  exports.resolveGasEstimate = resolveGasEstimate;
19664
+ exports.sortBeneficiaries = sortBeneficiaries;
19492
19665
  exports.sqrtPriceX96ToPrice = sqrtPriceX96ToPrice;
19493
19666
  exports.streamableFeesLockerAbi = streamableFeesLockerAbi;
19494
19667
  exports.streamableFeesLockerV2Abi = streamableFeesLockerV2Abi;