@pancakeswap/v3-sdk 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/abi/MasterChefV3.d.ts +1222 -0
  2. package/dist/abi/MasterChefV3.d.ts.map +1 -0
  3. package/dist/abi/NonfungiblePositionManager.d.ts +962 -0
  4. package/dist/abi/NonfungiblePositionManager.d.ts.map +1 -0
  5. package/dist/abi/PeripheryPaymentsWithFee.d.ts +88 -0
  6. package/dist/abi/PeripheryPaymentsWithFee.d.ts.map +1 -0
  7. package/dist/abi/Quoter.d.ts +162 -0
  8. package/dist/abi/Quoter.d.ts.map +1 -0
  9. package/dist/abi/QuoterV2.d.ts +220 -0
  10. package/dist/abi/QuoterV2.d.ts.map +1 -0
  11. package/dist/abi/SelfPermit.d.ts +122 -0
  12. package/dist/abi/SelfPermit.d.ts.map +1 -0
  13. package/dist/abi/SwapRouter.d.ts +453 -0
  14. package/dist/abi/SwapRouter.d.ts.map +1 -0
  15. package/dist/abi/V3Staker.d.ts +547 -0
  16. package/dist/abi/V3Staker.d.ts.map +1 -0
  17. package/dist/constants.d.ts.map +1 -1
  18. package/dist/entities/pool.d.ts +2 -1
  19. package/dist/entities/pool.d.ts.map +1 -1
  20. package/dist/entities/tick.d.ts.map +1 -1
  21. package/dist/index.d.ts +8 -0
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +1447 -1359
  24. package/dist/index.mjs +1447 -1367
  25. package/dist/masterchefV3.d.ts +1228 -9
  26. package/dist/masterchefV3.d.ts.map +1 -1
  27. package/dist/multicall.d.ts +16 -3
  28. package/dist/multicall.d.ts.map +1 -1
  29. package/dist/nonfungiblePositionManager.d.ts +976 -10
  30. package/dist/nonfungiblePositionManager.d.ts.map +1 -1
  31. package/dist/payments.d.ts +95 -6
  32. package/dist/payments.d.ts.map +1 -1
  33. package/dist/quoter.d.ts +385 -4
  34. package/dist/quoter.d.ts.map +1 -1
  35. package/dist/selfPermit.d.ts +128 -8
  36. package/dist/selfPermit.d.ts.map +1 -1
  37. package/dist/staker.d.ts +549 -3
  38. package/dist/staker.d.ts.map +1 -1
  39. package/dist/swapRouter.d.ts +452 -2
  40. package/dist/swapRouter.d.ts.map +1 -1
  41. package/dist/utils/calldata.d.ts +4 -3
  42. package/dist/utils/calldata.d.ts.map +1 -1
  43. package/dist/utils/computePoolAddress.d.ts +4 -3
  44. package/dist/utils/computePoolAddress.d.ts.map +1 -1
  45. package/dist/utils/encodeRouteToPath.d.ts +3 -2
  46. package/dist/utils/encodeRouteToPath.d.ts.map +1 -1
  47. package/dist/utils/encodeSqrtRatioX96.d.ts +1 -1
  48. package/dist/utils/encodeSqrtRatioX96.d.ts.map +1 -1
  49. package/dist/utils/feeCalculator.d.ts +1 -1
  50. package/dist/utils/feeCalculator.d.ts.map +1 -1
  51. package/dist/utils/parseProtocolFees.d.ts +1 -1
  52. package/dist/utils/parseProtocolFees.d.ts.map +1 -1
  53. package/dist/utils/positionMath.d.ts.map +1 -1
  54. package/dist/utils/priceTickConversions.d.ts +1 -1
  55. package/dist/utils/priceTickConversions.d.ts.map +1 -1
  56. package/package.json +6 -15
package/dist/index.mjs CHANGED
@@ -1,9 +1,7 @@
1
- import { ChainId, MaxUint256, sqrt, Price, CurrencyAmount, Fraction, ZERO as ZERO$1, Percent as Percent$1, TradeType, sortedInsert, validateAndParseAddress, ONE as ONE$1 } from '@pancakeswap/sdk';
2
- import invariant11 from 'tiny-invariant';
3
- import { Percent, Price as Price$1, Fraction as Fraction$1 } from '@pancakeswap/swap-sdk-core';
4
- import { Interface, defaultAbiCoder } from '@ethersproject/abi';
5
- import { getCreate2Address } from '@ethersproject/address';
6
- import { keccak256, pack } from '@ethersproject/solidity';
1
+ import { ChainId, Price, CurrencyAmount, Percent as Percent$1, MaxUint256 as MaxUint256$1, TradeType, Fraction, sortedInsert, validateAndParseAddress, ZERO as ZERO$2, ONE as ONE$1 } from '@pancakeswap/sdk';
2
+ import invariant9 from 'tiny-invariant';
3
+ import { Percent, MaxUint256, sqrt, Price as Price$1, CurrencyAmount as CurrencyAmount$1, Fraction as Fraction$1, ZERO as ZERO$1, TradeType as TradeType$1 } from '@pancakeswap/swap-sdk-core';
4
+ import { keccak256, encodeAbiParameters, parseAbiParameters, encodePacked, encodeFunctionData, toBytes, getAddress, pad, isBytes, slice, concat } from 'viem';
7
5
 
8
6
  // src/entities/pool.ts
9
7
  var FACTORY_ADDRESS = "0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865";
@@ -38,6 +36,13 @@ var MAX_FEE = 10n ** 6n;
38
36
  var ONE_HUNDRED_PERCENT = new Percent("1");
39
37
  var ZERO_PERCENT = new Percent("0");
40
38
  var Q128 = 2n ** 128n;
39
+ function getCreate2Address(from_, salt_, initCodeHash) {
40
+ const from = toBytes(getAddress(from_));
41
+ const salt = pad(isBytes(salt_) ? salt_ : toBytes(salt_), {
42
+ size: 32
43
+ });
44
+ return getAddress(slice(keccak256(concat([toBytes("0xff"), from, salt, toBytes(initCodeHash)])), 12));
45
+ }
41
46
  function computePoolAddress({
42
47
  deployerAddress,
43
48
  tokenA,
@@ -49,8 +54,7 @@ function computePoolAddress({
49
54
  return getCreate2Address(
50
55
  deployerAddress,
51
56
  keccak256(
52
- ["bytes"],
53
- [defaultAbiCoder.encode(["address", "address", "uint24"], [token0.address, token1.address, fee])]
57
+ encodeAbiParameters(parseAbiParameters(["address, address, uint24"]), [token0.address, token1.address, fee])
54
58
  ),
55
59
  initCodeHashManualOverride ?? POOL_INIT_CODE_HASH
56
60
  );
@@ -118,13 +122,13 @@ var SqrtPriceMath = class {
118
122
  return roundUp ? FullMath.mulDivRoundingUp(liquidity, sqrtRatioBX96 - sqrtRatioAX96, Q96) : liquidity * (sqrtRatioBX96 - sqrtRatioAX96) / Q96;
119
123
  }
120
124
  static getNextSqrtPriceFromInput(sqrtPX96, liquidity, amountIn, zeroForOne) {
121
- invariant11(sqrtPX96 > ZERO);
122
- invariant11(liquidity > ZERO);
125
+ invariant9(sqrtPX96 > ZERO);
126
+ invariant9(liquidity > ZERO);
123
127
  return zeroForOne ? this.getNextSqrtPriceFromAmount0RoundingUp(sqrtPX96, liquidity, amountIn, true) : this.getNextSqrtPriceFromAmount1RoundingDown(sqrtPX96, liquidity, amountIn, true);
124
128
  }
125
129
  static getNextSqrtPriceFromOutput(sqrtPX96, liquidity, amountOut, zeroForOne) {
126
- invariant11(sqrtPX96 > ZERO);
127
- invariant11(liquidity > ZERO);
130
+ invariant9(sqrtPX96 > ZERO);
131
+ invariant9(liquidity > ZERO);
128
132
  return zeroForOne ? this.getNextSqrtPriceFromAmount1RoundingDown(sqrtPX96, liquidity, amountOut, false) : this.getNextSqrtPriceFromAmount0RoundingUp(sqrtPX96, liquidity, amountOut, false);
129
133
  }
130
134
  static getNextSqrtPriceFromAmount0RoundingUp(sqrtPX96, liquidity, amount, add) {
@@ -142,8 +146,8 @@ var SqrtPriceMath = class {
142
146
  return FullMath.mulDivRoundingUp(numerator1, ONE, numerator1 / sqrtPX96 + amount);
143
147
  }
144
148
  const product = multiplyIn256(amount, sqrtPX96);
145
- invariant11(product / amount === sqrtPX96);
146
- invariant11(numerator1 > product);
149
+ invariant9(product / amount === sqrtPX96);
150
+ invariant9(numerator1 > product);
147
151
  const denominator = numerator1 - product;
148
152
  return FullMath.mulDivRoundingUp(numerator1, sqrtPX96, denominator);
149
153
  }
@@ -153,7 +157,7 @@ var SqrtPriceMath = class {
153
157
  return sqrtPX96 + quotient2;
154
158
  }
155
159
  const quotient = FullMath.mulDivRoundingUp(amount, Q96, liquidity);
156
- invariant11(sqrtPX96 > quotient);
160
+ invariant9(sqrtPX96 > quotient);
157
161
  return sqrtPX96 - quotient;
158
162
  }
159
163
  };
@@ -221,8 +225,8 @@ var SwapMath = class {
221
225
  var TWO = 2n;
222
226
  var POWERS_OF_2 = [128, 64, 32, 16, 8, 4, 2, 1].map((pow) => [pow, TWO ** BigInt(pow)]);
223
227
  function mostSignificantBit(x) {
224
- invariant11(x > ZERO, "ZERO");
225
- invariant11(x <= MaxUint256, "MAX");
228
+ invariant9(x > ZERO, "ZERO");
229
+ invariant9(x <= MaxUint256, "MAX");
226
230
  let msb = 0;
227
231
  for (const [power, min] of POWERS_OF_2) {
228
232
  if (x >= min) {
@@ -249,7 +253,7 @@ var _TickMath = class {
249
253
  * @param tick the tick for which to compute the sqrt ratio
250
254
  */
251
255
  static getSqrtRatioAtTick(tick) {
252
- invariant11(tick >= _TickMath.MIN_TICK && tick <= _TickMath.MAX_TICK && Number.isInteger(tick), "TICK");
256
+ invariant9(tick >= _TickMath.MIN_TICK && tick <= _TickMath.MAX_TICK && Number.isInteger(tick), "TICK");
253
257
  const absTick = tick < 0 ? tick * -1 : tick;
254
258
  let ratio = (absTick & 1) != 0 ? BigInt("0xfffcb933bd6fad37aa2d162d1a594001") : BigInt("0x100000000000000000000000000000000");
255
259
  if ((absTick & 2) != 0)
@@ -300,7 +304,7 @@ var _TickMath = class {
300
304
  * @param sqrtRatioX96 the sqrt ratio as a Q64.96 for which to compute the tick
301
305
  */
302
306
  static getTickAtSqrtRatio(sqrtRatioX96) {
303
- invariant11(sqrtRatioX96 >= _TickMath.MIN_SQRT_RATIO && sqrtRatioX96 < _TickMath.MAX_SQRT_RATIO, "SQRT_RATIO");
307
+ invariant9(sqrtRatioX96 >= _TickMath.MIN_SQRT_RATIO && sqrtRatioX96 < _TickMath.MAX_SQRT_RATIO, "SQRT_RATIO");
304
308
  const sqrtRatioX128 = sqrtRatioX96 << 32n;
305
309
  const msb = mostSignificantBit(sqrtRatioX128);
306
310
  let r;
@@ -374,25 +378,25 @@ var TickList = class {
374
378
  constructor() {
375
379
  }
376
380
  static validateList(ticks, tickSpacing) {
377
- invariant11(tickSpacing > 0, "TICK_SPACING_NONZERO");
378
- invariant11(
381
+ invariant9(tickSpacing > 0, "TICK_SPACING_NONZERO");
382
+ invariant9(
379
383
  ticks.every(({ index }) => index % tickSpacing === 0),
380
384
  "TICK_SPACING"
381
385
  );
382
- invariant11(ticks.reduce((accumulator, { liquidityNet }) => accumulator + liquidityNet, ZERO) === ZERO, "ZERO_NET");
383
- invariant11(isSorted(ticks, tickComparator), "SORTED");
386
+ invariant9(ticks.reduce((accumulator, { liquidityNet }) => accumulator + liquidityNet, ZERO) === ZERO, "ZERO_NET");
387
+ invariant9(isSorted(ticks, tickComparator), "SORTED");
384
388
  }
385
389
  static isBelowSmallest(ticks, tick) {
386
- invariant11(ticks.length > 0, "LENGTH");
390
+ invariant9(ticks.length > 0, "LENGTH");
387
391
  return tick < ticks[0].index;
388
392
  }
389
393
  static isAtOrAboveLargest(ticks, tick) {
390
- invariant11(ticks.length > 0, "LENGTH");
394
+ invariant9(ticks.length > 0, "LENGTH");
391
395
  return tick >= ticks[ticks.length - 1].index;
392
396
  }
393
397
  static getTick(ticks, index) {
394
398
  const tick = ticks[this.binarySearch(ticks, index)];
395
- invariant11(tick.index === index, "NOT_CONTAINED");
399
+ invariant9(tick.index === index, "NOT_CONTAINED");
396
400
  return tick;
397
401
  }
398
402
  /**
@@ -402,7 +406,7 @@ var TickList = class {
402
406
  * @private
403
407
  */
404
408
  static binarySearch(ticks, tick) {
405
- invariant11(!this.isBelowSmallest(ticks, tick), "BELOW_SMALLEST");
409
+ invariant9(!this.isBelowSmallest(ticks, tick), "BELOW_SMALLEST");
406
410
  let l = 0;
407
411
  let r = ticks.length - 1;
408
412
  let i;
@@ -420,14 +424,14 @@ var TickList = class {
420
424
  }
421
425
  static nextInitializedTick(ticks, tick, lte) {
422
426
  if (lte) {
423
- invariant11(!TickList.isBelowSmallest(ticks, tick), "BELOW_SMALLEST");
427
+ invariant9(!TickList.isBelowSmallest(ticks, tick), "BELOW_SMALLEST");
424
428
  if (TickList.isAtOrAboveLargest(ticks, tick)) {
425
429
  return ticks[ticks.length - 1];
426
430
  }
427
431
  const index2 = this.binarySearch(ticks, tick);
428
432
  return ticks[index2];
429
433
  }
430
- invariant11(!this.isAtOrAboveLargest(ticks, tick), "AT_OR_ABOVE_LARGEST");
434
+ invariant9(!this.isAtOrAboveLargest(ticks, tick), "AT_OR_ABOVE_LARGEST");
431
435
  if (this.isBelowSmallest(ticks, tick)) {
432
436
  return ticks[0];
433
437
  }
@@ -464,44 +468,219 @@ var TickList = class {
464
468
  return Math.abs(beforeIndex - afterIndex);
465
469
  }
466
470
  };
471
+ var Tick = class {
472
+ constructor({ index, liquidityGross, liquidityNet }) {
473
+ invariant9(index >= TickMath.MIN_TICK && index <= TickMath.MAX_TICK, "TICK");
474
+ this.index = index;
475
+ this.liquidityGross = BigInt(liquidityGross);
476
+ this.liquidityNet = BigInt(liquidityNet);
477
+ }
478
+ };
467
479
 
468
- // src/utils/calldata.ts
469
- function toHex(bigintIsh) {
470
- const bigInt = BigInt(bigintIsh);
471
- let hex = bigInt.toString(16);
472
- if (hex.length % 2 !== 0) {
473
- hex = `0${hex}`;
480
+ // src/entities/tickListDataProvider.ts
481
+ var TickListDataProvider = class {
482
+ constructor(ticks) {
483
+ const ticksMapped = ticks.map((t) => t instanceof Tick ? t : new Tick(t));
484
+ this.ticks = ticksMapped;
474
485
  }
475
- return `0x${hex}`;
476
- }
477
- function encodeRouteToPath(route, exactOutput) {
478
- const firstInputToken = route.input.wrapped;
479
- const { path, types } = route.pools.reduce(
480
- ({ inputToken, path: path2, types: types2 }, pool, index) => {
481
- const outputToken = pool.token0.equals(inputToken) ? pool.token1 : pool.token0;
482
- if (index === 0) {
483
- return {
484
- inputToken: outputToken,
485
- types: ["address", "uint24", "address"],
486
- path: [inputToken.address, pool.fee, outputToken.address]
487
- };
486
+ async getTick(tick) {
487
+ return TickList.getTick(this.ticks, tick);
488
+ }
489
+ async nextInitializedTickWithinOneWord(tick, lte, tickSpacing) {
490
+ return TickList.nextInitializedTickWithinOneWord(this.ticks, tick, lte, tickSpacing);
491
+ }
492
+ };
493
+
494
+ // src/entities/pool.ts
495
+ var NO_TICK_DATA_PROVIDER_DEFAULT = new NoTickDataProvider();
496
+ var Pool = class {
497
+ static getAddress(tokenA, tokenB, fee, initCodeHashManualOverride, deployerAddressOverride) {
498
+ return computePoolAddress({
499
+ deployerAddress: deployerAddressOverride ?? DEPLOYER_ADDRESSES[tokenA.chainId],
500
+ fee,
501
+ tokenA,
502
+ tokenB,
503
+ initCodeHashManualOverride
504
+ });
505
+ }
506
+ /**
507
+ * Construct a pool
508
+ * @param tokenA One of the tokens in the pool
509
+ * @param tokenB The other token in the pool
510
+ * @param fee The fee in hundredths of a bips of the input amount of every swap that is collected by the pool
511
+ * @param sqrtRatioX96 The sqrt of the current ratio of amounts of token1 to token0
512
+ * @param liquidity The current value of in range liquidity
513
+ * @param tickCurrent The current tick of the pool
514
+ * @param ticks The current state of the pool ticks or a data provider that can return tick data
515
+ */
516
+ constructor(tokenA, tokenB, fee, sqrtRatioX96, liquidity, tickCurrent, ticks = NO_TICK_DATA_PROVIDER_DEFAULT) {
517
+ invariant9(Number.isInteger(fee) && fee < 1e6, "FEE");
518
+ [this.token0, this.token1] = tokenA.sortsBefore(tokenB) ? [tokenA, tokenB] : [tokenB, tokenA];
519
+ this.fee = fee;
520
+ this.sqrtRatioX96 = BigInt(sqrtRatioX96);
521
+ this.liquidity = BigInt(liquidity);
522
+ this.tickCurrent = tickCurrent;
523
+ this.tickDataProvider = Array.isArray(ticks) ? new TickListDataProvider(ticks) : ticks;
524
+ }
525
+ /**
526
+ * Returns true if the token is either token0 or token1
527
+ * @param token The token to check
528
+ * @returns True if token is either token0 or token
529
+ */
530
+ involvesToken(token) {
531
+ return token.equals(this.token0) || token.equals(this.token1);
532
+ }
533
+ /**
534
+ * Returns the current mid price of the pool in terms of token0, i.e. the ratio of token1 over token0
535
+ */
536
+ get token0Price() {
537
+ return this._token0Price ?? (this._token0Price = new Price(this.token0, this.token1, Q192, this.sqrtRatioX96 * this.sqrtRatioX96));
538
+ }
539
+ /**
540
+ * Returns the current mid price of the pool in terms of token1, i.e. the ratio of token0 over token1
541
+ */
542
+ get token1Price() {
543
+ return this._token1Price ?? (this._token1Price = new Price(this.token1, this.token0, this.sqrtRatioX96 * this.sqrtRatioX96, Q192));
544
+ }
545
+ /**
546
+ * Return the price of the given token in terms of the other token in the pool.
547
+ * @param token The token to return price of
548
+ * @returns The price of the given token, in terms of the other.
549
+ */
550
+ priceOf(token) {
551
+ invariant9(this.involvesToken(token), "TOKEN");
552
+ return token.equals(this.token0) ? this.token0Price : this.token1Price;
553
+ }
554
+ /**
555
+ * Returns the chain ID of the tokens in the pool.
556
+ */
557
+ get chainId() {
558
+ return this.token0.chainId;
559
+ }
560
+ /**
561
+ * Given an input amount of a token, return the computed output amount, and a pool with state updated after the trade
562
+ * @param inputAmount The input amount for which to quote the output amount
563
+ * @param sqrtPriceLimitX96 The Q64.96 sqrt price limit
564
+ * @returns The output amount and the pool with updated state
565
+ */
566
+ async getOutputAmount(inputAmount, sqrtPriceLimitX96) {
567
+ invariant9(this.involvesToken(inputAmount.currency), "TOKEN");
568
+ const zeroForOne = inputAmount.currency.equals(this.token0);
569
+ const {
570
+ amountCalculated: outputAmount,
571
+ sqrtRatioX96,
572
+ liquidity,
573
+ tickCurrent
574
+ } = await this.swap(zeroForOne, inputAmount.quotient, sqrtPriceLimitX96);
575
+ const outputToken = zeroForOne ? this.token1 : this.token0;
576
+ return [
577
+ CurrencyAmount.fromRawAmount(outputToken, outputAmount * NEGATIVE_ONE),
578
+ new Pool(this.token0, this.token1, this.fee, sqrtRatioX96, liquidity, tickCurrent, this.tickDataProvider)
579
+ ];
580
+ }
581
+ /**
582
+ * Given a desired output amount of a token, return the computed input amount and a pool with state updated after the trade
583
+ * @param outputAmount the output amount for which to quote the input amount
584
+ * @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this value after the swap. If one for zero, the price cannot be greater than this value after the swap
585
+ * @returns The input amount and the pool with updated state
586
+ */
587
+ async getInputAmount(outputAmount, sqrtPriceLimitX96) {
588
+ invariant9(outputAmount.currency.isToken && this.involvesToken(outputAmount.currency), "TOKEN");
589
+ const zeroForOne = outputAmount.currency.equals(this.token1);
590
+ const {
591
+ amountSpecifiedRemaining,
592
+ amountCalculated: inputAmount,
593
+ sqrtRatioX96,
594
+ liquidity,
595
+ tickCurrent
596
+ } = await this.swap(zeroForOne, outputAmount.quotient * NEGATIVE_ONE, sqrtPriceLimitX96);
597
+ invariant9(amountSpecifiedRemaining === ZERO, "INSUFICIENT_LIQUIDITY");
598
+ const inputToken = zeroForOne ? this.token0 : this.token1;
599
+ return [
600
+ CurrencyAmount.fromRawAmount(inputToken, inputAmount),
601
+ new Pool(this.token0, this.token1, this.fee, sqrtRatioX96, liquidity, tickCurrent, this.tickDataProvider)
602
+ ];
603
+ }
604
+ /**
605
+ * Executes a swap
606
+ * @param zeroForOne Whether the amount in is token0 or token1
607
+ * @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)
608
+ * @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this value after the swap. If one for zero, the price cannot be greater than this value after the swap
609
+ * @returns amountCalculated
610
+ * @returns sqrtRatioX96
611
+ * @returns liquidity
612
+ * @returns tickCurrent
613
+ */
614
+ async swap(zeroForOne, amountSpecified, sqrtPriceLimitX96) {
615
+ if (!sqrtPriceLimitX96)
616
+ sqrtPriceLimitX96 = zeroForOne ? TickMath.MIN_SQRT_RATIO + ONE : TickMath.MAX_SQRT_RATIO - ONE;
617
+ if (zeroForOne) {
618
+ invariant9(sqrtPriceLimitX96 > TickMath.MIN_SQRT_RATIO, "RATIO_MIN");
619
+ invariant9(sqrtPriceLimitX96 < this.sqrtRatioX96, "RATIO_CURRENT");
620
+ } else {
621
+ invariant9(sqrtPriceLimitX96 < TickMath.MAX_SQRT_RATIO, "RATIO_MAX");
622
+ invariant9(sqrtPriceLimitX96 > this.sqrtRatioX96, "RATIO_CURRENT");
623
+ }
624
+ const exactInput = amountSpecified >= ZERO;
625
+ const state = {
626
+ amountSpecifiedRemaining: amountSpecified,
627
+ amountCalculated: ZERO,
628
+ sqrtPriceX96: this.sqrtRatioX96,
629
+ tick: this.tickCurrent,
630
+ liquidity: this.liquidity
631
+ };
632
+ while (state.amountSpecifiedRemaining !== ZERO && state.sqrtPriceX96 != sqrtPriceLimitX96) {
633
+ const step = {};
634
+ step.sqrtPriceStartX96 = state.sqrtPriceX96;
635
+ [step.tickNext, step.initialized] = await this.tickDataProvider.nextInitializedTickWithinOneWord(
636
+ state.tick,
637
+ zeroForOne,
638
+ this.tickSpacing
639
+ );
640
+ if (step.tickNext < TickMath.MIN_TICK) {
641
+ step.tickNext = TickMath.MIN_TICK;
642
+ } else if (step.tickNext > TickMath.MAX_TICK) {
643
+ step.tickNext = TickMath.MAX_TICK;
488
644
  }
489
- return {
490
- inputToken: outputToken,
491
- types: [...types2, "uint24", "address"],
492
- path: [...path2, pool.fee, outputToken.address]
493
- };
494
- },
495
- { inputToken: firstInputToken, path: [], types: [] }
496
- );
497
- return exactOutput ? pack(types.reverse(), path.reverse()) : pack(types, path);
498
- }
499
- function encodeSqrtRatioX96(amount1, amount0) {
500
- const numerator = BigInt(amount1) << 192n;
501
- const denominator = BigInt(amount0);
502
- const ratioX192 = numerator / denominator;
503
- return sqrt(ratioX192);
504
- }
645
+ step.sqrtPriceNextX96 = TickMath.getSqrtRatioAtTick(step.tickNext);
646
+ [state.sqrtPriceX96, step.amountIn, step.amountOut, step.feeAmount] = SwapMath.computeSwapStep(
647
+ state.sqrtPriceX96,
648
+ (zeroForOne ? step.sqrtPriceNextX96 < sqrtPriceLimitX96 : step.sqrtPriceNextX96 > sqrtPriceLimitX96) ? sqrtPriceLimitX96 : step.sqrtPriceNextX96,
649
+ state.liquidity,
650
+ state.amountSpecifiedRemaining,
651
+ this.fee
652
+ );
653
+ if (exactInput) {
654
+ state.amountSpecifiedRemaining = state.amountSpecifiedRemaining - (step.amountIn + step.feeAmount);
655
+ state.amountCalculated = state.amountCalculated - step.amountOut;
656
+ } else {
657
+ state.amountSpecifiedRemaining = state.amountSpecifiedRemaining + step.amountOut;
658
+ state.amountCalculated = state.amountCalculated + (step.amountIn + step.feeAmount);
659
+ }
660
+ if (state.sqrtPriceX96 === step.sqrtPriceNextX96) {
661
+ if (step.initialized) {
662
+ let liquidityNet = BigInt((await this.tickDataProvider.getTick(step.tickNext)).liquidityNet);
663
+ if (zeroForOne)
664
+ liquidityNet = liquidityNet * NEGATIVE_ONE;
665
+ state.liquidity = LiquidityMath.addDelta(state.liquidity, liquidityNet);
666
+ }
667
+ state.tick = zeroForOne ? step.tickNext - 1 : step.tickNext;
668
+ } else if (state.sqrtPriceX96 !== step.sqrtPriceStartX96) {
669
+ state.tick = TickMath.getTickAtSqrtRatio(state.sqrtPriceX96);
670
+ }
671
+ }
672
+ return {
673
+ amountSpecifiedRemaining: state.amountSpecifiedRemaining,
674
+ amountCalculated: state.amountCalculated,
675
+ sqrtRatioX96: state.sqrtPriceX96,
676
+ liquidity: state.liquidity,
677
+ tickCurrent: state.tick
678
+ };
679
+ }
680
+ get tickSpacing() {
681
+ return TICK_SPACINGS[this.fee];
682
+ }
683
+ };
505
684
 
506
685
  // src/utils/maxLiquidityForAmounts.ts
507
686
  function maxLiquidityForAmount0Imprecise(sqrtRatioAX96, sqrtRatioBX96, amount0) {
@@ -544,36 +723,18 @@ function maxLiquidityForAmounts(sqrtRatioCurrentX96, sqrtRatioAX96, sqrtRatioBX9
544
723
  }
545
724
  return maxLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);
546
725
  }
547
- function nearestUsableTick(tick, tickSpacing) {
548
- invariant11(Number.isInteger(tick) && Number.isInteger(tickSpacing), "INTEGERS");
549
- invariant11(tickSpacing > 0, "TICK_SPACING");
550
- invariant11(tick >= TickMath.MIN_TICK && tick <= TickMath.MAX_TICK, "TICK_BOUND");
551
- const rounded = Math.round(tick / tickSpacing) * tickSpacing;
552
- if (rounded < TickMath.MIN_TICK)
553
- return rounded + tickSpacing;
554
- if (rounded > TickMath.MAX_TICK)
555
- return rounded - tickSpacing;
556
- return rounded;
726
+ function encodeSqrtRatioX96(amount1, amount0) {
727
+ const numerator = BigInt(amount1) << 192n;
728
+ const denominator = BigInt(amount0);
729
+ const ratioX192 = numerator / denominator;
730
+ return sqrt(ratioX192);
557
731
  }
558
732
 
559
- // src/utils/position.ts
560
- var PositionLibrary = class {
561
- /**
562
- * Cannot be constructed.
563
- */
564
- constructor() {
565
- }
566
- // replicates the portions of Position#update required to compute unaccounted fees
567
- static getTokensOwed(feeGrowthInside0LastX128, feeGrowthInside1LastX128, liquidity, feeGrowthInside0X128, feeGrowthInside1X128) {
568
- const tokensOwed0 = subIn256(feeGrowthInside0X128, feeGrowthInside0LastX128) * liquidity / Q128;
569
- const tokensOwed1 = subIn256(feeGrowthInside1X128, feeGrowthInside1LastX128) * liquidity / Q128;
570
- return [tokensOwed0, tokensOwed1];
571
- }
572
- };
733
+ // src/utils/priceTickConversions.ts
573
734
  function tickToPrice(baseToken, quoteToken, tick) {
574
735
  const sqrtRatioX96 = TickMath.getSqrtRatioAtTick(tick);
575
736
  const ratioX192 = sqrtRatioX96 * sqrtRatioX96;
576
- return baseToken.sortsBefore(quoteToken) ? new Price(baseToken, quoteToken, Q192, ratioX192) : new Price(baseToken, quoteToken, ratioX192, Q192);
737
+ return baseToken.sortsBefore(quoteToken) ? new Price$1(baseToken, quoteToken, Q192, ratioX192) : new Price$1(baseToken, quoteToken, ratioX192, Q192);
577
738
  }
578
739
  function priceToClosestTick(price) {
579
740
  const sorted = price.baseCurrency.sortsBefore(price.quoteCurrency);
@@ -590,47 +751,6 @@ function priceToClosestTick(price) {
590
751
  return tick;
591
752
  }
592
753
 
593
- // src/utils/tickLibrary.ts
594
- var Q256 = 2n ** 256n;
595
- function subIn256(x, y) {
596
- const difference = x - y;
597
- if (difference < ZERO) {
598
- return Q256 + difference;
599
- }
600
- return difference;
601
- }
602
- var TickLibrary = class {
603
- /**
604
- * Cannot be constructed.
605
- */
606
- constructor() {
607
- }
608
- static getFeeGrowthInside(feeGrowthOutsideLower, feeGrowthOutsideUpper, tickLower, tickUpper, tickCurrent, feeGrowthGlobal0X128, feeGrowthGlobal1X128) {
609
- let feeGrowthBelow0X128;
610
- let feeGrowthBelow1X128;
611
- if (tickCurrent >= tickLower) {
612
- feeGrowthBelow0X128 = feeGrowthOutsideLower.feeGrowthOutside0X128;
613
- feeGrowthBelow1X128 = feeGrowthOutsideLower.feeGrowthOutside1X128;
614
- } else {
615
- feeGrowthBelow0X128 = subIn256(feeGrowthGlobal0X128, feeGrowthOutsideLower.feeGrowthOutside0X128);
616
- feeGrowthBelow1X128 = subIn256(feeGrowthGlobal1X128, feeGrowthOutsideLower.feeGrowthOutside1X128);
617
- }
618
- let feeGrowthAbove0X128;
619
- let feeGrowthAbove1X128;
620
- if (tickCurrent < tickUpper) {
621
- feeGrowthAbove0X128 = feeGrowthOutsideUpper.feeGrowthOutside0X128;
622
- feeGrowthAbove1X128 = feeGrowthOutsideUpper.feeGrowthOutside1X128;
623
- } else {
624
- feeGrowthAbove0X128 = subIn256(feeGrowthGlobal0X128, feeGrowthOutsideUpper.feeGrowthOutside0X128);
625
- feeGrowthAbove1X128 = subIn256(feeGrowthGlobal1X128, feeGrowthOutsideUpper.feeGrowthOutside1X128);
626
- }
627
- return [
628
- subIn256(subIn256(feeGrowthGlobal0X128, feeGrowthBelow0X128), feeGrowthAbove0X128),
629
- subIn256(subIn256(feeGrowthGlobal1X128, feeGrowthBelow1X128), feeGrowthAbove1X128)
630
- ];
631
- }
632
- };
633
-
634
754
  // src/utils/positionMath.ts
635
755
  function getToken0Amount(tickCurrent, tickLower, tickUpper, sqrtRatioX96, liquidity) {
636
756
  if (tickCurrent < tickLower) {
@@ -664,914 +784,514 @@ var PositionMath = {
664
784
  getToken0Amount,
665
785
  getToken1Amount
666
786
  };
667
- function parseNumberToFraction(num, precision = 6) {
668
- const scalar = 10 ** precision;
669
- return new Fraction$1(BigInt(Math.floor(num * scalar)), BigInt(scalar));
670
- }
671
787
 
672
- // src/utils/feeCalculator.ts
673
- var FeeCalculator = {
674
- getEstimatedLPFee,
675
- getEstimatedLPFeeByAmounts,
676
- getLiquidityFromTick,
677
- getLiquidityFromSqrtRatioX96,
678
- getAverageLiquidity,
679
- getLiquidityBySingleAmount,
680
- getDependentAmount,
681
- getLiquidityByAmountsAndPrice,
682
- getAmountsByLiquidityAndPrice,
683
- getAmountsAtNewPrice
684
- };
685
- function getEstimatedLPFeeWithProtocolFee({ amount, currency, ...rest }) {
686
- return getEstimatedLPFeeByAmountsWithProtocolFee({
687
- ...rest,
688
- amountA: amount,
689
- amountB: CurrencyAmount.fromRawAmount(currency, MaxUint256)
690
- });
691
- }
692
- function getEstimatedLPFee({ amount, currency, ...rest }) {
693
- return getEstimatedLPFeeByAmounts({
694
- ...rest,
695
- amountA: amount,
696
- amountB: CurrencyAmount.fromRawAmount(currency, MaxUint256)
697
- });
698
- }
699
- function getEstimatedLPFeeByAmountsWithProtocolFee(options) {
700
- try {
701
- return tryGetEstimatedLPFeeByAmounts(options);
702
- } catch (e) {
703
- console.error(e);
704
- return new Fraction(ZERO$1);
705
- }
706
- }
707
- function getEstimatedLPFeeByAmounts({ protocolFee = ZERO_PERCENT, ...rest }) {
708
- try {
709
- const fee = tryGetEstimatedLPFeeByAmounts(rest);
710
- return ONE_HUNDRED_PERCENT.subtract(protocolFee).multiply(fee).asFraction;
711
- } catch (e) {
712
- console.error(e);
713
- return new Fraction(ZERO$1);
788
+ // src/entities/position.ts
789
+ var Position = class {
790
+ /**
791
+ * Constructs a position for a given pool with the given liquidity
792
+ * @param pool For which pool the liquidity is assigned
793
+ * @param liquidity The amount of liquidity that is in the position
794
+ * @param tickLower The lower tick of the position
795
+ * @param tickUpper The upper tick of the position
796
+ */
797
+ constructor({ pool, liquidity, tickLower, tickUpper }) {
798
+ // cached resuts for the getters
799
+ this._token0Amount = null;
800
+ this._token1Amount = null;
801
+ this._mintAmounts = null;
802
+ invariant9(tickLower < tickUpper, "TICK_ORDER");
803
+ invariant9(tickLower >= TickMath.MIN_TICK && tickLower % pool.tickSpacing === 0, "TICK_LOWER");
804
+ invariant9(tickUpper <= TickMath.MAX_TICK && tickUpper % pool.tickSpacing === 0, "TICK_UPPER");
805
+ this.pool = pool;
806
+ this.tickLower = tickLower;
807
+ this.tickUpper = tickUpper;
808
+ this.liquidity = BigInt(liquidity);
714
809
  }
715
- }
716
- function tryGetEstimatedLPFeeByAmounts({
717
- amountA,
718
- amountB,
719
- volume24H,
720
- sqrtRatioX96,
721
- tickLower,
722
- tickUpper,
723
- mostActiveLiquidity,
724
- fee,
725
- insidePercentage = ONE_HUNDRED_PERCENT
726
- }) {
727
- invariant11(!Number.isNaN(fee) && fee >= 0, "INVALID_FEE");
728
- const tickCurrent = TickMath.getTickAtSqrtRatio(sqrtRatioX96);
729
- if (tickCurrent < tickLower || tickCurrent > tickUpper) {
730
- return new Fraction(ZERO$1);
810
+ /**
811
+ * Returns the price of token0 at the lower tick
812
+ */
813
+ get token0PriceLower() {
814
+ return tickToPrice(this.pool.token0, this.pool.token1, this.tickLower);
731
815
  }
732
- const liquidity = FeeCalculator.getLiquidityByAmountsAndPrice({
733
- amountA,
734
- amountB,
735
- tickUpper,
736
- tickLower,
737
- sqrtRatioX96
738
- });
739
- return insidePercentage.multiply(parseNumberToFraction(volume24H).multiply(BigInt(fee)).multiply(liquidity)).divide(MAX_FEE * (liquidity + mostActiveLiquidity)).asFraction;
740
- }
741
- function getDependentAmount(options) {
742
- const { currency, amount, sqrtRatioX96, tickLower, tickUpper } = options;
743
- const currentTick = TickMath.getTickAtSqrtRatio(sqrtRatioX96);
744
- const liquidity = FeeCalculator.getLiquidityBySingleAmount(options);
745
- const isToken0 = currency.wrapped.sortsBefore(amount.currency.wrapped);
746
- const getTokenAmount = isToken0 ? PositionMath.getToken0Amount : PositionMath.getToken1Amount;
747
- return CurrencyAmount.fromRawAmount(
748
- currency,
749
- getTokenAmount(currentTick, tickLower, tickUpper, sqrtRatioX96, liquidity)
750
- );
751
- }
752
- function getLiquidityBySingleAmount({ amount, currency, ...rest }) {
753
- return getLiquidityByAmountsAndPrice({
754
- amountA: amount,
755
- amountB: CurrencyAmount.fromRawAmount(currency, MaxUint256),
756
- ...rest
757
- });
758
- }
759
- function getLiquidityByAmountsAndPrice({
760
- amountA,
761
- amountB,
762
- tickUpper,
763
- tickLower,
764
- sqrtRatioX96
765
- }) {
766
- const isToken0 = amountA.currency.wrapped.sortsBefore(amountB.currency.wrapped);
767
- const [inputAmount0, inputAmount1] = isToken0 ? [amountA.quotient, amountB.quotient] : [amountB.quotient, amountA.quotient];
768
- const sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(tickLower);
769
- const sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(tickUpper);
770
- return maxLiquidityForAmounts(sqrtRatioX96, sqrtRatioAX96, sqrtRatioBX96, inputAmount0, inputAmount1, true);
771
- }
772
- function getAmountsByLiquidityAndPrice(options) {
773
- const { currencyA, currencyB, liquidity, sqrtRatioX96, tickLower, tickUpper } = options;
774
- const currentTick = TickMath.getTickAtSqrtRatio(sqrtRatioX96);
775
- const isToken0 = currencyA.wrapped.sortsBefore(currencyB.wrapped);
776
- const adjustedAmount0 = PositionMath.getToken0Amount(currentTick, tickLower, tickUpper, sqrtRatioX96, liquidity);
777
- const adjustedAmount1 = PositionMath.getToken1Amount(currentTick, tickLower, tickUpper, sqrtRatioX96, liquidity);
778
- return [
779
- CurrencyAmount.fromRawAmount(currencyA, isToken0 ? adjustedAmount0 : adjustedAmount1),
780
- CurrencyAmount.fromRawAmount(currencyB, isToken0 ? adjustedAmount1 : adjustedAmount0)
781
- ];
782
- }
783
- function getAmountsAtNewPrice({ newSqrtRatioX96, ...rest }) {
784
- const { tickLower, tickUpper, amountA, amountB } = rest;
785
- const liquidity = FeeCalculator.getLiquidityByAmountsAndPrice(rest);
786
- return FeeCalculator.getAmountsByLiquidityAndPrice({
787
- liquidity,
788
- currencyA: amountA.currency,
789
- currencyB: amountB.currency,
790
- tickLower,
791
- tickUpper,
792
- sqrtRatioX96: newSqrtRatioX96
793
- });
794
- }
795
- function getAverageLiquidity(ticks, tickSpacing, tickLower, tickUpper) {
796
- invariant11(tickLower <= tickUpper, "INVALID_TICK_RANGE");
797
- TickList.validateList(ticks, tickSpacing);
798
- if (tickLower === tickUpper) {
799
- return FeeCalculator.getLiquidityFromTick(ticks, tickLower);
816
+ /**
817
+ * Returns the price of token0 at the upper tick
818
+ */
819
+ get token0PriceUpper() {
820
+ return tickToPrice(this.pool.token0, this.pool.token1, this.tickUpper);
800
821
  }
801
- const lowerOutOfBound = tickLower < ticks[0].index;
802
- let lastTick = lowerOutOfBound ? new Tick({ index: TickMath.MIN_TICK, liquidityNet: ZERO$1, liquidityGross: ZERO$1 }) : TickList.nextInitializedTick(ticks, tickLower, true);
803
- let currentTick = TickList.nextInitializedTick(ticks, tickLower, false);
804
- let currentL = lowerOutOfBound ? ZERO$1 : FeeCalculator.getLiquidityFromTick(ticks, currentTick.index);
805
- let weightedL = ZERO$1;
806
- const getWeightedLFromLastTickTo = (toTick) => currentL * BigInt(toTick - Math.max(lastTick.index, tickLower));
807
- while (currentTick.index < tickUpper) {
808
- weightedL += getWeightedLFromLastTickTo(currentTick.index);
809
- currentL += currentTick.liquidityNet;
810
- lastTick = currentTick;
811
- if (currentTick.index === ticks[ticks.length - 1].index) {
812
- break;
822
+ /**
823
+ * Returns the amount of token0 that this position's liquidity could be burned for at the current pool price
824
+ */
825
+ get amount0() {
826
+ if (this._token0Amount === null) {
827
+ this._token0Amount = CurrencyAmount.fromRawAmount(
828
+ this.pool.token0,
829
+ PositionMath.getToken0Amount(
830
+ this.pool.tickCurrent,
831
+ this.tickLower,
832
+ this.tickUpper,
833
+ this.pool.sqrtRatioX96,
834
+ this.liquidity
835
+ )
836
+ );
813
837
  }
814
- currentTick = TickList.nextInitializedTick(ticks, currentTick.index, false);
815
- }
816
- weightedL += getWeightedLFromLastTickTo(tickUpper);
817
- return weightedL / BigInt(tickUpper - tickLower);
818
- }
819
- function getLiquidityFromSqrtRatioX96(ticks, sqrtRatioX96) {
820
- const tick = TickMath.getTickAtSqrtRatio(sqrtRatioX96);
821
- return FeeCalculator.getLiquidityFromTick(ticks, tick);
822
- }
823
- function getLiquidityFromTick(ticks, tick) {
824
- let liquidity = ZERO$1;
825
- if (!ticks?.length)
826
- return liquidity;
827
- if (tick < ticks[0].index || tick > ticks[ticks.length - 1].index) {
828
- return liquidity;
838
+ return this._token0Amount;
829
839
  }
830
- for (let i = 0; i < ticks.length - 1; ++i) {
831
- liquidity += ticks[i].liquidityNet;
832
- const lowerTick = ticks[i].index;
833
- const upperTick = ticks[i + 1]?.index;
834
- if (lowerTick <= tick && tick <= upperTick) {
835
- break;
840
+ /**
841
+ * Returns the amount of token1 that this position's liquidity could be burned for at the current pool price
842
+ */
843
+ get amount1() {
844
+ if (this._token1Amount === null) {
845
+ this._token1Amount = CurrencyAmount.fromRawAmount(
846
+ this.pool.token1,
847
+ PositionMath.getToken1Amount(
848
+ this.pool.tickCurrent,
849
+ this.tickLower,
850
+ this.tickUpper,
851
+ this.pool.sqrtRatioX96,
852
+ this.liquidity
853
+ )
854
+ );
836
855
  }
837
- }
838
- return liquidity;
839
- }
840
- var FEE_BASE = 10n ** 4n;
841
- function parseProtocolFees(feeProtocol) {
842
- const packed = Number(feeProtocol);
843
- if (Number.isNaN(packed)) {
844
- throw new Error(`Invalid fee protocol ${feeProtocol}`);
845
- }
846
- const token0ProtocolFee = packed % 2 ** 16;
847
- const token1ProtocolFee = packed >> 16;
848
- return [new Percent$1(token0ProtocolFee, FEE_BASE), new Percent$1(token1ProtocolFee, FEE_BASE)];
849
- }
850
- function sqrtRatioX96ToPrice(sqrtRatioX96, currencyA, currencyB) {
851
- const ratioX192 = sqrtRatioX96 * sqrtRatioX96;
852
- return currencyA.wrapped.sortsBefore(currencyB.wrapped) ? new Price$1(currencyA.wrapped, currencyB.wrapped, Q192, ratioX192) : new Price$1(currencyA.wrapped, currencyB.wrapped, ratioX192, Q192);
853
- }
854
-
855
- // src/entities/tick.ts
856
- var Tick = class {
857
- constructor({ index, liquidityGross, liquidityNet }) {
858
- invariant11(index >= TickMath.MIN_TICK && index <= TickMath.MAX_TICK, "TICK");
859
- this.index = index;
860
- this.liquidityGross = BigInt(liquidityGross);
861
- this.liquidityNet = BigInt(liquidityNet);
862
- }
863
- };
864
-
865
- // src/entities/tickListDataProvider.ts
866
- var TickListDataProvider = class {
867
- constructor(ticks) {
868
- const ticksMapped = ticks.map((t) => t instanceof Tick ? t : new Tick(t));
869
- this.ticks = ticksMapped;
870
- }
871
- async getTick(tick) {
872
- return TickList.getTick(this.ticks, tick);
873
- }
874
- async nextInitializedTickWithinOneWord(tick, lte, tickSpacing) {
875
- return TickList.nextInitializedTickWithinOneWord(this.ticks, tick, lte, tickSpacing);
876
- }
877
- };
878
-
879
- // src/entities/pool.ts
880
- var NO_TICK_DATA_PROVIDER_DEFAULT = new NoTickDataProvider();
881
- var Pool = class {
882
- static getAddress(tokenA, tokenB, fee, initCodeHashManualOverride, deployerAddressOverride) {
883
- return computePoolAddress({
884
- deployerAddress: deployerAddressOverride ?? DEPLOYER_ADDRESSES[tokenA.chainId],
885
- fee,
886
- tokenA,
887
- tokenB,
888
- initCodeHashManualOverride
889
- });
856
+ return this._token1Amount;
890
857
  }
891
858
  /**
892
- * Construct a pool
893
- * @param tokenA One of the tokens in the pool
894
- * @param tokenB The other token in the pool
895
- * @param fee The fee in hundredths of a bips of the input amount of every swap that is collected by the pool
896
- * @param sqrtRatioX96 The sqrt of the current ratio of amounts of token1 to token0
897
- * @param liquidity The current value of in range liquidity
898
- * @param tickCurrent The current tick of the pool
899
- * @param ticks The current state of the pool ticks or a data provider that can return tick data
859
+ * Returns the lower and upper sqrt ratios if the price 'slips' up to slippage tolerance percentage
860
+ * @param slippageTolerance The amount by which the price can 'slip' before the transaction will revert
861
+ * @returns The sqrt ratios after slippage
900
862
  */
901
- constructor(tokenA, tokenB, fee, sqrtRatioX96, liquidity, tickCurrent, ticks = NO_TICK_DATA_PROVIDER_DEFAULT) {
902
- invariant11(Number.isInteger(fee) && fee < 1e6, "FEE");
903
- [this.token0, this.token1] = tokenA.sortsBefore(tokenB) ? [tokenA, tokenB] : [tokenB, tokenA];
904
- this.fee = fee;
905
- this.sqrtRatioX96 = BigInt(sqrtRatioX96);
906
- this.liquidity = BigInt(liquidity);
907
- this.tickCurrent = tickCurrent;
908
- this.tickDataProvider = Array.isArray(ticks) ? new TickListDataProvider(ticks) : ticks;
863
+ ratiosAfterSlippage(slippageTolerance) {
864
+ const priceLower = this.pool.token0Price.asFraction.multiply(new Percent$1(1).subtract(slippageTolerance));
865
+ const priceUpper = this.pool.token0Price.asFraction.multiply(slippageTolerance.add(1));
866
+ let sqrtRatioX96Lower = encodeSqrtRatioX96(priceLower.numerator, priceLower.denominator);
867
+ if (sqrtRatioX96Lower <= TickMath.MIN_SQRT_RATIO) {
868
+ sqrtRatioX96Lower = TickMath.MIN_SQRT_RATIO + 1n;
869
+ }
870
+ let sqrtRatioX96Upper = encodeSqrtRatioX96(priceUpper.numerator, priceUpper.denominator);
871
+ if (sqrtRatioX96Upper >= TickMath.MAX_SQRT_RATIO) {
872
+ sqrtRatioX96Upper = TickMath.MAX_SQRT_RATIO - 1n;
873
+ }
874
+ return {
875
+ sqrtRatioX96Lower,
876
+ sqrtRatioX96Upper
877
+ };
909
878
  }
910
879
  /**
911
- * Returns true if the token is either token0 or token1
912
- * @param token The token to check
913
- * @returns True if token is either token0 or token
880
+ * Returns the minimum amounts that must be sent in order to safely mint the amount of liquidity held by the position
881
+ * with the given slippage tolerance
882
+ * @param slippageTolerance Tolerance of unfavorable slippage from the current price
883
+ * @returns The amounts, with slippage
914
884
  */
915
- involvesToken(token) {
916
- return token.equals(this.token0) || token.equals(this.token1);
885
+ mintAmountsWithSlippage(slippageTolerance) {
886
+ const { sqrtRatioX96Upper, sqrtRatioX96Lower } = this.ratiosAfterSlippage(slippageTolerance);
887
+ const poolLower = new Pool(
888
+ this.pool.token0,
889
+ this.pool.token1,
890
+ this.pool.fee,
891
+ sqrtRatioX96Lower,
892
+ 0,
893
+ TickMath.getTickAtSqrtRatio(sqrtRatioX96Lower)
894
+ );
895
+ const poolUpper = new Pool(
896
+ this.pool.token0,
897
+ this.pool.token1,
898
+ this.pool.fee,
899
+ sqrtRatioX96Upper,
900
+ 0,
901
+ TickMath.getTickAtSqrtRatio(sqrtRatioX96Upper)
902
+ );
903
+ const positionThatWillBeCreated = Position.fromAmounts({
904
+ pool: this.pool,
905
+ tickLower: this.tickLower,
906
+ tickUpper: this.tickUpper,
907
+ ...this.mintAmounts,
908
+ // the mint amounts are what will be passed as calldata
909
+ useFullPrecision: false
910
+ });
911
+ const { amount0 } = new Position({
912
+ pool: poolUpper,
913
+ liquidity: positionThatWillBeCreated.liquidity,
914
+ tickLower: this.tickLower,
915
+ tickUpper: this.tickUpper
916
+ }).mintAmounts;
917
+ const { amount1 } = new Position({
918
+ pool: poolLower,
919
+ liquidity: positionThatWillBeCreated.liquidity,
920
+ tickLower: this.tickLower,
921
+ tickUpper: this.tickUpper
922
+ }).mintAmounts;
923
+ return { amount0, amount1 };
917
924
  }
918
925
  /**
919
- * Returns the current mid price of the pool in terms of token0, i.e. the ratio of token1 over token0
926
+ * Returns the minimum amounts that should be requested in order to safely burn the amount of liquidity held by the
927
+ * position with the given slippage tolerance
928
+ * @param slippageTolerance tolerance of unfavorable slippage from the current price
929
+ * @returns The amounts, with slippage
920
930
  */
921
- get token0Price() {
922
- return this._token0Price ?? (this._token0Price = new Price(this.token0, this.token1, Q192, this.sqrtRatioX96 * this.sqrtRatioX96));
931
+ burnAmountsWithSlippage(slippageTolerance) {
932
+ const { sqrtRatioX96Upper, sqrtRatioX96Lower } = this.ratiosAfterSlippage(slippageTolerance);
933
+ const poolLower = new Pool(
934
+ this.pool.token0,
935
+ this.pool.token1,
936
+ this.pool.fee,
937
+ sqrtRatioX96Lower,
938
+ 0,
939
+ TickMath.getTickAtSqrtRatio(sqrtRatioX96Lower)
940
+ );
941
+ const poolUpper = new Pool(
942
+ this.pool.token0,
943
+ this.pool.token1,
944
+ this.pool.fee,
945
+ sqrtRatioX96Upper,
946
+ 0,
947
+ TickMath.getTickAtSqrtRatio(sqrtRatioX96Upper)
948
+ );
949
+ const { amount0 } = new Position({
950
+ pool: poolUpper,
951
+ liquidity: this.liquidity,
952
+ tickLower: this.tickLower,
953
+ tickUpper: this.tickUpper
954
+ });
955
+ const { amount1 } = new Position({
956
+ pool: poolLower,
957
+ liquidity: this.liquidity,
958
+ tickLower: this.tickLower,
959
+ tickUpper: this.tickUpper
960
+ });
961
+ return { amount0: amount0.quotient, amount1: amount1.quotient };
923
962
  }
924
963
  /**
925
- * Returns the current mid price of the pool in terms of token1, i.e. the ratio of token0 over token1
964
+ * Returns the minimum amounts that must be sent in order to mint the amount of liquidity held by the position at
965
+ * the current price for the pool
926
966
  */
927
- get token1Price() {
928
- return this._token1Price ?? (this._token1Price = new Price(this.token1, this.token0, this.sqrtRatioX96 * this.sqrtRatioX96, Q192));
967
+ get mintAmounts() {
968
+ if (this._mintAmounts === null) {
969
+ if (this.pool.tickCurrent < this.tickLower) {
970
+ return {
971
+ amount0: SqrtPriceMath.getAmount0Delta(
972
+ TickMath.getSqrtRatioAtTick(this.tickLower),
973
+ TickMath.getSqrtRatioAtTick(this.tickUpper),
974
+ this.liquidity,
975
+ true
976
+ ),
977
+ amount1: ZERO
978
+ };
979
+ }
980
+ if (this.pool.tickCurrent < this.tickUpper) {
981
+ return {
982
+ amount0: SqrtPriceMath.getAmount0Delta(
983
+ this.pool.sqrtRatioX96,
984
+ TickMath.getSqrtRatioAtTick(this.tickUpper),
985
+ this.liquidity,
986
+ true
987
+ ),
988
+ amount1: SqrtPriceMath.getAmount1Delta(
989
+ TickMath.getSqrtRatioAtTick(this.tickLower),
990
+ this.pool.sqrtRatioX96,
991
+ this.liquidity,
992
+ true
993
+ )
994
+ };
995
+ }
996
+ return {
997
+ amount0: ZERO,
998
+ amount1: SqrtPriceMath.getAmount1Delta(
999
+ TickMath.getSqrtRatioAtTick(this.tickLower),
1000
+ TickMath.getSqrtRatioAtTick(this.tickUpper),
1001
+ this.liquidity,
1002
+ true
1003
+ )
1004
+ };
1005
+ }
1006
+ return this._mintAmounts;
929
1007
  }
930
1008
  /**
931
- * Return the price of the given token in terms of the other token in the pool.
932
- * @param token The token to return price of
933
- * @returns The price of the given token, in terms of the other.
1009
+ * Computes the maximum amount of liquidity received for a given amount of token0, token1,
1010
+ * and the prices at the tick boundaries.
1011
+ * @param pool The pool for which the position should be created
1012
+ * @param tickLower The lower tick of the position
1013
+ * @param tickUpper The upper tick of the position
1014
+ * @param amount0 token0 amount
1015
+ * @param amount1 token1 amount
1016
+ * @param useFullPrecision If false, liquidity will be maximized according to what the router can calculate,
1017
+ * not what core can theoretically support
1018
+ * @returns The amount of liquidity for the position
934
1019
  */
935
- priceOf(token) {
936
- invariant11(this.involvesToken(token), "TOKEN");
937
- return token.equals(this.token0) ? this.token0Price : this.token1Price;
1020
+ static fromAmounts({
1021
+ pool,
1022
+ tickLower,
1023
+ tickUpper,
1024
+ amount0,
1025
+ amount1,
1026
+ useFullPrecision
1027
+ }) {
1028
+ const sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(tickLower);
1029
+ const sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(tickUpper);
1030
+ return new Position({
1031
+ pool,
1032
+ tickLower,
1033
+ tickUpper,
1034
+ liquidity: maxLiquidityForAmounts(
1035
+ pool.sqrtRatioX96,
1036
+ sqrtRatioAX96,
1037
+ sqrtRatioBX96,
1038
+ amount0,
1039
+ amount1,
1040
+ useFullPrecision
1041
+ )
1042
+ });
938
1043
  }
939
1044
  /**
940
- * Returns the chain ID of the tokens in the pool.
941
- */
942
- get chainId() {
943
- return this.token0.chainId;
1045
+ * Computes a position with the maximum amount of liquidity received for a given amount of token0, assuming an unlimited amount of token1
1046
+ * @param pool The pool for which the position is created
1047
+ * @param tickLower The lower tick
1048
+ * @param tickUpper The upper tick
1049
+ * @param amount0 The desired amount of token0
1050
+ * @param useFullPrecision If true, liquidity will be maximized according to what the router can calculate,
1051
+ * not what core can theoretically support
1052
+ * @returns The position
1053
+ */
1054
+ static fromAmount0({
1055
+ pool,
1056
+ tickLower,
1057
+ tickUpper,
1058
+ amount0,
1059
+ useFullPrecision
1060
+ }) {
1061
+ return Position.fromAmounts({ pool, tickLower, tickUpper, amount0, amount1: MaxUint256$1, useFullPrecision });
944
1062
  }
945
1063
  /**
946
- * Given an input amount of a token, return the computed output amount, and a pool with state updated after the trade
947
- * @param inputAmount The input amount for which to quote the output amount
948
- * @param sqrtPriceLimitX96 The Q64.96 sqrt price limit
949
- * @returns The output amount and the pool with updated state
1064
+ * Computes a position with the maximum amount of liquidity received for a given amount of token1, assuming an unlimited amount of token0
1065
+ * @param pool The pool for which the position is created
1066
+ * @param tickLower The lower tick
1067
+ * @param tickUpper The upper tick
1068
+ * @param amount1 The desired amount of token1
1069
+ * @returns The position
950
1070
  */
951
- async getOutputAmount(inputAmount, sqrtPriceLimitX96) {
952
- invariant11(this.involvesToken(inputAmount.currency), "TOKEN");
953
- const zeroForOne = inputAmount.currency.equals(this.token0);
954
- const {
955
- amountCalculated: outputAmount,
956
- sqrtRatioX96,
957
- liquidity,
958
- tickCurrent
959
- } = await this.swap(zeroForOne, inputAmount.quotient, sqrtPriceLimitX96);
960
- const outputToken = zeroForOne ? this.token1 : this.token0;
961
- return [
962
- CurrencyAmount.fromRawAmount(outputToken, outputAmount * NEGATIVE_ONE),
963
- new Pool(this.token0, this.token1, this.fee, sqrtRatioX96, liquidity, tickCurrent, this.tickDataProvider)
964
- ];
1071
+ static fromAmount1({
1072
+ pool,
1073
+ tickLower,
1074
+ tickUpper,
1075
+ amount1
1076
+ }) {
1077
+ return Position.fromAmounts({ pool, tickLower, tickUpper, amount0: MaxUint256$1, amount1, useFullPrecision: true });
965
1078
  }
1079
+ };
1080
+ var Route = class {
966
1081
  /**
967
- * Given a desired output amount of a token, return the computed input amount and a pool with state updated after the trade
968
- * @param outputAmount the output amount for which to quote the input amount
969
- * @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this value after the swap. If one for zero, the price cannot be greater than this value after the swap
970
- * @returns The input amount and the pool with updated state
1082
+ * Creates an instance of route.
1083
+ * @param pools An array of `Pool` objects, ordered by the route the swap will take
1084
+ * @param input The input token
1085
+ * @param output The output token
971
1086
  */
972
- async getInputAmount(outputAmount, sqrtPriceLimitX96) {
973
- invariant11(outputAmount.currency.isToken && this.involvesToken(outputAmount.currency), "TOKEN");
974
- const zeroForOne = outputAmount.currency.equals(this.token1);
975
- const {
976
- amountSpecifiedRemaining,
977
- amountCalculated: inputAmount,
978
- sqrtRatioX96,
979
- liquidity,
980
- tickCurrent
981
- } = await this.swap(zeroForOne, outputAmount.quotient * NEGATIVE_ONE, sqrtPriceLimitX96);
982
- invariant11(amountSpecifiedRemaining === ZERO, "INSUFICIENT_LIQUIDITY");
983
- const inputToken = zeroForOne ? this.token0 : this.token1;
984
- return [
985
- CurrencyAmount.fromRawAmount(inputToken, inputAmount),
986
- new Pool(this.token0, this.token1, this.fee, sqrtRatioX96, liquidity, tickCurrent, this.tickDataProvider)
987
- ];
1087
+ constructor(pools, input, output) {
1088
+ this._midPrice = null;
1089
+ invariant9(pools.length > 0, "POOLS");
1090
+ const { chainId } = pools[0];
1091
+ const allOnSameChain = pools.every((pool) => pool.chainId === chainId);
1092
+ invariant9(allOnSameChain, "CHAIN_IDS");
1093
+ const wrappedInput = input.wrapped;
1094
+ invariant9(pools[0].involvesToken(wrappedInput), "INPUT");
1095
+ invariant9(pools[pools.length - 1].involvesToken(output.wrapped), "OUTPUT");
1096
+ const tokenPath = [wrappedInput];
1097
+ for (const [i, pool] of pools.entries()) {
1098
+ const currentInputToken = tokenPath[i];
1099
+ invariant9(currentInputToken.equals(pool.token0) || currentInputToken.equals(pool.token1), "PATH");
1100
+ const nextToken = currentInputToken.equals(pool.token0) ? pool.token1 : pool.token0;
1101
+ tokenPath.push(nextToken);
1102
+ }
1103
+ this.pools = pools;
1104
+ this.tokenPath = tokenPath;
1105
+ this.input = input;
1106
+ this.output = output ?? tokenPath[tokenPath.length - 1];
1107
+ }
1108
+ get chainId() {
1109
+ return this.pools[0].chainId;
988
1110
  }
989
1111
  /**
990
- * Executes a swap
991
- * @param zeroForOne Whether the amount in is token0 or token1
992
- * @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative)
993
- * @param sqrtPriceLimitX96 The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this value after the swap. If one for zero, the price cannot be greater than this value after the swap
994
- * @returns amountCalculated
995
- * @returns sqrtRatioX96
996
- * @returns liquidity
997
- * @returns tickCurrent
1112
+ * Returns the mid price of the route
998
1113
  */
999
- async swap(zeroForOne, amountSpecified, sqrtPriceLimitX96) {
1000
- if (!sqrtPriceLimitX96)
1001
- sqrtPriceLimitX96 = zeroForOne ? TickMath.MIN_SQRT_RATIO + ONE : TickMath.MAX_SQRT_RATIO - ONE;
1002
- if (zeroForOne) {
1003
- invariant11(sqrtPriceLimitX96 > TickMath.MIN_SQRT_RATIO, "RATIO_MIN");
1004
- invariant11(sqrtPriceLimitX96 < this.sqrtRatioX96, "RATIO_CURRENT");
1005
- } else {
1006
- invariant11(sqrtPriceLimitX96 < TickMath.MAX_SQRT_RATIO, "RATIO_MAX");
1007
- invariant11(sqrtPriceLimitX96 > this.sqrtRatioX96, "RATIO_CURRENT");
1008
- }
1009
- const exactInput = amountSpecified >= ZERO;
1010
- const state = {
1011
- amountSpecifiedRemaining: amountSpecified,
1012
- amountCalculated: ZERO,
1013
- sqrtPriceX96: this.sqrtRatioX96,
1014
- tick: this.tickCurrent,
1015
- liquidity: this.liquidity
1016
- };
1017
- while (state.amountSpecifiedRemaining !== ZERO && state.sqrtPriceX96 != sqrtPriceLimitX96) {
1018
- const step = {};
1019
- step.sqrtPriceStartX96 = state.sqrtPriceX96;
1020
- [step.tickNext, step.initialized] = await this.tickDataProvider.nextInitializedTickWithinOneWord(
1021
- state.tick,
1022
- zeroForOne,
1023
- this.tickSpacing
1024
- );
1025
- if (step.tickNext < TickMath.MIN_TICK) {
1026
- step.tickNext = TickMath.MIN_TICK;
1027
- } else if (step.tickNext > TickMath.MAX_TICK) {
1028
- step.tickNext = TickMath.MAX_TICK;
1029
- }
1030
- step.sqrtPriceNextX96 = TickMath.getSqrtRatioAtTick(step.tickNext);
1031
- [state.sqrtPriceX96, step.amountIn, step.amountOut, step.feeAmount] = SwapMath.computeSwapStep(
1032
- state.sqrtPriceX96,
1033
- (zeroForOne ? step.sqrtPriceNextX96 < sqrtPriceLimitX96 : step.sqrtPriceNextX96 > sqrtPriceLimitX96) ? sqrtPriceLimitX96 : step.sqrtPriceNextX96,
1034
- state.liquidity,
1035
- state.amountSpecifiedRemaining,
1036
- this.fee
1037
- );
1038
- if (exactInput) {
1039
- state.amountSpecifiedRemaining = state.amountSpecifiedRemaining - (step.amountIn + step.feeAmount);
1040
- state.amountCalculated = state.amountCalculated - step.amountOut;
1041
- } else {
1042
- state.amountSpecifiedRemaining = state.amountSpecifiedRemaining + step.amountOut;
1043
- state.amountCalculated = state.amountCalculated + (step.amountIn + step.feeAmount);
1044
- }
1045
- if (state.sqrtPriceX96 === step.sqrtPriceNextX96) {
1046
- if (step.initialized) {
1047
- let liquidityNet = BigInt((await this.tickDataProvider.getTick(step.tickNext)).liquidityNet);
1048
- if (zeroForOne)
1049
- liquidityNet = liquidityNet * NEGATIVE_ONE;
1050
- state.liquidity = LiquidityMath.addDelta(state.liquidity, liquidityNet);
1051
- }
1052
- state.tick = zeroForOne ? step.tickNext - 1 : step.tickNext;
1053
- } else if (state.sqrtPriceX96 !== step.sqrtPriceStartX96) {
1054
- state.tick = TickMath.getTickAtSqrtRatio(state.sqrtPriceX96);
1114
+ get midPrice() {
1115
+ if (this._midPrice !== null)
1116
+ return this._midPrice;
1117
+ const { price } = this.pools.slice(1).reduce(
1118
+ ({ nextInput, price: price2 }, pool) => {
1119
+ return nextInput.equals(pool.token0) ? {
1120
+ nextInput: pool.token1,
1121
+ price: price2.multiply(pool.token0Price)
1122
+ } : {
1123
+ nextInput: pool.token0,
1124
+ price: price2.multiply(pool.token1Price)
1125
+ };
1126
+ },
1127
+ this.pools[0].token0.equals(this.input.wrapped) ? {
1128
+ nextInput: this.pools[0].token1,
1129
+ price: this.pools[0].token0Price
1130
+ } : {
1131
+ nextInput: this.pools[0].token0,
1132
+ price: this.pools[0].token1Price
1055
1133
  }
1134
+ );
1135
+ return this._midPrice = new Price$1(this.input, this.output, price.denominator, price.numerator);
1136
+ }
1137
+ };
1138
+ function tradeComparator(a, b) {
1139
+ invariant9(a.inputAmount.currency.equals(b.inputAmount.currency), "INPUT_CURRENCY");
1140
+ invariant9(a.outputAmount.currency.equals(b.outputAmount.currency), "OUTPUT_CURRENCY");
1141
+ if (a.outputAmount.equalTo(b.outputAmount)) {
1142
+ if (a.inputAmount.equalTo(b.inputAmount)) {
1143
+ const aHops = a.swaps.reduce((total, cur) => total + cur.route.tokenPath.length, 0);
1144
+ const bHops = b.swaps.reduce((total, cur) => total + cur.route.tokenPath.length, 0);
1145
+ return aHops - bHops;
1056
1146
  }
1057
- return {
1058
- amountSpecifiedRemaining: state.amountSpecifiedRemaining,
1059
- amountCalculated: state.amountCalculated,
1060
- sqrtRatioX96: state.sqrtPriceX96,
1061
- liquidity: state.liquidity,
1062
- tickCurrent: state.tick
1063
- };
1147
+ if (a.inputAmount.lessThan(b.inputAmount)) {
1148
+ return -1;
1149
+ }
1150
+ return 1;
1064
1151
  }
1065
- get tickSpacing() {
1066
- return TICK_SPACINGS[this.fee];
1152
+ if (a.outputAmount.lessThan(b.outputAmount)) {
1153
+ return 1;
1067
1154
  }
1068
- };
1069
- var Position = class {
1155
+ return -1;
1156
+ }
1157
+ var Trade = class {
1070
1158
  /**
1071
- * Constructs a position for a given pool with the given liquidity
1072
- * @param pool For which pool the liquidity is assigned
1073
- * @param liquidity The amount of liquidity that is in the position
1074
- * @param tickLower The lower tick of the position
1075
- * @param tickUpper The upper tick of the position
1159
+ * @deprecated Deprecated in favor of 'swaps' property. If the trade consists of multiple routes
1160
+ * this will return an error.
1161
+ *
1162
+ * When the trade consists of just a single route, this returns the route of the trade,
1163
+ * i.e. which pools the trade goes through.
1076
1164
  */
1077
- constructor({ pool, liquidity, tickLower, tickUpper }) {
1078
- // cached resuts for the getters
1079
- this._token0Amount = null;
1080
- this._token1Amount = null;
1081
- this._mintAmounts = null;
1082
- invariant11(tickLower < tickUpper, "TICK_ORDER");
1083
- invariant11(tickLower >= TickMath.MIN_TICK && tickLower % pool.tickSpacing === 0, "TICK_LOWER");
1084
- invariant11(tickUpper <= TickMath.MAX_TICK && tickUpper % pool.tickSpacing === 0, "TICK_UPPER");
1085
- this.pool = pool;
1086
- this.tickLower = tickLower;
1087
- this.tickUpper = tickUpper;
1088
- this.liquidity = BigInt(liquidity);
1165
+ get route() {
1166
+ invariant9(this.swaps.length == 1, "MULTIPLE_ROUTES");
1167
+ return this.swaps[0].route;
1089
1168
  }
1090
1169
  /**
1091
- * Returns the price of token0 at the lower tick
1170
+ * The input amount for the trade assuming no slippage.
1092
1171
  */
1093
- get token0PriceLower() {
1094
- return tickToPrice(this.pool.token0, this.pool.token1, this.tickLower);
1172
+ get inputAmount() {
1173
+ if (this._inputAmount) {
1174
+ return this._inputAmount;
1175
+ }
1176
+ const inputCurrency = this.swaps[0].inputAmount.currency;
1177
+ const totalInputFromRoutes = this.swaps.map(({ inputAmount }) => inputAmount).reduce((total, cur) => total.add(cur), CurrencyAmount.fromRawAmount(inputCurrency, 0));
1178
+ this._inputAmount = totalInputFromRoutes;
1179
+ return this._inputAmount;
1095
1180
  }
1096
1181
  /**
1097
- * Returns the price of token0 at the upper tick
1182
+ * The output amount for the trade assuming no slippage.
1098
1183
  */
1099
- get token0PriceUpper() {
1100
- return tickToPrice(this.pool.token0, this.pool.token1, this.tickUpper);
1184
+ get outputAmount() {
1185
+ if (this._outputAmount) {
1186
+ return this._outputAmount;
1187
+ }
1188
+ const outputCurrency = this.swaps[0].outputAmount.currency;
1189
+ const totalOutputFromRoutes = this.swaps.map(({ outputAmount }) => outputAmount).reduce((total, cur) => total.add(cur), CurrencyAmount.fromRawAmount(outputCurrency, 0));
1190
+ this._outputAmount = totalOutputFromRoutes;
1191
+ return this._outputAmount;
1101
1192
  }
1102
1193
  /**
1103
- * Returns the amount of token0 that this position's liquidity could be burned for at the current pool price
1194
+ * The price expressed in terms of output amount/input amount.
1104
1195
  */
1105
- get amount0() {
1106
- if (this._token0Amount === null) {
1107
- this._token0Amount = CurrencyAmount.fromRawAmount(
1108
- this.pool.token0,
1109
- PositionMath.getToken0Amount(
1110
- this.pool.tickCurrent,
1111
- this.tickLower,
1112
- this.tickUpper,
1113
- this.pool.sqrtRatioX96,
1114
- this.liquidity
1115
- )
1116
- );
1117
- }
1118
- return this._token0Amount;
1119
- }
1120
- /**
1121
- * Returns the amount of token1 that this position's liquidity could be burned for at the current pool price
1122
- */
1123
- get amount1() {
1124
- if (this._token1Amount === null) {
1125
- this._token1Amount = CurrencyAmount.fromRawAmount(
1126
- this.pool.token1,
1127
- PositionMath.getToken1Amount(
1128
- this.pool.tickCurrent,
1129
- this.tickLower,
1130
- this.tickUpper,
1131
- this.pool.sqrtRatioX96,
1132
- this.liquidity
1133
- )
1134
- );
1135
- }
1136
- return this._token1Amount;
1196
+ get executionPrice() {
1197
+ return this._executionPrice ?? (this._executionPrice = new Price(
1198
+ this.inputAmount.currency,
1199
+ this.outputAmount.currency,
1200
+ this.inputAmount.quotient,
1201
+ this.outputAmount.quotient
1202
+ ));
1137
1203
  }
1138
1204
  /**
1139
- * Returns the lower and upper sqrt ratios if the price 'slips' up to slippage tolerance percentage
1140
- * @param slippageTolerance The amount by which the price can 'slip' before the transaction will revert
1141
- * @returns The sqrt ratios after slippage
1205
+ * Returns the percent difference between the route's mid price and the price impact
1142
1206
  */
1143
- ratiosAfterSlippage(slippageTolerance) {
1144
- const priceLower = this.pool.token0Price.asFraction.multiply(new Percent$1(1).subtract(slippageTolerance));
1145
- const priceUpper = this.pool.token0Price.asFraction.multiply(slippageTolerance.add(1));
1146
- let sqrtRatioX96Lower = encodeSqrtRatioX96(priceLower.numerator, priceLower.denominator);
1147
- if (sqrtRatioX96Lower <= TickMath.MIN_SQRT_RATIO) {
1148
- sqrtRatioX96Lower = TickMath.MIN_SQRT_RATIO + 1n;
1207
+ get priceImpact() {
1208
+ if (this._priceImpact) {
1209
+ return this._priceImpact;
1149
1210
  }
1150
- let sqrtRatioX96Upper = encodeSqrtRatioX96(priceUpper.numerator, priceUpper.denominator);
1151
- if (sqrtRatioX96Upper >= TickMath.MAX_SQRT_RATIO) {
1152
- sqrtRatioX96Upper = TickMath.MAX_SQRT_RATIO - 1n;
1211
+ let spotOutputAmount = CurrencyAmount.fromRawAmount(this.outputAmount.currency, 0);
1212
+ for (const { route, inputAmount } of this.swaps) {
1213
+ const { midPrice } = route;
1214
+ spotOutputAmount = spotOutputAmount.add(midPrice.quote(inputAmount));
1153
1215
  }
1154
- return {
1155
- sqrtRatioX96Lower,
1156
- sqrtRatioX96Upper
1157
- };
1216
+ const priceImpact = spotOutputAmount.subtract(this.outputAmount).divide(spotOutputAmount);
1217
+ this._priceImpact = new Percent$1(priceImpact.numerator, priceImpact.denominator);
1218
+ return this._priceImpact;
1158
1219
  }
1159
1220
  /**
1160
- * Returns the minimum amounts that must be sent in order to safely mint the amount of liquidity held by the position
1161
- * with the given slippage tolerance
1162
- * @param slippageTolerance Tolerance of unfavorable slippage from the current price
1163
- * @returns The amounts, with slippage
1221
+ * Constructs an exact in trade with the given amount in and route
1222
+ * @template TInput The input token, either Ether or an ERC-20
1223
+ * @template TOutput The output token, either Ether or an ERC-20
1224
+ * @param route The route of the exact in trade
1225
+ * @param amountIn The amount being passed in
1226
+ * @returns The exact in trade
1164
1227
  */
1165
- mintAmountsWithSlippage(slippageTolerance) {
1166
- const { sqrtRatioX96Upper, sqrtRatioX96Lower } = this.ratiosAfterSlippage(slippageTolerance);
1167
- const poolLower = new Pool(
1168
- this.pool.token0,
1169
- this.pool.token1,
1170
- this.pool.fee,
1171
- sqrtRatioX96Lower,
1172
- 0,
1173
- TickMath.getTickAtSqrtRatio(sqrtRatioX96Lower)
1174
- );
1175
- const poolUpper = new Pool(
1176
- this.pool.token0,
1177
- this.pool.token1,
1178
- this.pool.fee,
1179
- sqrtRatioX96Upper,
1180
- 0,
1181
- TickMath.getTickAtSqrtRatio(sqrtRatioX96Upper)
1182
- );
1183
- const positionThatWillBeCreated = Position.fromAmounts({
1184
- pool: this.pool,
1185
- tickLower: this.tickLower,
1186
- tickUpper: this.tickUpper,
1187
- ...this.mintAmounts,
1188
- // the mint amounts are what will be passed as calldata
1189
- useFullPrecision: false
1190
- });
1191
- const { amount0 } = new Position({
1192
- pool: poolUpper,
1193
- liquidity: positionThatWillBeCreated.liquidity,
1194
- tickLower: this.tickLower,
1195
- tickUpper: this.tickUpper
1196
- }).mintAmounts;
1197
- const { amount1 } = new Position({
1198
- pool: poolLower,
1199
- liquidity: positionThatWillBeCreated.liquidity,
1200
- tickLower: this.tickLower,
1201
- tickUpper: this.tickUpper
1202
- }).mintAmounts;
1203
- return { amount0, amount1 };
1228
+ static async exactIn(route, amountIn) {
1229
+ return Trade.fromRoute(route, amountIn, TradeType.EXACT_INPUT);
1204
1230
  }
1205
1231
  /**
1206
- * Returns the minimum amounts that should be requested in order to safely burn the amount of liquidity held by the
1207
- * position with the given slippage tolerance
1208
- * @param slippageTolerance tolerance of unfavorable slippage from the current price
1209
- * @returns The amounts, with slippage
1232
+ * Constructs an exact out trade with the given amount out and route
1233
+ * @template TInput The input token, either Ether or an ERC-20
1234
+ * @template TOutput The output token, either Ether or an ERC-20
1235
+ * @param route The route of the exact out trade
1236
+ * @param amountOut The amount returned by the trade
1237
+ * @returns The exact out trade
1210
1238
  */
1211
- burnAmountsWithSlippage(slippageTolerance) {
1212
- const { sqrtRatioX96Upper, sqrtRatioX96Lower } = this.ratiosAfterSlippage(slippageTolerance);
1213
- const poolLower = new Pool(
1214
- this.pool.token0,
1215
- this.pool.token1,
1216
- this.pool.fee,
1217
- sqrtRatioX96Lower,
1218
- 0,
1219
- TickMath.getTickAtSqrtRatio(sqrtRatioX96Lower)
1220
- );
1221
- const poolUpper = new Pool(
1222
- this.pool.token0,
1223
- this.pool.token1,
1224
- this.pool.fee,
1225
- sqrtRatioX96Upper,
1226
- 0,
1227
- TickMath.getTickAtSqrtRatio(sqrtRatioX96Upper)
1228
- );
1229
- const { amount0 } = new Position({
1230
- pool: poolUpper,
1231
- liquidity: this.liquidity,
1232
- tickLower: this.tickLower,
1233
- tickUpper: this.tickUpper
1234
- });
1235
- const { amount1 } = new Position({
1236
- pool: poolLower,
1237
- liquidity: this.liquidity,
1238
- tickLower: this.tickLower,
1239
- tickUpper: this.tickUpper
1240
- });
1241
- return { amount0: amount0.quotient, amount1: amount1.quotient };
1239
+ static async exactOut(route, amountOut) {
1240
+ return Trade.fromRoute(route, amountOut, TradeType.EXACT_OUTPUT);
1242
1241
  }
1243
1242
  /**
1244
- * Returns the minimum amounts that must be sent in order to mint the amount of liquidity held by the position at
1245
- * the current price for the pool
1243
+ * Constructs a trade by simulating swaps through the given route
1244
+ * @template TInput The input token, either Ether or an ERC-20.
1245
+ * @template TOutput The output token, either Ether or an ERC-20.
1246
+ * @template TTradeType The type of the trade, either exact in or exact out.
1247
+ * @param route route to swap through
1248
+ * @param amount the amount specified, either input or output, depending on tradeType
1249
+ * @param tradeType whether the trade is an exact input or exact output swap
1250
+ * @returns The route
1246
1251
  */
1247
- get mintAmounts() {
1248
- if (this._mintAmounts === null) {
1249
- if (this.pool.tickCurrent < this.tickLower) {
1250
- return {
1251
- amount0: SqrtPriceMath.getAmount0Delta(
1252
- TickMath.getSqrtRatioAtTick(this.tickLower),
1253
- TickMath.getSqrtRatioAtTick(this.tickUpper),
1254
- this.liquidity,
1255
- true
1256
- ),
1257
- amount1: ZERO
1258
- };
1252
+ static async fromRoute(route, amount, tradeType) {
1253
+ const amounts = new Array(route.tokenPath.length);
1254
+ let inputAmount;
1255
+ let outputAmount;
1256
+ if (tradeType === TradeType.EXACT_INPUT) {
1257
+ invariant9(amount.currency.equals(route.input), "INPUT");
1258
+ amounts[0] = amount.wrapped;
1259
+ for (let i = 0; i < route.tokenPath.length - 1; i++) {
1260
+ const pool = route.pools[i];
1261
+ const [outputAmount2] = await pool.getOutputAmount(amounts[i]);
1262
+ amounts[i + 1] = outputAmount2;
1259
1263
  }
1260
- if (this.pool.tickCurrent < this.tickUpper) {
1261
- return {
1262
- amount0: SqrtPriceMath.getAmount0Delta(
1263
- this.pool.sqrtRatioX96,
1264
- TickMath.getSqrtRatioAtTick(this.tickUpper),
1265
- this.liquidity,
1266
- true
1267
- ),
1268
- amount1: SqrtPriceMath.getAmount1Delta(
1269
- TickMath.getSqrtRatioAtTick(this.tickLower),
1270
- this.pool.sqrtRatioX96,
1271
- this.liquidity,
1272
- true
1273
- )
1274
- };
1264
+ inputAmount = CurrencyAmount.fromFractionalAmount(route.input, amount.numerator, amount.denominator);
1265
+ outputAmount = CurrencyAmount.fromFractionalAmount(
1266
+ route.output,
1267
+ amounts[amounts.length - 1].numerator,
1268
+ amounts[amounts.length - 1].denominator
1269
+ );
1270
+ } else {
1271
+ invariant9(amount.currency.equals(route.output), "OUTPUT");
1272
+ amounts[amounts.length - 1] = amount.wrapped;
1273
+ for (let i = route.tokenPath.length - 1; i > 0; i--) {
1274
+ const pool = route.pools[i - 1];
1275
+ const [inputAmount2] = await pool.getInputAmount(amounts[i]);
1276
+ amounts[i - 1] = inputAmount2;
1275
1277
  }
1276
- return {
1277
- amount0: ZERO,
1278
- amount1: SqrtPriceMath.getAmount1Delta(
1279
- TickMath.getSqrtRatioAtTick(this.tickLower),
1280
- TickMath.getSqrtRatioAtTick(this.tickUpper),
1281
- this.liquidity,
1282
- true
1283
- )
1284
- };
1278
+ inputAmount = CurrencyAmount.fromFractionalAmount(route.input, amounts[0].numerator, amounts[0].denominator);
1279
+ outputAmount = CurrencyAmount.fromFractionalAmount(route.output, amount.numerator, amount.denominator);
1285
1280
  }
1286
- return this._mintAmounts;
1281
+ return new Trade({
1282
+ routes: [{ inputAmount, outputAmount, route }],
1283
+ tradeType
1284
+ });
1287
1285
  }
1288
1286
  /**
1289
- * Computes the maximum amount of liquidity received for a given amount of token0, token1,
1290
- * and the prices at the tick boundaries.
1291
- * @param pool The pool for which the position should be created
1292
- * @param tickLower The lower tick of the position
1293
- * @param tickUpper The upper tick of the position
1294
- * @param amount0 token0 amount
1295
- * @param amount1 token1 amount
1296
- * @param useFullPrecision If false, liquidity will be maximized according to what the router can calculate,
1297
- * not what core can theoretically support
1298
- * @returns The amount of liquidity for the position
1299
- */
1300
- static fromAmounts({
1301
- pool,
1302
- tickLower,
1303
- tickUpper,
1304
- amount0,
1305
- amount1,
1306
- useFullPrecision
1307
- }) {
1308
- const sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(tickLower);
1309
- const sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(tickUpper);
1310
- return new Position({
1311
- pool,
1312
- tickLower,
1313
- tickUpper,
1314
- liquidity: maxLiquidityForAmounts(
1315
- pool.sqrtRatioX96,
1316
- sqrtRatioAX96,
1317
- sqrtRatioBX96,
1318
- amount0,
1319
- amount1,
1320
- useFullPrecision
1321
- )
1322
- });
1323
- }
1324
- /**
1325
- * Computes a position with the maximum amount of liquidity received for a given amount of token0, assuming an unlimited amount of token1
1326
- * @param pool The pool for which the position is created
1327
- * @param tickLower The lower tick
1328
- * @param tickUpper The upper tick
1329
- * @param amount0 The desired amount of token0
1330
- * @param useFullPrecision If true, liquidity will be maximized according to what the router can calculate,
1331
- * not what core can theoretically support
1332
- * @returns The position
1333
- */
1334
- static fromAmount0({
1335
- pool,
1336
- tickLower,
1337
- tickUpper,
1338
- amount0,
1339
- useFullPrecision
1340
- }) {
1341
- return Position.fromAmounts({ pool, tickLower, tickUpper, amount0, amount1: MaxUint256, useFullPrecision });
1342
- }
1343
- /**
1344
- * Computes a position with the maximum amount of liquidity received for a given amount of token1, assuming an unlimited amount of token0
1345
- * @param pool The pool for which the position is created
1346
- * @param tickLower The lower tick
1347
- * @param tickUpper The upper tick
1348
- * @param amount1 The desired amount of token1
1349
- * @returns The position
1350
- */
1351
- static fromAmount1({
1352
- pool,
1353
- tickLower,
1354
- tickUpper,
1355
- amount1
1356
- }) {
1357
- return Position.fromAmounts({ pool, tickLower, tickUpper, amount0: MaxUint256, amount1, useFullPrecision: true });
1358
- }
1359
- };
1360
- var Route = class {
1361
- /**
1362
- * Creates an instance of route.
1363
- * @param pools An array of `Pool` objects, ordered by the route the swap will take
1364
- * @param input The input token
1365
- * @param output The output token
1366
- */
1367
- constructor(pools, input, output) {
1368
- this._midPrice = null;
1369
- invariant11(pools.length > 0, "POOLS");
1370
- const { chainId } = pools[0];
1371
- const allOnSameChain = pools.every((pool) => pool.chainId === chainId);
1372
- invariant11(allOnSameChain, "CHAIN_IDS");
1373
- const wrappedInput = input.wrapped;
1374
- invariant11(pools[0].involvesToken(wrappedInput), "INPUT");
1375
- invariant11(pools[pools.length - 1].involvesToken(output.wrapped), "OUTPUT");
1376
- const tokenPath = [wrappedInput];
1377
- for (const [i, pool] of pools.entries()) {
1378
- const currentInputToken = tokenPath[i];
1379
- invariant11(currentInputToken.equals(pool.token0) || currentInputToken.equals(pool.token1), "PATH");
1380
- const nextToken = currentInputToken.equals(pool.token0) ? pool.token1 : pool.token0;
1381
- tokenPath.push(nextToken);
1382
- }
1383
- this.pools = pools;
1384
- this.tokenPath = tokenPath;
1385
- this.input = input;
1386
- this.output = output ?? tokenPath[tokenPath.length - 1];
1387
- }
1388
- get chainId() {
1389
- return this.pools[0].chainId;
1390
- }
1391
- /**
1392
- * Returns the mid price of the route
1393
- */
1394
- get midPrice() {
1395
- if (this._midPrice !== null)
1396
- return this._midPrice;
1397
- const { price } = this.pools.slice(1).reduce(
1398
- ({ nextInput, price: price2 }, pool) => {
1399
- return nextInput.equals(pool.token0) ? {
1400
- nextInput: pool.token1,
1401
- price: price2.multiply(pool.token0Price)
1402
- } : {
1403
- nextInput: pool.token0,
1404
- price: price2.multiply(pool.token1Price)
1405
- };
1406
- },
1407
- this.pools[0].token0.equals(this.input.wrapped) ? {
1408
- nextInput: this.pools[0].token1,
1409
- price: this.pools[0].token0Price
1410
- } : {
1411
- nextInput: this.pools[0].token0,
1412
- price: this.pools[0].token1Price
1413
- }
1414
- );
1415
- return this._midPrice = new Price$1(this.input, this.output, price.denominator, price.numerator);
1416
- }
1417
- };
1418
- function tradeComparator(a, b) {
1419
- invariant11(a.inputAmount.currency.equals(b.inputAmount.currency), "INPUT_CURRENCY");
1420
- invariant11(a.outputAmount.currency.equals(b.outputAmount.currency), "OUTPUT_CURRENCY");
1421
- if (a.outputAmount.equalTo(b.outputAmount)) {
1422
- if (a.inputAmount.equalTo(b.inputAmount)) {
1423
- const aHops = a.swaps.reduce((total, cur) => total + cur.route.tokenPath.length, 0);
1424
- const bHops = b.swaps.reduce((total, cur) => total + cur.route.tokenPath.length, 0);
1425
- return aHops - bHops;
1426
- }
1427
- if (a.inputAmount.lessThan(b.inputAmount)) {
1428
- return -1;
1429
- }
1430
- return 1;
1431
- }
1432
- if (a.outputAmount.lessThan(b.outputAmount)) {
1433
- return 1;
1434
- }
1435
- return -1;
1436
- }
1437
- var Trade = class {
1438
- /**
1439
- * @deprecated Deprecated in favor of 'swaps' property. If the trade consists of multiple routes
1440
- * this will return an error.
1441
- *
1442
- * When the trade consists of just a single route, this returns the route of the trade,
1443
- * i.e. which pools the trade goes through.
1444
- */
1445
- get route() {
1446
- invariant11(this.swaps.length == 1, "MULTIPLE_ROUTES");
1447
- return this.swaps[0].route;
1448
- }
1449
- /**
1450
- * The input amount for the trade assuming no slippage.
1451
- */
1452
- get inputAmount() {
1453
- if (this._inputAmount) {
1454
- return this._inputAmount;
1455
- }
1456
- const inputCurrency = this.swaps[0].inputAmount.currency;
1457
- const totalInputFromRoutes = this.swaps.map(({ inputAmount }) => inputAmount).reduce((total, cur) => total.add(cur), CurrencyAmount.fromRawAmount(inputCurrency, 0));
1458
- this._inputAmount = totalInputFromRoutes;
1459
- return this._inputAmount;
1460
- }
1461
- /**
1462
- * The output amount for the trade assuming no slippage.
1463
- */
1464
- get outputAmount() {
1465
- if (this._outputAmount) {
1466
- return this._outputAmount;
1467
- }
1468
- const outputCurrency = this.swaps[0].outputAmount.currency;
1469
- const totalOutputFromRoutes = this.swaps.map(({ outputAmount }) => outputAmount).reduce((total, cur) => total.add(cur), CurrencyAmount.fromRawAmount(outputCurrency, 0));
1470
- this._outputAmount = totalOutputFromRoutes;
1471
- return this._outputAmount;
1472
- }
1473
- /**
1474
- * The price expressed in terms of output amount/input amount.
1475
- */
1476
- get executionPrice() {
1477
- return this._executionPrice ?? (this._executionPrice = new Price(
1478
- this.inputAmount.currency,
1479
- this.outputAmount.currency,
1480
- this.inputAmount.quotient,
1481
- this.outputAmount.quotient
1482
- ));
1483
- }
1484
- /**
1485
- * Returns the percent difference between the route's mid price and the price impact
1486
- */
1487
- get priceImpact() {
1488
- if (this._priceImpact) {
1489
- return this._priceImpact;
1490
- }
1491
- let spotOutputAmount = CurrencyAmount.fromRawAmount(this.outputAmount.currency, 0);
1492
- for (const { route, inputAmount } of this.swaps) {
1493
- const { midPrice } = route;
1494
- spotOutputAmount = spotOutputAmount.add(midPrice.quote(inputAmount));
1495
- }
1496
- const priceImpact = spotOutputAmount.subtract(this.outputAmount).divide(spotOutputAmount);
1497
- this._priceImpact = new Percent$1(priceImpact.numerator, priceImpact.denominator);
1498
- return this._priceImpact;
1499
- }
1500
- /**
1501
- * Constructs an exact in trade with the given amount in and route
1502
- * @template TInput The input token, either Ether or an ERC-20
1503
- * @template TOutput The output token, either Ether or an ERC-20
1504
- * @param route The route of the exact in trade
1505
- * @param amountIn The amount being passed in
1506
- * @returns The exact in trade
1507
- */
1508
- static async exactIn(route, amountIn) {
1509
- return Trade.fromRoute(route, amountIn, TradeType.EXACT_INPUT);
1510
- }
1511
- /**
1512
- * Constructs an exact out trade with the given amount out and route
1513
- * @template TInput The input token, either Ether or an ERC-20
1514
- * @template TOutput The output token, either Ether or an ERC-20
1515
- * @param route The route of the exact out trade
1516
- * @param amountOut The amount returned by the trade
1517
- * @returns The exact out trade
1518
- */
1519
- static async exactOut(route, amountOut) {
1520
- return Trade.fromRoute(route, amountOut, TradeType.EXACT_OUTPUT);
1521
- }
1522
- /**
1523
- * Constructs a trade by simulating swaps through the given route
1524
- * @template TInput The input token, either Ether or an ERC-20.
1525
- * @template TOutput The output token, either Ether or an ERC-20.
1526
- * @template TTradeType The type of the trade, either exact in or exact out.
1527
- * @param route route to swap through
1528
- * @param amount the amount specified, either input or output, depending on tradeType
1529
- * @param tradeType whether the trade is an exact input or exact output swap
1530
- * @returns The route
1531
- */
1532
- static async fromRoute(route, amount, tradeType) {
1533
- const amounts = new Array(route.tokenPath.length);
1534
- let inputAmount;
1535
- let outputAmount;
1536
- if (tradeType === TradeType.EXACT_INPUT) {
1537
- invariant11(amount.currency.equals(route.input), "INPUT");
1538
- amounts[0] = amount.wrapped;
1539
- for (let i = 0; i < route.tokenPath.length - 1; i++) {
1540
- const pool = route.pools[i];
1541
- const [outputAmount2] = await pool.getOutputAmount(amounts[i]);
1542
- amounts[i + 1] = outputAmount2;
1543
- }
1544
- inputAmount = CurrencyAmount.fromFractionalAmount(route.input, amount.numerator, amount.denominator);
1545
- outputAmount = CurrencyAmount.fromFractionalAmount(
1546
- route.output,
1547
- amounts[amounts.length - 1].numerator,
1548
- amounts[amounts.length - 1].denominator
1549
- );
1550
- } else {
1551
- invariant11(amount.currency.equals(route.output), "OUTPUT");
1552
- amounts[amounts.length - 1] = amount.wrapped;
1553
- for (let i = route.tokenPath.length - 1; i > 0; i--) {
1554
- const pool = route.pools[i - 1];
1555
- const [inputAmount2] = await pool.getInputAmount(amounts[i]);
1556
- amounts[i - 1] = inputAmount2;
1557
- }
1558
- inputAmount = CurrencyAmount.fromFractionalAmount(route.input, amounts[0].numerator, amounts[0].denominator);
1559
- outputAmount = CurrencyAmount.fromFractionalAmount(route.output, amount.numerator, amount.denominator);
1560
- }
1561
- return new Trade({
1562
- routes: [{ inputAmount, outputAmount, route }],
1563
- tradeType
1564
- });
1565
- }
1566
- /**
1567
- * Constructs a trade from routes by simulating swaps
1568
- *
1569
- * @template TInput The input token, either Ether or an ERC-20.
1570
- * @template TOutput The output token, either Ether or an ERC-20.
1571
- * @template TTradeType The type of the trade, either exact in or exact out.
1572
- * @param routes the routes to swap through and how much of the amount should be routed through each
1573
- * @param tradeType whether the trade is an exact input or exact output swap
1574
- * @returns The trade
1287
+ * Constructs a trade from routes by simulating swaps
1288
+ *
1289
+ * @template TInput The input token, either Ether or an ERC-20.
1290
+ * @template TOutput The output token, either Ether or an ERC-20.
1291
+ * @template TTradeType The type of the trade, either exact in or exact out.
1292
+ * @param routes the routes to swap through and how much of the amount should be routed through each
1293
+ * @param tradeType whether the trade is an exact input or exact output swap
1294
+ * @returns The trade
1575
1295
  */
1576
1296
  static async fromRoutes(routes, tradeType) {
1577
1297
  const populatedRoutes = [];
@@ -1580,7 +1300,7 @@ var Trade = class {
1580
1300
  let inputAmount;
1581
1301
  let outputAmount;
1582
1302
  if (tradeType === TradeType.EXACT_INPUT) {
1583
- invariant11(amount.currency.equals(route.input), "INPUT");
1303
+ invariant9(amount.currency.equals(route.input), "INPUT");
1584
1304
  inputAmount = CurrencyAmount.fromFractionalAmount(route.input, amount.numerator, amount.denominator);
1585
1305
  amounts[0] = CurrencyAmount.fromFractionalAmount(route.input.wrapped, amount.numerator, amount.denominator);
1586
1306
  for (let i = 0; i < route.tokenPath.length - 1; i++) {
@@ -1594,7 +1314,7 @@ var Trade = class {
1594
1314
  amounts[amounts.length - 1].denominator
1595
1315
  );
1596
1316
  } else {
1597
- invariant11(amount.currency.equals(route.output), "OUTPUT");
1317
+ invariant9(amount.currency.equals(route.output), "OUTPUT");
1598
1318
  outputAmount = CurrencyAmount.fromFractionalAmount(route.output, amount.numerator, amount.denominator);
1599
1319
  amounts[amounts.length - 1] = CurrencyAmount.fromFractionalAmount(
1600
1320
  route.output.wrapped,
@@ -1659,11 +1379,11 @@ var Trade = class {
1659
1379
  }) {
1660
1380
  const inputCurrency = routes[0].inputAmount.currency;
1661
1381
  const outputCurrency = routes[0].outputAmount.currency;
1662
- invariant11(
1382
+ invariant9(
1663
1383
  routes.every(({ route }) => inputCurrency.wrapped.equals(route.input.wrapped)),
1664
1384
  "INPUT_CURRENCY_MATCH"
1665
1385
  );
1666
- invariant11(
1386
+ invariant9(
1667
1387
  routes.every(({ route }) => outputCurrency.wrapped.equals(route.output.wrapped)),
1668
1388
  "OUTPUT_CURRENCY_MATCH"
1669
1389
  );
@@ -1674,7 +1394,7 @@ var Trade = class {
1674
1394
  poolAddressSet.add(Pool.getAddress(pool.token0, pool.token1, pool.fee));
1675
1395
  }
1676
1396
  }
1677
- invariant11(numPools == poolAddressSet.size, "POOLS_DUPLICATED");
1397
+ invariant9(numPools == poolAddressSet.size, "POOLS_DUPLICATED");
1678
1398
  this.swaps = routes;
1679
1399
  this.tradeType = tradeType;
1680
1400
  }
@@ -1684,169 +1404,459 @@ var Trade = class {
1684
1404
  * @returns The amount out
1685
1405
  */
1686
1406
  minimumAmountOut(slippageTolerance, amountOut = this.outputAmount) {
1687
- invariant11(!slippageTolerance.lessThan(ZERO), "SLIPPAGE_TOLERANCE");
1407
+ invariant9(!slippageTolerance.lessThan(ZERO), "SLIPPAGE_TOLERANCE");
1688
1408
  if (this.tradeType === TradeType.EXACT_OUTPUT) {
1689
1409
  return amountOut;
1690
1410
  }
1691
1411
  const slippageAdjustedAmountOut = new Fraction(ONE).add(slippageTolerance).invert().multiply(amountOut.quotient).quotient;
1692
1412
  return CurrencyAmount.fromRawAmount(amountOut.currency, slippageAdjustedAmountOut);
1693
1413
  }
1694
- /**
1695
- * Get the maximum amount in that can be spent via this trade for the given slippage tolerance
1696
- * @param slippageTolerance The tolerance of unfavorable slippage from the execution price of this trade
1697
- * @returns The amount in
1698
- */
1699
- maximumAmountIn(slippageTolerance, amountIn = this.inputAmount) {
1700
- invariant11(!slippageTolerance.lessThan(ZERO), "SLIPPAGE_TOLERANCE");
1701
- if (this.tradeType === TradeType.EXACT_INPUT) {
1702
- return amountIn;
1414
+ /**
1415
+ * Get the maximum amount in that can be spent via this trade for the given slippage tolerance
1416
+ * @param slippageTolerance The tolerance of unfavorable slippage from the execution price of this trade
1417
+ * @returns The amount in
1418
+ */
1419
+ maximumAmountIn(slippageTolerance, amountIn = this.inputAmount) {
1420
+ invariant9(!slippageTolerance.lessThan(ZERO), "SLIPPAGE_TOLERANCE");
1421
+ if (this.tradeType === TradeType.EXACT_INPUT) {
1422
+ return amountIn;
1423
+ }
1424
+ const slippageAdjustedAmountIn = new Fraction(ONE).add(slippageTolerance).multiply(amountIn.quotient).quotient;
1425
+ return CurrencyAmount.fromRawAmount(amountIn.currency, slippageAdjustedAmountIn);
1426
+ }
1427
+ /**
1428
+ * Return the execution price after accounting for slippage tolerance
1429
+ * @param slippageTolerance the allowed tolerated slippage
1430
+ * @returns The execution price
1431
+ */
1432
+ worstExecutionPrice(slippageTolerance) {
1433
+ return new Price(
1434
+ this.inputAmount.currency,
1435
+ this.outputAmount.currency,
1436
+ this.maximumAmountIn(slippageTolerance).quotient,
1437
+ this.minimumAmountOut(slippageTolerance).quotient
1438
+ );
1439
+ }
1440
+ /**
1441
+ * Given a list of pools, and a fixed amount in, returns the top `maxNumResults` trades that go from an input token
1442
+ * amount to an output token, making at most `maxHops` hops.
1443
+ * Note this does not consider aggregation, as routes are linear. It's possible a better route exists by splitting
1444
+ * the amount in among multiple routes.
1445
+ * @param pools the pools to consider in finding the best trade
1446
+ * @param nextAmountIn exact amount of input currency to spend
1447
+ * @param currencyOut the desired currency out
1448
+ * @param maxNumResults maximum number of results to return
1449
+ * @param maxHops maximum number of hops a returned trade can make, e.g. 1 hop goes through a single pool
1450
+ * @param currentPools used in recursion; the current list of pools
1451
+ * @param currencyAmountIn used in recursion; the original value of the currencyAmountIn parameter
1452
+ * @param bestTrades used in recursion; the current list of best trades
1453
+ * @returns The exact in trade
1454
+ */
1455
+ static async bestTradeExactIn(pools, currencyAmountIn, currencyOut, { maxNumResults = 3, maxHops = 3 } = {}, currentPools = [], nextAmountIn = currencyAmountIn, bestTrades = []) {
1456
+ invariant9(pools.length > 0, "POOLS");
1457
+ invariant9(maxHops > 0, "MAX_HOPS");
1458
+ invariant9(currencyAmountIn === nextAmountIn || currentPools.length > 0, "INVALID_RECURSION");
1459
+ const amountIn = nextAmountIn.wrapped;
1460
+ const tokenOut = currencyOut.wrapped;
1461
+ for (let i = 0; i < pools.length; i++) {
1462
+ const pool = pools[i];
1463
+ if (!pool.token0.equals(amountIn.currency) && !pool.token1.equals(amountIn.currency))
1464
+ continue;
1465
+ let amountOut;
1466
+ try {
1467
+ const [result] = await pool.getOutputAmount(amountIn);
1468
+ amountOut = result;
1469
+ } catch (error) {
1470
+ if (error.isInsufficientInputAmountError) {
1471
+ continue;
1472
+ }
1473
+ throw error;
1474
+ }
1475
+ if (amountOut.currency.isToken && amountOut.currency.equals(tokenOut)) {
1476
+ sortedInsert(
1477
+ bestTrades,
1478
+ await Trade.fromRoute(
1479
+ new Route([...currentPools, pool], currencyAmountIn.currency, currencyOut),
1480
+ currencyAmountIn,
1481
+ TradeType.EXACT_INPUT
1482
+ ),
1483
+ maxNumResults,
1484
+ tradeComparator
1485
+ );
1486
+ } else if (maxHops > 1 && pools.length > 1) {
1487
+ const poolsExcludingThisPool = pools.slice(0, i).concat(pools.slice(i + 1, pools.length));
1488
+ await Trade.bestTradeExactIn(
1489
+ poolsExcludingThisPool,
1490
+ currencyAmountIn,
1491
+ currencyOut,
1492
+ {
1493
+ maxNumResults,
1494
+ maxHops: maxHops - 1
1495
+ },
1496
+ [...currentPools, pool],
1497
+ amountOut,
1498
+ bestTrades
1499
+ );
1500
+ }
1501
+ }
1502
+ return bestTrades;
1503
+ }
1504
+ /**
1505
+ * similar to the above method but instead targets a fixed output amount
1506
+ * given a list of pools, and a fixed amount out, returns the top `maxNumResults` trades that go from an input token
1507
+ * to an output token amount, making at most `maxHops` hops
1508
+ * note this does not consider aggregation, as routes are linear. it's possible a better route exists by splitting
1509
+ * the amount in among multiple routes.
1510
+ * @param pools the pools to consider in finding the best trade
1511
+ * @param currencyIn the currency to spend
1512
+ * @param currencyAmountOut the desired currency amount out
1513
+ * @param nextAmountOut the exact amount of currency out
1514
+ * @param maxNumResults maximum number of results to return
1515
+ * @param maxHops maximum number of hops a returned trade can make, e.g. 1 hop goes through a single pool
1516
+ * @param currentPools used in recursion; the current list of pools
1517
+ * @param bestTrades used in recursion; the current list of best trades
1518
+ * @returns The exact out trade
1519
+ */
1520
+ static async bestTradeExactOut(pools, currencyIn, currencyAmountOut, { maxNumResults = 3, maxHops = 3 } = {}, currentPools = [], nextAmountOut = currencyAmountOut, bestTrades = []) {
1521
+ invariant9(pools.length > 0, "POOLS");
1522
+ invariant9(maxHops > 0, "MAX_HOPS");
1523
+ invariant9(currencyAmountOut === nextAmountOut || currentPools.length > 0, "INVALID_RECURSION");
1524
+ const amountOut = nextAmountOut.wrapped;
1525
+ const tokenIn = currencyIn.wrapped;
1526
+ for (let i = 0; i < pools.length; i++) {
1527
+ const pool = pools[i];
1528
+ if (!pool.token0.equals(amountOut.currency) && !pool.token1.equals(amountOut.currency))
1529
+ continue;
1530
+ let amountIn;
1531
+ try {
1532
+ const [result] = await pool.getInputAmount(amountOut);
1533
+ amountIn = result;
1534
+ } catch (error) {
1535
+ if (error.isInsufficientReservesError) {
1536
+ continue;
1537
+ }
1538
+ throw error;
1539
+ }
1540
+ if (amountIn.currency.equals(tokenIn)) {
1541
+ sortedInsert(
1542
+ bestTrades,
1543
+ await Trade.fromRoute(
1544
+ new Route([pool, ...currentPools], currencyIn, currencyAmountOut.currency),
1545
+ currencyAmountOut,
1546
+ TradeType.EXACT_OUTPUT
1547
+ ),
1548
+ maxNumResults,
1549
+ tradeComparator
1550
+ );
1551
+ } else if (maxHops > 1 && pools.length > 1) {
1552
+ const poolsExcludingThisPool = pools.slice(0, i).concat(pools.slice(i + 1, pools.length));
1553
+ await Trade.bestTradeExactOut(
1554
+ poolsExcludingThisPool,
1555
+ currencyIn,
1556
+ currencyAmountOut,
1557
+ {
1558
+ maxNumResults,
1559
+ maxHops: maxHops - 1
1560
+ },
1561
+ [pool, ...currentPools],
1562
+ amountIn,
1563
+ bestTrades
1564
+ );
1565
+ }
1566
+ }
1567
+ return bestTrades;
1568
+ }
1569
+ };
1570
+
1571
+ // src/utils/calldata.ts
1572
+ function toHex(bigintIsh) {
1573
+ const bigInt = BigInt(bigintIsh);
1574
+ let hex = bigInt.toString(16);
1575
+ if (hex.length % 2 !== 0) {
1576
+ hex = `0${hex}`;
1577
+ }
1578
+ return `0x${hex}`;
1579
+ }
1580
+ function encodeRouteToPath(route, exactOutput) {
1581
+ const firstInputToken = route.input.wrapped;
1582
+ const { path, types } = route.pools.reduce(
1583
+ ({ inputToken, path: path2, types: types2 }, pool, index) => {
1584
+ const outputToken = pool.token0.equals(inputToken) ? pool.token1 : pool.token0;
1585
+ if (index === 0) {
1586
+ return {
1587
+ inputToken: outputToken,
1588
+ types: ["address", "uint24", "address"],
1589
+ path: [inputToken.address, pool.fee, outputToken.address]
1590
+ };
1591
+ }
1592
+ return {
1593
+ inputToken: outputToken,
1594
+ types: [...types2, "uint24", "address"],
1595
+ path: [...path2, pool.fee, outputToken.address]
1596
+ };
1597
+ },
1598
+ { inputToken: firstInputToken, path: [], types: [] }
1599
+ );
1600
+ return exactOutput ? encodePacked(types.reverse(), path.reverse()) : encodePacked(types, path);
1601
+ }
1602
+ function nearestUsableTick(tick, tickSpacing) {
1603
+ invariant9(Number.isInteger(tick) && Number.isInteger(tickSpacing), "INTEGERS");
1604
+ invariant9(tickSpacing > 0, "TICK_SPACING");
1605
+ invariant9(tick >= TickMath.MIN_TICK && tick <= TickMath.MAX_TICK, "TICK_BOUND");
1606
+ const rounded = Math.round(tick / tickSpacing) * tickSpacing;
1607
+ if (rounded < TickMath.MIN_TICK)
1608
+ return rounded + tickSpacing;
1609
+ if (rounded > TickMath.MAX_TICK)
1610
+ return rounded - tickSpacing;
1611
+ return rounded;
1612
+ }
1613
+
1614
+ // src/utils/position.ts
1615
+ var PositionLibrary = class {
1616
+ /**
1617
+ * Cannot be constructed.
1618
+ */
1619
+ constructor() {
1620
+ }
1621
+ // replicates the portions of Position#update required to compute unaccounted fees
1622
+ static getTokensOwed(feeGrowthInside0LastX128, feeGrowthInside1LastX128, liquidity, feeGrowthInside0X128, feeGrowthInside1X128) {
1623
+ const tokensOwed0 = subIn256(feeGrowthInside0X128, feeGrowthInside0LastX128) * liquidity / Q128;
1624
+ const tokensOwed1 = subIn256(feeGrowthInside1X128, feeGrowthInside1LastX128) * liquidity / Q128;
1625
+ return [tokensOwed0, tokensOwed1];
1626
+ }
1627
+ };
1628
+
1629
+ // src/utils/tickLibrary.ts
1630
+ var Q256 = 2n ** 256n;
1631
+ function subIn256(x, y) {
1632
+ const difference = x - y;
1633
+ if (difference < ZERO) {
1634
+ return Q256 + difference;
1635
+ }
1636
+ return difference;
1637
+ }
1638
+ var TickLibrary = class {
1639
+ /**
1640
+ * Cannot be constructed.
1641
+ */
1642
+ constructor() {
1643
+ }
1644
+ static getFeeGrowthInside(feeGrowthOutsideLower, feeGrowthOutsideUpper, tickLower, tickUpper, tickCurrent, feeGrowthGlobal0X128, feeGrowthGlobal1X128) {
1645
+ let feeGrowthBelow0X128;
1646
+ let feeGrowthBelow1X128;
1647
+ if (tickCurrent >= tickLower) {
1648
+ feeGrowthBelow0X128 = feeGrowthOutsideLower.feeGrowthOutside0X128;
1649
+ feeGrowthBelow1X128 = feeGrowthOutsideLower.feeGrowthOutside1X128;
1650
+ } else {
1651
+ feeGrowthBelow0X128 = subIn256(feeGrowthGlobal0X128, feeGrowthOutsideLower.feeGrowthOutside0X128);
1652
+ feeGrowthBelow1X128 = subIn256(feeGrowthGlobal1X128, feeGrowthOutsideLower.feeGrowthOutside1X128);
1653
+ }
1654
+ let feeGrowthAbove0X128;
1655
+ let feeGrowthAbove1X128;
1656
+ if (tickCurrent < tickUpper) {
1657
+ feeGrowthAbove0X128 = feeGrowthOutsideUpper.feeGrowthOutside0X128;
1658
+ feeGrowthAbove1X128 = feeGrowthOutsideUpper.feeGrowthOutside1X128;
1659
+ } else {
1660
+ feeGrowthAbove0X128 = subIn256(feeGrowthGlobal0X128, feeGrowthOutsideUpper.feeGrowthOutside0X128);
1661
+ feeGrowthAbove1X128 = subIn256(feeGrowthGlobal1X128, feeGrowthOutsideUpper.feeGrowthOutside1X128);
1662
+ }
1663
+ return [
1664
+ subIn256(subIn256(feeGrowthGlobal0X128, feeGrowthBelow0X128), feeGrowthAbove0X128),
1665
+ subIn256(subIn256(feeGrowthGlobal1X128, feeGrowthBelow1X128), feeGrowthAbove1X128)
1666
+ ];
1667
+ }
1668
+ };
1669
+ function parseNumberToFraction(num, precision = 6) {
1670
+ if (Number.isNaN(num) || !Number.isFinite(num)) {
1671
+ return void 0;
1672
+ }
1673
+ const scalar = 10 ** precision;
1674
+ return new Fraction$1(BigInt(Math.floor(num * scalar)), BigInt(scalar));
1675
+ }
1676
+
1677
+ // src/utils/feeCalculator.ts
1678
+ var FeeCalculator = {
1679
+ getEstimatedLPFee,
1680
+ getEstimatedLPFeeByAmounts,
1681
+ getLiquidityFromTick,
1682
+ getLiquidityFromSqrtRatioX96,
1683
+ getAverageLiquidity,
1684
+ getLiquidityBySingleAmount,
1685
+ getDependentAmount,
1686
+ getLiquidityByAmountsAndPrice,
1687
+ getAmountsByLiquidityAndPrice,
1688
+ getAmountsAtNewPrice
1689
+ };
1690
+ function getEstimatedLPFeeWithProtocolFee({ amount, currency, ...rest }) {
1691
+ return getEstimatedLPFeeByAmountsWithProtocolFee({
1692
+ ...rest,
1693
+ amountA: amount,
1694
+ amountB: CurrencyAmount$1.fromRawAmount(currency, MaxUint256)
1695
+ });
1696
+ }
1697
+ function getEstimatedLPFee({ amount, currency, ...rest }) {
1698
+ return getEstimatedLPFeeByAmounts({
1699
+ ...rest,
1700
+ amountA: amount,
1701
+ amountB: CurrencyAmount$1.fromRawAmount(currency, MaxUint256)
1702
+ });
1703
+ }
1704
+ function getEstimatedLPFeeByAmountsWithProtocolFee(options) {
1705
+ try {
1706
+ return tryGetEstimatedLPFeeByAmounts(options);
1707
+ } catch (e) {
1708
+ console.error(e);
1709
+ return new Fraction$1(ZERO$1);
1710
+ }
1711
+ }
1712
+ function getEstimatedLPFeeByAmounts({ protocolFee = ZERO_PERCENT, ...rest }) {
1713
+ try {
1714
+ const fee = tryGetEstimatedLPFeeByAmounts(rest);
1715
+ return ONE_HUNDRED_PERCENT.subtract(protocolFee).multiply(fee).asFraction;
1716
+ } catch (e) {
1717
+ console.error(e);
1718
+ return new Fraction$1(ZERO$1);
1719
+ }
1720
+ }
1721
+ function tryGetEstimatedLPFeeByAmounts({
1722
+ amountA,
1723
+ amountB,
1724
+ volume24H,
1725
+ sqrtRatioX96,
1726
+ tickLower,
1727
+ tickUpper,
1728
+ mostActiveLiquidity,
1729
+ fee,
1730
+ insidePercentage = ONE_HUNDRED_PERCENT
1731
+ }) {
1732
+ invariant9(!Number.isNaN(fee) && fee >= 0, "INVALID_FEE");
1733
+ const tickCurrent = TickMath.getTickAtSqrtRatio(sqrtRatioX96);
1734
+ if (tickCurrent < tickLower || tickCurrent > tickUpper) {
1735
+ return new Fraction$1(ZERO$1);
1736
+ }
1737
+ const liquidity = FeeCalculator.getLiquidityByAmountsAndPrice({
1738
+ amountA,
1739
+ amountB,
1740
+ tickUpper,
1741
+ tickLower,
1742
+ sqrtRatioX96
1743
+ });
1744
+ const volumeInFraction = parseNumberToFraction(volume24H) || new Fraction$1(ZERO$1);
1745
+ return insidePercentage.multiply(volumeInFraction.multiply(BigInt(fee)).multiply(liquidity)).divide(MAX_FEE * (liquidity + mostActiveLiquidity)).asFraction;
1746
+ }
1747
+ function getDependentAmount(options) {
1748
+ const { currency, amount, sqrtRatioX96, tickLower, tickUpper } = options;
1749
+ const currentTick = TickMath.getTickAtSqrtRatio(sqrtRatioX96);
1750
+ const liquidity = FeeCalculator.getLiquidityBySingleAmount(options);
1751
+ const isToken0 = currency.wrapped.sortsBefore(amount.currency.wrapped);
1752
+ const getTokenAmount = isToken0 ? PositionMath.getToken0Amount : PositionMath.getToken1Amount;
1753
+ return CurrencyAmount$1.fromRawAmount(
1754
+ currency,
1755
+ getTokenAmount(currentTick, tickLower, tickUpper, sqrtRatioX96, liquidity)
1756
+ );
1757
+ }
1758
+ function getLiquidityBySingleAmount({ amount, currency, ...rest }) {
1759
+ return getLiquidityByAmountsAndPrice({
1760
+ amountA: amount,
1761
+ amountB: CurrencyAmount$1.fromRawAmount(currency, MaxUint256),
1762
+ ...rest
1763
+ });
1764
+ }
1765
+ function getLiquidityByAmountsAndPrice({
1766
+ amountA,
1767
+ amountB,
1768
+ tickUpper,
1769
+ tickLower,
1770
+ sqrtRatioX96
1771
+ }) {
1772
+ const isToken0 = amountA.currency.wrapped.address !== amountB.currency.wrapped.address ? amountA.currency.wrapped.sortsBefore(amountB.currency.wrapped) : true;
1773
+ const [inputAmount0, inputAmount1] = isToken0 ? [amountA.quotient, amountB.quotient] : [amountB.quotient, amountA.quotient];
1774
+ const sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(tickLower);
1775
+ const sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(tickUpper);
1776
+ return maxLiquidityForAmounts(sqrtRatioX96, sqrtRatioAX96, sqrtRatioBX96, inputAmount0, inputAmount1, true);
1777
+ }
1778
+ function getAmountsByLiquidityAndPrice(options) {
1779
+ const { currencyA, currencyB, liquidity, sqrtRatioX96, tickLower, tickUpper } = options;
1780
+ const currentTick = TickMath.getTickAtSqrtRatio(sqrtRatioX96);
1781
+ const isToken0 = currencyA.wrapped.sortsBefore(currencyB.wrapped);
1782
+ const adjustedAmount0 = PositionMath.getToken0Amount(currentTick, tickLower, tickUpper, sqrtRatioX96, liquidity);
1783
+ const adjustedAmount1 = PositionMath.getToken1Amount(currentTick, tickLower, tickUpper, sqrtRatioX96, liquidity);
1784
+ return [
1785
+ CurrencyAmount$1.fromRawAmount(currencyA, isToken0 ? adjustedAmount0 : adjustedAmount1),
1786
+ CurrencyAmount$1.fromRawAmount(currencyB, isToken0 ? adjustedAmount1 : adjustedAmount0)
1787
+ ];
1788
+ }
1789
+ function getAmountsAtNewPrice({ newSqrtRatioX96, ...rest }) {
1790
+ const { tickLower, tickUpper, amountA, amountB } = rest;
1791
+ const liquidity = FeeCalculator.getLiquidityByAmountsAndPrice(rest);
1792
+ return FeeCalculator.getAmountsByLiquidityAndPrice({
1793
+ liquidity,
1794
+ currencyA: amountA.currency,
1795
+ currencyB: amountB.currency,
1796
+ tickLower,
1797
+ tickUpper,
1798
+ sqrtRatioX96: newSqrtRatioX96
1799
+ });
1800
+ }
1801
+ function getAverageLiquidity(ticks, tickSpacing, tickLower, tickUpper) {
1802
+ invariant9(tickLower <= tickUpper, "INVALID_TICK_RANGE");
1803
+ TickList.validateList(ticks, tickSpacing);
1804
+ if (tickLower === tickUpper) {
1805
+ return FeeCalculator.getLiquidityFromTick(ticks, tickLower);
1806
+ }
1807
+ const lowerOutOfBound = tickLower < ticks[0].index;
1808
+ let lastTick = lowerOutOfBound ? new Tick({ index: TickMath.MIN_TICK, liquidityNet: ZERO$1, liquidityGross: ZERO$1 }) : TickList.nextInitializedTick(ticks, tickLower, true);
1809
+ let currentTick = TickList.nextInitializedTick(ticks, tickLower, false);
1810
+ let currentL = lowerOutOfBound ? ZERO$1 : FeeCalculator.getLiquidityFromTick(ticks, currentTick.index);
1811
+ let weightedL = ZERO$1;
1812
+ const getWeightedLFromLastTickTo = (toTick) => currentL * BigInt(toTick - Math.max(lastTick.index, tickLower));
1813
+ while (currentTick.index < tickUpper) {
1814
+ weightedL += getWeightedLFromLastTickTo(currentTick.index);
1815
+ currentL += currentTick.liquidityNet;
1816
+ lastTick = currentTick;
1817
+ if (currentTick.index === ticks[ticks.length - 1].index) {
1818
+ break;
1703
1819
  }
1704
- const slippageAdjustedAmountIn = new Fraction(ONE).add(slippageTolerance).multiply(amountIn.quotient).quotient;
1705
- return CurrencyAmount.fromRawAmount(amountIn.currency, slippageAdjustedAmountIn);
1820
+ currentTick = TickList.nextInitializedTick(ticks, currentTick.index, false);
1706
1821
  }
1707
- /**
1708
- * Return the execution price after accounting for slippage tolerance
1709
- * @param slippageTolerance the allowed tolerated slippage
1710
- * @returns The execution price
1711
- */
1712
- worstExecutionPrice(slippageTolerance) {
1713
- return new Price(
1714
- this.inputAmount.currency,
1715
- this.outputAmount.currency,
1716
- this.maximumAmountIn(slippageTolerance).quotient,
1717
- this.minimumAmountOut(slippageTolerance).quotient
1718
- );
1822
+ weightedL += getWeightedLFromLastTickTo(tickUpper);
1823
+ return weightedL / BigInt(tickUpper - tickLower);
1824
+ }
1825
+ function getLiquidityFromSqrtRatioX96(ticks, sqrtRatioX96) {
1826
+ const tick = TickMath.getTickAtSqrtRatio(sqrtRatioX96);
1827
+ return FeeCalculator.getLiquidityFromTick(ticks, tick);
1828
+ }
1829
+ function getLiquidityFromTick(ticks, tick) {
1830
+ let liquidity = ZERO$1;
1831
+ if (!ticks?.length)
1832
+ return liquidity;
1833
+ if (tick < ticks[0].index || tick > ticks[ticks.length - 1].index) {
1834
+ return liquidity;
1719
1835
  }
1720
- /**
1721
- * Given a list of pools, and a fixed amount in, returns the top `maxNumResults` trades that go from an input token
1722
- * amount to an output token, making at most `maxHops` hops.
1723
- * Note this does not consider aggregation, as routes are linear. It's possible a better route exists by splitting
1724
- * the amount in among multiple routes.
1725
- * @param pools the pools to consider in finding the best trade
1726
- * @param nextAmountIn exact amount of input currency to spend
1727
- * @param currencyOut the desired currency out
1728
- * @param maxNumResults maximum number of results to return
1729
- * @param maxHops maximum number of hops a returned trade can make, e.g. 1 hop goes through a single pool
1730
- * @param currentPools used in recursion; the current list of pools
1731
- * @param currencyAmountIn used in recursion; the original value of the currencyAmountIn parameter
1732
- * @param bestTrades used in recursion; the current list of best trades
1733
- * @returns The exact in trade
1734
- */
1735
- static async bestTradeExactIn(pools, currencyAmountIn, currencyOut, { maxNumResults = 3, maxHops = 3 } = {}, currentPools = [], nextAmountIn = currencyAmountIn, bestTrades = []) {
1736
- invariant11(pools.length > 0, "POOLS");
1737
- invariant11(maxHops > 0, "MAX_HOPS");
1738
- invariant11(currencyAmountIn === nextAmountIn || currentPools.length > 0, "INVALID_RECURSION");
1739
- const amountIn = nextAmountIn.wrapped;
1740
- const tokenOut = currencyOut.wrapped;
1741
- for (let i = 0; i < pools.length; i++) {
1742
- const pool = pools[i];
1743
- if (!pool.token0.equals(amountIn.currency) && !pool.token1.equals(amountIn.currency))
1744
- continue;
1745
- let amountOut;
1746
- try {
1747
- const [result] = await pool.getOutputAmount(amountIn);
1748
- amountOut = result;
1749
- } catch (error) {
1750
- if (error.isInsufficientInputAmountError) {
1751
- continue;
1752
- }
1753
- throw error;
1754
- }
1755
- if (amountOut.currency.isToken && amountOut.currency.equals(tokenOut)) {
1756
- sortedInsert(
1757
- bestTrades,
1758
- await Trade.fromRoute(
1759
- new Route([...currentPools, pool], currencyAmountIn.currency, currencyOut),
1760
- currencyAmountIn,
1761
- TradeType.EXACT_INPUT
1762
- ),
1763
- maxNumResults,
1764
- tradeComparator
1765
- );
1766
- } else if (maxHops > 1 && pools.length > 1) {
1767
- const poolsExcludingThisPool = pools.slice(0, i).concat(pools.slice(i + 1, pools.length));
1768
- await Trade.bestTradeExactIn(
1769
- poolsExcludingThisPool,
1770
- currencyAmountIn,
1771
- currencyOut,
1772
- {
1773
- maxNumResults,
1774
- maxHops: maxHops - 1
1775
- },
1776
- [...currentPools, pool],
1777
- amountOut,
1778
- bestTrades
1779
- );
1780
- }
1836
+ for (let i = 0; i < ticks.length - 1; ++i) {
1837
+ liquidity += ticks[i].liquidityNet;
1838
+ const lowerTick = ticks[i].index;
1839
+ const upperTick = ticks[i + 1]?.index;
1840
+ if (lowerTick <= tick && tick <= upperTick) {
1841
+ break;
1781
1842
  }
1782
- return bestTrades;
1783
1843
  }
1784
- /**
1785
- * similar to the above method but instead targets a fixed output amount
1786
- * given a list of pools, and a fixed amount out, returns the top `maxNumResults` trades that go from an input token
1787
- * to an output token amount, making at most `maxHops` hops
1788
- * note this does not consider aggregation, as routes are linear. it's possible a better route exists by splitting
1789
- * the amount in among multiple routes.
1790
- * @param pools the pools to consider in finding the best trade
1791
- * @param currencyIn the currency to spend
1792
- * @param currencyAmountOut the desired currency amount out
1793
- * @param nextAmountOut the exact amount of currency out
1794
- * @param maxNumResults maximum number of results to return
1795
- * @param maxHops maximum number of hops a returned trade can make, e.g. 1 hop goes through a single pool
1796
- * @param currentPools used in recursion; the current list of pools
1797
- * @param bestTrades used in recursion; the current list of best trades
1798
- * @returns The exact out trade
1799
- */
1800
- static async bestTradeExactOut(pools, currencyIn, currencyAmountOut, { maxNumResults = 3, maxHops = 3 } = {}, currentPools = [], nextAmountOut = currencyAmountOut, bestTrades = []) {
1801
- invariant11(pools.length > 0, "POOLS");
1802
- invariant11(maxHops > 0, "MAX_HOPS");
1803
- invariant11(currencyAmountOut === nextAmountOut || currentPools.length > 0, "INVALID_RECURSION");
1804
- const amountOut = nextAmountOut.wrapped;
1805
- const tokenIn = currencyIn.wrapped;
1806
- for (let i = 0; i < pools.length; i++) {
1807
- const pool = pools[i];
1808
- if (!pool.token0.equals(amountOut.currency) && !pool.token1.equals(amountOut.currency))
1809
- continue;
1810
- let amountIn;
1811
- try {
1812
- const [result] = await pool.getInputAmount(amountOut);
1813
- amountIn = result;
1814
- } catch (error) {
1815
- if (error.isInsufficientReservesError) {
1816
- continue;
1817
- }
1818
- throw error;
1819
- }
1820
- if (amountIn.currency.equals(tokenIn)) {
1821
- sortedInsert(
1822
- bestTrades,
1823
- await Trade.fromRoute(
1824
- new Route([pool, ...currentPools], currencyIn, currencyAmountOut.currency),
1825
- currencyAmountOut,
1826
- TradeType.EXACT_OUTPUT
1827
- ),
1828
- maxNumResults,
1829
- tradeComparator
1830
- );
1831
- } else if (maxHops > 1 && pools.length > 1) {
1832
- const poolsExcludingThisPool = pools.slice(0, i).concat(pools.slice(i + 1, pools.length));
1833
- await Trade.bestTradeExactOut(
1834
- poolsExcludingThisPool,
1835
- currencyIn,
1836
- currencyAmountOut,
1837
- {
1838
- maxNumResults,
1839
- maxHops: maxHops - 1
1840
- },
1841
- [pool, ...currentPools],
1842
- amountIn,
1843
- bestTrades
1844
- );
1845
- }
1846
- }
1847
- return bestTrades;
1844
+ return liquidity;
1845
+ }
1846
+ var FEE_BASE = 10n ** 4n;
1847
+ function parseProtocolFees(feeProtocol) {
1848
+ const packed = Number(feeProtocol);
1849
+ if (Number.isNaN(packed)) {
1850
+ throw new Error(`Invalid fee protocol ${feeProtocol}`);
1848
1851
  }
1849
- };
1852
+ const token0ProtocolFee = packed % 2 ** 16;
1853
+ const token1ProtocolFee = packed >> 16;
1854
+ return [new Percent(token0ProtocolFee, FEE_BASE), new Percent(token1ProtocolFee, FEE_BASE)];
1855
+ }
1856
+ function sqrtRatioX96ToPrice(sqrtRatioX96, currencyA, currencyB) {
1857
+ const ratioX192 = sqrtRatioX96 * sqrtRatioX96;
1858
+ return currencyA.wrapped.sortsBefore(currencyB.wrapped) ? new Price$1(currencyA.wrapped, currencyB.wrapped, Q192, ratioX192) : new Price$1(currencyA.wrapped, currencyB.wrapped, ratioX192, Q192);
1859
+ }
1850
1860
  var IMulticall = [
1851
1861
  {
1852
1862
  inputs: [
@@ -1878,14 +1888,14 @@ var _Multicall = class {
1878
1888
  if (!Array.isArray(calldatas)) {
1879
1889
  calldatas = [calldatas];
1880
1890
  }
1881
- return calldatas.length === 1 ? calldatas[0] : _Multicall.INTERFACE.encodeFunctionData("multicall", [calldatas]);
1891
+ return calldatas.length === 1 ? calldatas[0] : encodeFunctionData({ abi: _Multicall.ABI, functionName: "multicall", args: [calldatas] });
1882
1892
  }
1883
1893
  };
1884
1894
  var Multicall = _Multicall;
1885
- Multicall.INTERFACE = new Interface(IMulticall);
1895
+ Multicall.ABI = IMulticall;
1886
1896
 
1887
- // src/abi/NonfungiblePositionManager.json
1888
- var NonfungiblePositionManager_default = [
1897
+ // src/abi/NonfungiblePositionManager.ts
1898
+ var nonfungiblePositionManagerABI = [
1889
1899
  {
1890
1900
  inputs: [
1891
1901
  { internalType: "address", name: "_deployer", type: "address" },
@@ -2391,8 +2401,8 @@ var NonfungiblePositionManager_default = [
2391
2401
  { stateMutability: "payable", type: "receive" }
2392
2402
  ];
2393
2403
 
2394
- // src/abi/SelfPermit.json
2395
- var SelfPermit_default = [
2404
+ // src/abi/SelfPermit.ts
2405
+ var selfPermitABI = [
2396
2406
  {
2397
2407
  inputs: [
2398
2408
  {
@@ -2558,28 +2568,22 @@ var _SelfPermit = class {
2558
2568
  constructor() {
2559
2569
  }
2560
2570
  static encodePermit(token, options) {
2561
- return isAllowedPermit(options) ? _SelfPermit.INTERFACE.encodeFunctionData("selfPermitAllowed", [
2562
- token.address,
2563
- toHex(options.nonce),
2564
- toHex(options.expiry),
2565
- options.v,
2566
- options.r,
2567
- options.s
2568
- ]) : _SelfPermit.INTERFACE.encodeFunctionData("selfPermit", [
2569
- token.address,
2570
- toHex(options.amount),
2571
- toHex(options.deadline),
2572
- options.v,
2573
- options.r,
2574
- options.s
2575
- ]);
2571
+ return isAllowedPermit(options) ? encodeFunctionData({
2572
+ abi: _SelfPermit.ABI,
2573
+ functionName: "selfPermitAllowed",
2574
+ args: [token.address, BigInt(options.nonce), BigInt(options.expiry), options.v, options.r, options.s]
2575
+ }) : encodeFunctionData({
2576
+ abi: _SelfPermit.ABI,
2577
+ functionName: "selfPermit",
2578
+ args: [token.address, BigInt(options.amount), BigInt(options.deadline), options.v, options.r, options.s]
2579
+ });
2576
2580
  }
2577
2581
  };
2578
2582
  var SelfPermit = _SelfPermit;
2579
- SelfPermit.INTERFACE = new Interface(SelfPermit_default);
2583
+ SelfPermit.ABI = selfPermitABI;
2580
2584
 
2581
- // src/abi/IPeripheryPaymentsWithFee.json
2582
- var IPeripheryPaymentsWithFee_default = [
2585
+ // src/abi/PeripheryPaymentsWithFee.ts
2586
+ var peripheryPaymentsWithFeeABI = [
2583
2587
  {
2584
2588
  inputs: [],
2585
2589
  name: "refundETH",
@@ -2699,46 +2703,47 @@ var _Payments = class {
2699
2703
  constructor() {
2700
2704
  }
2701
2705
  static encodeFeeBips(fee) {
2702
- return toHex(fee.multiply(1e4).quotient);
2706
+ return fee.multiply(1e4).quotient;
2703
2707
  }
2704
2708
  static encodeUnwrapWETH9(amountMinimum, recipient, feeOptions) {
2705
2709
  recipient = validateAndParseAddress(recipient);
2706
2710
  if (feeOptions) {
2707
2711
  const feeBips = this.encodeFeeBips(feeOptions.fee);
2708
2712
  const feeRecipient = validateAndParseAddress(feeOptions.recipient);
2709
- return _Payments.INTERFACE.encodeFunctionData("unwrapWETH9WithFee", [
2710
- toHex(amountMinimum),
2711
- recipient,
2712
- feeBips,
2713
- feeRecipient
2714
- ]);
2713
+ return encodeFunctionData({
2714
+ abi: _Payments.ABI,
2715
+ functionName: "unwrapWETH9WithFee",
2716
+ args: [amountMinimum, recipient, feeBips, feeRecipient]
2717
+ });
2715
2718
  }
2716
- return _Payments.INTERFACE.encodeFunctionData("unwrapWETH9", [toHex(amountMinimum), recipient]);
2719
+ return encodeFunctionData({ abi: _Payments.ABI, functionName: "unwrapWETH9", args: [amountMinimum, recipient] });
2717
2720
  }
2718
2721
  static encodeSweepToken(token, amountMinimum, recipient, feeOptions) {
2719
2722
  recipient = validateAndParseAddress(recipient);
2720
2723
  if (feeOptions) {
2721
2724
  const feeBips = this.encodeFeeBips(feeOptions.fee);
2722
2725
  const feeRecipient = validateAndParseAddress(feeOptions.recipient);
2723
- return _Payments.INTERFACE.encodeFunctionData("sweepTokenWithFee", [
2724
- token.address,
2725
- toHex(amountMinimum),
2726
- recipient,
2727
- feeBips,
2728
- feeRecipient
2729
- ]);
2726
+ return encodeFunctionData({
2727
+ abi: _Payments.ABI,
2728
+ functionName: "sweepTokenWithFee",
2729
+ args: [token.address, amountMinimum, recipient, feeBips, feeRecipient]
2730
+ });
2730
2731
  }
2731
- return _Payments.INTERFACE.encodeFunctionData("sweepToken", [token.address, toHex(amountMinimum), recipient]);
2732
+ return encodeFunctionData({
2733
+ abi: _Payments.ABI,
2734
+ functionName: "sweepToken",
2735
+ args: [token.address, amountMinimum, recipient]
2736
+ });
2732
2737
  }
2733
2738
  static encodeRefundETH() {
2734
- return _Payments.INTERFACE.encodeFunctionData("refundETH");
2739
+ return encodeFunctionData({ abi: _Payments.ABI, functionName: "refundETH" });
2735
2740
  }
2736
2741
  };
2737
2742
  var Payments = _Payments;
2738
- Payments.INTERFACE = new Interface(IPeripheryPaymentsWithFee_default);
2743
+ Payments.ABI = peripheryPaymentsWithFeeABI;
2739
2744
 
2740
2745
  // src/nonfungiblePositionManager.ts
2741
- var MaxUint128 = toHex(2n ** 128n - 1n);
2746
+ var MaxUint128 = 2n ** 128n - 1n;
2742
2747
  function isMint(options) {
2743
2748
  return Object.keys(options).some((k) => k === "recipient");
2744
2749
  }
@@ -2750,12 +2755,11 @@ var _NonfungiblePositionManager = class {
2750
2755
  constructor() {
2751
2756
  }
2752
2757
  static encodeCreate(pool) {
2753
- return _NonfungiblePositionManager.INTERFACE.encodeFunctionData("createAndInitializePoolIfNecessary", [
2754
- pool.token0.address,
2755
- pool.token1.address,
2756
- pool.fee,
2757
- toHex(pool.sqrtRatioX96)
2758
- ]);
2758
+ return encodeFunctionData({
2759
+ abi: _NonfungiblePositionManager.ABI,
2760
+ functionName: "createAndInitializePoolIfNecessary",
2761
+ args: [pool.token0.address, pool.token1.address, pool.fee, pool.sqrtRatioX96]
2762
+ });
2759
2763
  }
2760
2764
  static createCallParameters(pool) {
2761
2765
  return {
@@ -2764,13 +2768,13 @@ var _NonfungiblePositionManager = class {
2764
2768
  };
2765
2769
  }
2766
2770
  static addCallParameters(position, options) {
2767
- invariant11(position.liquidity > ZERO, "ZERO_LIQUIDITY");
2771
+ invariant9(position.liquidity > ZERO, "ZERO_LIQUIDITY");
2768
2772
  const calldatas = [];
2769
2773
  const { amount0: amount0Desired, amount1: amount1Desired } = position.mintAmounts;
2770
2774
  const minimumAmounts = position.mintAmountsWithSlippage(options.slippageTolerance);
2771
- const amount0Min = toHex(minimumAmounts.amount0);
2772
- const amount1Min = toHex(minimumAmounts.amount1);
2773
- const deadline = toHex(options.deadline);
2775
+ const amount0Min = minimumAmounts.amount0;
2776
+ const amount1Min = minimumAmounts.amount1;
2777
+ const deadline = BigInt(options.deadline);
2774
2778
  if (isMint(options) && options.createPool) {
2775
2779
  calldatas.push(this.encodeCreate(position.pool));
2776
2780
  }
@@ -2783,40 +2787,48 @@ var _NonfungiblePositionManager = class {
2783
2787
  if (isMint(options)) {
2784
2788
  const recipient = validateAndParseAddress(options.recipient);
2785
2789
  calldatas.push(
2786
- _NonfungiblePositionManager.INTERFACE.encodeFunctionData("mint", [
2787
- {
2788
- token0: position.pool.token0.address,
2789
- token1: position.pool.token1.address,
2790
- fee: position.pool.fee,
2791
- tickLower: position.tickLower,
2792
- tickUpper: position.tickUpper,
2793
- amount0Desired: toHex(amount0Desired),
2794
- amount1Desired: toHex(amount1Desired),
2795
- amount0Min,
2796
- amount1Min,
2797
- recipient,
2798
- deadline
2799
- }
2800
- ])
2790
+ encodeFunctionData({
2791
+ abi: _NonfungiblePositionManager.ABI,
2792
+ functionName: "mint",
2793
+ args: [
2794
+ {
2795
+ token0: position.pool.token0.address,
2796
+ token1: position.pool.token1.address,
2797
+ fee: position.pool.fee,
2798
+ tickLower: position.tickLower,
2799
+ tickUpper: position.tickUpper,
2800
+ amount0Desired,
2801
+ amount1Desired,
2802
+ amount0Min,
2803
+ amount1Min,
2804
+ recipient,
2805
+ deadline
2806
+ }
2807
+ ]
2808
+ })
2801
2809
  );
2802
2810
  } else {
2803
2811
  calldatas.push(
2804
- _NonfungiblePositionManager.INTERFACE.encodeFunctionData("increaseLiquidity", [
2805
- {
2806
- tokenId: toHex(options.tokenId),
2807
- amount0Desired: toHex(amount0Desired),
2808
- amount1Desired: toHex(amount1Desired),
2809
- amount0Min,
2810
- amount1Min,
2811
- deadline
2812
- }
2813
- ])
2812
+ encodeFunctionData({
2813
+ abi: _NonfungiblePositionManager.ABI,
2814
+ functionName: "increaseLiquidity",
2815
+ args: [
2816
+ {
2817
+ tokenId: BigInt(options.tokenId),
2818
+ amount0Desired,
2819
+ amount1Desired,
2820
+ amount0Min,
2821
+ amount1Min,
2822
+ deadline
2823
+ }
2824
+ ]
2825
+ })
2814
2826
  );
2815
2827
  }
2816
2828
  let value = toHex(0);
2817
2829
  if (options.useNative) {
2818
2830
  const { wrapped } = options.useNative;
2819
- invariant11(position.pool.token0.equals(wrapped) || position.pool.token1.equals(wrapped), "NO_WETH");
2831
+ invariant9(position.pool.token0.equals(wrapped) || position.pool.token1.equals(wrapped), "NO_WETH");
2820
2832
  const wrappedValue = position.pool.token0.equals(wrapped) ? amount0Desired : amount1Desired;
2821
2833
  if (wrappedValue > ZERO) {
2822
2834
  calldatas.push(Payments.encodeRefundETH());
@@ -2830,18 +2842,22 @@ var _NonfungiblePositionManager = class {
2830
2842
  }
2831
2843
  static encodeCollect(options) {
2832
2844
  const calldatas = [];
2833
- const tokenId = toHex(options.tokenId);
2845
+ const tokenId = BigInt(options.tokenId);
2834
2846
  const involvesETH = options.expectedCurrencyOwed0.currency.isNative || options.expectedCurrencyOwed1.currency.isNative;
2835
2847
  const recipient = validateAndParseAddress(options.recipient);
2836
2848
  calldatas.push(
2837
- _NonfungiblePositionManager.INTERFACE.encodeFunctionData("collect", [
2838
- {
2839
- tokenId,
2840
- recipient: involvesETH ? ADDRESS_ZERO : recipient,
2841
- amount0Max: MaxUint128,
2842
- amount1Max: MaxUint128
2843
- }
2844
- ])
2849
+ encodeFunctionData({
2850
+ abi: _NonfungiblePositionManager.ABI,
2851
+ functionName: "collect",
2852
+ args: [
2853
+ {
2854
+ tokenId,
2855
+ recipient: involvesETH ? ADDRESS_ZERO : recipient,
2856
+ amount0Max: MaxUint128,
2857
+ amount1Max: MaxUint128
2858
+ }
2859
+ ]
2860
+ })
2845
2861
  );
2846
2862
  if (involvesETH) {
2847
2863
  const ethAmount = options.expectedCurrencyOwed0.currency.isNative ? options.expectedCurrencyOwed0.quotient : options.expectedCurrencyOwed1.quotient;
@@ -2867,40 +2883,48 @@ var _NonfungiblePositionManager = class {
2867
2883
  */
2868
2884
  static removeCallParameters(position, options) {
2869
2885
  const calldatas = [];
2870
- const deadline = toHex(options.deadline);
2871
- const tokenId = toHex(options.tokenId);
2886
+ const deadline = BigInt(options.deadline);
2887
+ const tokenId = BigInt(options.tokenId);
2872
2888
  const partialPosition = new Position({
2873
2889
  pool: position.pool,
2874
2890
  liquidity: options.liquidityPercentage.multiply(position.liquidity).quotient,
2875
2891
  tickLower: position.tickLower,
2876
2892
  tickUpper: position.tickUpper
2877
2893
  });
2878
- invariant11(partialPosition.liquidity > ZERO, "ZERO_LIQUIDITY");
2894
+ invariant9(partialPosition.liquidity > ZERO, "ZERO_LIQUIDITY");
2879
2895
  const { amount0: amount0Min, amount1: amount1Min } = partialPosition.burnAmountsWithSlippage(
2880
2896
  options.slippageTolerance
2881
2897
  );
2882
2898
  if (options.permit) {
2883
2899
  calldatas.push(
2884
- _NonfungiblePositionManager.INTERFACE.encodeFunctionData("permit", [
2885
- validateAndParseAddress(options.permit.spender),
2886
- tokenId,
2887
- toHex(options.permit.deadline),
2888
- options.permit.v,
2889
- options.permit.r,
2890
- options.permit.s
2891
- ])
2900
+ encodeFunctionData({
2901
+ abi: _NonfungiblePositionManager.ABI,
2902
+ functionName: "permit",
2903
+ args: [
2904
+ validateAndParseAddress(options.permit.spender),
2905
+ tokenId,
2906
+ BigInt(options.permit.deadline),
2907
+ options.permit.v,
2908
+ options.permit.r,
2909
+ options.permit.s
2910
+ ]
2911
+ })
2892
2912
  );
2893
2913
  }
2894
2914
  calldatas.push(
2895
- _NonfungiblePositionManager.INTERFACE.encodeFunctionData("decreaseLiquidity", [
2896
- {
2897
- tokenId,
2898
- liquidity: toHex(partialPosition.liquidity),
2899
- amount0Min: toHex(amount0Min),
2900
- amount1Min: toHex(amount1Min),
2901
- deadline
2902
- }
2903
- ])
2915
+ encodeFunctionData({
2916
+ abi: _NonfungiblePositionManager.ABI,
2917
+ functionName: "decreaseLiquidity",
2918
+ args: [
2919
+ {
2920
+ tokenId,
2921
+ liquidity: partialPosition.liquidity,
2922
+ amount0Min,
2923
+ amount1Min,
2924
+ deadline
2925
+ }
2926
+ ]
2927
+ })
2904
2928
  );
2905
2929
  const { expectedCurrencyOwed0, expectedCurrencyOwed1, ...rest } = options.collectOptions;
2906
2930
  calldatas.push(
@@ -2918,10 +2942,12 @@ var _NonfungiblePositionManager = class {
2918
2942
  );
2919
2943
  if (options.liquidityPercentage.equalTo(ONE)) {
2920
2944
  if (options.burnToken) {
2921
- calldatas.push(_NonfungiblePositionManager.INTERFACE.encodeFunctionData("burn", [tokenId]));
2945
+ calldatas.push(
2946
+ encodeFunctionData({ abi: _NonfungiblePositionManager.ABI, functionName: "burn", args: [tokenId] })
2947
+ );
2922
2948
  }
2923
2949
  } else {
2924
- invariant11(options.burnToken !== true, "CANNOT_BURN");
2950
+ invariant9(options.burnToken !== true, "CANNOT_BURN");
2925
2951
  }
2926
2952
  return {
2927
2953
  calldata: Multicall.encodeMulticall(calldatas),
@@ -2933,16 +2959,17 @@ var _NonfungiblePositionManager = class {
2933
2959
  const sender = validateAndParseAddress(options.sender);
2934
2960
  let calldata;
2935
2961
  if (options.data) {
2936
- calldata = _NonfungiblePositionManager.INTERFACE.encodeFunctionData(
2937
- "safeTransferFrom(address,address,uint256,bytes)",
2938
- [sender, recipient, toHex(options.tokenId), options.data]
2939
- );
2962
+ calldata = encodeFunctionData({
2963
+ abi: _NonfungiblePositionManager.ABI,
2964
+ functionName: "safeTransferFrom",
2965
+ args: [sender, recipient, BigInt(options.tokenId), options.data]
2966
+ });
2940
2967
  } else {
2941
- calldata = _NonfungiblePositionManager.INTERFACE.encodeFunctionData("safeTransferFrom(address,address,uint256)", [
2942
- sender,
2943
- recipient,
2944
- toHex(options.tokenId)
2945
- ]);
2968
+ calldata = encodeFunctionData({
2969
+ abi: _NonfungiblePositionManager.ABI,
2970
+ functionName: "safeTransferFrom",
2971
+ args: [sender, recipient, BigInt(options.tokenId)]
2972
+ });
2946
2973
  }
2947
2974
  return {
2948
2975
  calldata,
@@ -2951,10 +2978,10 @@ var _NonfungiblePositionManager = class {
2951
2978
  }
2952
2979
  };
2953
2980
  var NonfungiblePositionManager = _NonfungiblePositionManager;
2954
- NonfungiblePositionManager.INTERFACE = new Interface(NonfungiblePositionManager_default);
2981
+ NonfungiblePositionManager.ABI = nonfungiblePositionManagerABI;
2955
2982
 
2956
- // src/abi/Quoter.json
2957
- var Quoter_default = [
2983
+ // src/abi/Quoter.ts
2984
+ var quoterABI = [
2958
2985
  {
2959
2986
  inputs: [
2960
2987
  {
@@ -3166,8 +3193,8 @@ var Quoter_default = [
3166
3193
  }
3167
3194
  ];
3168
3195
 
3169
- // src/abi/QuoterV2.json
3170
- var QuoterV2_default = [
3196
+ // src/abi/QuoterV2.ts
3197
+ var quoterV2ABI = [
3171
3198
  {
3172
3199
  inputs: [
3173
3200
  {
@@ -3468,19 +3495,19 @@ var SwapQuoter = class {
3468
3495
  */
3469
3496
  static quoteCallParameters(route, amount, tradeType, options = {}) {
3470
3497
  const singleHop = route.pools.length === 1;
3471
- const quoteAmount = toHex(amount.quotient);
3498
+ const quoteAmount = amount.quotient;
3472
3499
  let calldata;
3473
- const swapInterface = options.useQuoterV2 ? this.V2INTERFACE : this.V1INTERFACE;
3500
+ const swapAbi = options.useQuoterV2 ? this.V2ABI : this.V1ABI;
3474
3501
  if (singleHop) {
3475
3502
  const baseQuoteParams = {
3476
3503
  tokenIn: route.tokenPath[0].address,
3477
3504
  tokenOut: route.tokenPath[1].address,
3478
3505
  fee: route.pools[0].fee,
3479
- sqrtPriceLimitX96: toHex(options?.sqrtPriceLimitX96 ?? 0)
3506
+ sqrtPriceLimitX96: BigInt(options?.sqrtPriceLimitX96 ?? 0)
3480
3507
  };
3481
3508
  const v2QuoteParams = {
3482
3509
  ...baseQuoteParams,
3483
- ...tradeType == TradeType.EXACT_INPUT ? { amountIn: quoteAmount } : { amount: quoteAmount }
3510
+ ...tradeType === TradeType$1.EXACT_INPUT ? { amountIn: quoteAmount } : { amount: quoteAmount }
3484
3511
  };
3485
3512
  const v1QuoteParams = [
3486
3513
  baseQuoteParams.tokenIn,
@@ -3489,16 +3516,31 @@ var SwapQuoter = class {
3489
3516
  quoteAmount,
3490
3517
  baseQuoteParams.sqrtPriceLimitX96
3491
3518
  ];
3492
- const tradeTypeFunctionName = tradeType === TradeType.EXACT_INPUT ? "quoteExactInputSingle" : "quoteExactOutputSingle";
3493
- calldata = swapInterface.encodeFunctionData(
3494
- tradeTypeFunctionName,
3495
- options.useQuoterV2 ? [v2QuoteParams] : v1QuoteParams
3496
- );
3519
+ const tradeTypeFunctionName = tradeType === TradeType$1.EXACT_INPUT ? "quoteExactInputSingle" : "quoteExactOutputSingle";
3520
+ if (options.useQuoterV2) {
3521
+ calldata = encodeFunctionData({
3522
+ abi: this.V2ABI,
3523
+ functionName: tradeTypeFunctionName,
3524
+ // @ts-ignore // FIXME
3525
+ args: [v2QuoteParams]
3526
+ });
3527
+ } else {
3528
+ calldata = encodeFunctionData({
3529
+ abi: this.V1ABI,
3530
+ functionName: tradeTypeFunctionName,
3531
+ args: v1QuoteParams
3532
+ });
3533
+ }
3497
3534
  } else {
3498
- invariant11(options?.sqrtPriceLimitX96 === void 0, "MULTIHOP_PRICE_LIMIT");
3499
- const path = encodeRouteToPath(route, tradeType === TradeType.EXACT_OUTPUT);
3500
- const tradeTypeFunctionName = tradeType === TradeType.EXACT_INPUT ? "quoteExactInput" : "quoteExactOutput";
3501
- calldata = swapInterface.encodeFunctionData(tradeTypeFunctionName, [path, quoteAmount]);
3535
+ invariant9(options?.sqrtPriceLimitX96 === void 0, "MULTIHOP_PRICE_LIMIT");
3536
+ const path = encodeRouteToPath(route, tradeType === TradeType$1.EXACT_OUTPUT);
3537
+ const tradeTypeFunctionName = tradeType === TradeType$1.EXACT_INPUT ? "quoteExactInput" : "quoteExactOutput";
3538
+ calldata = encodeFunctionData({
3539
+ // @ts-ignore
3540
+ abi: swapAbi,
3541
+ functionName: tradeTypeFunctionName,
3542
+ args: [path, quoteAmount]
3543
+ });
3502
3544
  }
3503
3545
  return {
3504
3546
  calldata,
@@ -3506,11 +3548,11 @@ var SwapQuoter = class {
3506
3548
  };
3507
3549
  }
3508
3550
  };
3509
- SwapQuoter.V1INTERFACE = new Interface(Quoter_default);
3510
- SwapQuoter.V2INTERFACE = new Interface(QuoterV2_default);
3551
+ SwapQuoter.V1ABI = quoterABI;
3552
+ SwapQuoter.V2ABI = quoterV2ABI;
3511
3553
 
3512
- // src/abi/V3Staker.json
3513
- var V3Staker_default = [
3554
+ // src/abi/V3Staker.ts
3555
+ var v3StakerABI = [
3514
3556
  {
3515
3557
  inputs: [
3516
3558
  {
@@ -4230,15 +4272,20 @@ var _Staker = class {
4230
4272
  static encodeClaim(incentiveKey, options) {
4231
4273
  const calldatas = [];
4232
4274
  calldatas.push(
4233
- _Staker.INTERFACE.encodeFunctionData("unstakeToken", [
4234
- this._encodeIncentiveKey(incentiveKey),
4235
- toHex(options.tokenId)
4236
- ])
4275
+ encodeFunctionData({
4276
+ abi: _Staker.ABI,
4277
+ functionName: "unstakeToken",
4278
+ args: [this._encodeIncentiveKey(incentiveKey), BigInt(options.tokenId)]
4279
+ })
4237
4280
  );
4238
4281
  const recipient = validateAndParseAddress(options.recipient);
4239
4282
  const amount = options.amount ?? 0;
4240
4283
  calldatas.push(
4241
- _Staker.INTERFACE.encodeFunctionData("claimReward", [incentiveKey.rewardToken.address, recipient, toHex(amount)])
4284
+ encodeFunctionData({
4285
+ abi: _Staker.ABI,
4286
+ functionName: "claimReward",
4287
+ args: [incentiveKey.rewardToken.address, recipient, BigInt(amount)]
4288
+ })
4242
4289
  );
4243
4290
  return calldatas;
4244
4291
  }
@@ -4258,10 +4305,11 @@ var _Staker = class {
4258
4305
  const incentiveKey = incentiveKeys[i];
4259
4306
  calldatas = calldatas.concat(this.encodeClaim(incentiveKey, options));
4260
4307
  calldatas.push(
4261
- _Staker.INTERFACE.encodeFunctionData("stakeToken", [
4262
- this._encodeIncentiveKey(incentiveKey),
4263
- toHex(options.tokenId)
4264
- ])
4308
+ encodeFunctionData({
4309
+ abi: _Staker.ABI,
4310
+ functionName: "stakeToken",
4311
+ args: [this._encodeIncentiveKey(incentiveKey), BigInt(options.tokenId)]
4312
+ })
4265
4313
  );
4266
4314
  }
4267
4315
  return {
@@ -4289,11 +4337,11 @@ var _Staker = class {
4289
4337
  }
4290
4338
  const owner = validateAndParseAddress(withdrawOptions.owner);
4291
4339
  calldatas.push(
4292
- _Staker.INTERFACE.encodeFunctionData("withdrawToken", [
4293
- toHex(withdrawOptions.tokenId),
4294
- owner,
4295
- withdrawOptions.data ? withdrawOptions.data : toHex(0)
4296
- ])
4340
+ encodeFunctionData({
4341
+ abi: _Staker.ABI,
4342
+ functionName: "withdrawToken",
4343
+ args: [BigInt(withdrawOptions.tokenId), owner, toHex(0)]
4344
+ })
4297
4345
  );
4298
4346
  return {
4299
4347
  calldata: Multicall.encodeMulticall(calldatas),
@@ -4314,16 +4362,18 @@ var _Staker = class {
4314
4362
  const incentiveKey = incentiveKeys[i];
4315
4363
  keys.push(this._encodeIncentiveKey(incentiveKey));
4316
4364
  }
4317
- data = defaultAbiCoder.encode([`${_Staker.INCENTIVE_KEY_ABI}[]`], [keys]);
4365
+ data = encodeAbiParameters(parseAbiParameters([`${_Staker.INCENTIVE_KEY_ABI}[]`]), [keys]);
4318
4366
  } else {
4319
- data = defaultAbiCoder.encode([_Staker.INCENTIVE_KEY_ABI], [this._encodeIncentiveKey(incentiveKeys[0])]);
4367
+ data = encodeAbiParameters(parseAbiParameters(_Staker.INCENTIVE_KEY_ABI), [
4368
+ this._encodeIncentiveKey(incentiveKeys[0])
4369
+ ]);
4320
4370
  }
4321
4371
  return data;
4322
4372
  }
4323
4373
  /**
4324
4374
  *
4325
4375
  * @param incentiveKey An `IncentiveKey` which represents a unique staking program.
4326
- * @returns An encoded IncentiveKey to be read by ethers
4376
+ * @returns An encoded IncentiveKey to be read by viem
4327
4377
  */
4328
4378
  static _encodeIncentiveKey(incentiveKey) {
4329
4379
  const { token0, token1, fee } = incentiveKey.pool;
@@ -4331,18 +4381,18 @@ var _Staker = class {
4331
4381
  return {
4332
4382
  rewardToken: incentiveKey.rewardToken.address,
4333
4383
  pool: Pool.getAddress(token0, token1, fee),
4334
- startTime: toHex(incentiveKey.startTime),
4335
- endTime: toHex(incentiveKey.endTime),
4384
+ startTime: BigInt(incentiveKey.startTime),
4385
+ endTime: BigInt(incentiveKey.endTime),
4336
4386
  refundee
4337
4387
  };
4338
4388
  }
4339
4389
  };
4340
4390
  var Staker = _Staker;
4341
- Staker.INTERFACE = new Interface(V3Staker_default);
4391
+ Staker.ABI = v3StakerABI;
4342
4392
  Staker.INCENTIVE_KEY_ABI = "tuple(address rewardToken, address pool, uint256 startTime, uint256 endTime, address refundee)";
4343
4393
 
4344
- // src/abi/SwapRouter.json
4345
- var SwapRouter_default = [
4394
+ // src/abi/SwapRouter.ts
4395
+ var swapRouterABI = [
4346
4396
  {
4347
4397
  inputs: [
4348
4398
  {
@@ -4945,11 +4995,11 @@ var _SwapRouter = class {
4945
4995
  const sampleTrade = trades[0];
4946
4996
  const tokenIn = sampleTrade.inputAmount.currency.wrapped;
4947
4997
  const tokenOut = sampleTrade.outputAmount.currency.wrapped;
4948
- invariant11(
4998
+ invariant9(
4949
4999
  trades.every((trade) => trade.inputAmount.currency.wrapped.equals(tokenIn)),
4950
5000
  "TOKEN_IN_DIFF"
4951
5001
  );
4952
- invariant11(
5002
+ invariant9(
4953
5003
  trades.every((trade) => trade.outputAmount.currency.wrapped.equals(tokenOut)),
4954
5004
  "TOKEN_OUT_DIFF"
4955
5005
  );
@@ -4966,15 +5016,15 @@ var _SwapRouter = class {
4966
5016
  const routerMustCustody = outputIsNative || !!options.fee;
4967
5017
  const totalValue = inputIsNative ? trades.reduce((sum, trade) => sum.add(trade.maximumAmountIn(options.slippageTolerance)), ZERO_IN) : ZERO_IN;
4968
5018
  if (options.inputTokenPermit) {
4969
- invariant11(sampleTrade.inputAmount.currency.isToken, "NON_TOKEN_PERMIT");
5019
+ invariant9(sampleTrade.inputAmount.currency.isToken, "NON_TOKEN_PERMIT");
4970
5020
  calldatas.push(SelfPermit.encodePermit(sampleTrade.inputAmount.currency, options.inputTokenPermit));
4971
5021
  }
4972
5022
  const recipient = validateAndParseAddress(options.recipient);
4973
- const deadline = toHex(options.deadline);
5023
+ const deadline = BigInt(options.deadline);
4974
5024
  for (const trade of trades) {
4975
5025
  for (const { route, inputAmount, outputAmount } of trade.swaps) {
4976
- const amountIn = toHex(trade.maximumAmountIn(options.slippageTolerance, inputAmount).quotient);
4977
- const amountOut = toHex(trade.minimumAmountOut(options.slippageTolerance, outputAmount).quotient);
5026
+ const amountIn = BigInt(trade.maximumAmountIn(options.slippageTolerance, inputAmount).quotient);
5027
+ const amountOut = BigInt(trade.minimumAmountOut(options.slippageTolerance, outputAmount).quotient);
4978
5028
  const singleHop = route.pools.length === 1;
4979
5029
  if (singleHop) {
4980
5030
  if (trade.tradeType === TradeType.EXACT_INPUT) {
@@ -4986,9 +5036,15 @@ var _SwapRouter = class {
4986
5036
  deadline,
4987
5037
  amountIn,
4988
5038
  amountOutMinimum: amountOut,
4989
- sqrtPriceLimitX96: toHex(options.sqrtPriceLimitX96 ?? 0)
5039
+ sqrtPriceLimitX96: BigInt(options.sqrtPriceLimitX96 ?? 0)
4990
5040
  };
4991
- calldatas.push(_SwapRouter.INTERFACE.encodeFunctionData("exactInputSingle", [exactInputSingleParams]));
5041
+ calldatas.push(
5042
+ encodeFunctionData({
5043
+ abi: _SwapRouter.ABI,
5044
+ functionName: "exactInputSingle",
5045
+ args: [exactInputSingleParams]
5046
+ })
5047
+ );
4992
5048
  } else {
4993
5049
  const exactOutputSingleParams = {
4994
5050
  tokenIn: route.tokenPath[0].address,
@@ -4998,12 +5054,18 @@ var _SwapRouter = class {
4998
5054
  deadline,
4999
5055
  amountOut,
5000
5056
  amountInMaximum: amountIn,
5001
- sqrtPriceLimitX96: toHex(options.sqrtPriceLimitX96 ?? 0)
5057
+ sqrtPriceLimitX96: BigInt(options.sqrtPriceLimitX96 ?? 0)
5002
5058
  };
5003
- calldatas.push(_SwapRouter.INTERFACE.encodeFunctionData("exactOutputSingle", [exactOutputSingleParams]));
5059
+ calldatas.push(
5060
+ encodeFunctionData({
5061
+ abi: _SwapRouter.ABI,
5062
+ functionName: "exactOutputSingle",
5063
+ args: [exactOutputSingleParams]
5064
+ })
5065
+ );
5004
5066
  }
5005
5067
  } else {
5006
- invariant11(options.sqrtPriceLimitX96 === void 0, "MULTIHOP_PRICE_LIMIT");
5068
+ invariant9(options.sqrtPriceLimitX96 === void 0, "MULTIHOP_PRICE_LIMIT");
5007
5069
  const path = encodeRouteToPath(route, trade.tradeType === TradeType.EXACT_OUTPUT);
5008
5070
  if (trade.tradeType === TradeType.EXACT_INPUT) {
5009
5071
  const exactInputParams = {
@@ -5013,7 +5075,9 @@ var _SwapRouter = class {
5013
5075
  amountIn,
5014
5076
  amountOutMinimum: amountOut
5015
5077
  };
5016
- calldatas.push(_SwapRouter.INTERFACE.encodeFunctionData("exactInput", [exactInputParams]));
5078
+ calldatas.push(
5079
+ encodeFunctionData({ abi: _SwapRouter.ABI, functionName: "exactInput", args: [exactInputParams] })
5080
+ );
5017
5081
  } else {
5018
5082
  const exactOutputParams = {
5019
5083
  path,
@@ -5022,7 +5086,9 @@ var _SwapRouter = class {
5022
5086
  amountOut,
5023
5087
  amountInMaximum: amountIn
5024
5088
  };
5025
- calldatas.push(_SwapRouter.INTERFACE.encodeFunctionData("exactOutput", [exactOutputParams]));
5089
+ calldatas.push(
5090
+ encodeFunctionData({ abi: _SwapRouter.ABI, functionName: "exactOutput", args: [exactOutputParams] })
5091
+ );
5026
5092
  }
5027
5093
  }
5028
5094
  }
@@ -5055,10 +5121,11 @@ var _SwapRouter = class {
5055
5121
  }
5056
5122
  };
5057
5123
  var SwapRouter = _SwapRouter;
5058
- SwapRouter.INTERFACE = new Interface(SwapRouter_default);
5124
+ // public static INTERFACE: Interface = new Interface(ISwapRouter)
5125
+ SwapRouter.ABI = swapRouterABI;
5059
5126
 
5060
- // src/abi/MasterChefV3.json
5061
- var MasterChefV3_default = [
5127
+ // src/abi/MasterChefV3.ts
5128
+ var masterChefV3ABI = [
5062
5129
  {
5063
5130
  inputs: [
5064
5131
  { internalType: "contract IERC20", name: "_CAKE", type: "address" },
@@ -5746,14 +5813,14 @@ var _MasterChefV3 = class {
5746
5813
  // Copy from NonfungiblePositionManager
5747
5814
  // Only support increaseLiquidity
5748
5815
  static addCallParameters(position, options) {
5749
- invariant11(position.liquidity > ZERO$1, "ZERO_LIQUIDITY");
5816
+ invariant9(position.liquidity > ZERO$2, "ZERO_LIQUIDITY");
5750
5817
  const calldatas = [];
5751
5818
  const { amount0: amount0Desired, amount1: amount1Desired } = position.mintAmounts;
5752
5819
  const minimumAmounts = position.mintAmountsWithSlippage(options.slippageTolerance);
5753
- const amount0Min = toHex(minimumAmounts.amount0);
5754
- const amount1Min = toHex(minimumAmounts.amount1);
5755
- const deadline = toHex(options.deadline);
5756
- invariant11(!isMint(options), "NO_MINT_SUPPORT");
5820
+ const amount0Min = BigInt(minimumAmounts.amount0);
5821
+ const amount1Min = BigInt(minimumAmounts.amount1);
5822
+ const deadline = BigInt(options.deadline);
5823
+ invariant9(!isMint(options), "NO_MINT_SUPPORT");
5757
5824
  if (options.token0Permit) {
5758
5825
  calldatas.push(SelfPermit.encodePermit(position.pool.token0, options.token0Permit));
5759
5826
  }
@@ -5761,21 +5828,25 @@ var _MasterChefV3 = class {
5761
5828
  calldatas.push(SelfPermit.encodePermit(position.pool.token1, options.token1Permit));
5762
5829
  }
5763
5830
  calldatas.push(
5764
- _MasterChefV3.INTERFACE.encodeFunctionData("increaseLiquidity", [
5765
- {
5766
- tokenId: toHex(options.tokenId),
5767
- amount0Desired: toHex(amount0Desired),
5768
- amount1Desired: toHex(amount1Desired),
5769
- amount0Min,
5770
- amount1Min,
5771
- deadline
5772
- }
5773
- ])
5831
+ encodeFunctionData({
5832
+ abi: _MasterChefV3.ABI,
5833
+ functionName: "increaseLiquidity",
5834
+ args: [
5835
+ {
5836
+ tokenId: BigInt(options.tokenId),
5837
+ amount0Desired,
5838
+ amount1Desired,
5839
+ amount0Min,
5840
+ amount1Min,
5841
+ deadline
5842
+ }
5843
+ ]
5844
+ })
5774
5845
  );
5775
5846
  let value = toHex(0);
5776
5847
  if (options.useNative) {
5777
5848
  const { wrapped } = options.useNative;
5778
- invariant11(position.pool.token0.equals(wrapped) || position.pool.token1.equals(wrapped), "NO_WETH");
5849
+ invariant9(position.pool.token0.equals(wrapped) || position.pool.token1.equals(wrapped), "NO_WETH");
5779
5850
  const wrappedValue = position.pool.token0.equals(wrapped) ? amount0Desired : amount1Desired;
5780
5851
  value = toHex(wrappedValue);
5781
5852
  }
@@ -5787,18 +5858,22 @@ var _MasterChefV3 = class {
5787
5858
  // Copy from NonfungiblePositionManager
5788
5859
  static encodeCollect(options) {
5789
5860
  const calldatas = [];
5790
- const tokenId = toHex(options.tokenId);
5861
+ const tokenId = BigInt(options.tokenId);
5791
5862
  const involvesETH = options.expectedCurrencyOwed0.currency.isNative || options.expectedCurrencyOwed1.currency.isNative;
5792
5863
  const recipient = validateAndParseAddress(options.recipient);
5793
5864
  calldatas.push(
5794
- _MasterChefV3.INTERFACE.encodeFunctionData("collect", [
5795
- {
5796
- tokenId,
5797
- recipient: involvesETH ? ADDRESS_ZERO : recipient,
5798
- amount0Max: MaxUint128,
5799
- amount1Max: MaxUint128
5800
- }
5801
- ])
5865
+ encodeFunctionData({
5866
+ abi: _MasterChefV3.ABI,
5867
+ functionName: "collect",
5868
+ args: [
5869
+ {
5870
+ tokenId,
5871
+ recipient: involvesETH ? ADDRESS_ZERO : recipient,
5872
+ amount0Max: MaxUint128,
5873
+ amount1Max: MaxUint128
5874
+ }
5875
+ ]
5876
+ })
5802
5877
  );
5803
5878
  if (involvesETH) {
5804
5879
  const ethAmount = options.expectedCurrencyOwed0.currency.isNative ? options.expectedCurrencyOwed0.quotient : options.expectedCurrencyOwed1.quotient;
@@ -5818,40 +5893,35 @@ var _MasterChefV3 = class {
5818
5893
  }
5819
5894
  static removeCallParameters(position, options) {
5820
5895
  const calldatas = [];
5821
- const deadline = toHex(options.deadline);
5822
- const tokenId = toHex(options.tokenId);
5896
+ const deadline = BigInt(options.deadline);
5897
+ const tokenId = BigInt(options.tokenId);
5823
5898
  const partialPosition = new Position({
5824
5899
  pool: position.pool,
5825
5900
  liquidity: options.liquidityPercentage.multiply(position.liquidity).quotient,
5826
5901
  tickLower: position.tickLower,
5827
5902
  tickUpper: position.tickUpper
5828
5903
  });
5829
- invariant11(partialPosition.liquidity > ZERO$1, "ZERO_LIQUIDITY");
5904
+ invariant9(partialPosition.liquidity > ZERO$2, "ZERO_LIQUIDITY");
5830
5905
  const { amount0: amount0Min, amount1: amount1Min } = partialPosition.burnAmountsWithSlippage(
5831
5906
  options.slippageTolerance
5832
5907
  );
5833
5908
  if (options.permit) {
5834
- calldatas.push(
5835
- _MasterChefV3.INTERFACE.encodeFunctionData("permit", [
5836
- validateAndParseAddress(options.permit.spender),
5837
- tokenId,
5838
- toHex(options.permit.deadline),
5839
- options.permit.v,
5840
- options.permit.r,
5841
- options.permit.s
5842
- ])
5843
- );
5909
+ throw new Error("NOT_IMPLEMENTED");
5844
5910
  }
5845
5911
  calldatas.push(
5846
- _MasterChefV3.INTERFACE.encodeFunctionData("decreaseLiquidity", [
5847
- {
5848
- tokenId,
5849
- liquidity: toHex(partialPosition.liquidity),
5850
- amount0Min: toHex(amount0Min),
5851
- amount1Min: toHex(amount1Min),
5852
- deadline
5853
- }
5854
- ])
5912
+ encodeFunctionData({
5913
+ abi: _MasterChefV3.ABI,
5914
+ functionName: "decreaseLiquidity",
5915
+ args: [
5916
+ {
5917
+ tokenId,
5918
+ liquidity: partialPosition.liquidity,
5919
+ amount0Min,
5920
+ amount1Min,
5921
+ deadline
5922
+ }
5923
+ ]
5924
+ })
5855
5925
  );
5856
5926
  const { expectedCurrencyOwed0, expectedCurrencyOwed1, ...rest } = options.collectOptions;
5857
5927
  calldatas.push(
@@ -5870,26 +5940,28 @@ var _MasterChefV3 = class {
5870
5940
  if (rest?.recipient) {
5871
5941
  if (options.liquidityPercentage.equalTo(ONE$1)) {
5872
5942
  calldatas.push(
5873
- _MasterChefV3.INTERFACE.encodeFunctionData("withdraw", [
5874
- tokenId.toString(),
5875
- validateAndParseAddress(rest?.recipient)
5876
- ])
5943
+ encodeFunctionData({
5944
+ abi: _MasterChefV3.ABI,
5945
+ functionName: "withdraw",
5946
+ args: [tokenId, validateAndParseAddress(rest?.recipient)]
5947
+ })
5877
5948
  );
5878
5949
  } else {
5879
5950
  calldatas.push(
5880
- _MasterChefV3.INTERFACE.encodeFunctionData("harvest", [
5881
- tokenId.toString(),
5882
- validateAndParseAddress(rest?.recipient)
5883
- ])
5951
+ encodeFunctionData({
5952
+ abi: _MasterChefV3.ABI,
5953
+ functionName: "harvest",
5954
+ args: [tokenId, validateAndParseAddress(rest?.recipient)]
5955
+ })
5884
5956
  );
5885
5957
  }
5886
5958
  }
5887
5959
  if (options.liquidityPercentage.equalTo(ONE$1)) {
5888
5960
  if (options.burnToken) {
5889
- calldatas.push(_MasterChefV3.INTERFACE.encodeFunctionData("burn", [tokenId]));
5961
+ calldatas.push(encodeFunctionData({ abi: _MasterChefV3.ABI, functionName: "burn", args: [tokenId] }));
5890
5962
  }
5891
5963
  } else {
5892
- invariant11(options.burnToken !== true, "CANNOT_BURN");
5964
+ invariant9(options.burnToken !== true, "CANNOT_BURN");
5893
5965
  }
5894
5966
  return {
5895
5967
  calldata: Multicall.encodeMulticall(calldatas),
@@ -5915,7 +5987,11 @@ var _MasterChefV3 = class {
5915
5987
  const { tokenId, to } = options;
5916
5988
  const calldatas = [];
5917
5989
  calldatas.push(
5918
- _MasterChefV3.INTERFACE.encodeFunctionData("harvest", [tokenId.toString(), validateAndParseAddress(to)])
5990
+ encodeFunctionData({
5991
+ abi: _MasterChefV3.ABI,
5992
+ functionName: "harvest",
5993
+ args: [BigInt(tokenId), validateAndParseAddress(to)]
5994
+ })
5919
5995
  );
5920
5996
  return calldatas;
5921
5997
  }
@@ -5923,7 +5999,11 @@ var _MasterChefV3 = class {
5923
5999
  const { tokenId, to } = options;
5924
6000
  const calldatas = [];
5925
6001
  calldatas.push(
5926
- _MasterChefV3.INTERFACE.encodeFunctionData("withdraw", [tokenId.toString(), validateAndParseAddress(to)])
6002
+ encodeFunctionData({
6003
+ abi: _MasterChefV3.ABI,
6004
+ functionName: "withdraw",
6005
+ args: [BigInt(tokenId), validateAndParseAddress(to)]
6006
+ })
5927
6007
  );
5928
6008
  return {
5929
6009
  calldata: Multicall.encodeMulticall(calldatas),
@@ -5932,6 +6012,6 @@ var _MasterChefV3 = class {
5932
6012
  }
5933
6013
  };
5934
6014
  var MasterChefV3 = _MasterChefV3;
5935
- MasterChefV3.INTERFACE = new Interface(MasterChefV3_default);
6015
+ MasterChefV3.ABI = masterChefV3ABI;
5936
6016
 
5937
- export { ADDRESS_ZERO, DEPLOYER_ADDRESS, DEPLOYER_ADDRESSES, FACTORY_ADDRESS, FeeAmount, FeeCalculator, FullMath, LiquidityMath, MasterChefV3, MaxUint128, Multicall, NoTickDataProvider, NonfungiblePositionManager, POOL_INIT_CODE_HASH, Payments, Pool, Position, PositionLibrary, PositionMath, Route, SelfPermit, SqrtPriceMath, Staker, SwapMath, SwapQuoter, SwapRouter, TICK_SPACINGS, Tick, TickLibrary, TickList, TickListDataProvider, TickMath, Trade, computePoolAddress, encodeRouteToPath, encodeSqrtRatioX96, getAmountsAtNewPrice, getAmountsByLiquidityAndPrice, getAverageLiquidity, getDependentAmount, getEstimatedLPFee, getEstimatedLPFeeByAmounts, getEstimatedLPFeeByAmountsWithProtocolFee, getEstimatedLPFeeWithProtocolFee, getLiquidityByAmountsAndPrice, getLiquidityBySingleAmount, getLiquidityFromSqrtRatioX96, getLiquidityFromTick, isMint, isSorted, maxLiquidityForAmounts, mostSignificantBit, nearestUsableTick, parseProtocolFees, priceToClosestTick, sqrtRatioX96ToPrice, subIn256, tickToPrice, toHex, tradeComparator };
6017
+ export { ADDRESS_ZERO, DEPLOYER_ADDRESS, DEPLOYER_ADDRESSES, FACTORY_ADDRESS, FeeAmount, FeeCalculator, FullMath, LiquidityMath, MasterChefV3, MaxUint128, Multicall, NoTickDataProvider, NonfungiblePositionManager, POOL_INIT_CODE_HASH, Payments, Pool, Position, PositionLibrary, PositionMath, Route, SelfPermit, SqrtPriceMath, Staker, SwapMath, SwapQuoter, SwapRouter, TICK_SPACINGS, Tick, TickLibrary, TickList, TickListDataProvider, TickMath, Trade, computePoolAddress, encodeRouteToPath, encodeSqrtRatioX96, getAmountsAtNewPrice, getAmountsByLiquidityAndPrice, getAverageLiquidity, getDependentAmount, getEstimatedLPFee, getEstimatedLPFeeByAmounts, getEstimatedLPFeeByAmountsWithProtocolFee, getEstimatedLPFeeWithProtocolFee, getLiquidityByAmountsAndPrice, getLiquidityBySingleAmount, getLiquidityFromSqrtRatioX96, getLiquidityFromTick, isMint, isSorted, masterChefV3ABI, maxLiquidityForAmounts, mostSignificantBit, nearestUsableTick, nonfungiblePositionManagerABI, parseProtocolFees, peripheryPaymentsWithFeeABI, priceToClosestTick, quoterABI, quoterV2ABI, selfPermitABI, sqrtRatioX96ToPrice, subIn256, swapRouterABI, tickToPrice, toHex, tradeComparator, v3StakerABI };