@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,1681 @@
1
+ import { BigNumber } from '@ethersproject/bignumber';
2
+ import { JsonRpcProvider } from '@ethersproject/providers';
3
+ import DEFAULT_TOKEN_LIST from '@uniswap/default-token-list';
4
+ import { Protocol, SwapRouter, ZERO, } from '@uniswap/router-sdk';
5
+ import { ChainId, Fraction, TradeType, } from '@uniswap/sdk-core';
6
+ import { UniversalRouterVersion } from '@uniswap/universal-router-sdk';
7
+ import { Pair as V2Pool } from '@uniswap/v2-sdk';
8
+ import { Pool, Pool as V3Pool, Position, SqrtPriceMath, TickMath, } from '@uniswap/v3-sdk';
9
+ import { Pool as V4Pool } from '@uniswap/v4-sdk';
10
+ import retry from 'async-retry';
11
+ import JSBI from 'jsbi';
12
+ import _ from 'lodash';
13
+ import NodeCache from 'node-cache';
14
+ import { CachedRoutes, CacheMode, CachingGasStationProvider, CachingTokenProviderWithFallback, CachingV2PoolProvider, CachingV2SubgraphProvider, CachingV3PoolProvider, CachingV3SubgraphProvider, CachingV4SubgraphProvider, EIP1559GasPriceProvider, ETHGasStationInfoProvider, LegacyGasPriceProvider, NodeJSCache, OnChainGasPriceProvider, OnChainQuoteProvider, SimulationStatus, StaticV2SubgraphProvider, StaticV3SubgraphProvider, StaticV4SubgraphProvider, SwapRouterProvider, TokenPropertiesProvider, UniswapMulticallProvider, URISubgraphProvider, V2QuoteProvider, V2SubgraphProviderWithFallBacks, V3SubgraphProviderWithFallBacks, V4SubgraphProviderWithFallBacks, } from '../../providers';
15
+ import { CachingTokenListProvider, } from '../../providers/caching-token-list-provider';
16
+ import { PortionProvider, } from '../../providers/portion-provider';
17
+ import { OnChainTokenFeeFetcher } from '../../providers/token-fee-fetcher';
18
+ import { TokenProvider } from '../../providers/token-provider';
19
+ import { TokenValidatorProvider, } from '../../providers/token-validator-provider';
20
+ import { V2PoolProvider, } from '../../providers/v2/pool-provider';
21
+ import { ArbitrumGasDataProvider, } from '../../providers/v3/gas-data-provider';
22
+ import { V3PoolProvider, } from '../../providers/v3/pool-provider';
23
+ import { CachingV4PoolProvider } from '../../providers/v4/caching-pool-provider';
24
+ import { V4PoolProvider, } from '../../providers/v4/pool-provider';
25
+ import { Erc20__factory } from '../../types/other/factories/Erc20__factory';
26
+ import { getAddress, getAddressLowerCase, getApplicableV4FeesTickspacingsHooks, HooksOptions, MIXED_CROSS_LIQUIDITY_V3_AGAINST_V4_SUPPORTED, MIXED_SUPPORTED, shouldWipeoutCachedRoutes, SWAP_ROUTER_02_ADDRESSES, V4_SUPPORTED, WRAPPED_NATIVE_CURRENCY, } from '../../util';
27
+ import { CurrencyAmount } from '../../util/amounts';
28
+ import { ID_TO_CHAIN_ID, ID_TO_NETWORK_NAME, V2_SUPPORTED, } from '../../util/chains';
29
+ import { DEFAULT_BLOCKS_TO_LIVE } from '../../util/defaultBlocksToLive';
30
+ import { getHighestLiquidityV3NativePool, getHighestLiquidityV3USDPool, } from '../../util/gas-factory-helpers';
31
+ import { INTENT } from '../../util/intent';
32
+ import { log } from '../../util/log';
33
+ import { buildSwapMethodParameters, buildTrade, } from '../../util/methodParameters';
34
+ import { metric, MetricLoggerUnit } from '../../util/metric';
35
+ import { BATCH_PARAMS, BLOCK_NUMBER_CONFIGS, DEFAULT_BATCH_PARAMS, DEFAULT_BLOCK_NUMBER_CONFIGS, DEFAULT_GAS_ERROR_FAILURE_OVERRIDES, DEFAULT_RETRY_OPTIONS, DEFAULT_SUCCESS_RATE_FAILURE_OVERRIDES, GAS_ERROR_FAILURE_OVERRIDES, RETRY_OPTIONS, SUCCESS_RATE_FAILURE_OVERRIDES, } from '../../util/onchainQuoteProviderConfigs';
36
+ import { serializeRouteIds } from '../../util/serializeRouteIds';
37
+ import { UNSUPPORTED_TOKENS } from '../../util/unsupported-tokens';
38
+ import { cloneMixedRouteWithNewPools, cloneV2RouteWithNewPools, cloneV3RouteWithNewPools, cloneV4RouteWithNewPools, SwapToRatioStatus, SwapType, } from '../router';
39
+ import { DEFAULT_ROUTING_CONFIG_BY_CHAIN, ETH_GAS_STATION_API_URL, } from './config';
40
+ import { getBestSwapRoute } from './functions/best-swap-route';
41
+ import { calculateRatioAmountIn } from './functions/calculate-ratio-amount-in';
42
+ import { getMixedCrossLiquidityCandidatePools, getV2CandidatePools, getV3CandidatePools, getV4CandidatePools, } from './functions/get-candidate-pools';
43
+ import { NATIVE_OVERHEAD } from './gas-models/gas-costs';
44
+ import { MixedRouteHeuristicGasModelFactory } from './gas-models/mixedRoute/mixed-route-heuristic-gas-model';
45
+ import { V2HeuristicGasModelFactory } from './gas-models/v2/v2-heuristic-gas-model';
46
+ import { V3HeuristicGasModelFactory } from './gas-models/v3/v3-heuristic-gas-model';
47
+ import { V4HeuristicGasModelFactory } from './gas-models/v4/v4-heuristic-gas-model';
48
+ import { MixedQuoter, V2Quoter, V3Quoter } from './quoters';
49
+ import { V4Quoter } from './quoters/v4-quoter';
50
+ export class MapWithLowerCaseKey extends Map {
51
+ set(key, value) {
52
+ return super.set(key.toLowerCase(), value);
53
+ }
54
+ }
55
+ export class LowerCaseStringArray extends Array {
56
+ constructor(...items) {
57
+ // Convert all items to lowercase before calling the parent constructor
58
+ super(...items.map((item) => item.toLowerCase()));
59
+ }
60
+ }
61
+ export class AlphaRouter {
62
+ constructor({ chainId, provider, multicall2Provider, v4SubgraphProvider, v4PoolProvider, v3PoolProvider, onChainQuoteProvider, v2PoolProvider, v2QuoteProvider, v2SubgraphProvider, tokenProvider, blockedTokenListProvider, v3SubgraphProvider, gasPriceProvider, v4GasModelFactory, v3GasModelFactory, v2GasModelFactory, mixedRouteGasModelFactory, swapRouterProvider, tokenValidatorProvider, arbitrumGasDataProvider, simulator, routeCachingProvider, tokenPropertiesProvider, portionProvider, v2Supported, v4Supported, mixedSupported, mixedCrossLiquidityV3AgainstV4Supported, v4PoolParams, cachedRoutesCacheInvalidationFixRolloutPercentage, deleteCacheEnabledChains, }) {
63
+ this.chainId = chainId;
64
+ this.provider = provider;
65
+ this.multicall2Provider =
66
+ multicall2Provider !== null && multicall2Provider !== void 0 ? multicall2Provider : new UniswapMulticallProvider(chainId, provider, 375000);
67
+ this.v4PoolProvider =
68
+ v4PoolProvider !== null && v4PoolProvider !== void 0 ? v4PoolProvider : new CachingV4PoolProvider(this.chainId, new V4PoolProvider(ID_TO_CHAIN_ID(chainId), this.multicall2Provider), new NodeJSCache(new NodeCache({ stdTTL: 360, useClones: false })));
69
+ this.v3PoolProvider =
70
+ v3PoolProvider !== null && v3PoolProvider !== void 0 ? v3PoolProvider : new CachingV3PoolProvider(this.chainId, new V3PoolProvider(ID_TO_CHAIN_ID(chainId), this.multicall2Provider), new NodeJSCache(new NodeCache({ stdTTL: 360, useClones: false })));
71
+ this.simulator = simulator;
72
+ this.routeCachingProvider = routeCachingProvider;
73
+ if (onChainQuoteProvider) {
74
+ this.onChainQuoteProvider = onChainQuoteProvider;
75
+ }
76
+ else {
77
+ switch (chainId) {
78
+ case ChainId.OPTIMISM:
79
+ case ChainId.OPTIMISM_GOERLI:
80
+ case ChainId.OPTIMISM_SEPOLIA:
81
+ this.onChainQuoteProvider = new OnChainQuoteProvider(chainId, provider, this.multicall2Provider, {
82
+ retries: 2,
83
+ minTimeout: 100,
84
+ maxTimeout: 1000,
85
+ }, (_) => {
86
+ return {
87
+ multicallChunk: 110,
88
+ gasLimitPerCall: 1200000,
89
+ quoteMinSuccessRate: 0.1,
90
+ };
91
+ }, (_) => {
92
+ return {
93
+ gasLimitOverride: 3000000,
94
+ multicallChunk: 45,
95
+ };
96
+ }, (_) => {
97
+ return {
98
+ gasLimitOverride: 3000000,
99
+ multicallChunk: 45,
100
+ };
101
+ }, (_) => {
102
+ return {
103
+ baseBlockOffset: -10,
104
+ rollback: {
105
+ enabled: true,
106
+ attemptsBeforeRollback: 1,
107
+ rollbackBlockOffset: -10,
108
+ },
109
+ };
110
+ });
111
+ break;
112
+ case ChainId.BASE:
113
+ case ChainId.BLAST:
114
+ case ChainId.ZORA:
115
+ case ChainId.WORLDCHAIN:
116
+ case ChainId.UNICHAIN_SEPOLIA:
117
+ case ChainId.MONAD_TESTNET:
118
+ case ChainId.MONAD:
119
+ case ChainId.BASE_SEPOLIA:
120
+ case ChainId.UNICHAIN:
121
+ case ChainId.BASE_GOERLI:
122
+ case ChainId.SONEIUM:
123
+ case ChainId.XLAYER:
124
+ this.onChainQuoteProvider = new OnChainQuoteProvider(chainId, provider, this.multicall2Provider, {
125
+ retries: 2,
126
+ minTimeout: 100,
127
+ maxTimeout: 1000,
128
+ }, (_) => {
129
+ return {
130
+ multicallChunk: 80,
131
+ gasLimitPerCall: 1200000,
132
+ quoteMinSuccessRate: 0.1,
133
+ };
134
+ }, (_) => {
135
+ return {
136
+ gasLimitOverride: 3000000,
137
+ multicallChunk: 45,
138
+ };
139
+ }, (_) => {
140
+ return {
141
+ gasLimitOverride: 3000000,
142
+ multicallChunk: 45,
143
+ };
144
+ }, (_) => {
145
+ return {
146
+ baseBlockOffset: -10,
147
+ rollback: {
148
+ enabled: true,
149
+ attemptsBeforeRollback: 1,
150
+ rollbackBlockOffset: -10,
151
+ },
152
+ };
153
+ });
154
+ break;
155
+ case ChainId.ZKSYNC:
156
+ this.onChainQuoteProvider = new OnChainQuoteProvider(chainId, provider, this.multicall2Provider, {
157
+ retries: 2,
158
+ minTimeout: 100,
159
+ maxTimeout: 1000,
160
+ }, (_) => {
161
+ return {
162
+ multicallChunk: 27,
163
+ gasLimitPerCall: 3000000,
164
+ quoteMinSuccessRate: 0.1,
165
+ };
166
+ }, (_) => {
167
+ return {
168
+ gasLimitOverride: 6000000,
169
+ multicallChunk: 13,
170
+ };
171
+ }, (_) => {
172
+ return {
173
+ gasLimitOverride: 6000000,
174
+ multicallChunk: 13,
175
+ };
176
+ }, (_) => {
177
+ return {
178
+ baseBlockOffset: -10,
179
+ rollback: {
180
+ enabled: true,
181
+ attemptsBeforeRollback: 1,
182
+ rollbackBlockOffset: -10,
183
+ },
184
+ };
185
+ });
186
+ break;
187
+ case ChainId.ARBITRUM_ONE:
188
+ case ChainId.ARBITRUM_GOERLI:
189
+ case ChainId.ARBITRUM_SEPOLIA:
190
+ this.onChainQuoteProvider = new OnChainQuoteProvider(chainId, provider, this.multicall2Provider, {
191
+ retries: 2,
192
+ minTimeout: 100,
193
+ maxTimeout: 1000,
194
+ }, (_) => {
195
+ return {
196
+ multicallChunk: 10,
197
+ gasLimitPerCall: 12000000,
198
+ quoteMinSuccessRate: 0.1,
199
+ };
200
+ }, (_) => {
201
+ return {
202
+ gasLimitOverride: 30000000,
203
+ multicallChunk: 6,
204
+ };
205
+ }, (_) => {
206
+ return {
207
+ gasLimitOverride: 30000000,
208
+ multicallChunk: 6,
209
+ };
210
+ });
211
+ break;
212
+ case ChainId.CELO:
213
+ case ChainId.CELO_ALFAJORES:
214
+ this.onChainQuoteProvider = new OnChainQuoteProvider(chainId, provider, this.multicall2Provider, {
215
+ retries: 2,
216
+ minTimeout: 100,
217
+ maxTimeout: 1000,
218
+ }, (_) => {
219
+ return {
220
+ multicallChunk: 10,
221
+ gasLimitPerCall: 5000000,
222
+ quoteMinSuccessRate: 0.1,
223
+ };
224
+ }, (_) => {
225
+ return {
226
+ gasLimitOverride: 5000000,
227
+ multicallChunk: 5,
228
+ };
229
+ }, (_) => {
230
+ return {
231
+ gasLimitOverride: 6250000,
232
+ multicallChunk: 4,
233
+ };
234
+ });
235
+ break;
236
+ case ChainId.POLYGON_MUMBAI:
237
+ case ChainId.SEPOLIA:
238
+ case ChainId.MAINNET:
239
+ case ChainId.POLYGON:
240
+ this.onChainQuoteProvider = new OnChainQuoteProvider(chainId, provider, this.multicall2Provider, RETRY_OPTIONS[chainId], (_) => BATCH_PARAMS[chainId], (_) => GAS_ERROR_FAILURE_OVERRIDES[chainId], (_) => SUCCESS_RATE_FAILURE_OVERRIDES[chainId], (_) => BLOCK_NUMBER_CONFIGS[chainId]);
241
+ break;
242
+ default:
243
+ this.onChainQuoteProvider = new OnChainQuoteProvider(chainId, provider, this.multicall2Provider, DEFAULT_RETRY_OPTIONS, (_) => DEFAULT_BATCH_PARAMS, (_) => DEFAULT_GAS_ERROR_FAILURE_OVERRIDES, (_) => DEFAULT_SUCCESS_RATE_FAILURE_OVERRIDES, (_) => DEFAULT_BLOCK_NUMBER_CONFIGS);
244
+ break;
245
+ }
246
+ }
247
+ if (tokenValidatorProvider) {
248
+ this.tokenValidatorProvider = tokenValidatorProvider;
249
+ }
250
+ else if (this.chainId === ChainId.MAINNET) {
251
+ this.tokenValidatorProvider = new TokenValidatorProvider(this.chainId, this.multicall2Provider, new NodeJSCache(new NodeCache({ stdTTL: 30000, useClones: false })));
252
+ }
253
+ if (tokenPropertiesProvider) {
254
+ this.tokenPropertiesProvider = tokenPropertiesProvider;
255
+ }
256
+ else {
257
+ this.tokenPropertiesProvider = new TokenPropertiesProvider(this.chainId, new NodeJSCache(new NodeCache({ stdTTL: 86400, useClones: false })), new OnChainTokenFeeFetcher(this.chainId, provider));
258
+ }
259
+ this.v2PoolProvider =
260
+ v2PoolProvider !== null && v2PoolProvider !== void 0 ? v2PoolProvider : new CachingV2PoolProvider(chainId, new V2PoolProvider(chainId, this.multicall2Provider, this.tokenPropertiesProvider), new NodeJSCache(new NodeCache({ stdTTL: 60, useClones: false })));
261
+ this.v2QuoteProvider = v2QuoteProvider !== null && v2QuoteProvider !== void 0 ? v2QuoteProvider : new V2QuoteProvider();
262
+ this.blockedTokenListProvider =
263
+ blockedTokenListProvider !== null && blockedTokenListProvider !== void 0 ? blockedTokenListProvider : new CachingTokenListProvider(chainId, UNSUPPORTED_TOKENS, new NodeJSCache(new NodeCache({ stdTTL: 3600, useClones: false })));
264
+ this.tokenProvider =
265
+ tokenProvider !== null && tokenProvider !== void 0 ? tokenProvider : new CachingTokenProviderWithFallback(chainId, new NodeJSCache(new NodeCache({ stdTTL: 3600, useClones: false })), new CachingTokenListProvider(chainId, DEFAULT_TOKEN_LIST, new NodeJSCache(new NodeCache({ stdTTL: 3600, useClones: false }))), new TokenProvider(chainId, this.multicall2Provider));
266
+ this.portionProvider = portionProvider !== null && portionProvider !== void 0 ? portionProvider : new PortionProvider();
267
+ const chainName = ID_TO_NETWORK_NAME(chainId);
268
+ // ipfs urls in the following format: `https://cloudflare-ipfs.com/ipns/api.uniswap.org/v1/pools/${protocol}/${chainName}.json`;
269
+ if (v2SubgraphProvider) {
270
+ this.v2SubgraphProvider = v2SubgraphProvider;
271
+ }
272
+ else {
273
+ this.v2SubgraphProvider = new V2SubgraphProviderWithFallBacks([
274
+ new CachingV2SubgraphProvider(chainId, new URISubgraphProvider(chainId, `https://cloudflare-ipfs.com/ipns/api.uniswap.org/v1/pools/v2/${chainName}.json`, undefined, 0), new NodeJSCache(new NodeCache({ stdTTL: 300, useClones: false }))),
275
+ new StaticV2SubgraphProvider(chainId),
276
+ ]);
277
+ }
278
+ if (v3SubgraphProvider) {
279
+ this.v3SubgraphProvider = v3SubgraphProvider;
280
+ }
281
+ else {
282
+ this.v3SubgraphProvider = new V3SubgraphProviderWithFallBacks([
283
+ new CachingV3SubgraphProvider(chainId, new URISubgraphProvider(chainId, `https://cloudflare-ipfs.com/ipns/api.uniswap.org/v1/pools/v3/${chainName}.json`, undefined, 0), new NodeJSCache(new NodeCache({ stdTTL: 300, useClones: false }))),
284
+ new StaticV3SubgraphProvider(chainId, this.v3PoolProvider),
285
+ ]);
286
+ }
287
+ this.v4PoolParams =
288
+ v4PoolParams !== null && v4PoolParams !== void 0 ? v4PoolParams : getApplicableV4FeesTickspacingsHooks(chainId);
289
+ if (v4SubgraphProvider) {
290
+ this.v4SubgraphProvider = v4SubgraphProvider;
291
+ }
292
+ else {
293
+ this.v4SubgraphProvider = new V4SubgraphProviderWithFallBacks([
294
+ new CachingV4SubgraphProvider(chainId, new URISubgraphProvider(chainId, `https://cloudflare-ipfs.com/ipns/api.uniswap.org/v1/pools/v4/${chainName}.json`, undefined, 0), new NodeJSCache(new NodeCache({ stdTTL: 300, useClones: false }))),
295
+ new StaticV4SubgraphProvider(chainId, this.v4PoolProvider, this.v4PoolParams),
296
+ ]);
297
+ }
298
+ let gasPriceProviderInstance;
299
+ if (JsonRpcProvider.isProvider(this.provider)) {
300
+ gasPriceProviderInstance = new OnChainGasPriceProvider(chainId, new EIP1559GasPriceProvider(this.provider), new LegacyGasPriceProvider(this.provider));
301
+ }
302
+ else {
303
+ gasPriceProviderInstance = new ETHGasStationInfoProvider(ETH_GAS_STATION_API_URL);
304
+ }
305
+ this.gasPriceProvider =
306
+ gasPriceProvider !== null && gasPriceProvider !== void 0 ? gasPriceProvider : new CachingGasStationProvider(chainId, gasPriceProviderInstance, new NodeJSCache(new NodeCache({ stdTTL: 7, useClones: false })));
307
+ this.v4GasModelFactory =
308
+ v4GasModelFactory !== null && v4GasModelFactory !== void 0 ? v4GasModelFactory : new V4HeuristicGasModelFactory(this.provider);
309
+ this.v3GasModelFactory =
310
+ v3GasModelFactory !== null && v3GasModelFactory !== void 0 ? v3GasModelFactory : new V3HeuristicGasModelFactory(this.provider);
311
+ this.v2GasModelFactory =
312
+ v2GasModelFactory !== null && v2GasModelFactory !== void 0 ? v2GasModelFactory : new V2HeuristicGasModelFactory(this.provider);
313
+ this.mixedRouteGasModelFactory =
314
+ mixedRouteGasModelFactory !== null && mixedRouteGasModelFactory !== void 0 ? mixedRouteGasModelFactory : new MixedRouteHeuristicGasModelFactory();
315
+ this.swapRouterProvider =
316
+ swapRouterProvider !== null && swapRouterProvider !== void 0 ? swapRouterProvider : new SwapRouterProvider(this.multicall2Provider, this.chainId);
317
+ if (chainId === ChainId.ARBITRUM_ONE ||
318
+ chainId === ChainId.ARBITRUM_GOERLI) {
319
+ this.l2GasDataProvider =
320
+ arbitrumGasDataProvider !== null && arbitrumGasDataProvider !== void 0 ? arbitrumGasDataProvider : new ArbitrumGasDataProvider(chainId, this.provider);
321
+ }
322
+ // Initialize the Quoters.
323
+ // Quoters are an abstraction encapsulating the business logic of fetching routes and quotes.
324
+ this.v2Quoter = new V2Quoter(this.v2SubgraphProvider, this.v2PoolProvider, this.v2QuoteProvider, this.v2GasModelFactory, this.tokenProvider, this.chainId, this.blockedTokenListProvider, this.tokenValidatorProvider, this.l2GasDataProvider);
325
+ this.v3Quoter = new V3Quoter(this.v3SubgraphProvider, this.v3PoolProvider, this.onChainQuoteProvider, this.tokenProvider, this.chainId, this.blockedTokenListProvider, this.tokenValidatorProvider);
326
+ this.v4Quoter = new V4Quoter(this.v4SubgraphProvider, this.v4PoolProvider, this.onChainQuoteProvider, this.tokenProvider, this.chainId, this.blockedTokenListProvider, this.tokenValidatorProvider);
327
+ this.mixedQuoter = new MixedQuoter(this.v4SubgraphProvider, this.v4PoolProvider, this.v3SubgraphProvider, this.v3PoolProvider, this.v2SubgraphProvider, this.v2PoolProvider, this.onChainQuoteProvider, this.tokenProvider, this.chainId, this.blockedTokenListProvider, this.tokenValidatorProvider);
328
+ this.v2Supported = v2Supported !== null && v2Supported !== void 0 ? v2Supported : V2_SUPPORTED;
329
+ this.v4Supported = v4Supported !== null && v4Supported !== void 0 ? v4Supported : V4_SUPPORTED;
330
+ this.mixedSupported = mixedSupported !== null && mixedSupported !== void 0 ? mixedSupported : MIXED_SUPPORTED;
331
+ this.mixedCrossLiquidityV3AgainstV4Supported =
332
+ mixedCrossLiquidityV3AgainstV4Supported !== null && mixedCrossLiquidityV3AgainstV4Supported !== void 0 ? mixedCrossLiquidityV3AgainstV4Supported : MIXED_CROSS_LIQUIDITY_V3_AGAINST_V4_SUPPORTED;
333
+ this.cachedRoutesCacheInvalidationFixRolloutPercentage =
334
+ cachedRoutesCacheInvalidationFixRolloutPercentage;
335
+ // https://linear.app/uniswap/issue/ROUTE-467/tenderly-simulation-during-caching-lambda
336
+ this.deleteCacheEnabledChains = deleteCacheEnabledChains;
337
+ }
338
+ async routeToRatio(token0Balance, token1Balance, position, swapAndAddConfig, swapAndAddOptions, routingConfig = DEFAULT_ROUTING_CONFIG_BY_CHAIN(this.chainId)) {
339
+ if (token1Balance.currency.wrapped.sortsBefore(token0Balance.currency.wrapped)) {
340
+ [token0Balance, token1Balance] = [token1Balance, token0Balance];
341
+ }
342
+ let preSwapOptimalRatio = this.calculateOptimalRatio(position, position.pool.sqrtRatioX96, true);
343
+ // set up parameters according to which token will be swapped
344
+ let zeroForOne;
345
+ if (position.pool.tickCurrent > position.tickUpper) {
346
+ zeroForOne = true;
347
+ }
348
+ else if (position.pool.tickCurrent < position.tickLower) {
349
+ zeroForOne = false;
350
+ }
351
+ else {
352
+ zeroForOne = new Fraction(token0Balance.quotient, token1Balance.quotient).greaterThan(preSwapOptimalRatio);
353
+ if (!zeroForOne)
354
+ preSwapOptimalRatio = preSwapOptimalRatio.invert();
355
+ }
356
+ const [inputBalance, outputBalance] = zeroForOne
357
+ ? [token0Balance, token1Balance]
358
+ : [token1Balance, token0Balance];
359
+ let optimalRatio = preSwapOptimalRatio;
360
+ let postSwapTargetPool = position.pool;
361
+ let exchangeRate = zeroForOne
362
+ ? position.pool.token0Price
363
+ : position.pool.token1Price;
364
+ let swap = null;
365
+ let ratioAchieved = false;
366
+ let n = 0;
367
+ // iterate until we find a swap with a sufficient ratio or return null
368
+ while (!ratioAchieved) {
369
+ n++;
370
+ if (n > swapAndAddConfig.maxIterations) {
371
+ log.info('max iterations exceeded');
372
+ return {
373
+ status: SwapToRatioStatus.NO_ROUTE_FOUND,
374
+ error: 'max iterations exceeded',
375
+ };
376
+ }
377
+ const amountToSwap = calculateRatioAmountIn(optimalRatio, exchangeRate, inputBalance, outputBalance);
378
+ if (amountToSwap.equalTo(0)) {
379
+ log.info(`no swap needed: amountToSwap = 0`);
380
+ return {
381
+ status: SwapToRatioStatus.NO_SWAP_NEEDED,
382
+ };
383
+ }
384
+ swap = await this.route(amountToSwap, outputBalance.currency, TradeType.EXACT_INPUT, undefined, {
385
+ ...DEFAULT_ROUTING_CONFIG_BY_CHAIN(this.chainId),
386
+ ...routingConfig,
387
+ /// @dev We do not want to query for mixedRoutes for routeToRatio as they are not supported
388
+ /// [Protocol.V3, Protocol.V2] will make sure we only query for V3 and V2
389
+ protocols: [Protocol.V3, Protocol.V2],
390
+ });
391
+ if (!swap) {
392
+ log.info('no route found from this.route()');
393
+ return {
394
+ status: SwapToRatioStatus.NO_ROUTE_FOUND,
395
+ error: 'no route found',
396
+ };
397
+ }
398
+ const inputBalanceUpdated = inputBalance.subtract(swap.trade.inputAmount);
399
+ const outputBalanceUpdated = outputBalance.add(swap.trade.outputAmount);
400
+ const newRatio = inputBalanceUpdated.divide(outputBalanceUpdated);
401
+ let targetPoolPriceUpdate;
402
+ swap.route.forEach((route) => {
403
+ if (route.protocol === Protocol.V3) {
404
+ const v3Route = route;
405
+ v3Route.route.pools.forEach((pool, i) => {
406
+ if (pool.token0.equals(position.pool.token0) &&
407
+ pool.token1.equals(position.pool.token1) &&
408
+ pool.fee === position.pool.fee) {
409
+ targetPoolPriceUpdate = JSBI.BigInt(v3Route.sqrtPriceX96AfterList[i].toString());
410
+ optimalRatio = this.calculateOptimalRatio(position, JSBI.BigInt(targetPoolPriceUpdate.toString()), zeroForOne);
411
+ }
412
+ });
413
+ }
414
+ });
415
+ if (!targetPoolPriceUpdate) {
416
+ optimalRatio = preSwapOptimalRatio;
417
+ }
418
+ ratioAchieved =
419
+ newRatio.equalTo(optimalRatio) ||
420
+ this.absoluteValue(newRatio.asFraction.divide(optimalRatio).subtract(1)).lessThan(swapAndAddConfig.ratioErrorTolerance);
421
+ if (ratioAchieved && targetPoolPriceUpdate) {
422
+ postSwapTargetPool = new Pool(position.pool.token0, position.pool.token1, position.pool.fee, targetPoolPriceUpdate, position.pool.liquidity, TickMath.getTickAtSqrtRatio(targetPoolPriceUpdate), position.pool.tickDataProvider);
423
+ }
424
+ exchangeRate = swap.trade.outputAmount.divide(swap.trade.inputAmount);
425
+ log.info({
426
+ exchangeRate: exchangeRate.asFraction.toFixed(18),
427
+ optimalRatio: optimalRatio.asFraction.toFixed(18),
428
+ newRatio: newRatio.asFraction.toFixed(18),
429
+ inputBalanceUpdated: inputBalanceUpdated.asFraction.toFixed(18),
430
+ outputBalanceUpdated: outputBalanceUpdated.asFraction.toFixed(18),
431
+ ratioErrorTolerance: swapAndAddConfig.ratioErrorTolerance.toFixed(18),
432
+ iterationN: n.toString(),
433
+ }, 'QuoteToRatio Iteration Parameters');
434
+ if (exchangeRate.equalTo(0)) {
435
+ log.info('exchangeRate to 0');
436
+ return {
437
+ status: SwapToRatioStatus.NO_ROUTE_FOUND,
438
+ error: 'insufficient liquidity to swap to optimal ratio',
439
+ };
440
+ }
441
+ }
442
+ if (!swap) {
443
+ return {
444
+ status: SwapToRatioStatus.NO_ROUTE_FOUND,
445
+ error: 'no route found',
446
+ };
447
+ }
448
+ let methodParameters;
449
+ if (swapAndAddOptions) {
450
+ methodParameters = await this.buildSwapAndAddMethodParameters(swap.trade, swapAndAddOptions, {
451
+ initialBalanceTokenIn: inputBalance,
452
+ initialBalanceTokenOut: outputBalance,
453
+ preLiquidityPosition: position,
454
+ });
455
+ }
456
+ return {
457
+ status: SwapToRatioStatus.SUCCESS,
458
+ result: { ...swap, methodParameters, optimalRatio, postSwapTargetPool },
459
+ };
460
+ }
461
+ /**
462
+ * @inheritdoc IRouter
463
+ */
464
+ async route(amount, quoteCurrency, tradeType, swapConfig, partialRoutingConfig = {}) {
465
+ var _a, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1;
466
+ const originalAmount = amount;
467
+ const { currencyIn, currencyOut } = this.determineCurrencyInOutFromTradeType(tradeType, amount, quoteCurrency);
468
+ const tokenOutProperties = await this.tokenPropertiesProvider.getTokensProperties([currencyOut], partialRoutingConfig);
469
+ const feeTakenOnTransfer = (_c = (_a = tokenOutProperties[getAddressLowerCase(currencyOut)]) === null || _a === void 0 ? void 0 : _a.tokenFeeResult) === null || _c === void 0 ? void 0 : _c.feeTakenOnTransfer;
470
+ const externalTransferFailed = (_e = (_d = tokenOutProperties[getAddressLowerCase(currencyOut)]) === null || _d === void 0 ? void 0 : _d.tokenFeeResult) === null || _e === void 0 ? void 0 : _e.externalTransferFailed;
471
+ // We want to log the fee on transfer output tokens that we are taking fee or not
472
+ // Ideally the trade size (normalized in USD) would be ideal to log here, but we don't have spot price of output tokens here.
473
+ // We have to make sure token out is FOT with either buy/sell fee bps > 0
474
+ if (((_h = (_g = (_f = tokenOutProperties[getAddressLowerCase(currencyOut)]) === null || _f === void 0 ? void 0 : _f.tokenFeeResult) === null || _g === void 0 ? void 0 : _g.buyFeeBps) === null || _h === void 0 ? void 0 : _h.gt(0)) ||
475
+ ((_l = (_k = (_j = tokenOutProperties[getAddressLowerCase(currencyOut)]) === null || _j === void 0 ? void 0 : _j.tokenFeeResult) === null || _k === void 0 ? void 0 : _k.sellFeeBps) === null || _l === void 0 ? void 0 : _l.gt(0))) {
476
+ if (feeTakenOnTransfer || externalTransferFailed) {
477
+ // also to be extra safe, in case of FOT with feeTakenOnTransfer or externalTransferFailed,
478
+ // we nullify the fee and flat fee to avoid any potential issues.
479
+ // although neither web nor wallet should use the calldata returned from routing/SOR
480
+ if ((swapConfig === null || swapConfig === void 0 ? void 0 : swapConfig.type) === SwapType.UNIVERSAL_ROUTER) {
481
+ swapConfig.fee = undefined;
482
+ swapConfig.flatFee = undefined;
483
+ }
484
+ metric.putMetric('TokenOutFeeOnTransferNotTakingFee', 1, MetricLoggerUnit.Count);
485
+ }
486
+ else {
487
+ metric.putMetric('TokenOutFeeOnTransferTakingFee', 1, MetricLoggerUnit.Count);
488
+ }
489
+ }
490
+ if (tradeType === TradeType.EXACT_OUTPUT) {
491
+ const portionAmount = this.portionProvider.getPortionAmount(amount, tradeType, feeTakenOnTransfer, externalTransferFailed, swapConfig);
492
+ if (portionAmount && portionAmount.greaterThan(ZERO)) {
493
+ // In case of exact out swap, before we route, we need to make sure that the
494
+ // token out amount accounts for flat portion, and token in amount after the best swap route contains the token in equivalent of portion.
495
+ // In other words, in case a pool's LP fee bps is lower than the portion bps (0.01%/0.05% for v3), a pool can go insolvency.
496
+ // This is because instead of the swapper being responsible for the portion,
497
+ // the pool instead gets responsible for the portion.
498
+ // The addition below avoids that situation.
499
+ amount = amount.add(portionAmount);
500
+ }
501
+ }
502
+ metric.setProperty('chainId', this.chainId);
503
+ metric.setProperty('pair', `${currencyIn.symbol}/${currencyOut.symbol}`);
504
+ metric.setProperty('tokenIn', getAddress(currencyIn));
505
+ metric.setProperty('tokenOut', getAddress(currencyOut));
506
+ metric.setProperty('tradeType', tradeType === TradeType.EXACT_INPUT ? 'ExactIn' : 'ExactOut');
507
+ metric.putMetric(`QuoteRequestedForChain${this.chainId}`, 1, MetricLoggerUnit.Count);
508
+ // Get a block number to specify in all our calls. Ensures data we fetch from chain is
509
+ // from the same block.
510
+ const blockNumber = (_m = partialRoutingConfig.blockNumber) !== null && _m !== void 0 ? _m : this.getBlockNumberPromise();
511
+ const routingConfig = _.merge({
512
+ // These settings could be changed by the partialRoutingConfig
513
+ useCachedRoutes: true,
514
+ writeToCachedRoutes: true,
515
+ optimisticCachedRoutes: false,
516
+ }, DEFAULT_ROUTING_CONFIG_BY_CHAIN(this.chainId), partialRoutingConfig, { blockNumber });
517
+ if (routingConfig.debugRouting) {
518
+ log.warn(`Finalized routing config is ${JSON.stringify(routingConfig)}`);
519
+ }
520
+ const gasPriceWei = await this.getGasPriceWei(await blockNumber, await partialRoutingConfig.blockNumber);
521
+ // const gasTokenAccessor = await this.tokenProvider.getTokens([routingConfig.gasToken!]);
522
+ const gasToken = routingConfig.gasToken
523
+ ? (await this.tokenProvider.getTokens([routingConfig.gasToken])).getTokenByAddress(routingConfig.gasToken)
524
+ : undefined;
525
+ const providerConfig = {
526
+ ...routingConfig,
527
+ blockNumber,
528
+ additionalGasOverhead: NATIVE_OVERHEAD(this.chainId, amount.currency, quoteCurrency),
529
+ gasToken,
530
+ externalTransferFailed,
531
+ feeTakenOnTransfer,
532
+ };
533
+ const { v2GasModel: v2GasModel, v3GasModel: v3GasModel, v4GasModel: v4GasModel, mixedRouteGasModel: mixedRouteGasModel, } = await this.getGasModels(gasPriceWei, amount.currency.wrapped, quoteCurrency.wrapped, providerConfig);
534
+ // Create a Set to sanitize the protocols input, a Set of undefined becomes an empty set,
535
+ // Then create an Array from the values of that Set.
536
+ const protocols = Array.from(new Set(routingConfig.protocols).values());
537
+ const cacheMode = (_o = routingConfig.overwriteCacheMode) !== null && _o !== void 0 ? _o : (await ((_p = this.routeCachingProvider) === null || _p === void 0 ? void 0 : _p.getCacheMode(this.chainId, amount, quoteCurrency, tradeType, protocols)));
538
+ // Fetch CachedRoutes
539
+ let cachedRoutes;
540
+ // Decide whether to use cached routes or not - If |enabledAndRequestedProtocolsMatch| is true we are good to use cached routes.
541
+ // In order to use cached routes, we need to have all enabled protocols specified in the request.
542
+ // By default, all protocols are enabled but for UniversalRouterVersion.V1_2, V4 is not.
543
+ // - ref: https://github.com/Uniswap/routing-api/blob/663b607d80d9249f85e7ab0925a611ec3701da2a/lib/util/supportedProtocolVersions.ts#L15
544
+ // So we take this into account when deciding whether to use cached routes or not.
545
+ // We only want to use cache if all enabled protocols are specified (V2,V3,V4? + MIXED). In any other case, use onchain path.
546
+ // - Cache is optimized for global search, not for specific protocol(s) search.
547
+ // For legacy systems (SWAP_ROUTER_02) or missing swapConfig, follow UniversalRouterVersion.V1_2 logic.
548
+ const availableProtocolsSet = new Set(Object.values(Protocol));
549
+ const requestedProtocolsSet = new Set(protocols);
550
+ const swapRouter = !swapConfig ||
551
+ swapConfig.type === SwapType.SWAP_ROUTER_02 ||
552
+ (swapConfig.type === SwapType.UNIVERSAL_ROUTER &&
553
+ swapConfig.version === UniversalRouterVersion.V1_2);
554
+ if (swapRouter) {
555
+ availableProtocolsSet.delete(Protocol.V4);
556
+ if (requestedProtocolsSet.has(Protocol.V4)) {
557
+ requestedProtocolsSet.delete(Protocol.V4);
558
+ }
559
+ }
560
+ const enabledAndRequestedProtocolsMatch = availableProtocolsSet.size === requestedProtocolsSet.size &&
561
+ [...availableProtocolsSet].every((protocol) => requestedProtocolsSet.has(protocol));
562
+ // If the requested protocols do not match the enabled protocols, we need to set the hooks options to NO_HOOKS.
563
+ if (!requestedProtocolsSet.has(Protocol.V4)) {
564
+ routingConfig.hooksOptions = HooksOptions.NO_HOOKS;
565
+ }
566
+ // If hooksOptions not specified and it's not a swapRouter (i.e. Universal Router it is),
567
+ // we should also set it to HOOKS_INCLUSIVE, as this is default behavior even without hooksOptions.
568
+ if (!routingConfig.hooksOptions) {
569
+ routingConfig.hooksOptions = HooksOptions.HOOKS_INCLUSIVE;
570
+ }
571
+ log.debug('UniversalRouterVersion_CacheGate_Check', {
572
+ availableProtocolsSet: Array.from(availableProtocolsSet),
573
+ requestedProtocolsSet: Array.from(requestedProtocolsSet),
574
+ enabledAndRequestedProtocolsMatch,
575
+ swapConfigType: swapConfig === null || swapConfig === void 0 ? void 0 : swapConfig.type,
576
+ swapConfigUniversalRouterVersion: (swapConfig === null || swapConfig === void 0 ? void 0 : swapConfig.type) === SwapType.UNIVERSAL_ROUTER
577
+ ? swapConfig === null || swapConfig === void 0 ? void 0 : swapConfig.version
578
+ : 'N/A',
579
+ });
580
+ if (routingConfig.useCachedRoutes &&
581
+ cacheMode !== CacheMode.Darkmode &&
582
+ AlphaRouter.isAllowedToEnterCachedRoutes(routingConfig.intent, routingConfig.hooksOptions, swapRouter)) {
583
+ if (enabledAndRequestedProtocolsMatch) {
584
+ if (protocols.includes(Protocol.V4) &&
585
+ (currencyIn.isNative || currencyOut.isNative)) {
586
+ const [wrappedNativeCachedRoutes, nativeCachedRoutes] = await Promise.all([
587
+ (_q = this.routeCachingProvider) === null || _q === void 0 ? void 0 : _q.getCachedRoute(this.chainId, CurrencyAmount.fromRawAmount(amount.currency.wrapped, amount.quotient), quoteCurrency.wrapped, tradeType, protocols, await blockNumber, routingConfig.optimisticCachedRoutes, routingConfig, swapConfig),
588
+ (_r = this.routeCachingProvider) === null || _r === void 0 ? void 0 : _r.getCachedRoute(this.chainId, amount, quoteCurrency, tradeType, [Protocol.V4], await blockNumber, routingConfig.optimisticCachedRoutes, routingConfig, swapConfig),
589
+ ]);
590
+ if ((wrappedNativeCachedRoutes &&
591
+ (wrappedNativeCachedRoutes === null || wrappedNativeCachedRoutes === void 0 ? void 0 : wrappedNativeCachedRoutes.routes.length) > 0) ||
592
+ (nativeCachedRoutes && (nativeCachedRoutes === null || nativeCachedRoutes === void 0 ? void 0 : nativeCachedRoutes.routes.length) > 0)) {
593
+ cachedRoutes = new CachedRoutes({
594
+ routes: [
595
+ ...((_s = nativeCachedRoutes === null || nativeCachedRoutes === void 0 ? void 0 : nativeCachedRoutes.routes) !== null && _s !== void 0 ? _s : []),
596
+ ...((_t = wrappedNativeCachedRoutes === null || wrappedNativeCachedRoutes === void 0 ? void 0 : wrappedNativeCachedRoutes.routes) !== null && _t !== void 0 ? _t : []),
597
+ ],
598
+ chainId: this.chainId,
599
+ currencyIn: currencyIn,
600
+ currencyOut: currencyOut,
601
+ protocolsCovered: protocols,
602
+ blockNumber: await blockNumber,
603
+ tradeType: tradeType,
604
+ originalAmount: (_v = (_u = wrappedNativeCachedRoutes === null || wrappedNativeCachedRoutes === void 0 ? void 0 : wrappedNativeCachedRoutes.originalAmount) !== null && _u !== void 0 ? _u : nativeCachedRoutes === null || nativeCachedRoutes === void 0 ? void 0 : nativeCachedRoutes.originalAmount) !== null && _v !== void 0 ? _v : amount.quotient.toString(),
605
+ blocksToLive: (_x = (_w = wrappedNativeCachedRoutes === null || wrappedNativeCachedRoutes === void 0 ? void 0 : wrappedNativeCachedRoutes.blocksToLive) !== null && _w !== void 0 ? _w : nativeCachedRoutes === null || nativeCachedRoutes === void 0 ? void 0 : nativeCachedRoutes.blocksToLive) !== null && _x !== void 0 ? _x : DEFAULT_BLOCKS_TO_LIVE[this.chainId],
606
+ });
607
+ }
608
+ }
609
+ else {
610
+ cachedRoutes = await ((_y = this.routeCachingProvider) === null || _y === void 0 ? void 0 : _y.getCachedRoute(this.chainId, amount, quoteCurrency, tradeType, protocols, await blockNumber, routingConfig.optimisticCachedRoutes, routingConfig, swapConfig));
611
+ }
612
+ }
613
+ }
614
+ if (shouldWipeoutCachedRoutes(cachedRoutes, routingConfig)) {
615
+ cachedRoutes = undefined;
616
+ }
617
+ metric.putMetric(routingConfig.useCachedRoutes
618
+ ? 'GetQuoteUsingCachedRoutes'
619
+ : 'GetQuoteNotUsingCachedRoutes', 1, MetricLoggerUnit.Count);
620
+ if (cacheMode &&
621
+ routingConfig.useCachedRoutes &&
622
+ cacheMode !== CacheMode.Darkmode &&
623
+ !cachedRoutes) {
624
+ metric.putMetric(`GetCachedRoute_miss_${cacheMode}`, 1, MetricLoggerUnit.Count);
625
+ log.info({
626
+ currencyIn: currencyIn.symbol,
627
+ currencyInAddress: getAddress(currencyIn),
628
+ currencyOut: currencyOut.symbol,
629
+ currencyOutAddress: getAddress(currencyOut),
630
+ cacheMode,
631
+ amount: amount.toExact(),
632
+ chainId: this.chainId,
633
+ tradeType: this.tradeTypeStr(tradeType),
634
+ }, `GetCachedRoute miss ${cacheMode} for ${this.tokenPairSymbolTradeTypeChainId(currencyIn, currencyOut, tradeType)}`);
635
+ }
636
+ else if (cachedRoutes && routingConfig.useCachedRoutes) {
637
+ metric.putMetric(`GetCachedRoute_hit_${cacheMode}`, 1, MetricLoggerUnit.Count);
638
+ log.info({
639
+ currencyIn: currencyIn.symbol,
640
+ currencyInAddress: getAddress(currencyIn),
641
+ currencyOut: currencyOut.symbol,
642
+ currencyOutAddress: getAddress(currencyOut),
643
+ cacheMode,
644
+ amount: amount.toExact(),
645
+ chainId: this.chainId,
646
+ tradeType: this.tradeTypeStr(tradeType),
647
+ }, `GetCachedRoute hit ${cacheMode} for ${this.tokenPairSymbolTradeTypeChainId(currencyIn, currencyOut, tradeType)}`);
648
+ }
649
+ let swapRouteFromCachePromise = Promise.resolve(null);
650
+ if (cachedRoutes) {
651
+ swapRouteFromCachePromise = this.getSwapRouteFromCache(currencyIn, currencyOut, cachedRoutes, await blockNumber, amount, quoteCurrency, tradeType, routingConfig, v3GasModel, v4GasModel, mixedRouteGasModel, gasPriceWei, v2GasModel, swapConfig, providerConfig);
652
+ }
653
+ let swapRouteFromChainPromise = Promise.resolve(null);
654
+ if (!cachedRoutes || cacheMode !== CacheMode.Livemode) {
655
+ swapRouteFromChainPromise = this.getSwapRouteFromChain(amount, currencyIn, currencyOut, protocols, quoteCurrency, tradeType, routingConfig, v3GasModel, v4GasModel, mixedRouteGasModel, gasPriceWei, v2GasModel, swapConfig, providerConfig);
656
+ }
657
+ const [swapRouteFromCache, swapRouteFromChain] = await Promise.all([
658
+ swapRouteFromCachePromise,
659
+ swapRouteFromChainPromise,
660
+ ]);
661
+ let swapRouteRaw;
662
+ let hitsCachedRoute = false;
663
+ if (cacheMode === CacheMode.Livemode && swapRouteFromCache) {
664
+ // offline lambda is never in cache mode
665
+ // refresh pools to avoid stale data
666
+ const beforeRefreshPools = Date.now();
667
+ await this.refreshPools(swapRouteFromCache.routes, routingConfig, this.v2PoolProvider, this.v3PoolProvider, this.v4PoolProvider);
668
+ metric.putMetric(`Route_RefreshPools_Latency`, Date.now() - beforeRefreshPools, MetricLoggerUnit.Milliseconds);
669
+ log.info(`CacheMode is ${cacheMode}, and we are using swapRoute from cache`);
670
+ hitsCachedRoute = true;
671
+ swapRouteRaw = swapRouteFromCache;
672
+ }
673
+ else {
674
+ log.info(`CacheMode is ${cacheMode}, and we are using materialized swapRoute`);
675
+ swapRouteRaw = swapRouteFromChain;
676
+ }
677
+ if (cacheMode === CacheMode.Tapcompare &&
678
+ swapRouteFromCache &&
679
+ swapRouteFromChain) {
680
+ const quoteDiff = swapRouteFromChain.quote.subtract(swapRouteFromCache.quote);
681
+ const quoteGasAdjustedDiff = swapRouteFromChain.quoteGasAdjusted.subtract(swapRouteFromCache.quoteGasAdjusted);
682
+ const gasUsedDiff = swapRouteFromChain.estimatedGasUsed.sub(swapRouteFromCache.estimatedGasUsed);
683
+ // Only log if quoteDiff is different from 0, or if quoteGasAdjustedDiff and gasUsedDiff are both different from 0
684
+ if (!quoteDiff.equalTo(0) ||
685
+ !(quoteGasAdjustedDiff.equalTo(0) || gasUsedDiff.eq(0))) {
686
+ try {
687
+ // Calculates the percentage of the difference with respect to the quoteFromChain (not from cache)
688
+ const misquotePercent = quoteGasAdjustedDiff
689
+ .divide(swapRouteFromChain.quoteGasAdjusted)
690
+ .multiply(100);
691
+ metric.putMetric(`TapcompareCachedRoute_quoteGasAdjustedDiffPercent`, Number(misquotePercent.toExact()), MetricLoggerUnit.Percent);
692
+ log.warn({
693
+ quoteFromChain: swapRouteFromChain.quote.toExact(),
694
+ quoteFromCache: swapRouteFromCache.quote.toExact(),
695
+ quoteDiff: quoteDiff.toExact(),
696
+ quoteGasAdjustedFromChain: swapRouteFromChain.quoteGasAdjusted.toExact(),
697
+ quoteGasAdjustedFromCache: swapRouteFromCache.quoteGasAdjusted.toExact(),
698
+ quoteGasAdjustedDiff: quoteGasAdjustedDiff.toExact(),
699
+ gasUsedFromChain: swapRouteFromChain.estimatedGasUsed.toString(),
700
+ gasUsedFromCache: swapRouteFromCache.estimatedGasUsed.toString(),
701
+ gasUsedDiff: gasUsedDiff.toString(),
702
+ routesFromChain: swapRouteFromChain.routes.toString(),
703
+ routesFromCache: swapRouteFromCache.routes.toString(),
704
+ amount: amount.toExact(),
705
+ originalAmount: cachedRoutes === null || cachedRoutes === void 0 ? void 0 : cachedRoutes.originalAmount,
706
+ pair: this.tokenPairSymbolTradeTypeChainId(currencyIn, currencyOut, tradeType),
707
+ blockNumber,
708
+ }, `Comparing quotes between Chain and Cache for ${this.tokenPairSymbolTradeTypeChainId(currencyIn, currencyOut, tradeType)}`);
709
+ }
710
+ catch (error) {
711
+ // This is in response to the 'division by zero' error
712
+ // during https://uniswapteam.slack.com/archives/C059TGEC57W/p1723997015399579
713
+ if (error instanceof RangeError &&
714
+ error.message.includes('Division by zero')) {
715
+ log.error({
716
+ quoteGasAdjustedDiff: quoteGasAdjustedDiff.toExact(),
717
+ swapRouteFromChainQuoteGasAdjusted: swapRouteFromChain.quoteGasAdjusted.toExact(),
718
+ }, 'Error calculating misquote percent');
719
+ metric.putMetric(`TapcompareCachedRoute_quoteGasAdjustedDiffPercent_divzero`, 1, MetricLoggerUnit.Count);
720
+ }
721
+ // Log but don't throw here - this is only for logging.
722
+ }
723
+ }
724
+ }
725
+ let newSetCachedRoutesPath = false;
726
+ const shouldEnableCachedRoutesCacheInvalidationFix = Math.random() * 100 <
727
+ ((_z = this.cachedRoutesCacheInvalidationFixRolloutPercentage) !== null && _z !== void 0 ? _z : 0);
728
+ // we have to write cached routes right before checking swapRouteRaw is null or not
729
+ // because getCachedRoutes in routing-api do not use the blocks-to-live to filter out the expired routes at all
730
+ // there's a possibility the cachedRoutes is always populated, but swapRouteFromCache is always null, because we don't update cachedRoutes in this case at all,
731
+ // as long as it's within 24 hours sliding window TTL
732
+ if (shouldEnableCachedRoutesCacheInvalidationFix) {
733
+ // theoretically, when routingConfig.intent === INTENT.CACHING, optimisticCachedRoutes should be false
734
+ // so that we can always pass in cachedRoutes?.notExpired(await blockNumber, !routingConfig.optimisticCachedRoutes)
735
+ // but just to be safe, we just hardcode true when checking the cached routes expiry for write update
736
+ // we decide to not check cached routes expiry in the read path anyway
737
+ if (!(cachedRoutes === null || cachedRoutes === void 0 ? void 0 : cachedRoutes.notExpired(await blockNumber, true))) {
738
+ // optimisticCachedRoutes === false means at routing-api level, we only want to set cached routes during intent=caching, not intent=quote
739
+ // this means during the online quote endpoint path, we should not reset cached routes
740
+ if (routingConfig.intent === INTENT.CACHING) {
741
+ // due to fire and forget nature, we already take note that we should set new cached routes during the new path
742
+ newSetCachedRoutesPath = true;
743
+ metric.putMetric(`SetCachedRoute_NewPath`, 1, MetricLoggerUnit.Count);
744
+ // there's a chance that swapRouteFromChain might be populated already,
745
+ // when there's no cachedroutes in the dynamo DB.
746
+ // in that case, we don't try to swap route from chain again
747
+ const swapRouteFromChainAgain = swapRouteFromChain !== null && swapRouteFromChain !== void 0 ? swapRouteFromChain :
748
+ // we have to intentionally await here, because routing-api lambda has a chance to return the swapRoute/swapRouteWithSimulation
749
+ // before the routing-api quote handler can finish running getSwapRouteFromChain (getSwapRouteFromChain is runtime intensive)
750
+ (await this.getSwapRouteFromChain(amount, currencyIn, currencyOut, protocols, quoteCurrency, tradeType, routingConfig, v3GasModel, v4GasModel, mixedRouteGasModel, gasPriceWei, v2GasModel, swapConfig, providerConfig));
751
+ if (swapRouteFromChainAgain) {
752
+ const routesToCache = CachedRoutes.fromRoutesWithValidQuotes(swapRouteFromChainAgain.routes, this.chainId, currencyIn, currencyOut, protocols.sort(), await blockNumber, tradeType, amount.toExact());
753
+ await this.setCachedRoutesAndLog(amount, currencyIn, currencyOut, tradeType, 'SetCachedRoute_NewPath', routesToCache, routingConfig.cachedRoutesRouteIds);
754
+ }
755
+ }
756
+ }
757
+ }
758
+ if (!swapRouteRaw) {
759
+ return null;
760
+ }
761
+ const { quote, quoteGasAdjusted, estimatedGasUsed, routes: routeAmounts, estimatedGasUsedQuoteToken, estimatedGasUsedUSD, estimatedGasUsedGasToken, } = swapRouteRaw;
762
+ // we intentionally dont add shouldEnableCachedRoutesCacheInvalidationFix in if condition below
763
+ // because we know cached routes in prod dont filter by blocks-to-live
764
+ // so that we know that swapRouteFromChain is always not populated, because
765
+ // if (!cachedRoutes || cacheMode !== CacheMode.Livemode) above always have the cachedRoutes as populated
766
+ if (this.routeCachingProvider &&
767
+ routingConfig.writeToCachedRoutes &&
768
+ cacheMode !== CacheMode.Darkmode &&
769
+ swapRouteFromChain) {
770
+ if (newSetCachedRoutesPath) {
771
+ // SetCachedRoute_NewPath and SetCachedRoute_OldPath metrics might have counts during short timeframe.
772
+ // over time, we should expect to see less SetCachedRoute_OldPath metrics count.
773
+ // in AWS metrics, one can investigate, by:
774
+ // 1) seeing the overall metrics count of SetCachedRoute_NewPath and SetCachedRoute_OldPath. SetCachedRoute_NewPath should steadily go up, while SetCachedRoute_OldPath should go down.
775
+ // 2) using the same requestId, one should see eventually when SetCachedRoute_NewPath metric is logged, SetCachedRoute_OldPath metric should not be called.
776
+ metric.putMetric(`SetCachedRoute_OldPath_INTENT_${routingConfig.intent}`, 1, MetricLoggerUnit.Count);
777
+ }
778
+ // Generate the object to be cached
779
+ const routesToCache = CachedRoutes.fromRoutesWithValidQuotes(swapRouteFromChain.routes, this.chainId, currencyIn, currencyOut, protocols.sort(), await blockNumber, tradeType, amount.toExact());
780
+ await this.setCachedRoutesAndLog(amount, currencyIn, currencyOut, tradeType, 'SetCachedRoute_OldPath', routesToCache, routingConfig.cachedRoutesRouteIds);
781
+ }
782
+ metric.putMetric(`QuoteFoundForChain${this.chainId}`, 1, MetricLoggerUnit.Count);
783
+ // Build Trade object that represents the optimal swap.
784
+ const trade = buildTrade(currencyIn, currencyOut, tradeType, routeAmounts);
785
+ let methodParameters;
786
+ // If user provided recipient, deadline etc. we also generate the calldata required to execute
787
+ // the swap and return it too.
788
+ if (swapConfig) {
789
+ methodParameters = buildSwapMethodParameters(trade, swapConfig, this.chainId);
790
+ }
791
+ const tokenOutAmount = tradeType === TradeType.EXACT_OUTPUT
792
+ ? originalAmount // we need to pass in originalAmount instead of amount, because amount already added portionAmount in case of exact out swap
793
+ : quote;
794
+ const portionAmount = this.portionProvider.getPortionAmount(tokenOutAmount, tradeType, feeTakenOnTransfer, externalTransferFailed, swapConfig);
795
+ const portionQuoteAmount = this.portionProvider.getPortionQuoteAmount(tradeType, quote, amount, // we need to pass in amount instead of originalAmount here, because amount here needs to add the portion for exact out
796
+ portionAmount);
797
+ // we need to correct quote and quote gas adjusted for exact output when portion is part of the exact out swap
798
+ const correctedQuote = this.portionProvider.getQuote(tradeType, quote, portionQuoteAmount);
799
+ const correctedQuoteGasAdjusted = this.portionProvider.getQuoteGasAdjusted(tradeType, quoteGasAdjusted, portionQuoteAmount);
800
+ const quoteGasAndPortionAdjusted = this.portionProvider.getQuoteGasAndPortionAdjusted(tradeType, quoteGasAdjusted, portionAmount);
801
+ const swapRoute = {
802
+ quote: correctedQuote,
803
+ quoteGasAdjusted: correctedQuoteGasAdjusted,
804
+ estimatedGasUsed,
805
+ estimatedGasUsedQuoteToken,
806
+ estimatedGasUsedUSD,
807
+ estimatedGasUsedGasToken,
808
+ gasPriceWei,
809
+ route: routeAmounts,
810
+ trade,
811
+ methodParameters,
812
+ blockNumber: BigNumber.from(await blockNumber),
813
+ hitsCachedRoute: hitsCachedRoute,
814
+ portionAmount: portionAmount,
815
+ quoteGasAndPortionAdjusted: quoteGasAndPortionAdjusted,
816
+ };
817
+ if (swapConfig &&
818
+ swapConfig.simulate &&
819
+ methodParameters &&
820
+ methodParameters.calldata) {
821
+ if (!this.simulator) {
822
+ throw new Error('Simulator not initialized!');
823
+ }
824
+ log.info(JSON.stringify({ swapConfig, methodParameters, providerConfig }, null, 2), `Starting simulation`);
825
+ const fromAddress = swapConfig.simulate.fromAddress;
826
+ const beforeSimulate = Date.now();
827
+ const swapRouteWithSimulation = await this.simulator.simulate(fromAddress, swapConfig, swapRoute, amount,
828
+ // Quote will be in WETH even if quoteCurrency is ETH
829
+ // So we init a new CurrencyAmount object here
830
+ CurrencyAmount.fromRawAmount(quoteCurrency, quote.quotient.toString()), providerConfig);
831
+ if (((_0 = this.deleteCacheEnabledChains) === null || _0 === void 0 ? void 0 : _0.includes(this.chainId)) &&
832
+ swapRouteWithSimulation.simulationStatus === SimulationStatus.Failed) {
833
+ // invalidate cached route if simulation failed
834
+ log.info({
835
+ simulationStatus: swapRouteWithSimulation.simulationStatus,
836
+ swapRoute: swapRouteWithSimulation,
837
+ }, `Simulation failed - detailed failure information: CacheInvalidationCount_${this.chainId}`);
838
+ metric.putMetric(`CacheInvalidationCount_${this.chainId}`, 1, MetricLoggerUnit.Count);
839
+ // Generate the object to be cached
840
+ const routesToCache = CachedRoutes.fromRoutesWithValidQuotes(swapRouteWithSimulation.route, this.chainId, currencyIn, currencyOut, protocols.sort(), await blockNumber, tradeType, amount.toExact());
841
+ if (!routesToCache) {
842
+ log.error({ swapRouteWithSimulation }, 'Failed to generate cached routes after simulation failure');
843
+ }
844
+ else {
845
+ try {
846
+ await ((_1 = this.routeCachingProvider) === null || _1 === void 0 ? void 0 : _1.deleteCachedRoute(routesToCache));
847
+ }
848
+ catch (err) {
849
+ log.error({ err, routesToCache }, 'Failed to delete cached route after simulation failure');
850
+ }
851
+ }
852
+ }
853
+ metric.putMetric('SimulateTransaction', Date.now() - beforeSimulate, MetricLoggerUnit.Milliseconds);
854
+ return swapRouteWithSimulation;
855
+ }
856
+ return swapRoute;
857
+ }
858
+ /**
859
+ * Refreshes the pools for the given routes.
860
+ *
861
+ * @param routes the routes to refresh the pools for
862
+ * @param routingConfig the routing config
863
+ */
864
+ async refreshPools(routes, routingConfig, v2PoolProvider, v3PoolProvider, v4PoolProvider) {
865
+ for (const route of routes) {
866
+ switch (route.protocol) {
867
+ case Protocol.V2:
868
+ route.route = await AlphaRouter.refreshV2Pools(route.route, routingConfig, v2PoolProvider);
869
+ break;
870
+ case Protocol.V3:
871
+ route.route = await AlphaRouter.refreshV3Pools(route.route, routingConfig, v3PoolProvider);
872
+ break;
873
+ case Protocol.V4:
874
+ route.route = await AlphaRouter.refreshV4Pools(route.route, routingConfig, v4PoolProvider);
875
+ break;
876
+ case Protocol.MIXED:
877
+ route.route = await AlphaRouter.refreshMixedPools(route.route, routingConfig, v2PoolProvider, v3PoolProvider, v4PoolProvider);
878
+ break;
879
+ default:
880
+ throw new Error(`Unknown protocol: ${route.protocol}`);
881
+ }
882
+ }
883
+ }
884
+ /**
885
+ * Refreshes the V2 pools for the given route.
886
+ *
887
+ * @param route the route to refresh the V2 pools for
888
+ * @param config the routing config
889
+ * @param v2PoolProvider the V2 pool provider
890
+ * @returns the refreshed route
891
+ */
892
+ static async refreshV2Pools(route, config, v2PoolProvider) {
893
+ const refreshedPairs = [];
894
+ for (const pair of route.pairs) {
895
+ const v2Pools = await v2PoolProvider.getPools([[pair.token0, pair.token1]], config);
896
+ const refreshed = v2Pools.getPool(pair.token0, pair.token1);
897
+ if (refreshed)
898
+ refreshedPairs.push(refreshed);
899
+ else {
900
+ // if the pool is not found, we need to log the error and add the original pool back in
901
+ AlphaRouter.logV2PoolRefreshError(pair);
902
+ refreshedPairs.push(pair);
903
+ }
904
+ }
905
+ return cloneV2RouteWithNewPools(route, refreshedPairs);
906
+ }
907
+ /**
908
+ * Refreshes the V3 pools for the given route.
909
+ *
910
+ * @param route the route to refresh the V3 pools for
911
+ * @param config the routing config
912
+ * @param v3PoolProvider the V3 pool provider
913
+ * @returns the refreshed route
914
+ */
915
+ static async refreshV3Pools(route, config, v3PoolProvider) {
916
+ const refreshedPools = [];
917
+ for (const pool of route.pools) {
918
+ const v3Pools = await v3PoolProvider.getPools([[pool.token0, pool.token1, pool.fee]], config);
919
+ const refreshed = v3Pools.getPool(pool.token0, pool.token1, pool.fee);
920
+ if (refreshed)
921
+ refreshedPools.push(refreshed);
922
+ else {
923
+ // if the pool is not found, we need to log the error and add the original pool back in
924
+ AlphaRouter.logV3PoolRefreshError(pool);
925
+ refreshedPools.push(pool);
926
+ }
927
+ }
928
+ return cloneV3RouteWithNewPools(route, refreshedPools);
929
+ }
930
+ /**
931
+ * Refreshes the V4 pools for the given route.
932
+ *
933
+ * @param route the route to refresh the V4 pools for
934
+ * @param config the routing config
935
+ * @param v4PoolProvider the V4 pool provider
936
+ * @returns the refreshed route
937
+ */
938
+ static async refreshV4Pools(route, config, v4PoolProvider) {
939
+ const refreshedPools = [];
940
+ for (const pool of route.pools) {
941
+ const v4Pools = await v4PoolProvider.getPools([
942
+ [
943
+ pool.currency0,
944
+ pool.currency1,
945
+ pool.fee,
946
+ pool.tickSpacing,
947
+ pool.hooks,
948
+ ],
949
+ ], config);
950
+ const refreshed = v4Pools.getPool(pool.currency0, pool.currency1, pool.fee, pool.tickSpacing, pool.hooks);
951
+ if (refreshed)
952
+ refreshedPools.push(refreshed);
953
+ else {
954
+ // if the pool is not found, we need to log the error and add the original pool back in
955
+ AlphaRouter.logV4PoolRefreshError(pool);
956
+ refreshedPools.push(pool);
957
+ }
958
+ }
959
+ return cloneV4RouteWithNewPools(route, refreshedPools);
960
+ }
961
+ /**
962
+ * Refreshes the mixed pools for the given route.
963
+ *
964
+ * @param route the route to refresh the mixed pools for
965
+ * @param config the routing config
966
+ * @param v2PoolProvider the V2 pool provider
967
+ * @param v3PoolProvider the V3 pool provider
968
+ * @param v4PoolProvider the V4 pool provider
969
+ * @returns the refreshed route
970
+ */
971
+ static async refreshMixedPools(route, config, v2PoolProvider, v3PoolProvider, v4PoolProvider) {
972
+ const refreshedPools = [];
973
+ for (const pool of route.pools) {
974
+ if (pool instanceof V2Pool) {
975
+ const v2Pools = await v2PoolProvider.getPools([[pool.token0, pool.token1]], config);
976
+ const refreshed = v2Pools.getPool(pool.token0, pool.token1);
977
+ if (refreshed)
978
+ refreshedPools.push(refreshed);
979
+ else {
980
+ // if the pool is not found, we need to log the error and add the original pool back in
981
+ AlphaRouter.logV2PoolRefreshError(pool);
982
+ refreshedPools.push(pool);
983
+ }
984
+ }
985
+ else if (pool instanceof V3Pool) {
986
+ const v3Pools = await v3PoolProvider.getPools([[pool.token0, pool.token1, pool.fee]], config);
987
+ const refreshed = v3Pools.getPool(pool.token0, pool.token1, pool.fee);
988
+ if (refreshed)
989
+ refreshedPools.push(refreshed);
990
+ else {
991
+ // if the pool is not found, we need to log the error and add the original pool back in
992
+ AlphaRouter.logV3PoolRefreshError(pool);
993
+ refreshedPools.push(pool);
994
+ }
995
+ }
996
+ else if (pool instanceof V4Pool) {
997
+ const v4Pools = await v4PoolProvider.getPools([
998
+ [
999
+ pool.currency0,
1000
+ pool.currency1,
1001
+ pool.fee,
1002
+ pool.tickSpacing,
1003
+ pool.hooks,
1004
+ ],
1005
+ ], config);
1006
+ const refreshed = v4Pools.getPool(pool.currency0, pool.currency1, pool.fee, pool.tickSpacing, pool.hooks);
1007
+ if (refreshed)
1008
+ refreshedPools.push(refreshed);
1009
+ else {
1010
+ // if the pool is not found, we need to log the error and add the original pool back in
1011
+ AlphaRouter.logV4PoolRefreshError(pool);
1012
+ refreshedPools.push(pool);
1013
+ }
1014
+ }
1015
+ else {
1016
+ throw new Error('Unknown pool type in mixed route');
1017
+ }
1018
+ }
1019
+ return cloneMixedRouteWithNewPools(route, refreshedPools);
1020
+ }
1021
+ static logV2PoolRefreshError(v2Pool) {
1022
+ log.error({
1023
+ token0: v2Pool.token0,
1024
+ token1: v2Pool.token1,
1025
+ }, 'Failed to refresh V2 pool');
1026
+ }
1027
+ static logV3PoolRefreshError(v3Pool) {
1028
+ log.error({
1029
+ token0: v3Pool.token0,
1030
+ token1: v3Pool.token1,
1031
+ fee: v3Pool.fee,
1032
+ }, 'Failed to refresh V3 pool');
1033
+ }
1034
+ static logV4PoolRefreshError(v4Pool) {
1035
+ log.error({
1036
+ token0: v4Pool.currency0,
1037
+ token1: v4Pool.currency1,
1038
+ fee: v4Pool.fee,
1039
+ tickSpacing: v4Pool.tickSpacing,
1040
+ hooks: v4Pool.hooks,
1041
+ }, 'Failed to refresh V4 pool');
1042
+ }
1043
+ async setCachedRoutesAndLog(amount, currencyIn, currencyOut, tradeType, metricsPrefix, routesToCache, cachedRoutesRouteIds) {
1044
+ var _a;
1045
+ if (routesToCache) {
1046
+ const cachedRoutesChanged = cachedRoutesRouteIds !== undefined &&
1047
+ // it's possible that top cached routes may be split routes,
1048
+ // so that we always serialize all the top 8 retrieved cached routes vs the top routes.
1049
+ !cachedRoutesRouteIds.startsWith(serializeRouteIds(routesToCache.routes.map((r) => r.routeId)));
1050
+ if (cachedRoutesChanged) {
1051
+ metric.putMetric('cachedRoutesChanged', 1, MetricLoggerUnit.Count);
1052
+ metric.putMetric(`cachedRoutesChanged_chainId${currencyIn.chainId}`, 1, MetricLoggerUnit.Count);
1053
+ metric.putMetric(`cachedRoutesChanged_chainId${currencyOut.chainId}_pair${currencyIn.symbol}${currencyOut.symbol}`, 1, MetricLoggerUnit.Count);
1054
+ }
1055
+ else {
1056
+ metric.putMetric('cachedRoutesNotChanged', 1, MetricLoggerUnit.Count);
1057
+ metric.putMetric(`cachedRoutesNotChanged_chainId${currencyIn.chainId}`, 1, MetricLoggerUnit.Count);
1058
+ metric.putMetric(`cachedRoutesNotChanged_chainId${currencyOut.chainId}_pair${currencyIn.symbol}${currencyOut.symbol}`, 1, MetricLoggerUnit.Count);
1059
+ }
1060
+ await ((_a = this.routeCachingProvider) === null || _a === void 0 ? void 0 : _a.setCachedRoute(routesToCache, amount).then((success) => {
1061
+ const status = success ? 'success' : 'rejected';
1062
+ metric.putMetric(`${metricsPrefix}_${status}`, 1, MetricLoggerUnit.Count);
1063
+ }).catch((reason) => {
1064
+ log.error({
1065
+ reason: reason,
1066
+ tokenPair: this.tokenPairSymbolTradeTypeChainId(currencyIn, currencyOut, tradeType),
1067
+ }, `SetCachedRoute failure`);
1068
+ metric.putMetric(`${metricsPrefix}_failure`, 1, MetricLoggerUnit.Count);
1069
+ }));
1070
+ }
1071
+ else {
1072
+ metric.putMetric(`${metricsPrefix}_unnecessary`, 1, MetricLoggerUnit.Count);
1073
+ }
1074
+ }
1075
+ async getSwapRouteFromCache(currencyIn, currencyOut, cachedRoutes, blockNumber, amount, quoteCurrency, tradeType, routingConfig, v3GasModel, v4GasModel, mixedRouteGasModel, gasPriceWei, v2GasModel, swapConfig, providerConfig) {
1076
+ var _a, _c, _d, _e, _f, _g;
1077
+ const tokenPairProperties = await this.tokenPropertiesProvider.getTokensProperties([currencyIn, currencyOut], providerConfig);
1078
+ const sellTokenIsFot = (_d = (_c = (_a = tokenPairProperties[getAddressLowerCase(currencyIn)]) === null || _a === void 0 ? void 0 : _a.tokenFeeResult) === null || _c === void 0 ? void 0 : _c.sellFeeBps) === null || _d === void 0 ? void 0 : _d.gt(0);
1079
+ const buyTokenIsFot = (_g = (_f = (_e = tokenPairProperties[getAddressLowerCase(currencyOut)]) === null || _e === void 0 ? void 0 : _e.tokenFeeResult) === null || _f === void 0 ? void 0 : _f.buyFeeBps) === null || _g === void 0 ? void 0 : _g.gt(0);
1080
+ const fotInDirectSwap = sellTokenIsFot || buyTokenIsFot;
1081
+ log.info({
1082
+ protocols: cachedRoutes.protocolsCovered,
1083
+ tradeType: cachedRoutes.tradeType,
1084
+ cachedBlockNumber: cachedRoutes.blockNumber,
1085
+ quoteBlockNumber: blockNumber,
1086
+ }, 'Routing across CachedRoute');
1087
+ const quotePromises = [];
1088
+ const v4Routes = cachedRoutes.routes.filter((route) => route.protocol === Protocol.V4);
1089
+ const v3Routes = cachedRoutes.routes.filter((route) => route.protocol === Protocol.V3);
1090
+ const v2Routes = cachedRoutes.routes.filter((route) => route.protocol === Protocol.V2);
1091
+ const mixedRoutes = cachedRoutes.routes.filter((route) => route.protocol === Protocol.MIXED);
1092
+ let percents;
1093
+ let amounts;
1094
+ if (cachedRoutes.routes.length > 1) {
1095
+ // If we have more than 1 route, we will quote the different percents for it, following the regular process
1096
+ [percents, amounts] = this.getAmountDistribution(amount, routingConfig);
1097
+ }
1098
+ else if (cachedRoutes.routes.length == 1) {
1099
+ [percents, amounts] = [[100], [amount]];
1100
+ }
1101
+ else {
1102
+ // In this case this means that there's no route, so we return null
1103
+ return Promise.resolve(null);
1104
+ }
1105
+ if (v4Routes.length > 0) {
1106
+ const v4RoutesFromCache = v4Routes.map((cachedRoute) => cachedRoute.route);
1107
+ metric.putMetric('SwapRouteFromCache_V4_GetQuotes_Request', 1, MetricLoggerUnit.Count);
1108
+ const beforeGetQuotes = Date.now();
1109
+ quotePromises.push(this.v4Quoter
1110
+ .getQuotes(v4RoutesFromCache, amounts, percents, quoteCurrency, tradeType, routingConfig, undefined, v4GasModel)
1111
+ .then((result) => {
1112
+ metric.putMetric(`SwapRouteFromCache_V4_GetQuotes_Load`, Date.now() - beforeGetQuotes, MetricLoggerUnit.Milliseconds);
1113
+ return result;
1114
+ }));
1115
+ }
1116
+ if (!fotInDirectSwap) {
1117
+ if (v3Routes.length > 0) {
1118
+ const v3RoutesFromCache = v3Routes.map((cachedRoute) => cachedRoute.route);
1119
+ metric.putMetric('SwapRouteFromCache_V3_GetQuotes_Request', 1, MetricLoggerUnit.Count);
1120
+ const beforeGetQuotes = Date.now();
1121
+ quotePromises.push(this.v3Quoter
1122
+ .getQuotes(v3RoutesFromCache, amounts, percents, quoteCurrency.wrapped, tradeType, routingConfig, undefined, v3GasModel)
1123
+ .then((result) => {
1124
+ metric.putMetric(`SwapRouteFromCache_V3_GetQuotes_Load`, Date.now() - beforeGetQuotes, MetricLoggerUnit.Milliseconds);
1125
+ return result;
1126
+ }));
1127
+ }
1128
+ }
1129
+ if (v2Routes.length > 0) {
1130
+ const v2RoutesFromCache = v2Routes.map((cachedRoute) => cachedRoute.route);
1131
+ metric.putMetric('SwapRouteFromCache_V2_GetQuotes_Request', 1, MetricLoggerUnit.Count);
1132
+ const beforeGetQuotes = Date.now();
1133
+ quotePromises.push(this.v2Quoter
1134
+ .refreshRoutesThenGetQuotes(cachedRoutes.currencyIn.wrapped, cachedRoutes.currencyOut.wrapped, v2RoutesFromCache, amounts, percents, quoteCurrency.wrapped, tradeType, routingConfig, gasPriceWei)
1135
+ .then((result) => {
1136
+ metric.putMetric(`SwapRouteFromCache_V2_GetQuotes_Load`, Date.now() - beforeGetQuotes, MetricLoggerUnit.Milliseconds);
1137
+ return result;
1138
+ }));
1139
+ }
1140
+ if (!fotInDirectSwap) {
1141
+ if (mixedRoutes.length > 0) {
1142
+ const mixedRoutesFromCache = mixedRoutes.map((cachedRoute) => cachedRoute.route);
1143
+ metric.putMetric('SwapRouteFromCache_Mixed_GetQuotes_Request', 1, MetricLoggerUnit.Count);
1144
+ const beforeGetQuotes = Date.now();
1145
+ quotePromises.push(this.mixedQuoter
1146
+ .getQuotes(mixedRoutesFromCache, amounts, percents, quoteCurrency.wrapped, tradeType, routingConfig, undefined, mixedRouteGasModel)
1147
+ .then((result) => {
1148
+ metric.putMetric(`SwapRouteFromCache_Mixed_GetQuotes_Load`, Date.now() - beforeGetQuotes, MetricLoggerUnit.Milliseconds);
1149
+ return result;
1150
+ }));
1151
+ }
1152
+ }
1153
+ const getQuotesResults = await Promise.all(quotePromises);
1154
+ const allRoutesWithValidQuotes = _.flatMap(getQuotesResults, (quoteResult) => quoteResult.routesWithValidQuotes);
1155
+ return getBestSwapRoute(amount, percents, allRoutesWithValidQuotes, tradeType, this.chainId, routingConfig, this.portionProvider, v2GasModel, v3GasModel, v4GasModel, swapConfig, providerConfig);
1156
+ }
1157
+ async getSwapRouteFromChain(amount, currencyIn, currencyOut, protocols, quoteCurrency, tradeType, routingConfig, v3GasModel, v4GasModel, mixedRouteGasModel, gasPriceWei, v2GasModel, swapConfig, providerConfig) {
1158
+ var _a, _c, _d, _e, _f, _g, _h, _j, _k;
1159
+ const tokenPairProperties = await this.tokenPropertiesProvider.getTokensProperties([currencyIn, currencyOut], providerConfig);
1160
+ const sellTokenIsFot = (_d = (_c = (_a = tokenPairProperties[getAddressLowerCase(currencyIn)]) === null || _a === void 0 ? void 0 : _a.tokenFeeResult) === null || _c === void 0 ? void 0 : _c.sellFeeBps) === null || _d === void 0 ? void 0 : _d.gt(0);
1161
+ const buyTokenIsFot = (_g = (_f = (_e = tokenPairProperties[getAddressLowerCase(currencyOut)]) === null || _e === void 0 ? void 0 : _e.tokenFeeResult) === null || _f === void 0 ? void 0 : _f.buyFeeBps) === null || _g === void 0 ? void 0 : _g.gt(0);
1162
+ const fotInDirectSwap = sellTokenIsFot || buyTokenIsFot;
1163
+ // Generate our distribution of amounts, i.e. fractions of the input amount.
1164
+ // We will get quotes for fractions of the input amount for different routes, then
1165
+ // combine to generate split routes.
1166
+ const [percents, amounts] = this.getAmountDistribution(amount, routingConfig);
1167
+ const noProtocolsSpecified = protocols.length === 0;
1168
+ const v4ProtocolSpecified = protocols.includes(Protocol.V4);
1169
+ const v3ProtocolSpecified = protocols.includes(Protocol.V3);
1170
+ const v2ProtocolSpecified = protocols.includes(Protocol.V2);
1171
+ const v2SupportedInChain = (_h = this.v2Supported) === null || _h === void 0 ? void 0 : _h.includes(this.chainId);
1172
+ const v4SupportedInChain = (_j = this.v4Supported) === null || _j === void 0 ? void 0 : _j.includes(this.chainId);
1173
+ const shouldQueryMixedProtocol = protocols.includes(Protocol.MIXED) ||
1174
+ (noProtocolsSpecified && v2SupportedInChain && v4SupportedInChain);
1175
+ const mixedProtocolAllowed = ((_k = this.mixedSupported) === null || _k === void 0 ? void 0 : _k.includes(this.chainId)) &&
1176
+ tradeType === TradeType.EXACT_INPUT;
1177
+ const beforeGetCandidates = Date.now();
1178
+ let v4CandidatePoolsPromise = Promise.resolve(undefined);
1179
+ // we are explicitly requiring people to specify v4 for now
1180
+ if (v4SupportedInChain && (v4ProtocolSpecified || noProtocolsSpecified)) {
1181
+ // if (v4ProtocolSpecified || noProtocolsSpecified) {
1182
+ v4CandidatePoolsPromise = getV4CandidatePools({
1183
+ currencyIn: currencyIn,
1184
+ currencyOut: currencyOut,
1185
+ tokenProvider: this.tokenProvider,
1186
+ blockedTokenListProvider: this.blockedTokenListProvider,
1187
+ poolProvider: this.v4PoolProvider,
1188
+ routeType: tradeType,
1189
+ subgraphProvider: this.v4SubgraphProvider,
1190
+ routingConfig,
1191
+ chainId: this.chainId,
1192
+ v4PoolParams: this.v4PoolParams,
1193
+ }).then((candidatePools) => {
1194
+ metric.putMetric('GetV4CandidatePools', Date.now() - beforeGetCandidates, MetricLoggerUnit.Milliseconds);
1195
+ return candidatePools;
1196
+ });
1197
+ }
1198
+ let v3CandidatePoolsPromise = Promise.resolve(undefined);
1199
+ if (!fotInDirectSwap) {
1200
+ if (v3ProtocolSpecified || noProtocolsSpecified) {
1201
+ const tokenIn = currencyIn.wrapped;
1202
+ const tokenOut = currencyOut.wrapped;
1203
+ v3CandidatePoolsPromise = getV3CandidatePools({
1204
+ tokenIn,
1205
+ tokenOut,
1206
+ tokenProvider: this.tokenProvider,
1207
+ blockedTokenListProvider: this.blockedTokenListProvider,
1208
+ poolProvider: this.v3PoolProvider,
1209
+ routeType: tradeType,
1210
+ subgraphProvider: this.v3SubgraphProvider,
1211
+ routingConfig,
1212
+ chainId: this.chainId,
1213
+ }).then((candidatePools) => {
1214
+ metric.putMetric('GetV3CandidatePools', Date.now() - beforeGetCandidates, MetricLoggerUnit.Milliseconds);
1215
+ return candidatePools;
1216
+ });
1217
+ }
1218
+ }
1219
+ let v2CandidatePoolsPromise = Promise.resolve(undefined);
1220
+ if (v2SupportedInChain && (v2ProtocolSpecified || noProtocolsSpecified)) {
1221
+ const tokenIn = currencyIn.wrapped;
1222
+ const tokenOut = currencyOut.wrapped;
1223
+ // Fetch all the pools that we will consider routing via. There are thousands
1224
+ // of pools, so we filter them to a set of candidate pools that we expect will
1225
+ // result in good prices.
1226
+ v2CandidatePoolsPromise = getV2CandidatePools({
1227
+ tokenIn,
1228
+ tokenOut,
1229
+ tokenProvider: this.tokenProvider,
1230
+ blockedTokenListProvider: this.blockedTokenListProvider,
1231
+ poolProvider: this.v2PoolProvider,
1232
+ routeType: tradeType,
1233
+ subgraphProvider: this.v2SubgraphProvider,
1234
+ routingConfig,
1235
+ chainId: this.chainId,
1236
+ }).then((candidatePools) => {
1237
+ metric.putMetric('GetV2CandidatePools', Date.now() - beforeGetCandidates, MetricLoggerUnit.Milliseconds);
1238
+ return candidatePools;
1239
+ });
1240
+ }
1241
+ const quotePromises = [];
1242
+ // for v4, for now we explicitly require people to specify
1243
+ if (v4SupportedInChain && v4ProtocolSpecified) {
1244
+ log.info({ protocols, tradeType }, 'Routing across V4');
1245
+ metric.putMetric('SwapRouteFromChain_V4_GetRoutesThenQuotes_Request', 1, MetricLoggerUnit.Count);
1246
+ const beforeGetRoutesThenQuotes = Date.now();
1247
+ quotePromises.push(v4CandidatePoolsPromise.then((v4CandidatePools) => this.v4Quoter
1248
+ .getRoutesThenQuotes(currencyIn, currencyOut, amount, amounts, percents, quoteCurrency, v4CandidatePools, tradeType, routingConfig, v4GasModel)
1249
+ .then((result) => {
1250
+ metric.putMetric(`SwapRouteFromChain_V4_GetRoutesThenQuotes_Load`, Date.now() - beforeGetRoutesThenQuotes, MetricLoggerUnit.Milliseconds);
1251
+ return result;
1252
+ })));
1253
+ }
1254
+ if (!fotInDirectSwap) {
1255
+ // Maybe Quote V3 - if V3 is specified, or no protocol is specified
1256
+ if (v3ProtocolSpecified || noProtocolsSpecified) {
1257
+ log.info({ protocols, tradeType }, 'Routing across V3');
1258
+ metric.putMetric('SwapRouteFromChain_V3_GetRoutesThenQuotes_Request', 1, MetricLoggerUnit.Count);
1259
+ const beforeGetRoutesThenQuotes = Date.now();
1260
+ const tokenIn = currencyIn.wrapped;
1261
+ const tokenOut = currencyOut.wrapped;
1262
+ quotePromises.push(v3CandidatePoolsPromise.then((v3CandidatePools) => this.v3Quoter
1263
+ .getRoutesThenQuotes(tokenIn, tokenOut, amount, amounts, percents, quoteCurrency.wrapped, v3CandidatePools, tradeType, routingConfig, v3GasModel)
1264
+ .then((result) => {
1265
+ metric.putMetric(`SwapRouteFromChain_V3_GetRoutesThenQuotes_Load`, Date.now() - beforeGetRoutesThenQuotes, MetricLoggerUnit.Milliseconds);
1266
+ return result;
1267
+ })));
1268
+ }
1269
+ }
1270
+ // Maybe Quote V2 - if V2 is specified, or no protocol is specified AND v2 is supported in this chain
1271
+ if (v2SupportedInChain && (v2ProtocolSpecified || noProtocolsSpecified)) {
1272
+ log.info({ protocols, tradeType }, 'Routing across V2');
1273
+ metric.putMetric('SwapRouteFromChain_V2_GetRoutesThenQuotes_Request', 1, MetricLoggerUnit.Count);
1274
+ const beforeGetRoutesThenQuotes = Date.now();
1275
+ const tokenIn = currencyIn.wrapped;
1276
+ const tokenOut = currencyOut.wrapped;
1277
+ quotePromises.push(v2CandidatePoolsPromise.then((v2CandidatePools) => this.v2Quoter
1278
+ .getRoutesThenQuotes(tokenIn, tokenOut, amount, amounts, percents, quoteCurrency.wrapped, v2CandidatePools, tradeType, routingConfig, v2GasModel, gasPriceWei)
1279
+ .then((result) => {
1280
+ metric.putMetric(`SwapRouteFromChain_V2_GetRoutesThenQuotes_Load`, Date.now() - beforeGetRoutesThenQuotes, MetricLoggerUnit.Milliseconds);
1281
+ return result;
1282
+ })));
1283
+ }
1284
+ if (!fotInDirectSwap) {
1285
+ // Maybe Quote mixed routes
1286
+ // if MixedProtocol is specified or no protocol is specified and v2 is supported AND tradeType is ExactIn
1287
+ // AND is Mainnet or Gorli
1288
+ // Also make sure there are at least 2 protocols provided besides MIXED, before entering mixed quoter
1289
+ if (shouldQueryMixedProtocol &&
1290
+ mixedProtocolAllowed &&
1291
+ protocols.filter((protocol) => protocol !== Protocol.MIXED).length >= 2) {
1292
+ log.info({ protocols, tradeType }, 'Routing across MixedRoutes');
1293
+ metric.putMetric('SwapRouteFromChain_Mixed_GetRoutesThenQuotes_Request', 1, MetricLoggerUnit.Count);
1294
+ const beforeGetRoutesThenQuotes = Date.now();
1295
+ quotePromises.push(Promise.all([
1296
+ v4CandidatePoolsPromise,
1297
+ v3CandidatePoolsPromise,
1298
+ v2CandidatePoolsPromise,
1299
+ ]).then(async ([v4CandidatePools, v3CandidatePools, v2CandidatePools]) => {
1300
+ const tokenIn = currencyIn.wrapped;
1301
+ const tokenOut = currencyOut.wrapped;
1302
+ const crossLiquidityPools = await getMixedCrossLiquidityCandidatePools({
1303
+ tokenIn,
1304
+ tokenOut,
1305
+ blockNumber: routingConfig.blockNumber,
1306
+ v2SubgraphProvider: this.v2SubgraphProvider,
1307
+ v3SubgraphProvider: this.v3SubgraphProvider,
1308
+ v4SubgraphProvider: this.v4SubgraphProvider,
1309
+ v2Candidates: v2CandidatePools,
1310
+ v3Candidates: v3CandidatePools,
1311
+ v4Candidates: v4CandidatePools,
1312
+ mixedCrossLiquidityV3AgainstV4Supported: this.mixedCrossLiquidityV3AgainstV4Supported,
1313
+ chainId: this.chainId,
1314
+ });
1315
+ return this.mixedQuoter
1316
+ .getRoutesThenQuotes(currencyIn, currencyOut, amount, amounts, percents, quoteCurrency.wrapped, [
1317
+ v4CandidatePools,
1318
+ v3CandidatePools,
1319
+ v2CandidatePools,
1320
+ crossLiquidityPools,
1321
+ ], tradeType, routingConfig, mixedRouteGasModel)
1322
+ .then((result) => {
1323
+ metric.putMetric(`SwapRouteFromChain_Mixed_GetRoutesThenQuotes_Load`, Date.now() - beforeGetRoutesThenQuotes, MetricLoggerUnit.Milliseconds);
1324
+ return result;
1325
+ });
1326
+ }));
1327
+ }
1328
+ }
1329
+ const getQuotesResults = await Promise.all(quotePromises);
1330
+ const allRoutesWithValidQuotes = [];
1331
+ const allCandidatePools = [];
1332
+ getQuotesResults.forEach((getQuoteResult) => {
1333
+ allRoutesWithValidQuotes.push(...getQuoteResult.routesWithValidQuotes);
1334
+ if (getQuoteResult.candidatePools) {
1335
+ allCandidatePools.push(getQuoteResult.candidatePools);
1336
+ }
1337
+ });
1338
+ if (allRoutesWithValidQuotes.length === 0) {
1339
+ log.info({ allRoutesWithValidQuotes }, 'Received no valid quotes');
1340
+ return null;
1341
+ }
1342
+ // Given all the quotes for all the amounts for all the routes, find the best combination.
1343
+ const bestSwapRoute = await getBestSwapRoute(amount, percents, allRoutesWithValidQuotes, tradeType, this.chainId, routingConfig, this.portionProvider, v2GasModel, v3GasModel, v4GasModel, swapConfig, providerConfig);
1344
+ if (bestSwapRoute) {
1345
+ this.emitPoolSelectionMetrics(bestSwapRoute, allCandidatePools, currencyIn, currencyOut);
1346
+ }
1347
+ return bestSwapRoute;
1348
+ }
1349
+ tradeTypeStr(tradeType) {
1350
+ return tradeType === TradeType.EXACT_INPUT ? 'ExactIn' : 'ExactOut';
1351
+ }
1352
+ tokenPairSymbolTradeTypeChainId(currencyIn, currencyOut, tradeType) {
1353
+ return `${currencyIn.symbol}/${currencyOut.symbol}/${this.tradeTypeStr(tradeType)}/${this.chainId}`;
1354
+ }
1355
+ determineCurrencyInOutFromTradeType(tradeType, amount, quoteCurrency) {
1356
+ if (tradeType === TradeType.EXACT_INPUT) {
1357
+ return {
1358
+ currencyIn: amount.currency,
1359
+ currencyOut: quoteCurrency,
1360
+ };
1361
+ }
1362
+ else {
1363
+ return {
1364
+ currencyIn: quoteCurrency,
1365
+ currencyOut: amount.currency,
1366
+ };
1367
+ }
1368
+ }
1369
+ async getGasPriceWei(latestBlockNumber, requestBlockNumber) {
1370
+ // Track how long it takes to resolve this async call.
1371
+ const beforeGasTimestamp = Date.now();
1372
+ // Get an estimate of the gas price to use when estimating gas cost of different routes.
1373
+ const { gasPriceWei } = await this.gasPriceProvider.getGasPrice(latestBlockNumber, requestBlockNumber);
1374
+ metric.putMetric('GasPriceLoad', Date.now() - beforeGasTimestamp, MetricLoggerUnit.Milliseconds);
1375
+ return gasPriceWei;
1376
+ }
1377
+ async getGasModels(gasPriceWei, amountToken, quoteToken, providerConfig) {
1378
+ var _a;
1379
+ const beforeGasModel = Date.now();
1380
+ const usdPoolPromise = getHighestLiquidityV3USDPool(this.chainId, this.v3PoolProvider, providerConfig);
1381
+ const nativeCurrency = WRAPPED_NATIVE_CURRENCY[this.chainId];
1382
+ const nativeAndQuoteTokenV3PoolPromise = !quoteToken.equals(nativeCurrency)
1383
+ ? getHighestLiquidityV3NativePool(quoteToken, this.v3PoolProvider, providerConfig)
1384
+ : Promise.resolve(null);
1385
+ const nativeAndAmountTokenV3PoolPromise = !amountToken.equals(nativeCurrency)
1386
+ ? getHighestLiquidityV3NativePool(amountToken, this.v3PoolProvider, providerConfig)
1387
+ : Promise.resolve(null);
1388
+ // If a specific gas token is specified in the provider config
1389
+ // fetch the highest liq V3 pool with it and the native currency
1390
+ const nativeAndSpecifiedGasTokenV3PoolPromise = (providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.gasToken) &&
1391
+ !(providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.gasToken.equals(nativeCurrency))
1392
+ ? getHighestLiquidityV3NativePool(providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.gasToken, this.v3PoolProvider, providerConfig)
1393
+ : Promise.resolve(null);
1394
+ const [usdPool, nativeAndQuoteTokenV3Pool, nativeAndAmountTokenV3Pool, nativeAndSpecifiedGasTokenV3Pool,] = await Promise.all([
1395
+ usdPoolPromise,
1396
+ nativeAndQuoteTokenV3PoolPromise,
1397
+ nativeAndAmountTokenV3PoolPromise,
1398
+ nativeAndSpecifiedGasTokenV3PoolPromise,
1399
+ ]);
1400
+ const pools = {
1401
+ usdPool: usdPool,
1402
+ nativeAndQuoteTokenV3Pool: nativeAndQuoteTokenV3Pool,
1403
+ nativeAndAmountTokenV3Pool: nativeAndAmountTokenV3Pool,
1404
+ nativeAndSpecifiedGasTokenV3Pool: nativeAndSpecifiedGasTokenV3Pool,
1405
+ };
1406
+ const v2GasModelPromise = ((_a = this.v2Supported) === null || _a === void 0 ? void 0 : _a.includes(this.chainId))
1407
+ ? this.v2GasModelFactory
1408
+ .buildGasModel({
1409
+ chainId: this.chainId,
1410
+ gasPriceWei,
1411
+ poolProvider: this.v2PoolProvider,
1412
+ token: quoteToken,
1413
+ l2GasDataProvider: this.l2GasDataProvider,
1414
+ providerConfig: providerConfig,
1415
+ })
1416
+ .catch((_) => undefined) // If v2 model throws uncaught exception, we return undefined v2 gas model, so there's a chance v3 route can go through
1417
+ : Promise.resolve(undefined);
1418
+ const v3GasModelPromise = this.v3GasModelFactory.buildGasModel({
1419
+ chainId: this.chainId,
1420
+ gasPriceWei,
1421
+ pools,
1422
+ amountToken,
1423
+ quoteToken,
1424
+ v2poolProvider: this.v2PoolProvider,
1425
+ l2GasDataProvider: this.l2GasDataProvider,
1426
+ providerConfig: providerConfig,
1427
+ });
1428
+ const v4GasModelPromise = this.v4GasModelFactory.buildGasModel({
1429
+ chainId: this.chainId,
1430
+ gasPriceWei,
1431
+ pools,
1432
+ amountToken,
1433
+ quoteToken,
1434
+ v2poolProvider: this.v2PoolProvider,
1435
+ l2GasDataProvider: this.l2GasDataProvider,
1436
+ providerConfig: providerConfig,
1437
+ });
1438
+ const mixedRouteGasModelPromise = this.mixedRouteGasModelFactory.buildGasModel({
1439
+ chainId: this.chainId,
1440
+ gasPriceWei,
1441
+ pools,
1442
+ amountToken,
1443
+ quoteToken,
1444
+ v2poolProvider: this.v2PoolProvider,
1445
+ providerConfig: providerConfig,
1446
+ });
1447
+ const [v2GasModel, v3GasModel, V4GasModel, mixedRouteGasModel] = await Promise.all([
1448
+ v2GasModelPromise,
1449
+ v3GasModelPromise,
1450
+ v4GasModelPromise,
1451
+ mixedRouteGasModelPromise,
1452
+ ]);
1453
+ metric.putMetric('GasModelCreation', Date.now() - beforeGasModel, MetricLoggerUnit.Milliseconds);
1454
+ return {
1455
+ v2GasModel: v2GasModel,
1456
+ v3GasModel: v3GasModel,
1457
+ v4GasModel: V4GasModel,
1458
+ mixedRouteGasModel: mixedRouteGasModel,
1459
+ };
1460
+ }
1461
+ // Note multiplications here can result in a loss of precision in the amounts (e.g. taking 50% of 101)
1462
+ // This is reconcilled at the end of the algorithm by adding any lost precision to one of
1463
+ // the splits in the route.
1464
+ getAmountDistribution(amount, routingConfig) {
1465
+ const { distributionPercent } = routingConfig;
1466
+ const percents = [];
1467
+ const amounts = [];
1468
+ for (let i = 1; i <= 100 / distributionPercent; i++) {
1469
+ percents.push(i * distributionPercent);
1470
+ amounts.push(amount.multiply(new Fraction(i * distributionPercent, 100)));
1471
+ }
1472
+ return [percents, amounts];
1473
+ }
1474
+ async buildSwapAndAddMethodParameters(trade, swapAndAddOptions, swapAndAddParameters) {
1475
+ const { swapOptions: { recipient, slippageTolerance, deadline, inputTokenPermit }, addLiquidityOptions: addLiquidityConfig, } = swapAndAddOptions;
1476
+ const preLiquidityPosition = swapAndAddParameters.preLiquidityPosition;
1477
+ const finalBalanceTokenIn = swapAndAddParameters.initialBalanceTokenIn.subtract(trade.inputAmount);
1478
+ const finalBalanceTokenOut = swapAndAddParameters.initialBalanceTokenOut.add(trade.outputAmount);
1479
+ const approvalTypes = await this.swapRouterProvider.getApprovalType(finalBalanceTokenIn, finalBalanceTokenOut);
1480
+ const zeroForOne = finalBalanceTokenIn.currency.wrapped.sortsBefore(finalBalanceTokenOut.currency.wrapped);
1481
+ return {
1482
+ ...SwapRouter.swapAndAddCallParameters(trade, {
1483
+ recipient,
1484
+ slippageTolerance,
1485
+ deadlineOrPreviousBlockhash: deadline,
1486
+ inputTokenPermit,
1487
+ }, Position.fromAmounts({
1488
+ pool: preLiquidityPosition.pool,
1489
+ tickLower: preLiquidityPosition.tickLower,
1490
+ tickUpper: preLiquidityPosition.tickUpper,
1491
+ amount0: zeroForOne
1492
+ ? finalBalanceTokenIn.quotient.toString()
1493
+ : finalBalanceTokenOut.quotient.toString(),
1494
+ amount1: zeroForOne
1495
+ ? finalBalanceTokenOut.quotient.toString()
1496
+ : finalBalanceTokenIn.quotient.toString(),
1497
+ useFullPrecision: false,
1498
+ }), addLiquidityConfig, approvalTypes.approvalTokenIn, approvalTypes.approvalTokenOut),
1499
+ to: SWAP_ROUTER_02_ADDRESSES(this.chainId),
1500
+ };
1501
+ }
1502
+ emitPoolSelectionMetrics(swapRouteRaw, allPoolsBySelection, currencyIn, currencyOut) {
1503
+ const poolAddressesUsed = new Set();
1504
+ const { routes: routeAmounts } = swapRouteRaw;
1505
+ _(routeAmounts)
1506
+ .flatMap((routeAmount) => {
1507
+ const { poolIdentifiers: poolAddresses } = routeAmount;
1508
+ return poolAddresses;
1509
+ })
1510
+ .forEach((address) => {
1511
+ poolAddressesUsed.add(address.toLowerCase());
1512
+ });
1513
+ for (const poolsBySelection of allPoolsBySelection) {
1514
+ const { protocol } = poolsBySelection;
1515
+ _.forIn(poolsBySelection.selections, (pools, topNSelection) => {
1516
+ const topNUsed = _.findLastIndex(pools, (pool) => poolAddressesUsed.has(pool.id.toLowerCase())) + 1;
1517
+ metric.putMetric(_.capitalize(`${protocol}${topNSelection}`), topNUsed, MetricLoggerUnit.Count);
1518
+ });
1519
+ }
1520
+ let hasV4Route = false;
1521
+ let hasV3Route = false;
1522
+ let hasV2Route = false;
1523
+ let hasMixedRoute = false;
1524
+ for (const routeAmount of routeAmounts) {
1525
+ if (routeAmount.protocol === Protocol.V4) {
1526
+ hasV4Route = true;
1527
+ }
1528
+ if (routeAmount.protocol === Protocol.V3) {
1529
+ hasV3Route = true;
1530
+ }
1531
+ if (routeAmount.protocol === Protocol.V2) {
1532
+ hasV2Route = true;
1533
+ }
1534
+ if (routeAmount.protocol === Protocol.MIXED) {
1535
+ hasMixedRoute = true;
1536
+ }
1537
+ }
1538
+ if (hasMixedRoute && (hasV4Route || hasV3Route || hasV2Route)) {
1539
+ let metricsPrefix = 'Mixed';
1540
+ if (hasV4Route) {
1541
+ metricsPrefix += 'AndV4';
1542
+ }
1543
+ if (hasV3Route) {
1544
+ metricsPrefix += 'AndV3';
1545
+ }
1546
+ if (hasV2Route) {
1547
+ metricsPrefix += 'AndV2';
1548
+ }
1549
+ metric.putMetric(`${metricsPrefix}SplitRoute`, 1, MetricLoggerUnit.Count);
1550
+ metric.putMetric(`${metricsPrefix}SplitRouteForChain${this.chainId}`, 1, MetricLoggerUnit.Count);
1551
+ if (hasV4Route && (currencyIn.isNative || currencyOut.isNative)) {
1552
+ // Keep track of this edge case https://linear.app/uniswap/issue/ROUTE-303/tech-debt-split-route-can-have-different-ethweth-input-or-output#comment-bba53758
1553
+ metric.putMetric(`${metricsPrefix}SplitRouteWithNativeToken`, 1, MetricLoggerUnit.Count);
1554
+ metric.putMetric(`${metricsPrefix}SplitRouteWithNativeTokenForChain${this.chainId}`, 1, MetricLoggerUnit.Count);
1555
+ }
1556
+ }
1557
+ else if (hasV4Route && hasV3Route && hasV2Route) {
1558
+ metric.putMetric(`V4AndV3AndV2SplitRoute`, 1, MetricLoggerUnit.Count);
1559
+ metric.putMetric(`V4AndV3AndV2SplitRouteForChain${this.chainId}`, 1, MetricLoggerUnit.Count);
1560
+ if (currencyIn.isNative || currencyOut.isNative) {
1561
+ // Keep track of this edge case https://linear.app/uniswap/issue/ROUTE-303/tech-debt-split-route-can-have-different-ethweth-input-or-output#comment-bba53758
1562
+ metric.putMetric(`V4AndV3AndV2SplitRouteWithNativeToken`, 1, MetricLoggerUnit.Count);
1563
+ metric.putMetric(`V4AndV3AndV2SplitRouteWithNativeTokenForChain${this.chainId}`, 1, MetricLoggerUnit.Count);
1564
+ }
1565
+ }
1566
+ else if (hasMixedRoute) {
1567
+ if (routeAmounts.length > 1) {
1568
+ metric.putMetric(`MixedSplitRoute`, 1, MetricLoggerUnit.Count);
1569
+ metric.putMetric(`MixedSplitRouteForChain${this.chainId}`, 1, MetricLoggerUnit.Count);
1570
+ }
1571
+ else {
1572
+ metric.putMetric(`MixedRoute`, 1, MetricLoggerUnit.Count);
1573
+ metric.putMetric(`MixedRouteForChain${this.chainId}`, 1, MetricLoggerUnit.Count);
1574
+ }
1575
+ }
1576
+ else if (hasV4Route) {
1577
+ if (routeAmounts.length > 1) {
1578
+ metric.putMetric(`V4SplitRoute`, 1, MetricLoggerUnit.Count);
1579
+ metric.putMetric(`V4SplitRouteForChain${this.chainId}`, 1, MetricLoggerUnit.Count);
1580
+ }
1581
+ }
1582
+ else if (hasV3Route) {
1583
+ if (routeAmounts.length > 1) {
1584
+ metric.putMetric(`V3SplitRoute`, 1, MetricLoggerUnit.Count);
1585
+ metric.putMetric(`V3SplitRouteForChain${this.chainId}`, 1, MetricLoggerUnit.Count);
1586
+ }
1587
+ else {
1588
+ metric.putMetric(`V3Route`, 1, MetricLoggerUnit.Count);
1589
+ metric.putMetric(`V3RouteForChain${this.chainId}`, 1, MetricLoggerUnit.Count);
1590
+ }
1591
+ }
1592
+ else if (hasV2Route) {
1593
+ if (routeAmounts.length > 1) {
1594
+ metric.putMetric(`V2SplitRoute`, 1, MetricLoggerUnit.Count);
1595
+ metric.putMetric(`V2SplitRouteForChain${this.chainId}`, 1, MetricLoggerUnit.Count);
1596
+ }
1597
+ else {
1598
+ metric.putMetric(`V2Route`, 1, MetricLoggerUnit.Count);
1599
+ metric.putMetric(`V2RouteForChain${this.chainId}`, 1, MetricLoggerUnit.Count);
1600
+ }
1601
+ }
1602
+ }
1603
+ calculateOptimalRatio(position, sqrtRatioX96, zeroForOne) {
1604
+ const upperSqrtRatioX96 = TickMath.getSqrtRatioAtTick(position.tickUpper);
1605
+ const lowerSqrtRatioX96 = TickMath.getSqrtRatioAtTick(position.tickLower);
1606
+ // returns Fraction(0, 1) for any out of range position regardless of zeroForOne. Implication: function
1607
+ // cannot be used to determine the trading direction of out of range positions.
1608
+ if (JSBI.greaterThan(sqrtRatioX96, upperSqrtRatioX96) ||
1609
+ JSBI.lessThan(sqrtRatioX96, lowerSqrtRatioX96)) {
1610
+ return new Fraction(0, 1);
1611
+ }
1612
+ const precision = JSBI.BigInt('1' + '0'.repeat(18));
1613
+ let optimalRatio = new Fraction(SqrtPriceMath.getAmount0Delta(sqrtRatioX96, upperSqrtRatioX96, precision, true), SqrtPriceMath.getAmount1Delta(sqrtRatioX96, lowerSqrtRatioX96, precision, true));
1614
+ if (!zeroForOne)
1615
+ optimalRatio = optimalRatio.invert();
1616
+ return optimalRatio;
1617
+ }
1618
+ async userHasSufficientBalance(fromAddress, tradeType, amount, quote) {
1619
+ try {
1620
+ const neededBalance = tradeType === TradeType.EXACT_INPUT ? amount : quote;
1621
+ let balance;
1622
+ if (neededBalance.currency.isNative) {
1623
+ balance = await this.provider.getBalance(fromAddress);
1624
+ }
1625
+ else {
1626
+ const tokenContract = Erc20__factory.connect(neededBalance.currency.address, this.provider);
1627
+ balance = await tokenContract.balanceOf(fromAddress);
1628
+ }
1629
+ return balance.gte(BigNumber.from(neededBalance.quotient.toString()));
1630
+ }
1631
+ catch (e) {
1632
+ log.error(e, 'Error while checking user balance');
1633
+ return false;
1634
+ }
1635
+ }
1636
+ absoluteValue(fraction) {
1637
+ const numeratorAbs = JSBI.lessThan(fraction.numerator, JSBI.BigInt(0))
1638
+ ? JSBI.unaryMinus(fraction.numerator)
1639
+ : fraction.numerator;
1640
+ const denominatorAbs = JSBI.lessThan(fraction.denominator, JSBI.BigInt(0))
1641
+ ? JSBI.unaryMinus(fraction.denominator)
1642
+ : fraction.denominator;
1643
+ return new Fraction(numeratorAbs, denominatorAbs);
1644
+ }
1645
+ getBlockNumberPromise() {
1646
+ return retry(async (_b, attempt) => {
1647
+ if (attempt > 1) {
1648
+ log.info(`Get block number attempt ${attempt}`);
1649
+ }
1650
+ return this.provider.getBlockNumber();
1651
+ }, {
1652
+ retries: 2,
1653
+ minTimeout: 100,
1654
+ maxTimeout: 1000,
1655
+ });
1656
+ }
1657
+ // If we are requesting URv1.2, we need to keep entering cache
1658
+ // We want to skip cached routes access whenever "intent === INTENT.CACHING" or "hooksOption !== HooksOption.HOOKS_INCLUSIVE"
1659
+ // We keep this method as we might want to add more conditions in the future.
1660
+ static isAllowedToEnterCachedRoutes(intent, hooksOptions, swapRouter) {
1661
+ // intent takes highest precedence, as we need to ensure during caching intent, we do not enter cache no matter what
1662
+ if (intent !== undefined && intent === INTENT.CACHING) {
1663
+ return false;
1664
+ }
1665
+ // in case we have URv1.2 request during QUOTE intent, we assume cached routes correctly returns mixed route w/o v4, if mixed is best
1666
+ // or v2/v3 is the best.
1667
+ // implicitly it means hooksOptions no longer matters for URv1.2
1668
+ // swapRouter has higher precedence than hooksOptions, because in case of URv1.2, we set hooksOptions = NO_HOOKS as default,
1669
+ // but swapRouter does not have any v4 pool for routing, so swapRouter should always use caching during QUOTE intent.
1670
+ if (swapRouter) {
1671
+ return true;
1672
+ }
1673
+ // in case we have URv2.0, and we are in QUOTE intent, we only want to enter cache when hooksOptions is default, HOOKS_INCLUSIVE
1674
+ if (hooksOptions !== undefined &&
1675
+ hooksOptions !== HooksOptions.HOOKS_INCLUSIVE) {
1676
+ return false;
1677
+ }
1678
+ return true;
1679
+ }
1680
+ }
1681
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxwaGEtcm91dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3JvdXRlcnMvYWxwaGEtcm91dGVyL2FscGhhLXJvdXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDckQsT0FBTyxFQUFnQixlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN6RSxPQUFPLGtCQUFrQixNQUFNLDZCQUE2QixDQUFDO0FBQzdELE9BQU8sRUFDTCxRQUFRLEVBQ1IsVUFBVSxFQUdWLElBQUksR0FDTCxNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFDTCxPQUFPLEVBRVAsUUFBUSxFQUVSLFNBQVMsR0FDVixNQUFNLG1CQUFtQixDQUFDO0FBRTNCLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxJQUFJLElBQUksTUFBTSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDakQsT0FBTyxFQUNMLElBQUksRUFDSixJQUFJLElBQUksTUFBTSxFQUNkLFFBQVEsRUFDUixhQUFhLEVBQ2IsUUFBUSxHQUNULE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLElBQUksSUFBSSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNqRCxPQUFPLEtBQUssTUFBTSxhQUFhLENBQUM7QUFDaEMsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQ3hCLE9BQU8sQ0FBQyxNQUFNLFFBQVEsQ0FBQztBQUN2QixPQUFPLFNBQVMsTUFBTSxZQUFZLENBQUM7QUFFbkMsT0FBTyxFQUNMLFlBQVksRUFDWixTQUFTLEVBQ1QseUJBQXlCLEVBQ3pCLGdDQUFnQyxFQUNoQyxxQkFBcUIsRUFDckIseUJBQXlCLEVBQ3pCLHFCQUFxQixFQUNyQix5QkFBeUIsRUFDekIseUJBQXlCLEVBQ3pCLHVCQUF1QixFQUN2Qix5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