@hkdex-tmp/smart-order-router 4.31.0

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