@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,198 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const graphql_1 = require("graphql");
4
+ const graphql_request_1 = require("graphql-request");
5
+ const dexIdsList_1 = require("../dexIdsList");
6
+ const uniswapState_1 = require("../pools/uniswap/uniswapState");
7
+ const UniswapV3_1 = require("../pools/uniswap/UniswapV3");
8
+ const graphQueryFilters_1 = require("./graphQueryFilters");
9
+ class UniswapV3 {
10
+ constructor() {
11
+ this.endpoint = ``;
12
+ this.chainId = 1;
13
+ this.dexId = dexIdsList_1.dexIds.UNI_V3;
14
+ this.myLocalStorage = null;
15
+ }
16
+ static initialize(myLocalStorage) {
17
+ const object = new UniswapV3();
18
+ object.myLocalStorage = myLocalStorage;
19
+ return object;
20
+ }
21
+ setEndpoint(chainId, graphApiKey) {
22
+ if (chainId == 1329) {
23
+ this.endpoint = 'https://indexer.us.hyperindex.xyz/32230f9/converter';
24
+ }
25
+ if (chainId == 1) {
26
+ this.endpoint = `https://gateway-arbitrum.network.thegraph.com/api/${graphApiKey}/subgraphs/id/5zvR82QoaXYFyDEKLZ9t6v9adgnptxYpKpSbxtgVENFV`;
27
+ }
28
+ if (chainId == 42161) {
29
+ this.endpoint = `https://gateway-arbitrum.network.thegraph.com/api/${graphApiKey}/subgraphs/id/FbCGRftH4a3yZugY7TnbYgPJVEv2LvMT6oF1fxPe9aJM`;
30
+ }
31
+ if (chainId == 420420417) {
32
+ this.endpoint = `https://saphyre-service-dev.saphyre.xyz/api/graphql/v3`;
33
+ }
34
+ this.chainId = chainId;
35
+ }
36
+ async getTopPools(numPools) {
37
+ const poolsInfo = [];
38
+ const { resultKey } = (0, graphQueryFilters_1.v3LiquidityCollection)(this.chainId);
39
+ const queryResult = await (0, graphql_request_1.request)(this.endpoint, queryTopPools(numPools, this.chainId));
40
+ queryResult[resultKey].forEach((pool) => {
41
+ poolsInfo.push(createPoolFromGraph(pool, this.dexId));
42
+ });
43
+ return poolsInfo;
44
+ }
45
+ async getPoolsWithTokenPair(tokenA, tokenB, numPools) {
46
+ const a = tokenA.toLowerCase();
47
+ const b = tokenB.toLowerCase();
48
+ const { resultKey } = (0, graphQueryFilters_1.v3LiquidityCollection)(this.chainId);
49
+ const [resAb, resBa] = await Promise.all([
50
+ (0, graphql_request_1.request)(this.endpoint, queryPoolsWithTokenPairDirected(a, b, numPools, this.chainId)),
51
+ (0, graphql_request_1.request)(this.endpoint, queryPoolsWithTokenPairDirected(b, a, numPools, this.chainId)),
52
+ ]);
53
+ return mergePoolsByVolume([resAb[resultKey], resBa[resultKey]], numPools, this.dexId);
54
+ }
55
+ async getPoolsWithToken(token, numPools) {
56
+ const t = token.toLowerCase();
57
+ const { resultKey } = (0, graphQueryFilters_1.v3LiquidityCollection)(this.chainId);
58
+ const [res0, res1] = await Promise.all([
59
+ (0, graphql_request_1.request)(this.endpoint, queryPoolsWithTokenOnSide0(t, numPools, this.chainId)),
60
+ (0, graphql_request_1.request)(this.endpoint, queryPoolsWithTokenOnSide1(t, numPools, this.chainId)),
61
+ ]);
62
+ return mergePoolsByVolume([res0[resultKey], res1[resultKey]], numPools, this.dexId);
63
+ }
64
+ async getAdditionalPoolDataFromSolidity(poolInfos, rpcProvider) {
65
+ const pools = poolInfos.map((poolInfo) => poolInfo.poolId);
66
+ await uniswapState_1.UniswapState.initializeFreshPoolsData(pools, this.chainId, rpcProvider);
67
+ const pools2 = poolInfos.map((poolInfo) => new UniswapV3_1.UniswapV3Pool(poolInfo.poolId, this.dexId, poolInfo.tokens));
68
+ for (const pool of pools2)
69
+ // @ts-ignore
70
+ this.myLocalStorage.setItem(pool.poolId.toLowerCase(), pool);
71
+ return pools2;
72
+ }
73
+ }
74
+ exports.default = UniswapV3;
75
+ function queryTopPools(numPools, chainId) {
76
+ const { field } = (0, graphQueryFilters_1.v3LiquidityCollection)(chainId);
77
+ return (0, graphql_1.parse)((0, graphql_request_1.gql) `
78
+ {
79
+ ${field}(first : ${numPools}, orderDirection : desc, orderBy : volumeUSD) {
80
+ id,
81
+ volumeUSD,
82
+ token0 {
83
+ id,
84
+ name,
85
+ decimals,
86
+ },
87
+ token1 {
88
+ id,
89
+ name,
90
+ decimals,
91
+ },
92
+ },
93
+ }
94
+ `);
95
+ }
96
+ function queryPoolsWithTokenPairDirected(token0Id, token1Id, numPools, chainId) {
97
+ const { field } = (0, graphQueryFilters_1.v3LiquidityCollection)(chainId);
98
+ return (0, graphql_1.parse)((0, graphql_request_1.gql) `
99
+ {
100
+ ${field}(first : ${numPools}, orderDirection : desc, orderBy : volumeUSD, where : {
101
+ ${(0, graphQueryFilters_1.whereDirectedTokenPair)(token0Id, token1Id, chainId)},
102
+ }) {
103
+ id,
104
+ volumeUSD,
105
+ token0 {
106
+ id,
107
+ name,
108
+ decimals,
109
+ },
110
+ token1 {
111
+ id,
112
+ name,
113
+ decimals,
114
+ },
115
+ },
116
+ }
117
+ `);
118
+ }
119
+ function queryPoolsWithTokenOnSide0(token, numPools, chainId) {
120
+ const { field } = (0, graphQueryFilters_1.v3LiquidityCollection)(chainId);
121
+ return (0, graphql_1.parse)((0, graphql_request_1.gql) `
122
+ {
123
+ ${field}(first : ${numPools}, orderDirection : desc, orderBy : volumeUSD, where : {
124
+ ${(0, graphQueryFilters_1.whereTokenOnSide)('token0', token, chainId)},
125
+ }) {
126
+ id,
127
+ volumeUSD,
128
+ token0 {
129
+ id,
130
+ name,
131
+ decimals,
132
+ },
133
+ token1 {
134
+ id,
135
+ name,
136
+ decimals,
137
+ },
138
+ },
139
+ }
140
+ `);
141
+ }
142
+ function queryPoolsWithTokenOnSide1(token, numPools, chainId) {
143
+ const { field } = (0, graphQueryFilters_1.v3LiquidityCollection)(chainId);
144
+ return (0, graphql_1.parse)((0, graphql_request_1.gql) `
145
+ {
146
+ ${field}(first : ${numPools}, orderDirection : desc, orderBy : volumeUSD, where : {
147
+ ${(0, graphQueryFilters_1.whereTokenOnSide)('token1', token, chainId)},
148
+ }) {
149
+ id,
150
+ volumeUSD,
151
+ token0 {
152
+ id,
153
+ name,
154
+ decimals,
155
+ },
156
+ token1 {
157
+ id,
158
+ name,
159
+ decimals,
160
+ },
161
+ },
162
+ }
163
+ `);
164
+ }
165
+ function mergePoolsByVolume(poolLists, numPools, dexId) {
166
+ const byId = new Map();
167
+ for (const list of poolLists) {
168
+ for (const pool of list) {
169
+ byId.set(String(pool.id).toLowerCase(), pool);
170
+ }
171
+ }
172
+ const merged = [...byId.values()];
173
+ merged.sort((a, b) => {
174
+ const va = parseFloat(a.volumeUSD) || 0;
175
+ const vb = parseFloat(b.volumeUSD) || 0;
176
+ return vb - va;
177
+ });
178
+ return merged.slice(0, numPools).map((p) => createPoolFromGraph(p, dexId));
179
+ }
180
+ function createPoolFromGraph(jsonData, dexId) {
181
+ const pool = {
182
+ poolId: jsonData.id,
183
+ dexId: dexId,
184
+ tokens: [
185
+ {
186
+ _address: jsonData.token0.id,
187
+ decimals: Number(jsonData.token0.decimals),
188
+ name: jsonData.token0.name,
189
+ },
190
+ {
191
+ _address: jsonData.token1.id,
192
+ decimals: Number(jsonData.token1.decimals),
193
+ name: jsonData.token1.name,
194
+ },
195
+ ],
196
+ };
197
+ return pool;
198
+ }
@@ -0,0 +1,19 @@
1
+ /** Chains whose graph URL goes through HyperIndex → Hasura (Saphyre / Sei). */
2
+ export declare function usesHyperIndexConverter(chainId: number): boolean;
3
+ /** V2 liquidity collection: merged schema uses V2_Factory_Pair; The Graph uses pairs. */
4
+ export declare function v2LiquidityCollection(chainId: number): {
5
+ field: string;
6
+ resultKey: string;
7
+ };
8
+ /** V3 liquidity collection: merged schema uses V3_Factory_Pool; The Graph uses pools. */
9
+ export declare function v3LiquidityCollection(chainId: number): {
10
+ field: string;
11
+ resultKey: string;
12
+ };
13
+ /**
14
+ * `where` clause fragment for a pool/pair token side.
15
+ * - HyperIndex: `token0: { id: "0x..." }` (scalar address becomes invalid `token1: { _eq }` on Token_bool_exp)
16
+ * - The Graph: `token0: "0x..."`
17
+ */
18
+ export declare function whereTokenOnSide(side: 'token0' | 'token1', address: string, chainId: number): string;
19
+ export declare function whereDirectedTokenPair(token0Id: string, token1Id: string, chainId: number): string;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.usesHyperIndexConverter = usesHyperIndexConverter;
4
+ exports.v2LiquidityCollection = v2LiquidityCollection;
5
+ exports.v3LiquidityCollection = v3LiquidityCollection;
6
+ exports.whereTokenOnSide = whereTokenOnSide;
7
+ exports.whereDirectedTokenPair = whereDirectedTokenPair;
8
+ /** Chains whose graph URL goes through HyperIndex → Hasura (Saphyre / Sei). */
9
+ function usesHyperIndexConverter(chainId) {
10
+ return chainId === 1329 || chainId === 420420417;
11
+ }
12
+ /** V2 liquidity collection: merged schema uses V2_Factory_Pair; The Graph uses pairs. */
13
+ function v2LiquidityCollection(chainId) {
14
+ if (usesHyperIndexConverter(chainId)) {
15
+ return { field: 'V2_Factory_Pair', resultKey: 'V2_Factory_Pair' };
16
+ }
17
+ return { field: 'pairs', resultKey: 'pairs' };
18
+ }
19
+ /** V3 liquidity collection: merged schema uses V3_Factory_Pool; The Graph uses pools. */
20
+ function v3LiquidityCollection(chainId) {
21
+ if (usesHyperIndexConverter(chainId)) {
22
+ return { field: 'V3_Factory_Pool', resultKey: 'V3_Factory_Pool' };
23
+ }
24
+ return { field: 'pools', resultKey: 'pools' };
25
+ }
26
+ /**
27
+ * `where` clause fragment for a pool/pair token side.
28
+ * - HyperIndex: `token0: { id: "0x..." }` (scalar address becomes invalid `token1: { _eq }` on Token_bool_exp)
29
+ * - The Graph: `token0: "0x..."`
30
+ */
31
+ function whereTokenOnSide(side, address, chainId) {
32
+ const id = address.toLowerCase();
33
+ if (usesHyperIndexConverter(chainId)) {
34
+ return `${side} : { id : "${id}" }`;
35
+ }
36
+ return `${side} : "${id}"`;
37
+ }
38
+ function whereDirectedTokenPair(token0Id, token1Id, chainId) {
39
+ return `${whereTokenOnSide('token0', token0Id, chainId)}, ${whereTokenOnSide('token1', token1Id, chainId)}`;
40
+ }
@@ -0,0 +1,12 @@
1
+ import { Pool, PoolInfo, DEXGraphFunctionality } from '../../utils/types/types';
2
+ export default class NewDex implements DEXGraphFunctionality {
3
+ endpoint: string;
4
+ dexId: string;
5
+ chainId: number;
6
+ static initialize(): DEXGraphFunctionality;
7
+ setEndpoint(chainId: number): void;
8
+ getTopPools(numPools: number): Promise<PoolInfo[]>;
9
+ getPoolsWithTokenPair(token1: string, token2: string, first: number): Promise<PoolInfo[]>;
10
+ getPoolsWithToken(token: string, numPools: number): Promise<PoolInfo[]>;
11
+ getAdditionalPoolDataFromSolidity(poolInfos: PoolInfo[]): Promise<Pool[]>;
12
+ }
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const graphql_1 = require("graphql");
4
+ const graphql_request_1 = require("graphql-request");
5
+ class NewDex {
6
+ constructor() {
7
+ this.endpoint = '';
8
+ this.dexId = '';
9
+ this.chainId = 1;
10
+ }
11
+ static initialize() {
12
+ return new NewDex();
13
+ }
14
+ setEndpoint(chainId) {
15
+ if (chainId == 42161) {
16
+ this.endpoint = '';
17
+ }
18
+ this.chainId = chainId;
19
+ }
20
+ async getTopPools(numPools) {
21
+ const poolsInfo = [];
22
+ const queryResult = await (0, graphql_request_1.request)(this.endpoint, queryTopPools(numPools));
23
+ queryResult.pairs.forEach((pair) => {
24
+ poolsInfo.push(pair.id);
25
+ });
26
+ return poolsInfo;
27
+ }
28
+ async getPoolsWithTokenPair(token1, token2, first) {
29
+ const poolsInfo = [];
30
+ const queryResult = await (0, graphql_request_1.request)(this.endpoint, queryPoolsWithTokenPair(token1, token2, first));
31
+ queryResult.pairs.forEach((pair) => {
32
+ poolsInfo.push(pair.id);
33
+ });
34
+ return poolsInfo;
35
+ }
36
+ async getPoolsWithToken(token, numPools) {
37
+ const poolsInfo = [];
38
+ const queryResult = await (0, graphql_request_1.request)(this.endpoint, queryPoolsWithToken(token, numPools));
39
+ queryResult.pairs.forEach((pair) => {
40
+ poolsInfo.push(pair.id);
41
+ });
42
+ return poolsInfo;
43
+ }
44
+ async getAdditionalPoolDataFromSolidity(poolInfos) {
45
+ return [];
46
+ }
47
+ }
48
+ exports.default = NewDex;
49
+ function queryTopPools(numPools) {
50
+ return (0, graphql_1.parse)((0, graphql_request_1.gql) ``);
51
+ }
52
+ function queryPoolsWithTokenPair(tokenA, tokenB, numPools) {
53
+ return (0, graphql_1.parse)((0, graphql_request_1.gql) ``);
54
+ }
55
+ function queryPoolsWithToken(token, numPools) {
56
+ return (0, graphql_1.parse)((0, graphql_request_1.gql) ``);
57
+ }
@@ -0,0 +1,6 @@
1
+ import { Pool, PoolInfo } from '../../../utils/types/types';
2
+ import Web3 from 'web3';
3
+ export declare class BalancerState {
4
+ private constructor();
5
+ static getPoolDataFromContract(pools: PoolInfo[], chainId: number, rpcProvider: Web3): Promise<Pool[]>;
6
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BalancerState = void 0;
4
+ const BalancerWeightedPool_1 = require("./BalancerWeightedPool");
5
+ const BalancerHelper_1 = require("../../../contracts/rateX/BalancerHelper");
6
+ class BalancerState {
7
+ constructor() { }
8
+ static async getPoolDataFromContract(pools, chainId, rpcProvider) {
9
+ const promises = pools.map(async (pool) => {
10
+ // return token address after '-' split
11
+ pool.tokens.forEach((token) => token._address = token._address.split('-')[1]);
12
+ const BalancerHelperContract = (0, BalancerHelper_1.CreateBalancerHelperContract)(chainId, rpcProvider);
13
+ try {
14
+ // @ts-ignore
15
+ const res = await BalancerHelperContract.methods
16
+ .getWeightedPoolInfo(pool.poolId)
17
+ .call();
18
+ const [decimals, tokens, balances, weights, swapFeePercentage] = [res[0], res[1], res[2], res[3], res[4]];
19
+ const weightedPool = new BalancerWeightedPool_1.BalancerWeightedPool(pool.poolId, pool.dexId, pool.tokens, balances, weights, swapFeePercentage);
20
+ return weightedPool;
21
+ }
22
+ catch (err) {
23
+ console.log('Weighted Get Pool Info Error: ', err);
24
+ return null; // Handle the error as needed
25
+ }
26
+ });
27
+ const newPools = await Promise.all(promises);
28
+ // @ts-ignore
29
+ return newPools.filter((pool) => pool !== null); // Filter out any null values
30
+ }
31
+ }
32
+ exports.BalancerState = BalancerState;
@@ -0,0 +1,12 @@
1
+ import { Token, Pool } from '../../../utils/types/types';
2
+ import BigNumber from 'bignumber.js';
3
+ export declare class BalancerWeightedPool extends Pool {
4
+ reserves: BigNumber[];
5
+ startingReserves: BigNumber[];
6
+ weights: BigNumber[];
7
+ swapFeePercentage: BigNumber;
8
+ constructor(poolId: string, dexId: string, tokens: Token[], reserves: BigInt[], weights: BigInt[], swapFeePercentage: BigInt);
9
+ reset(): void;
10
+ calculateExpectedOutputAmount(tokenIn: string, tokenOut: string, amountIn: bigint): bigint;
11
+ update(tokenIn: string, tokenOut: string, amountIn: bigint, amountOut: bigint): void;
12
+ }
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ // Ported from Solidity: https://github.com/balancer/balancer-v2-monorepo/blob/master/pkg/pool-weighted/contracts/WeightedMath.sol
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.BalancerWeightedPool = void 0;
41
+ const types_1 = require("../../../utils/types/types");
42
+ const bignumber_js_1 = __importDefault(require("bignumber.js"));
43
+ const fp = __importStar(require("../../../utils/math/fixed-points"));
44
+ const math = __importStar(require("../../../utils/math/math"));
45
+ // Swap limits: amounts swapped may not be larger than this percentage of total balance of the token being swapped
46
+ // Example - if the pool has 100 WETH, we can swap a maximum od 30 WETH
47
+ const _MAX_IN_RATIO = new bignumber_js_1.default(0.3e18);
48
+ class BalancerWeightedPool extends types_1.Pool {
49
+ constructor(poolId, dexId, tokens, reserves, weights, swapFeePercentage) {
50
+ super(poolId, dexId, tokens);
51
+ this.reserves = reserves.map((r) => new bignumber_js_1.default(r.toString()));
52
+ this.startingReserves = [...this.reserves];
53
+ this.weights = weights.map((r) => new bignumber_js_1.default(r.toString()));
54
+ this.swapFeePercentage = new bignumber_js_1.default(swapFeePercentage.toString());
55
+ }
56
+ reset() {
57
+ this.reserves = [...this.startingReserves];
58
+ }
59
+ calculateExpectedOutputAmount(tokenIn, tokenOut, amountIn) {
60
+ return calculateOutputAmount(this, tokenIn, tokenOut, (0, bignumber_js_1.default)(amountIn.toString()));
61
+ }
62
+ update(tokenIn, tokenOut, amountIn, amountOut) {
63
+ // CHECK ???
64
+ const i = this.tokens.findIndex((token) => token._address === tokenIn);
65
+ const j = this.tokens.findIndex((token) => token._address === tokenOut);
66
+ this.reserves[i] = fp.add(this.reserves[i], (0, bignumber_js_1.default)(amountIn.toString()));
67
+ this.reserves[j] = fp.sub(this.reserves[j], (0, bignumber_js_1.default)(amountOut.toString()));
68
+ }
69
+ }
70
+ exports.BalancerWeightedPool = BalancerWeightedPool;
71
+ function calculateOutputAmount(pool, tokenA, tokenB, tokenAmountIn, swapFeePercentage) {
72
+ // Subtract the fee from the amount in if requested
73
+ if (swapFeePercentage)
74
+ tokenAmountIn = fp.sub(tokenAmountIn, fp.mulUp(tokenAmountIn, swapFeePercentage));
75
+ // Get the index of the token we are swapping from and to
76
+ const i = pool.tokens.findIndex((token) => token._address === tokenA);
77
+ const j = pool.tokens.findIndex((token) => token._address === tokenB);
78
+ try {
79
+ const res = _calcOutGivenIn(pool.reserves[i], pool.weights[i], pool.reserves[j], pool.weights[j], tokenAmountIn);
80
+ return BigInt(res.toFixed());
81
+ }
82
+ catch (e) {
83
+ return BigInt(0);
84
+ }
85
+ }
86
+ /* Computes how many tokens can be taken out of a pool if `amountIn` are sent, given the current balances and weights.
87
+ Amount out, so we round down overall:
88
+ **********************************************************************************************
89
+ // outGivenIn //
90
+ // aO = amountOut //
91
+ // bO = balanceOut //
92
+ // bI = balanceIn / / bI \ (wI / wO) \ //
93
+ // aI = amountIn aO = bO * | 1 - | -------------------------- | ^ | //
94
+ // wI = weightIn \ \ ( bI + aI ) / / //
95
+ // wO = weightOut //
96
+ **********************************************************************************************
97
+ The multiplication rounds down, and the subtrahend (power) runds up (so the base rounds up too).
98
+ Because bI / (bI + aI) <= 1, the exponent rounds down. */
99
+ // Ovde puca!!!!!!!!!!!!!!
100
+ function _calcOutGivenIn(balanceIn, weightIn, balanceOut, weightOut, amountIn) {
101
+ // Cannot exceed maximum in ratio (30% of tokenIn balance)
102
+ if (amountIn.gte(fp.mulDown(balanceIn, _MAX_IN_RATIO)))
103
+ throw new Error('MAX_IN_RATIO');
104
+ const denominator = math.add(balanceIn, amountIn);
105
+ const base = fp.divUp(balanceIn, denominator);
106
+ const exponent = fp.divDown(weightIn, weightOut);
107
+ const power = fp.powUp(base, exponent);
108
+ return fp.mulDown(balanceOut, fp.complement(power));
109
+ }
@@ -0,0 +1,12 @@
1
+ import { Pool, Token } from '../../utils/types/types';
2
+ import BigNumber from "bignumber.js";
3
+ export declare class CamelotPool extends Pool {
4
+ fees: BigNumber[];
5
+ reserves: BigNumber[];
6
+ startingReserves: BigNumber[];
7
+ stableSwap: boolean;
8
+ constructor(poolId: string, dexId: string, tokens: Token[], reserves: bigint[], fees: bigint[], stableSwap: boolean);
9
+ reset(): void;
10
+ calculateExpectedOutputAmount(tokenIn: string, tokenOut: string, amountIn: bigint): bigint;
11
+ update(tokenIn: string, tokenOut: string, amountIn: bigint, amountOut: bigint): void;
12
+ }
@@ -0,0 +1,135 @@
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.CamelotPool = void 0;
7
+ const types_1 = require("../../utils/types/types");
8
+ const bignumber_js_1 = __importDefault(require("bignumber.js"));
9
+ // Camelot V2 pools have 2 tokens in the pool, and a fee
10
+ // Example contracts of one Camelot V2 pool: https://arbiscan.io/address/0xa6c5c7d189fa4eb5af8ba34e63dcdd3a635d433f#readContract
11
+ const feeDenominator = new bignumber_js_1.default(100000);
12
+ class CamelotPool extends types_1.Pool {
13
+ constructor(poolId, dexId, tokens, reserves, fees, stableSwap) {
14
+ super(poolId, dexId, tokens);
15
+ this.reserves = reserves.map((r) => (0, bignumber_js_1.default)(r.toString()));
16
+ this.startingReserves = [...this.reserves];
17
+ this.fees = fees.map((f) => (0, bignumber_js_1.default)(f.toString()));
18
+ this.stableSwap = stableSwap;
19
+ }
20
+ reset() {
21
+ this.reserves = [...this.startingReserves];
22
+ }
23
+ // function getAmountOut on Camelot V2 pools smart contracts
24
+ calculateExpectedOutputAmount(tokenIn, tokenOut, amountIn) {
25
+ // this function will be called by our routing algorithm which uses bigint values
26
+ const amountInBN = new bignumber_js_1.default(amountIn.toString());
27
+ if (this.stableSwap)
28
+ return calculateStableSwap(this, tokenIn, tokenOut, amountInBN);
29
+ else
30
+ return calculateRegularSwap(this, tokenIn, tokenOut, amountInBN);
31
+ }
32
+ update(tokenIn, tokenOut, amountIn, amountOut) {
33
+ const i = this.tokens.findIndex((token) => token._address === tokenIn);
34
+ const j = this.tokens.findIndex((token) => token._address === tokenOut);
35
+ this.reserves[i] = this.reserves[i].plus((0, bignumber_js_1.default)(amountIn.toString()));
36
+ this.reserves[j] = this.reserves[j].minus((0, bignumber_js_1.default)(amountOut.toString()));
37
+ }
38
+ }
39
+ exports.CamelotPool = CamelotPool;
40
+ function calculateStableSwap(pool, tokenIn, tokenOut, amountIn) {
41
+ const feePercent = tokenIn.toLowerCase() === pool.tokens[0]._address.toLowerCase() ? pool.fees[0] : pool.fees[1];
42
+ let reserve0 = pool.reserves[0];
43
+ let reserve1 = pool.reserves[1];
44
+ const precisionMultiplier0 = new bignumber_js_1.default(10 ** pool.tokens[0].decimals);
45
+ const precisionMultiplier1 = new bignumber_js_1.default(10 ** pool.tokens[1].decimals);
46
+ amountIn = amountIn.minus(amountIn.times(feePercent).div(feeDenominator)); // remove fee from amount received
47
+ const xy = _k(pool);
48
+ reserve0 = reserve0.times(1e18).div(precisionMultiplier0);
49
+ reserve1 = reserve1.times(1e18).div(precisionMultiplier1);
50
+ const [reserveA, reserveB] = tokenIn.toLowerCase() === pool.tokens[0]._address.toLowerCase()
51
+ ? [reserve0, reserve1]
52
+ : [reserve1, reserve0];
53
+ // amountIn = tokenIn == token0 ? amountIn * 1e18 / precisionMultiplier0 : amountIn * 1e18 / precisionMultiplier1;
54
+ amountIn = tokenIn.toLowerCase() === pool.tokens[0]._address.toLowerCase()
55
+ ? amountIn.times(1e18).div(precisionMultiplier0)
56
+ : amountIn.times(1e18).div(precisionMultiplier1);
57
+ // uint y = reserveB - _get_y(amountIn + reserveA, xy, reserveB);
58
+ const y = reserveB.minus(_get_y(amountIn.plus(reserveA), xy, reserveB));
59
+ // return y * (tokenIn == token0 ? precisionMultiplier1 : precisionMultiplier0) / 1e18;
60
+ let result = tokenIn.toLowerCase() === pool.tokens[0]._address.toLowerCase()
61
+ ? y.times(precisionMultiplier1).div(1e18)
62
+ : y.times(precisionMultiplier0).div(1e18);
63
+ result = floor(result);
64
+ return BigInt(result.toFixed());
65
+ }
66
+ // named the same as in Camelot V2 pools smart contracts
67
+ function _k(pool) {
68
+ // for simplicity extract values
69
+ let reserve0 = pool.reserves[0];
70
+ let reserve1 = pool.reserves[1];
71
+ if (pool.stableSwap) {
72
+ const precisionMultiplier0 = new bignumber_js_1.default(10 ** pool.tokens[0].decimals);
73
+ const precisionMultiplier1 = new bignumber_js_1.default(10 ** pool.tokens[1].decimals);
74
+ const x = reserve0.times(1e18).div(precisionMultiplier0);
75
+ const y = reserve1.times(1e18).div(precisionMultiplier1);
76
+ const a = x.times(y).div(1e18);
77
+ const b = x.times(x).div(1e18).plus(y.times(y).div(1e18));
78
+ let res = a.times(b).div(1e18);
79
+ return floor(res); // x3y+y3x >= k
80
+ }
81
+ return reserve0.times(reserve1);
82
+ }
83
+ // named the same as in Camelot V2 pools smart contracts
84
+ function _get_y(x0, xy, y) {
85
+ for (let i = 0; i < 255; i++) {
86
+ const y_prev = y;
87
+ const k = _f(x0, y);
88
+ if (k.lt(xy)) {
89
+ let dy = xy.minus(k).times(1e18).dividedToIntegerBy(_d(x0, y));
90
+ y = y.plus(dy);
91
+ }
92
+ else {
93
+ let dy = k.minus(xy).times(1e18).dividedToIntegerBy(_d(x0, y));
94
+ y = y.minus(dy);
95
+ }
96
+ const diff = y.minus(y_prev).abs();
97
+ if (diff.lte(1))
98
+ break;
99
+ }
100
+ return floor(y);
101
+ }
102
+ function _f(x0, y) {
103
+ // return x0 * (y * y / 1e18 * y / 1e18) / 1e18 + (x0 * x0 / 1e18 * x0 / 1e18) * y / 1e18;
104
+ const ySquared = y.times(y).dividedToIntegerBy(1e18);
105
+ const x0Squared = x0.times(x0).dividedToIntegerBy(1e18);
106
+ const term1 = x0.times((ySquared).times(y).dividedToIntegerBy(1e18)).dividedToIntegerBy(1e18);
107
+ const term2 = y.times(x0Squared.times(x0).dividedToIntegerBy(1e18)).dividedToIntegerBy(1e18);
108
+ return term1.plus(term2);
109
+ }
110
+ function _d(x0, y) {
111
+ // return 3 * x0 * (y * y / 1e18) / 1e18 + (x0 * x0 / 1e18 * x0 / 1e18);
112
+ const ySquared = y.times(y).dividedToIntegerBy(1e18);
113
+ const x0Squared = x0.times(x0).dividedToIntegerBy(1e18);
114
+ const term1 = x0.times(ySquared).times(3).dividedToIntegerBy(1e18);
115
+ const term2 = x0Squared.times(x0).dividedToIntegerBy(1e18);
116
+ return term1.plus(term2);
117
+ }
118
+ function calculateRegularSwap(pool, tokenIn, tokenOut, amountIn) {
119
+ const feePercent = tokenIn.toLowerCase() === pool.tokens[0]._address.toLowerCase() ? pool.fees[0] : pool.fees[1];
120
+ const [reserveA, reserveB] = tokenIn.toLowerCase() === pool.tokens[0]._address.toLowerCase()
121
+ ? [pool.reserves[0], pool.reserves[1]]
122
+ : [pool.reserves[1], pool.reserves[0]];
123
+ amountIn = amountIn.times(feeDenominator.minus(feePercent));
124
+ const numerator = amountIn.times(reserveB);
125
+ const denominator = reserveA.times(feeDenominator).plus(amountIn);
126
+ const result = floor(numerator.div(denominator));
127
+ return BigInt(result.toFixed());
128
+ }
129
+ /* Custom floor function because BigNumber library does not implement it
130
+ @param num: the BigNumber number to be floored
131
+ */
132
+ function floor(num) {
133
+ const whole = num.toFixed().toString().split('.')[0];
134
+ return new bignumber_js_1.default(whole);
135
+ }
@@ -0,0 +1,9 @@
1
+ import { Pool, Token } from '../../utils/types/types';
2
+ export declare class SushiSwapV2Pool extends Pool {
3
+ reserves: bigint[];
4
+ startingReserves: bigint[];
5
+ constructor(poolId: string, dexId: string, tokens: Token[], reserves: bigint[]);
6
+ reset(): void;
7
+ calculateExpectedOutputAmount(tokenIn: string, tokenOut: string, amountIn: bigint): bigint;
8
+ update(tokenIn: string, tokenOut: string, amountIn: bigint, amountOut: bigint): void;
9
+ }