@whetstone-research/doppler-sdk 1.0.26 → 1.0.27

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.
package/dist/evm/index.js CHANGED
@@ -402,23 +402,23 @@ var DEFAULT_OPENING_DOPPLER_NUM_PD_SLUGS = DEFAULT_PD_SLUGS;
402
402
  var DEFAULT_OPENING_DOPPLER_FEE = FEE_TIERS.HIGH;
403
403
  var DEFAULT_OPENING_DOPPLER_TICK_SPACING = DOPPLER_MAX_TICK_SPACING;
404
404
  var DEFAULT_MULTICURVE_LOWER_TICKS = [
405
- -202100,
406
- -183100,
407
- -167e3
405
+ -887200,
406
+ -222200,
407
+ -176200
408
408
  ];
409
409
  var DEFAULT_MULTICURVE_UPPER_TICKS = [
410
- -188200,
411
- -172100,
412
- -156e3
410
+ -142200,
411
+ -116300,
412
+ -84100
413
413
  ];
414
414
  var DEFAULT_MULTICURVE_NUM_POSITIONS = [11, 11, 11];
415
415
  var DEFAULT_MULTICURVE_MAX_SUPPLY_SHARES = [
416
- parseEther("0.05"),
417
- // 5% for LOW tier
418
- parseEther("0.125"),
419
- // 12.5% for MEDIUM tier
420
- parseEther("0.2")
421
- // 20% for HIGH tier
416
+ parseEther("0.5"),
417
+ // 50% for LOW tier
418
+ parseEther("0.25"),
419
+ // 25% for MEDIUM tier
420
+ parseEther("0.24")
421
+ // 24% for HIGH tier
422
422
  ];
423
423
  var BASIS_POINTS = 1e4;
424
424
  var FLAG_MASK = BigInt(16383);
@@ -462,7 +462,7 @@ var CHAIN_IDS = {
462
462
  BASE: 8453,
463
463
  BASE_SEPOLIA: 84532,
464
464
  INK: 57073,
465
- TEMP: 4663,
465
+ ROBINHOOD: 4663,
466
466
  UNICHAIN: 130,
467
467
  UNICHAIN_SEPOLIA: 1301,
468
468
  MONAD_TESTNET: 10143,
@@ -734,48 +734,50 @@ var ADDRESSES = {
734
734
  weth: "0x4200000000000000000000000000000000000006",
735
735
  uniswapV4Quoter: "0x3972c00f7ed4885e145823eb7c655375d275a1c5"
736
736
  },
737
- [CHAIN_IDS.TEMP]: {
738
- airlock: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].Airlock,
737
+ [CHAIN_IDS.ROBINHOOD]: {
738
+ airlock: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].Airlock,
739
739
  tokenFactory: ZERO_ADDRESS,
740
740
  dopplerERC20V1Factory: getGeneratedAddress(
741
- CHAIN_IDS.TEMP,
741
+ CHAIN_IDS.ROBINHOOD,
742
742
  "DopplerERC20V1Factory"
743
743
  ),
744
744
  dopplerERC20V1Implementation: getGeneratedAddress(
745
- CHAIN_IDS.TEMP,
745
+ CHAIN_IDS.ROBINHOOD,
746
746
  "DopplerERC20V1"
747
747
  ),
748
- doppler404Factory: getGeneratedAddress(CHAIN_IDS.TEMP, "DN404Factory"),
748
+ doppler404Factory: getGeneratedAddress(CHAIN_IDS.ROBINHOOD, "DN404Factory"),
749
749
  v3Initializer: ZERO_ADDRESS,
750
750
  v3Quoter: "0x33e885ed0ec9bf04ecfb19341582aadcb4c8a9e7",
751
- lockableV3Initializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].LockableUniswapV3Initializer,
752
- v4Initializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].UniswapV4Initializer,
753
- dopplerHookInitializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].DopplerHookInitializer,
751
+ lockableV3Initializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].LockableUniswapV3Initializer,
752
+ v4Initializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].UniswapV4Initializer,
753
+ dopplerHookInitializer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].DopplerHookInitializer,
754
754
  rehypeDopplerHookInitializer: getRehypeDopplerHookInitializerAddress(
755
- CHAIN_IDS.TEMP
755
+ CHAIN_IDS.ROBINHOOD
756
756
  ),
757
- rehypeDopplerHook: getRehypeDopplerHookInitializerAddress(CHAIN_IDS.TEMP),
758
- dopplerLens: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].DopplerLensQuoter,
759
- dopplerDeployer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].DopplerDeployer,
757
+ rehypeDopplerHook: getRehypeDopplerHookInitializerAddress(
758
+ CHAIN_IDS.ROBINHOOD
759
+ ),
760
+ dopplerLens: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].DopplerLensQuoter,
761
+ dopplerDeployer: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].DopplerDeployer,
760
762
  poolManager: "0x8366a39cc670b4001a1121b8f6a443a643e40951",
761
763
  v2Migrator: ZERO_ADDRESS,
762
- v2MigratorSplit: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].UniswapV2MigratorSplit,
764
+ v2MigratorSplit: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].UniswapV2MigratorSplit,
763
765
  v4Migrator: ZERO_ADDRESS,
764
- dopplerHookMigrator: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].DopplerHookMigrator,
765
- rehypeDopplerHookMigrator: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].RehypeDopplerHookMigrator,
766
- noOpMigrator: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].NoOpMigrator,
767
- governanceFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].GovernanceFactory,
768
- noOpGovernanceFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].NoOpGovernanceFactory,
769
- launchpadGovernanceFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].LaunchpadGovernanceFactory,
766
+ dopplerHookMigrator: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].DopplerHookMigrator,
767
+ rehypeDopplerHookMigrator: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].RehypeDopplerHookMigrator,
768
+ noOpMigrator: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].NoOpMigrator,
769
+ governanceFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].GovernanceFactory,
770
+ noOpGovernanceFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].NoOpGovernanceFactory,
771
+ launchpadGovernanceFactory: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].LaunchpadGovernanceFactory,
770
772
  streamableFeesLocker: ZERO_ADDRESS,
771
773
  streamableFeesLockerV2: getGeneratedAddress(
772
- CHAIN_IDS.TEMP,
774
+ CHAIN_IDS.ROBINHOOD,
773
775
  "StreamableFeesLockerV2"
774
776
  ),
775
- topUpDistributor: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].TopUpDistributor,
777
+ topUpDistributor: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].TopUpDistributor,
776
778
  universalRouter: "0x8876789976decbfcbbbe364623c63652db8c0904",
777
779
  permit2: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
778
- bundler: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.TEMP].Bundler,
780
+ bundler: GENERATED_DOPPLER_DEPLOYMENTS[CHAIN_IDS.ROBINHOOD].Bundler,
779
781
  weth: "0x0bd7d308f8e1639fab988df18a8011f41eacad73",
780
782
  uniswapV2Factory: "0x8bceaa40b9acdfaedf85adf4ff01f5ad6517937f",
781
783
  uniswapV3Factory: "0x1f7d7550b1b028f7571e69a784071f0205fd2efa",
@@ -6673,6 +6675,92 @@ function getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1) {
6673
6675
  return amount1 * Q96 / diff;
6674
6676
  }
6675
6677
 
6678
+ // src/evm/utils/multicurveLiquidity.ts
6679
+ var MAX_UINT128 = (1n << 128n) - 1n;
6680
+ function getMaxLiquiditySafeMulticurveTickUpper(params) {
6681
+ if (params.tickUpper <= params.tickLower) {
6682
+ throw new Error(
6683
+ `Unable to find a uint128-safe multicurve max tick below ${params.tickUpper}`
6684
+ );
6685
+ }
6686
+ if (isCanonicalCurveLiquiditySafe(params)) return params.tickUpper;
6687
+ for (let candidate = params.tickUpper - params.tickSpacing; candidate > params.tickLower; candidate -= params.tickSpacing) {
6688
+ if (isCanonicalCurveLiquiditySafe({ ...params, tickUpper: candidate })) {
6689
+ return candidate;
6690
+ }
6691
+ }
6692
+ throw new Error(
6693
+ `Unable to find a uint128-safe multicurve max tick below ${params.tickUpper}`
6694
+ );
6695
+ }
6696
+ function isCanonicalCurveLiquiditySafe(params) {
6697
+ return isAdjustedCurveLiquiditySafe({
6698
+ ...params,
6699
+ isToken0: true
6700
+ }) && isAdjustedCurveLiquiditySafe({
6701
+ ...params,
6702
+ tickLower: -params.tickUpper,
6703
+ tickUpper: -params.tickLower,
6704
+ isToken0: false
6705
+ });
6706
+ }
6707
+ function isAdjustedCurveLiquiditySafe(params) {
6708
+ if (params.numPositions <= 0 || params.tickSpacing <= 0) {
6709
+ throw new Error("Multicurve positions and tick spacing must be positive");
6710
+ }
6711
+ const amountPerPosition = params.curveSupply / BigInt(params.numPositions);
6712
+ if (amountPerPosition <= 1n) return true;
6713
+ const amount = amountPerPosition - 1n;
6714
+ const maxLiquidityPerTick = getMaxLiquidityPerTick(params.tickSpacing);
6715
+ const liquidityByTick = /* @__PURE__ */ new Map();
6716
+ const farTick = params.isToken0 ? params.tickUpper : params.tickLower;
6717
+ const closeTick = params.isToken0 ? params.tickLower : params.tickUpper;
6718
+ const spread = params.tickUpper - params.tickLower;
6719
+ const farSqrtPriceX96 = getSqrtRatioAtTick(farTick);
6720
+ for (let i = 0; i < params.numPositions; i++) {
6721
+ const tickDelta = Number(
6722
+ BigInt(i) * BigInt(spread) / BigInt(params.numPositions)
6723
+ );
6724
+ const unalignedTick = params.isToken0 ? closeTick + tickDelta : closeTick - tickDelta;
6725
+ const startingTick = alignMulticurveTick(
6726
+ params.isToken0,
6727
+ unalignedTick,
6728
+ params.tickSpacing
6729
+ );
6730
+ if (startingTick === farTick) continue;
6731
+ const startingSqrtPriceX96 = getSqrtRatioAtTick(startingTick);
6732
+ const liquidity = params.isToken0 ? getLiquidityForAmount0(startingSqrtPriceX96, farSqrtPriceX96, amount) : getLiquidityForAmount1(farSqrtPriceX96, startingSqrtPriceX96, amount);
6733
+ if (liquidity > maxLiquidityPerTick) return false;
6734
+ const tickA = Math.min(farTick, startingTick);
6735
+ const tickB = Math.max(farTick, startingTick);
6736
+ if (!addTickLiquidity(liquidityByTick, tickA, liquidity, maxLiquidityPerTick)) {
6737
+ return false;
6738
+ }
6739
+ if (!addTickLiquidity(liquidityByTick, tickB, liquidity, maxLiquidityPerTick)) {
6740
+ return false;
6741
+ }
6742
+ }
6743
+ return true;
6744
+ }
6745
+ function getMaxLiquidityPerTick(tickSpacing) {
6746
+ const minTick = Math.trunc(MIN_TICK / tickSpacing) * tickSpacing;
6747
+ const maxTick = Math.trunc(MAX_TICK / tickSpacing) * tickSpacing;
6748
+ const numTicks = BigInt((maxTick - minTick) / tickSpacing + 1);
6749
+ return MAX_UINT128 / numTicks;
6750
+ }
6751
+ function addTickLiquidity(liquidityByTick, tick, liquidity, maxLiquidityPerTick) {
6752
+ const updatedLiquidity = (liquidityByTick.get(tick) ?? 0n) + liquidity;
6753
+ if (updatedLiquidity > maxLiquidityPerTick) return false;
6754
+ liquidityByTick.set(tick, updatedLiquidity);
6755
+ return true;
6756
+ }
6757
+ function alignMulticurveTick(isToken0, tick, tickSpacing) {
6758
+ if (isToken0) {
6759
+ return tick < 0 ? Math.trunc((tick - tickSpacing + 1) / tickSpacing) * tickSpacing : Math.trunc(tick / tickSpacing) * tickSpacing;
6760
+ }
6761
+ return tick < 0 ? Math.trunc(tick / tickSpacing) * tickSpacing : Math.trunc((tick + tickSpacing - 1) / tickSpacing) * tickSpacing;
6762
+ }
6763
+
6676
6764
  // src/evm/utils/computeOptimalGamma.ts
6677
6765
  function computeOptimalGamma(startTick, endTick, duration, epochLength, tickSpacing) {
6678
6766
  const totalEpochs = duration / epochLength;
@@ -6708,6 +6796,23 @@ function isToken0Expected(numeraire) {
6708
6796
  }
6709
6797
  }
6710
6798
 
6799
+ // src/evm/utils/beneficiaries.ts
6800
+ function sortBeneficiaries(beneficiaries) {
6801
+ const sorted = [...beneficiaries].sort((a, b) => {
6802
+ const aAddr = a.beneficiary.toLowerCase();
6803
+ const bAddr = b.beneficiary.toLowerCase();
6804
+ return aAddr < bAddr ? -1 : aAddr > bAddr ? 1 : 0;
6805
+ });
6806
+ for (let i = 1; i < sorted.length; i++) {
6807
+ if (sorted[i].beneficiary.toLowerCase() === sorted[i - 1].beneficiary.toLowerCase()) {
6808
+ throw new Error(
6809
+ `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.`
6810
+ );
6811
+ }
6812
+ }
6813
+ return sorted;
6814
+ }
6815
+
6711
6816
  // src/evm/types.ts
6712
6817
  var NO_OP_ENABLED_CHAIN_IDS = [
6713
6818
  CHAIN_IDS.MAINNET,
@@ -6716,7 +6821,7 @@ var NO_OP_ENABLED_CHAIN_IDS = [
6716
6821
  CHAIN_IDS.BASE_SEPOLIA,
6717
6822
  CHAIN_IDS.UNICHAIN,
6718
6823
  CHAIN_IDS.UNICHAIN_SEPOLIA,
6719
- CHAIN_IDS.TEMP,
6824
+ CHAIN_IDS.ROBINHOOD,
6720
6825
  CHAIN_IDS.MONAD_TESTNET,
6721
6826
  CHAIN_IDS.MONAD_MAINNET
6722
6827
  ];
@@ -6727,7 +6832,7 @@ var LAUNCHPAD_ENABLED_CHAIN_IDS = [
6727
6832
  CHAIN_IDS.MAINNET,
6728
6833
  CHAIN_IDS.BASE,
6729
6834
  CHAIN_IDS.BASE_SEPOLIA,
6730
- CHAIN_IDS.TEMP,
6835
+ CHAIN_IDS.ROBINHOOD,
6731
6836
  CHAIN_IDS.MONAD_MAINNET
6732
6837
  ];
6733
6838
  function isLaunchpadEnabledChain(chainId) {
@@ -7312,7 +7417,7 @@ function buildCurvesFromPresets(params) {
7312
7417
  }
7313
7418
 
7314
7419
  // src/evm/entities/DopplerFactory.ts
7315
- var MAX_UINT128 = (1n << 128n) - 1n;
7420
+ var MAX_UINT1282 = (1n << 128n) - 1n;
7316
7421
  var MAX_PROCEEDS_SPLIT_SHARE = WAD / 2n;
7317
7422
  var DERC20_V1_MAX_PREMINT_WAD = WAD * 8n / 10n;
7318
7423
  var ONE_MILLION = 1000000n;
@@ -8008,11 +8113,7 @@ var DopplerFactory = class {
8008
8113
  const hasBeneficiaries = params.pool.beneficiaries && params.pool.beneficiaries.length > 0;
8009
8114
  let poolInitializerData;
8010
8115
  if (hasBeneficiaries) {
8011
- const sortedBeneficiaries = params.pool.beneficiaries.slice().sort((a, b) => {
8012
- const aAddr = a.beneficiary.toLowerCase();
8013
- const bAddr = b.beneficiary.toLowerCase();
8014
- return aAddr < bAddr ? -1 : aAddr > bAddr ? 1 : 0;
8015
- });
8116
+ const sortedBeneficiaries = sortBeneficiaries(params.pool.beneficiaries);
8016
8117
  poolInitializerData = encodeAbiParameters(
8017
8118
  [
8018
8119
  {
@@ -8092,14 +8193,20 @@ var DopplerFactory = class {
8092
8193
  const poolInitializerAddress = (() => {
8093
8194
  if (hasBeneficiaries) {
8094
8195
  const lockableInitializer = params.modules?.lockableV3Initializer ?? addresses.lockableV3Initializer;
8095
- if (!lockableInitializer) {
8196
+ if (!lockableInitializer || lockableInitializer === ZERO_ADDRESS) {
8096
8197
  throw new Error(
8097
8198
  "Lockable V3 initializer address not configured on this chain. Required when using beneficiaries."
8098
8199
  );
8099
8200
  }
8100
8201
  return lockableInitializer;
8101
8202
  }
8102
- return params.modules?.v3Initializer ?? addresses.v3Initializer;
8203
+ const standardInitializer = params.modules?.v3Initializer ?? addresses.v3Initializer;
8204
+ if (!standardInitializer || standardInitializer === ZERO_ADDRESS) {
8205
+ throw new Error(
8206
+ "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."
8207
+ );
8208
+ }
8209
+ return standardInitializer;
8103
8210
  })();
8104
8211
  const liquidityMigratorAddress = this.getMigratorAddress(
8105
8212
  params.migration,
@@ -8514,6 +8621,11 @@ var DopplerFactory = class {
8514
8621
  addresses
8515
8622
  });
8516
8623
  const poolInitializerAddress = params.modules?.v4Initializer ?? addresses.v4Initializer;
8624
+ if (!poolInitializerAddress || poolInitializerAddress === ZERO_ADDRESS) {
8625
+ throw new Error(
8626
+ "UniswapV4Initializer address not configured on this chain. Provide an override via builder.withV4Initializer(...) or use a chain with dynamic auction support."
8627
+ );
8628
+ }
8517
8629
  const liquidityMigratorAddress = this.getMigratorAddress(
8518
8630
  params.migration,
8519
8631
  params.modules
@@ -9844,13 +9956,7 @@ var DopplerFactory = class {
9844
9956
  if (!streamableFees) {
9845
9957
  return "0x";
9846
9958
  }
9847
- const beneficiaryData = [...streamableFees.beneficiaries].sort(
9848
- (a, b) => {
9849
- const addrA = a.beneficiary.toLowerCase();
9850
- const addrB = b.beneficiary.toLowerCase();
9851
- return addrA < addrB ? -1 : addrA > addrB ? 1 : 0;
9852
- }
9853
- );
9959
+ const beneficiaryData = sortBeneficiaries(streamableFees.beneficiaries);
9854
9960
  return encodeAbiParameters(
9855
9961
  [
9856
9962
  { type: "uint24" },
@@ -9875,12 +9981,8 @@ var DopplerFactory = class {
9875
9981
  ]
9876
9982
  );
9877
9983
  case "uniswapV4Split": {
9878
- const beneficiaryData2 = [...config.streamableFees.beneficiaries].sort(
9879
- (a, b) => {
9880
- const addrA = a.beneficiary.toLowerCase();
9881
- const addrB = b.beneficiary.toLowerCase();
9882
- return addrA < addrB ? -1 : addrA > addrB ? 1 : 0;
9883
- }
9984
+ const beneficiaryData2 = sortBeneficiaries(
9985
+ config.streamableFees.beneficiaries
9884
9986
  );
9885
9987
  const proceedsRecipient = config.proceedsSplit?.recipient ?? ZERO_ADDRESS;
9886
9988
  const proceedsShare = config.proceedsSplit?.share ?? 0n;
@@ -9916,12 +10018,8 @@ var DopplerFactory = class {
9916
10018
  "dopplerHook migration cannot set both hook and rehype config. Use exactly one hook mode."
9917
10019
  );
9918
10020
  }
9919
- const beneficiaries = [...dopplerHookConfig.beneficiaries].sort(
9920
- (a, b) => {
9921
- const addrA = a.beneficiary.toLowerCase();
9922
- const addrB = b.beneficiary.toLowerCase();
9923
- return addrA < addrB ? -1 : addrA > addrB ? 1 : 0;
9924
- }
10021
+ const beneficiaries = sortBeneficiaries(
10022
+ dopplerHookConfig.beneficiaries
9925
10023
  );
9926
10024
  let dopplerHookAddress = ZERO_ADDRESS;
9927
10025
  let onInitializationCalldata = "0x";
@@ -10324,15 +10422,12 @@ var DopplerFactory = class {
10324
10422
  }
10325
10423
  const normalizedCurves = this.normalizeMulticurveCurves(
10326
10424
  params.pool.curves,
10327
- params.pool.tickSpacing
10425
+ params.pool.tickSpacing,
10426
+ params.sale.numTokensToSell
10328
10427
  );
10329
10428
  const addresses = getAddresses(this.chainId);
10330
- const sortedBeneficiaries = (params.pool.beneficiaries ?? []).slice().sort(
10331
- (a, b) => {
10332
- const aAddr = a.beneficiary.toLowerCase();
10333
- const bAddr = b.beneficiary.toLowerCase();
10334
- return aAddr < bAddr ? -1 : aAddr > bAddr ? 1 : 0;
10335
- }
10429
+ const sortedBeneficiaries = sortBeneficiaries(
10430
+ params.pool.beneficiaries ?? []
10336
10431
  );
10337
10432
  const initializerMode = this.resolveMulticurveInitializerMode(params);
10338
10433
  const useScheduledInitializer = initializerMode.type === "scheduled";
@@ -10807,7 +10902,7 @@ var DopplerFactory = class {
10807
10902
  /**
10808
10903
  * Normalize user-provided multicurve positions and ensure they satisfy SDK constraints
10809
10904
  */
10810
- normalizeMulticurveCurves(curves, tickSpacing) {
10905
+ normalizeMulticurveCurves(curves, tickSpacing, numTokensToSell) {
10811
10906
  if (tickSpacing <= 0) {
10812
10907
  throw new Error("Tick spacing must be positive");
10813
10908
  }
@@ -10854,25 +10949,19 @@ var DopplerFactory = class {
10854
10949
  if (fallbackTickLower === void 0) {
10855
10950
  throw new Error("Unable to determine fallback multicurve tick range");
10856
10951
  }
10857
- const fallbackTickUpper = this.roundMaxTickDown(tickSpacing);
10858
- if (fallbackTickLower >= fallbackTickUpper) {
10859
- const adjustedLower = fallbackTickUpper - tickSpacing;
10860
- if (adjustedLower < fallbackTickLower) {
10861
- return sanitizedCurves;
10862
- }
10863
- const fallbackCurve2 = {
10864
- tickLower: adjustedLower,
10865
- tickUpper: fallbackTickUpper,
10866
- numPositions: sanitizedCurves[sanitizedCurves.length - 1]?.numPositions ?? 1,
10867
- shares: missingShare
10868
- };
10869
- return [...sanitizedCurves, fallbackCurve2];
10870
- }
10952
+ const fallbackNumPositions = sanitizedCurves[sanitizedCurves.length - 1]?.numPositions ?? 1;
10953
+ const fallbackTickUpper = getMaxLiquiditySafeMulticurveTickUpper({
10954
+ tickLower: fallbackTickLower,
10955
+ tickUpper: this.roundMaxTickDown(tickSpacing),
10956
+ tickSpacing,
10957
+ numPositions: fallbackNumPositions,
10958
+ curveSupply: numTokensToSell * missingShare / WAD
10959
+ });
10871
10960
  const fallbackCurve = {
10872
10961
  // Extend from the most positive user tick out to the maximum supported tick bucket
10873
10962
  tickLower: fallbackTickLower,
10874
10963
  tickUpper: fallbackTickUpper,
10875
- numPositions: sanitizedCurves[sanitizedCurves.length - 1]?.numPositions ?? 1,
10964
+ numPositions: fallbackNumPositions,
10876
10965
  shares: missingShare
10877
10966
  };
10878
10967
  return [...sanitizedCurves, fallbackCurve];
@@ -11392,8 +11481,15 @@ var DopplerFactory = class {
11392
11481
  getMigratorAddress(config, overrides) {
11393
11482
  const addresses = getAddresses(this.chainId);
11394
11483
  switch (config.type) {
11395
- case "uniswapV2":
11396
- return overrides?.v2Migrator ?? addresses.v2Migrator;
11484
+ case "uniswapV2": {
11485
+ const v2Address = overrides?.v2Migrator ?? addresses.v2Migrator;
11486
+ if (!v2Address || v2Address === ZERO_ADDRESS) {
11487
+ throw new Error(
11488
+ "UniswapV2Migrator not deployed on this chain. Use uniswapV2Split migration or provide override via modules.v2Migrator."
11489
+ );
11490
+ }
11491
+ return v2Address;
11492
+ }
11397
11493
  case "uniswapV2Split": {
11398
11494
  const v2SplitAddress = overrides?.v2MigratorSplit ?? addresses.v2MigratorSplit;
11399
11495
  if (!v2SplitAddress || v2SplitAddress === ZERO_ADDRESS) {
@@ -11405,7 +11501,7 @@ var DopplerFactory = class {
11405
11501
  }
11406
11502
  case "uniswapV4": {
11407
11503
  const v4Address = overrides?.v4Migrator ?? addresses.v4Migrator;
11408
- if (v4Address === "0x0000000000000000000000000000000000000000") {
11504
+ if (!v4Address || v4Address === ZERO_ADDRESS) {
11409
11505
  throw new Error(
11410
11506
  "UniswapV4Migrator not deployed on this chain. Use uniswapV2 migration or provide override via modules.v4Migrator."
11411
11507
  );
@@ -11571,7 +11667,7 @@ var DopplerFactory = class {
11571
11667
  if (!allowZero && value === 0n) {
11572
11668
  throw new Error(`${paramName} must be greater than zero`);
11573
11669
  }
11574
- if (value > MAX_UINT128) {
11670
+ if (value > MAX_UINT1282) {
11575
11671
  throw new Error(`${paramName} exceeds uint128 range`);
11576
11672
  }
11577
11673
  }
@@ -18568,9 +18664,16 @@ var MulticurveBuilder = class _MulticurveBuilder {
18568
18664
  tokenDecimals: config.tokenDecimals ?? 18,
18569
18665
  numeraireDecimals: config.numeraireDecimals ?? 18
18570
18666
  });
18667
+ const curveSupply = this.sale.numTokensToSell * curve.shares / WAD;
18668
+ const tickUpper = curve.marketCap.end === "max" ? getMaxLiquiditySafeMulticurveTickUpper({
18669
+ ...curveTicks,
18670
+ tickSpacing,
18671
+ numPositions: curve.numPositions,
18672
+ curveSupply
18673
+ }) : curveTicks.tickUpper;
18571
18674
  curves.push({
18572
18675
  tickLower: curveTicks.tickLower,
18573
- tickUpper: curveTicks.tickUpper,
18676
+ tickUpper,
18574
18677
  numPositions: curve.numPositions,
18575
18678
  shares: curve.shares
18576
18679
  });
@@ -18631,7 +18734,7 @@ var MulticurveBuilder = class _MulticurveBuilder {
18631
18734
  }
18632
18735
  dopplerHook = { ...dopplerHook, farTick };
18633
18736
  }
18634
- const initializer = this.initializer ?? (dopplerHook ? { type: "rehype", config: dopplerHook } : this.schedule ? { type: "scheduled", startTime: this.schedule.startTime } : { type: "standard" });
18737
+ 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" });
18635
18738
  if (initializer.type === "scheduled" && dopplerHook) {
18636
18739
  throw new Error(
18637
18740
  "Cannot combine scheduled multicurve with rehype initializer. Use exactly one initializer mode."
@@ -19318,6 +19421,6 @@ var DopplerSDK = class {
19318
19421
  // src/evm/index.ts
19319
19422
  var VERSION = "1.0.0";
19320
19423
 
19321
- export { ADDRESSES, BASIS_POINTS, CHAIN_IDS, DAY_SECONDS, DEAD_ADDRESS, DECAY_MAX_START_FEE, DEFAULT_AIRLOCK_BENEFICIARY_SHARES, DEFAULT_AUCTION_DURATION, DEFAULT_EPOCH_LENGTH, DEFAULT_LOCK_DURATION, DEFAULT_MULTICURVE_LOWER_TICKS, DEFAULT_MULTICURVE_MAX_SUPPLY_SHARES, DEFAULT_MULTICURVE_NUM_POSITIONS, DEFAULT_MULTICURVE_UPPER_TICKS, DEFAULT_OPENING_AUCTION_DURATION, DEFAULT_OPENING_AUCTION_FEE, DEFAULT_OPENING_AUCTION_INCENTIVE_SHARE_BPS, DEFAULT_OPENING_AUCTION_MIN_ACCEPTABLE_TICK_TOKEN0, DEFAULT_OPENING_AUCTION_MIN_ACCEPTABLE_TICK_TOKEN1, DEFAULT_OPENING_AUCTION_MIN_LIQUIDITY, DEFAULT_OPENING_AUCTION_SHARE_TO_AUCTION_BPS, DEFAULT_OPENING_DOPPLER_DURATION, DEFAULT_OPENING_DOPPLER_EPOCH_LENGTH, DEFAULT_OPENING_DOPPLER_FEE, DEFAULT_OPENING_DOPPLER_NUM_PD_SLUGS, DEFAULT_OPENING_DOPPLER_TICK_SPACING, DEFAULT_PD_SLUGS, DEFAULT_V3_END_TICK, DEFAULT_V3_FEE, DEFAULT_V3_INITIAL_PROPOSAL_THRESHOLD, DEFAULT_V3_INITIAL_SUPPLY, DEFAULT_V3_INITIAL_VOTING_DELAY, DEFAULT_V3_INITIAL_VOTING_PERIOD, DEFAULT_V3_MAX_SHARE_TO_BE_SOLD, DEFAULT_V3_NUM_POSITIONS, DEFAULT_V3_NUM_TOKENS_TO_SELL, DEFAULT_V3_PRE_MINT, DEFAULT_V3_START_TICK, DEFAULT_V3_VESTING_DURATION, DEFAULT_V3_YEARLY_MINT_RATE, DEFAULT_V4_INITIAL_PROPOSAL_THRESHOLD, DEFAULT_V4_INITIAL_VOTING_DELAY, DEFAULT_V4_INITIAL_VOTING_PERIOD, DEFAULT_V4_YEARLY_MINT_RATE, derc2080_default as DERC2080Bytecode, derc20_default as DERC20Bytecode, DOPPLER_FLAGS, DOPPLER_MAX_TICK_SPACING, DYNAMIC_FEE_FLAG, Derc20, Derc20V2, doppler_default as DopplerBytecode, dopplerDN404_default as DopplerDN404Bytecode, DopplerERC20V1, DopplerFactory, DopplerSDK, DynamicAuction, DynamicAuctionBuilder, Eth, FEE_AMOUNT_MASK, FEE_TIERS, FLAG_MASK, INT24_MAX, INT24_MIN, LAUNCHPAD_ENABLED_CHAIN_IDS, LockablePoolStatus, MAX_SQRT_RATIO, MAX_TICK, MIN_SQRT_RATIO, MIN_TICK, MulticurveBuilder, MulticurveFees, MulticurvePool, NO_OP_ENABLED_CHAIN_IDS, OPENING_AUCTION_FLAGS, OPENING_AUCTION_PHASE_ACTIVE, OPENING_AUCTION_PHASE_CLOSED, OPENING_AUCTION_PHASE_NOT_STARTED, OPENING_AUCTION_PHASE_SETTLED, OPENING_AUCTION_STATUS_ACTIVE, OPENING_AUCTION_STATUS_DOPPLER_ACTIVE, OPENING_AUCTION_STATUS_EXITED, OPENING_AUCTION_STATUS_UNINITIALIZED, OpeningAuction, OpeningAuctionBidManager, OpeningAuctionBuilder, openingAuction_default as OpeningAuctionBytecode, OpeningAuctionLifecycle, OpeningAuctionPhase, OpeningAuctionPositionManager, OpeningAuctionStatus, Q96, Quoter, RehypeDopplerHook, RehypeDopplerHookMigrator, RehypeFeeRoutingMode, SECONDS_PER_DAY, SECONDS_PER_YEAR, SUPPORTED_CHAIN_IDS, stateView_default as StateViewBytecode, StaticAuction, StaticAuctionBuilder, TICK_SPACINGS, TopUpDistributor, V3_FEE_TIERS, V4_MAX_FEE, VALID_FEE_TIERS, VERSION, WAD, ZERO_ADDRESS, airlockAbi, applyTickOffsets, bundlerAbi, calculateFDV, calculateGamma, calculateMarketCap, calculateTickRange, calculateTokensToSell, computeOptimalGamma, computePoolId, createAirlockBeneficiary, decayMulticurveInitializerHookAbi, decodeBalanceDelta, derc20Abi, derc20V2Abi, dopplerERC20V1Abi, dopplerHookAbi, dopplerHookInitializerAbi, dopplerLensAbi, encodeRehypeDopplerHookMigratorCalldata, estimatePriceAtEpoch, estimateSlippage, feeClaimsInitializerAbi, formatTickAsPrice, getAddresses, getAirlockBeneficiary, getAirlockOwner, getAmount0ForLiquidity, getAmount1ForLiquidity, getLiquidityForAmount0, getLiquidityForAmount1, getMaxTickRounded, getNearestUsableTick, getSqrtRatioAtTick, getTickAtSqrtRatio, isLaunchpadEnabledChain, isNoOpEnabledChain, isSupportedChainId, isToken0Expected, isToken1, lockableUniswapV3InitializerAbi, marketCapToTickForMulticurve, marketCapToTicksForDynamicAuction, marketCapToTicksForMulticurve, marketCapToTicksForStaticAuction, marketCapToTokenPrice, mineTokenAddress, normalizePoolKey, openingAuctionAbi, openingAuctionInitializerAbi, openingAuctionPositionManagerAbi, poolManagerAbi, priceToSqrtPriceX96, priceToTick, quoterV2Abi, ratioToTick, rehypeDopplerHookAbi, rehypeDopplerHookMigratorAbi, resolveGasEstimate, sqrtPriceX96ToPrice, streamableFeesLockerAbi, streamableFeesLockerV2Abi, tickToMarketCap, tickToPrice, tokenPriceToRatio, topUpDistributorAbi, uniswapV2Router02Abi, uniswapV3InitializerAbi, uniswapV3PoolAbi, uniswapV4InitializerAbi, v2MigratorAbi, v3MigratorAbi, v4MigratorAbi, v4MulticurveInitializerAbi, v4MulticurveMigratorAbi, v4QuoterAbi, validateMarketCapParameters, weth9Abi };
19424
+ export { ADDRESSES, BASIS_POINTS, CHAIN_IDS, DAY_SECONDS, DEAD_ADDRESS, DECAY_MAX_START_FEE, DEFAULT_AIRLOCK_BENEFICIARY_SHARES, DEFAULT_AUCTION_DURATION, DEFAULT_EPOCH_LENGTH, DEFAULT_LOCK_DURATION, DEFAULT_MULTICURVE_LOWER_TICKS, DEFAULT_MULTICURVE_MAX_SUPPLY_SHARES, DEFAULT_MULTICURVE_NUM_POSITIONS, DEFAULT_MULTICURVE_UPPER_TICKS, DEFAULT_OPENING_AUCTION_DURATION, DEFAULT_OPENING_AUCTION_FEE, DEFAULT_OPENING_AUCTION_INCENTIVE_SHARE_BPS, DEFAULT_OPENING_AUCTION_MIN_ACCEPTABLE_TICK_TOKEN0, DEFAULT_OPENING_AUCTION_MIN_ACCEPTABLE_TICK_TOKEN1, DEFAULT_OPENING_AUCTION_MIN_LIQUIDITY, DEFAULT_OPENING_AUCTION_SHARE_TO_AUCTION_BPS, DEFAULT_OPENING_DOPPLER_DURATION, DEFAULT_OPENING_DOPPLER_EPOCH_LENGTH, DEFAULT_OPENING_DOPPLER_FEE, DEFAULT_OPENING_DOPPLER_NUM_PD_SLUGS, DEFAULT_OPENING_DOPPLER_TICK_SPACING, DEFAULT_PD_SLUGS, DEFAULT_V3_END_TICK, DEFAULT_V3_FEE, DEFAULT_V3_INITIAL_PROPOSAL_THRESHOLD, DEFAULT_V3_INITIAL_SUPPLY, DEFAULT_V3_INITIAL_VOTING_DELAY, DEFAULT_V3_INITIAL_VOTING_PERIOD, DEFAULT_V3_MAX_SHARE_TO_BE_SOLD, DEFAULT_V3_NUM_POSITIONS, DEFAULT_V3_NUM_TOKENS_TO_SELL, DEFAULT_V3_PRE_MINT, DEFAULT_V3_START_TICK, DEFAULT_V3_VESTING_DURATION, DEFAULT_V3_YEARLY_MINT_RATE, DEFAULT_V4_INITIAL_PROPOSAL_THRESHOLD, DEFAULT_V4_INITIAL_VOTING_DELAY, DEFAULT_V4_INITIAL_VOTING_PERIOD, DEFAULT_V4_YEARLY_MINT_RATE, derc2080_default as DERC2080Bytecode, derc20_default as DERC20Bytecode, DOPPLER_FLAGS, DOPPLER_MAX_TICK_SPACING, DYNAMIC_FEE_FLAG, Derc20, Derc20V2, doppler_default as DopplerBytecode, dopplerDN404_default as DopplerDN404Bytecode, DopplerERC20V1, DopplerFactory, DopplerSDK, DynamicAuction, DynamicAuctionBuilder, Eth, FEE_AMOUNT_MASK, FEE_TIERS, FLAG_MASK, INT24_MAX, INT24_MIN, LAUNCHPAD_ENABLED_CHAIN_IDS, LockablePoolStatus, MAX_SQRT_RATIO, MAX_TICK, MIN_SQRT_RATIO, MIN_TICK, MulticurveBuilder, MulticurveFees, MulticurvePool, NO_OP_ENABLED_CHAIN_IDS, OPENING_AUCTION_FLAGS, OPENING_AUCTION_PHASE_ACTIVE, OPENING_AUCTION_PHASE_CLOSED, OPENING_AUCTION_PHASE_NOT_STARTED, OPENING_AUCTION_PHASE_SETTLED, OPENING_AUCTION_STATUS_ACTIVE, OPENING_AUCTION_STATUS_DOPPLER_ACTIVE, OPENING_AUCTION_STATUS_EXITED, OPENING_AUCTION_STATUS_UNINITIALIZED, OpeningAuction, OpeningAuctionBidManager, OpeningAuctionBuilder, openingAuction_default as OpeningAuctionBytecode, OpeningAuctionLifecycle, OpeningAuctionPhase, OpeningAuctionPositionManager, OpeningAuctionStatus, Q96, Quoter, RehypeDopplerHook, RehypeDopplerHookMigrator, RehypeFeeRoutingMode, SECONDS_PER_DAY, SECONDS_PER_YEAR, SUPPORTED_CHAIN_IDS, stateView_default as StateViewBytecode, StaticAuction, StaticAuctionBuilder, TICK_SPACINGS, TopUpDistributor, V3_FEE_TIERS, V4_MAX_FEE, VALID_FEE_TIERS, VERSION, WAD, ZERO_ADDRESS, airlockAbi, applyTickOffsets, bundlerAbi, calculateFDV, calculateGamma, calculateMarketCap, calculateTickRange, calculateTokensToSell, computeOptimalGamma, computePoolId, createAirlockBeneficiary, decayMulticurveInitializerHookAbi, decodeBalanceDelta, derc20Abi, derc20V2Abi, dopplerERC20V1Abi, dopplerHookAbi, dopplerHookInitializerAbi, dopplerLensAbi, encodeRehypeDopplerHookMigratorCalldata, estimatePriceAtEpoch, estimateSlippage, feeClaimsInitializerAbi, formatTickAsPrice, getAddresses, getAirlockBeneficiary, getAirlockOwner, getAmount0ForLiquidity, getAmount1ForLiquidity, getLiquidityForAmount0, getLiquidityForAmount1, getMaxLiquiditySafeMulticurveTickUpper, getMaxTickRounded, getNearestUsableTick, getSqrtRatioAtTick, getTickAtSqrtRatio, isLaunchpadEnabledChain, isNoOpEnabledChain, isSupportedChainId, isToken0Expected, isToken1, lockableUniswapV3InitializerAbi, marketCapToTickForMulticurve, marketCapToTicksForDynamicAuction, marketCapToTicksForMulticurve, marketCapToTicksForStaticAuction, marketCapToTokenPrice, mineTokenAddress, normalizePoolKey, openingAuctionAbi, openingAuctionInitializerAbi, openingAuctionPositionManagerAbi, poolManagerAbi, priceToSqrtPriceX96, priceToTick, quoterV2Abi, ratioToTick, rehypeDopplerHookAbi, rehypeDopplerHookMigratorAbi, resolveGasEstimate, sortBeneficiaries, sqrtPriceX96ToPrice, streamableFeesLockerAbi, streamableFeesLockerV2Abi, tickToMarketCap, tickToPrice, tokenPriceToRatio, topUpDistributorAbi, uniswapV2Router02Abi, uniswapV3InitializerAbi, uniswapV3PoolAbi, uniswapV4InitializerAbi, v2MigratorAbi, v3MigratorAbi, v4MigratorAbi, v4MulticurveInitializerAbi, v4MulticurveMigratorAbi, v4QuoterAbi, validateMarketCapParameters, weth9Abi };
19322
19425
  //# sourceMappingURL=index.js.map
19323
19426
  //# sourceMappingURL=index.js.map