@kumbaya_xyz/smart-order-router 4.22.38

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 (522) hide show
  1. package/CHANGELOG.md +255 -0
  2. package/LICENSE +674 -0
  3. package/README.md +315 -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 +77 -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 +111 -0
  21. package/build/main/providers/caching/route/route-caching-provider.js +86 -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 +170 -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 +242 -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 +21 -0
  33. package/build/main/providers/eth-estimate-gas-provider.js +91 -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 +47 -0
  39. package/build/main/providers/index.js +64 -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 +37 -0
  48. package/build/main/providers/on-chain-quote-provider.d.ts +258 -0
  49. package/build/main/providers/on-chain-quote-provider.js +713 -0
  50. package/build/main/providers/pool-provider.d.ts +45 -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 +46 -0
  57. package/build/main/providers/simulation-provider.js +138 -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 +56 -0
  63. package/build/main/providers/subgraph-provider.js +287 -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/tenderly-simulation-provider.d.ts +69 -0
  67. package/build/main/providers/tenderly-simulation-provider.js +458 -0
  68. package/build/main/providers/token-fee-fetcher.d.ts +31 -0
  69. package/build/main/providers/token-fee-fetcher.js +165 -0
  70. package/build/main/providers/token-properties-provider.d.ts +31 -0
  71. package/build/main/providers/token-properties-provider.js +118 -0
  72. package/build/main/providers/token-provider.d.ts +141 -0
  73. package/build/main/providers/token-provider.js +394 -0
  74. package/build/main/providers/token-validator-provider.d.ts +42 -0
  75. package/build/main/providers/token-validator-provider.js +99 -0
  76. package/build/main/providers/uri-subgraph-provider.d.ts +20 -0
  77. package/build/main/providers/uri-subgraph-provider.js +65 -0
  78. package/build/main/providers/v2/caching-pool-provider.d.ts +33 -0
  79. package/build/main/providers/v2/caching-pool-provider.js +89 -0
  80. package/build/main/providers/v2/caching-subgraph-provider.d.ts +19 -0
  81. package/build/main/providers/v2/caching-subgraph-provider.js +24 -0
  82. package/build/main/providers/v2/pool-provider.d.ts +63 -0
  83. package/build/main/providers/v2/pool-provider.js +148 -0
  84. package/build/main/providers/v2/quote-provider.d.ts +34 -0
  85. package/build/main/providers/v2/quote-provider.js +90 -0
  86. package/build/main/providers/v2/static-subgraph-provider.d.ts +19 -0
  87. package/build/main/providers/v2/static-subgraph-provider.js +171 -0
  88. package/build/main/providers/v2/subgraph-provider-with-fallback.d.ts +16 -0
  89. package/build/main/providers/v2/subgraph-provider-with-fallback.js +23 -0
  90. package/build/main/providers/v2/subgraph-provider.d.ts +53 -0
  91. package/build/main/providers/v2/subgraph-provider.js +344 -0
  92. package/build/main/providers/v2/uri-subgraph-provider.d.ts +4 -0
  93. package/build/main/providers/v2/uri-subgraph-provider.js +8 -0
  94. package/build/main/providers/v3/caching-pool-provider.d.ts +32 -0
  95. package/build/main/providers/v3/caching-pool-provider.js +84 -0
  96. package/build/main/providers/v3/caching-subgraph-provider.d.ts +19 -0
  97. package/build/main/providers/v3/caching-subgraph-provider.js +24 -0
  98. package/build/main/providers/v3/gas-data-provider.d.ts +39 -0
  99. package/build/main/providers/v3/gas-data-provider.js +26 -0
  100. package/build/main/providers/v3/pool-provider.d.ts +77 -0
  101. package/build/main/providers/v3/pool-provider.js +108 -0
  102. package/build/main/providers/v3/static-subgraph-provider.d.ts +21 -0
  103. package/build/main/providers/v3/static-subgraph-provider.js +217 -0
  104. package/build/main/providers/v3/subgraph-provider-with-fallback.d.ts +12 -0
  105. package/build/main/providers/v3/subgraph-provider-with-fallback.js +19 -0
  106. package/build/main/providers/v3/subgraph-provider.d.ts +45 -0
  107. package/build/main/providers/v3/subgraph-provider.js +46 -0
  108. package/build/main/providers/v3/uri-subgraph-provider.d.ts +4 -0
  109. package/build/main/providers/v3/uri-subgraph-provider.js +8 -0
  110. package/build/main/providers/v4/caching-pool-provider.d.ts +24 -0
  111. package/build/main/providers/v4/caching-pool-provider.js +81 -0
  112. package/build/main/providers/v4/caching-subgraph-provider.d.ts +19 -0
  113. package/build/main/providers/v4/caching-subgraph-provider.js +24 -0
  114. package/build/main/providers/v4/euler-swap-hooks-subgraph-provider.d.ts +25 -0
  115. package/build/main/providers/v4/euler-swap-hooks-subgraph-provider.js +160 -0
  116. package/build/main/providers/v4/pool-provider.d.ts +58 -0
  117. package/build/main/providers/v4/pool-provider.js +115 -0
  118. package/build/main/providers/v4/static-subgraph-provider.d.ts +15 -0
  119. package/build/main/providers/v4/static-subgraph-provider.js +78 -0
  120. package/build/main/providers/v4/subgraph-provider-with-fallback.d.ts +5 -0
  121. package/build/main/providers/v4/subgraph-provider-with-fallback.js +12 -0
  122. package/build/main/providers/v4/subgraph-provider.d.ts +63 -0
  123. package/build/main/providers/v4/subgraph-provider.js +63 -0
  124. package/build/main/providers/v4/uri-subgraph-provider.d.ts +4 -0
  125. package/build/main/providers/v4/uri-subgraph-provider.js +8 -0
  126. package/build/main/routers/alpha-router/alpha-router.d.ts +483 -0
  127. package/build/main/routers/alpha-router/alpha-router.js +1678 -0
  128. package/build/main/routers/alpha-router/config.d.ts +4 -0
  129. package/build/main/routers/alpha-router/config.js +131 -0
  130. package/build/main/routers/alpha-router/entities/index.d.ts +1 -0
  131. package/build/main/routers/alpha-router/entities/index.js +18 -0
  132. package/build/main/routers/alpha-router/entities/route-with-valid-quote.d.ts +208 -0
  133. package/build/main/routers/alpha-router/entities/route-with-valid-quote.js +194 -0
  134. package/build/main/routers/alpha-router/functions/best-swap-route.d.ts +24 -0
  135. package/build/main/routers/alpha-router/functions/best-swap-route.js +538 -0
  136. package/build/main/routers/alpha-router/functions/calculate-ratio-amount-in.d.ts +3 -0
  137. package/build/main/routers/alpha-router/functions/calculate-ratio-amount-in.js +18 -0
  138. package/build/main/routers/alpha-router/functions/compute-all-routes.d.ts +12 -0
  139. package/build/main/routers/alpha-router/functions/compute-all-routes.js +133 -0
  140. package/build/main/routers/alpha-router/functions/get-candidate-pools.d.ts +126 -0
  141. package/build/main/routers/alpha-router/functions/get-candidate-pools.js +1527 -0
  142. package/build/main/routers/alpha-router/gas-models/gas-costs.d.ts +12 -0
  143. package/build/main/routers/alpha-router/gas-models/gas-costs.js +200 -0
  144. package/build/main/routers/alpha-router/gas-models/gas-model.d.ts +107 -0
  145. package/build/main/routers/alpha-router/gas-models/gas-model.js +117 -0
  146. package/build/main/routers/alpha-router/gas-models/index.d.ts +2 -0
  147. package/build/main/routers/alpha-router/gas-models/index.js +19 -0
  148. package/build/main/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.d.ts +24 -0
  149. package/build/main/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.js +161 -0
  150. package/build/main/routers/alpha-router/gas-models/tick-based-heuristic-gas-model.d.ts +15 -0
  151. package/build/main/routers/alpha-router/gas-models/tick-based-heuristic-gas-model.js +191 -0
  152. package/build/main/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.d.ts +31 -0
  153. package/build/main/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.js +169 -0
  154. package/build/main/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.d.ts +26 -0
  155. package/build/main/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.js +41 -0
  156. package/build/main/routers/alpha-router/gas-models/v4/v4-heuristic-gas-model.d.ts +15 -0
  157. package/build/main/routers/alpha-router/gas-models/v4/v4-heuristic-gas-model.js +40 -0
  158. package/build/main/routers/alpha-router/index.d.ts +4 -0
  159. package/build/main/routers/alpha-router/index.js +21 -0
  160. package/build/main/routers/alpha-router/quoters/base-quoter.d.ts +77 -0
  161. package/build/main/routers/alpha-router/quoters/base-quoter.js +76 -0
  162. package/build/main/routers/alpha-router/quoters/index.d.ts +5 -0
  163. package/build/main/routers/alpha-router/quoters/index.js +22 -0
  164. package/build/main/routers/alpha-router/quoters/mixed-quoter.d.ts +32 -0
  165. package/build/main/routers/alpha-router/quoters/mixed-quoter.js +154 -0
  166. package/build/main/routers/alpha-router/quoters/model/index.d.ts +1 -0
  167. package/build/main/routers/alpha-router/quoters/model/index.js +18 -0
  168. package/build/main/routers/alpha-router/quoters/model/results/get-quotes-result.d.ts +6 -0
  169. package/build/main/routers/alpha-router/quoters/model/results/get-quotes-result.js +3 -0
  170. package/build/main/routers/alpha-router/quoters/model/results/get-routes-result.d.ts +6 -0
  171. package/build/main/routers/alpha-router/quoters/model/results/get-routes-result.js +3 -0
  172. package/build/main/routers/alpha-router/quoters/model/results/index.d.ts +2 -0
  173. package/build/main/routers/alpha-router/quoters/model/results/index.js +19 -0
  174. package/build/main/routers/alpha-router/quoters/v2-quoter.d.ts +24 -0
  175. package/build/main/routers/alpha-router/quoters/v2-quoter.js +141 -0
  176. package/build/main/routers/alpha-router/quoters/v3-quoter.d.ts +19 -0
  177. package/build/main/routers/alpha-router/quoters/v3-quoter.js +125 -0
  178. package/build/main/routers/alpha-router/quoters/v4-quoter.d.ts +18 -0
  179. package/build/main/routers/alpha-router/quoters/v4-quoter.js +122 -0
  180. package/build/main/routers/index.d.ts +4 -0
  181. package/build/main/routers/index.js +21 -0
  182. package/build/main/routers/legacy-router/bases.d.ts +213 -0
  183. package/build/main/routers/legacy-router/bases.js +124 -0
  184. package/build/main/routers/legacy-router/index.d.ts +1 -0
  185. package/build/main/routers/legacy-router/index.js +18 -0
  186. package/build/main/routers/legacy-router/legacy-router.d.ts +41 -0
  187. package/build/main/routers/legacy-router/legacy-router.js +291 -0
  188. package/build/main/routers/router.d.ts +195 -0
  189. package/build/main/routers/router.js +92 -0
  190. package/build/main/tsconfig.tsbuildinfo +1 -0
  191. package/build/main/types/other/factories/Erc20__factory.d.ts +45 -0
  192. package/build/main/types/other/factories/Erc20__factory.js +240 -0
  193. package/build/main/types/other/factories/GasDataArbitrum__factory.d.ts +18 -0
  194. package/build/main/types/other/factories/GasDataArbitrum__factory.js +58 -0
  195. package/build/main/types/other/factories/IMixedRouteQuoterV1__factory.d.ts +41 -0
  196. package/build/main/types/other/factories/IMixedRouteQuoterV1__factory.js +156 -0
  197. package/build/main/types/other/factories/ITokenValidator__factory.d.ts +22 -0
  198. package/build/main/types/other/factories/ITokenValidator__factory.js +78 -0
  199. package/build/main/types/other/factories/MixedRouteQuoterV2__factory.d.ts +86 -0
  200. package/build/main/types/other/factories/MixedRouteQuoterV2__factory.js +477 -0
  201. package/build/main/types/other/factories/Permit2__factory.d.ts +87 -0
  202. package/build/main/types/other/factories/Permit2__factory.js +941 -0
  203. package/build/main/types/other/factories/StateView__factory.d.ts +32 -0
  204. package/build/main/types/other/factories/StateView__factory.js +383 -0
  205. package/build/main/types/other/factories/SwapRouter02__factory.d.ts +67 -0
  206. package/build/main/types/other/factories/SwapRouter02__factory.js +1103 -0
  207. package/build/main/types/other/factories/TokenFeeDetector__factory.d.ts +47 -0
  208. package/build/main/types/other/factories/TokenFeeDetector__factory.js +243 -0
  209. package/build/main/types/other/factories/V4Quoter__factory.d.ts +37 -0
  210. package/build/main/types/other/factories/V4Quoter__factory.js +312 -0
  211. package/build/main/types/v2/factories/IUniswapV2Pair__factory.d.ts +35 -0
  212. package/build/main/types/v2/factories/IUniswapV2Pair__factory.js +671 -0
  213. package/build/main/types/v3/factories/IERC20Metadata__factory.d.ts +35 -0
  214. package/build/main/types/v3/factories/IERC20Metadata__factory.js +242 -0
  215. package/build/main/types/v3/factories/IQuoterV2__factory.d.ts +41 -0
  216. package/build/main/types/v3/factories/IQuoterV2__factory.js +220 -0
  217. package/build/main/types/v3/factories/IUniswapV3PoolState__factory.d.ts +22 -0
  218. package/build/main/types/v3/factories/IUniswapV3PoolState__factory.js +266 -0
  219. package/build/main/types/v3/factories/UniswapInterfaceMulticall__factory.d.ts +61 -0
  220. package/build/main/types/v3/factories/UniswapInterfaceMulticall__factory.js +132 -0
  221. package/build/main/util/addresses.d.ts +32 -0
  222. package/build/main/util/addresses.js +113 -0
  223. package/build/main/util/amounts.d.ts +10 -0
  224. package/build/main/util/amounts.js +94 -0
  225. package/build/main/util/callData.d.ts +1 -0
  226. package/build/main/util/callData.js +6 -0
  227. package/build/main/util/chains.d.ts +69 -0
  228. package/build/main/util/chains.js +740 -0
  229. package/build/main/util/defaultBlocksToLive.d.ts +4 -0
  230. package/build/main/util/defaultBlocksToLive.js +58 -0
  231. package/build/main/util/gas-factory-helpers.d.ts +34 -0
  232. package/build/main/util/gas-factory-helpers.js +439 -0
  233. package/build/main/util/hooksOptions.d.ts +5 -0
  234. package/build/main/util/hooksOptions.js +10 -0
  235. package/build/main/util/index.d.ts +10 -0
  236. package/build/main/util/index.js +27 -0
  237. package/build/main/util/intent.d.ts +6 -0
  238. package/build/main/util/intent.js +13 -0
  239. package/build/main/util/l2FeeChains.d.ts +2 -0
  240. package/build/main/util/l2FeeChains.js +18 -0
  241. package/build/main/util/log.d.ts +3 -0
  242. package/build/main/util/log.js +97 -0
  243. package/build/main/util/methodParameters.d.ts +5 -0
  244. package/build/main/util/methodParameters.js +147 -0
  245. package/build/main/util/metric.d.ts +48 -0
  246. package/build/main/util/metric.js +59 -0
  247. package/build/main/util/mixedRouteFilterOutV4Pools.d.ts +3 -0
  248. package/build/main/util/mixedRouteFilterOutV4Pools.js +17 -0
  249. package/build/main/util/onchainQuoteProviderConfigs.d.ts +42 -0
  250. package/build/main/util/onchainQuoteProviderConfigs.js +72 -0
  251. package/build/main/util/pool.d.ts +5 -0
  252. package/build/main/util/pool.js +44 -0
  253. package/build/main/util/protocols.d.ts +2 -0
  254. package/build/main/util/protocols.js +20 -0
  255. package/build/main/util/routes.d.ts +11 -0
  256. package/build/main/util/routes.js +148 -0
  257. package/build/main/util/serializeRouteIds.d.ts +2 -0
  258. package/build/main/util/serializeRouteIds.js +12 -0
  259. package/build/main/util/tenderlySimulationErrorBreakDown.d.ts +3 -0
  260. package/build/main/util/tenderlySimulationErrorBreakDown.js +33 -0
  261. package/build/main/util/unsupported-tokens.d.ts +37 -0
  262. package/build/main/util/unsupported-tokens.js +1119 -0
  263. package/build/module/index.d.ts +3 -0
  264. package/build/module/index.js +4 -0
  265. package/build/module/providers/cache-node.d.ts +10 -0
  266. package/build/module/providers/cache-node.js +29 -0
  267. package/build/module/providers/cache.d.ts +14 -0
  268. package/build/module/providers/cache.js +2 -0
  269. package/build/module/providers/caching/route/index.d.ts +2 -0
  270. package/build/module/providers/caching/route/index.js +3 -0
  271. package/build/module/providers/caching/route/model/cache-mode.d.ts +16 -0
  272. package/build/module/providers/caching/route/model/cache-mode.js +18 -0
  273. package/build/module/providers/caching/route/model/cached-route.d.ts +29 -0
  274. package/build/module/providers/caching/route/model/cached-route.js +73 -0
  275. package/build/module/providers/caching/route/model/cached-routes.d.ts +67 -0
  276. package/build/module/providers/caching/route/model/cached-routes.js +74 -0
  277. package/build/module/providers/caching/route/model/index.d.ts +3 -0
  278. package/build/module/providers/caching/route/model/index.js +4 -0
  279. package/build/module/providers/caching/route/route-caching-provider.d.ts +111 -0
  280. package/build/module/providers/caching/route/route-caching-provider.js +82 -0
  281. package/build/module/providers/caching-gas-provider.d.ts +23 -0
  282. package/build/module/providers/caching-gas-provider.js +37 -0
  283. package/build/module/providers/caching-subgraph-provider.d.ts +33 -0
  284. package/build/module/providers/caching-subgraph-provider.js +166 -0
  285. package/build/module/providers/caching-token-list-provider.d.ts +52 -0
  286. package/build/module/providers/caching-token-list-provider.js +140 -0
  287. package/build/module/providers/caching-token-provider.d.ts +24 -0
  288. package/build/module/providers/caching-token-provider.js +235 -0
  289. package/build/module/providers/eip-1559-gas-price-provider.d.ts +31 -0
  290. package/build/module/providers/eip-1559-gas-price-provider.js +64 -0
  291. package/build/module/providers/eth-estimate-gas-provider.d.ts +21 -0
  292. package/build/module/providers/eth-estimate-gas-provider.js +99 -0
  293. package/build/module/providers/eth-gas-station-info-gas-price-provider.d.ts +19 -0
  294. package/build/module/providers/eth-gas-station-info-gas-price-provider.js +29 -0
  295. package/build/module/providers/gas-price-provider.d.ts +10 -0
  296. package/build/module/providers/gas-price-provider.js +6 -0
  297. package/build/module/providers/index.d.ts +47 -0
  298. package/build/module/providers/index.js +48 -0
  299. package/build/module/providers/legacy-gas-price-provider.d.ts +7 -0
  300. package/build/module/providers/legacy-gas-price-provider.js +14 -0
  301. package/build/module/providers/multicall-provider.d.ts +83 -0
  302. package/build/module/providers/multicall-provider.js +11 -0
  303. package/build/module/providers/multicall-uniswap-provider.d.ts +37 -0
  304. package/build/module/providers/multicall-uniswap-provider.js +157 -0
  305. package/build/module/providers/on-chain-gas-price-provider.d.ts +19 -0
  306. package/build/module/providers/on-chain-gas-price-provider.js +33 -0
  307. package/build/module/providers/on-chain-quote-provider.d.ts +258 -0
  308. package/build/module/providers/on-chain-quote-provider.js +707 -0
  309. package/build/module/providers/pool-provider.d.ts +45 -0
  310. package/build/module/providers/pool-provider.js +66 -0
  311. package/build/module/providers/portion-provider.d.ts +86 -0
  312. package/build/module/providers/portion-provider.js +114 -0
  313. package/build/module/providers/provider.d.ts +38 -0
  314. package/build/module/providers/provider.js +2 -0
  315. package/build/module/providers/simulation-provider.d.ts +46 -0
  316. package/build/module/providers/simulation-provider.js +140 -0
  317. package/build/module/providers/static-gas-price-provider.d.ts +7 -0
  318. package/build/module/providers/static-gas-price-provider.js +9 -0
  319. package/build/module/providers/subgraph-provider-with-fallback.d.ts +11 -0
  320. package/build/module/providers/subgraph-provider-with-fallback.js +21 -0
  321. package/build/module/providers/subgraph-provider.d.ts +56 -0
  322. package/build/module/providers/subgraph-provider.js +284 -0
  323. package/build/module/providers/swap-router-provider.d.ts +30 -0
  324. package/build/module/providers/swap-router-provider.js +38 -0
  325. package/build/module/providers/tenderly-simulation-provider.d.ts +69 -0
  326. package/build/module/providers/tenderly-simulation-provider.js +456 -0
  327. package/build/module/providers/token-fee-fetcher.d.ts +31 -0
  328. package/build/module/providers/token-fee-fetcher.js +161 -0
  329. package/build/module/providers/token-properties-provider.d.ts +31 -0
  330. package/build/module/providers/token-properties-provider.js +114 -0
  331. package/build/module/providers/token-provider.d.ts +141 -0
  332. package/build/module/providers/token-provider.js +381 -0
  333. package/build/module/providers/token-validator-provider.d.ts +42 -0
  334. package/build/module/providers/token-validator-provider.js +92 -0
  335. package/build/module/providers/uri-subgraph-provider.d.ts +20 -0
  336. package/build/module/providers/uri-subgraph-provider.js +58 -0
  337. package/build/module/providers/v2/caching-pool-provider.d.ts +33 -0
  338. package/build/module/providers/v2/caching-pool-provider.js +85 -0
  339. package/build/module/providers/v2/caching-subgraph-provider.d.ts +19 -0
  340. package/build/module/providers/v2/caching-subgraph-provider.js +20 -0
  341. package/build/module/providers/v2/pool-provider.d.ts +63 -0
  342. package/build/module/providers/v2/pool-provider.js +141 -0
  343. package/build/module/providers/v2/quote-provider.d.ts +34 -0
  344. package/build/module/providers/v2/quote-provider.js +86 -0
  345. package/build/module/providers/v2/static-subgraph-provider.d.ts +19 -0
  346. package/build/module/providers/v2/static-subgraph-provider.js +164 -0
  347. package/build/module/providers/v2/subgraph-provider-with-fallback.d.ts +16 -0
  348. package/build/module/providers/v2/subgraph-provider-with-fallback.js +19 -0
  349. package/build/module/providers/v2/subgraph-provider.d.ts +53 -0
  350. package/build/module/providers/v2/subgraph-provider.js +341 -0
  351. package/build/module/providers/v2/uri-subgraph-provider.d.ts +4 -0
  352. package/build/module/providers/v2/uri-subgraph-provider.js +4 -0
  353. package/build/module/providers/v3/caching-pool-provider.d.ts +32 -0
  354. package/build/module/providers/v3/caching-pool-provider.js +77 -0
  355. package/build/module/providers/v3/caching-subgraph-provider.d.ts +19 -0
  356. package/build/module/providers/v3/caching-subgraph-provider.js +20 -0
  357. package/build/module/providers/v3/gas-data-provider.d.ts +39 -0
  358. package/build/module/providers/v3/gas-data-provider.js +22 -0
  359. package/build/module/providers/v3/pool-provider.d.ts +77 -0
  360. package/build/module/providers/v3/pool-provider.js +101 -0
  361. package/build/module/providers/v3/static-subgraph-provider.d.ts +21 -0
  362. package/build/module/providers/v3/static-subgraph-provider.js +210 -0
  363. package/build/module/providers/v3/subgraph-provider-with-fallback.d.ts +12 -0
  364. package/build/module/providers/v3/subgraph-provider-with-fallback.js +15 -0
  365. package/build/module/providers/v3/subgraph-provider.d.ts +45 -0
  366. package/build/module/providers/v3/subgraph-provider.js +42 -0
  367. package/build/module/providers/v3/uri-subgraph-provider.d.ts +4 -0
  368. package/build/module/providers/v3/uri-subgraph-provider.js +4 -0
  369. package/build/module/providers/v4/caching-pool-provider.d.ts +24 -0
  370. package/build/module/providers/v4/caching-pool-provider.js +74 -0
  371. package/build/module/providers/v4/caching-subgraph-provider.d.ts +19 -0
  372. package/build/module/providers/v4/caching-subgraph-provider.js +20 -0
  373. package/build/module/providers/v4/euler-swap-hooks-subgraph-provider.d.ts +25 -0
  374. package/build/module/providers/v4/euler-swap-hooks-subgraph-provider.js +153 -0
  375. package/build/module/providers/v4/pool-provider.d.ts +58 -0
  376. package/build/module/providers/v4/pool-provider.js +106 -0
  377. package/build/module/providers/v4/static-subgraph-provider.d.ts +15 -0
  378. package/build/module/providers/v4/static-subgraph-provider.js +71 -0
  379. package/build/module/providers/v4/subgraph-provider-with-fallback.d.ts +5 -0
  380. package/build/module/providers/v4/subgraph-provider-with-fallback.js +8 -0
  381. package/build/module/providers/v4/subgraph-provider.d.ts +63 -0
  382. package/build/module/providers/v4/subgraph-provider.js +59 -0
  383. package/build/module/providers/v4/uri-subgraph-provider.d.ts +4 -0
  384. package/build/module/providers/v4/uri-subgraph-provider.js +4 -0
  385. package/build/module/routers/alpha-router/alpha-router.d.ts +483 -0
  386. package/build/module/routers/alpha-router/alpha-router.js +1680 -0
  387. package/build/module/routers/alpha-router/config.d.ts +4 -0
  388. package/build/module/routers/alpha-router/config.js +127 -0
  389. package/build/module/routers/alpha-router/entities/index.d.ts +1 -0
  390. package/build/module/routers/alpha-router/entities/index.js +2 -0
  391. package/build/module/routers/alpha-router/entities/route-with-valid-quote.d.ts +208 -0
  392. package/build/module/routers/alpha-router/entities/route-with-valid-quote.js +184 -0
  393. package/build/module/routers/alpha-router/functions/best-swap-route.d.ts +24 -0
  394. package/build/module/routers/alpha-router/functions/best-swap-route.js +528 -0
  395. package/build/module/routers/alpha-router/functions/calculate-ratio-amount-in.d.ts +3 -0
  396. package/build/module/routers/alpha-router/functions/calculate-ratio-amount-in.js +14 -0
  397. package/build/module/routers/alpha-router/functions/compute-all-routes.d.ts +12 -0
  398. package/build/module/routers/alpha-router/functions/compute-all-routes.js +125 -0
  399. package/build/module/routers/alpha-router/functions/get-candidate-pools.d.ts +126 -0
  400. package/build/module/routers/alpha-router/functions/get-candidate-pools.js +1516 -0
  401. package/build/module/routers/alpha-router/gas-models/gas-costs.d.ts +12 -0
  402. package/build/module/routers/alpha-router/gas-models/gas-costs.js +189 -0
  403. package/build/module/routers/alpha-router/gas-models/gas-model.d.ts +107 -0
  404. package/build/module/routers/alpha-router/gas-models/gas-model.js +111 -0
  405. package/build/module/routers/alpha-router/gas-models/index.d.ts +2 -0
  406. package/build/module/routers/alpha-router/gas-models/index.js +3 -0
  407. package/build/module/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.d.ts +24 -0
  408. package/build/module/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.js +154 -0
  409. package/build/module/routers/alpha-router/gas-models/tick-based-heuristic-gas-model.d.ts +15 -0
  410. package/build/module/routers/alpha-router/gas-models/tick-based-heuristic-gas-model.js +187 -0
  411. package/build/module/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.d.ts +31 -0
  412. package/build/module/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.js +162 -0
  413. package/build/module/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.d.ts +26 -0
  414. package/build/module/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.js +37 -0
  415. package/build/module/routers/alpha-router/gas-models/v4/v4-heuristic-gas-model.d.ts +15 -0
  416. package/build/module/routers/alpha-router/gas-models/v4/v4-heuristic-gas-model.js +36 -0
  417. package/build/module/routers/alpha-router/index.d.ts +4 -0
  418. package/build/module/routers/alpha-router/index.js +5 -0
  419. package/build/module/routers/alpha-router/quoters/base-quoter.d.ts +77 -0
  420. package/build/module/routers/alpha-router/quoters/base-quoter.js +69 -0
  421. package/build/module/routers/alpha-router/quoters/index.d.ts +5 -0
  422. package/build/module/routers/alpha-router/quoters/index.js +6 -0
  423. package/build/module/routers/alpha-router/quoters/mixed-quoter.d.ts +32 -0
  424. package/build/module/routers/alpha-router/quoters/mixed-quoter.js +147 -0
  425. package/build/module/routers/alpha-router/quoters/model/index.d.ts +1 -0
  426. package/build/module/routers/alpha-router/quoters/model/index.js +2 -0
  427. package/build/module/routers/alpha-router/quoters/model/results/get-quotes-result.d.ts +6 -0
  428. package/build/module/routers/alpha-router/quoters/model/results/get-quotes-result.js +2 -0
  429. package/build/module/routers/alpha-router/quoters/model/results/get-routes-result.d.ts +6 -0
  430. package/build/module/routers/alpha-router/quoters/model/results/get-routes-result.js +2 -0
  431. package/build/module/routers/alpha-router/quoters/model/results/index.d.ts +2 -0
  432. package/build/module/routers/alpha-router/quoters/model/results/index.js +3 -0
  433. package/build/module/routers/alpha-router/quoters/v2-quoter.d.ts +24 -0
  434. package/build/module/routers/alpha-router/quoters/v2-quoter.js +138 -0
  435. package/build/module/routers/alpha-router/quoters/v3-quoter.d.ts +19 -0
  436. package/build/module/routers/alpha-router/quoters/v3-quoter.js +118 -0
  437. package/build/module/routers/alpha-router/quoters/v4-quoter.d.ts +18 -0
  438. package/build/module/routers/alpha-router/quoters/v4-quoter.js +115 -0
  439. package/build/module/routers/index.d.ts +4 -0
  440. package/build/module/routers/index.js +5 -0
  441. package/build/module/routers/legacy-router/bases.d.ts +213 -0
  442. package/build/module/routers/legacy-router/bases.js +130 -0
  443. package/build/module/routers/legacy-router/index.d.ts +1 -0
  444. package/build/module/routers/legacy-router/index.js +2 -0
  445. package/build/module/routers/legacy-router/legacy-router.d.ts +41 -0
  446. package/build/module/routers/legacy-router/legacy-router.js +292 -0
  447. package/build/module/routers/router.d.ts +195 -0
  448. package/build/module/routers/router.js +79 -0
  449. package/build/module/tsconfig.module.tsbuildinfo +1 -0
  450. package/build/module/types/other/factories/Erc20__factory.d.ts +45 -0
  451. package/build/module/types/other/factories/Erc20__factory.js +236 -0
  452. package/build/module/types/other/factories/GasDataArbitrum__factory.d.ts +18 -0
  453. package/build/module/types/other/factories/GasDataArbitrum__factory.js +54 -0
  454. package/build/module/types/other/factories/IMixedRouteQuoterV1__factory.d.ts +41 -0
  455. package/build/module/types/other/factories/IMixedRouteQuoterV1__factory.js +152 -0
  456. package/build/module/types/other/factories/ITokenValidator__factory.d.ts +22 -0
  457. package/build/module/types/other/factories/ITokenValidator__factory.js +74 -0
  458. package/build/module/types/other/factories/MixedRouteQuoterV2__factory.d.ts +86 -0
  459. package/build/module/types/other/factories/MixedRouteQuoterV2__factory.js +473 -0
  460. package/build/module/types/other/factories/Permit2__factory.d.ts +87 -0
  461. package/build/module/types/other/factories/Permit2__factory.js +937 -0
  462. package/build/module/types/other/factories/StateView__factory.d.ts +32 -0
  463. package/build/module/types/other/factories/StateView__factory.js +379 -0
  464. package/build/module/types/other/factories/SwapRouter02__factory.d.ts +67 -0
  465. package/build/module/types/other/factories/SwapRouter02__factory.js +1099 -0
  466. package/build/module/types/other/factories/TokenFeeDetector__factory.d.ts +47 -0
  467. package/build/module/types/other/factories/TokenFeeDetector__factory.js +239 -0
  468. package/build/module/types/other/factories/V4Quoter__factory.d.ts +37 -0
  469. package/build/module/types/other/factories/V4Quoter__factory.js +308 -0
  470. package/build/module/types/v2/factories/IUniswapV2Pair__factory.d.ts +35 -0
  471. package/build/module/types/v2/factories/IUniswapV2Pair__factory.js +667 -0
  472. package/build/module/types/v3/factories/IERC20Metadata__factory.d.ts +35 -0
  473. package/build/module/types/v3/factories/IERC20Metadata__factory.js +238 -0
  474. package/build/module/types/v3/factories/IQuoterV2__factory.d.ts +41 -0
  475. package/build/module/types/v3/factories/IQuoterV2__factory.js +216 -0
  476. package/build/module/types/v3/factories/IUniswapV3PoolState__factory.d.ts +22 -0
  477. package/build/module/types/v3/factories/IUniswapV3PoolState__factory.js +262 -0
  478. package/build/module/types/v3/factories/UniswapInterfaceMulticall__factory.d.ts +61 -0
  479. package/build/module/types/v3/factories/UniswapInterfaceMulticall__factory.js +128 -0
  480. package/build/module/util/addresses.d.ts +32 -0
  481. package/build/module/util/addresses.js +233 -0
  482. package/build/module/util/amounts.d.ts +10 -0
  483. package/build/module/util/amounts.js +82 -0
  484. package/build/module/util/callData.d.ts +1 -0
  485. package/build/module/util/callData.js +3 -0
  486. package/build/module/util/chains.d.ts +69 -0
  487. package/build/module/util/chains.js +732 -0
  488. package/build/module/util/defaultBlocksToLive.d.ts +4 -0
  489. package/build/module/util/defaultBlocksToLive.js +55 -0
  490. package/build/module/util/gas-factory-helpers.d.ts +34 -0
  491. package/build/module/util/gas-factory-helpers.js +421 -0
  492. package/build/module/util/hooksOptions.d.ts +5 -0
  493. package/build/module/util/hooksOptions.js +7 -0
  494. package/build/module/util/index.d.ts +10 -0
  495. package/build/module/util/index.js +11 -0
  496. package/build/module/util/intent.d.ts +6 -0
  497. package/build/module/util/intent.js +10 -0
  498. package/build/module/util/l2FeeChains.d.ts +2 -0
  499. package/build/module/util/l2FeeChains.js +15 -0
  500. package/build/module/util/log.d.ts +3 -0
  501. package/build/module/util/log.js +93 -0
  502. package/build/module/util/methodParameters.d.ts +5 -0
  503. package/build/module/util/methodParameters.js +145 -0
  504. package/build/module/util/metric.d.ts +48 -0
  505. package/build/module/util/metric.js +53 -0
  506. package/build/module/util/mixedRouteFilterOutV4Pools.d.ts +3 -0
  507. package/build/module/util/mixedRouteFilterOutV4Pools.js +12 -0
  508. package/build/module/util/onchainQuoteProviderConfigs.d.ts +42 -0
  509. package/build/module/util/onchainQuoteProviderConfigs.js +74 -0
  510. package/build/module/util/pool.d.ts +5 -0
  511. package/build/module/util/pool.js +41 -0
  512. package/build/module/util/protocols.d.ts +2 -0
  513. package/build/module/util/protocols.js +16 -0
  514. package/build/module/util/routes.d.ts +11 -0
  515. package/build/module/util/routes.js +136 -0
  516. package/build/module/util/serializeRouteIds.d.ts +2 -0
  517. package/build/module/util/serializeRouteIds.js +7 -0
  518. package/build/module/util/tenderlySimulationErrorBreakDown.d.ts +3 -0
  519. package/build/module/util/tenderlySimulationErrorBreakDown.js +29 -0
  520. package/build/module/util/unsupported-tokens.d.ts +37 -0
  521. package/build/module/util/unsupported-tokens.js +1116 -0
  522. package/package.json +129 -0
@@ -0,0 +1,1516 @@
1
+ import { ADDRESS_ZERO, Protocol } from '@uniswap/router-sdk';
2
+ import { ChainId, TradeType } from '@uniswap/sdk-core';
3
+ import { isNativeCurrency } from '@uniswap/universal-router-sdk';
4
+ import { DYNAMIC_FEE_FLAG } from '@uniswap/v4-sdk';
5
+ import _ from 'lodash';
6
+ import { DAI_OPTIMISM_SEPOLIA, isPoolFeeDynamic, USDC_ARBITRUM_SEPOLIA, USDC_OPTIMISM_SEPOLIA, USDT_OPTIMISM_SEPOLIA, WBTC_OPTIMISM_SEPOLIA, } from '../../../providers';
7
+ import { CELO, CELO_ALFAJORES, CEUR_CELO, CEUR_CELO_ALFAJORES, CUSD_CELO, CUSD_CELO_ALFAJORES, DAI_ARBITRUM, DAI_AVAX, DAI_BNB, DAI_MAINNET, DAI_MOONBEAM, DAI_OPTIMISM, DAI_OPTIMISM_GOERLI, DAI_POLYGON_MUMBAI, DAI_SEPOLIA, DAI_UNICHAIN, FEI_MAINNET, USDB_BLAST, USDC_ARBITRUM, USDC_ARBITRUM_GOERLI, USDC_AVAX, USDC_BASE, USDC_BASE_SEPOLIA, USDC_BNB, USDC_ETHEREUM_GNOSIS, USDC_MAINNET, USDC_MONAD, USDC_MOONBEAM, USDC_OPTIMISM, USDC_OPTIMISM_GOERLI, USDC_POLYGON, USDC_SEPOLIA, USDC_SONEIUM, USDC_UNICHAIN, USDT_ARBITRUM, USDT_BNB, USDT_MAINNET, USDT_MONAD_TESTNET, USDT_OPTIMISM, USDT_OPTIMISM_GOERLI, WBTC_ARBITRUM, WBTC_GNOSIS, WBTC_MAINNET, WBTC_MOONBEAM, WBTC_OPTIMISM, WBTC_OPTIMISM_GOERLI, WGLMR_MOONBEAM, WMATIC_POLYGON, WMATIC_POLYGON_MUMBAI, WSTETH_MAINNET, WXDAI_GNOSIS, } from '../../../providers/token-provider';
8
+ import { getAddress, getAddressLowerCase, getApplicableV3FeeAmounts, getApplicableV4FeesTickspacingsHooks, HooksOptions, nativeOnChain, unparseFeeAmount, WRAPPED_NATIVE_CURRENCY, } from '../../../util';
9
+ import { parseFeeAmount } from '../../../util/amounts';
10
+ import { log } from '../../../util/log';
11
+ import { metric, MetricLoggerUnit } from '../../../util/metric';
12
+ const baseTokensByChain = {
13
+ [ChainId.MAINNET]: [
14
+ USDC_MAINNET,
15
+ USDT_MAINNET,
16
+ WBTC_MAINNET,
17
+ DAI_MAINNET,
18
+ WRAPPED_NATIVE_CURRENCY[1],
19
+ FEI_MAINNET,
20
+ WSTETH_MAINNET,
21
+ ],
22
+ [ChainId.OPTIMISM]: [
23
+ DAI_OPTIMISM,
24
+ USDC_OPTIMISM,
25
+ USDT_OPTIMISM,
26
+ WBTC_OPTIMISM,
27
+ ],
28
+ [ChainId.SEPOLIA]: [DAI_SEPOLIA, USDC_SEPOLIA],
29
+ [ChainId.OPTIMISM_GOERLI]: [
30
+ DAI_OPTIMISM_GOERLI,
31
+ USDC_OPTIMISM_GOERLI,
32
+ USDT_OPTIMISM_GOERLI,
33
+ WBTC_OPTIMISM_GOERLI,
34
+ ],
35
+ [ChainId.OPTIMISM_SEPOLIA]: [
36
+ DAI_OPTIMISM_SEPOLIA,
37
+ USDC_OPTIMISM_SEPOLIA,
38
+ USDT_OPTIMISM_SEPOLIA,
39
+ WBTC_OPTIMISM_SEPOLIA,
40
+ ],
41
+ [ChainId.ARBITRUM_ONE]: [
42
+ DAI_ARBITRUM,
43
+ USDC_ARBITRUM,
44
+ WBTC_ARBITRUM,
45
+ USDT_ARBITRUM,
46
+ ],
47
+ [ChainId.ARBITRUM_GOERLI]: [USDC_ARBITRUM_GOERLI],
48
+ [ChainId.ARBITRUM_SEPOLIA]: [USDC_ARBITRUM_SEPOLIA],
49
+ [ChainId.POLYGON]: [USDC_POLYGON, WMATIC_POLYGON],
50
+ [ChainId.POLYGON_MUMBAI]: [DAI_POLYGON_MUMBAI, WMATIC_POLYGON_MUMBAI],
51
+ [ChainId.CELO]: [CUSD_CELO, CEUR_CELO, CELO],
52
+ [ChainId.CELO_ALFAJORES]: [
53
+ CUSD_CELO_ALFAJORES,
54
+ CEUR_CELO_ALFAJORES,
55
+ CELO_ALFAJORES,
56
+ ],
57
+ [ChainId.GNOSIS]: [WBTC_GNOSIS, WXDAI_GNOSIS, USDC_ETHEREUM_GNOSIS],
58
+ [ChainId.MOONBEAM]: [
59
+ DAI_MOONBEAM,
60
+ USDC_MOONBEAM,
61
+ WBTC_MOONBEAM,
62
+ WGLMR_MOONBEAM,
63
+ ],
64
+ [ChainId.BNB]: [DAI_BNB, USDC_BNB, USDT_BNB],
65
+ [ChainId.AVALANCHE]: [DAI_AVAX, USDC_AVAX],
66
+ [ChainId.BASE]: [USDC_BASE],
67
+ [ChainId.BLAST]: [WRAPPED_NATIVE_CURRENCY[ChainId.BLAST], USDB_BLAST],
68
+ [ChainId.ZORA]: [WRAPPED_NATIVE_CURRENCY[ChainId.ZORA]],
69
+ [ChainId.ZKSYNC]: [WRAPPED_NATIVE_CURRENCY[ChainId.ZKSYNC]],
70
+ [ChainId.WORLDCHAIN]: [WRAPPED_NATIVE_CURRENCY[ChainId.WORLDCHAIN]],
71
+ [ChainId.UNICHAIN_SEPOLIA]: [
72
+ WRAPPED_NATIVE_CURRENCY[ChainId.UNICHAIN_SEPOLIA],
73
+ ],
74
+ [ChainId.MONAD_TESTNET]: [
75
+ WRAPPED_NATIVE_CURRENCY[ChainId.MONAD_TESTNET],
76
+ USDT_MONAD_TESTNET,
77
+ ],
78
+ [ChainId.MONAD]: [WRAPPED_NATIVE_CURRENCY[ChainId.MONAD], USDC_MONAD],
79
+ [ChainId.BASE_SEPOLIA]: [
80
+ WRAPPED_NATIVE_CURRENCY[ChainId.BASE_SEPOLIA],
81
+ USDC_BASE_SEPOLIA,
82
+ ],
83
+ [ChainId.UNICHAIN]: [
84
+ WRAPPED_NATIVE_CURRENCY[ChainId.UNICHAIN],
85
+ DAI_UNICHAIN,
86
+ USDC_UNICHAIN,
87
+ ],
88
+ [ChainId.SONEIUM]: [USDC_SONEIUM, WRAPPED_NATIVE_CURRENCY[ChainId.SONEIUM]],
89
+ };
90
+ const excludedV3PoolIds = new Set([
91
+ // https://linear.app/uniswap/issue/CX-1005
92
+ '0x0f681f10ab1aa1cde04232a199fe3c6f2652a80c'.toLowerCase(),
93
+ ]);
94
+ class SubcategorySelectionPools {
95
+ constructor(pools, poolsNeeded) {
96
+ this.pools = pools;
97
+ this.poolsNeeded = poolsNeeded;
98
+ }
99
+ hasEnoughPools() {
100
+ return this.pools.length >= this.poolsNeeded;
101
+ }
102
+ }
103
+ /**
104
+ * Function that finds any missing pools that were not selected by the heuristic but that would
105
+ * create a route with the topPool by TVL with either tokenIn or tokenOut across protocols.
106
+ *
107
+ * e.g. In V2CandidatePools we found that wstETH/DOG is the most liquid pool,
108
+ * then in V3CandidatePools ETH/wstETH is *not* the most liquid pool, so it is not selected
109
+ * This process will look for that pool in order to complete the route.
110
+ *
111
+ */
112
+ export async function getMixedCrossLiquidityCandidatePools({ tokenIn, tokenOut, blockNumber, v2SubgraphProvider, v3SubgraphProvider, v2Candidates, v3Candidates, v4Candidates, mixedCrossLiquidityV3AgainstV4Supported, chainId, }) {
113
+ var _a, _b, _c, _d, _e, _f, _g, _h;
114
+ const v2Pools = (await v2SubgraphProvider.getPools(tokenIn, tokenOut, {
115
+ blockNumber,
116
+ })).sort((a, b) => b.reserve - a.reserve);
117
+ const v3Pools = (await v3SubgraphProvider.getPools(tokenIn, tokenOut, {
118
+ blockNumber,
119
+ })).sort((a, b) => b.tvlUSD - a.tvlUSD);
120
+ const tokenInAddress = tokenIn.address.toLowerCase();
121
+ const tokenOutAddress = tokenOut.address.toLowerCase();
122
+ const v2AgainstV3SelectedPools = findCrossProtocolMissingPools(tokenInAddress, tokenOutAddress, v2Pools, v2Candidates, v3Candidates);
123
+ const v3AgainstV2SelectedPools = findCrossProtocolMissingPools(tokenInAddress, tokenOutAddress, v3Pools, v3Candidates, v2Candidates);
124
+ const v3AgainstV4SelectedPools = chainId && (mixedCrossLiquidityV3AgainstV4Supported === null || mixedCrossLiquidityV3AgainstV4Supported === void 0 ? void 0 : mixedCrossLiquidityV3AgainstV4Supported.includes(chainId))
125
+ ? findCrossProtocolMissingPools(tokenInAddress, tokenOutAddress, v3Pools, v3Candidates, v4Candidates)
126
+ : { forTokenIn: undefined, forTokenOut: undefined };
127
+ // this is for deduplicate v3 pools, in case both v4 and v2 select the same v3 pools for tokenIn/tokenOut
128
+ if (((_a = v3AgainstV4SelectedPools.forTokenIn) === null || _a === void 0 ? void 0 : _a.id) ===
129
+ ((_b = v3AgainstV2SelectedPools.forTokenIn) === null || _b === void 0 ? void 0 : _b.id) ||
130
+ ((_c = v3AgainstV4SelectedPools.forTokenIn) === null || _c === void 0 ? void 0 : _c.id) ===
131
+ ((_d = v3AgainstV2SelectedPools.forTokenOut) === null || _d === void 0 ? void 0 : _d.id)) {
132
+ v3AgainstV4SelectedPools.forTokenIn = undefined;
133
+ }
134
+ if (((_e = v3AgainstV4SelectedPools.forTokenOut) === null || _e === void 0 ? void 0 : _e.id) ===
135
+ ((_f = v3AgainstV2SelectedPools.forTokenIn) === null || _f === void 0 ? void 0 : _f.id) ||
136
+ ((_g = v3AgainstV4SelectedPools.forTokenOut) === null || _g === void 0 ? void 0 : _g.id) ===
137
+ ((_h = v3AgainstV2SelectedPools.forTokenOut) === null || _h === void 0 ? void 0 : _h.id)) {
138
+ v3AgainstV4SelectedPools.forTokenOut = undefined;
139
+ }
140
+ const selectedV2Pools = [
141
+ v2AgainstV3SelectedPools.forTokenIn,
142
+ v2AgainstV3SelectedPools.forTokenOut,
143
+ ].filter((pool) => pool !== undefined);
144
+ const selectedV3Pools = [
145
+ v3AgainstV2SelectedPools.forTokenIn,
146
+ v3AgainstV2SelectedPools.forTokenOut,
147
+ v3AgainstV4SelectedPools.forTokenIn,
148
+ v3AgainstV4SelectedPools.forTokenOut,
149
+ ].filter((pool) => pool !== undefined);
150
+ return {
151
+ v2Pools: selectedV2Pools,
152
+ v3Pools: selectedV3Pools,
153
+ v4Pools: [],
154
+ };
155
+ }
156
+ function findCrossProtocolMissingPools(tokenInAddress, tokenOutAddress, pools, candidatesInProtocolToSearch, candidatesInContextProtocol) {
157
+ var _a;
158
+ const selectedPools = {};
159
+ const previouslySelectedPools = new Set((_a = candidatesInProtocolToSearch === null || candidatesInProtocolToSearch === void 0 ? void 0 : candidatesInProtocolToSearch.subgraphPools.map((pool) => pool.id)) !== null && _a !== void 0 ? _a : []);
160
+ const topPoolByTvlWithTokenOut = candidatesInContextProtocol === null || candidatesInContextProtocol === void 0 ? void 0 : candidatesInContextProtocol.candidatePools.selections.topByTVLUsingTokenOut[0];
161
+ const crossTokenAgainstTokenOut = (topPoolByTvlWithTokenOut === null || topPoolByTvlWithTokenOut === void 0 ? void 0 : topPoolByTvlWithTokenOut.token0.id.toLowerCase()) === tokenOutAddress
162
+ ? topPoolByTvlWithTokenOut === null || topPoolByTvlWithTokenOut === void 0 ? void 0 : topPoolByTvlWithTokenOut.token1.id.toLowerCase()
163
+ : topPoolByTvlWithTokenOut === null || topPoolByTvlWithTokenOut === void 0 ? void 0 : topPoolByTvlWithTokenOut.token0.id.toLowerCase();
164
+ const topPoolByTvlWithTokenIn = candidatesInContextProtocol === null || candidatesInContextProtocol === void 0 ? void 0 : candidatesInContextProtocol.candidatePools.selections.topByTVLUsingTokenIn[0];
165
+ const crossTokenAgainstTokenIn = (topPoolByTvlWithTokenIn === null || topPoolByTvlWithTokenIn === void 0 ? void 0 : topPoolByTvlWithTokenIn.token0.id.toLowerCase()) === tokenInAddress
166
+ ? topPoolByTvlWithTokenIn === null || topPoolByTvlWithTokenIn === void 0 ? void 0 : topPoolByTvlWithTokenIn.token1.id.toLowerCase()
167
+ : topPoolByTvlWithTokenIn === null || topPoolByTvlWithTokenIn === void 0 ? void 0 : topPoolByTvlWithTokenIn.token0.id.toLowerCase();
168
+ for (const pool of pools) {
169
+ // If we already found both pools for tokenIn and tokenOut. break out of this for loop.
170
+ if (selectedPools.forTokenIn !== undefined &&
171
+ selectedPools.forTokenOut !== undefined) {
172
+ break;
173
+ }
174
+ // If the pool has already been selected. continue to the next pool.
175
+ if (previouslySelectedPools.has(pool.id.toLowerCase())) {
176
+ continue;
177
+ }
178
+ const poolToken0Address = pool.token0.id.toLowerCase();
179
+ const poolToken1Address = pool.token1.id.toLowerCase();
180
+ // If we haven't selected the pool for tokenIn, and we found a pool matching the tokenOut, and the intermediateToken, select this pool
181
+ if (selectedPools.forTokenIn === undefined &&
182
+ ((poolToken0Address === tokenOutAddress &&
183
+ poolToken1Address === crossTokenAgainstTokenIn) ||
184
+ (poolToken1Address === tokenOutAddress &&
185
+ poolToken0Address === crossTokenAgainstTokenIn))) {
186
+ selectedPools.forTokenIn = pool;
187
+ }
188
+ // If we haven't selected the pool for tokenOut, and we found a pool matching the tokenIn, and the intermediateToken, select this pool
189
+ if (selectedPools.forTokenOut === undefined &&
190
+ ((poolToken0Address === tokenInAddress &&
191
+ poolToken1Address === crossTokenAgainstTokenOut) ||
192
+ (poolToken1Address === tokenInAddress &&
193
+ poolToken0Address === crossTokenAgainstTokenOut))) {
194
+ selectedPools.forTokenOut = pool;
195
+ }
196
+ }
197
+ return selectedPools;
198
+ }
199
+ // TODO: ROUTE-241 - refactor getV3CandidatePools against getV4CandidatePools
200
+ export async function getV4CandidatePools({ currencyIn, currencyOut, routeType, routingConfig, subgraphProvider, tokenProvider, poolProvider, blockedTokenListProvider, chainId, v4PoolParams = getApplicableV4FeesTickspacingsHooks(chainId), }) {
201
+ var _a, _b, _c, _d, _e;
202
+ const { blockNumber, v4PoolSelection: { topN, topNDirectSwaps, topNTokenInOut, topNSecondHop, topNSecondHopForTokenAddress, tokensToAvoidOnSecondHops, topNWithEachBaseToken, topNWithBaseToken, }, } = routingConfig;
203
+ const tokenInAddress = getAddressLowerCase(currencyIn);
204
+ const tokenOutAddress = getAddressLowerCase(currencyOut);
205
+ const beforeSubgraphPools = Date.now();
206
+ const allPools = await subgraphProvider.getPools(currencyIn, currencyOut, {
207
+ blockNumber,
208
+ });
209
+ log.info({ samplePools: allPools.slice(0, 3) }, 'Got all pools from V4 subgraph provider');
210
+ // Although this is less of an optimization than the V2 equivalent,
211
+ // save some time copying objects by mutating the underlying pool directly.
212
+ for (const pool of allPools) {
213
+ pool.token0.id = pool.token0.id.toLowerCase();
214
+ pool.token1.id = pool.token1.id.toLowerCase();
215
+ }
216
+ metric.putMetric('V4SubgraphPoolsLoad', Date.now() - beforeSubgraphPools, MetricLoggerUnit.Milliseconds);
217
+ const beforePoolsFiltered = Date.now();
218
+ // Only consider pools where neither tokens are in the blocked token list.
219
+ let filteredPools = allPools;
220
+ if (blockedTokenListProvider) {
221
+ filteredPools = [];
222
+ for (const pool of allPools) {
223
+ const token0InBlocklist = await blockedTokenListProvider.hasTokenByAddress(pool.token0.id);
224
+ const token1InBlocklist = await blockedTokenListProvider.hasTokenByAddress(pool.token1.id);
225
+ if (token0InBlocklist || token1InBlocklist) {
226
+ continue;
227
+ }
228
+ filteredPools.push(pool);
229
+ }
230
+ }
231
+ // Sort by tvlUSD in descending order
232
+ const subgraphPoolsSorted = filteredPools.sort((a, b) => b.tvlUSD - a.tvlUSD);
233
+ log.info(`After filtering blocked tokens went from ${allPools.length} to ${subgraphPoolsSorted.length}.`);
234
+ const poolAddressesSoFar = new Set();
235
+ const addToAddressSet = (pools) => {
236
+ _(pools)
237
+ .map((pool) => pool.id)
238
+ .forEach((poolAddress) => poolAddressesSoFar.add(poolAddress));
239
+ };
240
+ const baseTokens = (_a = baseTokensByChain[chainId]) !== null && _a !== void 0 ? _a : [];
241
+ const topByBaseWithTokenIn = _(baseTokens)
242
+ .flatMap((token) => {
243
+ return _(subgraphPoolsSorted)
244
+ .filter((subgraphPool) => {
245
+ const tokenAddress = token.address.toLowerCase();
246
+ return ((subgraphPool.token0.id == tokenAddress &&
247
+ subgraphPool.token1.id == tokenInAddress) ||
248
+ (subgraphPool.token1.id == tokenAddress &&
249
+ subgraphPool.token0.id == tokenInAddress));
250
+ })
251
+ .filter((subgraphPool) => {
252
+ // in case of hooks only, it means we want to filter out hookless pools
253
+ if (routingConfig.hooksOptions === HooksOptions.HOOKS_ONLY) {
254
+ return subgraphPool.hooks !== ADDRESS_ZERO;
255
+ }
256
+ // in case of no hooks, it means we want to filter out hook pools
257
+ if (routingConfig.hooksOptions === HooksOptions.NO_HOOKS) {
258
+ return subgraphPool.hooks === ADDRESS_ZERO;
259
+ }
260
+ // otherwise it's the default case, so we just return true
261
+ return true;
262
+ })
263
+ .sortBy((tokenListPool) => -tokenListPool.tvlUSD)
264
+ .slice(0, topNWithEachBaseToken)
265
+ .value();
266
+ })
267
+ .sortBy((tokenListPool) => -tokenListPool.tvlUSD)
268
+ .slice(0, topNWithBaseToken)
269
+ .value();
270
+ const topByBaseWithTokenOut = _(baseTokens)
271
+ .flatMap((token) => {
272
+ return _(subgraphPoolsSorted)
273
+ .filter((subgraphPool) => {
274
+ const tokenAddress = token.address.toLowerCase();
275
+ return ((subgraphPool.token0.id == tokenAddress &&
276
+ subgraphPool.token1.id == tokenOutAddress) ||
277
+ (subgraphPool.token1.id == tokenAddress &&
278
+ subgraphPool.token0.id == tokenOutAddress));
279
+ })
280
+ .filter((subgraphPool) => {
281
+ // in case of hooks only, it means we want to filter out hookless pools
282
+ if (routingConfig.hooksOptions === HooksOptions.HOOKS_ONLY) {
283
+ return subgraphPool.hooks !== ADDRESS_ZERO;
284
+ }
285
+ // in case of no hooks, it means we want to filter out hook pools
286
+ if (routingConfig.hooksOptions === HooksOptions.NO_HOOKS) {
287
+ return subgraphPool.hooks === ADDRESS_ZERO;
288
+ }
289
+ // otherwise it's the default case, so we just return true
290
+ return true;
291
+ })
292
+ .sortBy((tokenListPool) => -tokenListPool.tvlUSD)
293
+ .slice(0, topNWithEachBaseToken)
294
+ .value();
295
+ })
296
+ .sortBy((tokenListPool) => -tokenListPool.tvlUSD)
297
+ .slice(0, topNWithBaseToken)
298
+ .value();
299
+ let top2DirectSwapPool = _(subgraphPoolsSorted)
300
+ .filter((subgraphPool) => {
301
+ return (!poolAddressesSoFar.has(subgraphPool.id) &&
302
+ ((subgraphPool.token0.id == tokenInAddress &&
303
+ subgraphPool.token1.id == tokenOutAddress) ||
304
+ (subgraphPool.token1.id == tokenInAddress &&
305
+ subgraphPool.token0.id == tokenOutAddress)));
306
+ })
307
+ .filter((subgraphPool) => {
308
+ // in case of hooks only, it means we want to filter out hookless pools
309
+ if (routingConfig.hooksOptions === HooksOptions.HOOKS_ONLY) {
310
+ return subgraphPool.hooks !== ADDRESS_ZERO;
311
+ }
312
+ // in case of no hooks, it means we want to filter out hook pools
313
+ if (routingConfig.hooksOptions === HooksOptions.NO_HOOKS) {
314
+ return subgraphPool.hooks === ADDRESS_ZERO;
315
+ }
316
+ // otherwise it's the default case, so we just return true
317
+ return true;
318
+ })
319
+ .slice(0, topNDirectSwaps)
320
+ .value();
321
+ if (top2DirectSwapPool.length == 0 &&
322
+ topNDirectSwaps > 0 &&
323
+ routingConfig.hooksOptions !== HooksOptions.HOOKS_ONLY) {
324
+ // If we requested direct swap pools but did not find any in the subgraph query.
325
+ // Optimistically add them into the query regardless. Invalid pools ones will be dropped anyway
326
+ // when we query the pool on-chain. Ensures that new pools for new pairs can be swapped on immediately.
327
+ // Also we need to avoid adding hookless pools into the query, when upstream requested hooksOnly
328
+ top2DirectSwapPool = _.map(v4PoolParams, (poolParams) => {
329
+ const [fee, tickSpacing, hooks] = poolParams;
330
+ const { currency0, currency1, poolId } = poolProvider.getPoolId(currencyIn, currencyOut, fee, tickSpacing, hooks);
331
+ return {
332
+ id: poolId,
333
+ feeTier: fee.toString(),
334
+ tickSpacing: tickSpacing.toString(),
335
+ hooks: hooks,
336
+ liquidity: '10000',
337
+ token0: {
338
+ symbol: currency0.symbol,
339
+ id: getAddress(currency0),
340
+ name: currency0.name,
341
+ decimals: currency0.decimals.toString(),
342
+ },
343
+ token1: {
344
+ symbol: currency1.symbol,
345
+ id: getAddress(currency1),
346
+ name: currency1.name,
347
+ decimals: currency1.decimals.toString(),
348
+ },
349
+ tvlETH: 10000,
350
+ tvlUSD: 10000,
351
+ };
352
+ });
353
+ }
354
+ addToAddressSet(top2DirectSwapPool);
355
+ const wrappedNativeAddress = (_b = WRAPPED_NATIVE_CURRENCY[chainId]) === null || _b === void 0 ? void 0 : _b.address.toLowerCase();
356
+ // Main reason we need this is for gas estimates, only needed if token out is not native.
357
+ // We don't check the seen address set because if we've already added pools for getting native quotes
358
+ // theres no need to add more.
359
+ let top2EthQuoteTokenPool = [];
360
+ if ((((_c = WRAPPED_NATIVE_CURRENCY[chainId]) === null || _c === void 0 ? void 0 : _c.symbol) ==
361
+ ((_d = WRAPPED_NATIVE_CURRENCY[ChainId.MAINNET]) === null || _d === void 0 ? void 0 : _d.symbol) &&
362
+ currencyOut.symbol != 'WETH' &&
363
+ currencyOut.symbol != 'WETH9' &&
364
+ currencyOut.symbol != 'ETH') ||
365
+ (((_e = WRAPPED_NATIVE_CURRENCY[chainId]) === null || _e === void 0 ? void 0 : _e.symbol) == WMATIC_POLYGON.symbol &&
366
+ currencyOut.symbol != 'MATIC' &&
367
+ currencyOut.symbol != 'WMATIC')) {
368
+ top2EthQuoteTokenPool = _(subgraphPoolsSorted)
369
+ .filter((subgraphPool) => {
370
+ if (routeType == TradeType.EXACT_INPUT) {
371
+ return ((subgraphPool.token0.id == wrappedNativeAddress &&
372
+ subgraphPool.token1.id == tokenOutAddress) ||
373
+ (subgraphPool.token1.id == wrappedNativeAddress &&
374
+ subgraphPool.token0.id == tokenOutAddress));
375
+ }
376
+ else {
377
+ return ((subgraphPool.token0.id == wrappedNativeAddress &&
378
+ subgraphPool.token1.id == tokenInAddress) ||
379
+ (subgraphPool.token1.id == wrappedNativeAddress &&
380
+ subgraphPool.token0.id == tokenInAddress));
381
+ }
382
+ })
383
+ .slice(0, 1)
384
+ .value();
385
+ }
386
+ addToAddressSet(top2EthQuoteTokenPool);
387
+ const topByTVL = _(subgraphPoolsSorted)
388
+ .filter((subgraphPool) => {
389
+ return !poolAddressesSoFar.has(subgraphPool.id);
390
+ })
391
+ .slice(0, topN)
392
+ .value();
393
+ addToAddressSet(topByTVL);
394
+ const topByTVLUsingTokenIn = _(subgraphPoolsSorted)
395
+ .filter((subgraphPool) => {
396
+ return (!poolAddressesSoFar.has(subgraphPool.id) &&
397
+ (subgraphPool.token0.id == tokenInAddress ||
398
+ subgraphPool.token1.id == tokenInAddress));
399
+ })
400
+ .filter((subgraphPool) => {
401
+ // in case of hooks only, it means we want to filter out hookless pools
402
+ if (routingConfig.hooksOptions === HooksOptions.HOOKS_ONLY) {
403
+ return subgraphPool.hooks !== ADDRESS_ZERO;
404
+ }
405
+ // in case of no hooks, it means we want to filter out hook pools
406
+ if (routingConfig.hooksOptions === HooksOptions.NO_HOOKS) {
407
+ return subgraphPool.hooks === ADDRESS_ZERO;
408
+ }
409
+ // otherwise it's the default case, so we just return true
410
+ return true;
411
+ })
412
+ .slice(0, topNTokenInOut)
413
+ .value();
414
+ addToAddressSet(topByTVLUsingTokenIn);
415
+ const topByTVLUsingTokenOut = _(subgraphPoolsSorted)
416
+ .filter((subgraphPool) => {
417
+ return (!poolAddressesSoFar.has(subgraphPool.id) &&
418
+ (subgraphPool.token0.id == tokenOutAddress ||
419
+ subgraphPool.token1.id == tokenOutAddress));
420
+ })
421
+ .filter((subgraphPool) => {
422
+ // in case of hooks only, it means we want to filter out hookless pools
423
+ if (routingConfig.hooksOptions === HooksOptions.HOOKS_ONLY) {
424
+ return subgraphPool.hooks !== ADDRESS_ZERO;
425
+ }
426
+ // in case of no hooks, it means we want to filter out hook pools
427
+ if (routingConfig.hooksOptions === HooksOptions.NO_HOOKS) {
428
+ return subgraphPool.hooks === ADDRESS_ZERO;
429
+ }
430
+ // otherwise it's the default case, so we just return true
431
+ return true;
432
+ })
433
+ .slice(0, topNTokenInOut)
434
+ .value();
435
+ addToAddressSet(topByTVLUsingTokenOut);
436
+ const topByTVLUsingTokenInSecondHops = _(topByTVLUsingTokenIn)
437
+ .map((subgraphPool) => {
438
+ return tokenInAddress == subgraphPool.token0.id
439
+ ? subgraphPool.token1.id
440
+ : subgraphPool.token0.id;
441
+ })
442
+ .flatMap((secondHopId) => {
443
+ var _a;
444
+ return _(subgraphPoolsSorted)
445
+ .filter((subgraphPool) => {
446
+ return (!poolAddressesSoFar.has(subgraphPool.id) &&
447
+ !(tokensToAvoidOnSecondHops === null || tokensToAvoidOnSecondHops === void 0 ? void 0 : tokensToAvoidOnSecondHops.includes(secondHopId.toLowerCase())) &&
448
+ (subgraphPool.token0.id == secondHopId ||
449
+ subgraphPool.token1.id == secondHopId));
450
+ })
451
+ .filter((subgraphPool) => {
452
+ // in case of hooks only, it means we want to filter out hookless pools
453
+ if (routingConfig.hooksOptions === HooksOptions.HOOKS_ONLY) {
454
+ return subgraphPool.hooks !== ADDRESS_ZERO;
455
+ }
456
+ // in case of no hooks, it means we want to filter out hook pools
457
+ if (routingConfig.hooksOptions === HooksOptions.NO_HOOKS) {
458
+ return subgraphPool.hooks === ADDRESS_ZERO;
459
+ }
460
+ // otherwise it's the default case, so we just return true
461
+ return true;
462
+ })
463
+ .slice(0, (_a = topNSecondHopForTokenAddress === null || topNSecondHopForTokenAddress === void 0 ? void 0 : topNSecondHopForTokenAddress.get(secondHopId)) !== null && _a !== void 0 ? _a : topNSecondHop)
464
+ .value();
465
+ })
466
+ .uniqBy((pool) => pool.id)
467
+ .value();
468
+ addToAddressSet(topByTVLUsingTokenInSecondHops);
469
+ const topByTVLUsingTokenOutSecondHops = _(topByTVLUsingTokenOut)
470
+ .map((subgraphPool) => {
471
+ return tokenOutAddress == subgraphPool.token0.id
472
+ ? subgraphPool.token1.id
473
+ : subgraphPool.token0.id;
474
+ })
475
+ .flatMap((secondHopId) => {
476
+ var _a;
477
+ return _(subgraphPoolsSorted)
478
+ .filter((subgraphPool) => {
479
+ return (!poolAddressesSoFar.has(subgraphPool.id) &&
480
+ !(tokensToAvoidOnSecondHops === null || tokensToAvoidOnSecondHops === void 0 ? void 0 : tokensToAvoidOnSecondHops.includes(secondHopId.toLowerCase())) &&
481
+ (subgraphPool.token0.id == secondHopId ||
482
+ subgraphPool.token1.id == secondHopId));
483
+ })
484
+ .filter((subgraphPool) => {
485
+ // in case of hooks only, it means we want to filter out hookless pools
486
+ if (routingConfig.hooksOptions === HooksOptions.HOOKS_ONLY) {
487
+ return subgraphPool.hooks !== ADDRESS_ZERO;
488
+ }
489
+ // in case of no hooks, it means we want to filter out hook pools
490
+ if (routingConfig.hooksOptions === HooksOptions.NO_HOOKS) {
491
+ return subgraphPool.hooks === ADDRESS_ZERO;
492
+ }
493
+ // otherwise it's the default case, so we just return true
494
+ return true;
495
+ })
496
+ .slice(0, (_a = topNSecondHopForTokenAddress === null || topNSecondHopForTokenAddress === void 0 ? void 0 : topNSecondHopForTokenAddress.get(secondHopId)) !== null && _a !== void 0 ? _a : topNSecondHop)
497
+ .value();
498
+ })
499
+ .uniqBy((pool) => pool.id)
500
+ .value();
501
+ addToAddressSet(topByTVLUsingTokenOutSecondHops);
502
+ const subgraphPools = _([
503
+ ...topByBaseWithTokenIn,
504
+ ...topByBaseWithTokenOut,
505
+ ...top2DirectSwapPool,
506
+ ...top2EthQuoteTokenPool,
507
+ ...topByTVL,
508
+ ...topByTVLUsingTokenIn,
509
+ ...topByTVLUsingTokenOut,
510
+ ...topByTVLUsingTokenInSecondHops,
511
+ ...topByTVLUsingTokenOutSecondHops,
512
+ ])
513
+ .compact()
514
+ .uniqBy((pool) => pool.id)
515
+ .value();
516
+ const tokenAddresses = _(subgraphPools)
517
+ .flatMap((subgraphPool) => [subgraphPool.token0.id, subgraphPool.token1.id])
518
+ .compact()
519
+ .uniq()
520
+ .value();
521
+ log.info(`Getting the ${tokenAddresses.length} tokens within the ${subgraphPools.length} V4 pools we are considering`);
522
+ const tokenAccessor = await tokenProvider.getTokens(tokenAddresses, {
523
+ blockNumber,
524
+ });
525
+ const printV4SubgraphPool = (s) => {
526
+ var _a, _b, _c, _d;
527
+ 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}/${s.tickSpacing}/${s.hooks}`;
528
+ };
529
+ log.info({
530
+ topByBaseWithTokenIn: topByBaseWithTokenIn.map(printV4SubgraphPool),
531
+ topByBaseWithTokenOut: topByBaseWithTokenOut.map(printV4SubgraphPool),
532
+ topByTVL: topByTVL.map(printV4SubgraphPool),
533
+ topByTVLUsingTokenIn: topByTVLUsingTokenIn.map(printV4SubgraphPool),
534
+ topByTVLUsingTokenOut: topByTVLUsingTokenOut.map(printV4SubgraphPool),
535
+ topByTVLUsingTokenInSecondHops: topByTVLUsingTokenInSecondHops.map(printV4SubgraphPool),
536
+ topByTVLUsingTokenOutSecondHops: topByTVLUsingTokenOutSecondHops.map(printV4SubgraphPool),
537
+ top2DirectSwap: top2DirectSwapPool.map(printV4SubgraphPool),
538
+ top2EthQuotePool: top2EthQuoteTokenPool.map(printV4SubgraphPool),
539
+ }, `V4 Candidate Pools`);
540
+ const tokenPairsRaw = _.map(subgraphPools, (subgraphPool) => {
541
+ // native currency is not erc20 token, therefore there's no way to retrieve native currency metadata as the erc20 token.
542
+ const tokenA = isNativeCurrency(subgraphPool.token0.id)
543
+ ? nativeOnChain(chainId)
544
+ : tokenAccessor.getTokenByAddress(subgraphPool.token0.id);
545
+ const tokenB = isNativeCurrency(subgraphPool.token1.id)
546
+ ? nativeOnChain(chainId)
547
+ : tokenAccessor.getTokenByAddress(subgraphPool.token1.id);
548
+ let fee;
549
+ try {
550
+ fee = Number(subgraphPool.feeTier);
551
+ fee = isPoolFeeDynamic(tokenA, tokenB, Number(subgraphPool.tickSpacing), subgraphPool.hooks, subgraphPool.id)
552
+ ? DYNAMIC_FEE_FLAG
553
+ : fee;
554
+ }
555
+ catch (err) {
556
+ log.info({ subgraphPool }, `Dropping candidate pool for ${subgraphPool.token0.id}/${subgraphPool.token1.id}/${subgraphPool.feeTier} because fee tier not supported`);
557
+ return undefined;
558
+ }
559
+ if (!tokenA || !tokenB) {
560
+ 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`);
561
+ return undefined;
562
+ }
563
+ return [
564
+ tokenA,
565
+ tokenB,
566
+ fee,
567
+ Number(subgraphPool.tickSpacing),
568
+ subgraphPool.hooks,
569
+ ];
570
+ });
571
+ const tokenPairs = _.compact(tokenPairsRaw);
572
+ metric.putMetric('V4PoolsFilterLoad', Date.now() - beforePoolsFiltered, MetricLoggerUnit.Milliseconds);
573
+ const beforePoolsLoad = Date.now();
574
+ const poolAccessor = await poolProvider.getPools(tokenPairs, {
575
+ blockNumber,
576
+ });
577
+ metric.putMetric('V4PoolsLoad', Date.now() - beforePoolsLoad, MetricLoggerUnit.Milliseconds);
578
+ const poolsBySelection = {
579
+ protocol: Protocol.V4,
580
+ selections: {
581
+ topByBaseWithTokenIn,
582
+ topByBaseWithTokenOut,
583
+ topByDirectSwapPool: top2DirectSwapPool,
584
+ topByEthQuoteTokenPool: top2EthQuoteTokenPool,
585
+ topByTVL,
586
+ topByTVLUsingTokenIn,
587
+ topByTVLUsingTokenOut,
588
+ topByTVLUsingTokenInSecondHops,
589
+ topByTVLUsingTokenOutSecondHops,
590
+ },
591
+ };
592
+ return { poolAccessor, candidatePools: poolsBySelection, subgraphPools };
593
+ }
594
+ export async function getV3CandidatePools({ tokenIn, tokenOut, routeType, routingConfig, subgraphProvider, tokenProvider, poolProvider, blockedTokenListProvider, chainId, }) {
595
+ var _a, _b, _c, _d, _e;
596
+ const { blockNumber, v3PoolSelection: { topN, topNDirectSwaps, topNTokenInOut, topNSecondHop, topNSecondHopForTokenAddress, tokensToAvoidOnSecondHops, topNWithEachBaseToken, topNWithBaseToken, }, } = routingConfig;
597
+ const tokenInAddress = tokenIn.address.toLowerCase();
598
+ const tokenOutAddress = tokenOut.address.toLowerCase();
599
+ const beforeSubgraphPools = Date.now();
600
+ const allPools = await subgraphProvider.getPools(tokenIn, tokenOut, {
601
+ blockNumber,
602
+ });
603
+ log.info({ samplePools: allPools.slice(0, 3) }, 'Got all pools from V3 subgraph provider');
604
+ // Although this is less of an optimization than the V2 equivalent,
605
+ // save some time copying objects by mutating the underlying pool directly.
606
+ for (const pool of allPools) {
607
+ pool.token0.id = pool.token0.id.toLowerCase();
608
+ pool.token1.id = pool.token1.id.toLowerCase();
609
+ }
610
+ metric.putMetric('V3SubgraphPoolsLoad', Date.now() - beforeSubgraphPools, MetricLoggerUnit.Milliseconds);
611
+ const beforePoolsFiltered = Date.now();
612
+ // Only consider pools where neither tokens are in the blocked token list.
613
+ let filteredPools = allPools;
614
+ if (blockedTokenListProvider) {
615
+ filteredPools = [];
616
+ for (const pool of allPools) {
617
+ const token0InBlocklist = await blockedTokenListProvider.hasTokenByAddress(pool.token0.id);
618
+ const token1InBlocklist = await blockedTokenListProvider.hasTokenByAddress(pool.token1.id);
619
+ if (token0InBlocklist || token1InBlocklist) {
620
+ continue;
621
+ }
622
+ filteredPools.push(pool);
623
+ }
624
+ }
625
+ // Sort by tvlUSD in descending order
626
+ const subgraphPoolsSorted = filteredPools.sort((a, b) => b.tvlUSD - a.tvlUSD);
627
+ log.info(`After filtering blocked tokens went from ${allPools.length} to ${subgraphPoolsSorted.length}.`);
628
+ const poolAddressesSoFar = new Set();
629
+ const addToAddressSet = (pools) => {
630
+ _(pools)
631
+ .map((pool) => pool.id)
632
+ .forEach((poolAddress) => poolAddressesSoFar.add(poolAddress));
633
+ };
634
+ const baseTokens = (_a = baseTokensByChain[chainId]) !== null && _a !== void 0 ? _a : [];
635
+ const topByBaseWithTokenIn = _(baseTokens)
636
+ .flatMap((token) => {
637
+ return _(subgraphPoolsSorted)
638
+ .filter((subgraphPool) => {
639
+ const tokenAddress = token.address.toLowerCase();
640
+ return ((subgraphPool.token0.id == tokenAddress &&
641
+ subgraphPool.token1.id == tokenInAddress) ||
642
+ (subgraphPool.token1.id == tokenAddress &&
643
+ subgraphPool.token0.id == tokenInAddress));
644
+ })
645
+ .sortBy((tokenListPool) => -tokenListPool.tvlUSD)
646
+ .slice(0, topNWithEachBaseToken)
647
+ .value();
648
+ })
649
+ .sortBy((tokenListPool) => -tokenListPool.tvlUSD)
650
+ .slice(0, topNWithBaseToken)
651
+ .value();
652
+ const topByBaseWithTokenOut = _(baseTokens)
653
+ .flatMap((token) => {
654
+ return _(subgraphPoolsSorted)
655
+ .filter((subgraphPool) => {
656
+ const tokenAddress = token.address.toLowerCase();
657
+ return ((subgraphPool.token0.id == tokenAddress &&
658
+ subgraphPool.token1.id == tokenOutAddress) ||
659
+ (subgraphPool.token1.id == tokenAddress &&
660
+ subgraphPool.token0.id == tokenOutAddress));
661
+ })
662
+ .sortBy((tokenListPool) => -tokenListPool.tvlUSD)
663
+ .slice(0, topNWithEachBaseToken)
664
+ .value();
665
+ })
666
+ .sortBy((tokenListPool) => -tokenListPool.tvlUSD)
667
+ .slice(0, topNWithBaseToken)
668
+ .value();
669
+ let top2DirectSwapPool = _(subgraphPoolsSorted)
670
+ .filter((subgraphPool) => {
671
+ return (!poolAddressesSoFar.has(subgraphPool.id) &&
672
+ ((subgraphPool.token0.id == tokenInAddress &&
673
+ subgraphPool.token1.id == tokenOutAddress) ||
674
+ (subgraphPool.token1.id == tokenInAddress &&
675
+ subgraphPool.token0.id == tokenOutAddress)));
676
+ })
677
+ .slice(0, topNDirectSwaps)
678
+ .value();
679
+ if (top2DirectSwapPool.length == 0 && topNDirectSwaps > 0) {
680
+ // We don't want to re-add AMPL token pools for V3 in Mainnet.
681
+ // TODO: ROUTE-347, Remove this check once we have a better way to sync filters from subgraph cronjob <> routing path.
682
+ if (!(chainId == ChainId.MAINNET &&
683
+ (tokenIn.address.toLowerCase() ===
684
+ '0xd46ba6d942050d489dbd938a2c909a5d5039a161' ||
685
+ tokenOut.address.toLowerCase() ===
686
+ '0xd46ba6d942050d489dbd938a2c909a5d5039a161'))) {
687
+ // If we requested direct swap pools but did not find any in the subgraph query.
688
+ // Optimistically add them into the query regardless. Invalid pools ones will be dropped anyway
689
+ // when we query the pool on-chain. Ensures that new pools for new pairs can be swapped on immediately.
690
+ top2DirectSwapPool = _.map(getApplicableV3FeeAmounts(chainId), (feeAmount) => {
691
+ const { token0, token1, poolAddress } = poolProvider.getPoolAddress(tokenIn, tokenOut, feeAmount);
692
+ return {
693
+ id: poolAddress,
694
+ feeTier: unparseFeeAmount(feeAmount),
695
+ liquidity: '10000',
696
+ token0: {
697
+ id: token0.address,
698
+ },
699
+ token1: {
700
+ id: token1.address,
701
+ },
702
+ tvlETH: 10000,
703
+ tvlUSD: 10000,
704
+ };
705
+ });
706
+ top2DirectSwapPool = top2DirectSwapPool.filter((pool) => !excludedV3PoolIds.has(pool.id.toLowerCase()));
707
+ }
708
+ }
709
+ addToAddressSet(top2DirectSwapPool);
710
+ const wrappedNativeAddress = (_b = WRAPPED_NATIVE_CURRENCY[chainId]) === null || _b === void 0 ? void 0 : _b.address.toLowerCase();
711
+ // Main reason we need this is for gas estimates, only needed if token out is not native.
712
+ // We don't check the seen address set because if we've already added pools for getting native quotes
713
+ // theres no need to add more.
714
+ let top2EthQuoteTokenPool = [];
715
+ if ((((_c = WRAPPED_NATIVE_CURRENCY[chainId]) === null || _c === void 0 ? void 0 : _c.symbol) ==
716
+ ((_d = WRAPPED_NATIVE_CURRENCY[ChainId.MAINNET]) === null || _d === void 0 ? void 0 : _d.symbol) &&
717
+ tokenOut.symbol != 'WETH' &&
718
+ tokenOut.symbol != 'WETH9' &&
719
+ tokenOut.symbol != 'ETH') ||
720
+ (((_e = WRAPPED_NATIVE_CURRENCY[chainId]) === null || _e === void 0 ? void 0 : _e.symbol) == WMATIC_POLYGON.symbol &&
721
+ tokenOut.symbol != 'MATIC' &&
722
+ tokenOut.symbol != 'WMATIC')) {
723
+ top2EthQuoteTokenPool = _(subgraphPoolsSorted)
724
+ .filter((subgraphPool) => {
725
+ if (routeType == TradeType.EXACT_INPUT) {
726
+ return ((subgraphPool.token0.id == wrappedNativeAddress &&
727
+ subgraphPool.token1.id == tokenOutAddress) ||
728
+ (subgraphPool.token1.id == wrappedNativeAddress &&
729
+ subgraphPool.token0.id == tokenOutAddress));
730
+ }
731
+ else {
732
+ return ((subgraphPool.token0.id == wrappedNativeAddress &&
733
+ subgraphPool.token1.id == tokenInAddress) ||
734
+ (subgraphPool.token1.id == wrappedNativeAddress &&
735
+ subgraphPool.token0.id == tokenInAddress));
736
+ }
737
+ })
738
+ .slice(0, 1)
739
+ .value();
740
+ }
741
+ addToAddressSet(top2EthQuoteTokenPool);
742
+ const topByTVL = _(subgraphPoolsSorted)
743
+ .filter((subgraphPool) => {
744
+ return !poolAddressesSoFar.has(subgraphPool.id);
745
+ })
746
+ .slice(0, topN)
747
+ .value();
748
+ addToAddressSet(topByTVL);
749
+ const topByTVLUsingTokenIn = _(subgraphPoolsSorted)
750
+ .filter((subgraphPool) => {
751
+ return (!poolAddressesSoFar.has(subgraphPool.id) &&
752
+ (subgraphPool.token0.id == tokenInAddress ||
753
+ subgraphPool.token1.id == tokenInAddress));
754
+ })
755
+ .slice(0, topNTokenInOut)
756
+ .value();
757
+ addToAddressSet(topByTVLUsingTokenIn);
758
+ const topByTVLUsingTokenOut = _(subgraphPoolsSorted)
759
+ .filter((subgraphPool) => {
760
+ return (!poolAddressesSoFar.has(subgraphPool.id) &&
761
+ (subgraphPool.token0.id == tokenOutAddress ||
762
+ subgraphPool.token1.id == tokenOutAddress));
763
+ })
764
+ .slice(0, topNTokenInOut)
765
+ .value();
766
+ addToAddressSet(topByTVLUsingTokenOut);
767
+ const topByTVLUsingTokenInSecondHops = _(topByTVLUsingTokenIn)
768
+ .map((subgraphPool) => {
769
+ return tokenInAddress == subgraphPool.token0.id
770
+ ? subgraphPool.token1.id
771
+ : subgraphPool.token0.id;
772
+ })
773
+ .flatMap((secondHopId) => {
774
+ var _a;
775
+ return _(subgraphPoolsSorted)
776
+ .filter((subgraphPool) => {
777
+ return (!poolAddressesSoFar.has(subgraphPool.id) &&
778
+ !(tokensToAvoidOnSecondHops === null || tokensToAvoidOnSecondHops === void 0 ? void 0 : tokensToAvoidOnSecondHops.includes(secondHopId.toLowerCase())) &&
779
+ (subgraphPool.token0.id == secondHopId ||
780
+ subgraphPool.token1.id == secondHopId));
781
+ })
782
+ .slice(0, (_a = topNSecondHopForTokenAddress === null || topNSecondHopForTokenAddress === void 0 ? void 0 : topNSecondHopForTokenAddress.get(secondHopId)) !== null && _a !== void 0 ? _a : topNSecondHop)
783
+ .value();
784
+ })
785
+ .uniqBy((pool) => pool.id)
786
+ .value();
787
+ addToAddressSet(topByTVLUsingTokenInSecondHops);
788
+ const topByTVLUsingTokenOutSecondHops = _(topByTVLUsingTokenOut)
789
+ .map((subgraphPool) => {
790
+ return tokenOutAddress == subgraphPool.token0.id
791
+ ? subgraphPool.token1.id
792
+ : subgraphPool.token0.id;
793
+ })
794
+ .flatMap((secondHopId) => {
795
+ var _a;
796
+ return _(subgraphPoolsSorted)
797
+ .filter((subgraphPool) => {
798
+ return (!poolAddressesSoFar.has(subgraphPool.id) &&
799
+ !(tokensToAvoidOnSecondHops === null || tokensToAvoidOnSecondHops === void 0 ? void 0 : tokensToAvoidOnSecondHops.includes(secondHopId.toLowerCase())) &&
800
+ (subgraphPool.token0.id == secondHopId ||
801
+ subgraphPool.token1.id == secondHopId));
802
+ })
803
+ .slice(0, (_a = topNSecondHopForTokenAddress === null || topNSecondHopForTokenAddress === void 0 ? void 0 : topNSecondHopForTokenAddress.get(secondHopId)) !== null && _a !== void 0 ? _a : topNSecondHop)
804
+ .value();
805
+ })
806
+ .uniqBy((pool) => pool.id)
807
+ .value();
808
+ addToAddressSet(topByTVLUsingTokenOutSecondHops);
809
+ const subgraphPools = _([
810
+ ...topByBaseWithTokenIn,
811
+ ...topByBaseWithTokenOut,
812
+ ...top2DirectSwapPool,
813
+ ...top2EthQuoteTokenPool,
814
+ ...topByTVL,
815
+ ...topByTVLUsingTokenIn,
816
+ ...topByTVLUsingTokenOut,
817
+ ...topByTVLUsingTokenInSecondHops,
818
+ ...topByTVLUsingTokenOutSecondHops,
819
+ ])
820
+ .compact()
821
+ .uniqBy((pool) => pool.id)
822
+ .value();
823
+ const tokenAddresses = _(subgraphPools)
824
+ .flatMap((subgraphPool) => [subgraphPool.token0.id, subgraphPool.token1.id])
825
+ .compact()
826
+ .uniq()
827
+ .value();
828
+ log.info(`Getting the ${tokenAddresses.length} tokens within the ${subgraphPools.length} V3 pools we are considering`);
829
+ const tokenAccessor = await tokenProvider.getTokens(tokenAddresses, {
830
+ blockNumber,
831
+ });
832
+ const printV3SubgraphPool = (s) => {
833
+ var _a, _b, _c, _d;
834
+ 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}`;
835
+ };
836
+ log.info({
837
+ topByBaseWithTokenIn: topByBaseWithTokenIn.map(printV3SubgraphPool),
838
+ topByBaseWithTokenOut: topByBaseWithTokenOut.map(printV3SubgraphPool),
839
+ topByTVL: topByTVL.map(printV3SubgraphPool),
840
+ topByTVLUsingTokenIn: topByTVLUsingTokenIn.map(printV3SubgraphPool),
841
+ topByTVLUsingTokenOut: topByTVLUsingTokenOut.map(printV3SubgraphPool),
842
+ topByTVLUsingTokenInSecondHops: topByTVLUsingTokenInSecondHops.map(printV3SubgraphPool),
843
+ topByTVLUsingTokenOutSecondHops: topByTVLUsingTokenOutSecondHops.map(printV3SubgraphPool),
844
+ top2DirectSwap: top2DirectSwapPool.map(printV3SubgraphPool),
845
+ top2EthQuotePool: top2EthQuoteTokenPool.map(printV3SubgraphPool),
846
+ }, `V3 Candidate Pools`);
847
+ const tokenPairsRaw = _.map(subgraphPools, (subgraphPool) => {
848
+ const tokenA = tokenAccessor.getTokenByAddress(subgraphPool.token0.id);
849
+ const tokenB = tokenAccessor.getTokenByAddress(subgraphPool.token1.id);
850
+ let fee;
851
+ try {
852
+ fee = parseFeeAmount(subgraphPool.feeTier);
853
+ }
854
+ catch (err) {
855
+ log.info({ subgraphPool }, `Dropping candidate pool for ${subgraphPool.token0.id}/${subgraphPool.token1.id}/${subgraphPool.feeTier} because fee tier not supported`);
856
+ return undefined;
857
+ }
858
+ if (!tokenA || !tokenB) {
859
+ 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`);
860
+ return undefined;
861
+ }
862
+ return [tokenA, tokenB, fee];
863
+ });
864
+ const tokenPairs = _.compact(tokenPairsRaw);
865
+ metric.putMetric('V3PoolsFilterLoad', Date.now() - beforePoolsFiltered, MetricLoggerUnit.Milliseconds);
866
+ const beforePoolsLoad = Date.now();
867
+ const poolAccessor = await poolProvider.getPools(tokenPairs, {
868
+ blockNumber,
869
+ });
870
+ metric.putMetric('V3PoolsLoad', Date.now() - beforePoolsLoad, MetricLoggerUnit.Milliseconds);
871
+ const poolsBySelection = {
872
+ protocol: Protocol.V3,
873
+ selections: {
874
+ topByBaseWithTokenIn,
875
+ topByBaseWithTokenOut,
876
+ topByDirectSwapPool: top2DirectSwapPool,
877
+ topByEthQuoteTokenPool: top2EthQuoteTokenPool,
878
+ topByTVL,
879
+ topByTVLUsingTokenIn,
880
+ topByTVLUsingTokenOut,
881
+ topByTVLUsingTokenInSecondHops,
882
+ topByTVLUsingTokenOutSecondHops,
883
+ },
884
+ };
885
+ return { poolAccessor, candidatePools: poolsBySelection, subgraphPools };
886
+ }
887
+ export async function getV2CandidatePools({ tokenIn, tokenOut, routeType, routingConfig, subgraphProvider, tokenProvider, poolProvider, blockedTokenListProvider, chainId, }) {
888
+ var _a;
889
+ const { blockNumber, v2PoolSelection: { topN, topNDirectSwaps, topNTokenInOut, topNSecondHop, tokensToAvoidOnSecondHops, topNWithEachBaseToken, topNWithBaseToken, }, } = routingConfig;
890
+ const tokenInAddress = tokenIn.address.toLowerCase();
891
+ const tokenOutAddress = tokenOut.address.toLowerCase();
892
+ const beforeSubgraphPools = Date.now();
893
+ const allPoolsRaw = await subgraphProvider.getPools(tokenIn, tokenOut, {
894
+ blockNumber,
895
+ });
896
+ // With tens of thousands of V2 pools, operations that copy pools become costly.
897
+ // Mutate the pool directly rather than creating a new pool / token to optimmize for speed.
898
+ for (const pool of allPoolsRaw) {
899
+ pool.token0.id = pool.token0.id.toLowerCase();
900
+ pool.token1.id = pool.token1.id.toLowerCase();
901
+ }
902
+ metric.putMetric('V2SubgraphPoolsLoad', Date.now() - beforeSubgraphPools, MetricLoggerUnit.Milliseconds);
903
+ const beforePoolsFiltered = Date.now();
904
+ // Sort by pool reserve in descending order.
905
+ const subgraphPoolsSorted = allPoolsRaw.sort((a, b) => b.reserve - a.reserve);
906
+ const poolAddressesSoFar = new Set();
907
+ // Always add the direct swap pool into the mix regardless of if it exists in the subgraph pool list.
908
+ // Ensures that new pools can be swapped on immediately, and that if a pool was filtered out of the
909
+ // subgraph query for some reason (e.g. trackedReserveETH was 0), then we still consider it.
910
+ let topByDirectSwapPool = [];
911
+ if (topNDirectSwaps > 0) {
912
+ const { token0, token1, poolAddress } = poolProvider.getPoolAddress(tokenIn, tokenOut);
913
+ poolAddressesSoFar.add(poolAddress.toLowerCase());
914
+ topByDirectSwapPool = [
915
+ {
916
+ id: poolAddress,
917
+ token0: {
918
+ id: token0.address,
919
+ },
920
+ token1: {
921
+ id: token1.address,
922
+ },
923
+ supply: 10000,
924
+ reserve: 10000,
925
+ reserveUSD: 10000, // Not used. Set to arbitrary number.
926
+ },
927
+ ];
928
+ }
929
+ const wethAddress = WRAPPED_NATIVE_CURRENCY[chainId].address.toLowerCase();
930
+ const topByBaseWithTokenInMap = new Map();
931
+ const topByBaseWithTokenOutMap = new Map();
932
+ const baseTokens = (_a = baseTokensByChain[chainId]) !== null && _a !== void 0 ? _a : [];
933
+ const baseTokensAddresses = new Set();
934
+ baseTokens.forEach((token) => {
935
+ const baseTokenAddr = token.address.toLowerCase();
936
+ baseTokensAddresses.add(baseTokenAddr);
937
+ topByBaseWithTokenInMap.set(baseTokenAddr, new SubcategorySelectionPools([], topNWithEachBaseToken));
938
+ topByBaseWithTokenOutMap.set(baseTokenAddr, new SubcategorySelectionPools([], topNWithEachBaseToken));
939
+ });
940
+ let topByBaseWithTokenInPoolsFound = 0;
941
+ let topByBaseWithTokenOutPoolsFound = 0;
942
+ // Main reason we need this is for gas estimates
943
+ // There can ever only be 1 Token/ETH pool, so we will only look for 1
944
+ let topNEthQuoteToken = 1;
945
+ // but, we only need it if token out is not ETH.
946
+ if (tokenOut.symbol == 'WETH' ||
947
+ tokenOut.symbol == 'WETH9' ||
948
+ tokenOut.symbol == 'ETH') {
949
+ // if it's eth we change the topN to 0, so we can break early from the loop.
950
+ topNEthQuoteToken = 0;
951
+ }
952
+ const topByEthQuoteTokenPool = [];
953
+ const topByTVLUsingTokenIn = [];
954
+ const topByTVLUsingTokenOut = [];
955
+ const topByTVL = [];
956
+ // Used to track how many iterations we do in the first loop
957
+ let loopsInFirstIteration = 0;
958
+ // Filtering step for up to first hop
959
+ // The pools are pre-sorted, so we can just iterate through them and fill our heuristics.
960
+ for (const subgraphPool of subgraphPoolsSorted) {
961
+ loopsInFirstIteration += 1;
962
+ // Check if we have satisfied all the heuristics, if so, we can stop.
963
+ if (topByBaseWithTokenInPoolsFound >= topNWithBaseToken &&
964
+ topByBaseWithTokenOutPoolsFound >= topNWithBaseToken &&
965
+ topByEthQuoteTokenPool.length >= topNEthQuoteToken &&
966
+ topByTVL.length >= topN &&
967
+ topByTVLUsingTokenIn.length >= topNTokenInOut &&
968
+ topByTVLUsingTokenOut.length >= topNTokenInOut) {
969
+ // We have satisfied all the heuristics, so we can stop.
970
+ break;
971
+ }
972
+ if (poolAddressesSoFar.has(subgraphPool.id)) {
973
+ // We've already added this pool, so skip it.
974
+ continue;
975
+ }
976
+ // Only consider pools where neither tokens are in the blocked token list.
977
+ if (blockedTokenListProvider) {
978
+ const [token0InBlocklist, token1InBlocklist] = await Promise.all([
979
+ blockedTokenListProvider.hasTokenByAddress(subgraphPool.token0.id),
980
+ blockedTokenListProvider.hasTokenByAddress(subgraphPool.token1.id),
981
+ ]);
982
+ if (token0InBlocklist || token1InBlocklist) {
983
+ continue;
984
+ }
985
+ }
986
+ const tokenInToken0TopByBase = topByBaseWithTokenInMap.get(subgraphPool.token0.id);
987
+ if (topByBaseWithTokenInPoolsFound < topNWithBaseToken &&
988
+ tokenInToken0TopByBase &&
989
+ subgraphPool.token0.id != tokenOutAddress &&
990
+ subgraphPool.token1.id == tokenInAddress) {
991
+ topByBaseWithTokenInPoolsFound += 1;
992
+ poolAddressesSoFar.add(subgraphPool.id);
993
+ if (topByTVLUsingTokenIn.length < topNTokenInOut) {
994
+ topByTVLUsingTokenIn.push(subgraphPool);
995
+ }
996
+ if (routeType === TradeType.EXACT_OUTPUT &&
997
+ subgraphPool.token0.id == wethAddress) {
998
+ topByEthQuoteTokenPool.push(subgraphPool);
999
+ }
1000
+ tokenInToken0TopByBase.pools.push(subgraphPool);
1001
+ continue;
1002
+ }
1003
+ const tokenInToken1TopByBase = topByBaseWithTokenInMap.get(subgraphPool.token1.id);
1004
+ if (topByBaseWithTokenInPoolsFound < topNWithBaseToken &&
1005
+ tokenInToken1TopByBase &&
1006
+ subgraphPool.token0.id == tokenInAddress &&
1007
+ subgraphPool.token1.id != tokenOutAddress) {
1008
+ topByBaseWithTokenInPoolsFound += 1;
1009
+ poolAddressesSoFar.add(subgraphPool.id);
1010
+ if (topByTVLUsingTokenIn.length < topNTokenInOut) {
1011
+ topByTVLUsingTokenIn.push(subgraphPool);
1012
+ }
1013
+ if (routeType === TradeType.EXACT_OUTPUT &&
1014
+ subgraphPool.token1.id == wethAddress) {
1015
+ topByEthQuoteTokenPool.push(subgraphPool);
1016
+ }
1017
+ tokenInToken1TopByBase.pools.push(subgraphPool);
1018
+ continue;
1019
+ }
1020
+ const tokenOutToken0TopByBase = topByBaseWithTokenOutMap.get(subgraphPool.token0.id);
1021
+ if (topByBaseWithTokenOutPoolsFound < topNWithBaseToken &&
1022
+ tokenOutToken0TopByBase &&
1023
+ subgraphPool.token0.id != tokenInAddress &&
1024
+ subgraphPool.token1.id == tokenOutAddress) {
1025
+ topByBaseWithTokenOutPoolsFound += 1;
1026
+ poolAddressesSoFar.add(subgraphPool.id);
1027
+ if (topByTVLUsingTokenOut.length < topNTokenInOut) {
1028
+ topByTVLUsingTokenOut.push(subgraphPool);
1029
+ }
1030
+ if (routeType === TradeType.EXACT_INPUT &&
1031
+ subgraphPool.token0.id == wethAddress) {
1032
+ topByEthQuoteTokenPool.push(subgraphPool);
1033
+ }
1034
+ tokenOutToken0TopByBase.pools.push(subgraphPool);
1035
+ continue;
1036
+ }
1037
+ const tokenOutToken1TopByBase = topByBaseWithTokenOutMap.get(subgraphPool.token1.id);
1038
+ if (topByBaseWithTokenOutPoolsFound < topNWithBaseToken &&
1039
+ tokenOutToken1TopByBase &&
1040
+ subgraphPool.token0.id == tokenOutAddress &&
1041
+ subgraphPool.token1.id != tokenInAddress) {
1042
+ topByBaseWithTokenOutPoolsFound += 1;
1043
+ poolAddressesSoFar.add(subgraphPool.id);
1044
+ if (topByTVLUsingTokenOut.length < topNTokenInOut) {
1045
+ topByTVLUsingTokenOut.push(subgraphPool);
1046
+ }
1047
+ if (routeType === TradeType.EXACT_INPUT &&
1048
+ subgraphPool.token1.id == wethAddress) {
1049
+ topByEthQuoteTokenPool.push(subgraphPool);
1050
+ }
1051
+ tokenOutToken1TopByBase.pools.push(subgraphPool);
1052
+ continue;
1053
+ }
1054
+ // Note: we do not need to check other native currencies for the V2 Protocol
1055
+ if (topByEthQuoteTokenPool.length < topNEthQuoteToken &&
1056
+ ((routeType === TradeType.EXACT_INPUT &&
1057
+ ((subgraphPool.token0.id == wethAddress &&
1058
+ subgraphPool.token1.id == tokenOutAddress) ||
1059
+ (subgraphPool.token1.id == wethAddress &&
1060
+ subgraphPool.token0.id == tokenOutAddress))) ||
1061
+ (routeType === TradeType.EXACT_OUTPUT &&
1062
+ ((subgraphPool.token0.id == wethAddress &&
1063
+ subgraphPool.token1.id == tokenInAddress) ||
1064
+ (subgraphPool.token1.id == wethAddress &&
1065
+ subgraphPool.token0.id == tokenInAddress))))) {
1066
+ poolAddressesSoFar.add(subgraphPool.id);
1067
+ topByEthQuoteTokenPool.push(subgraphPool);
1068
+ continue;
1069
+ }
1070
+ if (topByTVL.length < topN) {
1071
+ poolAddressesSoFar.add(subgraphPool.id);
1072
+ topByTVL.push(subgraphPool);
1073
+ continue;
1074
+ }
1075
+ if (topByTVLUsingTokenIn.length < topNTokenInOut &&
1076
+ (subgraphPool.token0.id == tokenInAddress ||
1077
+ subgraphPool.token1.id == tokenInAddress)) {
1078
+ poolAddressesSoFar.add(subgraphPool.id);
1079
+ topByTVLUsingTokenIn.push(subgraphPool);
1080
+ continue;
1081
+ }
1082
+ if (topByTVLUsingTokenOut.length < topNTokenInOut &&
1083
+ (subgraphPool.token0.id == tokenOutAddress ||
1084
+ subgraphPool.token1.id == tokenOutAddress)) {
1085
+ poolAddressesSoFar.add(subgraphPool.id);
1086
+ topByTVLUsingTokenOut.push(subgraphPool);
1087
+ continue;
1088
+ }
1089
+ }
1090
+ metric.putMetric('V2SubgraphLoopsInFirstIteration', loopsInFirstIteration, MetricLoggerUnit.Count);
1091
+ const topByBaseWithTokenIn = [];
1092
+ for (const topByBaseWithTokenInSelection of topByBaseWithTokenInMap.values()) {
1093
+ topByBaseWithTokenIn.push(...topByBaseWithTokenInSelection.pools);
1094
+ }
1095
+ const topByBaseWithTokenOut = [];
1096
+ for (const topByBaseWithTokenOutSelection of topByBaseWithTokenOutMap.values()) {
1097
+ topByBaseWithTokenOut.push(...topByBaseWithTokenOutSelection.pools);
1098
+ }
1099
+ // Filtering step for second hops
1100
+ const topByTVLUsingTokenInSecondHopsMap = new Map();
1101
+ const topByTVLUsingTokenOutSecondHopsMap = new Map();
1102
+ const tokenInSecondHopAddresses = topByTVLUsingTokenIn
1103
+ .filter((pool) => {
1104
+ // filtering second hops
1105
+ if (tokenInAddress === pool.token0.id) {
1106
+ return !(tokensToAvoidOnSecondHops === null || tokensToAvoidOnSecondHops === void 0 ? void 0 : tokensToAvoidOnSecondHops.includes(pool.token1.id.toLowerCase()));
1107
+ }
1108
+ else {
1109
+ return !(tokensToAvoidOnSecondHops === null || tokensToAvoidOnSecondHops === void 0 ? void 0 : tokensToAvoidOnSecondHops.includes(pool.token0.id.toLowerCase()));
1110
+ }
1111
+ })
1112
+ .map((pool) => tokenInAddress === pool.token0.id ? pool.token1.id : pool.token0.id);
1113
+ const tokenOutSecondHopAddresses = topByTVLUsingTokenOut
1114
+ .filter((pool) => {
1115
+ // filtering second hops
1116
+ if (tokenOutAddress === pool.token0.id) {
1117
+ return !(tokensToAvoidOnSecondHops === null || tokensToAvoidOnSecondHops === void 0 ? void 0 : tokensToAvoidOnSecondHops.includes(pool.token1.id.toLowerCase()));
1118
+ }
1119
+ else {
1120
+ return !(tokensToAvoidOnSecondHops === null || tokensToAvoidOnSecondHops === void 0 ? void 0 : tokensToAvoidOnSecondHops.includes(pool.token0.id.toLowerCase()));
1121
+ }
1122
+ })
1123
+ .map((pool) => tokenOutAddress === pool.token0.id ? pool.token1.id : pool.token0.id);
1124
+ for (const secondHopId of tokenInSecondHopAddresses) {
1125
+ topByTVLUsingTokenInSecondHopsMap.set(secondHopId, new SubcategorySelectionPools([], topNSecondHop));
1126
+ }
1127
+ for (const secondHopId of tokenOutSecondHopAddresses) {
1128
+ topByTVLUsingTokenOutSecondHopsMap.set(secondHopId, new SubcategorySelectionPools([], topNSecondHop));
1129
+ }
1130
+ // Used to track how many iterations we do in the second loop
1131
+ let loopsInSecondIteration = 0;
1132
+ if (tokenInSecondHopAddresses.length > 0 ||
1133
+ tokenOutSecondHopAddresses.length > 0) {
1134
+ for (const subgraphPool of subgraphPoolsSorted) {
1135
+ loopsInSecondIteration += 1;
1136
+ let allTokenInSecondHopsHaveTheirTopN = true;
1137
+ for (const secondHopPools of topByTVLUsingTokenInSecondHopsMap.values()) {
1138
+ if (!secondHopPools.hasEnoughPools()) {
1139
+ allTokenInSecondHopsHaveTheirTopN = false;
1140
+ break;
1141
+ }
1142
+ }
1143
+ let allTokenOutSecondHopsHaveTheirTopN = true;
1144
+ for (const secondHopPools of topByTVLUsingTokenOutSecondHopsMap.values()) {
1145
+ if (!secondHopPools.hasEnoughPools()) {
1146
+ allTokenOutSecondHopsHaveTheirTopN = false;
1147
+ break;
1148
+ }
1149
+ }
1150
+ if (allTokenInSecondHopsHaveTheirTopN &&
1151
+ allTokenOutSecondHopsHaveTheirTopN) {
1152
+ // We have satisfied all the heuristics, so we can stop.
1153
+ break;
1154
+ }
1155
+ if (poolAddressesSoFar.has(subgraphPool.id)) {
1156
+ continue;
1157
+ }
1158
+ // Only consider pools where neither tokens are in the blocked token list.
1159
+ if (blockedTokenListProvider) {
1160
+ const [token0InBlocklist, token1InBlocklist] = await Promise.all([
1161
+ blockedTokenListProvider.hasTokenByAddress(subgraphPool.token0.id),
1162
+ blockedTokenListProvider.hasTokenByAddress(subgraphPool.token1.id),
1163
+ ]);
1164
+ if (token0InBlocklist || token1InBlocklist) {
1165
+ continue;
1166
+ }
1167
+ }
1168
+ const tokenInToken0SecondHop = topByTVLUsingTokenInSecondHopsMap.get(subgraphPool.token0.id);
1169
+ if (tokenInToken0SecondHop && !tokenInToken0SecondHop.hasEnoughPools()) {
1170
+ poolAddressesSoFar.add(subgraphPool.id);
1171
+ tokenInToken0SecondHop.pools.push(subgraphPool);
1172
+ continue;
1173
+ }
1174
+ const tokenInToken1SecondHop = topByTVLUsingTokenInSecondHopsMap.get(subgraphPool.token1.id);
1175
+ if (tokenInToken1SecondHop && !tokenInToken1SecondHop.hasEnoughPools()) {
1176
+ poolAddressesSoFar.add(subgraphPool.id);
1177
+ tokenInToken1SecondHop.pools.push(subgraphPool);
1178
+ continue;
1179
+ }
1180
+ const tokenOutToken0SecondHop = topByTVLUsingTokenOutSecondHopsMap.get(subgraphPool.token0.id);
1181
+ if (tokenOutToken0SecondHop &&
1182
+ !tokenOutToken0SecondHop.hasEnoughPools()) {
1183
+ poolAddressesSoFar.add(subgraphPool.id);
1184
+ tokenOutToken0SecondHop.pools.push(subgraphPool);
1185
+ continue;
1186
+ }
1187
+ const tokenOutToken1SecondHop = topByTVLUsingTokenOutSecondHopsMap.get(subgraphPool.token1.id);
1188
+ if (tokenOutToken1SecondHop &&
1189
+ !tokenOutToken1SecondHop.hasEnoughPools()) {
1190
+ poolAddressesSoFar.add(subgraphPool.id);
1191
+ tokenOutToken1SecondHop.pools.push(subgraphPool);
1192
+ continue;
1193
+ }
1194
+ }
1195
+ }
1196
+ metric.putMetric('V2SubgraphLoopsInSecondIteration', loopsInSecondIteration, MetricLoggerUnit.Count);
1197
+ const topByTVLUsingTokenInSecondHops = [];
1198
+ for (const secondHopPools of topByTVLUsingTokenInSecondHopsMap.values()) {
1199
+ topByTVLUsingTokenInSecondHops.push(...secondHopPools.pools);
1200
+ }
1201
+ const topByTVLUsingTokenOutSecondHops = [];
1202
+ for (const secondHopPools of topByTVLUsingTokenOutSecondHopsMap.values()) {
1203
+ topByTVLUsingTokenOutSecondHops.push(...secondHopPools.pools);
1204
+ }
1205
+ const subgraphPools = _([
1206
+ ...topByBaseWithTokenIn,
1207
+ ...topByBaseWithTokenOut,
1208
+ ...topByDirectSwapPool,
1209
+ ...topByEthQuoteTokenPool,
1210
+ ...topByTVL,
1211
+ ...topByTVLUsingTokenIn,
1212
+ ...topByTVLUsingTokenOut,
1213
+ ...topByTVLUsingTokenInSecondHops,
1214
+ ...topByTVLUsingTokenOutSecondHops,
1215
+ ])
1216
+ .uniqBy((pool) => pool.id)
1217
+ .value();
1218
+ const tokenAddressesSet = new Set();
1219
+ for (const pool of subgraphPools) {
1220
+ tokenAddressesSet.add(pool.token0.id);
1221
+ tokenAddressesSet.add(pool.token1.id);
1222
+ }
1223
+ const tokenAddresses = Array.from(tokenAddressesSet);
1224
+ log.info(`Getting the ${tokenAddresses.length} tokens within the ${subgraphPools.length} V2 pools we are considering`);
1225
+ const tokenAccessor = await tokenProvider.getTokens(tokenAddresses, {
1226
+ blockNumber,
1227
+ });
1228
+ const printV2SubgraphPool = (s) => {
1229
+ var _a, _b, _c, _d;
1230
+ 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}`;
1231
+ };
1232
+ log.info({
1233
+ topByBaseWithTokenIn: topByBaseWithTokenIn.map(printV2SubgraphPool),
1234
+ topByBaseWithTokenOut: topByBaseWithTokenOut.map(printV2SubgraphPool),
1235
+ topByTVL: topByTVL.map(printV2SubgraphPool),
1236
+ topByTVLUsingTokenIn: topByTVLUsingTokenIn.map(printV2SubgraphPool),
1237
+ topByTVLUsingTokenOut: topByTVLUsingTokenOut.map(printV2SubgraphPool),
1238
+ topByTVLUsingTokenInSecondHops: topByTVLUsingTokenInSecondHops.map(printV2SubgraphPool),
1239
+ topByTVLUsingTokenOutSecondHops: topByTVLUsingTokenOutSecondHops.map(printV2SubgraphPool),
1240
+ top2DirectSwap: topByDirectSwapPool.map(printV2SubgraphPool),
1241
+ top2EthQuotePool: topByEthQuoteTokenPool.map(printV2SubgraphPool),
1242
+ }, `V2 Candidate pools`);
1243
+ const tokenPairsRaw = _.map(subgraphPools, (subgraphPool) => {
1244
+ const tokenA = tokenAccessor.getTokenByAddress(subgraphPool.token0.id);
1245
+ const tokenB = tokenAccessor.getTokenByAddress(subgraphPool.token1.id);
1246
+ if (!tokenA || !tokenB) {
1247
+ log.info(`Dropping candidate pool for ${subgraphPool.token0.id}/${subgraphPool.token1.id}`);
1248
+ return undefined;
1249
+ }
1250
+ return [tokenA, tokenB];
1251
+ });
1252
+ const tokenPairs = _.compact(tokenPairsRaw);
1253
+ metric.putMetric('V2PoolsFilterLoad', Date.now() - beforePoolsFiltered, MetricLoggerUnit.Milliseconds);
1254
+ const beforePoolsLoad = Date.now();
1255
+ // this should be the only place to enable fee-on-transfer fee fetching,
1256
+ // because this places loads pools (pairs of tokens with fot taxes) from the subgraph
1257
+ const poolAccessor = await poolProvider.getPools(tokenPairs, routingConfig);
1258
+ metric.putMetric('V2PoolsLoad', Date.now() - beforePoolsLoad, MetricLoggerUnit.Milliseconds);
1259
+ const poolsBySelection = {
1260
+ protocol: Protocol.V2,
1261
+ selections: {
1262
+ topByBaseWithTokenIn,
1263
+ topByBaseWithTokenOut,
1264
+ topByDirectSwapPool,
1265
+ topByEthQuoteTokenPool,
1266
+ topByTVL,
1267
+ topByTVLUsingTokenIn,
1268
+ topByTVLUsingTokenOut,
1269
+ topByTVLUsingTokenInSecondHops,
1270
+ topByTVLUsingTokenOutSecondHops,
1271
+ },
1272
+ };
1273
+ return { poolAccessor, candidatePools: poolsBySelection, subgraphPools };
1274
+ }
1275
+ export async function getMixedRouteCandidatePools({ v4CandidatePools, v3CandidatePools, v2CandidatePools, crossLiquidityPools, routingConfig, tokenProvider, v4PoolProvider, v3poolProvider, v2poolProvider, chainId, }) {
1276
+ const beforeSubgraphPools = Date.now();
1277
+ const [v4Results, v3Results, v2Results] = [
1278
+ v4CandidatePools,
1279
+ v3CandidatePools,
1280
+ v2CandidatePools,
1281
+ ];
1282
+ // Create empty defaults for undefined results
1283
+ const { subgraphPools: V4subgraphPools = [], candidatePools: V4candidatePools = {
1284
+ protocol: Protocol.V4,
1285
+ selections: {
1286
+ topByBaseWithTokenIn: [],
1287
+ topByBaseWithTokenOut: [],
1288
+ topByDirectSwapPool: [],
1289
+ topByEthQuoteTokenPool: [],
1290
+ topByTVL: [],
1291
+ topByTVLUsingTokenIn: [],
1292
+ topByTVLUsingTokenOut: [],
1293
+ topByTVLUsingTokenInSecondHops: [],
1294
+ topByTVLUsingTokenOutSecondHops: [],
1295
+ },
1296
+ }, } = v4Results || {};
1297
+ const { subgraphPools: V3subgraphPools = [], candidatePools: V3candidatePools = {
1298
+ protocol: Protocol.V3,
1299
+ selections: {
1300
+ topByBaseWithTokenIn: [],
1301
+ topByBaseWithTokenOut: [],
1302
+ topByDirectSwapPool: [],
1303
+ topByEthQuoteTokenPool: [],
1304
+ topByTVL: [],
1305
+ topByTVLUsingTokenIn: [],
1306
+ topByTVLUsingTokenOut: [],
1307
+ topByTVLUsingTokenInSecondHops: [],
1308
+ topByTVLUsingTokenOutSecondHops: [],
1309
+ },
1310
+ }, } = v3Results || {};
1311
+ const { subgraphPools: V2subgraphPools = [], candidatePools: V2candidatePools = {
1312
+ protocol: Protocol.V2,
1313
+ selections: {
1314
+ topByBaseWithTokenIn: [],
1315
+ topByBaseWithTokenOut: [],
1316
+ topByDirectSwapPool: [],
1317
+ topByEthQuoteTokenPool: [],
1318
+ topByTVL: [],
1319
+ topByTVLUsingTokenIn: [],
1320
+ topByTVLUsingTokenOut: [],
1321
+ topByTVLUsingTokenInSecondHops: [],
1322
+ topByTVLUsingTokenOutSecondHops: [],
1323
+ },
1324
+ }, } = v2Results || {};
1325
+ // Injects the liquidity pools found by the getMixedCrossLiquidityCandidatePools function
1326
+ V2subgraphPools.push(...crossLiquidityPools.v2Pools);
1327
+ V3subgraphPools.push(...crossLiquidityPools.v3Pools);
1328
+ V4subgraphPools.push(...crossLiquidityPools.v4Pools);
1329
+ metric.putMetric('MixedSubgraphPoolsLoad', Date.now() - beforeSubgraphPools, MetricLoggerUnit.Milliseconds);
1330
+ const beforePoolsFiltered = Date.now();
1331
+ /**
1332
+ * Main heuristic for pruning mixedRoutes:
1333
+ * - we pick V2 pools with higher liq than respective V3 pools, or if the v3 pool doesn't exist
1334
+ *
1335
+ * This way we can reduce calls to our provider since it's possible to generate a lot of mixed routes
1336
+ */
1337
+ /// We only really care about pools involving the tokenIn or tokenOut explictly,
1338
+ /// since there's no way a long tail token in V2 would be routed through as an intermediary
1339
+ const V2topByTVLPoolIds = new Set([
1340
+ ...V2candidatePools.selections.topByTVLUsingTokenIn,
1341
+ ...V2candidatePools.selections.topByBaseWithTokenIn,
1342
+ /// tokenOut:
1343
+ ...V2candidatePools.selections.topByTVLUsingTokenOut,
1344
+ ...V2candidatePools.selections.topByBaseWithTokenOut,
1345
+ /// Direct swap:
1346
+ ...V2candidatePools.selections.topByDirectSwapPool,
1347
+ // Cross Liquidity (has to be added to be considered):
1348
+ ...crossLiquidityPools.v2Pools,
1349
+ ].map((poolId) => poolId.id));
1350
+ const V2topByTVLSortedPools = _(V2subgraphPools)
1351
+ .filter((pool) => V2topByTVLPoolIds.has(pool.id))
1352
+ .sortBy((pool) => -pool.reserveUSD)
1353
+ .value();
1354
+ /// we consider all returned V3 pools for this heuristic to "fill in the gaps"
1355
+ const V3sortedPools = _(V3subgraphPools)
1356
+ .sortBy((pool) => -pool.tvlUSD)
1357
+ .value();
1358
+ const V4sortedPools = _(V4subgraphPools)
1359
+ .sortBy((pool) => -pool.tvlUSD)
1360
+ .value();
1361
+ /// Finding pools with greater reserveUSD on v2 than tvlUSD on v3, or if there is no v3 liquidity
1362
+ const buildV2Pools = [];
1363
+ V2topByTVLSortedPools.forEach((V2subgraphPool) => {
1364
+ const V3subgraphPool = V3sortedPools.find((pool) => (pool.token0.id == V2subgraphPool.token0.id &&
1365
+ pool.token1.id == V2subgraphPool.token1.id) ||
1366
+ (pool.token0.id == V2subgraphPool.token1.id &&
1367
+ pool.token1.id == V2subgraphPool.token0.id));
1368
+ if (V3subgraphPool) {
1369
+ if (V2subgraphPool.reserveUSD > V3subgraphPool.tvlUSD) {
1370
+ log.info({
1371
+ token0: V2subgraphPool.token0.id,
1372
+ token1: V2subgraphPool.token1.id,
1373
+ v2reserveUSD: V2subgraphPool.reserveUSD,
1374
+ v3tvlUSD: V3subgraphPool.tvlUSD,
1375
+ }, `MixedRoute heuristic, found a V2 pool with higher liquidity than its V3 counterpart`);
1376
+ buildV2Pools.push(V2subgraphPool);
1377
+ }
1378
+ }
1379
+ else {
1380
+ log.info({
1381
+ token0: V2subgraphPool.token0.id,
1382
+ token1: V2subgraphPool.token1.id,
1383
+ v2reserveUSD: V2subgraphPool.reserveUSD,
1384
+ }, `MixedRoute heuristic, found a V2 pool with no V3 counterpart`);
1385
+ buildV2Pools.push(V2subgraphPool);
1386
+ }
1387
+ const V4subgraphPool = V4sortedPools.find((pool) => (pool.token0.id == V2subgraphPool.token0.id &&
1388
+ pool.token1.id == V2subgraphPool.token1.id) ||
1389
+ (pool.token0.id == V2subgraphPool.token1.id &&
1390
+ pool.token1.id == V2subgraphPool.token0.id));
1391
+ if (V4subgraphPool) {
1392
+ if (V2subgraphPool.reserveUSD > V4subgraphPool.tvlUSD) {
1393
+ log.info({
1394
+ token0: V2subgraphPool.token0.id,
1395
+ token1: V2subgraphPool.token1.id,
1396
+ v2reserveUSD: V2subgraphPool.reserveUSD,
1397
+ v4tvlUSD: V4subgraphPool.tvlUSD,
1398
+ }, `MixedRoute heuristic, found a V2 pool with higher liquidity than its V4 counterpart`);
1399
+ buildV2Pools.push(V2subgraphPool);
1400
+ }
1401
+ }
1402
+ else {
1403
+ log.info({
1404
+ token0: V2subgraphPool.token0.id,
1405
+ token1: V2subgraphPool.token1.id,
1406
+ v2reserveUSD: V2subgraphPool.reserveUSD,
1407
+ }, `MixedRoute heuristic, found a V2 pool with no V3 counterpart`);
1408
+ buildV2Pools.push(V2subgraphPool);
1409
+ }
1410
+ });
1411
+ log.info(buildV2Pools.length, `Number of V2 candidate pools that fit first heuristic`);
1412
+ const subgraphPools = [...buildV2Pools, ...V3sortedPools, ...V4sortedPools];
1413
+ const tokenAddresses = _(subgraphPools)
1414
+ .flatMap((subgraphPool) => [subgraphPool.token0.id, subgraphPool.token1.id])
1415
+ .compact()
1416
+ .uniq()
1417
+ .value();
1418
+ log.info(`Getting the ${tokenAddresses.length} tokens within the ${subgraphPools.length} pools we are considering`);
1419
+ const tokenAccessor = await tokenProvider.getTokens(tokenAddresses, routingConfig);
1420
+ const V4tokenPairsRaw = _.map(V4sortedPools, (subgraphPool) => {
1421
+ // native currency is not erc20 token, therefore there's no way to retrieve native currency metadata as the erc20 token.
1422
+ const tokenA = isNativeCurrency(subgraphPool.token0.id)
1423
+ ? nativeOnChain(chainId)
1424
+ : tokenAccessor.getTokenByAddress(subgraphPool.token0.id);
1425
+ const tokenB = isNativeCurrency(subgraphPool.token1.id)
1426
+ ? nativeOnChain(chainId)
1427
+ : tokenAccessor.getTokenByAddress(subgraphPool.token1.id);
1428
+ let fee;
1429
+ try {
1430
+ fee = Number(subgraphPool.feeTier);
1431
+ }
1432
+ catch (err) {
1433
+ log.info({ subgraphPool }, `Dropping candidate pool for ${subgraphPool.token0.id}/${subgraphPool.token1.id}/${subgraphPool.feeTier}/${subgraphPool.tickSpacing}/${subgraphPool.hooks} because fee tier not supported`);
1434
+ return undefined;
1435
+ }
1436
+ if (!tokenA || !tokenB) {
1437
+ log.info(`Dropping candidate pool for ${subgraphPool.token0.id}/${subgraphPool.token1.id}/${fee}/${subgraphPool.tickSpacing}/${subgraphPool.hooks} because ${tokenA ? subgraphPool.token1.id : subgraphPool.token0.id} not found by token provider`);
1438
+ return undefined;
1439
+ }
1440
+ return [
1441
+ tokenA,
1442
+ tokenB,
1443
+ fee,
1444
+ Number(subgraphPool.tickSpacing),
1445
+ subgraphPool.hooks,
1446
+ ];
1447
+ });
1448
+ const V4tokenPairs = _.compact(V4tokenPairsRaw);
1449
+ const V3tokenPairsRaw = _.map(V3sortedPools, (subgraphPool) => {
1450
+ const tokenA = tokenAccessor.getTokenByAddress(subgraphPool.token0.id);
1451
+ const tokenB = tokenAccessor.getTokenByAddress(subgraphPool.token1.id);
1452
+ let fee;
1453
+ try {
1454
+ fee = parseFeeAmount(subgraphPool.feeTier);
1455
+ }
1456
+ catch (err) {
1457
+ log.info({ subgraphPool }, `Dropping candidate pool for ${subgraphPool.token0.id}/${subgraphPool.token1.id}/${subgraphPool.feeTier} because fee tier not supported`);
1458
+ return undefined;
1459
+ }
1460
+ if (!tokenA || !tokenB) {
1461
+ 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`);
1462
+ return undefined;
1463
+ }
1464
+ return [tokenA, tokenB, fee];
1465
+ });
1466
+ const V3tokenPairs = _.compact(V3tokenPairsRaw);
1467
+ const V2tokenPairsRaw = _.map(buildV2Pools, (subgraphPool) => {
1468
+ const tokenA = tokenAccessor.getTokenByAddress(subgraphPool.token0.id);
1469
+ const tokenB = tokenAccessor.getTokenByAddress(subgraphPool.token1.id);
1470
+ if (!tokenA || !tokenB) {
1471
+ log.info(`Dropping candidate pool for ${subgraphPool.token0.id}/${subgraphPool.token1.id}`);
1472
+ return undefined;
1473
+ }
1474
+ return [tokenA, tokenB];
1475
+ });
1476
+ const V2tokenPairs = _.compact(V2tokenPairsRaw);
1477
+ metric.putMetric('MixedPoolsFilterLoad', Date.now() - beforePoolsFiltered, MetricLoggerUnit.Milliseconds);
1478
+ const beforePoolsLoad = Date.now();
1479
+ const [V2poolAccessor, V3poolAccessor, V4poolAccessor] = await Promise.all([
1480
+ v2poolProvider.getPools(V2tokenPairs, routingConfig),
1481
+ v3poolProvider.getPools(V3tokenPairs, routingConfig),
1482
+ v4PoolProvider.getPools(V4tokenPairs, routingConfig),
1483
+ ]);
1484
+ metric.putMetric('MixedPoolsLoad', Date.now() - beforePoolsLoad, MetricLoggerUnit.Milliseconds);
1485
+ /// @dev a bit tricky here since the original V2CandidateSelections object included pools that we may have dropped
1486
+ /// as part of the heuristic. We need to reconstruct a new object with the v3 pools too.
1487
+ const buildPoolsBySelection = (key) => {
1488
+ return [
1489
+ ...buildV2Pools.filter((pool) => V2candidatePools.selections[key].map((p) => p.id).includes(pool.id)),
1490
+ ...V3candidatePools.selections[key],
1491
+ ...V4candidatePools.selections[key],
1492
+ ];
1493
+ };
1494
+ const poolsBySelection = {
1495
+ protocol: Protocol.MIXED,
1496
+ selections: {
1497
+ topByBaseWithTokenIn: buildPoolsBySelection('topByBaseWithTokenIn'),
1498
+ topByBaseWithTokenOut: buildPoolsBySelection('topByBaseWithTokenOut'),
1499
+ topByDirectSwapPool: buildPoolsBySelection('topByDirectSwapPool'),
1500
+ topByEthQuoteTokenPool: buildPoolsBySelection('topByEthQuoteTokenPool'),
1501
+ topByTVL: buildPoolsBySelection('topByTVL'),
1502
+ topByTVLUsingTokenIn: buildPoolsBySelection('topByTVLUsingTokenIn'),
1503
+ topByTVLUsingTokenOut: buildPoolsBySelection('topByTVLUsingTokenOut'),
1504
+ topByTVLUsingTokenInSecondHops: buildPoolsBySelection('topByTVLUsingTokenInSecondHops'),
1505
+ topByTVLUsingTokenOutSecondHops: buildPoolsBySelection('topByTVLUsingTokenOutSecondHops'),
1506
+ },
1507
+ };
1508
+ return {
1509
+ V2poolAccessor,
1510
+ V3poolAccessor,
1511
+ V4poolAccessor,
1512
+ candidatePools: poolsBySelection,
1513
+ subgraphPools,
1514
+ };
1515
+ }
1516
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0LWNhbmRpZGF0ZS1wb29scy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9yb3V0ZXJzL2FscGhhLXJvdXRlci9mdW5jdGlvbnMvZ2V0LWNhbmRpZGF0ZS1wb29scy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzdELE9BQU8sRUFBRSxPQUFPLEVBQW1CLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRWpFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ25ELE9BQU8sQ0FBQyxNQUFNLFFBQVEsQ0FBQztBQUd2QixPQUFPLEVBQ0wsb0JBQW9CLEVBQ3BCLGdCQUFnQixFQUtoQixxQkFBcUIsRUFDckIscUJBQXFCLEVBQ3JCLHFCQUFxQixFQUlyQixxQkFBcUIsR0FDdEIsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QixPQUFPLEVBQ0wsSUFBSSxFQUNKLGNBQWMsRUFDZCxTQUFTLEVBQ1QsbUJBQW1CLEVBQ25CLFNBQVMsRUFDVCxtQkFBbUIsRUFDbkIsWUFBWSxFQUNaLFFBQVEsRUFDUixPQUFPLEVBQ1AsV0FBVyxFQUNYLFlBQVksRUFDWixZQUFZLEVBQ1osbUJBQW1CLEVBQ25CLGtCQUFrQixFQUNsQixXQUFXLEVBQ1gsWUFBWSxFQUNaLFdBQVcsRUFFWCxVQUFVLEVBQ1YsYUFBYSxFQUNiLG9CQUFvQixFQUNwQixTQUFTLEVBQ1QsU0FBUyxFQUNULGlCQUFpQixFQUNqQixRQUFRLEVBQ1Isb0JBQW9CLEVBQ3BCLFlBQVksRUFDWixVQUFVLEVBQ1YsYUFBYSxFQUNiLGFBQWEsRUFDYixvQkFBb0IsRUFDcEIsWUFBWSxFQUNaLFlBQVksRUFDWixZQUFZLEVBQ1osYUFBYSxFQUNiLGFBQWEsRUFDYixR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