@paraswap/dex-lib 2.28.7 → 2.28.9-ramses-v2

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 (149) hide show
  1. package/.idea/aws.xml +17 -0
  2. package/.idea/codeStyles/Project.xml +19 -0
  3. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  4. package/.idea/misc.xml +6 -0
  5. package/.idea/modules.xml +8 -0
  6. package/.idea/paraswap-dex-lib.iml +9 -0
  7. package/.idea/vcs.xml +6 -0
  8. package/build/abi/RamsesV2StateMulticall.abi.json +891 -0
  9. package/build/abi/algebra/AlgebraPool.abi.json +727 -0
  10. package/build/abi/curve-v1/StableSwapFRXETH.json +889 -0
  11. package/build/abi/curve-v1/StableSwapWBETH.json +1223 -0
  12. package/build/abi/wBETH.json +1527 -0
  13. package/build/dex/algebra/algebra-pool.d.ts +46 -0
  14. package/build/dex/algebra/algebra-pool.js +336 -0
  15. package/build/dex/algebra/algebra-pool.js.map +1 -0
  16. package/build/dex/balancer-v2/balancer-v2.js +2 -0
  17. package/build/dex/balancer-v2/balancer-v2.js.map +1 -1
  18. package/build/dex/balancer-v2/optimizer.js +51 -38
  19. package/build/dex/balancer-v2/optimizer.js.map +1 -1
  20. package/build/dex/balancer-v2/types.d.ts +4 -0
  21. package/build/dex/balancer-v2/types.js.map +1 -1
  22. package/build/dex/curve-v1/pools/frxETHpool.d.ts +7 -0
  23. package/build/dex/curve-v1/pools/frxETHpool.js +27 -0
  24. package/build/dex/curve-v1/pools/frxETHpool.js.map +1 -0
  25. package/build/dex/curve-v1/pools/wbETHpool.d.ts +29 -0
  26. package/build/dex/curve-v1/pools/wbETHpool.js +408 -0
  27. package/build/dex/curve-v1/pools/wbETHpool.js.map +1 -0
  28. package/build/dex/curve-v1-factory/price-handlers/functions/calc_token_amount.js +26 -1
  29. package/build/dex/curve-v1-factory/price-handlers/functions/calc_token_amount.js.map +1 -1
  30. package/build/dex/index.js +2 -0
  31. package/build/dex/index.js.map +1 -1
  32. package/build/dex/pancakeswap-v3/types.d.ts +14 -0
  33. package/build/dex/{test-dex → pancakeswap-v3}/types.js.map +1 -1
  34. package/build/dex/{test-dex → ramses-v2}/config.d.ts +1 -1
  35. package/build/dex/ramses-v2/config.js +28 -0
  36. package/build/dex/ramses-v2/config.js.map +1 -0
  37. package/build/dex/ramses-v2/constants.d.ts +28 -0
  38. package/build/dex/ramses-v2/constants.js +35 -0
  39. package/build/dex/ramses-v2/constants.js.map +1 -0
  40. package/build/dex/ramses-v2/contract-math/BitMath.d.ts +4 -0
  41. package/build/dex/ramses-v2/contract-math/BitMath.js +93 -0
  42. package/build/dex/ramses-v2/contract-math/BitMath.js.map +1 -0
  43. package/build/dex/ramses-v2/contract-math/FixedPoint128.d.ts +3 -0
  44. package/build/dex/ramses-v2/contract-math/FixedPoint128.js +8 -0
  45. package/build/dex/ramses-v2/contract-math/FixedPoint128.js.map +1 -0
  46. package/build/dex/ramses-v2/contract-math/FixedPoint96.d.ts +4 -0
  47. package/build/dex/ramses-v2/contract-math/FixedPoint96.js +9 -0
  48. package/build/dex/ramses-v2/contract-math/FixedPoint96.js.map +1 -0
  49. package/build/dex/ramses-v2/contract-math/FullMath.d.ts +4 -0
  50. package/build/dex/ramses-v2/contract-math/FullMath.js +19 -0
  51. package/build/dex/ramses-v2/contract-math/FullMath.js.map +1 -0
  52. package/build/dex/ramses-v2/contract-math/LiquidityMath.d.ts +3 -0
  53. package/build/dex/ramses-v2/contract-math/LiquidityMath.js +22 -0
  54. package/build/dex/ramses-v2/contract-math/LiquidityMath.js.map +1 -0
  55. package/build/dex/ramses-v2/contract-math/Oracle.d.ts +10 -0
  56. package/build/dex/ramses-v2/contract-math/Oracle.js +133 -0
  57. package/build/dex/ramses-v2/contract-math/Oracle.js.map +1 -0
  58. package/build/dex/ramses-v2/contract-math/SqrtPriceMath.d.ts +10 -0
  59. package/build/dex/ramses-v2/contract-math/SqrtPriceMath.js +91 -0
  60. package/build/dex/ramses-v2/contract-math/SqrtPriceMath.js.map +1 -0
  61. package/build/dex/ramses-v2/contract-math/SwapMath.d.ts +8 -0
  62. package/build/dex/ramses-v2/contract-math/SwapMath.js +70 -0
  63. package/build/dex/ramses-v2/contract-math/SwapMath.js.map +1 -0
  64. package/build/dex/ramses-v2/contract-math/Tick.d.ts +7 -0
  65. package/build/dex/ramses-v2/contract-math/Tick.js +45 -0
  66. package/build/dex/ramses-v2/contract-math/Tick.js.map +1 -0
  67. package/build/dex/ramses-v2/contract-math/TickBitMap.d.ts +8 -0
  68. package/build/dex/ramses-v2/contract-math/TickBitMap.js +87 -0
  69. package/build/dex/ramses-v2/contract-math/TickBitMap.js.map +1 -0
  70. package/build/dex/ramses-v2/contract-math/TickMath.d.ts +8 -0
  71. package/build/dex/ramses-v2/contract-math/TickMath.js +162 -0
  72. package/build/dex/ramses-v2/contract-math/TickMath.js.map +1 -0
  73. package/build/dex/ramses-v2/contract-math/UnsafeMath.d.ts +3 -0
  74. package/build/dex/ramses-v2/contract-math/UnsafeMath.js +10 -0
  75. package/build/dex/ramses-v2/contract-math/UnsafeMath.js.map +1 -0
  76. package/build/dex/ramses-v2/contract-math/uniswap-v3-math.d.ts +18 -0
  77. package/build/dex/ramses-v2/contract-math/uniswap-v3-math.js +392 -0
  78. package/build/dex/ramses-v2/contract-math/uniswap-v3-math.js.map +1 -0
  79. package/build/dex/ramses-v2/contract-math/utils.d.ts +3 -0
  80. package/build/dex/ramses-v2/contract-math/utils.js +16 -0
  81. package/build/dex/ramses-v2/contract-math/utils.js.map +1 -0
  82. package/build/dex/ramses-v2/ramses-v2-pool.d.ts +44 -0
  83. package/build/dex/ramses-v2/ramses-v2-pool.js +327 -0
  84. package/build/dex/ramses-v2/ramses-v2-pool.js.map +1 -0
  85. package/build/dex/ramses-v2/ramses-v2.d.ts +61 -0
  86. package/build/dex/ramses-v2/ramses-v2.js +690 -0
  87. package/build/dex/ramses-v2/ramses-v2.js.map +1 -0
  88. package/build/dex/ramses-v2/types.d.ts +154 -0
  89. package/build/dex/ramses-v2/types.js +9 -0
  90. package/build/dex/ramses-v2/types.js.map +1 -0
  91. package/build/dex/ramses-v2/utils.d.ts +6 -0
  92. package/build/dex/ramses-v2/utils.js +71 -0
  93. package/build/dex/ramses-v2/utils.js.map +1 -0
  94. package/build/dex/solidly/forks-override/ramses.d.ts +8 -0
  95. package/build/dex/solidly/forks-override/ramses.js +15 -0
  96. package/build/dex/solidly/forks-override/ramses.js.map +1 -0
  97. package/build/dex/uniswap-v3/uniswap-v3.js +1 -1
  98. package/build/dex/uniswap-v3/uniswap-v3.js.map +1 -1
  99. package/build/lib/multi-wrapper.js +5 -3
  100. package/build/lib/multi-wrapper.js.map +1 -1
  101. package/package.json +1 -1
  102. package/src/abi/RamsesV2Pool.abi.json +1554 -0
  103. package/src/abi/RamsesV2StateMulticall.abi.json +891 -0
  104. package/src/dex/balancer-v2/balancer-v2.ts +2 -0
  105. package/src/dex/balancer-v2/optimizer.ts +62 -49
  106. package/src/dex/balancer-v2/types.ts +4 -0
  107. package/src/dex/curve-v1-factory/price-handlers/functions/calc_token_amount.ts +33 -1
  108. package/src/dex/index.ts +2 -0
  109. package/src/dex/ramses-v2/config.ts +31 -0
  110. package/src/dex/ramses-v2/constants.ts +41 -0
  111. package/src/dex/ramses-v2/contract-math/BitMath.ts +90 -0
  112. package/src/dex/ramses-v2/contract-math/FixedPoint128.ts +3 -0
  113. package/src/dex/ramses-v2/contract-math/FixedPoint96.ts +4 -0
  114. package/src/dex/ramses-v2/contract-math/FullMath.ts +30 -0
  115. package/src/dex/ramses-v2/contract-math/LiquidityMath.ts +17 -0
  116. package/src/dex/ramses-v2/contract-math/Oracle.ts +226 -0
  117. package/src/dex/ramses-v2/contract-math/SqrtPriceMath.ts +226 -0
  118. package/src/dex/ramses-v2/contract-math/SwapMath.ts +139 -0
  119. package/src/dex/ramses-v2/contract-math/Tick.ts +82 -0
  120. package/src/dex/ramses-v2/contract-math/TickBitMap.ts +128 -0
  121. package/src/dex/ramses-v2/contract-math/TickMath.ts +211 -0
  122. package/src/dex/ramses-v2/contract-math/UnsafeMath.ts +5 -0
  123. package/src/dex/ramses-v2/contract-math/uniswap-v3-math.ts +666 -0
  124. package/src/dex/ramses-v2/contract-math/utils.ts +11 -0
  125. package/src/dex/ramses-v2/ramses-v2-e2e.test.ts +100 -0
  126. package/src/dex/ramses-v2/ramses-v2-events.test.ts +182 -0
  127. package/src/dex/ramses-v2/ramses-v2-integration.test.ts +462 -0
  128. package/src/dex/ramses-v2/ramses-v2-pool.ts +546 -0
  129. package/src/dex/ramses-v2/ramses-v2.ts +1136 -0
  130. package/src/dex/ramses-v2/types.ts +177 -0
  131. package/src/dex/ramses-v2/utils.ts +90 -0
  132. package/src/dex/uniswap-v3/uniswap-v3-integration.test.ts +26 -3
  133. package/src/dex/uniswap-v3/uniswap-v3.ts +1 -1
  134. package/src/lib/multi-wrapper.ts +4 -4
  135. package/tests/constants-e2e.ts +1 -5
  136. package/tests/utils-e2e.ts +1 -0
  137. package/build/dex/test-dex/config.js +0 -15
  138. package/build/dex/test-dex/config.js.map +0 -1
  139. package/build/dex/test-dex/test-dex-pool.d.ts +0 -39
  140. package/build/dex/test-dex/test-dex-pool.js +0 -63
  141. package/build/dex/test-dex/test-dex-pool.js.map +0 -1
  142. package/build/dex/test-dex/test-dex.d.ts +0 -37
  143. package/build/dex/test-dex/test-dex.js +0 -126
  144. package/build/dex/test-dex/test-dex.js.map +0 -1
  145. package/build/dex/test-dex/types.d.ts +0 -6
  146. package/build/dex/woo-fi-v2/woo-fi-math.d.ts +0 -16
  147. package/build/dex/woo-fi-v2/woo-fi-math.js +0 -137
  148. package/build/dex/woo-fi-v2/woo-fi-math.js.map +0 -1
  149. /package/build/dex/{test-dex → pancakeswap-v3}/types.js +0 -0
@@ -826,6 +826,8 @@ export class BalancerV2
826
826
  prices: resOut.prices,
827
827
  data: {
828
828
  poolId: pool.id,
829
+ tokenIn: _from.address.toLowerCase(),
830
+ tokenOut: _to.address.toLowerCase(),
829
831
  },
830
832
  poolAddresses: [poolAddress],
831
833
  exchange: this.dexKey,
@@ -1,70 +1,83 @@
1
- import { UnoptimizedRate, OptimalSwapExchange } from '../../types';
2
- import { BalancerSwapV2 } from './types';
1
+ import _ from 'lodash';
2
+ import { UnoptimizedRate } from '../../types';
3
3
  import { SwapSide } from '../../constants';
4
4
  import { BalancerConfig } from './config';
5
-
6
- const MAX_UINT256 =
7
- '115792089237316195423570985008687907853269984665640564039457584007913129639935';
8
-
9
- const AllBalancerV2Forks = Object.keys(BalancerConfig);
5
+ import { OptimalSwap } from '@paraswap/core';
10
6
 
11
7
  export function balancerV2Merge(or: UnoptimizedRate): UnoptimizedRate {
12
- const fixSwap = (
13
- rawSwap: OptimalSwapExchange<any>[],
14
- side: SwapSide,
15
- ): OptimalSwapExchange<any>[] => {
16
- const newBalancers: { [key: string]: OptimalSwapExchange<any> } = {};
17
- let optimizedSwap = new Array<OptimalSwapExchange<any>>();
18
- rawSwap.forEach((s: OptimalSwapExchange<any>) => {
19
- const exchangeKey = s.exchange.toLowerCase();
20
- if (AllBalancerV2Forks.some(d => d.toLowerCase() === exchangeKey)) {
21
- if (!(exchangeKey in newBalancers)) {
22
- newBalancers[exchangeKey] = {
23
- exchange: s.exchange,
24
- srcAmount: '0',
25
- destAmount: '0',
26
- percent: 0,
27
- poolAddresses: [],
28
- data: {
29
- swaps: new Array<BalancerSwapV2>(),
30
- gasUSD: '0',
31
- },
32
- };
33
- }
34
- newBalancers[exchangeKey].srcAmount = (
35
- BigInt(newBalancers[exchangeKey].srcAmount) + BigInt(s.srcAmount)
8
+ const balancerForksList = Object.keys(BalancerConfig).map(b =>
9
+ b.toLowerCase(),
10
+ );
11
+ const fixSwap = (rawRate: OptimalSwap[], side: SwapSide): OptimalSwap[] => {
12
+ let lastExchange: false | OptimalSwap = false;
13
+ let optimizedRate = new Array<OptimalSwap>();
14
+ rawRate.forEach((s: OptimalSwap) => {
15
+ if (
16
+ s.swapExchanges.length !== 1 ||
17
+ !balancerForksList.includes(s.swapExchanges[0].exchange.toLowerCase())
18
+ ) {
19
+ lastExchange = false;
20
+ optimizedRate.push(s);
21
+ } else if (
22
+ lastExchange &&
23
+ lastExchange.swapExchanges[0].exchange.toLowerCase() ===
24
+ s.swapExchanges[0].exchange.toLowerCase() &&
25
+ _.last(
26
+ <any[]>lastExchange.swapExchanges[0].data.swaps,
27
+ )!.tokenOut.toLowerCase() ===
28
+ s.swapExchanges[0].data.tokenIn.toLowerCase()
29
+ ) {
30
+ const [lastExchangeSwap] = lastExchange.swapExchanges;
31
+ const [currentSwap] = s.swapExchanges;
32
+ lastExchangeSwap.srcAmount = (
33
+ BigInt(lastExchangeSwap.srcAmount) + BigInt(currentSwap.srcAmount)
36
34
  ).toString();
37
35
 
38
- newBalancers[exchangeKey].destAmount = (
39
- BigInt(newBalancers[exchangeKey].destAmount) + BigInt(s.destAmount)
36
+ lastExchangeSwap.destAmount = (
37
+ BigInt(lastExchangeSwap.destAmount) + BigInt(currentSwap.destAmount)
40
38
  ).toString();
41
39
 
42
- newBalancers[exchangeKey].percent += s.percent;
43
- newBalancers[exchangeKey].data.exchangeProxy = s.data.exchangeProxy;
44
- newBalancers[exchangeKey].data.gasUSD = (
45
- parseFloat(newBalancers[exchangeKey].data.gasUSD) +
46
- parseFloat(s.data.gasUSD)
40
+ lastExchangeSwap.percent += currentSwap.percent;
41
+ lastExchangeSwap.data.gasUSD = (
42
+ parseFloat(lastExchangeSwap.data.gasUSD) +
43
+ parseFloat(currentSwap.data.gasUSD)
47
44
  ).toFixed(6);
48
45
 
49
- newBalancers[exchangeKey].data.swaps.push({
50
- poolId: s.data.poolId,
51
- amount: side === SwapSide.SELL ? s.srcAmount : s.destAmount,
46
+ lastExchangeSwap.data.swaps.push({
47
+ poolId: currentSwap.data.poolId,
48
+ amount:
49
+ side === SwapSide.SELL
50
+ ? currentSwap.srcAmount
51
+ : currentSwap.destAmount,
52
+ tokenIn: currentSwap.data.tokenIn,
53
+ tokenOut: currentSwap.data.tokenOut,
52
54
  });
53
- newBalancers[exchangeKey].poolAddresses!.push(s.poolAddresses![0]);
55
+ lastExchangeSwap.poolAddresses!.push(currentSwap.poolAddresses![0]);
54
56
  } else {
55
- optimizedSwap.push(s);
57
+ lastExchange = _.cloneDeep(s);
58
+ lastExchange.swapExchanges[0].data = {};
59
+ lastExchange.swapExchanges[0].data.gasUSD =
60
+ s.swapExchanges[0].data.gasUSD;
61
+ lastExchange.swapExchanges[0].data.swaps = [
62
+ {
63
+ poolId: s.swapExchanges[0].data.poolId,
64
+ amount:
65
+ side === SwapSide.SELL
66
+ ? s.swapExchanges[0].srcAmount
67
+ : s.swapExchanges[0].destAmount,
68
+ tokenIn: s.swapExchanges[0].data.tokenIn,
69
+ tokenOut: s.swapExchanges[0].data.tokenOut,
70
+ },
71
+ ];
72
+ optimizedRate.push(lastExchange);
56
73
  }
57
74
  });
58
- optimizedSwap = optimizedSwap.concat(Object.values(newBalancers));
59
- return optimizedSwap;
75
+ return optimizedRate;
60
76
  };
61
77
 
62
78
  or.bestRoute = or.bestRoute.map(r => ({
63
79
  ...r,
64
- swaps: r.swaps.map(s => ({
65
- ...s,
66
- swapExchanges: fixSwap(s.swapExchanges, or.side),
67
- })),
80
+ swaps: fixSwap(r.swaps, or.side),
68
81
  }));
69
82
  return or;
70
83
  }
@@ -82,6 +82,8 @@ export interface SubgraphPoolBase {
82
82
  export type BalancerSwapV2 = {
83
83
  poolId: string;
84
84
  amount: string;
85
+ tokenIn: string;
86
+ tokenOut: string;
85
87
  };
86
88
 
87
89
  export type OptimizedBalancerV2Data = {
@@ -139,6 +141,8 @@ export type BalancerV2DirectParam = [
139
141
 
140
142
  export type BalancerV2Data = {
141
143
  poolId: string;
144
+ tokenIn: string;
145
+ tokenOut: string;
142
146
  };
143
147
 
144
148
  export type DexParams = {
@@ -35,6 +35,38 @@ const customPlain3CoinThree: calc_token_amount = (
35
35
  return (diff * token_amount) / D0;
36
36
  };
37
37
 
38
+ const factoryPlain2Basic: calc_token_amount = (
39
+ self: IPoolContext,
40
+ state: PoolState,
41
+ amounts: bigint[],
42
+ is_deposit: boolean,
43
+ ) => {
44
+ const { N_COINS } = self.constants;
45
+ const amp = state.A;
46
+ const balances = [...state.balances];
47
+ const D0 = self.get_D(self, balances, amp);
48
+ for (const i of _.range(N_COINS)) {
49
+ if (is_deposit) balances[i] += amounts[i];
50
+ else balances[i] -= amounts[i];
51
+ }
52
+ const D1 = self.get_D(self, balances, amp);
53
+
54
+ if (state.totalSupply === undefined) {
55
+ throw new Error(
56
+ `${self.IMPLEMENTATION_NAME} customPlain3CoinThree: totalSupply is not provided`,
57
+ );
58
+ }
59
+
60
+ const token_amount = state.totalSupply;
61
+ let diff = 0n;
62
+ if (is_deposit) {
63
+ diff = D1 - D0;
64
+ } else {
65
+ diff = D0 - D1;
66
+ }
67
+ return (diff * token_amount) / D0;
68
+ };
69
+
38
70
  const customAvalanche3CoinLending: calc_token_amount = (
39
71
  self: IPoolContext,
40
72
  state: PoolState,
@@ -114,7 +146,7 @@ const implementations: Record<ImplementationNames, calc_token_amount> = {
114
146
  [ImplementationNames.FACTORY_META_USD_BALANCES_FRAX_USDC]: notImplemented,
115
147
 
116
148
  [ImplementationNames.FACTORY_PLAIN_2_BALANCES]: notImplemented,
117
- [ImplementationNames.FACTORY_PLAIN_2_BASIC]: notImplemented,
149
+ [ImplementationNames.FACTORY_PLAIN_2_BASIC]: factoryPlain2Basic,
118
150
  [ImplementationNames.FACTORY_PLAIN_2_ETH]: notImplemented,
119
151
  [ImplementationNames.FACTORY_PLAIN_2_OPTIMIZED]: notImplemented,
120
152
 
package/src/dex/index.ts CHANGED
@@ -69,6 +69,7 @@ import { SwaapV2 } from './swaap-v2/swaap-v2';
69
69
  import { SpiritSwapV3 } from './quickswap/spiritswap-v3';
70
70
  import { TraderJoeV21 } from './trader-joe-v2.1';
71
71
  import { PancakeswapV3 } from './pancakeswap-v3/pancakeswap-v3';
72
+ import { RamsesV2 } from './ramses-v2/ramses-v2';
72
73
  import { Algebra } from './algebra/algebra';
73
74
 
74
75
  const LegacyDexes = [
@@ -137,6 +138,7 @@ const Dexes = [
137
138
  MaverickV1,
138
139
  Camelot,
139
140
  SwaapV2,
141
+ RamsesV2,
140
142
  ];
141
143
 
142
144
  export type LegacyDexConstructor = new (dexHelper: IDexHelper) => IDexTxBuilder<
@@ -0,0 +1,31 @@
1
+ import { DexParams } from './types';
2
+ import { DexConfigMap, AdapterMappings } from '../../types';
3
+ import { Network, SwapSide } from '../../constants';
4
+
5
+ const RAMSES_SUPPORTED_FEES = [10000n, 2500n, 500n, 100n];
6
+
7
+ export const RamsesV2Config: DexConfigMap<DexParams> = {
8
+ RamsesV2: {
9
+ [Network.ARBITRUM]: {
10
+ factory: '0xAA2cd7477c451E703f3B9Ba5663334914763edF8',
11
+ deployer: '0xb3e423ab9cE6C03D98326A3A2a0D7D96b0829f22',
12
+ quoter: '0xAA20EFF7ad2F523590dE6c04918DaAE0904E3b20',
13
+ router: '0xAA23611badAFB62D37E7295A682D21960ac85A90',
14
+ supportedFees: RAMSES_SUPPORTED_FEES,
15
+ stateMulticall: '0x50EE4112Cab9c79812F23bE079aB3911395ACc8e',
16
+ uniswapMulticall: '0x1F98415757620B543A52E61c46B32eB19261F984',
17
+ chunksCount: 10,
18
+ initHash:
19
+ '0x1565b129f2d1790f12d45301b9b084335626f0c92410bc43130763b69971135d',
20
+ subgraphURL:
21
+ 'https://api.thegraph.com/subgraphs/name/ramsesexchange/concentrated-liquidity-graph',
22
+ },
23
+ },
24
+ };
25
+
26
+ export const Adapters: Record<number, AdapterMappings> = {
27
+ [Network.ARBITRUM]: {
28
+ [SwapSide.SELL]: [{ name: 'ArbitrumAdapter01', index: 3 }],
29
+ [SwapSide.BUY]: [{ name: 'ArbitrumBuyAdapter', index: 2 }],
30
+ },
31
+ };
@@ -0,0 +1,41 @@
1
+ export const UNISWAPV3_TICK_GAS_COST = 24_000; // Ceiled
2
+ export const UNISWAPV3_TICK_BASE_OVERHEAD = 75_000;
3
+ export const UNISWAPV3_POOL_SEARCH_OVERHEAD = 10_000;
4
+
5
+ // This is used for price calculation. If out of scope, return 0n
6
+ export const TICK_BITMAP_TO_USE = 4n;
7
+
8
+ // This is used to check if the state is still valid.
9
+ export const TICK_BITMAP_BUFFER = 8n;
10
+
11
+ export const MAX_PRICING_COMPUTATION_STEPS_ALLOWED = 128;
12
+
13
+ export const UNISWAPV3_SUBGRAPH_URL =
14
+ 'https://api.thegraph.com/subgraphs/name/ramsesexchange/concentrated-liquidity-graph';
15
+
16
+ export const UNISWAPV3_EFFICIENCY_FACTOR = 3;
17
+
18
+ export const ZERO_TICK_INFO = {
19
+ liquidityGross: 0n,
20
+ liquidityNet: 0n,
21
+ tickCumulativeOutside: 0n,
22
+ secondsPerLiquidityOutsideX128: 0n,
23
+ secondsOutside: 0n,
24
+ initialized: false,
25
+ };
26
+
27
+ export const ZERO_ORACLE_OBSERVATION = {
28
+ blockTimestamp: 0n,
29
+ tickCumulative: 0n,
30
+ secondsPerLiquidityCumulativeX128: 0n,
31
+ initialized: false,
32
+ };
33
+
34
+ export const OUT_OF_RANGE_ERROR_POSTFIX = `INVALID_TICK_BIT_MAP_RANGES`;
35
+
36
+ export const DEFAULT_POOL_INIT_CODE_HASH = `0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54`;
37
+
38
+ export enum DirectMethods {
39
+ directSell = 'directUniV3Swap',
40
+ directBuy = 'directUniV3Buy',
41
+ }
@@ -0,0 +1,90 @@
1
+ import {
2
+ BI_MAX_UINT128,
3
+ BI_MAX_UINT16,
4
+ BI_MAX_UINT32,
5
+ BI_MAX_UINT64,
6
+ BI_MAX_UINT8,
7
+ } from '../../../bigint-constants';
8
+ import { _require } from '../../../utils';
9
+
10
+ export class BitMath {
11
+ static mostSignificantBit(x: bigint): bigint {
12
+ _require(x > 0, '', { x }, 'x > 0');
13
+ let r = 0n;
14
+
15
+ if (x >= 0x100000000000000000000000000000000n) {
16
+ x >>= 128n;
17
+ r += 128n;
18
+ }
19
+ if (x >= 0x10000000000000000n) {
20
+ x >>= 64n;
21
+ r += 64n;
22
+ }
23
+ if (x >= 0x100000000n) {
24
+ x >>= 32n;
25
+ r += 32n;
26
+ }
27
+ if (x >= 0x10000n) {
28
+ x >>= 16n;
29
+ r += 16n;
30
+ }
31
+ if (x >= 0x100n) {
32
+ x >>= 8n;
33
+ r += 8n;
34
+ }
35
+ if (x >= 0x10n) {
36
+ x >>= 4n;
37
+ r += 4n;
38
+ }
39
+ if (x >= 0x4n) {
40
+ x >>= 2n;
41
+ r += 2n;
42
+ }
43
+ if (x >= 0x2n) r += 1n;
44
+
45
+ return r;
46
+ }
47
+
48
+ static leastSignificantBit(x: bigint): bigint {
49
+ _require(x > 0, '', { x }, 'x > 0');
50
+
51
+ let r = 255n;
52
+ if ((x & BI_MAX_UINT128) > 0n) {
53
+ r -= 128n;
54
+ } else {
55
+ x >>= 128n;
56
+ }
57
+ if ((x & BI_MAX_UINT64) > 0n) {
58
+ r -= 64n;
59
+ } else {
60
+ x >>= 64n;
61
+ }
62
+ if ((x & BI_MAX_UINT32) > 0n) {
63
+ r -= 32n;
64
+ } else {
65
+ x >>= 32n;
66
+ }
67
+ if ((x & BI_MAX_UINT16) > 0n) {
68
+ r -= 16n;
69
+ } else {
70
+ x >>= 16n;
71
+ }
72
+ if ((x & BI_MAX_UINT8) > 0n) {
73
+ r -= 8n;
74
+ } else {
75
+ x >>= 8n;
76
+ }
77
+ if ((x & 0xfn) > 0n) {
78
+ r -= 4n;
79
+ } else {
80
+ x >>= 4n;
81
+ }
82
+ if ((x & 0x3n) > 0n) {
83
+ r -= 2n;
84
+ } else {
85
+ x >>= 2n;
86
+ }
87
+ if ((x & 0x1n) > 0n) r -= 1n;
88
+ return r;
89
+ }
90
+ }
@@ -0,0 +1,3 @@
1
+ export class FixedPoint128 {
2
+ static readonly Q128 = 0x100000000000000000000000000000000n;
3
+ }
@@ -0,0 +1,4 @@
1
+ export class FixedPoint96 {
2
+ static readonly RESOLUTION = 96n;
3
+ static readonly Q96 = 0x1000000000000000000000000n;
4
+ }
@@ -0,0 +1,30 @@
1
+ import { BI_MAX_UINT256 } from '../../../bigint-constants';
2
+ import { _require } from '../../../utils';
3
+
4
+ export class FullMath {
5
+ static mulDiv(a: bigint, b: bigint, denominator: bigint) {
6
+ const result = (a * b) / denominator;
7
+
8
+ _require(
9
+ result <= BI_MAX_UINT256,
10
+ '',
11
+ { result, BI_MAX_UINT: BI_MAX_UINT256 },
12
+ 'result <= BI_MAX_UINT',
13
+ );
14
+
15
+ return result;
16
+ }
17
+
18
+ static mulDivRoundingUp(a: bigint, b: bigint, denominator: bigint) {
19
+ const result = (a * b + denominator - 1n) / denominator;
20
+
21
+ _require(
22
+ result <= BI_MAX_UINT256,
23
+ '',
24
+ { result, BI_MAX_UINT: BI_MAX_UINT256 },
25
+ 'result <= BI_MAX_UINT',
26
+ );
27
+
28
+ return result;
29
+ }
30
+ }
@@ -0,0 +1,17 @@
1
+ import { _require } from '../../../utils';
2
+
3
+ export class LiquidityMath {
4
+ static addDelta(x: bigint, y: bigint): bigint {
5
+ let z;
6
+ if (y < 0) {
7
+ const _y = BigInt.asUintN(128, -y);
8
+ z = x - _y;
9
+ _require(z < x, 'LS', { z, x, y, _y }, 'z < x');
10
+ } else {
11
+ const _y = BigInt.asUintN(128, y);
12
+ z = x + _y;
13
+ _require(z >= x, 'LA', { z, x, y, _y }, 'z >= x');
14
+ }
15
+ return z;
16
+ }
17
+ }
@@ -0,0 +1,226 @@
1
+ import {
2
+ OracleObservation,
3
+ OracleObservationCandidates,
4
+ PoolState,
5
+ } from '../types';
6
+ import { _require } from '../../../utils';
7
+ import { DeepReadonly } from 'ts-essentials';
8
+ import { ZERO_ORACLE_OBSERVATION } from '../constants';
9
+
10
+ function replaceUndefinedObservationWithZero(state: PoolState, index: number) {
11
+ if (state.observations[index] === undefined) {
12
+ state.observations[index] = { ...ZERO_ORACLE_OBSERVATION };
13
+ }
14
+ }
15
+
16
+ export class Oracle {
17
+ static transform(
18
+ state: DeepReadonly<PoolState>,
19
+ last: OracleObservation,
20
+ blockTimestamp: bigint,
21
+ tick: bigint,
22
+ liquidity: bigint,
23
+ ): OracleObservation {
24
+ const delta = blockTimestamp - last.blockTimestamp;
25
+ return {
26
+ blockTimestamp: state.blockTimestamp,
27
+ tickCumulative: last.tickCumulative + BigInt.asIntN(56, tick) * delta,
28
+ secondsPerLiquidityCumulativeX128:
29
+ last.secondsPerLiquidityCumulativeX128 +
30
+ (BigInt.asUintN(160, delta) << 128n) /
31
+ (liquidity > 0n ? liquidity : 1n),
32
+ initialized: true,
33
+ };
34
+ }
35
+
36
+ static write(
37
+ state: PoolState,
38
+ index: number,
39
+ blockTimestamp: bigint,
40
+ tick: bigint,
41
+ liquidity: bigint,
42
+ cardinality: number,
43
+ cardinalityNext: number,
44
+ ): [number, number] {
45
+ const last = state.observations[index];
46
+
47
+ if (last.blockTimestamp == state.blockTimestamp)
48
+ return [index, cardinality];
49
+
50
+ let indexUpdated = 0;
51
+ let cardinalityUpdated = 0;
52
+
53
+ if (cardinalityNext > cardinality && index == cardinality - 1) {
54
+ cardinalityUpdated = cardinalityNext;
55
+ } else {
56
+ cardinalityUpdated = cardinality;
57
+ }
58
+
59
+ indexUpdated = (index + 1) % cardinalityUpdated;
60
+
61
+ state.observations[indexUpdated] = Oracle.transform(
62
+ state,
63
+ last,
64
+ blockTimestamp,
65
+ tick,
66
+ liquidity,
67
+ );
68
+ if (indexUpdated !== index) {
69
+ delete state.observations[index];
70
+ }
71
+ return [indexUpdated, cardinalityUpdated];
72
+ }
73
+
74
+ static lte(time: bigint, a: bigint, b: bigint): boolean {
75
+ if (a <= time && b <= time) return a <= b;
76
+
77
+ const aAdjusted = a > time ? a : a + 2n ** 32n;
78
+ const bAdjusted = b > time ? b : b + 2n ** 32n;
79
+ return aAdjusted <= bAdjusted;
80
+ }
81
+
82
+ static binarySearch(
83
+ state: DeepReadonly<PoolState>,
84
+ time: bigint,
85
+ target: bigint,
86
+ index: number,
87
+ cardinality: number,
88
+ ): OracleObservationCandidates {
89
+ let l = (index + 1) % cardinality;
90
+ let r = l + cardinality - 1;
91
+ let i;
92
+
93
+ let beforeOrAt;
94
+ let atOrAfter;
95
+ while (true) {
96
+ i = (l + r) / 2;
97
+
98
+ beforeOrAt = state.observations[i % cardinality];
99
+
100
+ // we've landed on an uninitialized tick, keep searching higher (more recently)
101
+ if (!beforeOrAt.initialized) {
102
+ l = i + 1;
103
+ continue;
104
+ }
105
+
106
+ atOrAfter = state.observations[(i + 1) % cardinality];
107
+
108
+ const targetAtOrAfter = Oracle.lte(
109
+ time,
110
+ beforeOrAt.blockTimestamp,
111
+ target,
112
+ );
113
+
114
+ // check if we've found the answer!
115
+ if (targetAtOrAfter && Oracle.lte(time, target, atOrAfter.blockTimestamp))
116
+ break;
117
+
118
+ if (!targetAtOrAfter) r = i - 1;
119
+ else l = i + 1;
120
+ }
121
+ return { beforeOrAt, atOrAfter };
122
+ }
123
+
124
+ static getSurroundingObservations(
125
+ state: DeepReadonly<PoolState>,
126
+ time: bigint,
127
+ target: bigint,
128
+ tick: bigint,
129
+ index: number,
130
+ liquidity: bigint,
131
+ cardinality: number,
132
+ ): OracleObservationCandidates {
133
+ let beforeOrAt = state.observations[index];
134
+
135
+ if (Oracle.lte(time, beforeOrAt.blockTimestamp, target)) {
136
+ if (beforeOrAt.blockTimestamp === target) {
137
+ return { beforeOrAt, atOrAfter: beforeOrAt };
138
+ } else {
139
+ return {
140
+ beforeOrAt,
141
+ atOrAfter: Oracle.transform(
142
+ state,
143
+ beforeOrAt,
144
+ target,
145
+ tick,
146
+ liquidity,
147
+ ),
148
+ };
149
+ }
150
+ }
151
+
152
+ beforeOrAt = state.observations[(index + 1) % cardinality];
153
+ if (!beforeOrAt.initialized) beforeOrAt = state.observations[0];
154
+
155
+ _require(
156
+ Oracle.lte(time, beforeOrAt.blockTimestamp, target),
157
+ 'OLD',
158
+ { time, beforeOrAtBlockTimestamp: beforeOrAt.blockTimestamp, target },
159
+ 'Oracle.lte(time, beforeOrAt.blockTimestamp, target)',
160
+ );
161
+
162
+ return Oracle.binarySearch(state, time, target, index, cardinality);
163
+ }
164
+
165
+ static observeSingle(
166
+ state: DeepReadonly<PoolState>,
167
+ time: bigint,
168
+ secondsAgo: bigint,
169
+ tick: bigint,
170
+ index: number,
171
+ liquidity: bigint,
172
+ cardinality: number,
173
+ ): [bigint, bigint] {
174
+ if (secondsAgo == 0n) {
175
+ let last = state.observations[index];
176
+ if (last.blockTimestamp != time)
177
+ last = Oracle.transform(state, last, time, tick, liquidity);
178
+ return [last.tickCumulative, last.secondsPerLiquidityCumulativeX128];
179
+ }
180
+
181
+ const target = time - secondsAgo;
182
+
183
+ const { beforeOrAt, atOrAfter } = Oracle.getSurroundingObservations(
184
+ state,
185
+ time,
186
+ target,
187
+ tick,
188
+ index,
189
+ liquidity,
190
+ cardinality,
191
+ );
192
+
193
+ if (target === beforeOrAt.blockTimestamp) {
194
+ return [
195
+ beforeOrAt.tickCumulative,
196
+ beforeOrAt.secondsPerLiquidityCumulativeX128,
197
+ ];
198
+ } else if (target === atOrAfter.blockTimestamp) {
199
+ return [
200
+ atOrAfter.tickCumulative,
201
+ atOrAfter.secondsPerLiquidityCumulativeX128,
202
+ ];
203
+ } else {
204
+ const observationTimeDelta =
205
+ atOrAfter.blockTimestamp - beforeOrAt.blockTimestamp;
206
+ const targetDelta = target - beforeOrAt.blockTimestamp;
207
+ return [
208
+ beforeOrAt.tickCumulative +
209
+ ((atOrAfter.tickCumulative - beforeOrAt.tickCumulative) /
210
+ observationTimeDelta) *
211
+ targetDelta,
212
+ beforeOrAt.secondsPerLiquidityCumulativeX128 +
213
+ BigInt.asUintN(
214
+ 160,
215
+ (BigInt.asUintN(
216
+ 256,
217
+ atOrAfter.secondsPerLiquidityCumulativeX128 -
218
+ beforeOrAt.secondsPerLiquidityCumulativeX128,
219
+ ) *
220
+ targetDelta) /
221
+ observationTimeDelta,
222
+ ),
223
+ ];
224
+ }
225
+ }
226
+ }