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