@fanx-protocol/smart-order-router 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (438) hide show
  1. package/CHANGELOG.md +255 -0
  2. package/LICENSE +674 -0
  3. package/README.md +273 -0
  4. package/build/main/index.d.ts +3 -0
  5. package/build/main/index.js +20 -0
  6. package/build/main/providers/cache-node.d.ts +10 -0
  7. package/build/main/providers/cache-node.js +33 -0
  8. package/build/main/providers/cache.d.ts +14 -0
  9. package/build/main/providers/cache.js +3 -0
  10. package/build/main/providers/caching/route/index.d.ts +2 -0
  11. package/build/main/providers/caching/route/index.js +19 -0
  12. package/build/main/providers/caching/route/model/cache-mode.d.ts +16 -0
  13. package/build/main/providers/caching/route/model/cache-mode.js +21 -0
  14. package/build/main/providers/caching/route/model/cached-route.d.ts +29 -0
  15. package/build/main/providers/caching/route/model/cached-route.js +89 -0
  16. package/build/main/providers/caching/route/model/cached-routes.d.ts +67 -0
  17. package/build/main/providers/caching/route/model/cached-routes.js +81 -0
  18. package/build/main/providers/caching/route/model/index.d.ts +3 -0
  19. package/build/main/providers/caching/route/model/index.js +20 -0
  20. package/build/main/providers/caching/route/route-caching-provider.d.ts +88 -0
  21. package/build/main/providers/caching/route/route-caching-provider.js +72 -0
  22. package/build/main/providers/caching-gas-provider.d.ts +23 -0
  23. package/build/main/providers/caching-gas-provider.js +41 -0
  24. package/build/main/providers/caching-subgraph-provider.d.ts +33 -0
  25. package/build/main/providers/caching-subgraph-provider.js +37 -0
  26. package/build/main/providers/caching-token-list-provider.d.ts +52 -0
  27. package/build/main/providers/caching-token-list-provider.js +147 -0
  28. package/build/main/providers/caching-token-provider.d.ts +24 -0
  29. package/build/main/providers/caching-token-provider.js +108 -0
  30. package/build/main/providers/eip-1559-gas-price-provider.d.ts +31 -0
  31. package/build/main/providers/eip-1559-gas-price-provider.js +71 -0
  32. package/build/main/providers/eth-estimate-gas-provider.d.ts +19 -0
  33. package/build/main/providers/eth-estimate-gas-provider.js +94 -0
  34. package/build/main/providers/eth-gas-station-info-gas-price-provider.d.ts +19 -0
  35. package/build/main/providers/eth-gas-station-info-gas-price-provider.js +36 -0
  36. package/build/main/providers/gas-price-provider.d.ts +10 -0
  37. package/build/main/providers/gas-price-provider.js +10 -0
  38. package/build/main/providers/index.d.ts +38 -0
  39. package/build/main/providers/index.js +55 -0
  40. package/build/main/providers/legacy-gas-price-provider.d.ts +7 -0
  41. package/build/main/providers/legacy-gas-price-provider.js +18 -0
  42. package/build/main/providers/multicall-provider.d.ts +83 -0
  43. package/build/main/providers/multicall-provider.js +15 -0
  44. package/build/main/providers/multicall-uniswap-provider.d.ts +37 -0
  45. package/build/main/providers/multicall-uniswap-provider.js +164 -0
  46. package/build/main/providers/on-chain-gas-price-provider.d.ts +19 -0
  47. package/build/main/providers/on-chain-gas-price-provider.js +36 -0
  48. package/build/main/providers/on-chain-quote-provider.d.ts +258 -0
  49. package/build/main/providers/on-chain-quote-provider.js +693 -0
  50. package/build/main/providers/pool-provider.d.ts +44 -0
  51. package/build/main/providers/pool-provider.js +73 -0
  52. package/build/main/providers/portion-provider.d.ts +86 -0
  53. package/build/main/providers/portion-provider.js +118 -0
  54. package/build/main/providers/provider.d.ts +38 -0
  55. package/build/main/providers/provider.js +3 -0
  56. package/build/main/providers/simulation-provider.d.ts +43 -0
  57. package/build/main/providers/simulation-provider.js +136 -0
  58. package/build/main/providers/static-gas-price-provider.d.ts +7 -0
  59. package/build/main/providers/static-gas-price-provider.js +13 -0
  60. package/build/main/providers/subgraph-provider-with-fallback.d.ts +11 -0
  61. package/build/main/providers/subgraph-provider-with-fallback.js +25 -0
  62. package/build/main/providers/subgraph-provider.d.ts +51 -0
  63. package/build/main/providers/subgraph-provider.js +120 -0
  64. package/build/main/providers/swap-router-provider.d.ts +30 -0
  65. package/build/main/providers/swap-router-provider.js +42 -0
  66. package/build/main/providers/token-fee-fetcher.d.ts +31 -0
  67. package/build/main/providers/token-fee-fetcher.js +108 -0
  68. package/build/main/providers/token-properties-provider.d.ts +31 -0
  69. package/build/main/providers/token-properties-provider.js +118 -0
  70. package/build/main/providers/token-provider.d.ts +38 -0
  71. package/build/main/providers/token-provider.js +175 -0
  72. package/build/main/providers/token-validator-provider.d.ts +42 -0
  73. package/build/main/providers/token-validator-provider.js +99 -0
  74. package/build/main/providers/uri-subgraph-provider.d.ts +20 -0
  75. package/build/main/providers/uri-subgraph-provider.js +65 -0
  76. package/build/main/providers/v2/caching-pool-provider.d.ts +33 -0
  77. package/build/main/providers/v2/caching-pool-provider.js +89 -0
  78. package/build/main/providers/v2/caching-subgraph-provider.d.ts +19 -0
  79. package/build/main/providers/v2/caching-subgraph-provider.js +24 -0
  80. package/build/main/providers/v2/pool-provider.d.ts +63 -0
  81. package/build/main/providers/v2/pool-provider.js +138 -0
  82. package/build/main/providers/v2/quote-provider.d.ts +34 -0
  83. package/build/main/providers/v2/quote-provider.js +90 -0
  84. package/build/main/providers/v2/static-subgraph-provider.d.ts +19 -0
  85. package/build/main/providers/v2/static-subgraph-provider.js +75 -0
  86. package/build/main/providers/v2/subgraph-provider-with-fallback.d.ts +16 -0
  87. package/build/main/providers/v2/subgraph-provider-with-fallback.js +23 -0
  88. package/build/main/providers/v2/subgraph-provider.d.ts +36 -0
  89. package/build/main/providers/v2/subgraph-provider.js +174 -0
  90. package/build/main/providers/v2/uri-subgraph-provider.d.ts +4 -0
  91. package/build/main/providers/v2/uri-subgraph-provider.js +8 -0
  92. package/build/main/providers/v3/caching-pool-provider.d.ts +32 -0
  93. package/build/main/providers/v3/caching-pool-provider.js +84 -0
  94. package/build/main/providers/v3/caching-subgraph-provider.d.ts +19 -0
  95. package/build/main/providers/v3/caching-subgraph-provider.js +24 -0
  96. package/build/main/providers/v3/gas-data-provider.d.ts +39 -0
  97. package/build/main/providers/v3/gas-data-provider.js +26 -0
  98. package/build/main/providers/v3/pool-provider.d.ts +77 -0
  99. package/build/main/providers/v3/pool-provider.js +108 -0
  100. package/build/main/providers/v3/static-subgraph-provider.d.ts +21 -0
  101. package/build/main/providers/v3/static-subgraph-provider.js +89 -0
  102. package/build/main/providers/v3/subgraph-provider-with-fallback.d.ts +12 -0
  103. package/build/main/providers/v3/subgraph-provider-with-fallback.js +19 -0
  104. package/build/main/providers/v3/subgraph-provider.d.ts +46 -0
  105. package/build/main/providers/v3/subgraph-provider.js +54 -0
  106. package/build/main/providers/v3/uri-subgraph-provider.d.ts +4 -0
  107. package/build/main/providers/v3/uri-subgraph-provider.js +8 -0
  108. package/build/main/routers/alpha-router/alpha-router.d.ts +347 -0
  109. package/build/main/routers/alpha-router/alpha-router.js +1219 -0
  110. package/build/main/routers/alpha-router/config.d.ts +4 -0
  111. package/build/main/routers/alpha-router/config.js +40 -0
  112. package/build/main/routers/alpha-router/entities/index.d.ts +1 -0
  113. package/build/main/routers/alpha-router/entities/index.js +18 -0
  114. package/build/main/routers/alpha-router/entities/route-with-valid-quote.d.ts +167 -0
  115. package/build/main/routers/alpha-router/entities/route-with-valid-quote.js +166 -0
  116. package/build/main/routers/alpha-router/functions/best-swap-route.d.ts +22 -0
  117. package/build/main/routers/alpha-router/functions/best-swap-route.js +534 -0
  118. package/build/main/routers/alpha-router/functions/calculate-ratio-amount-in.d.ts +3 -0
  119. package/build/main/routers/alpha-router/functions/calculate-ratio-amount-in.js +18 -0
  120. package/build/main/routers/alpha-router/functions/compute-all-routes.d.ts +9 -0
  121. package/build/main/routers/alpha-router/functions/compute-all-routes.js +104 -0
  122. package/build/main/routers/alpha-router/functions/get-candidate-pools.d.ts +100 -0
  123. package/build/main/routers/alpha-router/functions/get-candidate-pools.js +1008 -0
  124. package/build/main/routers/alpha-router/gas-models/gas-costs.d.ts +12 -0
  125. package/build/main/routers/alpha-router/gas-models/gas-costs.js +90 -0
  126. package/build/main/routers/alpha-router/gas-models/gas-model.d.ts +106 -0
  127. package/build/main/routers/alpha-router/gas-models/gas-model.js +68 -0
  128. package/build/main/routers/alpha-router/gas-models/index.d.ts +2 -0
  129. package/build/main/routers/alpha-router/gas-models/index.js +19 -0
  130. package/build/main/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.d.ts +24 -0
  131. package/build/main/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.js +161 -0
  132. package/build/main/routers/alpha-router/gas-models/tick-based-heuristic-gas-model.d.ts +15 -0
  133. package/build/main/routers/alpha-router/gas-models/tick-based-heuristic-gas-model.js +185 -0
  134. package/build/main/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.d.ts +31 -0
  135. package/build/main/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.js +169 -0
  136. package/build/main/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.d.ts +26 -0
  137. package/build/main/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.js +41 -0
  138. package/build/main/routers/alpha-router/index.d.ts +4 -0
  139. package/build/main/routers/alpha-router/index.js +21 -0
  140. package/build/main/routers/alpha-router/quoters/base-quoter.d.ts +76 -0
  141. package/build/main/routers/alpha-router/quoters/base-quoter.js +76 -0
  142. package/build/main/routers/alpha-router/quoters/index.d.ts +5 -0
  143. package/build/main/routers/alpha-router/quoters/index.js +22 -0
  144. package/build/main/routers/alpha-router/quoters/mixed-quoter.d.ts +28 -0
  145. package/build/main/routers/alpha-router/quoters/mixed-quoter.js +154 -0
  146. package/build/main/routers/alpha-router/quoters/model/index.d.ts +1 -0
  147. package/build/main/routers/alpha-router/quoters/model/index.js +18 -0
  148. package/build/main/routers/alpha-router/quoters/model/results/get-quotes-result.d.ts +6 -0
  149. package/build/main/routers/alpha-router/quoters/model/results/get-quotes-result.js +3 -0
  150. package/build/main/routers/alpha-router/quoters/model/results/get-routes-result.d.ts +6 -0
  151. package/build/main/routers/alpha-router/quoters/model/results/get-routes-result.js +3 -0
  152. package/build/main/routers/alpha-router/quoters/model/results/index.d.ts +2 -0
  153. package/build/main/routers/alpha-router/quoters/model/results/index.js +19 -0
  154. package/build/main/routers/alpha-router/quoters/v2-quoter.d.ts +24 -0
  155. package/build/main/routers/alpha-router/quoters/v2-quoter.js +140 -0
  156. package/build/main/routers/alpha-router/quoters/v3-quoter.d.ts +19 -0
  157. package/build/main/routers/alpha-router/quoters/v3-quoter.js +117 -0
  158. package/build/main/routers/index.d.ts +3 -0
  159. package/build/main/routers/index.js +20 -0
  160. package/build/main/routers/router.d.ts +186 -0
  161. package/build/main/routers/router.js +55 -0
  162. package/build/main/tsconfig.tsbuildinfo +1 -0
  163. package/build/main/types/other/commons.d.ts +16 -0
  164. package/build/main/types/other/commons.js +6 -0
  165. package/build/main/types/other/factories/Erc20__factory.d.ts +45 -0
  166. package/build/main/types/other/factories/Erc20__factory.js +240 -0
  167. package/build/main/types/other/factories/GasDataArbitrum__factory.d.ts +18 -0
  168. package/build/main/types/other/factories/GasDataArbitrum__factory.js +58 -0
  169. package/build/main/types/other/factories/IMixedRouteQuoterV1__factory.d.ts +41 -0
  170. package/build/main/types/other/factories/IMixedRouteQuoterV1__factory.js +156 -0
  171. package/build/main/types/other/factories/ITokenValidator__factory.d.ts +22 -0
  172. package/build/main/types/other/factories/ITokenValidator__factory.js +78 -0
  173. package/build/main/types/other/factories/MixedRouteQuoterV2__factory.d.ts +86 -0
  174. package/build/main/types/other/factories/MixedRouteQuoterV2__factory.js +477 -0
  175. package/build/main/types/other/factories/Permit2__factory.d.ts +87 -0
  176. package/build/main/types/other/factories/Permit2__factory.js +936 -0
  177. package/build/main/types/other/factories/SwapRouter02__factory.d.ts +67 -0
  178. package/build/main/types/other/factories/SwapRouter02__factory.js +1098 -0
  179. package/build/main/types/other/factories/TokenFeeDetector__factory.d.ts +47 -0
  180. package/build/main/types/other/factories/TokenFeeDetector__factory.js +243 -0
  181. package/build/main/types/v2/commons.d.ts +16 -0
  182. package/build/main/types/v2/commons.js +6 -0
  183. package/build/main/types/v2/factories/IUniswapV2Pair__factory.d.ts +35 -0
  184. package/build/main/types/v2/factories/IUniswapV2Pair__factory.js +671 -0
  185. package/build/main/types/v3/commons.d.ts +16 -0
  186. package/build/main/types/v3/commons.js +6 -0
  187. package/build/main/types/v3/factories/IERC20Metadata__factory.d.ts +35 -0
  188. package/build/main/types/v3/factories/IERC20Metadata__factory.js +242 -0
  189. package/build/main/types/v3/factories/IQuoterV2__factory.d.ts +41 -0
  190. package/build/main/types/v3/factories/IQuoterV2__factory.js +220 -0
  191. package/build/main/types/v3/factories/IUniswapV3PoolState__factory.d.ts +22 -0
  192. package/build/main/types/v3/factories/IUniswapV3PoolState__factory.js +266 -0
  193. package/build/main/types/v3/factories/UniswapInterfaceMulticall__factory.d.ts +61 -0
  194. package/build/main/types/v3/factories/UniswapInterfaceMulticall__factory.js +127 -0
  195. package/build/main/util/addresses.d.ts +24 -0
  196. package/build/main/util/addresses.js +76 -0
  197. package/build/main/util/amounts.d.ts +9 -0
  198. package/build/main/util/amounts.js +73 -0
  199. package/build/main/util/chains.d.ts +31 -0
  200. package/build/main/util/chains.js +97 -0
  201. package/build/main/util/gas-factory-helpers.d.ts +33 -0
  202. package/build/main/util/gas-factory-helpers.js +463 -0
  203. package/build/main/util/index.d.ts +7 -0
  204. package/build/main/util/index.js +24 -0
  205. package/build/main/util/l2FeeChains.d.ts +2 -0
  206. package/build/main/util/l2FeeChains.js +13 -0
  207. package/build/main/util/log.d.ts +3 -0
  208. package/build/main/util/log.js +97 -0
  209. package/build/main/util/methodParameters.d.ts +5 -0
  210. package/build/main/util/methodParameters.js +183 -0
  211. package/build/main/util/metric.d.ts +48 -0
  212. package/build/main/util/metric.js +59 -0
  213. package/build/main/util/onchainQuoteProviderConfigs.d.ts +42 -0
  214. package/build/main/util/onchainQuoteProviderConfigs.js +74 -0
  215. package/build/main/util/protocols.d.ts +2 -0
  216. package/build/main/util/protocols.js +20 -0
  217. package/build/main/util/routes.d.ts +11 -0
  218. package/build/main/util/routes.js +149 -0
  219. package/build/main/util/unsupported-tokens.d.ts +37 -0
  220. package/build/main/util/unsupported-tokens.js +1119 -0
  221. package/build/module/index.d.ts +3 -0
  222. package/build/module/index.js +4 -0
  223. package/build/module/providers/cache-node.d.ts +10 -0
  224. package/build/module/providers/cache-node.js +29 -0
  225. package/build/module/providers/cache.d.ts +14 -0
  226. package/build/module/providers/cache.js +2 -0
  227. package/build/module/providers/caching/route/index.d.ts +2 -0
  228. package/build/module/providers/caching/route/index.js +3 -0
  229. package/build/module/providers/caching/route/model/cache-mode.d.ts +16 -0
  230. package/build/module/providers/caching/route/model/cache-mode.js +18 -0
  231. package/build/module/providers/caching/route/model/cached-route.d.ts +29 -0
  232. package/build/module/providers/caching/route/model/cached-route.js +85 -0
  233. package/build/module/providers/caching/route/model/cached-routes.d.ts +67 -0
  234. package/build/module/providers/caching/route/model/cached-routes.js +74 -0
  235. package/build/module/providers/caching/route/model/index.d.ts +3 -0
  236. package/build/module/providers/caching/route/model/index.js +4 -0
  237. package/build/module/providers/caching/route/route-caching-provider.d.ts +88 -0
  238. package/build/module/providers/caching/route/route-caching-provider.js +68 -0
  239. package/build/module/providers/caching-gas-provider.d.ts +23 -0
  240. package/build/module/providers/caching-gas-provider.js +37 -0
  241. package/build/module/providers/caching-subgraph-provider.d.ts +33 -0
  242. package/build/module/providers/caching-subgraph-provider.js +33 -0
  243. package/build/module/providers/caching-token-list-provider.d.ts +52 -0
  244. package/build/module/providers/caching-token-list-provider.js +140 -0
  245. package/build/module/providers/caching-token-provider.d.ts +24 -0
  246. package/build/module/providers/caching-token-provider.js +101 -0
  247. package/build/module/providers/eip-1559-gas-price-provider.d.ts +31 -0
  248. package/build/module/providers/eip-1559-gas-price-provider.js +64 -0
  249. package/build/module/providers/eth-estimate-gas-provider.d.ts +19 -0
  250. package/build/module/providers/eth-estimate-gas-provider.js +102 -0
  251. package/build/module/providers/eth-gas-station-info-gas-price-provider.d.ts +19 -0
  252. package/build/module/providers/eth-gas-station-info-gas-price-provider.js +29 -0
  253. package/build/module/providers/gas-price-provider.d.ts +10 -0
  254. package/build/module/providers/gas-price-provider.js +6 -0
  255. package/build/module/providers/index.d.ts +38 -0
  256. package/build/module/providers/index.js +39 -0
  257. package/build/module/providers/legacy-gas-price-provider.d.ts +7 -0
  258. package/build/module/providers/legacy-gas-price-provider.js +14 -0
  259. package/build/module/providers/multicall-provider.d.ts +83 -0
  260. package/build/module/providers/multicall-provider.js +11 -0
  261. package/build/module/providers/multicall-uniswap-provider.d.ts +37 -0
  262. package/build/module/providers/multicall-uniswap-provider.js +157 -0
  263. package/build/module/providers/on-chain-gas-price-provider.d.ts +19 -0
  264. package/build/module/providers/on-chain-gas-price-provider.js +32 -0
  265. package/build/module/providers/on-chain-quote-provider.d.ts +258 -0
  266. package/build/module/providers/on-chain-quote-provider.js +687 -0
  267. package/build/module/providers/pool-provider.d.ts +44 -0
  268. package/build/module/providers/pool-provider.js +66 -0
  269. package/build/module/providers/portion-provider.d.ts +86 -0
  270. package/build/module/providers/portion-provider.js +114 -0
  271. package/build/module/providers/provider.d.ts +38 -0
  272. package/build/module/providers/provider.js +2 -0
  273. package/build/module/providers/simulation-provider.d.ts +43 -0
  274. package/build/module/providers/simulation-provider.js +138 -0
  275. package/build/module/providers/static-gas-price-provider.d.ts +7 -0
  276. package/build/module/providers/static-gas-price-provider.js +9 -0
  277. package/build/module/providers/subgraph-provider-with-fallback.d.ts +11 -0
  278. package/build/module/providers/subgraph-provider-with-fallback.js +21 -0
  279. package/build/module/providers/subgraph-provider.d.ts +51 -0
  280. package/build/module/providers/subgraph-provider.js +113 -0
  281. package/build/module/providers/swap-router-provider.d.ts +30 -0
  282. package/build/module/providers/swap-router-provider.js +38 -0
  283. package/build/module/providers/token-fee-fetcher.d.ts +31 -0
  284. package/build/module/providers/token-fee-fetcher.js +104 -0
  285. package/build/module/providers/token-properties-provider.d.ts +31 -0
  286. package/build/module/providers/token-properties-provider.js +114 -0
  287. package/build/module/providers/token-provider.d.ts +38 -0
  288. package/build/module/providers/token-provider.js +164 -0
  289. package/build/module/providers/token-validator-provider.d.ts +42 -0
  290. package/build/module/providers/token-validator-provider.js +92 -0
  291. package/build/module/providers/uri-subgraph-provider.d.ts +20 -0
  292. package/build/module/providers/uri-subgraph-provider.js +58 -0
  293. package/build/module/providers/v2/caching-pool-provider.d.ts +33 -0
  294. package/build/module/providers/v2/caching-pool-provider.js +85 -0
  295. package/build/module/providers/v2/caching-subgraph-provider.d.ts +19 -0
  296. package/build/module/providers/v2/caching-subgraph-provider.js +20 -0
  297. package/build/module/providers/v2/pool-provider.d.ts +63 -0
  298. package/build/module/providers/v2/pool-provider.js +131 -0
  299. package/build/module/providers/v2/quote-provider.d.ts +34 -0
  300. package/build/module/providers/v2/quote-provider.js +86 -0
  301. package/build/module/providers/v2/static-subgraph-provider.d.ts +19 -0
  302. package/build/module/providers/v2/static-subgraph-provider.js +68 -0
  303. package/build/module/providers/v2/subgraph-provider-with-fallback.d.ts +16 -0
  304. package/build/module/providers/v2/subgraph-provider-with-fallback.js +19 -0
  305. package/build/module/providers/v2/subgraph-provider.d.ts +36 -0
  306. package/build/module/providers/v2/subgraph-provider.js +167 -0
  307. package/build/module/providers/v2/uri-subgraph-provider.d.ts +4 -0
  308. package/build/module/providers/v2/uri-subgraph-provider.js +4 -0
  309. package/build/module/providers/v3/caching-pool-provider.d.ts +32 -0
  310. package/build/module/providers/v3/caching-pool-provider.js +77 -0
  311. package/build/module/providers/v3/caching-subgraph-provider.d.ts +19 -0
  312. package/build/module/providers/v3/caching-subgraph-provider.js +20 -0
  313. package/build/module/providers/v3/gas-data-provider.d.ts +39 -0
  314. package/build/module/providers/v3/gas-data-provider.js +22 -0
  315. package/build/module/providers/v3/pool-provider.d.ts +77 -0
  316. package/build/module/providers/v3/pool-provider.js +101 -0
  317. package/build/module/providers/v3/static-subgraph-provider.d.ts +21 -0
  318. package/build/module/providers/v3/static-subgraph-provider.js +82 -0
  319. package/build/module/providers/v3/subgraph-provider-with-fallback.d.ts +12 -0
  320. package/build/module/providers/v3/subgraph-provider-with-fallback.js +15 -0
  321. package/build/module/providers/v3/subgraph-provider.d.ts +46 -0
  322. package/build/module/providers/v3/subgraph-provider.js +50 -0
  323. package/build/module/providers/v3/uri-subgraph-provider.d.ts +4 -0
  324. package/build/module/providers/v3/uri-subgraph-provider.js +4 -0
  325. package/build/module/routers/alpha-router/alpha-router.d.ts +347 -0
  326. package/build/module/routers/alpha-router/alpha-router.js +1229 -0
  327. package/build/module/routers/alpha-router/config.d.ts +4 -0
  328. package/build/module/routers/alpha-router/config.js +36 -0
  329. package/build/module/routers/alpha-router/entities/index.d.ts +1 -0
  330. package/build/module/routers/alpha-router/entities/index.js +2 -0
  331. package/build/module/routers/alpha-router/entities/route-with-valid-quote.d.ts +167 -0
  332. package/build/module/routers/alpha-router/entities/route-with-valid-quote.js +157 -0
  333. package/build/module/routers/alpha-router/functions/best-swap-route.d.ts +22 -0
  334. package/build/module/routers/alpha-router/functions/best-swap-route.js +526 -0
  335. package/build/module/routers/alpha-router/functions/calculate-ratio-amount-in.d.ts +3 -0
  336. package/build/module/routers/alpha-router/functions/calculate-ratio-amount-in.js +14 -0
  337. package/build/module/routers/alpha-router/functions/compute-all-routes.d.ts +9 -0
  338. package/build/module/routers/alpha-router/functions/compute-all-routes.js +97 -0
  339. package/build/module/routers/alpha-router/functions/get-candidate-pools.d.ts +100 -0
  340. package/build/module/routers/alpha-router/functions/get-candidate-pools.js +998 -0
  341. package/build/module/routers/alpha-router/gas-models/gas-costs.d.ts +12 -0
  342. package/build/module/routers/alpha-router/gas-models/gas-costs.js +79 -0
  343. package/build/module/routers/alpha-router/gas-models/gas-model.d.ts +106 -0
  344. package/build/module/routers/alpha-router/gas-models/gas-model.js +102 -0
  345. package/build/module/routers/alpha-router/gas-models/index.d.ts +2 -0
  346. package/build/module/routers/alpha-router/gas-models/index.js +3 -0
  347. package/build/module/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.d.ts +24 -0
  348. package/build/module/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.js +154 -0
  349. package/build/module/routers/alpha-router/gas-models/tick-based-heuristic-gas-model.d.ts +15 -0
  350. package/build/module/routers/alpha-router/gas-models/tick-based-heuristic-gas-model.js +181 -0
  351. package/build/module/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.d.ts +31 -0
  352. package/build/module/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.js +162 -0
  353. package/build/module/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.d.ts +26 -0
  354. package/build/module/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.js +37 -0
  355. package/build/module/routers/alpha-router/index.d.ts +4 -0
  356. package/build/module/routers/alpha-router/index.js +5 -0
  357. package/build/module/routers/alpha-router/quoters/base-quoter.d.ts +76 -0
  358. package/build/module/routers/alpha-router/quoters/base-quoter.js +69 -0
  359. package/build/module/routers/alpha-router/quoters/index.d.ts +5 -0
  360. package/build/module/routers/alpha-router/quoters/index.js +6 -0
  361. package/build/module/routers/alpha-router/quoters/mixed-quoter.d.ts +28 -0
  362. package/build/module/routers/alpha-router/quoters/mixed-quoter.js +152 -0
  363. package/build/module/routers/alpha-router/quoters/model/index.d.ts +1 -0
  364. package/build/module/routers/alpha-router/quoters/model/index.js +2 -0
  365. package/build/module/routers/alpha-router/quoters/model/results/get-quotes-result.d.ts +6 -0
  366. package/build/module/routers/alpha-router/quoters/model/results/get-quotes-result.js +2 -0
  367. package/build/module/routers/alpha-router/quoters/model/results/get-routes-result.d.ts +6 -0
  368. package/build/module/routers/alpha-router/quoters/model/results/get-routes-result.js +2 -0
  369. package/build/module/routers/alpha-router/quoters/model/results/index.d.ts +2 -0
  370. package/build/module/routers/alpha-router/quoters/model/results/index.js +3 -0
  371. package/build/module/routers/alpha-router/quoters/v2-quoter.d.ts +24 -0
  372. package/build/module/routers/alpha-router/quoters/v2-quoter.js +137 -0
  373. package/build/module/routers/alpha-router/quoters/v3-quoter.d.ts +19 -0
  374. package/build/module/routers/alpha-router/quoters/v3-quoter.js +110 -0
  375. package/build/module/routers/index.d.ts +3 -0
  376. package/build/module/routers/index.js +4 -0
  377. package/build/module/routers/router.d.ts +186 -0
  378. package/build/module/routers/router.js +47 -0
  379. package/build/module/tsconfig.module.tsbuildinfo +1 -0
  380. package/build/module/types/other/commons.d.ts +16 -0
  381. package/build/module/types/other/commons.js +5 -0
  382. package/build/module/types/other/factories/Erc20__factory.d.ts +45 -0
  383. package/build/module/types/other/factories/Erc20__factory.js +236 -0
  384. package/build/module/types/other/factories/GasDataArbitrum__factory.d.ts +18 -0
  385. package/build/module/types/other/factories/GasDataArbitrum__factory.js +54 -0
  386. package/build/module/types/other/factories/IMixedRouteQuoterV1__factory.d.ts +41 -0
  387. package/build/module/types/other/factories/IMixedRouteQuoterV1__factory.js +152 -0
  388. package/build/module/types/other/factories/ITokenValidator__factory.d.ts +22 -0
  389. package/build/module/types/other/factories/ITokenValidator__factory.js +74 -0
  390. package/build/module/types/other/factories/MixedRouteQuoterV2__factory.d.ts +86 -0
  391. package/build/module/types/other/factories/MixedRouteQuoterV2__factory.js +473 -0
  392. package/build/module/types/other/factories/Permit2__factory.d.ts +87 -0
  393. package/build/module/types/other/factories/Permit2__factory.js +932 -0
  394. package/build/module/types/other/factories/SwapRouter02__factory.d.ts +67 -0
  395. package/build/module/types/other/factories/SwapRouter02__factory.js +1094 -0
  396. package/build/module/types/other/factories/TokenFeeDetector__factory.d.ts +47 -0
  397. package/build/module/types/other/factories/TokenFeeDetector__factory.js +239 -0
  398. package/build/module/types/v2/commons.d.ts +16 -0
  399. package/build/module/types/v2/commons.js +5 -0
  400. package/build/module/types/v2/factories/IUniswapV2Pair__factory.d.ts +35 -0
  401. package/build/module/types/v2/factories/IUniswapV2Pair__factory.js +667 -0
  402. package/build/module/types/v3/commons.d.ts +16 -0
  403. package/build/module/types/v3/commons.js +5 -0
  404. package/build/module/types/v3/factories/IERC20Metadata__factory.d.ts +35 -0
  405. package/build/module/types/v3/factories/IERC20Metadata__factory.js +238 -0
  406. package/build/module/types/v3/factories/IQuoterV2__factory.d.ts +41 -0
  407. package/build/module/types/v3/factories/IQuoterV2__factory.js +216 -0
  408. package/build/module/types/v3/factories/IUniswapV3PoolState__factory.d.ts +22 -0
  409. package/build/module/types/v3/factories/IUniswapV3PoolState__factory.js +262 -0
  410. package/build/module/types/v3/factories/UniswapInterfaceMulticall__factory.d.ts +61 -0
  411. package/build/module/types/v3/factories/UniswapInterfaceMulticall__factory.js +123 -0
  412. package/build/module/util/addresses.d.ts +24 -0
  413. package/build/module/util/addresses.js +69 -0
  414. package/build/module/util/amounts.d.ts +9 -0
  415. package/build/module/util/amounts.js +62 -0
  416. package/build/module/util/chains.d.ts +31 -0
  417. package/build/module/util/chains.js +89 -0
  418. package/build/module/util/gas-factory-helpers.d.ts +33 -0
  419. package/build/module/util/gas-factory-helpers.js +446 -0
  420. package/build/module/util/index.d.ts +7 -0
  421. package/build/module/util/index.js +8 -0
  422. package/build/module/util/l2FeeChains.d.ts +2 -0
  423. package/build/module/util/l2FeeChains.js +10 -0
  424. package/build/module/util/log.d.ts +3 -0
  425. package/build/module/util/log.js +93 -0
  426. package/build/module/util/methodParameters.d.ts +5 -0
  427. package/build/module/util/methodParameters.js +181 -0
  428. package/build/module/util/metric.d.ts +48 -0
  429. package/build/module/util/metric.js +53 -0
  430. package/build/module/util/onchainQuoteProviderConfigs.d.ts +42 -0
  431. package/build/module/util/onchainQuoteProviderConfigs.js +76 -0
  432. package/build/module/util/protocols.d.ts +2 -0
  433. package/build/module/util/protocols.js +16 -0
  434. package/build/module/util/routes.d.ts +11 -0
  435. package/build/module/util/routes.js +137 -0
  436. package/build/module/util/unsupported-tokens.d.ts +37 -0
  437. package/build/module/util/unsupported-tokens.js +1116 -0
  438. package/package.json +133 -0
@@ -0,0 +1,1008 @@
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.getMixedRouteCandidatePools = exports.getV2CandidatePools = exports.getV3CandidatePools = exports.getMixedCrossLiquidityCandidatePools = void 0;
7
+ const router_sdk_1 = require("@fanx-protocol/router-sdk");
8
+ const sdk_core_1 = require("@fanx-protocol/sdk-core");
9
+ const lodash_1 = __importDefault(require("lodash"));
10
+ const token_provider_1 = require("../../../providers/token-provider");
11
+ const util_1 = require("../../../util");
12
+ const amounts_1 = require("../../../util/amounts");
13
+ const log_1 = require("../../../util/log");
14
+ const metric_1 = require("../../../util/metric");
15
+ const baseTokensByChain = {
16
+ [sdk_core_1.ChainId.SPICY]: [util_1.WRAPPED_NATIVE_CURRENCY[sdk_core_1.ChainId.SPICY], token_provider_1.USDC_SPICY],
17
+ [sdk_core_1.ChainId.CHILIZ]: [util_1.WRAPPED_NATIVE_CURRENCY[sdk_core_1.ChainId.CHILIZ], token_provider_1.USDC_CHILIZ],
18
+ };
19
+ class SubcategorySelectionPools {
20
+ constructor(pools, poolsNeeded) {
21
+ this.pools = pools;
22
+ this.poolsNeeded = poolsNeeded;
23
+ }
24
+ hasEnoughPools() {
25
+ return this.pools.length >= this.poolsNeeded;
26
+ }
27
+ }
28
+ /**
29
+ * Function that finds any missing pools that were not selected by the heuristic but that would
30
+ * create a route with the topPool by TVL with either tokenIn or tokenOut across protocols.
31
+ *
32
+ * e.g. In V2CandidatePools we found that wstETH/DOG is the most liquid pool,
33
+ * then in V3CandidatePools ETH/wstETH is *not* the most liquid pool, so it is not selected
34
+ * This process will look for that pool in order to complete the route.
35
+ *
36
+ */
37
+ async function getMixedCrossLiquidityCandidatePools({ tokenIn, tokenOut, blockNumber, v2SubgraphProvider, v3SubgraphProvider, v2Candidates, v3Candidates, }) {
38
+ const v2Pools = (await v2SubgraphProvider.getPools(tokenIn, tokenOut, {
39
+ blockNumber,
40
+ })).sort((a, b) => b.reserve - a.reserve);
41
+ const v3Pools = (await v3SubgraphProvider.getPools(tokenIn, tokenOut, {
42
+ blockNumber,
43
+ })).sort((a, b) => b.tvlUSD - a.tvlUSD);
44
+ const tokenInAddress = tokenIn.address.toLowerCase();
45
+ const tokenOutAddress = tokenOut.address.toLowerCase();
46
+ const v2SelectedPools = findCrossProtocolMissingPools(tokenInAddress, tokenOutAddress, v2Pools, v2Candidates, v3Candidates);
47
+ const v3SelectedPools = findCrossProtocolMissingPools(tokenInAddress, tokenOutAddress, v3Pools, v3Candidates, v2Candidates);
48
+ const selectedV2Pools = [
49
+ v2SelectedPools.forTokenIn,
50
+ v2SelectedPools.forTokenOut,
51
+ ].filter((pool) => pool !== undefined);
52
+ const selectedV3Pools = [
53
+ v3SelectedPools.forTokenIn,
54
+ v3SelectedPools.forTokenOut,
55
+ ].filter((pool) => pool !== undefined);
56
+ return {
57
+ v2Pools: selectedV2Pools,
58
+ v3Pools: selectedV3Pools,
59
+ };
60
+ }
61
+ exports.getMixedCrossLiquidityCandidatePools = getMixedCrossLiquidityCandidatePools;
62
+ function findCrossProtocolMissingPools(tokenInAddress, tokenOutAddress, pools, candidatesInProtocolToSearch, candidatesInContextProtocol) {
63
+ var _a;
64
+ const selectedPools = {};
65
+ const previouslySelectedPools = new Set((_a = candidatesInProtocolToSearch === null || candidatesInProtocolToSearch === void 0 ? void 0 : candidatesInProtocolToSearch.subgraphPools.map((pool) => pool.id)) !== null && _a !== void 0 ? _a : []);
66
+ const topPoolByTvlWithTokenOut = candidatesInContextProtocol === null || candidatesInContextProtocol === void 0 ? void 0 : candidatesInContextProtocol.candidatePools.selections.topByTVLUsingTokenOut[0];
67
+ const crossTokenAgainstTokenOut = (topPoolByTvlWithTokenOut === null || topPoolByTvlWithTokenOut === void 0 ? void 0 : topPoolByTvlWithTokenOut.token0.id.toLowerCase()) === tokenOutAddress
68
+ ? topPoolByTvlWithTokenOut === null || topPoolByTvlWithTokenOut === void 0 ? void 0 : topPoolByTvlWithTokenOut.token1.id.toLowerCase()
69
+ : topPoolByTvlWithTokenOut === null || topPoolByTvlWithTokenOut === void 0 ? void 0 : topPoolByTvlWithTokenOut.token0.id.toLowerCase();
70
+ const topPoolByTvlWithTokenIn = candidatesInContextProtocol === null || candidatesInContextProtocol === void 0 ? void 0 : candidatesInContextProtocol.candidatePools.selections.topByTVLUsingTokenIn[0];
71
+ const crossTokenAgainstTokenIn = (topPoolByTvlWithTokenIn === null || topPoolByTvlWithTokenIn === void 0 ? void 0 : topPoolByTvlWithTokenIn.token0.id.toLowerCase()) === tokenInAddress
72
+ ? topPoolByTvlWithTokenIn === null || topPoolByTvlWithTokenIn === void 0 ? void 0 : topPoolByTvlWithTokenIn.token1.id.toLowerCase()
73
+ : topPoolByTvlWithTokenIn === null || topPoolByTvlWithTokenIn === void 0 ? void 0 : topPoolByTvlWithTokenIn.token0.id.toLowerCase();
74
+ for (const pool of pools) {
75
+ // If we already found both pools for tokenIn and tokenOut. break out of this for loop.
76
+ if (selectedPools.forTokenIn !== undefined &&
77
+ selectedPools.forTokenOut !== undefined) {
78
+ break;
79
+ }
80
+ // If the pool has already been selected. continue to the next pool.
81
+ if (previouslySelectedPools.has(pool.id.toLowerCase())) {
82
+ continue;
83
+ }
84
+ const poolToken0Address = pool.token0.id.toLowerCase();
85
+ const poolToken1Address = pool.token1.id.toLowerCase();
86
+ // If we haven't selected the pool for tokenIn, and we found a pool matching the tokenOut, and the intermediateToken, select this pool
87
+ if (selectedPools.forTokenIn === undefined &&
88
+ ((poolToken0Address === tokenOutAddress &&
89
+ poolToken1Address === crossTokenAgainstTokenIn) ||
90
+ (poolToken1Address === tokenOutAddress &&
91
+ poolToken0Address === crossTokenAgainstTokenIn))) {
92
+ selectedPools.forTokenIn = pool;
93
+ }
94
+ // If we haven't selected the pool for tokenOut, and we found a pool matching the tokenIn, and the intermediateToken, select this pool
95
+ if (selectedPools.forTokenOut === undefined &&
96
+ ((poolToken0Address === tokenInAddress &&
97
+ poolToken1Address === crossTokenAgainstTokenOut) ||
98
+ (poolToken1Address === tokenInAddress &&
99
+ poolToken0Address === crossTokenAgainstTokenOut))) {
100
+ selectedPools.forTokenOut = pool;
101
+ }
102
+ }
103
+ return selectedPools;
104
+ }
105
+ async function getV3CandidatePools({ tokenIn, tokenOut,
106
+ // routeType,
107
+ routingConfig, subgraphProvider, tokenProvider, poolProvider, blockedTokenListProvider, chainId, }) {
108
+ var _a;
109
+ const { blockNumber, v3PoolSelection: { topN, topNDirectSwaps, topNTokenInOut, topNSecondHop, topNSecondHopForTokenAddress, tokensToAvoidOnSecondHops, topNWithEachBaseToken, topNWithBaseToken, }, } = routingConfig;
110
+ const tokenInAddress = tokenIn.address.toLowerCase();
111
+ const tokenOutAddress = tokenOut.address.toLowerCase();
112
+ const beforeSubgraphPools = Date.now();
113
+ const allPools = await subgraphProvider.getPools(tokenIn, tokenOut, {
114
+ blockNumber,
115
+ });
116
+ log_1.log.info({ samplePools: allPools.slice(0, 3) }, 'Got all pools from V3 subgraph provider');
117
+ // Although this is less of an optimization than the V2 equivalent,
118
+ // save some time copying objects by mutating the underlying pool directly.
119
+ for (const pool of allPools) {
120
+ pool.token0.id = pool.token0.id.toLowerCase();
121
+ pool.token1.id = pool.token1.id.toLowerCase();
122
+ }
123
+ metric_1.metric.putMetric('V3SubgraphPoolsLoad', Date.now() - beforeSubgraphPools, metric_1.MetricLoggerUnit.Milliseconds);
124
+ const beforePoolsFiltered = Date.now();
125
+ // Only consider pools where neither tokens are in the blocked token list.
126
+ let filteredPools = allPools;
127
+ if (blockedTokenListProvider) {
128
+ filteredPools = [];
129
+ for (const pool of allPools) {
130
+ const token0InBlocklist = await blockedTokenListProvider.hasTokenByAddress(pool.token0.id);
131
+ const token1InBlocklist = await blockedTokenListProvider.hasTokenByAddress(pool.token1.id);
132
+ if (token0InBlocklist || token1InBlocklist) {
133
+ continue;
134
+ }
135
+ filteredPools.push(pool);
136
+ }
137
+ }
138
+ // Sort by tvlUSD in descending order
139
+ const subgraphPoolsSorted = filteredPools.sort((a, b) => b.tvlUSD - a.tvlUSD);
140
+ log_1.log.info(`After filtering blocked tokens went from ${allPools.length} to ${subgraphPoolsSorted.length}.`);
141
+ const poolAddressesSoFar = new Set();
142
+ const addToAddressSet = (pools) => {
143
+ (0, lodash_1.default)(pools)
144
+ .map((pool) => pool.id)
145
+ .forEach((poolAddress) => poolAddressesSoFar.add(poolAddress));
146
+ };
147
+ const baseTokens = (_a = baseTokensByChain[chainId]) !== null && _a !== void 0 ? _a : [];
148
+ const topByBaseWithTokenIn = (0, lodash_1.default)(baseTokens)
149
+ .flatMap((token) => {
150
+ return (0, lodash_1.default)(subgraphPoolsSorted)
151
+ .filter((subgraphPool) => {
152
+ const tokenAddress = token.address.toLowerCase();
153
+ return ((subgraphPool.token0.id == tokenAddress &&
154
+ subgraphPool.token1.id == tokenInAddress) ||
155
+ (subgraphPool.token1.id == tokenAddress &&
156
+ subgraphPool.token0.id == tokenInAddress));
157
+ })
158
+ .sortBy((tokenListPool) => -tokenListPool.tvlUSD)
159
+ .slice(0, topNWithEachBaseToken)
160
+ .value();
161
+ })
162
+ .sortBy((tokenListPool) => -tokenListPool.tvlUSD)
163
+ .slice(0, topNWithBaseToken)
164
+ .value();
165
+ const topByBaseWithTokenOut = (0, lodash_1.default)(baseTokens)
166
+ .flatMap((token) => {
167
+ return (0, lodash_1.default)(subgraphPoolsSorted)
168
+ .filter((subgraphPool) => {
169
+ const tokenAddress = token.address.toLowerCase();
170
+ return ((subgraphPool.token0.id == tokenAddress &&
171
+ subgraphPool.token1.id == tokenOutAddress) ||
172
+ (subgraphPool.token1.id == tokenAddress &&
173
+ subgraphPool.token0.id == tokenOutAddress));
174
+ })
175
+ .sortBy((tokenListPool) => -tokenListPool.tvlUSD)
176
+ .slice(0, topNWithEachBaseToken)
177
+ .value();
178
+ })
179
+ .sortBy((tokenListPool) => -tokenListPool.tvlUSD)
180
+ .slice(0, topNWithBaseToken)
181
+ .value();
182
+ let top2DirectSwapPool = (0, lodash_1.default)(subgraphPoolsSorted)
183
+ .filter((subgraphPool) => {
184
+ return (!poolAddressesSoFar.has(subgraphPool.id) &&
185
+ ((subgraphPool.token0.id == tokenInAddress &&
186
+ subgraphPool.token1.id == tokenOutAddress) ||
187
+ (subgraphPool.token1.id == tokenInAddress &&
188
+ subgraphPool.token0.id == tokenOutAddress)));
189
+ })
190
+ .slice(0, topNDirectSwaps)
191
+ .value();
192
+ if (top2DirectSwapPool.length == 0 && topNDirectSwaps > 0) {
193
+ // If we requested direct swap pools but did not find any in the subgraph query.
194
+ // Optimistically add them into the query regardless. Invalid pools ones will be dropped anyway
195
+ // when we query the pool on-chain. Ensures that new pools for new pairs can be swapped on immediately.
196
+ top2DirectSwapPool = lodash_1.default.map((0, util_1.getApplicableV3FeeAmounts)(chainId), (feeAmount) => {
197
+ const { token0, token1, poolAddress } = poolProvider.getPoolAddress(tokenIn, tokenOut, feeAmount);
198
+ return {
199
+ id: poolAddress,
200
+ feeTier: (0, util_1.unparseFeeAmount)(feeAmount),
201
+ liquidity: '10000',
202
+ token0: {
203
+ id: token0.address,
204
+ },
205
+ token1: {
206
+ id: token1.address,
207
+ },
208
+ tvlETH: 10000,
209
+ tvlUSD: 10000,
210
+ };
211
+ });
212
+ }
213
+ addToAddressSet(top2DirectSwapPool);
214
+ // const wrappedNativeAddress =
215
+ // WRAPPED_NATIVE_CURRENCY[chainId]?.address.toLowerCase();
216
+ // Main reason we need this is for gas estimates, only needed if token out is not native.
217
+ // We don't check the seen address set because if we've already added pools for getting native quotes
218
+ // theres no need to add more.
219
+ let top2EthQuoteTokenPool = [];
220
+ // if (
221
+ // (WRAPPED_NATIVE_CURRENCY[chainId]?.symbol == WRAPPED_NATIVE_CURRENCY[ChainId.MAINNET]?.symbol &&
222
+ // tokenOut.symbol != 'WETH' &&
223
+ // tokenOut.symbol != 'WETH9' &&
224
+ // tokenOut.symbol != 'ETH') ||
225
+ // (WRAPPED_NATIVE_CURRENCY[chainId]?.symbol == WMATIC_POLYGON.symbol &&
226
+ // tokenOut.symbol != 'MATIC' &&
227
+ // tokenOut.symbol != 'WMATIC')
228
+ // ) {
229
+ // top2EthQuoteTokenPool = _(subgraphPoolsSorted)
230
+ // .filter((subgraphPool) => {
231
+ // if (routeType == TradeType.EXACT_INPUT) {
232
+ // return (
233
+ // (subgraphPool.token0.id == wrappedNativeAddress &&
234
+ // subgraphPool.token1.id == tokenOutAddress) ||
235
+ // (subgraphPool.token1.id == wrappedNativeAddress &&
236
+ // subgraphPool.token0.id == tokenOutAddress)
237
+ // );
238
+ // } else {
239
+ // return (
240
+ // (subgraphPool.token0.id == wrappedNativeAddress &&
241
+ // subgraphPool.token1.id == tokenInAddress) ||
242
+ // (subgraphPool.token1.id == wrappedNativeAddress &&
243
+ // subgraphPool.token0.id == tokenInAddress)
244
+ // );
245
+ // }
246
+ // })
247
+ // .slice(0, 1)
248
+ // .value();
249
+ // }
250
+ addToAddressSet(top2EthQuoteTokenPool);
251
+ const topByTVL = (0, lodash_1.default)(subgraphPoolsSorted)
252
+ .filter((subgraphPool) => {
253
+ return !poolAddressesSoFar.has(subgraphPool.id);
254
+ })
255
+ .slice(0, topN)
256
+ .value();
257
+ addToAddressSet(topByTVL);
258
+ const topByTVLUsingTokenIn = (0, lodash_1.default)(subgraphPoolsSorted)
259
+ .filter((subgraphPool) => {
260
+ return (!poolAddressesSoFar.has(subgraphPool.id) &&
261
+ (subgraphPool.token0.id == tokenInAddress ||
262
+ subgraphPool.token1.id == tokenInAddress));
263
+ })
264
+ .slice(0, topNTokenInOut)
265
+ .value();
266
+ addToAddressSet(topByTVLUsingTokenIn);
267
+ const topByTVLUsingTokenOut = (0, lodash_1.default)(subgraphPoolsSorted)
268
+ .filter((subgraphPool) => {
269
+ return (!poolAddressesSoFar.has(subgraphPool.id) &&
270
+ (subgraphPool.token0.id == tokenOutAddress ||
271
+ subgraphPool.token1.id == tokenOutAddress));
272
+ })
273
+ .slice(0, topNTokenInOut)
274
+ .value();
275
+ addToAddressSet(topByTVLUsingTokenOut);
276
+ const topByTVLUsingTokenInSecondHops = (0, lodash_1.default)(topByTVLUsingTokenIn)
277
+ .map((subgraphPool) => {
278
+ return tokenInAddress == subgraphPool.token0.id
279
+ ? subgraphPool.token1.id
280
+ : subgraphPool.token0.id;
281
+ })
282
+ .flatMap((secondHopId) => {
283
+ var _a;
284
+ return (0, lodash_1.default)(subgraphPoolsSorted)
285
+ .filter((subgraphPool) => {
286
+ return (!poolAddressesSoFar.has(subgraphPool.id) &&
287
+ !(tokensToAvoidOnSecondHops === null || tokensToAvoidOnSecondHops === void 0 ? void 0 : tokensToAvoidOnSecondHops.includes(secondHopId.toLowerCase())) &&
288
+ (subgraphPool.token0.id == secondHopId ||
289
+ subgraphPool.token1.id == secondHopId));
290
+ })
291
+ .slice(0, (_a = topNSecondHopForTokenAddress === null || topNSecondHopForTokenAddress === void 0 ? void 0 : topNSecondHopForTokenAddress.get(secondHopId)) !== null && _a !== void 0 ? _a : topNSecondHop)
292
+ .value();
293
+ })
294
+ .uniqBy((pool) => pool.id)
295
+ .value();
296
+ addToAddressSet(topByTVLUsingTokenInSecondHops);
297
+ const topByTVLUsingTokenOutSecondHops = (0, lodash_1.default)(topByTVLUsingTokenOut)
298
+ .map((subgraphPool) => {
299
+ return tokenOutAddress == subgraphPool.token0.id
300
+ ? subgraphPool.token1.id
301
+ : subgraphPool.token0.id;
302
+ })
303
+ .flatMap((secondHopId) => {
304
+ var _a;
305
+ return (0, lodash_1.default)(subgraphPoolsSorted)
306
+ .filter((subgraphPool) => {
307
+ return (!poolAddressesSoFar.has(subgraphPool.id) &&
308
+ !(tokensToAvoidOnSecondHops === null || tokensToAvoidOnSecondHops === void 0 ? void 0 : tokensToAvoidOnSecondHops.includes(secondHopId.toLowerCase())) &&
309
+ (subgraphPool.token0.id == secondHopId ||
310
+ subgraphPool.token1.id == secondHopId));
311
+ })
312
+ .slice(0, (_a = topNSecondHopForTokenAddress === null || topNSecondHopForTokenAddress === void 0 ? void 0 : topNSecondHopForTokenAddress.get(secondHopId)) !== null && _a !== void 0 ? _a : topNSecondHop)
313
+ .value();
314
+ })
315
+ .uniqBy((pool) => pool.id)
316
+ .value();
317
+ addToAddressSet(topByTVLUsingTokenOutSecondHops);
318
+ const subgraphPools = (0, lodash_1.default)([
319
+ ...topByBaseWithTokenIn,
320
+ ...topByBaseWithTokenOut,
321
+ ...top2DirectSwapPool,
322
+ ...top2EthQuoteTokenPool,
323
+ ...topByTVL,
324
+ ...topByTVLUsingTokenIn,
325
+ ...topByTVLUsingTokenOut,
326
+ ...topByTVLUsingTokenInSecondHops,
327
+ ...topByTVLUsingTokenOutSecondHops,
328
+ ])
329
+ .compact()
330
+ .uniqBy((pool) => pool.id)
331
+ .value();
332
+ const tokenAddresses = (0, lodash_1.default)(subgraphPools)
333
+ .flatMap((subgraphPool) => [subgraphPool.token0.id, subgraphPool.token1.id])
334
+ .compact()
335
+ .uniq()
336
+ .value();
337
+ log_1.log.info(`Getting the ${tokenAddresses.length} tokens within the ${subgraphPools.length} V3 pools we are considering`);
338
+ const tokenAccessor = await tokenProvider.getTokens(tokenAddresses, {
339
+ blockNumber,
340
+ });
341
+ const printV3SubgraphPool = (s) => {
342
+ var _a, _b, _c, _d;
343
+ return `${(_b = (_a = tokenAccessor.getTokenByAddress(s.token0.id)) === null || _a === void 0 ? void 0 : _a.symbol) !== null && _b !== void 0 ? _b : s.token0.id}/${(_d = (_c = tokenAccessor.getTokenByAddress(s.token1.id)) === null || _c === void 0 ? void 0 : _c.symbol) !== null && _d !== void 0 ? _d : s.token1.id}/${s.feeTier}`;
344
+ };
345
+ log_1.log.info({
346
+ topByBaseWithTokenIn: topByBaseWithTokenIn.map(printV3SubgraphPool),
347
+ topByBaseWithTokenOut: topByBaseWithTokenOut.map(printV3SubgraphPool),
348
+ topByTVL: topByTVL.map(printV3SubgraphPool),
349
+ topByTVLUsingTokenIn: topByTVLUsingTokenIn.map(printV3SubgraphPool),
350
+ topByTVLUsingTokenOut: topByTVLUsingTokenOut.map(printV3SubgraphPool),
351
+ topByTVLUsingTokenInSecondHops: topByTVLUsingTokenInSecondHops.map(printV3SubgraphPool),
352
+ topByTVLUsingTokenOutSecondHops: topByTVLUsingTokenOutSecondHops.map(printV3SubgraphPool),
353
+ top2DirectSwap: top2DirectSwapPool.map(printV3SubgraphPool),
354
+ top2EthQuotePool: top2EthQuoteTokenPool.map(printV3SubgraphPool),
355
+ }, `V3 Candidate Pools`);
356
+ const tokenPairsRaw = lodash_1.default.map(subgraphPools, (subgraphPool) => {
357
+ const tokenA = tokenAccessor.getTokenByAddress(subgraphPool.token0.id);
358
+ const tokenB = tokenAccessor.getTokenByAddress(subgraphPool.token1.id);
359
+ let fee;
360
+ try {
361
+ fee = (0, amounts_1.parseFeeAmount)(subgraphPool.feeTier);
362
+ }
363
+ catch (err) {
364
+ log_1.log.info({ subgraphPool }, `Dropping candidate pool for ${subgraphPool.token0.id}/${subgraphPool.token1.id}/${subgraphPool.feeTier} because fee tier not supported`);
365
+ return undefined;
366
+ }
367
+ if (!tokenA || !tokenB) {
368
+ log_1.log.info(`Dropping candidate pool for ${subgraphPool.token0.id}/${subgraphPool.token1.id}/${fee} because ${tokenA ? subgraphPool.token1.id : subgraphPool.token0.id} not found by token provider`);
369
+ return undefined;
370
+ }
371
+ return [tokenA, tokenB, fee];
372
+ });
373
+ const tokenPairs = lodash_1.default.compact(tokenPairsRaw);
374
+ metric_1.metric.putMetric('V3PoolsFilterLoad', Date.now() - beforePoolsFiltered, metric_1.MetricLoggerUnit.Milliseconds);
375
+ const beforePoolsLoad = Date.now();
376
+ const poolAccessor = await poolProvider.getPools(tokenPairs, {
377
+ blockNumber,
378
+ });
379
+ metric_1.metric.putMetric('V3PoolsLoad', Date.now() - beforePoolsLoad, metric_1.MetricLoggerUnit.Milliseconds);
380
+ const poolsBySelection = {
381
+ protocol: router_sdk_1.Protocol.V3,
382
+ selections: {
383
+ topByBaseWithTokenIn,
384
+ topByBaseWithTokenOut,
385
+ topByDirectSwapPool: top2DirectSwapPool,
386
+ topByEthQuoteTokenPool: top2EthQuoteTokenPool,
387
+ topByTVL,
388
+ topByTVLUsingTokenIn,
389
+ topByTVLUsingTokenOut,
390
+ topByTVLUsingTokenInSecondHops,
391
+ topByTVLUsingTokenOutSecondHops,
392
+ },
393
+ };
394
+ return { poolAccessor, candidatePools: poolsBySelection, subgraphPools };
395
+ }
396
+ exports.getV3CandidatePools = getV3CandidatePools;
397
+ async function getV2CandidatePools({ tokenIn, tokenOut, routeType, routingConfig, subgraphProvider, tokenProvider, poolProvider, blockedTokenListProvider, chainId, }) {
398
+ var _a, _b;
399
+ const { blockNumber, v2PoolSelection: { topN, topNDirectSwaps, topNTokenInOut, topNSecondHop, tokensToAvoidOnSecondHops, topNWithEachBaseToken, topNWithBaseToken, }, } = routingConfig;
400
+ const tokenInAddress = tokenIn.address.toLowerCase();
401
+ const tokenOutAddress = tokenOut.address.toLowerCase();
402
+ const beforeSubgraphPools = Date.now();
403
+ const allPoolsRaw = await subgraphProvider.getPools(tokenIn, tokenOut, {
404
+ blockNumber,
405
+ });
406
+ // With tens of thousands of V2 pools, operations that copy pools become costly.
407
+ // Mutate the pool directly rather than creating a new pool / token to optimmize for speed.
408
+ for (const pool of allPoolsRaw) {
409
+ pool.token0.id = pool.token0.id.toLowerCase();
410
+ pool.token1.id = pool.token1.id.toLowerCase();
411
+ }
412
+ metric_1.metric.putMetric('V2SubgraphPoolsLoad', Date.now() - beforeSubgraphPools, metric_1.MetricLoggerUnit.Milliseconds);
413
+ const beforePoolsFiltered = Date.now();
414
+ // Sort by pool reserve in descending order.
415
+ const subgraphPoolsSorted = allPoolsRaw.sort((a, b) => b.reserve - a.reserve);
416
+ const poolAddressesSoFar = new Set();
417
+ // Always add the direct swap pool into the mix regardless of if it exists in the subgraph pool list.
418
+ // Ensures that new pools can be swapped on immediately, and that if a pool was filtered out of the
419
+ // subgraph query for some reason (e.g. trackedReserveETH was 0), then we still consider it.
420
+ let topByDirectSwapPool = [];
421
+ if (topNDirectSwaps > 0) {
422
+ const { token0, token1, poolAddress } = poolProvider.getPoolAddress(tokenIn, tokenOut);
423
+ poolAddressesSoFar.add(poolAddress.toLowerCase());
424
+ topByDirectSwapPool = [
425
+ {
426
+ id: poolAddress,
427
+ token0: {
428
+ id: token0.address,
429
+ },
430
+ token1: {
431
+ id: token1.address,
432
+ },
433
+ supply: 10000,
434
+ reserve: 10000,
435
+ reserveUSD: 10000, // Not used. Set to arbitrary number.
436
+ },
437
+ ];
438
+ }
439
+ const wethAddress = util_1.WRAPPED_NATIVE_CURRENCY[chainId].address.toLowerCase();
440
+ const topByBaseWithTokenInMap = new Map();
441
+ const topByBaseWithTokenOutMap = new Map();
442
+ const baseTokens = (_a = baseTokensByChain[chainId]) !== null && _a !== void 0 ? _a : [];
443
+ const baseTokensAddresses = new Set();
444
+ baseTokens.forEach((token) => {
445
+ const baseTokenAddr = token.address.toLowerCase();
446
+ baseTokensAddresses.add(baseTokenAddr);
447
+ topByBaseWithTokenInMap.set(baseTokenAddr, new SubcategorySelectionPools([], topNWithEachBaseToken));
448
+ topByBaseWithTokenOutMap.set(baseTokenAddr, new SubcategorySelectionPools([], topNWithEachBaseToken));
449
+ });
450
+ let topByBaseWithTokenInPoolsFound = 0;
451
+ let topByBaseWithTokenOutPoolsFound = 0;
452
+ // Main reason we need this is for gas estimates
453
+ // There can ever only be 1 Token/ETH pool, so we will only look for 1
454
+ let topNEthQuoteToken = 1;
455
+ // but, we only need it if token out is not ETH.
456
+ if (tokenOut.symbol == 'WETH' ||
457
+ tokenOut.symbol == 'WETH9' ||
458
+ tokenOut.symbol == 'ETH' ||
459
+ tokenOut.symbol == 'CHZ' ||
460
+ ((_b = tokenOut.symbol) === null || _b === void 0 ? void 0 : _b.toLowerCase()) == 'wchz') {
461
+ // if it's eth we change the topN to 0, so we can break early from the loop.
462
+ topNEthQuoteToken = 0;
463
+ }
464
+ const topByEthQuoteTokenPool = [];
465
+ const topByTVLUsingTokenIn = [];
466
+ const topByTVLUsingTokenOut = [];
467
+ const topByTVL = [];
468
+ // Used to track how many iterations we do in the first loop
469
+ let loopsInFirstIteration = 0;
470
+ // Filtering step for up to first hop
471
+ // The pools are pre-sorted, so we can just iterate through them and fill our heuristics.
472
+ for (const subgraphPool of subgraphPoolsSorted) {
473
+ loopsInFirstIteration += 1;
474
+ // Check if we have satisfied all the heuristics, if so, we can stop.
475
+ if (topByBaseWithTokenInPoolsFound >= topNWithBaseToken &&
476
+ topByBaseWithTokenOutPoolsFound >= topNWithBaseToken &&
477
+ topByEthQuoteTokenPool.length >= topNEthQuoteToken &&
478
+ topByTVL.length >= topN &&
479
+ topByTVLUsingTokenIn.length >= topNTokenInOut &&
480
+ topByTVLUsingTokenOut.length >= topNTokenInOut) {
481
+ // We have satisfied all the heuristics, so we can stop.
482
+ break;
483
+ }
484
+ if (poolAddressesSoFar.has(subgraphPool.id)) {
485
+ // We've already added this pool, so skip it.
486
+ continue;
487
+ }
488
+ // Only consider pools where neither tokens are in the blocked token list.
489
+ if (blockedTokenListProvider) {
490
+ const [token0InBlocklist, token1InBlocklist] = await Promise.all([
491
+ blockedTokenListProvider.hasTokenByAddress(subgraphPool.token0.id),
492
+ blockedTokenListProvider.hasTokenByAddress(subgraphPool.token1.id),
493
+ ]);
494
+ if (token0InBlocklist || token1InBlocklist) {
495
+ continue;
496
+ }
497
+ }
498
+ const tokenInToken0TopByBase = topByBaseWithTokenInMap.get(subgraphPool.token0.id);
499
+ if (topByBaseWithTokenInPoolsFound < topNWithBaseToken &&
500
+ tokenInToken0TopByBase &&
501
+ subgraphPool.token0.id != tokenOutAddress &&
502
+ subgraphPool.token1.id == tokenInAddress) {
503
+ topByBaseWithTokenInPoolsFound += 1;
504
+ poolAddressesSoFar.add(subgraphPool.id);
505
+ if (topByTVLUsingTokenIn.length < topNTokenInOut) {
506
+ topByTVLUsingTokenIn.push(subgraphPool);
507
+ }
508
+ if (routeType === sdk_core_1.TradeType.EXACT_OUTPUT &&
509
+ subgraphPool.token0.id == wethAddress) {
510
+ topByEthQuoteTokenPool.push(subgraphPool);
511
+ }
512
+ tokenInToken0TopByBase.pools.push(subgraphPool);
513
+ continue;
514
+ }
515
+ const tokenInToken1TopByBase = topByBaseWithTokenInMap.get(subgraphPool.token1.id);
516
+ if (topByBaseWithTokenInPoolsFound < topNWithBaseToken &&
517
+ tokenInToken1TopByBase &&
518
+ subgraphPool.token0.id == tokenInAddress &&
519
+ subgraphPool.token1.id != tokenOutAddress) {
520
+ topByBaseWithTokenInPoolsFound += 1;
521
+ poolAddressesSoFar.add(subgraphPool.id);
522
+ if (topByTVLUsingTokenIn.length < topNTokenInOut) {
523
+ topByTVLUsingTokenIn.push(subgraphPool);
524
+ }
525
+ if (routeType === sdk_core_1.TradeType.EXACT_OUTPUT &&
526
+ subgraphPool.token1.id == wethAddress) {
527
+ topByEthQuoteTokenPool.push(subgraphPool);
528
+ }
529
+ tokenInToken1TopByBase.pools.push(subgraphPool);
530
+ continue;
531
+ }
532
+ const tokenOutToken0TopByBase = topByBaseWithTokenOutMap.get(subgraphPool.token0.id);
533
+ if (topByBaseWithTokenOutPoolsFound < topNWithBaseToken &&
534
+ tokenOutToken0TopByBase &&
535
+ subgraphPool.token0.id != tokenInAddress &&
536
+ subgraphPool.token1.id == tokenOutAddress) {
537
+ topByBaseWithTokenOutPoolsFound += 1;
538
+ poolAddressesSoFar.add(subgraphPool.id);
539
+ if (topByTVLUsingTokenOut.length < topNTokenInOut) {
540
+ topByTVLUsingTokenOut.push(subgraphPool);
541
+ }
542
+ if (routeType === sdk_core_1.TradeType.EXACT_INPUT &&
543
+ subgraphPool.token0.id == wethAddress) {
544
+ topByEthQuoteTokenPool.push(subgraphPool);
545
+ }
546
+ tokenOutToken0TopByBase.pools.push(subgraphPool);
547
+ continue;
548
+ }
549
+ const tokenOutToken1TopByBase = topByBaseWithTokenOutMap.get(subgraphPool.token1.id);
550
+ if (topByBaseWithTokenOutPoolsFound < topNWithBaseToken &&
551
+ tokenOutToken1TopByBase &&
552
+ subgraphPool.token0.id == tokenOutAddress &&
553
+ subgraphPool.token1.id != tokenInAddress) {
554
+ topByBaseWithTokenOutPoolsFound += 1;
555
+ poolAddressesSoFar.add(subgraphPool.id);
556
+ if (topByTVLUsingTokenOut.length < topNTokenInOut) {
557
+ topByTVLUsingTokenOut.push(subgraphPool);
558
+ }
559
+ if (routeType === sdk_core_1.TradeType.EXACT_INPUT &&
560
+ subgraphPool.token1.id == wethAddress) {
561
+ topByEthQuoteTokenPool.push(subgraphPool);
562
+ }
563
+ tokenOutToken1TopByBase.pools.push(subgraphPool);
564
+ continue;
565
+ }
566
+ // Note: we do not need to check other native currencies for the V2 Protocol
567
+ if (topByEthQuoteTokenPool.length < topNEthQuoteToken &&
568
+ ((routeType === sdk_core_1.TradeType.EXACT_INPUT &&
569
+ ((subgraphPool.token0.id == wethAddress &&
570
+ subgraphPool.token1.id == tokenOutAddress) ||
571
+ (subgraphPool.token1.id == wethAddress &&
572
+ subgraphPool.token0.id == tokenOutAddress))) ||
573
+ (routeType === sdk_core_1.TradeType.EXACT_OUTPUT &&
574
+ ((subgraphPool.token0.id == wethAddress &&
575
+ subgraphPool.token1.id == tokenInAddress) ||
576
+ (subgraphPool.token1.id == wethAddress &&
577
+ subgraphPool.token0.id == tokenInAddress))))) {
578
+ poolAddressesSoFar.add(subgraphPool.id);
579
+ topByEthQuoteTokenPool.push(subgraphPool);
580
+ continue;
581
+ }
582
+ if (topByTVL.length < topN) {
583
+ poolAddressesSoFar.add(subgraphPool.id);
584
+ topByTVL.push(subgraphPool);
585
+ continue;
586
+ }
587
+ if (topByTVLUsingTokenIn.length < topNTokenInOut &&
588
+ (subgraphPool.token0.id == tokenInAddress ||
589
+ subgraphPool.token1.id == tokenInAddress)) {
590
+ poolAddressesSoFar.add(subgraphPool.id);
591
+ topByTVLUsingTokenIn.push(subgraphPool);
592
+ continue;
593
+ }
594
+ if (topByTVLUsingTokenOut.length < topNTokenInOut &&
595
+ (subgraphPool.token0.id == tokenOutAddress ||
596
+ subgraphPool.token1.id == tokenOutAddress)) {
597
+ poolAddressesSoFar.add(subgraphPool.id);
598
+ topByTVLUsingTokenOut.push(subgraphPool);
599
+ continue;
600
+ }
601
+ }
602
+ metric_1.metric.putMetric('V2SubgraphLoopsInFirstIteration', loopsInFirstIteration, metric_1.MetricLoggerUnit.Count);
603
+ const topByBaseWithTokenIn = [];
604
+ for (const topByBaseWithTokenInSelection of topByBaseWithTokenInMap.values()) {
605
+ topByBaseWithTokenIn.push(...topByBaseWithTokenInSelection.pools);
606
+ }
607
+ const topByBaseWithTokenOut = [];
608
+ for (const topByBaseWithTokenOutSelection of topByBaseWithTokenOutMap.values()) {
609
+ topByBaseWithTokenOut.push(...topByBaseWithTokenOutSelection.pools);
610
+ }
611
+ // Filtering step for second hops
612
+ const topByTVLUsingTokenInSecondHopsMap = new Map();
613
+ const topByTVLUsingTokenOutSecondHopsMap = new Map();
614
+ const tokenInSecondHopAddresses = topByTVLUsingTokenIn
615
+ .filter((pool) => {
616
+ // filtering second hops
617
+ if (tokenInAddress === pool.token0.id) {
618
+ return !(tokensToAvoidOnSecondHops === null || tokensToAvoidOnSecondHops === void 0 ? void 0 : tokensToAvoidOnSecondHops.includes(pool.token1.id.toLowerCase()));
619
+ }
620
+ else {
621
+ return !(tokensToAvoidOnSecondHops === null || tokensToAvoidOnSecondHops === void 0 ? void 0 : tokensToAvoidOnSecondHops.includes(pool.token0.id.toLowerCase()));
622
+ }
623
+ })
624
+ .map((pool) => tokenInAddress === pool.token0.id ? pool.token1.id : pool.token0.id);
625
+ const tokenOutSecondHopAddresses = topByTVLUsingTokenOut
626
+ .filter((pool) => {
627
+ // filtering second hops
628
+ if (tokenOutAddress === pool.token0.id) {
629
+ return !(tokensToAvoidOnSecondHops === null || tokensToAvoidOnSecondHops === void 0 ? void 0 : tokensToAvoidOnSecondHops.includes(pool.token1.id.toLowerCase()));
630
+ }
631
+ else {
632
+ return !(tokensToAvoidOnSecondHops === null || tokensToAvoidOnSecondHops === void 0 ? void 0 : tokensToAvoidOnSecondHops.includes(pool.token0.id.toLowerCase()));
633
+ }
634
+ })
635
+ .map((pool) => tokenOutAddress === pool.token0.id ? pool.token1.id : pool.token0.id);
636
+ for (const secondHopId of tokenInSecondHopAddresses) {
637
+ topByTVLUsingTokenInSecondHopsMap.set(secondHopId, new SubcategorySelectionPools([], topNSecondHop));
638
+ }
639
+ for (const secondHopId of tokenOutSecondHopAddresses) {
640
+ topByTVLUsingTokenOutSecondHopsMap.set(secondHopId, new SubcategorySelectionPools([], topNSecondHop));
641
+ }
642
+ // Used to track how many iterations we do in the second loop
643
+ let loopsInSecondIteration = 0;
644
+ if (tokenInSecondHopAddresses.length > 0 ||
645
+ tokenOutSecondHopAddresses.length > 0) {
646
+ for (const subgraphPool of subgraphPoolsSorted) {
647
+ loopsInSecondIteration += 1;
648
+ let allTokenInSecondHopsHaveTheirTopN = true;
649
+ for (const secondHopPools of topByTVLUsingTokenInSecondHopsMap.values()) {
650
+ if (!secondHopPools.hasEnoughPools()) {
651
+ allTokenInSecondHopsHaveTheirTopN = false;
652
+ break;
653
+ }
654
+ }
655
+ let allTokenOutSecondHopsHaveTheirTopN = true;
656
+ for (const secondHopPools of topByTVLUsingTokenOutSecondHopsMap.values()) {
657
+ if (!secondHopPools.hasEnoughPools()) {
658
+ allTokenOutSecondHopsHaveTheirTopN = false;
659
+ break;
660
+ }
661
+ }
662
+ if (allTokenInSecondHopsHaveTheirTopN &&
663
+ allTokenOutSecondHopsHaveTheirTopN) {
664
+ // We have satisfied all the heuristics, so we can stop.
665
+ break;
666
+ }
667
+ if (poolAddressesSoFar.has(subgraphPool.id)) {
668
+ continue;
669
+ }
670
+ // Only consider pools where neither tokens are in the blocked token list.
671
+ if (blockedTokenListProvider) {
672
+ const [token0InBlocklist, token1InBlocklist] = await Promise.all([
673
+ blockedTokenListProvider.hasTokenByAddress(subgraphPool.token0.id),
674
+ blockedTokenListProvider.hasTokenByAddress(subgraphPool.token1.id),
675
+ ]);
676
+ if (token0InBlocklist || token1InBlocklist) {
677
+ continue;
678
+ }
679
+ }
680
+ const tokenInToken0SecondHop = topByTVLUsingTokenInSecondHopsMap.get(subgraphPool.token0.id);
681
+ if (tokenInToken0SecondHop && !tokenInToken0SecondHop.hasEnoughPools()) {
682
+ poolAddressesSoFar.add(subgraphPool.id);
683
+ tokenInToken0SecondHop.pools.push(subgraphPool);
684
+ continue;
685
+ }
686
+ const tokenInToken1SecondHop = topByTVLUsingTokenInSecondHopsMap.get(subgraphPool.token1.id);
687
+ if (tokenInToken1SecondHop && !tokenInToken1SecondHop.hasEnoughPools()) {
688
+ poolAddressesSoFar.add(subgraphPool.id);
689
+ tokenInToken1SecondHop.pools.push(subgraphPool);
690
+ continue;
691
+ }
692
+ const tokenOutToken0SecondHop = topByTVLUsingTokenOutSecondHopsMap.get(subgraphPool.token0.id);
693
+ if (tokenOutToken0SecondHop &&
694
+ !tokenOutToken0SecondHop.hasEnoughPools()) {
695
+ poolAddressesSoFar.add(subgraphPool.id);
696
+ tokenOutToken0SecondHop.pools.push(subgraphPool);
697
+ continue;
698
+ }
699
+ const tokenOutToken1SecondHop = topByTVLUsingTokenOutSecondHopsMap.get(subgraphPool.token1.id);
700
+ if (tokenOutToken1SecondHop &&
701
+ !tokenOutToken1SecondHop.hasEnoughPools()) {
702
+ poolAddressesSoFar.add(subgraphPool.id);
703
+ tokenOutToken1SecondHop.pools.push(subgraphPool);
704
+ continue;
705
+ }
706
+ }
707
+ }
708
+ metric_1.metric.putMetric('V2SubgraphLoopsInSecondIteration', loopsInSecondIteration, metric_1.MetricLoggerUnit.Count);
709
+ const topByTVLUsingTokenInSecondHops = [];
710
+ for (const secondHopPools of topByTVLUsingTokenInSecondHopsMap.values()) {
711
+ topByTVLUsingTokenInSecondHops.push(...secondHopPools.pools);
712
+ }
713
+ const topByTVLUsingTokenOutSecondHops = [];
714
+ for (const secondHopPools of topByTVLUsingTokenOutSecondHopsMap.values()) {
715
+ topByTVLUsingTokenOutSecondHops.push(...secondHopPools.pools);
716
+ }
717
+ const subgraphPools = (0, lodash_1.default)([
718
+ ...topByBaseWithTokenIn,
719
+ ...topByBaseWithTokenOut,
720
+ ...topByDirectSwapPool,
721
+ ...topByEthQuoteTokenPool,
722
+ ...topByTVL,
723
+ ...topByTVLUsingTokenIn,
724
+ ...topByTVLUsingTokenOut,
725
+ ...topByTVLUsingTokenInSecondHops,
726
+ ...topByTVLUsingTokenOutSecondHops,
727
+ ])
728
+ .uniqBy((pool) => pool.id)
729
+ .value();
730
+ const tokenAddressesSet = new Set();
731
+ for (const pool of subgraphPools) {
732
+ tokenAddressesSet.add(pool.token0.id);
733
+ tokenAddressesSet.add(pool.token1.id);
734
+ }
735
+ const tokenAddresses = Array.from(tokenAddressesSet);
736
+ log_1.log.info(`Getting the ${tokenAddresses.length} tokens within the ${subgraphPools.length} V2 pools we are considering`);
737
+ const tokenAccessor = await tokenProvider.getTokens(tokenAddresses, {
738
+ blockNumber,
739
+ });
740
+ const printV2SubgraphPool = (s) => {
741
+ var _a, _b, _c, _d;
742
+ return `${(_b = (_a = tokenAccessor.getTokenByAddress(s.token0.id)) === null || _a === void 0 ? void 0 : _a.symbol) !== null && _b !== void 0 ? _b : s.token0.id}/${(_d = (_c = tokenAccessor.getTokenByAddress(s.token1.id)) === null || _c === void 0 ? void 0 : _c.symbol) !== null && _d !== void 0 ? _d : s.token1.id}`;
743
+ };
744
+ log_1.log.info({
745
+ topByBaseWithTokenIn: topByBaseWithTokenIn.map(printV2SubgraphPool),
746
+ topByBaseWithTokenOut: topByBaseWithTokenOut.map(printV2SubgraphPool),
747
+ topByTVL: topByTVL.map(printV2SubgraphPool),
748
+ topByTVLUsingTokenIn: topByTVLUsingTokenIn.map(printV2SubgraphPool),
749
+ topByTVLUsingTokenOut: topByTVLUsingTokenOut.map(printV2SubgraphPool),
750
+ topByTVLUsingTokenInSecondHops: topByTVLUsingTokenInSecondHops.map(printV2SubgraphPool),
751
+ topByTVLUsingTokenOutSecondHops: topByTVLUsingTokenOutSecondHops.map(printV2SubgraphPool),
752
+ top2DirectSwap: topByDirectSwapPool.map(printV2SubgraphPool),
753
+ top2EthQuotePool: topByEthQuoteTokenPool.map(printV2SubgraphPool),
754
+ }, `V2 Candidate pools`);
755
+ const tokenPairsRaw = lodash_1.default.map(subgraphPools, (subgraphPool) => {
756
+ const tokenA = tokenAccessor.getTokenByAddress(subgraphPool.token0.id);
757
+ const tokenB = tokenAccessor.getTokenByAddress(subgraphPool.token1.id);
758
+ if (!tokenA || !tokenB) {
759
+ log_1.log.info(`Dropping candidate pool for ${subgraphPool.token0.id}/${subgraphPool.token1.id}`);
760
+ return undefined;
761
+ }
762
+ return [tokenA, tokenB];
763
+ });
764
+ const tokenPairs = lodash_1.default.compact(tokenPairsRaw);
765
+ metric_1.metric.putMetric('V2PoolsFilterLoad', Date.now() - beforePoolsFiltered, metric_1.MetricLoggerUnit.Milliseconds);
766
+ const beforePoolsLoad = Date.now();
767
+ // this should be the only place to enable fee-on-transfer fee fetching,
768
+ // because this places loads pools (pairs of tokens with fot taxes) from the subgraph
769
+ const poolAccessor = await poolProvider.getPools(tokenPairs, routingConfig);
770
+ metric_1.metric.putMetric('V2PoolsLoad', Date.now() - beforePoolsLoad, metric_1.MetricLoggerUnit.Milliseconds);
771
+ const poolsBySelection = {
772
+ protocol: router_sdk_1.Protocol.V2,
773
+ selections: {
774
+ topByBaseWithTokenIn,
775
+ topByBaseWithTokenOut,
776
+ topByDirectSwapPool,
777
+ topByEthQuoteTokenPool,
778
+ topByTVL,
779
+ topByTVLUsingTokenIn,
780
+ topByTVLUsingTokenOut,
781
+ topByTVLUsingTokenInSecondHops,
782
+ topByTVLUsingTokenOutSecondHops,
783
+ },
784
+ };
785
+ return { poolAccessor, candidatePools: poolsBySelection, subgraphPools };
786
+ }
787
+ exports.getV2CandidatePools = getV2CandidatePools;
788
+ async function getMixedRouteCandidatePools({
789
+ // v4CandidatePools,
790
+ v3CandidatePools, v2CandidatePools, crossLiquidityPools, routingConfig, tokenProvider,
791
+ // v4PoolProvider,
792
+ v3poolProvider, v2poolProvider, }) {
793
+ const beforeSubgraphPools = Date.now();
794
+ // const { subgraphPools: V4subgraphPools, candidatePools: V4candidatePools } =
795
+ // v4CandidatePools || { subgraphPools: [], candidatePools: [] };
796
+ // const V4subgraphPools: any[] = []; // V4 not supported
797
+ // const V4candidatePools: any = { selections: {} }; // V4 not supported
798
+ const { subgraphPools: V3subgraphPools, candidatePools: V3candidatePools } = v3CandidatePools || { subgraphPools: [], candidatePools: [] };
799
+ const { subgraphPools: V2subgraphPools, candidatePools: V2candidatePools } = v2CandidatePools || { subgraphPools: [], candidatePools: [] };
800
+ // Injects the liquidity pools found by the getMixedCrossLiquidityCandidatePools function
801
+ V2subgraphPools.push(...crossLiquidityPools.v2Pools);
802
+ V3subgraphPools.push(...crossLiquidityPools.v3Pools);
803
+ metric_1.metric.putMetric('MixedSubgraphPoolsLoad', Date.now() - beforeSubgraphPools, metric_1.MetricLoggerUnit.Milliseconds);
804
+ const beforePoolsFiltered = Date.now();
805
+ /**
806
+ * Main heuristic for pruning mixedRoutes:
807
+ * - we pick V2 pools with higher liq than respective V3 pools, or if the v3 pool doesn't exist
808
+ *
809
+ * This way we can reduce calls to our provider since it's possible to generate a lot of mixed routes
810
+ */
811
+ /// We only really care about pools involving the tokenIn or tokenOut explictly,
812
+ /// since there's no way a long tail token in V2 would be routed through as an intermediary
813
+ const V2topByTVLPoolIds = new Set([
814
+ ...V2candidatePools.selections.topByTVLUsingTokenIn,
815
+ ...V2candidatePools.selections.topByBaseWithTokenIn,
816
+ /// tokenOut:
817
+ ...V2candidatePools.selections.topByTVLUsingTokenOut,
818
+ ...V2candidatePools.selections.topByBaseWithTokenOut,
819
+ /// Direct swap:
820
+ ...V2candidatePools.selections.topByDirectSwapPool,
821
+ // Cross Liquidity (has to be added to be considered):
822
+ ...crossLiquidityPools.v2Pools,
823
+ ].map((poolId) => poolId.id));
824
+ const V2topByTVLSortedPools = (0, lodash_1.default)(V2subgraphPools)
825
+ .filter((pool) => V2topByTVLPoolIds.has(pool.id))
826
+ .sortBy((pool) => -pool.reserveUSD)
827
+ .value();
828
+ /// we consider all returned V3 pools for this heuristic to "fill in the gaps"
829
+ const V3sortedPools = (0, lodash_1.default)(V3subgraphPools)
830
+ .sortBy((pool) => -pool.tvlUSD)
831
+ .value();
832
+ // const V4sortedPools = _(V4subgraphPools)
833
+ // .sortBy((pool) => -pool.tvlUSD)
834
+ // .value();
835
+ // const V4sortedPools: any[] = []; // V4 not supported
836
+ /// Finding pools with greater reserveUSD on v2 than tvlUSD on v3, or if there is no v3 liquidity
837
+ const buildV2Pools = [];
838
+ V2topByTVLSortedPools.forEach((V2subgraphPool) => {
839
+ const V3subgraphPool = V3sortedPools.find((pool) => (pool.token0.id == V2subgraphPool.token0.id &&
840
+ pool.token1.id == V2subgraphPool.token1.id) ||
841
+ (pool.token0.id == V2subgraphPool.token1.id &&
842
+ pool.token1.id == V2subgraphPool.token0.id));
843
+ if (V3subgraphPool) {
844
+ if (V2subgraphPool.reserveUSD > V3subgraphPool.tvlUSD) {
845
+ log_1.log.info({
846
+ token0: V2subgraphPool.token0.id,
847
+ token1: V2subgraphPool.token1.id,
848
+ v2reserveUSD: V2subgraphPool.reserveUSD,
849
+ v3tvlUSD: V3subgraphPool.tvlUSD,
850
+ }, `MixedRoute heuristic, found a V2 pool with higher liquidity than its V3 counterpart`);
851
+ buildV2Pools.push(V2subgraphPool);
852
+ }
853
+ }
854
+ else {
855
+ log_1.log.info({
856
+ token0: V2subgraphPool.token0.id,
857
+ token1: V2subgraphPool.token1.id,
858
+ v2reserveUSD: V2subgraphPool.reserveUSD,
859
+ }, `MixedRoute heuristic, found a V2 pool with no V3 counterpart`);
860
+ buildV2Pools.push(V2subgraphPool);
861
+ }
862
+ // const V4subgraphPool = V4sortedPools.find(
863
+ // (pool) =>
864
+ // (pool.token0.id == V2subgraphPool.token0.id &&
865
+ // pool.token1.id == V2subgraphPool.token1.id) ||
866
+ // (pool.token0.id == V2subgraphPool.token1.id &&
867
+ // pool.token1.id == V2subgraphPool.token0.id)
868
+ // );
869
+ // if (V4subgraphPool) {
870
+ // if (V2subgraphPool.reserveUSD > V4subgraphPool.tvlUSD) {
871
+ // log.info(
872
+ // {
873
+ // token0: V2subgraphPool.token0.id,
874
+ // token1: V2subgraphPool.token1.id,
875
+ // v2reserveUSD: V2subgraphPool.reserveUSD,
876
+ // v4tvlUSD: V4subgraphPool.tvlUSD,
877
+ // },
878
+ // `MixedRoute heuristic, found a V2 pool with higher liquidity than its V4 counterpart`
879
+ // );
880
+ // buildV2Pools.push(V2subgraphPool);
881
+ // }
882
+ // } else {
883
+ // log.info(
884
+ // {
885
+ // token0: V2subgraphPool.token0.id,
886
+ // token1: V2subgraphPool.token1.id,
887
+ // v2reserveUSD: V2subgraphPool.reserveUSD,
888
+ // },
889
+ // `MixedRoute heuristic, found a V2 pool with no V3 counterpart`
890
+ // );
891
+ // buildV2Pools.push(V2subgraphPool);
892
+ // }
893
+ });
894
+ log_1.log.info(buildV2Pools.length, `Number of V2 candidate pools that fit first heuristic`);
895
+ const subgraphPools = [...buildV2Pools, ...V3sortedPools /* , ...V4sortedPools */];
896
+ const tokenAddresses = (0, lodash_1.default)(subgraphPools)
897
+ .flatMap((subgraphPool) => [subgraphPool.token0.id, subgraphPool.token1.id])
898
+ .compact()
899
+ .uniq()
900
+ .value();
901
+ log_1.log.info(`Getting the ${tokenAddresses.length} tokens within the ${subgraphPools.length} pools we are considering`);
902
+ const tokenAccessor = await tokenProvider.getTokens(tokenAddresses, routingConfig);
903
+ // const V4tokenPairsRaw = _.map<
904
+ // V4SubgraphPool,
905
+ // [Token, Token, number, number, string] | undefined
906
+ // >(V4sortedPools, (subgraphPool) => {
907
+ // const tokenA = tokenAccessor.getTokenByAddress(subgraphPool.token0.id);
908
+ // const tokenB = tokenAccessor.getTokenByAddress(subgraphPool.token1.id);
909
+ // let fee: FeeAmount;
910
+ // try {
911
+ // fee = Number(subgraphPool.feeTier);
912
+ // } catch (err) {
913
+ // log.info(
914
+ // { subgraphPool },
915
+ // `Dropping candidate pool for ${subgraphPool.token0.id}/${subgraphPool.token1.id}/${subgraphPool.feeTier}/${subgraphPool.tickSpacing}/${subgraphPool.hooks} because fee tier not supported`
916
+ // );
917
+ // return undefined;
918
+ // }
919
+ // if (!tokenA || !tokenB) {
920
+ // log.info(
921
+ // `Dropping candidate pool for ${subgraphPool.token0.id}/${
922
+ // subgraphPool.token1.id
923
+ // }/${fee}/${subgraphPool.tickSpacing}/${subgraphPool.hooks} because ${
924
+ // tokenA ? subgraphPool.token1.id : subgraphPool.token0.id
925
+ // } not found by token provider`
926
+ // );
927
+ // return undefined;
928
+ // }
929
+ // return [
930
+ // tokenA,
931
+ // tokenB,
932
+ // fee,
933
+ // Number(subgraphPool.tickSpacing),
934
+ // subgraphPool.hooks,
935
+ // ];
936
+ // });
937
+ // const V4tokenPairs = _.compact(V4tokenPairsRaw);
938
+ // const V4tokenPairs: any[] = []; // V4 not supported
939
+ const V3tokenPairsRaw = lodash_1.default.map(V3sortedPools, (subgraphPool) => {
940
+ const tokenA = tokenAccessor.getTokenByAddress(subgraphPool.token0.id);
941
+ const tokenB = tokenAccessor.getTokenByAddress(subgraphPool.token1.id);
942
+ let fee;
943
+ try {
944
+ fee = (0, amounts_1.parseFeeAmount)(subgraphPool.feeTier);
945
+ }
946
+ catch (err) {
947
+ log_1.log.info({ subgraphPool }, `Dropping candidate pool for ${subgraphPool.token0.id}/${subgraphPool.token1.id}/${subgraphPool.feeTier} because fee tier not supported`);
948
+ return undefined;
949
+ }
950
+ if (!tokenA || !tokenB) {
951
+ log_1.log.info(`Dropping candidate pool for ${subgraphPool.token0.id}/${subgraphPool.token1.id}/${fee} because ${tokenA ? subgraphPool.token1.id : subgraphPool.token0.id} not found by token provider`);
952
+ return undefined;
953
+ }
954
+ return [tokenA, tokenB, fee];
955
+ });
956
+ const V3tokenPairs = lodash_1.default.compact(V3tokenPairsRaw);
957
+ const V2tokenPairsRaw = lodash_1.default.map(buildV2Pools, (subgraphPool) => {
958
+ const tokenA = tokenAccessor.getTokenByAddress(subgraphPool.token0.id);
959
+ const tokenB = tokenAccessor.getTokenByAddress(subgraphPool.token1.id);
960
+ if (!tokenA || !tokenB) {
961
+ log_1.log.info(`Dropping candidate pool for ${subgraphPool.token0.id}/${subgraphPool.token1.id}`);
962
+ return undefined;
963
+ }
964
+ return [tokenA, tokenB];
965
+ });
966
+ const V2tokenPairs = lodash_1.default.compact(V2tokenPairsRaw);
967
+ metric_1.metric.putMetric('MixedPoolsFilterLoad', Date.now() - beforePoolsFiltered, metric_1.MetricLoggerUnit.Milliseconds);
968
+ const beforePoolsLoad = Date.now();
969
+ const [V2poolAccessor, V3poolAccessor /* , V4poolAccessor */] = await Promise.all([
970
+ v2poolProvider.getPools(V2tokenPairs, routingConfig),
971
+ v3poolProvider.getPools(V3tokenPairs, routingConfig),
972
+ // v4PoolProvider.getPools(V4tokenPairs, routingConfig),
973
+ ]);
974
+ // const V4poolAccessor: any = null; // V4 not supported
975
+ metric_1.metric.putMetric('MixedPoolsLoad', Date.now() - beforePoolsLoad, metric_1.MetricLoggerUnit.Milliseconds);
976
+ /// @dev a bit tricky here since the original V2CandidateSelections object included pools that we may have dropped
977
+ /// as part of the heuristic. We need to reconstruct a new object with the v3 pools too.
978
+ const buildPoolsBySelection = (key) => {
979
+ return [
980
+ ...buildV2Pools.filter((pool) => V2candidatePools.selections[key].map((p) => p.id).includes(pool.id)),
981
+ ...V3candidatePools.selections[key],
982
+ // ...(V4candidatePools.selections?.[key] || []),
983
+ ];
984
+ };
985
+ const poolsBySelection = {
986
+ protocol: router_sdk_1.Protocol.MIXED,
987
+ selections: {
988
+ topByBaseWithTokenIn: buildPoolsBySelection('topByBaseWithTokenIn'),
989
+ topByBaseWithTokenOut: buildPoolsBySelection('topByBaseWithTokenOut'),
990
+ topByDirectSwapPool: buildPoolsBySelection('topByDirectSwapPool'),
991
+ topByEthQuoteTokenPool: buildPoolsBySelection('topByEthQuoteTokenPool'),
992
+ topByTVL: buildPoolsBySelection('topByTVL'),
993
+ topByTVLUsingTokenIn: buildPoolsBySelection('topByTVLUsingTokenIn'),
994
+ topByTVLUsingTokenOut: buildPoolsBySelection('topByTVLUsingTokenOut'),
995
+ topByTVLUsingTokenInSecondHops: buildPoolsBySelection('topByTVLUsingTokenInSecondHops'),
996
+ topByTVLUsingTokenOutSecondHops: buildPoolsBySelection('topByTVLUsingTokenOutSecondHops'),
997
+ },
998
+ };
999
+ return {
1000
+ V2poolAccessor,
1001
+ V3poolAccessor,
1002
+ // V4poolAccessor,
1003
+ candidatePools: poolsBySelection,
1004
+ subgraphPools,
1005
+ };
1006
+ }
1007
+ exports.getMixedRouteCandidatePools = getMixedRouteCandidatePools;
1008
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0LWNhbmRpZGF0ZS1wb29scy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9yb3V0ZXJzL2FscGhhLXJvdXRlci9mdW5jdGlvbnMvZ2V0LWNhbmRpZGF0ZS1wb29scy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSwwREFBcUQ7QUFDckQsc0RBQW9FO0FBRXBFLG9EQUF1QjtBQVN2QixzRUFJMkM7QUFhM0Msd0NBSXVCO0FBQ3ZCLG1EQUF1RDtBQUN2RCwyQ0FBd0M7QUFDeEMsaURBQWdFO0FBdUZoRSxNQUFNLGlCQUFpQixHQUF1QztJQUM1RCxDQUFDLGtCQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyw4QkFBdUIsQ0FBQyxrQkFBTyxDQUFDLEtBQUssQ0FBRSxFQUFFLDJCQUFVLENBQUM7SUFDdEUsQ0FBQyxrQkFBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsOEJBQXVCLENBQUMsa0JBQU8sQ0FBQyxNQUFNLENBQUUsRUFBRSw0QkFBVyxDQUFDO0NBQzFFLENBQUM7QUFFRixNQUFNLHlCQUF5QjtJQUM3QixZQUNTLEtBQXFCLEVBQ1osV0FBbUI7UUFENUIsVUFBSyxHQUFMLEtBQUssQ0FBZ0I7UUFDWixnQkFBVyxHQUFYLFdBQVcsQ0FBUTtJQUNsQyxDQUFDO0lBRUcsY0FBYztRQUNuQixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUM7SUFDL0MsQ0FBQztDQUNGO0FBT0Q7Ozs7Ozs7O0dBUUc7QUFDSSxLQUFLLFVBQVUsb0NBQW9DLENBQUMsRUFDekQsT0FBTyxFQUNQLFFBQVEsRUFDUixXQUFXLEVBQ1gsa0JBQWtCLEVBQ2xCLGtCQUFrQixFQUNsQixZQUFZLEVBQ1osWUFBWSxHQUM0QjtJQUN4QyxNQUFNLE9BQU8sR0FBRyxDQUNkLE1BQU0sa0JBQWtCLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUU7UUFDbkQs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