@pancakeswap/v3-sdk 2.0.0 → 3.0.1

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