@marko00/routing-finder-mare 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 (173) hide show
  1. package/.idea/copilot.data.migration.agent.xml +6 -0
  2. package/.idea/copilot.data.migration.ask.xml +6 -0
  3. package/.idea/copilot.data.migration.ask2agent.xml +6 -0
  4. package/.idea/copilot.data.migration.edit.xml +6 -0
  5. package/.idea/modules.xml +8 -0
  6. package/.idea/php.xml +19 -0
  7. package/.idea/ratex-sdk.iml +8 -0
  8. package/.idea/vcs.xml +6 -0
  9. package/LICENSE-MIT +21 -0
  10. package/README.md +209 -0
  11. package/contracts/abi/BalancerHelperAbi.ts +1 -0
  12. package/contracts/abi/CamelotHelperAbi.ts +1 -0
  13. package/contracts/abi/RateXAbi.ts +482 -0
  14. package/contracts/abi/SushiSwapHelperAbi.ts +1 -0
  15. package/contracts/abi/UniswapHelperAbi.ts +1 -0
  16. package/contracts/abi/UniswapV2HelperAbi.ts +1 -0
  17. package/contracts/addresses-arbitrum.ts +8 -0
  18. package/contracts/addresses-mainnet.ts +7 -0
  19. package/contracts/addresses-polkadot.ts +9 -0
  20. package/contracts/addresses-sei.ts +9 -0
  21. package/contracts/rateX/BalancerHelper.ts +13 -0
  22. package/contracts/rateX/CamelotHelper.ts +13 -0
  23. package/contracts/rateX/SushiSwapHelper.ts +13 -0
  24. package/contracts/rateX/UniswapHelper.ts +19 -0
  25. package/contracts/rateX/UniswapV2Helper.ts +19 -0
  26. package/dexes/dexIdsList.ts +9 -0
  27. package/dexes/graph_queries/BalancerV2.ts +150 -0
  28. package/dexes/graph_queries/CamelotV2.ts +202 -0
  29. package/dexes/graph_queries/SushiSwapV2.ts +283 -0
  30. package/dexes/graph_queries/UniswapV2.ts +252 -0
  31. package/dexes/graph_queries/UniswapV3.ts +229 -0
  32. package/dexes/graph_queries/graphQueryFilters.ts +41 -0
  33. package/dexes/graph_queries/x_template.ts +67 -0
  34. package/dexes/pools/Balancer/BalancerState.ts +34 -0
  35. package/dexes/pools/Balancer/BalancerWeightedPool.ts +96 -0
  36. package/dexes/pools/Camelot.ts +164 -0
  37. package/dexes/pools/SushiSwapV2.ts +35 -0
  38. package/dexes/pools/UniswapV2.ts +36 -0
  39. package/dexes/pools/uniswap/UniswapV3.ts +40 -0
  40. package/dexes/pools/uniswap/testUniswapOffchainQuoter.ts +169 -0
  41. package/dexes/pools/uniswap/types.ts +174 -0
  42. package/dexes/pools/uniswap/uniswapOffchainQuoter.ts +173 -0
  43. package/dexes/pools/uniswap/uniswapState.ts +56 -0
  44. package/dexes/pools/uniswap/utils.ts +71 -0
  45. package/dist/contracts/abi/BalancerHelperAbi.d.ts +25 -0
  46. package/dist/contracts/abi/BalancerHelperAbi.js +4 -0
  47. package/dist/contracts/abi/CamelotHelperAbi.d.ts +45 -0
  48. package/dist/contracts/abi/CamelotHelperAbi.js +4 -0
  49. package/dist/contracts/abi/RateXAbi.d.ts +71 -0
  50. package/dist/contracts/abi/RateXAbi.js +485 -0
  51. package/dist/contracts/abi/SushiSwapHelperAbi.d.ts +45 -0
  52. package/dist/contracts/abi/SushiSwapHelperAbi.js +4 -0
  53. package/dist/contracts/abi/UniswapHelperAbi.d.ts +39 -0
  54. package/dist/contracts/abi/UniswapHelperAbi.js +4 -0
  55. package/dist/contracts/abi/UniswapV2HelperAbi.d.ts +45 -0
  56. package/dist/contracts/abi/UniswapV2HelperAbi.js +4 -0
  57. package/dist/contracts/addresses-arbitrum.d.ts +6 -0
  58. package/dist/contracts/addresses-arbitrum.js +10 -0
  59. package/dist/contracts/addresses-mainnet.d.ts +6 -0
  60. package/dist/contracts/addresses-mainnet.js +10 -0
  61. package/dist/contracts/addresses-polkadot.d.ts +6 -0
  62. package/dist/contracts/addresses-polkadot.js +10 -0
  63. package/dist/contracts/addresses-sei.d.ts +6 -0
  64. package/dist/contracts/addresses-sei.js +10 -0
  65. package/dist/contracts/rateX/BalancerHelper.d.ts +26 -0
  66. package/dist/contracts/rateX/BalancerHelper.js +14 -0
  67. package/dist/contracts/rateX/CamelotHelper.d.ts +46 -0
  68. package/dist/contracts/rateX/CamelotHelper.js +14 -0
  69. package/dist/contracts/rateX/SushiSwapHelper.d.ts +46 -0
  70. package/dist/contracts/rateX/SushiSwapHelper.js +14 -0
  71. package/dist/contracts/rateX/UniswapHelper.d.ts +40 -0
  72. package/dist/contracts/rateX/UniswapHelper.js +22 -0
  73. package/dist/contracts/rateX/UniswapV2Helper.d.ts +46 -0
  74. package/dist/contracts/rateX/UniswapV2Helper.js +22 -0
  75. package/dist/dexes/dexIdsList.d.ts +9 -0
  76. package/dist/dexes/dexIdsList.js +12 -0
  77. package/dist/dexes/graph_queries/BalancerV2.d.ts +14 -0
  78. package/dist/dexes/graph_queries/BalancerV2.js +141 -0
  79. package/dist/dexes/graph_queries/CamelotV2.d.ts +14 -0
  80. package/dist/dexes/graph_queries/CamelotV2.js +183 -0
  81. package/dist/dexes/graph_queries/SushiSwapV2.d.ts +14 -0
  82. package/dist/dexes/graph_queries/SushiSwapV2.js +263 -0
  83. package/dist/dexes/graph_queries/UniswapV2.d.ts +14 -0
  84. package/dist/dexes/graph_queries/UniswapV2.js +217 -0
  85. package/dist/dexes/graph_queries/UniswapV3.d.ts +14 -0
  86. package/dist/dexes/graph_queries/UniswapV3.js +198 -0
  87. package/dist/dexes/graph_queries/graphQueryFilters.d.ts +19 -0
  88. package/dist/dexes/graph_queries/graphQueryFilters.js +40 -0
  89. package/dist/dexes/graph_queries/x_template.d.ts +12 -0
  90. package/dist/dexes/graph_queries/x_template.js +57 -0
  91. package/dist/dexes/pools/Balancer/BalancerState.d.ts +6 -0
  92. package/dist/dexes/pools/Balancer/BalancerState.js +32 -0
  93. package/dist/dexes/pools/Balancer/BalancerWeightedPool.d.ts +12 -0
  94. package/dist/dexes/pools/Balancer/BalancerWeightedPool.js +109 -0
  95. package/dist/dexes/pools/Camelot.d.ts +12 -0
  96. package/dist/dexes/pools/Camelot.js +135 -0
  97. package/dist/dexes/pools/SushiSwapV2.d.ts +9 -0
  98. package/dist/dexes/pools/SushiSwapV2.js +34 -0
  99. package/dist/dexes/pools/UniswapV2.d.ts +9 -0
  100. package/dist/dexes/pools/UniswapV2.js +34 -0
  101. package/dist/dexes/pools/uniswap/UniswapV3.d.ts +7 -0
  102. package/dist/dexes/pools/uniswap/UniswapV3.js +36 -0
  103. package/dist/dexes/pools/uniswap/types.d.ts +76 -0
  104. package/dist/dexes/pools/uniswap/types.js +111 -0
  105. package/dist/dexes/pools/uniswap/uniswapOffchainQuoter.d.ts +13 -0
  106. package/dist/dexes/pools/uniswap/uniswapOffchainQuoter.js +121 -0
  107. package/dist/dexes/pools/uniswap/uniswapState.d.ts +14 -0
  108. package/dist/dexes/pools/uniswap/uniswapState.js +51 -0
  109. package/dist/dexes/pools/uniswap/utils.d.ts +3 -0
  110. package/dist/dexes/pools/uniswap/utils.js +41 -0
  111. package/dist/index.d.ts +26 -0
  112. package/dist/index.js +41 -0
  113. package/dist/routes.d.ts +1 -0
  114. package/dist/routes.js +20 -0
  115. package/dist/routing/iterative_spliting/main.d.ts +3 -0
  116. package/dist/routing/iterative_spliting/main.js +104 -0
  117. package/dist/routing/iterative_spliting/multiHopSwap.d.ts +4 -0
  118. package/dist/routing/iterative_spliting/multiHopSwap.js +83 -0
  119. package/dist/routing/main.d.ts +2 -0
  120. package/dist/routing/main.js +22 -0
  121. package/dist/routing/uni_like_algo/algo_config.d.ts +2 -0
  122. package/dist/routing/uni_like_algo/algo_config.js +8 -0
  123. package/dist/routing/uni_like_algo/amount_distribution.d.ts +2 -0
  124. package/dist/routing/uni_like_algo/amount_distribution.js +17 -0
  125. package/dist/routing/uni_like_algo/compute_routes_backtrack.d.ts +3 -0
  126. package/dist/routing/uni_like_algo/compute_routes_backtrack.js +44 -0
  127. package/dist/routing/uni_like_algo/main.d.ts +2 -0
  128. package/dist/routing/uni_like_algo/main.js +49 -0
  129. package/dist/routing/uni_like_algo/routes_quoter.d.ts +21 -0
  130. package/dist/routing/uni_like_algo/routes_quoter.js +53 -0
  131. package/dist/routing/uni_like_algo/swap_finder.d.ts +25 -0
  132. package/dist/routing/uni_like_algo/swap_finder.js +154 -0
  133. package/dist/routing/uni_like_algo/types.d.ts +40 -0
  134. package/dist/routing/uni_like_algo/types.js +12 -0
  135. package/dist/swap/graph_communication.d.ts +5 -0
  136. package/dist/swap/graph_communication.js +187 -0
  137. package/dist/swap/my_local_storage.d.ts +8 -0
  138. package/dist/swap/my_local_storage.js +16 -0
  139. package/dist/utils/addresses.d.ts +24 -0
  140. package/dist/utils/addresses.js +60 -0
  141. package/dist/utils/math/fixed-points.d.ts +14 -0
  142. package/dist/utils/math/fixed-points.js +123 -0
  143. package/dist/utils/math/log-exp.d.ts +5 -0
  144. package/dist/utils/math/log-exp.js +385 -0
  145. package/dist/utils/math/math.d.ts +12 -0
  146. package/dist/utils/math/math.js +50 -0
  147. package/dist/utils/types/types.d.ts +51 -0
  148. package/dist/utils/types/types.js +25 -0
  149. package/dist/utils/utils.d.ts +20 -0
  150. package/dist/utils/utils.js +72 -0
  151. package/images/decenter_logo.png +0 -0
  152. package/index.ts +50 -0
  153. package/package.json +39 -0
  154. package/routes.ts +27 -0
  155. package/routing/iterative_spliting/main.ts +131 -0
  156. package/routing/iterative_spliting/multiHopSwap.ts +98 -0
  157. package/routing/main.ts +22 -0
  158. package/routing/uni_like_algo/algo_config.ts +7 -0
  159. package/routing/uni_like_algo/amount_distribution.ts +16 -0
  160. package/routing/uni_like_algo/compute_routes_backtrack.ts +81 -0
  161. package/routing/uni_like_algo/main.ts +65 -0
  162. package/routing/uni_like_algo/routes_quoter.ts +63 -0
  163. package/routing/uni_like_algo/swap_finder.ts +185 -0
  164. package/routing/uni_like_algo/types.ts +54 -0
  165. package/swap/graph_communication.ts +212 -0
  166. package/swap/my_local_storage.ts +27 -0
  167. package/tsconfig.json +26 -0
  168. package/utils/addresses.ts +64 -0
  169. package/utils/math/fixed-points.ts +88 -0
  170. package/utils/math/log-exp.ts +469 -0
  171. package/utils/math/math.ts +46 -0
  172. package/utils/types/types.ts +100 -0
  173. package/utils/utils.ts +125 -0
@@ -0,0 +1,174 @@
1
+ export class PoolInfo {
2
+ pool: string;
3
+ token0: string;
4
+ token1: string;
5
+ tick: bigint;
6
+ tickLiquidityNet: bigint;
7
+ tickSpacing: bigint;
8
+ fee: bigint;
9
+ sqrtPriceX96: bigint;
10
+ liquidity: bigint;
11
+
12
+ constructor(pool: string, token0: string, token1: string, tick: bigint, tickLiquidityNet: bigint, tickSpacing: bigint, fee: bigint, sqrtPriceX96: bigint, liquidity: bigint) {
13
+ this.pool = pool;
14
+ this.token0 = token0;
15
+ this.token1 = token1;
16
+ this.tick = tick;
17
+ this.tickLiquidityNet = tickLiquidityNet
18
+ this.tickSpacing = tickSpacing;
19
+ this.fee = fee;
20
+ this.sqrtPriceX96 = sqrtPriceX96;
21
+ this.liquidity = liquidity;
22
+ }
23
+ }
24
+
25
+ export class TickData {
26
+ tick: bigint;
27
+ initialized: boolean;
28
+ liquidityNet: bigint;
29
+
30
+ clone() {
31
+ return new TickData(this.tick, this.initialized, this.liquidityNet);
32
+ }
33
+
34
+ constructor(tick: bigint, initialized: boolean, liquidityNet: bigint) {
35
+ this.tick = tick;
36
+ this.initialized = initialized;
37
+ this.liquidityNet = liquidityNet;
38
+ }
39
+ }
40
+
41
+ export class PoolData {
42
+ info: PoolInfo;
43
+ zeroForOneTicks: TickData[];
44
+ oneForZeroTicks: TickData[];
45
+
46
+ constructor(info: PoolInfo, zeroForOneTicks: TickData[], oneForZeroTicks: TickData[]) {
47
+ this.info = info;
48
+ this.zeroForOneTicks = zeroForOneTicks;
49
+ this.oneForZeroTicks = oneForZeroTicks;
50
+ }
51
+ }
52
+
53
+ export type SwapState = {
54
+ amountSpecifiedRemaining: bigint,
55
+ amountCalculated: bigint,
56
+ sqrtPriceX96: bigint,
57
+ tick: bigint,
58
+ liquidity: bigint
59
+ }
60
+
61
+ export type StepComputations = {
62
+ sqrtPriceStartX96: bigint,
63
+ tickNext: bigint,
64
+ initialized: boolean,
65
+ sqrtPriceNextX96: bigint,
66
+ amountIn: bigint,
67
+ amountOut: bigint,
68
+ feeAmount: bigint
69
+ }
70
+
71
+
72
+ // helper used for test
73
+ export class TradeInfo {
74
+ pool: string;
75
+ tokenIn: string;
76
+ tokenOut: string;
77
+ amountIn: bigint;
78
+ fee: bigint;
79
+
80
+ constructor(pool: string, tokenIn: string, tokenOut: string, amountIn: bigint, fee: bigint) {
81
+ this.pool = pool;
82
+ this.tokenIn = tokenIn;
83
+ this.tokenOut = tokenOut;
84
+ this.amountIn = amountIn;
85
+ this.fee = fee;
86
+ }
87
+ }
88
+
89
+ export class AdaptedPoolData {
90
+ pool: string;
91
+ token0: string;
92
+ token1: string;
93
+ tickSpacing: bigint;
94
+ fee: bigint;
95
+ currentLiquidity: bigint;
96
+ currentSqrtPriceX96: bigint;
97
+ ticks: TickData[];
98
+
99
+ currentTickIndex: number; // currenTick info is at ticks[currentTickIndex]
100
+
101
+ clone() {
102
+ const newData = new AdaptedPoolData(null);
103
+ newData.pool = this.pool;
104
+ newData.token0 = this.token0;
105
+ newData.token1 = this.token1;
106
+ newData.tickSpacing = this.tickSpacing;
107
+ newData.fee = this.fee;
108
+ newData.currentLiquidity = this.currentLiquidity;
109
+ newData.currentSqrtPriceX96 = this.currentSqrtPriceX96;
110
+ newData.ticks = this.ticks.map(e => e.clone());
111
+ newData.currentTickIndex = this.currentTickIndex;
112
+ return newData;
113
+ }
114
+
115
+ constructor(poolData: PoolData | null) {
116
+ if (!poolData) {
117
+ this.pool = '';
118
+ this.token0 = '';
119
+ this.token1 = '';
120
+ this.tickSpacing = BigInt(0);
121
+ this.fee = BigInt(0);
122
+ this.currentLiquidity = BigInt(0);
123
+ this.currentSqrtPriceX96 = BigInt(0);
124
+ this.ticks = []
125
+ this.currentTickIndex = 0
126
+ return;
127
+ }
128
+ this.pool = poolData.info.pool;
129
+ this.token0 = poolData.info.token0;
130
+ this.token1 = poolData.info.token1;
131
+ this.tickSpacing = poolData.info.tickSpacing;
132
+ this.fee = poolData.info.fee;
133
+ this.currentLiquidity = poolData.info.liquidity;
134
+ this.currentSqrtPriceX96 = poolData.info.sqrtPriceX96;
135
+
136
+ const currentTickData = new TickData(poolData.info.tick, true, poolData.info.tickLiquidityNet);
137
+ this.ticks = poolData.zeroForOneTicks.reverse().concat(currentTickData).concat(poolData.oneForZeroTicks);
138
+ this.currentTickIndex = poolData.zeroForOneTicks.length;
139
+ }
140
+
141
+ public getCurrTickData(): TickData {
142
+ return this.ticks[this.currentTickIndex];
143
+ }
144
+ }
145
+
146
+ export class LastQuote {
147
+ newLiquidity: bigint;
148
+ newSqrtPriceX96: bigint;
149
+ newTickIndex: number; // index in array of ticks
150
+
151
+ clone() {
152
+ return new LastQuote(this.newLiquidity, this.newSqrtPriceX96, this.newTickIndex)
153
+ }
154
+
155
+ constructor(newLiquidity: bigint, newSqrtPriceX96: bigint, newTickIndex: number) {
156
+ this.newLiquidity = newLiquidity;
157
+ this.newSqrtPriceX96 = newSqrtPriceX96;
158
+ this.newTickIndex = newTickIndex;
159
+ }
160
+ }
161
+
162
+ export class PoolState {
163
+ data: AdaptedPoolData;
164
+ lastQuote: LastQuote;
165
+
166
+ clone() {
167
+ return new PoolState(this.data.clone(), this.lastQuote.clone())
168
+ }
169
+
170
+ constructor(currData: AdaptedPoolData, lastQuote: LastQuote) {
171
+ this.data = currData;
172
+ this.lastQuote = lastQuote;
173
+ }
174
+ }
@@ -0,0 +1,173 @@
1
+ import { FeeAmount, LiquidityMath, SwapMath, TickMath } from "@uniswap/v3-sdk";
2
+ import JSBI from "jsbi";
3
+ import { LastQuote, PoolState, StepComputations, SwapState, TickData } from "./types";
4
+
5
+ export class UniswapOffchainQuoter {
6
+
7
+ public quote(
8
+ poolState: PoolState,
9
+ tokenIn: string,
10
+ tokenOut: string,
11
+ amountIn: bigint
12
+ ): [bigint, bigint] {
13
+
14
+ if (amountIn <= BigInt(0)) {
15
+ return [BigInt(0), BigInt(0)];
16
+ }
17
+
18
+ try {
19
+ const zeroForOne: boolean = tokenIn < tokenOut;
20
+ const sqrtPriceLimitX96 = this.getSqrtPriceLimitX96(zeroForOne);
21
+
22
+ let state: SwapState = this.initSwapState(poolState, amountIn);
23
+
24
+ let tickDataIndex = zeroForOne
25
+ ? poolState.data.currentTickIndex - 1
26
+ : poolState.data.currentTickIndex + 1;
27
+
28
+ while (
29
+ state.amountSpecifiedRemaining !== BigInt(0) &&
30
+ state.sqrtPriceX96 !== sqrtPriceLimitX96 &&
31
+ tickDataIndex >= 0 &&
32
+ tickDataIndex < poolState.data.ticks.length
33
+ ) {
34
+ const tickData = poolState.data.ticks[tickDataIndex];
35
+
36
+ let step: StepComputations = this.initStepComputations(state, tickData);
37
+
38
+ this.updateSwapIteration(state, step, tickData, poolState.data.fee, sqrtPriceLimitX96, zeroForOne);
39
+
40
+ tickDataIndex = zeroForOne ? tickDataIndex - 1 : tickDataIndex + 1;
41
+ }
42
+
43
+ // remember where we left off, so we can update pool later
44
+ poolState.lastQuote = new LastQuote(state.liquidity, state.sqrtPriceX96, zeroForOne ? tickDataIndex + 2 : tickDataIndex - 2)
45
+
46
+ const amountOut = state.amountCalculated > BigInt(0) ? state.amountCalculated : -state.amountCalculated;
47
+ return [amountOut, state.amountSpecifiedRemaining];
48
+ } catch (e) {
49
+ return [BigInt(0), BigInt(0)];
50
+ }
51
+ }
52
+
53
+ private initSwapState(poolState: PoolState, amountIn: bigint): SwapState {
54
+ return {
55
+ amountSpecifiedRemaining: amountIn,
56
+ amountCalculated: BigInt(0),
57
+ sqrtPriceX96: poolState.data.currentSqrtPriceX96,
58
+ tick: poolState.data.getCurrTickData().tick,
59
+ liquidity: poolState.data.currentLiquidity
60
+ };
61
+ }
62
+
63
+ private initStepComputations(state: SwapState, tickData: TickData): StepComputations {
64
+ return {
65
+ sqrtPriceStartX96: state.sqrtPriceX96,
66
+ tickNext: tickData.tick,
67
+ initialized: tickData.initialized,
68
+ sqrtPriceNextX96: BigInt(TickMath.getSqrtRatioAtTick(Number(tickData.tick)).toString()),
69
+ amountIn: BigInt(0),
70
+ amountOut: BigInt(0),
71
+ feeAmount: BigInt(0)
72
+ };
73
+ }
74
+
75
+ private convertToFeeAmount(fee: bigint): FeeAmount {
76
+ switch (fee.toString()) {
77
+ case "100":
78
+ return FeeAmount.LOWEST;
79
+ case "500":
80
+ return FeeAmount.LOW;
81
+ case "3000":
82
+ return FeeAmount.MEDIUM;
83
+ case "10000":
84
+ return FeeAmount.HIGH;
85
+ default:
86
+ throw new Error("Invalid fee amount");
87
+ }
88
+ }
89
+
90
+ private updateSwapIteration(
91
+ state: SwapState,
92
+ step: StepComputations,
93
+ tickData: TickData,
94
+ fee: bigint,
95
+ sqrtPriceLimitX96: bigint,
96
+ zeroForOne: boolean
97
+ ) {
98
+ this.updateSwapStep(state, step, fee, sqrtPriceLimitX96, zeroForOne);
99
+ this.calculateAmount(state, step);
100
+ this.updateTickWithLiquidity(state, step, tickData, zeroForOne);
101
+ }
102
+
103
+ private updateSwapStep(
104
+ state: SwapState,
105
+ step: StepComputations,
106
+ fee: bigint,
107
+ sqrtPriceLimitX96: bigint,
108
+ zeroForOne: boolean
109
+ ) {
110
+ const [sqrtPriceX96, amountIn, amountOut, feeAmount] =
111
+ SwapMath.computeSwapStep(
112
+ JSBI.BigInt(state.sqrtPriceX96.toString()),
113
+ this.calculateRatioTargetX96(zeroForOne, step.sqrtPriceNextX96, sqrtPriceLimitX96),
114
+ JSBI.BigInt(state.liquidity.toString()),
115
+ JSBI.BigInt(state.amountSpecifiedRemaining.toString()),
116
+ this.convertToFeeAmount(fee)
117
+ );
118
+
119
+ state.sqrtPriceX96 = BigInt(sqrtPriceX96.toString());
120
+ step.amountIn = BigInt(amountIn.toString());
121
+ step.amountOut = BigInt(amountOut.toString());
122
+ step.feeAmount = BigInt(feeAmount.toString());
123
+ }
124
+
125
+ private calculateAmount(state: SwapState, step: StepComputations) {
126
+ state.amountSpecifiedRemaining -= (step.amountIn + step.feeAmount);
127
+ state.amountCalculated -= step.amountOut;
128
+ }
129
+
130
+ private updateTickWithLiquidity(
131
+ state: SwapState,
132
+ step: StepComputations,
133
+ tickData: TickData,
134
+ zeroForOne: boolean
135
+ ) {
136
+ if (state.sqrtPriceX96 === step.sqrtPriceNextX96) {
137
+ // if the tick is initialized, run the tick transition
138
+ if (step.initialized) {
139
+ let liquidityNet = tickData.liquidityNet;
140
+ // if we're moving leftward, we interpret liquidityNet as the opposite sign
141
+ if (zeroForOne) {
142
+ liquidityNet = -liquidityNet;
143
+ }
144
+ const finalLiquidity = LiquidityMath.addDelta(
145
+ JSBI.BigInt(state.liquidity.toString()),
146
+ JSBI.BigInt(liquidityNet.toString())
147
+ );
148
+ state.liquidity = BigInt(finalLiquidity.toString());
149
+ }
150
+ state.tick = zeroForOne ? step.tickNext - BigInt(1) : step.tickNext;
151
+ } else if (state.sqrtPriceX96 !== step.sqrtPriceStartX96) {
152
+ // recompute unless we're on a lower tick boundary (i.e. already transitioned ticks), and haven't moved
153
+ const tick = TickMath.getTickAtSqrtRatio(JSBI.BigInt(state.sqrtPriceX96.toString()));
154
+ state.tick = BigInt(tick.toString());
155
+ }
156
+ }
157
+
158
+ private calculateRatioTargetX96(
159
+ zeroForOne: boolean,
160
+ sqrtPriceNextX96: bigint,
161
+ sqrtPriceLimitX96: bigint
162
+ ): JSBI {
163
+ return (zeroForOne ? sqrtPriceNextX96 < sqrtPriceLimitX96 : sqrtPriceNextX96 > sqrtPriceLimitX96)
164
+ ? JSBI.BigInt(sqrtPriceLimitX96.toString())
165
+ : JSBI.BigInt(sqrtPriceNextX96.toString());
166
+ }
167
+
168
+ private getSqrtPriceLimitX96(zeroForOne: boolean): bigint {
169
+ return zeroForOne ?
170
+ BigInt(JSBI.add(TickMath.MIN_SQRT_RATIO, JSBI.BigInt("1")).toString()) :
171
+ BigInt(JSBI.subtract(TickMath.MAX_SQRT_RATIO, JSBI.BigInt("1")).toString());
172
+ }
173
+ }
@@ -0,0 +1,56 @@
1
+ import { PoolData, PoolState } from './types'
2
+ import { convertInitialPoolDataToPoolState, convertRowPoolData } from './utils'
3
+ import { UniswapOffchainQuoter } from './uniswapOffchainQuoter'
4
+ import { CreateUniswapHelperContract } from '../../../contracts/rateX/UniswapHelper'
5
+ import Web3 from 'web3'
6
+
7
+ export class UniswapState {
8
+ private static poolStateMap: Map<string, PoolState> = new Map<string, PoolState>()
9
+ private static startingPoolStateMap: Map<string, PoolState> = new Map<string, PoolState>()
10
+ public static quoter: UniswapOffchainQuoter = new UniswapOffchainQuoter()
11
+ private static batch_size = 3
12
+
13
+ private constructor() { }
14
+
15
+ public static getPoolState(poolAddress: string): PoolState | undefined {
16
+ return this.poolStateMap.get(poolAddress.toLowerCase())
17
+ }
18
+ public static resetPoolState(poolAddress: string): void {
19
+ const poolState = this.startingPoolStateMap.get(poolAddress.toLowerCase())
20
+ if (poolState) {
21
+ this.poolStateMap.set(poolAddress.toLowerCase(), poolState.clone())
22
+ }
23
+ }
24
+
25
+ private static async getPoolsDataFromContract(pools: string[], chainId: number, rpcProvider: Web3): Promise<PoolData[]> {
26
+ //@ts-ignore
27
+ try {
28
+ const UniswapHelperContract = CreateUniswapHelperContract(chainId, rpcProvider)
29
+ const rawPoolsData: any[] = await UniswapHelperContract.methods.fetchData(pools, 15).call()
30
+ return rawPoolsData.map((rawPoolData: any) => convertRowPoolData(rawPoolData))
31
+ } catch (err) {
32
+ console.log('Error while fetching additional data from the smart contracts: ', err)
33
+ throw err
34
+ }
35
+ }
36
+
37
+ public static async initializeFreshPoolsData(pools: string[], chainId: number, rpcProvider: Web3) {
38
+ const poolsSize = pools.length
39
+ const numberOfBatches = Math.ceil(poolsSize / this.batch_size)
40
+
41
+ const promises: Promise<PoolData[]>[] = []
42
+
43
+ for (let i = 0; i < numberOfBatches; i++) {
44
+ const batch = pools.slice(i * this.batch_size, (i + 1) * this.batch_size)
45
+ promises.push(this.getPoolsDataFromContract(batch, chainId, rpcProvider))
46
+ }
47
+ const allPoolsData = await Promise.all(promises)
48
+
49
+ allPoolsData.flat().forEach((poolData: PoolData) => {
50
+ let poolState = convertInitialPoolDataToPoolState(poolData)
51
+ // we will store keys as lowercase addresses
52
+ this.poolStateMap.set(poolData.info.pool.toLowerCase(), poolState)
53
+ this.startingPoolStateMap.set(poolData.info.pool.toLowerCase(), poolState.clone())
54
+ })
55
+ }
56
+ }
@@ -0,0 +1,71 @@
1
+ import {AdaptedPoolData, LastQuote, PoolData, PoolInfo, PoolState, TickData} from "./types";
2
+
3
+ export function convertRowPoolData(poolData: any): PoolData {
4
+
5
+ const getPoolInfo = (poolInfoRaw: any): PoolInfo => {
6
+ const pool: string = poolInfoRaw[0];
7
+ const token0: string = poolInfoRaw[1];
8
+ const token1: string = poolInfoRaw[2];
9
+ const tick: bigint = poolInfoRaw[3];
10
+ const tickLiquidityNet: bigint = poolInfoRaw[4];
11
+ const tickSpacing: bigint = poolInfoRaw[5];
12
+ const fee: bigint = poolInfoRaw[6];
13
+ const sqrtPriceX96: bigint = poolInfoRaw[7];
14
+ const liquidity: bigint = poolInfoRaw[8];
15
+
16
+ return new PoolInfo(
17
+ pool,
18
+ token0,
19
+ token1,
20
+ tick,
21
+ tickLiquidityNet,
22
+ tickSpacing,
23
+ fee,
24
+ sqrtPriceX96,
25
+ liquidity
26
+ );
27
+ }
28
+
29
+ const getTickData = (tickDataRaw: any): TickData => {
30
+ const tick: bigint = tickDataRaw[0];
31
+ const initialized: boolean = tickDataRaw[1];
32
+ const liquidityNet: bigint = tickDataRaw[2];
33
+
34
+ return new TickData(
35
+ tick,
36
+ initialized,
37
+ liquidityNet
38
+ );
39
+ }
40
+
41
+ const zeroForOneTicksRaw = poolData[1];
42
+ const zeroForOneTicks: TickData[] = [];
43
+ for (let i = 0; i < zeroForOneTicksRaw.length; i++) {
44
+ zeroForOneTicks.push(getTickData(zeroForOneTicksRaw[i]));
45
+ }
46
+
47
+ const oneForZeroTicksRaw = poolData[2];
48
+ const oneForZeroTicks: TickData[] = [];
49
+ for (let i = 0; i < oneForZeroTicksRaw.length; i++) {
50
+ oneForZeroTicks.push(getTickData(oneForZeroTicksRaw[i]));
51
+ }
52
+
53
+ return new PoolData(
54
+ getPoolInfo(poolData[0]),
55
+ zeroForOneTicks,
56
+ oneForZeroTicks
57
+ );
58
+ }
59
+
60
+ export function convertInitialPoolDataToPoolState(poolData: PoolData): PoolState {
61
+ const adaptedPoolData = new AdaptedPoolData(poolData);
62
+ const lastQuote = new LastQuote(
63
+ adaptedPoolData.currentLiquidity,
64
+ adaptedPoolData.currentSqrtPriceX96,
65
+ adaptedPoolData.currentTickIndex
66
+ );
67
+
68
+ return new PoolState(adaptedPoolData, lastQuote);
69
+ }
70
+
71
+
@@ -0,0 +1,25 @@
1
+ export declare const BalancerHelperAbi: ({
2
+ inputs: {
3
+ internalType: string;
4
+ name: string;
5
+ type: string;
6
+ }[];
7
+ stateMutability: string;
8
+ type: string;
9
+ name?: undefined;
10
+ outputs?: undefined;
11
+ } | {
12
+ inputs: {
13
+ internalType: string;
14
+ name: string;
15
+ type: string;
16
+ }[];
17
+ name: string;
18
+ outputs: {
19
+ internalType: string;
20
+ name: string;
21
+ type: string;
22
+ }[];
23
+ stateMutability: string;
24
+ type: string;
25
+ })[];
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BalancerHelperAbi = void 0;
4
+ exports.BalancerHelperAbi = [{ "inputs": [{ "internalType": "address", "name": "_balancerVault", "type": "address" }], "stateMutability": "nonpayable", "type": "constructor" }, { "inputs": [{ "internalType": "bytes32", "name": "_poolId", "type": "bytes32" }], "name": "getWeightedPoolInfo", "outputs": [{ "internalType": "uint8", "name": "decimals", "type": "uint8" }, { "internalType": "address[]", "name": "tokens", "type": "address[]" }, { "internalType": "uint256[]", "name": "balances", "type": "uint256[]" }, { "internalType": "uint256[]", "name": "weights", "type": "uint256[]" }, { "internalType": "uint256", "name": "feePercentage", "type": "uint256" }], "stateMutability": "view", "type": "function" }];
@@ -0,0 +1,45 @@
1
+ export declare const CamelotHelperAbi: {
2
+ inputs: {
3
+ components: ({
4
+ internalType: string;
5
+ name: string;
6
+ type: string;
7
+ components?: undefined;
8
+ } | {
9
+ components: {
10
+ internalType: string;
11
+ name: string;
12
+ type: string;
13
+ }[];
14
+ internalType: string;
15
+ name: string;
16
+ type: string;
17
+ })[];
18
+ internalType: string;
19
+ name: string;
20
+ type: string;
21
+ }[];
22
+ name: string;
23
+ outputs: {
24
+ components: ({
25
+ internalType: string;
26
+ name: string;
27
+ type: string;
28
+ components?: undefined;
29
+ } | {
30
+ components: {
31
+ internalType: string;
32
+ name: string;
33
+ type: string;
34
+ }[];
35
+ internalType: string;
36
+ name: string;
37
+ type: string;
38
+ })[];
39
+ internalType: string;
40
+ name: string;
41
+ type: string;
42
+ }[];
43
+ stateMutability: string;
44
+ type: string;
45
+ }[];
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CamelotHelperAbi = void 0;
4
+ exports.CamelotHelperAbi = [{ "inputs": [{ "components": [{ "internalType": "address", "name": "poolId", "type": "address" }, { "internalType": "string", "name": "dexId", "type": "string" }, { "components": [{ "internalType": "address", "name": "_address", "type": "address" }, { "internalType": "uint256", "name": "decimals", "type": "uint256" }], "internalType": "struct IHelperState.Token[]", "name": "tokens", "type": "tuple[]" }], "internalType": "struct IHelperState.PoolInfo[]", "name": "poolsInfo", "type": "tuple[]" }], "name": "getPoolsData", "outputs": [{ "components": [{ "internalType": "address", "name": "poolId", "type": "address" }, { "internalType": "string", "name": "dexId", "type": "string" }, { "components": [{ "internalType": "address", "name": "_address", "type": "address" }, { "internalType": "uint256", "name": "decimals", "type": "uint256" }], "internalType": "struct IHelperState.Token[]", "name": "tokens", "type": "tuple[]" }, { "internalType": "uint112[2]", "name": "reserves", "type": "uint112[2]" }, { "internalType": "uint16[2]", "name": "fees", "type": "uint16[2]" }, { "internalType": "bool", "name": "stableSwap", "type": "bool" }], "internalType": "struct CamelotHelper.CamelotPool[]", "name": "pools", "type": "tuple[]" }], "stateMutability": "view", "type": "function" }];
@@ -0,0 +1,71 @@
1
+ export declare const RateXAbi: ({
2
+ inputs: {
3
+ components: {
4
+ internalType: string;
5
+ name: string;
6
+ type: string;
7
+ }[];
8
+ internalType: string;
9
+ name: string;
10
+ type: string;
11
+ }[];
12
+ stateMutability: string;
13
+ type: string;
14
+ name?: undefined;
15
+ anonymous?: undefined;
16
+ outputs?: undefined;
17
+ } | {
18
+ inputs: never[];
19
+ name: string;
20
+ type: string;
21
+ stateMutability?: undefined;
22
+ anonymous?: undefined;
23
+ outputs?: undefined;
24
+ } | {
25
+ anonymous: boolean;
26
+ inputs: {
27
+ indexed: boolean;
28
+ internalType: string;
29
+ name: string;
30
+ type: string;
31
+ }[];
32
+ name: string;
33
+ type: string;
34
+ stateMutability?: undefined;
35
+ outputs?: undefined;
36
+ } | {
37
+ inputs: ({
38
+ components: ({
39
+ components: {
40
+ internalType: string;
41
+ name: string;
42
+ type: string;
43
+ }[];
44
+ internalType: string;
45
+ name: string;
46
+ type: string;
47
+ } | {
48
+ internalType: string;
49
+ name: string;
50
+ type: string;
51
+ components?: undefined;
52
+ })[];
53
+ internalType: string;
54
+ name: string;
55
+ type: string;
56
+ } | {
57
+ internalType: string;
58
+ name: string;
59
+ type: string;
60
+ components?: undefined;
61
+ })[];
62
+ name: string;
63
+ outputs: {
64
+ internalType: string;
65
+ name: string;
66
+ type: string;
67
+ }[];
68
+ stateMutability: string;
69
+ type: string;
70
+ anonymous?: undefined;
71
+ })[];