@alcorexchange/alcor-swap-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc +12 -0
  3. package/LICENSE +21 -0
  4. package/build/entities/baseCurrency.js +27 -0
  5. package/build/entities/currency.js +2 -0
  6. package/build/entities/fractions/currencyAmount.js +80 -0
  7. package/build/entities/fractions/fraction.js +117 -0
  8. package/build/entities/fractions/index.js +11 -0
  9. package/build/entities/fractions/percent.js +46 -0
  10. package/build/entities/fractions/price.js +73 -0
  11. package/build/entities/index.js +26 -0
  12. package/build/entities/pool.js +248 -0
  13. package/build/entities/position.js +364 -0
  14. package/build/entities/route.js +70 -0
  15. package/build/entities/tick.js +23 -0
  16. package/build/entities/tickDataProvider.js +30 -0
  17. package/build/entities/tickListDataProvider.js +35 -0
  18. package/build/entities/token.js +53 -0
  19. package/build/entities/trade.js +464 -0
  20. package/build/index.js +19 -0
  21. package/build/internalConstants.js +54 -0
  22. package/build/utils/computeAllRoutes.js +39 -0
  23. package/build/utils/encodeSqrtRatioX64.js +21 -0
  24. package/build/utils/fullMath.js +22 -0
  25. package/build/utils/index.js +30 -0
  26. package/build/utils/isSorted.js +18 -0
  27. package/build/utils/liquidityMath.js +23 -0
  28. package/build/utils/maxLiquidityForAmounts.js +86 -0
  29. package/build/utils/mostSignificantBit.js +27 -0
  30. package/build/utils/nearestUsableTick.js +26 -0
  31. package/build/utils/positionLibrary.js +22 -0
  32. package/build/utils/priceTickConversions.js +51 -0
  33. package/build/utils/sortedInsert.js +39 -0
  34. package/build/utils/sqrt.js +33 -0
  35. package/build/utils/sqrtPriceMath.js +92 -0
  36. package/build/utils/swapMath.js +86 -0
  37. package/build/utils/tickLibrary.js +61 -0
  38. package/build/utils/tickList.js +110 -0
  39. package/build/utils/tickMath.js +122 -0
  40. package/jest.config.js +40 -0
  41. package/nodemon.json +6 -0
  42. package/package.json +51 -0
  43. package/src/entities/baseCurrency.ts +53 -0
  44. package/src/entities/currency.ts +3 -0
  45. package/src/entities/fractions/currencyAmount.ts +129 -0
  46. package/src/entities/fractions/fraction.ts +190 -0
  47. package/src/entities/fractions/index.ts +4 -0
  48. package/src/entities/fractions/percent.ts +54 -0
  49. package/src/entities/fractions/price.ts +127 -0
  50. package/src/entities/index.ts +11 -0
  51. package/src/entities/pool.ts +399 -0
  52. package/src/entities/position.ts +591 -0
  53. package/src/entities/route.ts +84 -0
  54. package/src/entities/tick.ts +48 -0
  55. package/src/entities/tickDataProvider.ts +43 -0
  56. package/src/entities/tickListDataProvider.ts +37 -0
  57. package/src/entities/token.ts +56 -0
  58. package/src/entities/trade.ts +650 -0
  59. package/src/index.ts +3 -0
  60. package/src/internalConstants.ts +58 -0
  61. package/src/utils/computeAllRoutes.ts +64 -0
  62. package/src/utils/encodeSqrtRatioX64.ts +20 -0
  63. package/src/utils/fullMath.ts +17 -0
  64. package/src/utils/index.ts +14 -0
  65. package/src/utils/isSorted.ts +17 -0
  66. package/src/utils/liquidityMath.ts +17 -0
  67. package/src/utils/maxLiquidityForAmounts.ts +127 -0
  68. package/src/utils/mostSignificantBit.ts +25 -0
  69. package/src/utils/nearestUsableTick.ts +23 -0
  70. package/src/utils/positionLibrary.ts +37 -0
  71. package/src/utils/priceTickConversions.ts +57 -0
  72. package/src/utils/sortedInsert.ts +35 -0
  73. package/src/utils/sqrt.ts +31 -0
  74. package/src/utils/sqrtPriceMath.ts +169 -0
  75. package/src/utils/swapMath.ts +175 -0
  76. package/src/utils/tickLibrary.ts +88 -0
  77. package/src/utils/tickList.ts +147 -0
  78. package/src/utils/tickMath.ts +166 -0
  79. package/test/bestTradeExactOut.test.ts +266 -0
  80. package/test/currencyAmount.test.js +92 -0
  81. package/test/currencyAmount.test.ts +114 -0
  82. package/test/encodeSqrtRatioX64.test.ts +33 -0
  83. package/test/fixtures/pools.json +276 -0
  84. package/test/fixtures/ticks.json +608 -0
  85. package/test/fraction.test.js +87 -0
  86. package/test/fraction.test.ts +176 -0
  87. package/test/isSorted.test.ts +52 -0
  88. package/test/maxLiquidityForAmounts.test copy.ts +256 -0
  89. package/test/mostSignificantBit.test.ts +32 -0
  90. package/test/nearestUsableTick.test.ts +54 -0
  91. package/test/percent.test.js +52 -0
  92. package/test/percent.test.ts +68 -0
  93. package/test/pool.test.ts +377 -0
  94. package/test/position.test.ts +579 -0
  95. package/test/positionLibrary.test.ts +31 -0
  96. package/test/price.test.js +57 -0
  97. package/test/price.test.ts +62 -0
  98. package/test/priceTickConversions.test.ts +137 -0
  99. package/test/sqrtPriceMath.test.ts +113 -0
  100. package/test/tick.test.js +22 -0
  101. package/test/tick.test.ts +28 -0
  102. package/test/tickDataProvider.test.ts +17 -0
  103. package/test/tickLibrary.test.ts +111 -0
  104. package/test/tickList.test.ts +215 -0
  105. package/test/tickListDataProvider.test.ts +64 -0
  106. package/test/tickMath.test.ts +66 -0
  107. package/test/token.test.ts +58 -0
  108. package/test/trade.test.ts +210 -0
  109. package/test2.ts +73 -0
  110. package/tsconfig.json +24 -0
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isSorted = void 0;
4
+ /**
5
+ * Determines if a tick list is sorted
6
+ * @param list The tick list
7
+ * @param comparator The comparator
8
+ * @returns true if sorted
9
+ */
10
+ function isSorted(list, comparator) {
11
+ for (let i = 0; i < list.length - 1; i++) {
12
+ if (comparator(list[i], list[i + 1]) > 0) {
13
+ return false;
14
+ }
15
+ }
16
+ return true;
17
+ }
18
+ exports.isSorted = isSorted;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.LiquidityMath = void 0;
7
+ const jsbi_1 = __importDefault(require("jsbi"));
8
+ const internalConstants_1 = require("../internalConstants");
9
+ class LiquidityMath {
10
+ /**
11
+ * Cannot be constructed.
12
+ */
13
+ constructor() { }
14
+ static addDelta(x, y) {
15
+ if (jsbi_1.default.lessThan(y, internalConstants_1.ZERO)) {
16
+ return jsbi_1.default.subtract(x, jsbi_1.default.multiply(y, internalConstants_1.NEGATIVE_ONE));
17
+ }
18
+ else {
19
+ return jsbi_1.default.add(x, y);
20
+ }
21
+ }
22
+ }
23
+ exports.LiquidityMath = LiquidityMath;
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.maxLiquidityForAmounts = void 0;
7
+ const jsbi_1 = __importDefault(require("jsbi"));
8
+ const internalConstants_1 = require("../internalConstants");
9
+ /**
10
+ * Returns an imprecise maximum amount of liquidity received for a given amount of token 0.
11
+ * This function is available to accommodate LiquidityAmounts#getLiquidityForAmountA in the v3 periphery,
12
+ * which could be more precise by at least 32 bits by dividing by Q64 instead of Q64 in the intermediate step,
13
+ * and shifting the subtracted ratio left by 32 bits. This imprecise calculation will likely be replaced in a future
14
+ * v3 router contract.
15
+ * @param sqrtRatioLX64 The price at the lower boundary
16
+ * @param sqrtRatioUX64 The price at the upper boundary
17
+ * @param amountA The token0 amount
18
+ * @returns liquidity for amountA, imprecise
19
+ */
20
+ function maxLiquidityForAmountAImprecise(sqrtRatioLX64, sqrtRatioUX64, amountA) {
21
+ if (jsbi_1.default.greaterThan(sqrtRatioLX64, sqrtRatioUX64)) {
22
+ [sqrtRatioLX64, sqrtRatioUX64] = [sqrtRatioUX64, sqrtRatioLX64];
23
+ }
24
+ const intermediate = jsbi_1.default.divide(jsbi_1.default.multiply(sqrtRatioLX64, sqrtRatioUX64), internalConstants_1.Q64);
25
+ return jsbi_1.default.divide(jsbi_1.default.multiply(jsbi_1.default.BigInt(amountA), intermediate), jsbi_1.default.subtract(sqrtRatioUX64, sqrtRatioLX64));
26
+ }
27
+ /**
28
+ * Returns a precise maximum amount of liquidity received for a given amount of token 0 by dividing by Q64 instead of Q64 in the intermediate step,
29
+ * and shifting the subtracted ratio left by 32 bits.
30
+ * @param sqrtRatioLX64 The price at the lower boundary
31
+ * @param sqrtRatioUX64 The price at the upper boundary
32
+ * @param amountA The token0 amount
33
+ * @returns liquidity for amountA, precise
34
+ */
35
+ function maxLiquidityForAmountAPrecise(sqrtRatioLX64, sqrtRatioUX64, amountA) {
36
+ if (jsbi_1.default.greaterThan(sqrtRatioLX64, sqrtRatioUX64)) {
37
+ [sqrtRatioLX64, sqrtRatioUX64] = [sqrtRatioUX64, sqrtRatioLX64];
38
+ }
39
+ const numerator = jsbi_1.default.multiply(jsbi_1.default.multiply(jsbi_1.default.BigInt(amountA), sqrtRatioLX64), sqrtRatioUX64);
40
+ const denominator = jsbi_1.default.multiply(internalConstants_1.Q64, jsbi_1.default.subtract(sqrtRatioUX64, sqrtRatioLX64));
41
+ return jsbi_1.default.divide(numerator, denominator);
42
+ }
43
+ /**
44
+ * Computes the maximum amount of liquidity received for a given amount of token1
45
+ * @param sqrtRatioLX64 The price at the lower tick boundary
46
+ * @param sqrtRatioUX64 The price at the upper tick boundary
47
+ * @param amountB The token1 amount
48
+ * @returns liquidity for amountB
49
+ */
50
+ function maxLiquidityForAmountB(sqrtRatioLX64, sqrtRatioUX64, amountB) {
51
+ if (jsbi_1.default.greaterThan(sqrtRatioLX64, sqrtRatioUX64)) {
52
+ [sqrtRatioLX64, sqrtRatioUX64] = [sqrtRatioUX64, sqrtRatioLX64];
53
+ }
54
+ return jsbi_1.default.divide(jsbi_1.default.multiply(jsbi_1.default.BigInt(amountB), internalConstants_1.Q64), jsbi_1.default.subtract(sqrtRatioUX64, sqrtRatioLX64));
55
+ }
56
+ /**
57
+ * Computes the maximum amount of liquidity received for a given amount of token0, token1,
58
+ * and the prices at the tick boundaries.
59
+ * @param sqrtRatioCurrentX64 the current price
60
+ * @param sqrtRatioLX64 price at lower boundary
61
+ * @param sqrtRatioUX64 price at upper boundary
62
+ * @param amountA token0 amount
63
+ * @param amountB token1 amount
64
+ * @param useFullPrecision if false, liquidity will be maximized according to what the router can calculate,
65
+ * not what core can theoretically support
66
+ */
67
+ function maxLiquidityForAmounts(sqrtRatioCurrentX64, sqrtRatioLX64, sqrtRatioUX64, amountA, amountB, useFullPrecision) {
68
+ if (jsbi_1.default.greaterThan(sqrtRatioLX64, sqrtRatioUX64)) {
69
+ [sqrtRatioLX64, sqrtRatioUX64] = [sqrtRatioUX64, sqrtRatioLX64];
70
+ }
71
+ const maxLiquidityForAmountA = useFullPrecision
72
+ ? maxLiquidityForAmountAPrecise
73
+ : maxLiquidityForAmountAImprecise;
74
+ if (jsbi_1.default.lessThanOrEqual(sqrtRatioCurrentX64, sqrtRatioLX64)) {
75
+ return maxLiquidityForAmountA(sqrtRatioLX64, sqrtRatioUX64, amountA);
76
+ }
77
+ else if (jsbi_1.default.lessThan(sqrtRatioCurrentX64, sqrtRatioUX64)) {
78
+ const liquidityA = maxLiquidityForAmountA(sqrtRatioCurrentX64, sqrtRatioUX64, amountA);
79
+ const liquidityB = maxLiquidityForAmountB(sqrtRatioLX64, sqrtRatioCurrentX64, amountB);
80
+ return jsbi_1.default.lessThan(liquidityA, liquidityB) ? liquidityA : liquidityB;
81
+ }
82
+ else {
83
+ return maxLiquidityForAmountB(sqrtRatioLX64, sqrtRatioUX64, amountB);
84
+ }
85
+ }
86
+ exports.maxLiquidityForAmounts = maxLiquidityForAmounts;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.mostSignificantBit = void 0;
7
+ const jsbi_1 = __importDefault(require("jsbi"));
8
+ const tiny_invariant_1 = __importDefault(require("tiny-invariant"));
9
+ const internalConstants_1 = require("../internalConstants");
10
+ const TWO = jsbi_1.default.BigInt(2);
11
+ const POWERS_OF_2 = [128, 64, 32, 16, 8, 4, 2, 1].map((pow) => [
12
+ pow,
13
+ jsbi_1.default.exponentiate(TWO, jsbi_1.default.BigInt(pow)),
14
+ ]);
15
+ function mostSignificantBit(x) {
16
+ (0, tiny_invariant_1.default)(jsbi_1.default.greaterThan(x, internalConstants_1.ZERO), "ZERO");
17
+ (0, tiny_invariant_1.default)(jsbi_1.default.lessThanOrEqual(x, internalConstants_1.MaxUint256), "MAX");
18
+ let msb = 0;
19
+ for (const [power, min] of POWERS_OF_2) {
20
+ if (jsbi_1.default.greaterThanOrEqual(x, min)) {
21
+ x = jsbi_1.default.signedRightShift(x, jsbi_1.default.BigInt(power));
22
+ msb += power;
23
+ }
24
+ }
25
+ return msb;
26
+ }
27
+ exports.mostSignificantBit = mostSignificantBit;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.nearestUsableTick = void 0;
7
+ const tiny_invariant_1 = __importDefault(require("tiny-invariant"));
8
+ const tickMath_1 = require("./tickMath");
9
+ /**
10
+ * Returns the closest tick that is nearest a given tick and usable for the given tick spacing
11
+ * @param tick the target tick
12
+ * @param tickSpacing the spacing of the pool
13
+ */
14
+ function nearestUsableTick(tick, tickSpacing) {
15
+ (0, tiny_invariant_1.default)(Number.isInteger(tick) && Number.isInteger(tickSpacing), "INTEGERS");
16
+ (0, tiny_invariant_1.default)(tickSpacing > 0, "TICK_SPACING");
17
+ (0, tiny_invariant_1.default)(tick >= tickMath_1.TickMath.MIN_TICK && tick <= tickMath_1.TickMath.MAX_TICK, "TICK_BOUND");
18
+ const rounded = Math.round(tick / tickSpacing) * tickSpacing;
19
+ if (rounded < tickMath_1.TickMath.MIN_TICK)
20
+ return rounded + tickSpacing;
21
+ else if (rounded > tickMath_1.TickMath.MAX_TICK)
22
+ return rounded - tickSpacing;
23
+ else
24
+ return rounded;
25
+ }
26
+ exports.nearestUsableTick = nearestUsableTick;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PositionLibrary = void 0;
7
+ const jsbi_1 = __importDefault(require("jsbi"));
8
+ const _1 = require(".");
9
+ const internalConstants_1 = require("../internalConstants");
10
+ class PositionLibrary {
11
+ /**
12
+ * Cannot be constructed.
13
+ */
14
+ constructor() { }
15
+ // replicates the portions of Position#update required to compute unaccounted fees
16
+ static getTokensOwed(feeGrowthInsideALastX64, feeGrowthInsideBLastX64, liquidity, feeGrowthInsideAX64, feeGrowthInsideBX64) {
17
+ const tokensOwed0 = jsbi_1.default.divide(jsbi_1.default.multiply((0, _1.subIn128)(feeGrowthInsideAX64, feeGrowthInsideALastX64), liquidity), internalConstants_1.Q64);
18
+ const tokensOwed1 = jsbi_1.default.divide(jsbi_1.default.multiply((0, _1.subIn128)(feeGrowthInsideBX64, feeGrowthInsideBLastX64), liquidity), internalConstants_1.Q64);
19
+ return [tokensOwed0, tokensOwed1];
20
+ }
21
+ }
22
+ exports.PositionLibrary = PositionLibrary;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.priceToClosestTick = exports.tickToPrice = void 0;
7
+ const price_1 = require("../entities/fractions/price");
8
+ const jsbi_1 = __importDefault(require("jsbi"));
9
+ const internalConstants_1 = require("../internalConstants");
10
+ const encodeSqrtRatioX64_1 = require("./encodeSqrtRatioX64");
11
+ const tickMath_1 = require("./tickMath");
12
+ /**
13
+ * Returns a price object corresponding to the input tick and the base/quote token
14
+ * Inputs must be tokens because the address order is used to interpret the price represented by the tick
15
+ * @param baseToken the base token of the price
16
+ * @param quoteToken the quote token of the price
17
+ * @param tick the tick for which to return the price
18
+ */
19
+ function tickToPrice(baseToken, quoteToken, tick) {
20
+ const sqrtRatioX64 = tickMath_1.TickMath.getSqrtRatioAtTick(tick);
21
+ const ratioX128 = jsbi_1.default.multiply(sqrtRatioX64, sqrtRatioX64);
22
+ return baseToken.sortsBefore(quoteToken)
23
+ ? new price_1.Price(baseToken, quoteToken, internalConstants_1.Q128, ratioX128)
24
+ : new price_1.Price(baseToken, quoteToken, ratioX128, internalConstants_1.Q128);
25
+ }
26
+ exports.tickToPrice = tickToPrice;
27
+ /**
28
+ * Returns the first tick for which the given price is greater than or equal to the tick price
29
+ * @param price for which to return the closest tick that represents a price less than or equal to the input price,
30
+ * i.e. the price of the returned tick is less than or equal to the input price
31
+ */
32
+ function priceToClosestTick(price) {
33
+ const sorted = price.baseCurrency.sortsBefore(price.quoteCurrency);
34
+ const sqrtRatioX64 = sorted
35
+ ? (0, encodeSqrtRatioX64_1.encodeSqrtRatioX64)(price.numerator, price.denominator)
36
+ : (0, encodeSqrtRatioX64_1.encodeSqrtRatioX64)(price.denominator, price.numerator);
37
+ let tick = tickMath_1.TickMath.getTickAtSqrtRatio(sqrtRatioX64);
38
+ const nextTickPrice = tickToPrice(price.baseCurrency, price.quoteCurrency, tick + 1);
39
+ if (sorted) {
40
+ if (!price.lessThan(nextTickPrice)) {
41
+ tick++;
42
+ }
43
+ }
44
+ else {
45
+ if (!price.greaterThan(nextTickPrice)) {
46
+ tick++;
47
+ }
48
+ }
49
+ return tick;
50
+ }
51
+ exports.priceToClosestTick = priceToClosestTick;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.sortedInsert = void 0;
7
+ const tiny_invariant_1 = __importDefault(require("tiny-invariant"));
8
+ // given an array of items sorted by `comparator`, insert an item into its sort index and constrain the size to
9
+ // `maxSize` by removing the last item
10
+ function sortedInsert(items, add, maxSize, comparator) {
11
+ (0, tiny_invariant_1.default)(maxSize > 0, 'MAX_SIZE_ZERO');
12
+ // this is an invariant because the interface cannot return multiple removed items if items.length exceeds maxSize
13
+ (0, tiny_invariant_1.default)(items.length <= maxSize, 'ITEMS_SIZE');
14
+ // short circuit first item add
15
+ if (items.length === 0) {
16
+ items.push(add);
17
+ return null;
18
+ }
19
+ else {
20
+ const isFull = items.length === maxSize;
21
+ // short circuit if full and the additional item does not come before the last item
22
+ if (isFull && comparator(items[items.length - 1], add) <= 0) {
23
+ return add;
24
+ }
25
+ let lo = 0, hi = items.length;
26
+ while (lo < hi) {
27
+ const mid = (lo + hi) >>> 1;
28
+ if (comparator(items[mid], add) <= 0) {
29
+ lo = mid + 1;
30
+ }
31
+ else {
32
+ hi = mid;
33
+ }
34
+ }
35
+ items.splice(lo, 0, add);
36
+ return isFull ? items.pop() : null;
37
+ }
38
+ }
39
+ exports.sortedInsert = sortedInsert;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.sqrt = exports.MAX_SAFE_INTEGER = void 0;
7
+ const jsbi_1 = __importDefault(require("jsbi"));
8
+ const tiny_invariant_1 = __importDefault(require("tiny-invariant"));
9
+ exports.MAX_SAFE_INTEGER = jsbi_1.default.BigInt(Number.MAX_SAFE_INTEGER);
10
+ const ZERO = jsbi_1.default.BigInt(0);
11
+ const ONE = jsbi_1.default.BigInt(1);
12
+ const TWO = jsbi_1.default.BigInt(2);
13
+ /**
14
+ * Computes floor(sqrt(value))
15
+ * @param value the value for which to compute the square root, rounded down
16
+ */
17
+ function sqrt(value) {
18
+ (0, tiny_invariant_1.default)(jsbi_1.default.greaterThanOrEqual(value, ZERO), "NEGATIVE");
19
+ // rely on built in sqrt if possible
20
+ if (jsbi_1.default.lessThan(value, exports.MAX_SAFE_INTEGER)) {
21
+ return jsbi_1.default.BigInt(Math.floor(Math.sqrt(jsbi_1.default.toNumber(value))));
22
+ }
23
+ let z;
24
+ let x;
25
+ z = value;
26
+ x = jsbi_1.default.add(jsbi_1.default.divide(value, TWO), ONE);
27
+ while (jsbi_1.default.lessThan(x, z)) {
28
+ z = x;
29
+ x = jsbi_1.default.divide(jsbi_1.default.add(jsbi_1.default.divide(value, x), x), TWO);
30
+ }
31
+ return z;
32
+ }
33
+ exports.sqrt = sqrt;
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SqrtPriceMath = void 0;
7
+ const jsbi_1 = __importDefault(require("jsbi"));
8
+ const tiny_invariant_1 = __importDefault(require("tiny-invariant"));
9
+ const internalConstants_1 = require("../internalConstants");
10
+ const fullMath_1 = require("./fullMath");
11
+ function multiplyIn128(x, y) {
12
+ const product = jsbi_1.default.multiply(x, y);
13
+ return jsbi_1.default.bitwiseAnd(product, internalConstants_1.MaxUint128);
14
+ }
15
+ function addIn128(x, y) {
16
+ const sum = jsbi_1.default.add(x, y);
17
+ return jsbi_1.default.bitwiseAnd(sum, internalConstants_1.MaxUint128);
18
+ }
19
+ class SqrtPriceMath {
20
+ /**
21
+ * Cannot be constructed.
22
+ */
23
+ constructor() { }
24
+ static getAmountADelta(sqrtRatioLX64, sqrtRatioUX64, liquidity, roundUp) {
25
+ if (jsbi_1.default.greaterThan(sqrtRatioLX64, sqrtRatioUX64)) {
26
+ [sqrtRatioLX64, sqrtRatioUX64] = [sqrtRatioUX64, sqrtRatioLX64];
27
+ }
28
+ const numerator1 = jsbi_1.default.leftShift(liquidity, jsbi_1.default.BigInt(64));
29
+ const numerator2 = jsbi_1.default.subtract(sqrtRatioUX64, sqrtRatioLX64);
30
+ return roundUp
31
+ ? fullMath_1.FullMath.mulDivRoundingUp(fullMath_1.FullMath.mulDivRoundingUp(numerator1, numerator2, sqrtRatioUX64), internalConstants_1.ONE, sqrtRatioLX64)
32
+ : jsbi_1.default.divide(jsbi_1.default.divide(jsbi_1.default.multiply(numerator1, numerator2), sqrtRatioUX64), sqrtRatioLX64);
33
+ }
34
+ static getAmountBDelta(sqrtRatioLX64, sqrtRatioUX64, liquidity, roundUp) {
35
+ if (jsbi_1.default.greaterThan(sqrtRatioLX64, sqrtRatioUX64)) {
36
+ [sqrtRatioLX64, sqrtRatioUX64] = [sqrtRatioUX64, sqrtRatioLX64];
37
+ }
38
+ return roundUp
39
+ ? fullMath_1.FullMath.mulDivRoundingUp(liquidity, jsbi_1.default.subtract(sqrtRatioUX64, sqrtRatioLX64), internalConstants_1.Q64)
40
+ : jsbi_1.default.divide(jsbi_1.default.multiply(liquidity, jsbi_1.default.subtract(sqrtRatioUX64, sqrtRatioLX64)), internalConstants_1.Q64);
41
+ }
42
+ static getNextSqrtPriceFromInput(sqrtPX64, liquidity, amountIn, zeroForOne) {
43
+ (0, tiny_invariant_1.default)(jsbi_1.default.greaterThan(sqrtPX64, internalConstants_1.ZERO));
44
+ (0, tiny_invariant_1.default)(jsbi_1.default.greaterThan(liquidity, internalConstants_1.ZERO));
45
+ return zeroForOne
46
+ ? this.getNextSqrtPriceFromAmountARoundingUp(sqrtPX64, liquidity, amountIn, true)
47
+ : this.getNextSqrtPriceFromAmountBRoundingDown(sqrtPX64, liquidity, amountIn, true);
48
+ }
49
+ static getNextSqrtPriceFromOutput(sqrtPX64, liquidity, amountOut, zeroForOne) {
50
+ (0, tiny_invariant_1.default)(jsbi_1.default.greaterThan(sqrtPX64, internalConstants_1.ZERO));
51
+ (0, tiny_invariant_1.default)(jsbi_1.default.greaterThan(liquidity, internalConstants_1.ZERO));
52
+ return zeroForOne
53
+ ? this.getNextSqrtPriceFromAmountBRoundingDown(sqrtPX64, liquidity, amountOut, false)
54
+ : this.getNextSqrtPriceFromAmountARoundingUp(sqrtPX64, liquidity, amountOut, false);
55
+ }
56
+ static getNextSqrtPriceFromAmountARoundingUp(sqrtPX64, liquidity, amount, add) {
57
+ if (jsbi_1.default.equal(amount, internalConstants_1.ZERO))
58
+ return sqrtPX64;
59
+ const numerator1 = jsbi_1.default.leftShift(liquidity, jsbi_1.default.BigInt(64));
60
+ if (add) {
61
+ let product = multiplyIn128(amount, sqrtPX64);
62
+ if (jsbi_1.default.equal(jsbi_1.default.divide(product, amount), sqrtPX64)) {
63
+ const denominator = addIn128(numerator1, product);
64
+ if (jsbi_1.default.greaterThanOrEqual(denominator, numerator1)) {
65
+ return fullMath_1.FullMath.mulDivRoundingUp(numerator1, sqrtPX64, denominator);
66
+ }
67
+ }
68
+ return fullMath_1.FullMath.mulDivRoundingUp(numerator1, internalConstants_1.ONE, jsbi_1.default.add(jsbi_1.default.divide(numerator1, sqrtPX64), amount));
69
+ }
70
+ else {
71
+ let product = multiplyIn128(amount, sqrtPX64);
72
+ (0, tiny_invariant_1.default)(jsbi_1.default.equal(jsbi_1.default.divide(product, amount), sqrtPX64));
73
+ (0, tiny_invariant_1.default)(jsbi_1.default.greaterThan(numerator1, product));
74
+ const denominator = jsbi_1.default.subtract(numerator1, product);
75
+ return fullMath_1.FullMath.mulDivRoundingUp(numerator1, sqrtPX64, denominator);
76
+ }
77
+ }
78
+ static getNextSqrtPriceFromAmountBRoundingDown(sqrtPX64, liquidity, amount, add) {
79
+ if (add) {
80
+ const quotient = jsbi_1.default.lessThanOrEqual(amount, internalConstants_1.MaxUint128)
81
+ ? jsbi_1.default.divide(jsbi_1.default.leftShift(amount, jsbi_1.default.BigInt(64)), liquidity)
82
+ : jsbi_1.default.divide(jsbi_1.default.multiply(amount, internalConstants_1.Q64), liquidity);
83
+ return jsbi_1.default.add(sqrtPX64, quotient);
84
+ }
85
+ else {
86
+ const quotient = fullMath_1.FullMath.mulDivRoundingUp(amount, internalConstants_1.Q64, liquidity);
87
+ (0, tiny_invariant_1.default)(jsbi_1.default.greaterThan(sqrtPX64, quotient));
88
+ return jsbi_1.default.subtract(sqrtPX64, quotient);
89
+ }
90
+ }
91
+ }
92
+ exports.SqrtPriceMath = SqrtPriceMath;
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SwapMath = void 0;
7
+ const jsbi_1 = __importDefault(require("jsbi"));
8
+ const internalConstants_1 = require("../internalConstants");
9
+ const fullMath_1 = require("./fullMath");
10
+ const sqrtPriceMath_1 = require("./sqrtPriceMath");
11
+ const MAX_FEE = jsbi_1.default.exponentiate(jsbi_1.default.BigInt(10), jsbi_1.default.BigInt(6));
12
+ class SwapMath {
13
+ /**
14
+ * Cannot be constructed.
15
+ */
16
+ constructor() { }
17
+ static computeSwapStep(sqrtRatioCurrentX64, sqrtRatioTargetX64, liquidity, amountRemaining, feePips) {
18
+ const returnValues = {};
19
+ const zeroForOne = jsbi_1.default.greaterThanOrEqual(sqrtRatioCurrentX64, sqrtRatioTargetX64);
20
+ const exactIn = jsbi_1.default.greaterThanOrEqual(amountRemaining, internalConstants_1.ZERO);
21
+ if (exactIn) {
22
+ const amountRemainingLessFee = jsbi_1.default.divide(jsbi_1.default.multiply(amountRemaining, jsbi_1.default.subtract(MAX_FEE, jsbi_1.default.BigInt(feePips))), MAX_FEE);
23
+ returnValues.amountIn = zeroForOne
24
+ ? sqrtPriceMath_1.SqrtPriceMath.getAmountADelta(sqrtRatioTargetX64, sqrtRatioCurrentX64, liquidity, true)
25
+ : sqrtPriceMath_1.SqrtPriceMath.getAmountBDelta(sqrtRatioCurrentX64, sqrtRatioTargetX64, liquidity, true);
26
+ if (jsbi_1.default.greaterThanOrEqual(amountRemainingLessFee, returnValues.amountIn)) {
27
+ returnValues.sqrtRatioNextX64 = sqrtRatioTargetX64;
28
+ }
29
+ else {
30
+ returnValues.sqrtRatioNextX64 = sqrtPriceMath_1.SqrtPriceMath.getNextSqrtPriceFromInput(sqrtRatioCurrentX64, liquidity, amountRemainingLessFee, zeroForOne);
31
+ }
32
+ }
33
+ else {
34
+ returnValues.amountOut = zeroForOne
35
+ ? sqrtPriceMath_1.SqrtPriceMath.getAmountBDelta(sqrtRatioTargetX64, sqrtRatioCurrentX64, liquidity, false)
36
+ : sqrtPriceMath_1.SqrtPriceMath.getAmountADelta(sqrtRatioCurrentX64, sqrtRatioTargetX64, liquidity, false);
37
+ if (jsbi_1.default.greaterThanOrEqual(jsbi_1.default.multiply(amountRemaining, internalConstants_1.NEGATIVE_ONE), returnValues.amountOut)) {
38
+ returnValues.sqrtRatioNextX64 = sqrtRatioTargetX64;
39
+ }
40
+ else {
41
+ returnValues.sqrtRatioNextX64 =
42
+ sqrtPriceMath_1.SqrtPriceMath.getNextSqrtPriceFromOutput(sqrtRatioCurrentX64, liquidity, jsbi_1.default.multiply(amountRemaining, internalConstants_1.NEGATIVE_ONE), zeroForOne);
43
+ }
44
+ }
45
+ const max = jsbi_1.default.equal(sqrtRatioTargetX64, returnValues.sqrtRatioNextX64);
46
+ if (zeroForOne) {
47
+ returnValues.amountIn =
48
+ max && exactIn
49
+ ? returnValues.amountIn
50
+ : sqrtPriceMath_1.SqrtPriceMath.getAmountADelta(returnValues.sqrtRatioNextX64, sqrtRatioCurrentX64, liquidity, true);
51
+ returnValues.amountOut =
52
+ max && !exactIn
53
+ ? returnValues.amountOut
54
+ : sqrtPriceMath_1.SqrtPriceMath.getAmountBDelta(returnValues.sqrtRatioNextX64, sqrtRatioCurrentX64, liquidity, false);
55
+ }
56
+ else {
57
+ returnValues.amountIn =
58
+ max && exactIn
59
+ ? returnValues.amountIn
60
+ : sqrtPriceMath_1.SqrtPriceMath.getAmountBDelta(sqrtRatioCurrentX64, returnValues.sqrtRatioNextX64, liquidity, true);
61
+ returnValues.amountOut =
62
+ max && !exactIn
63
+ ? returnValues.amountOut
64
+ : sqrtPriceMath_1.SqrtPriceMath.getAmountADelta(sqrtRatioCurrentX64, returnValues.sqrtRatioNextX64, liquidity, false);
65
+ }
66
+ if (!exactIn &&
67
+ jsbi_1.default.greaterThan(returnValues.amountOut, jsbi_1.default.multiply(amountRemaining, internalConstants_1.NEGATIVE_ONE))) {
68
+ returnValues.amountOut = jsbi_1.default.multiply(amountRemaining, internalConstants_1.NEGATIVE_ONE);
69
+ }
70
+ if (exactIn &&
71
+ jsbi_1.default.notEqual(returnValues.sqrtRatioNextX64, sqrtRatioTargetX64)) {
72
+ // we didn't reach the target, so take the remainder of the maximum input as fee
73
+ returnValues.feeAmount = jsbi_1.default.subtract(amountRemaining, returnValues.amountIn);
74
+ }
75
+ else {
76
+ returnValues.feeAmount = fullMath_1.FullMath.mulDivRoundingUp(returnValues.amountIn, jsbi_1.default.BigInt(feePips), jsbi_1.default.subtract(MAX_FEE, jsbi_1.default.BigInt(feePips)));
77
+ }
78
+ return [
79
+ returnValues.sqrtRatioNextX64,
80
+ returnValues.amountIn,
81
+ returnValues.amountOut,
82
+ returnValues.feeAmount,
83
+ ];
84
+ }
85
+ }
86
+ exports.SwapMath = SwapMath;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TickLibrary = exports.subIn128 = exports.subIn256 = void 0;
7
+ const jsbi_1 = __importDefault(require("jsbi"));
8
+ const internalConstants_1 = require("../internalConstants");
9
+ function subIn256(x, y) {
10
+ const difference = jsbi_1.default.subtract(x, y);
11
+ if (jsbi_1.default.lessThan(difference, internalConstants_1.ZERO)) {
12
+ return jsbi_1.default.add(internalConstants_1.Q256, difference);
13
+ }
14
+ else {
15
+ return difference;
16
+ }
17
+ }
18
+ exports.subIn256 = subIn256;
19
+ function subIn128(x, y) {
20
+ const difference = jsbi_1.default.subtract(x, y);
21
+ if (jsbi_1.default.lessThan(difference, internalConstants_1.ZERO)) {
22
+ return jsbi_1.default.add(internalConstants_1.Q128, difference);
23
+ }
24
+ else {
25
+ return difference;
26
+ }
27
+ }
28
+ exports.subIn128 = subIn128;
29
+ class TickLibrary {
30
+ /**
31
+ * Cannot be constructed.
32
+ */
33
+ constructor() { }
34
+ static getFeeGrowthInside(feeGrowthOutsideLower, feeGrowthOutsideUpper, tickLower, tickUpper, tickCurrent, feeGrowthGlobalAX64, feeGrowthGlobalBX64) {
35
+ let feeGrowthBelowAX64;
36
+ let feeGrowthBelowBX64;
37
+ if (tickCurrent >= tickLower) {
38
+ feeGrowthBelowAX64 = feeGrowthOutsideLower.feeGrowthOutsideAX64;
39
+ feeGrowthBelowBX64 = feeGrowthOutsideLower.feeGrowthOutsideBX64;
40
+ }
41
+ else {
42
+ feeGrowthBelowAX64 = subIn128(feeGrowthGlobalAX64, feeGrowthOutsideLower.feeGrowthOutsideAX64);
43
+ feeGrowthBelowBX64 = subIn128(feeGrowthGlobalBX64, feeGrowthOutsideLower.feeGrowthOutsideBX64);
44
+ }
45
+ let feeGrowthAboveAX64;
46
+ let feeGrowthAboveBX64;
47
+ if (tickCurrent < tickUpper) {
48
+ feeGrowthAboveAX64 = feeGrowthOutsideUpper.feeGrowthOutsideAX64;
49
+ feeGrowthAboveBX64 = feeGrowthOutsideUpper.feeGrowthOutsideBX64;
50
+ }
51
+ else {
52
+ feeGrowthAboveAX64 = subIn128(feeGrowthGlobalAX64, feeGrowthOutsideUpper.feeGrowthOutsideAX64);
53
+ feeGrowthAboveBX64 = subIn128(feeGrowthGlobalBX64, feeGrowthOutsideUpper.feeGrowthOutsideBX64);
54
+ }
55
+ return [
56
+ subIn128(subIn128(feeGrowthGlobalAX64, feeGrowthBelowAX64), feeGrowthAboveAX64),
57
+ subIn128(subIn128(feeGrowthGlobalBX64, feeGrowthBelowBX64), feeGrowthAboveBX64),
58
+ ];
59
+ }
60
+ }
61
+ exports.TickLibrary = TickLibrary;