@ring-protocol/smart-order-router 0.5.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 (606) hide show
  1. package/CHANGELOG.md +255 -0
  2. package/LICENSE +674 -0
  3. package/README.md +307 -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 +186 -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 +234 -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/fewV2/ring-caching-pool-provider.d.ts +33 -0
  37. package/build/main/providers/fewV2/ring-caching-pool-provider.js +89 -0
  38. package/build/main/providers/fewV2/ring-caching-subgraph-provider.d.ts +19 -0
  39. package/build/main/providers/fewV2/ring-caching-subgraph-provider.js +24 -0
  40. package/build/main/providers/fewV2/ring-pool-provider.d.ts +63 -0
  41. package/build/main/providers/fewV2/ring-pool-provider.js +148 -0
  42. package/build/main/providers/fewV2/ring-quote-provider.d.ts +34 -0
  43. package/build/main/providers/fewV2/ring-quote-provider.js +90 -0
  44. package/build/main/providers/fewV2/ring-static-subgraph-provider.d.ts +24 -0
  45. package/build/main/providers/fewV2/ring-static-subgraph-provider.js +284 -0
  46. package/build/main/providers/fewV2/ring-subgraph-provider-with-fallback.d.ts +16 -0
  47. package/build/main/providers/fewV2/ring-subgraph-provider-with-fallback.js +23 -0
  48. package/build/main/providers/fewV2/ring-subgraph-provider.d.ts +52 -0
  49. package/build/main/providers/fewV2/ring-subgraph-provider.js +183 -0
  50. package/build/main/providers/fewV2/ring-uri-subgraph-provider.d.ts +4 -0
  51. package/build/main/providers/fewV2/ring-uri-subgraph-provider.js +8 -0
  52. package/build/main/providers/gas-price-provider.d.ts +10 -0
  53. package/build/main/providers/gas-price-provider.js +10 -0
  54. package/build/main/providers/index.d.ts +56 -0
  55. package/build/main/providers/index.js +73 -0
  56. package/build/main/providers/legacy-gas-price-provider.d.ts +7 -0
  57. package/build/main/providers/legacy-gas-price-provider.js +18 -0
  58. package/build/main/providers/multicall-provider.d.ts +83 -0
  59. package/build/main/providers/multicall-provider.js +15 -0
  60. package/build/main/providers/multicall-ringswap-provider.d.ts +35 -0
  61. package/build/main/providers/multicall-ringswap-provider.js +164 -0
  62. package/build/main/providers/multicall-uniswap-provider.d.ts +37 -0
  63. package/build/main/providers/multicall-uniswap-provider.js +164 -0
  64. package/build/main/providers/on-chain-gas-price-provider.d.ts +19 -0
  65. package/build/main/providers/on-chain-gas-price-provider.js +37 -0
  66. package/build/main/providers/on-chain-quote-provider.d.ts +260 -0
  67. package/build/main/providers/on-chain-quote-provider.js +702 -0
  68. package/build/main/providers/pool-provider.d.ts +45 -0
  69. package/build/main/providers/pool-provider.js +73 -0
  70. package/build/main/providers/portion-provider.d.ts +86 -0
  71. package/build/main/providers/portion-provider.js +118 -0
  72. package/build/main/providers/provider.d.ts +38 -0
  73. package/build/main/providers/provider.js +3 -0
  74. package/build/main/providers/simulation-provider.d.ts +46 -0
  75. package/build/main/providers/simulation-provider.js +138 -0
  76. package/build/main/providers/static-gas-price-provider.d.ts +7 -0
  77. package/build/main/providers/static-gas-price-provider.js +13 -0
  78. package/build/main/providers/subgraph-provider-with-fallback.d.ts +11 -0
  79. package/build/main/providers/subgraph-provider-with-fallback.js +25 -0
  80. package/build/main/providers/subgraph-provider.d.ts +56 -0
  81. package/build/main/providers/subgraph-provider.js +287 -0
  82. package/build/main/providers/swap-router-provider.d.ts +30 -0
  83. package/build/main/providers/swap-router-provider.js +42 -0
  84. package/build/main/providers/tenderly-simulation-provider.d.ts +63 -0
  85. package/build/main/providers/tenderly-simulation-provider.js +446 -0
  86. package/build/main/providers/token-fee-fetcher.d.ts +31 -0
  87. package/build/main/providers/token-fee-fetcher.js +114 -0
  88. package/build/main/providers/token-properties-provider.d.ts +31 -0
  89. package/build/main/providers/token-properties-provider.js +118 -0
  90. package/build/main/providers/token-provider.d.ts +167 -0
  91. package/build/main/providers/token-provider.js +414 -0
  92. package/build/main/providers/token-validator-provider.d.ts +42 -0
  93. package/build/main/providers/token-validator-provider.js +99 -0
  94. package/build/main/providers/uri-subgraph-provider.d.ts +21 -0
  95. package/build/main/providers/uri-subgraph-provider.js +65 -0
  96. package/build/main/providers/v2/caching-pool-provider.d.ts +33 -0
  97. package/build/main/providers/v2/caching-pool-provider.js +89 -0
  98. package/build/main/providers/v2/caching-subgraph-provider.d.ts +19 -0
  99. package/build/main/providers/v2/caching-subgraph-provider.js +24 -0
  100. package/build/main/providers/v2/pool-provider.d.ts +63 -0
  101. package/build/main/providers/v2/pool-provider.js +148 -0
  102. package/build/main/providers/v2/quote-provider.d.ts +34 -0
  103. package/build/main/providers/v2/quote-provider.js +90 -0
  104. package/build/main/providers/v2/static-subgraph-provider.d.ts +19 -0
  105. package/build/main/providers/v2/static-subgraph-provider.js +183 -0
  106. package/build/main/providers/v2/subgraph-provider-with-fallback.d.ts +16 -0
  107. package/build/main/providers/v2/subgraph-provider-with-fallback.js +23 -0
  108. package/build/main/providers/v2/subgraph-provider.d.ts +52 -0
  109. package/build/main/providers/v2/subgraph-provider.js +334 -0
  110. package/build/main/providers/v2/uri-subgraph-provider.d.ts +4 -0
  111. package/build/main/providers/v2/uri-subgraph-provider.js +8 -0
  112. package/build/main/providers/v3/caching-pool-provider.d.ts +32 -0
  113. package/build/main/providers/v3/caching-pool-provider.js +84 -0
  114. package/build/main/providers/v3/caching-subgraph-provider.d.ts +19 -0
  115. package/build/main/providers/v3/caching-subgraph-provider.js +24 -0
  116. package/build/main/providers/v3/gas-data-provider.d.ts +39 -0
  117. package/build/main/providers/v3/gas-data-provider.js +26 -0
  118. package/build/main/providers/v3/pool-provider.d.ts +77 -0
  119. package/build/main/providers/v3/pool-provider.js +108 -0
  120. package/build/main/providers/v3/static-subgraph-provider.d.ts +21 -0
  121. package/build/main/providers/v3/static-subgraph-provider.js +229 -0
  122. package/build/main/providers/v3/subgraph-provider-with-fallback.d.ts +12 -0
  123. package/build/main/providers/v3/subgraph-provider-with-fallback.js +19 -0
  124. package/build/main/providers/v3/subgraph-provider.d.ts +45 -0
  125. package/build/main/providers/v3/subgraph-provider.js +46 -0
  126. package/build/main/providers/v3/uri-subgraph-provider.d.ts +4 -0
  127. package/build/main/providers/v3/uri-subgraph-provider.js +8 -0
  128. package/build/main/providers/v4/caching-pool-provider.d.ts +24 -0
  129. package/build/main/providers/v4/caching-pool-provider.js +81 -0
  130. package/build/main/providers/v4/caching-subgraph-provider.d.ts +19 -0
  131. package/build/main/providers/v4/caching-subgraph-provider.js +24 -0
  132. package/build/main/providers/v4/euler-swap-hooks-subgraph-provider.d.ts +25 -0
  133. package/build/main/providers/v4/euler-swap-hooks-subgraph-provider.js +160 -0
  134. package/build/main/providers/v4/pool-provider.d.ts +58 -0
  135. package/build/main/providers/v4/pool-provider.js +115 -0
  136. package/build/main/providers/v4/static-subgraph-provider.d.ts +15 -0
  137. package/build/main/providers/v4/static-subgraph-provider.js +78 -0
  138. package/build/main/providers/v4/subgraph-provider-with-fallback.d.ts +5 -0
  139. package/build/main/providers/v4/subgraph-provider-with-fallback.js +12 -0
  140. package/build/main/providers/v4/subgraph-provider.d.ts +63 -0
  141. package/build/main/providers/v4/subgraph-provider.js +63 -0
  142. package/build/main/providers/v4/uri-subgraph-provider.d.ts +4 -0
  143. package/build/main/providers/v4/uri-subgraph-provider.js +8 -0
  144. package/build/main/routers/alpha-router/alpha-router.d.ts +483 -0
  145. package/build/main/routers/alpha-router/alpha-router.js +2267 -0
  146. package/build/main/routers/alpha-router/config.d.ts +4 -0
  147. package/build/main/routers/alpha-router/config.js +129 -0
  148. package/build/main/routers/alpha-router/entities/index.d.ts +1 -0
  149. package/build/main/routers/alpha-router/entities/index.js +18 -0
  150. package/build/main/routers/alpha-router/entities/route-with-valid-quote.d.ts +329 -0
  151. package/build/main/routers/alpha-router/entities/route-with-valid-quote.js +319 -0
  152. package/build/main/routers/alpha-router/functions/best-swap-route.d.ts +25 -0
  153. package/build/main/routers/alpha-router/functions/best-swap-route.js +597 -0
  154. package/build/main/routers/alpha-router/functions/calculate-ratio-amount-in.d.ts +3 -0
  155. package/build/main/routers/alpha-router/functions/calculate-ratio-amount-in.js +18 -0
  156. package/build/main/routers/alpha-router/functions/compute-all-routes.d.ts +16 -0
  157. package/build/main/routers/alpha-router/functions/compute-all-routes.js +158 -0
  158. package/build/main/routers/alpha-router/functions/get-candidate-pools.d.ts +192 -0
  159. package/build/main/routers/alpha-router/functions/get-candidate-pools.js +3025 -0
  160. package/build/main/routers/alpha-router/gas-models/fewV2/v2-heuristic-gas-model.d.ts +31 -0
  161. package/build/main/routers/alpha-router/gas-models/fewV2/v2-heuristic-gas-model.js +169 -0
  162. package/build/main/routers/alpha-router/gas-models/gas-costs.d.ts +12 -0
  163. package/build/main/routers/alpha-router/gas-models/gas-costs.js +200 -0
  164. package/build/main/routers/alpha-router/gas-models/gas-model.d.ts +111 -0
  165. package/build/main/routers/alpha-router/gas-models/gas-model.js +120 -0
  166. package/build/main/routers/alpha-router/gas-models/index.d.ts +5 -0
  167. package/build/main/routers/alpha-router/gas-models/index.js +22 -0
  168. package/build/main/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.d.ts +24 -0
  169. package/build/main/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.js +161 -0
  170. package/build/main/routers/alpha-router/gas-models/ring-gas-model.d.ts +111 -0
  171. package/build/main/routers/alpha-router/gas-models/ring-gas-model.js +169 -0
  172. package/build/main/routers/alpha-router/gas-models/tick-based-heuristic-gas-model.d.ts +21 -0
  173. package/build/main/routers/alpha-router/gas-models/tick-based-heuristic-gas-model.js +366 -0
  174. package/build/main/routers/alpha-router/gas-models/uniswapFewV3/v3-heuristic-gas-model.d.ts +26 -0
  175. package/build/main/routers/alpha-router/gas-models/uniswapFewV3/v3-heuristic-gas-model.js +41 -0
  176. package/build/main/routers/alpha-router/gas-models/uniswapFewV4/v4-heuristic-gas-model.d.ts +15 -0
  177. package/build/main/routers/alpha-router/gas-models/uniswapFewV4/v4-heuristic-gas-model.js +40 -0
  178. package/build/main/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.d.ts +31 -0
  179. package/build/main/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.js +169 -0
  180. package/build/main/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.d.ts +26 -0
  181. package/build/main/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.js +41 -0
  182. package/build/main/routers/alpha-router/gas-models/v4/v4-heuristic-gas-model.d.ts +15 -0
  183. package/build/main/routers/alpha-router/gas-models/v4/v4-heuristic-gas-model.js +40 -0
  184. package/build/main/routers/alpha-router/index.d.ts +4 -0
  185. package/build/main/routers/alpha-router/index.js +21 -0
  186. package/build/main/routers/alpha-router/quoters/base-quoter.d.ts +78 -0
  187. package/build/main/routers/alpha-router/quoters/base-quoter.js +77 -0
  188. package/build/main/routers/alpha-router/quoters/few-v2-quoter.d.ts +24 -0
  189. package/build/main/routers/alpha-router/quoters/few-v2-quoter.js +141 -0
  190. package/build/main/routers/alpha-router/quoters/index.d.ts +5 -0
  191. package/build/main/routers/alpha-router/quoters/index.js +22 -0
  192. package/build/main/routers/alpha-router/quoters/mixed-quoter.d.ts +34 -0
  193. package/build/main/routers/alpha-router/quoters/mixed-quoter.js +156 -0
  194. package/build/main/routers/alpha-router/quoters/model/index.d.ts +1 -0
  195. package/build/main/routers/alpha-router/quoters/model/index.js +18 -0
  196. package/build/main/routers/alpha-router/quoters/model/results/get-quotes-result.d.ts +6 -0
  197. package/build/main/routers/alpha-router/quoters/model/results/get-quotes-result.js +3 -0
  198. package/build/main/routers/alpha-router/quoters/model/results/get-routes-result.d.ts +6 -0
  199. package/build/main/routers/alpha-router/quoters/model/results/get-routes-result.js +3 -0
  200. package/build/main/routers/alpha-router/quoters/model/results/index.d.ts +2 -0
  201. package/build/main/routers/alpha-router/quoters/model/results/index.js +19 -0
  202. package/build/main/routers/alpha-router/quoters/uniswap-few-v3-quoter.d.ts +19 -0
  203. package/build/main/routers/alpha-router/quoters/uniswap-few-v3-quoter.js +118 -0
  204. package/build/main/routers/alpha-router/quoters/uniswap-few-v4-quoter.d.ts +18 -0
  205. package/build/main/routers/alpha-router/quoters/uniswap-few-v4-quoter.js +121 -0
  206. package/build/main/routers/alpha-router/quoters/v2-quoter.d.ts +24 -0
  207. package/build/main/routers/alpha-router/quoters/v2-quoter.js +141 -0
  208. package/build/main/routers/alpha-router/quoters/v3-quoter.d.ts +19 -0
  209. package/build/main/routers/alpha-router/quoters/v3-quoter.js +125 -0
  210. package/build/main/routers/alpha-router/quoters/v4-quoter.d.ts +18 -0
  211. package/build/main/routers/alpha-router/quoters/v4-quoter.js +121 -0
  212. package/build/main/routers/index.d.ts +4 -0
  213. package/build/main/routers/index.js +21 -0
  214. package/build/main/routers/legacy-router/bases.d.ts +225 -0
  215. package/build/main/routers/legacy-router/bases.js +132 -0
  216. package/build/main/routers/legacy-router/index.d.ts +1 -0
  217. package/build/main/routers/legacy-router/index.js +18 -0
  218. package/build/main/routers/legacy-router/legacy-router.d.ts +41 -0
  219. package/build/main/routers/legacy-router/legacy-router.js +291 -0
  220. package/build/main/routers/router.d.ts +195 -0
  221. package/build/main/routers/router.js +68 -0
  222. package/build/main/tsconfig.tsbuildinfo +1 -0
  223. package/build/main/types/other/commons.d.ts +16 -0
  224. package/build/main/types/other/commons.js +6 -0
  225. package/build/main/types/other/factories/Erc20__factory.d.ts +45 -0
  226. package/build/main/types/other/factories/Erc20__factory.js +240 -0
  227. package/build/main/types/other/factories/GasDataArbitrum__factory.d.ts +18 -0
  228. package/build/main/types/other/factories/GasDataArbitrum__factory.js +58 -0
  229. package/build/main/types/other/factories/IMixedRouteQuoterV1__factory.d.ts +41 -0
  230. package/build/main/types/other/factories/IMixedRouteQuoterV1__factory.js +156 -0
  231. package/build/main/types/other/factories/ITokenValidator__factory.d.ts +22 -0
  232. package/build/main/types/other/factories/ITokenValidator__factory.js +78 -0
  233. package/build/main/types/other/factories/MixedRouteQuoterV2__factory.d.ts +86 -0
  234. package/build/main/types/other/factories/MixedRouteQuoterV2__factory.js +477 -0
  235. package/build/main/types/other/factories/Permit2__factory.d.ts +87 -0
  236. package/build/main/types/other/factories/Permit2__factory.js +936 -0
  237. package/build/main/types/other/factories/StateView__factory.d.ts +32 -0
  238. package/build/main/types/other/factories/StateView__factory.js +383 -0
  239. package/build/main/types/other/factories/SwapRouter02__factory.d.ts +67 -0
  240. package/build/main/types/other/factories/SwapRouter02__factory.js +1098 -0
  241. package/build/main/types/other/factories/TokenFeeDetector__factory.d.ts +47 -0
  242. package/build/main/types/other/factories/TokenFeeDetector__factory.js +243 -0
  243. package/build/main/types/other/factories/V4Quoter__factory.d.ts +37 -0
  244. package/build/main/types/other/factories/V4Quoter__factory.js +312 -0
  245. package/build/main/types/v2/commons.d.ts +16 -0
  246. package/build/main/types/v2/commons.js +6 -0
  247. package/build/main/types/v2/factories/IUniswapV2Pair__factory.d.ts +35 -0
  248. package/build/main/types/v2/factories/IUniswapV2Pair__factory.js +671 -0
  249. package/build/main/types/v3/commons.d.ts +16 -0
  250. package/build/main/types/v3/commons.js +6 -0
  251. package/build/main/types/v3/factories/IERC20Metadata__factory.d.ts +35 -0
  252. package/build/main/types/v3/factories/IERC20Metadata__factory.js +242 -0
  253. package/build/main/types/v3/factories/IQuoterV2__factory.d.ts +41 -0
  254. package/build/main/types/v3/factories/IQuoterV2__factory.js +220 -0
  255. package/build/main/types/v3/factories/IUniswapV3PoolState__factory.d.ts +22 -0
  256. package/build/main/types/v3/factories/IUniswapV3PoolState__factory.js +266 -0
  257. package/build/main/types/v3/factories/UniswapInterfaceMulticall__factory.d.ts +61 -0
  258. package/build/main/types/v3/factories/UniswapInterfaceMulticall__factory.js +127 -0
  259. package/build/main/util/addresses.d.ts +34 -0
  260. package/build/main/util/addresses.js +140 -0
  261. package/build/main/util/amounts.d.ts +10 -0
  262. package/build/main/util/amounts.js +94 -0
  263. package/build/main/util/callData.d.ts +1 -0
  264. package/build/main/util/callData.js +6 -0
  265. package/build/main/util/chains.d.ts +75 -0
  266. package/build/main/util/chains.js +780 -0
  267. package/build/main/util/defaultBlocksToLive.d.ts +4 -0
  268. package/build/main/util/defaultBlocksToLive.js +57 -0
  269. package/build/main/util/fewAddress.d.ts +48 -0
  270. package/build/main/util/fewAddress.js +624 -0
  271. package/build/main/util/gas-factory-helpers.d.ts +38 -0
  272. package/build/main/util/gas-factory-helpers.js +596 -0
  273. package/build/main/util/hooksOptions.d.ts +5 -0
  274. package/build/main/util/hooksOptions.js +10 -0
  275. package/build/main/util/index.d.ts +10 -0
  276. package/build/main/util/index.js +27 -0
  277. package/build/main/util/intent.d.ts +6 -0
  278. package/build/main/util/intent.js +13 -0
  279. package/build/main/util/l2FeeChains.d.ts +2 -0
  280. package/build/main/util/l2FeeChains.js +18 -0
  281. package/build/main/util/log.d.ts +3 -0
  282. package/build/main/util/log.js +97 -0
  283. package/build/main/util/methodParameters.d.ts +5 -0
  284. package/build/main/util/methodParameters.js +176 -0
  285. package/build/main/util/metric.d.ts +48 -0
  286. package/build/main/util/metric.js +59 -0
  287. package/build/main/util/mixedRouteFilterOutV4Pools.d.ts +3 -0
  288. package/build/main/util/mixedRouteFilterOutV4Pools.js +17 -0
  289. package/build/main/util/onchainQuoteProviderConfigs.d.ts +42 -0
  290. package/build/main/util/onchainQuoteProviderConfigs.js +72 -0
  291. package/build/main/util/pool.d.ts +5 -0
  292. package/build/main/util/pool.js +46 -0
  293. package/build/main/util/protocols.d.ts +2 -0
  294. package/build/main/util/protocols.js +22 -0
  295. package/build/main/util/routes.d.ts +11 -0
  296. package/build/main/util/routes.js +159 -0
  297. package/build/main/util/serializeRouteIds.d.ts +2 -0
  298. package/build/main/util/serializeRouteIds.js +12 -0
  299. package/build/main/util/simple-perf-tracker.d.ts +27 -0
  300. package/build/main/util/simple-perf-tracker.js +171 -0
  301. package/build/main/util/tenderlySimulationErrorBreakDown.d.ts +3 -0
  302. package/build/main/util/tenderlySimulationErrorBreakDown.js +33 -0
  303. package/build/main/util/unsupported-tokens.d.ts +37 -0
  304. package/build/main/util/unsupported-tokens.js +1119 -0
  305. package/build/module/index.d.ts +3 -0
  306. package/build/module/index.js +4 -0
  307. package/build/module/providers/cache-node.d.ts +10 -0
  308. package/build/module/providers/cache-node.js +29 -0
  309. package/build/module/providers/cache.d.ts +14 -0
  310. package/build/module/providers/cache.js +2 -0
  311. package/build/module/providers/caching/route/index.d.ts +2 -0
  312. package/build/module/providers/caching/route/index.js +3 -0
  313. package/build/module/providers/caching/route/model/cache-mode.d.ts +16 -0
  314. package/build/module/providers/caching/route/model/cache-mode.js +18 -0
  315. package/build/module/providers/caching/route/model/cached-route.d.ts +29 -0
  316. package/build/module/providers/caching/route/model/cached-route.js +73 -0
  317. package/build/module/providers/caching/route/model/cached-routes.d.ts +67 -0
  318. package/build/module/providers/caching/route/model/cached-routes.js +74 -0
  319. package/build/module/providers/caching/route/model/index.d.ts +3 -0
  320. package/build/module/providers/caching/route/model/index.js +4 -0
  321. package/build/module/providers/caching/route/route-caching-provider.d.ts +111 -0
  322. package/build/module/providers/caching/route/route-caching-provider.js +82 -0
  323. package/build/module/providers/caching-gas-provider.d.ts +23 -0
  324. package/build/module/providers/caching-gas-provider.js +37 -0
  325. package/build/module/providers/caching-subgraph-provider.d.ts +33 -0
  326. package/build/module/providers/caching-subgraph-provider.js +182 -0
  327. package/build/module/providers/caching-token-list-provider.d.ts +52 -0
  328. package/build/module/providers/caching-token-list-provider.js +140 -0
  329. package/build/module/providers/caching-token-provider.d.ts +24 -0
  330. package/build/module/providers/caching-token-provider.js +227 -0
  331. package/build/module/providers/eip-1559-gas-price-provider.d.ts +31 -0
  332. package/build/module/providers/eip-1559-gas-price-provider.js +64 -0
  333. package/build/module/providers/eth-estimate-gas-provider.d.ts +21 -0
  334. package/build/module/providers/eth-estimate-gas-provider.js +99 -0
  335. package/build/module/providers/eth-gas-station-info-gas-price-provider.d.ts +19 -0
  336. package/build/module/providers/eth-gas-station-info-gas-price-provider.js +29 -0
  337. package/build/module/providers/fewV2/ring-caching-pool-provider.d.ts +33 -0
  338. package/build/module/providers/fewV2/ring-caching-pool-provider.js +85 -0
  339. package/build/module/providers/fewV2/ring-caching-subgraph-provider.d.ts +19 -0
  340. package/build/module/providers/fewV2/ring-caching-subgraph-provider.js +20 -0
  341. package/build/module/providers/fewV2/ring-pool-provider.d.ts +63 -0
  342. package/build/module/providers/fewV2/ring-pool-provider.js +141 -0
  343. package/build/module/providers/fewV2/ring-quote-provider.d.ts +34 -0
  344. package/build/module/providers/fewV2/ring-quote-provider.js +86 -0
  345. package/build/module/providers/fewV2/ring-static-subgraph-provider.d.ts +24 -0
  346. package/build/module/providers/fewV2/ring-static-subgraph-provider.js +319 -0
  347. package/build/module/providers/fewV2/ring-subgraph-provider-with-fallback.d.ts +16 -0
  348. package/build/module/providers/fewV2/ring-subgraph-provider-with-fallback.js +19 -0
  349. package/build/module/providers/fewV2/ring-subgraph-provider.d.ts +52 -0
  350. package/build/module/providers/fewV2/ring-subgraph-provider.js +176 -0
  351. package/build/module/providers/fewV2/ring-uri-subgraph-provider.d.ts +4 -0
  352. package/build/module/providers/fewV2/ring-uri-subgraph-provider.js +4 -0
  353. package/build/module/providers/gas-price-provider.d.ts +10 -0
  354. package/build/module/providers/gas-price-provider.js +6 -0
  355. package/build/module/providers/index.d.ts +56 -0
  356. package/build/module/providers/index.js +57 -0
  357. package/build/module/providers/legacy-gas-price-provider.d.ts +7 -0
  358. package/build/module/providers/legacy-gas-price-provider.js +14 -0
  359. package/build/module/providers/multicall-provider.d.ts +83 -0
  360. package/build/module/providers/multicall-provider.js +11 -0
  361. package/build/module/providers/multicall-ringswap-provider.d.ts +35 -0
  362. package/build/module/providers/multicall-ringswap-provider.js +157 -0
  363. package/build/module/providers/multicall-uniswap-provider.d.ts +37 -0
  364. package/build/module/providers/multicall-uniswap-provider.js +157 -0
  365. package/build/module/providers/on-chain-gas-price-provider.d.ts +19 -0
  366. package/build/module/providers/on-chain-gas-price-provider.js +33 -0
  367. package/build/module/providers/on-chain-quote-provider.d.ts +260 -0
  368. package/build/module/providers/on-chain-quote-provider.js +696 -0
  369. package/build/module/providers/pool-provider.d.ts +45 -0
  370. package/build/module/providers/pool-provider.js +66 -0
  371. package/build/module/providers/portion-provider.d.ts +86 -0
  372. package/build/module/providers/portion-provider.js +114 -0
  373. package/build/module/providers/provider.d.ts +38 -0
  374. package/build/module/providers/provider.js +2 -0
  375. package/build/module/providers/simulation-provider.d.ts +46 -0
  376. package/build/module/providers/simulation-provider.js +140 -0
  377. package/build/module/providers/static-gas-price-provider.d.ts +7 -0
  378. package/build/module/providers/static-gas-price-provider.js +9 -0
  379. package/build/module/providers/subgraph-provider-with-fallback.d.ts +11 -0
  380. package/build/module/providers/subgraph-provider-with-fallback.js +21 -0
  381. package/build/module/providers/subgraph-provider.d.ts +56 -0
  382. package/build/module/providers/subgraph-provider.js +284 -0
  383. package/build/module/providers/swap-router-provider.d.ts +30 -0
  384. package/build/module/providers/swap-router-provider.js +38 -0
  385. package/build/module/providers/tenderly-simulation-provider.d.ts +63 -0
  386. package/build/module/providers/tenderly-simulation-provider.js +444 -0
  387. package/build/module/providers/token-fee-fetcher.d.ts +31 -0
  388. package/build/module/providers/token-fee-fetcher.js +110 -0
  389. package/build/module/providers/token-properties-provider.d.ts +31 -0
  390. package/build/module/providers/token-properties-provider.js +114 -0
  391. package/build/module/providers/token-provider.d.ts +167 -0
  392. package/build/module/providers/token-provider.js +401 -0
  393. package/build/module/providers/token-validator-provider.d.ts +42 -0
  394. package/build/module/providers/token-validator-provider.js +92 -0
  395. package/build/module/providers/uri-subgraph-provider.d.ts +21 -0
  396. package/build/module/providers/uri-subgraph-provider.js +58 -0
  397. package/build/module/providers/v2/caching-pool-provider.d.ts +33 -0
  398. package/build/module/providers/v2/caching-pool-provider.js +85 -0
  399. package/build/module/providers/v2/caching-subgraph-provider.d.ts +19 -0
  400. package/build/module/providers/v2/caching-subgraph-provider.js +20 -0
  401. package/build/module/providers/v2/pool-provider.d.ts +63 -0
  402. package/build/module/providers/v2/pool-provider.js +141 -0
  403. package/build/module/providers/v2/quote-provider.d.ts +34 -0
  404. package/build/module/providers/v2/quote-provider.js +86 -0
  405. package/build/module/providers/v2/static-subgraph-provider.d.ts +19 -0
  406. package/build/module/providers/v2/static-subgraph-provider.js +178 -0
  407. package/build/module/providers/v2/subgraph-provider-with-fallback.d.ts +16 -0
  408. package/build/module/providers/v2/subgraph-provider-with-fallback.js +19 -0
  409. package/build/module/providers/v2/subgraph-provider.d.ts +52 -0
  410. package/build/module/providers/v2/subgraph-provider.js +331 -0
  411. package/build/module/providers/v2/uri-subgraph-provider.d.ts +4 -0
  412. package/build/module/providers/v2/uri-subgraph-provider.js +4 -0
  413. package/build/module/providers/v3/caching-pool-provider.d.ts +32 -0
  414. package/build/module/providers/v3/caching-pool-provider.js +77 -0
  415. package/build/module/providers/v3/caching-subgraph-provider.d.ts +19 -0
  416. package/build/module/providers/v3/caching-subgraph-provider.js +20 -0
  417. package/build/module/providers/v3/gas-data-provider.d.ts +39 -0
  418. package/build/module/providers/v3/gas-data-provider.js +22 -0
  419. package/build/module/providers/v3/pool-provider.d.ts +77 -0
  420. package/build/module/providers/v3/pool-provider.js +101 -0
  421. package/build/module/providers/v3/static-subgraph-provider.d.ts +21 -0
  422. package/build/module/providers/v3/static-subgraph-provider.js +224 -0
  423. package/build/module/providers/v3/subgraph-provider-with-fallback.d.ts +12 -0
  424. package/build/module/providers/v3/subgraph-provider-with-fallback.js +15 -0
  425. package/build/module/providers/v3/subgraph-provider.d.ts +45 -0
  426. package/build/module/providers/v3/subgraph-provider.js +42 -0
  427. package/build/module/providers/v3/uri-subgraph-provider.d.ts +4 -0
  428. package/build/module/providers/v3/uri-subgraph-provider.js +4 -0
  429. package/build/module/providers/v4/caching-pool-provider.d.ts +24 -0
  430. package/build/module/providers/v4/caching-pool-provider.js +74 -0
  431. package/build/module/providers/v4/caching-subgraph-provider.d.ts +19 -0
  432. package/build/module/providers/v4/caching-subgraph-provider.js +20 -0
  433. package/build/module/providers/v4/euler-swap-hooks-subgraph-provider.d.ts +25 -0
  434. package/build/module/providers/v4/euler-swap-hooks-subgraph-provider.js +153 -0
  435. package/build/module/providers/v4/pool-provider.d.ts +58 -0
  436. package/build/module/providers/v4/pool-provider.js +106 -0
  437. package/build/module/providers/v4/static-subgraph-provider.d.ts +15 -0
  438. package/build/module/providers/v4/static-subgraph-provider.js +71 -0
  439. package/build/module/providers/v4/subgraph-provider-with-fallback.d.ts +5 -0
  440. package/build/module/providers/v4/subgraph-provider-with-fallback.js +8 -0
  441. package/build/module/providers/v4/subgraph-provider.d.ts +63 -0
  442. package/build/module/providers/v4/subgraph-provider.js +59 -0
  443. package/build/module/providers/v4/uri-subgraph-provider.d.ts +4 -0
  444. package/build/module/providers/v4/uri-subgraph-provider.js +4 -0
  445. package/build/module/routers/alpha-router/alpha-router.d.ts +483 -0
  446. package/build/module/routers/alpha-router/alpha-router.js +2280 -0
  447. package/build/module/routers/alpha-router/config.d.ts +4 -0
  448. package/build/module/routers/alpha-router/config.js +125 -0
  449. package/build/module/routers/alpha-router/entities/index.d.ts +1 -0
  450. package/build/module/routers/alpha-router/entities/index.js +2 -0
  451. package/build/module/routers/alpha-router/entities/route-with-valid-quote.d.ts +329 -0
  452. package/build/module/routers/alpha-router/entities/route-with-valid-quote.js +306 -0
  453. package/build/module/routers/alpha-router/functions/best-swap-route.d.ts +25 -0
  454. package/build/module/routers/alpha-router/functions/best-swap-route.js +586 -0
  455. package/build/module/routers/alpha-router/functions/calculate-ratio-amount-in.d.ts +3 -0
  456. package/build/module/routers/alpha-router/functions/calculate-ratio-amount-in.js +14 -0
  457. package/build/module/routers/alpha-router/functions/compute-all-routes.d.ts +16 -0
  458. package/build/module/routers/alpha-router/functions/compute-all-routes.js +147 -0
  459. package/build/module/routers/alpha-router/functions/get-candidate-pools.d.ts +192 -0
  460. package/build/module/routers/alpha-router/functions/get-candidate-pools.js +3010 -0
  461. package/build/module/routers/alpha-router/gas-models/fewV2/v2-heuristic-gas-model.d.ts +31 -0
  462. package/build/module/routers/alpha-router/gas-models/fewV2/v2-heuristic-gas-model.js +162 -0
  463. package/build/module/routers/alpha-router/gas-models/gas-costs.d.ts +12 -0
  464. package/build/module/routers/alpha-router/gas-models/gas-costs.js +189 -0
  465. package/build/module/routers/alpha-router/gas-models/gas-model.d.ts +111 -0
  466. package/build/module/routers/alpha-router/gas-models/gas-model.js +114 -0
  467. package/build/module/routers/alpha-router/gas-models/index.d.ts +5 -0
  468. package/build/module/routers/alpha-router/gas-models/index.js +6 -0
  469. package/build/module/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.d.ts +24 -0
  470. package/build/module/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.js +154 -0
  471. package/build/module/routers/alpha-router/gas-models/ring-gas-model.d.ts +111 -0
  472. package/build/module/routers/alpha-router/gas-models/ring-gas-model.js +163 -0
  473. package/build/module/routers/alpha-router/gas-models/tick-based-heuristic-gas-model.d.ts +21 -0
  474. package/build/module/routers/alpha-router/gas-models/tick-based-heuristic-gas-model.js +362 -0
  475. package/build/module/routers/alpha-router/gas-models/uniswapFewV3/v3-heuristic-gas-model.d.ts +26 -0
  476. package/build/module/routers/alpha-router/gas-models/uniswapFewV3/v3-heuristic-gas-model.js +37 -0
  477. package/build/module/routers/alpha-router/gas-models/uniswapFewV4/v4-heuristic-gas-model.d.ts +15 -0
  478. package/build/module/routers/alpha-router/gas-models/uniswapFewV4/v4-heuristic-gas-model.js +36 -0
  479. package/build/module/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.d.ts +31 -0
  480. package/build/module/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.js +162 -0
  481. package/build/module/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.d.ts +26 -0
  482. package/build/module/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.js +37 -0
  483. package/build/module/routers/alpha-router/gas-models/v4/v4-heuristic-gas-model.d.ts +15 -0
  484. package/build/module/routers/alpha-router/gas-models/v4/v4-heuristic-gas-model.js +36 -0
  485. package/build/module/routers/alpha-router/index.d.ts +4 -0
  486. package/build/module/routers/alpha-router/index.js +5 -0
  487. package/build/module/routers/alpha-router/quoters/base-quoter.d.ts +78 -0
  488. package/build/module/routers/alpha-router/quoters/base-quoter.js +70 -0
  489. package/build/module/routers/alpha-router/quoters/few-v2-quoter.d.ts +24 -0
  490. package/build/module/routers/alpha-router/quoters/few-v2-quoter.js +138 -0
  491. package/build/module/routers/alpha-router/quoters/index.d.ts +5 -0
  492. package/build/module/routers/alpha-router/quoters/index.js +6 -0
  493. package/build/module/routers/alpha-router/quoters/mixed-quoter.d.ts +34 -0
  494. package/build/module/routers/alpha-router/quoters/mixed-quoter.js +149 -0
  495. package/build/module/routers/alpha-router/quoters/model/index.d.ts +1 -0
  496. package/build/module/routers/alpha-router/quoters/model/index.js +2 -0
  497. package/build/module/routers/alpha-router/quoters/model/results/get-quotes-result.d.ts +6 -0
  498. package/build/module/routers/alpha-router/quoters/model/results/get-quotes-result.js +2 -0
  499. package/build/module/routers/alpha-router/quoters/model/results/get-routes-result.d.ts +6 -0
  500. package/build/module/routers/alpha-router/quoters/model/results/get-routes-result.js +2 -0
  501. package/build/module/routers/alpha-router/quoters/model/results/index.d.ts +2 -0
  502. package/build/module/routers/alpha-router/quoters/model/results/index.js +3 -0
  503. package/build/module/routers/alpha-router/quoters/uniswap-few-v3-quoter.d.ts +19 -0
  504. package/build/module/routers/alpha-router/quoters/uniswap-few-v3-quoter.js +111 -0
  505. package/build/module/routers/alpha-router/quoters/uniswap-few-v4-quoter.d.ts +18 -0
  506. package/build/module/routers/alpha-router/quoters/uniswap-few-v4-quoter.js +114 -0
  507. package/build/module/routers/alpha-router/quoters/v2-quoter.d.ts +24 -0
  508. package/build/module/routers/alpha-router/quoters/v2-quoter.js +138 -0
  509. package/build/module/routers/alpha-router/quoters/v3-quoter.d.ts +19 -0
  510. package/build/module/routers/alpha-router/quoters/v3-quoter.js +118 -0
  511. package/build/module/routers/alpha-router/quoters/v4-quoter.d.ts +18 -0
  512. package/build/module/routers/alpha-router/quoters/v4-quoter.js +114 -0
  513. package/build/module/routers/index.d.ts +4 -0
  514. package/build/module/routers/index.js +5 -0
  515. package/build/module/routers/legacy-router/bases.d.ts +225 -0
  516. package/build/module/routers/legacy-router/bases.js +138 -0
  517. package/build/module/routers/legacy-router/index.d.ts +1 -0
  518. package/build/module/routers/legacy-router/index.js +2 -0
  519. package/build/module/routers/legacy-router/legacy-router.d.ts +41 -0
  520. package/build/module/routers/legacy-router/legacy-router.js +292 -0
  521. package/build/module/routers/router.d.ts +195 -0
  522. package/build/module/routers/router.js +58 -0
  523. package/build/module/tsconfig.module.tsbuildinfo +1 -0
  524. package/build/module/types/other/commons.d.ts +16 -0
  525. package/build/module/types/other/commons.js +5 -0
  526. package/build/module/types/other/factories/Erc20__factory.d.ts +45 -0
  527. package/build/module/types/other/factories/Erc20__factory.js +236 -0
  528. package/build/module/types/other/factories/GasDataArbitrum__factory.d.ts +18 -0
  529. package/build/module/types/other/factories/GasDataArbitrum__factory.js +54 -0
  530. package/build/module/types/other/factories/IMixedRouteQuoterV1__factory.d.ts +41 -0
  531. package/build/module/types/other/factories/IMixedRouteQuoterV1__factory.js +152 -0
  532. package/build/module/types/other/factories/ITokenValidator__factory.d.ts +22 -0
  533. package/build/module/types/other/factories/ITokenValidator__factory.js +74 -0
  534. package/build/module/types/other/factories/MixedRouteQuoterV2__factory.d.ts +86 -0
  535. package/build/module/types/other/factories/MixedRouteQuoterV2__factory.js +473 -0
  536. package/build/module/types/other/factories/Permit2__factory.d.ts +87 -0
  537. package/build/module/types/other/factories/Permit2__factory.js +932 -0
  538. package/build/module/types/other/factories/StateView__factory.d.ts +32 -0
  539. package/build/module/types/other/factories/StateView__factory.js +379 -0
  540. package/build/module/types/other/factories/SwapRouter02__factory.d.ts +67 -0
  541. package/build/module/types/other/factories/SwapRouter02__factory.js +1094 -0
  542. package/build/module/types/other/factories/TokenFeeDetector__factory.d.ts +47 -0
  543. package/build/module/types/other/factories/TokenFeeDetector__factory.js +239 -0
  544. package/build/module/types/other/factories/V4Quoter__factory.d.ts +37 -0
  545. package/build/module/types/other/factories/V4Quoter__factory.js +308 -0
  546. package/build/module/types/v2/commons.d.ts +16 -0
  547. package/build/module/types/v2/commons.js +5 -0
  548. package/build/module/types/v2/factories/IUniswapV2Pair__factory.d.ts +35 -0
  549. package/build/module/types/v2/factories/IUniswapV2Pair__factory.js +667 -0
  550. package/build/module/types/v3/commons.d.ts +16 -0
  551. package/build/module/types/v3/commons.js +5 -0
  552. package/build/module/types/v3/factories/IERC20Metadata__factory.d.ts +35 -0
  553. package/build/module/types/v3/factories/IERC20Metadata__factory.js +238 -0
  554. package/build/module/types/v3/factories/IQuoterV2__factory.d.ts +41 -0
  555. package/build/module/types/v3/factories/IQuoterV2__factory.js +216 -0
  556. package/build/module/types/v3/factories/IUniswapV3PoolState__factory.d.ts +22 -0
  557. package/build/module/types/v3/factories/IUniswapV3PoolState__factory.js +262 -0
  558. package/build/module/types/v3/factories/UniswapInterfaceMulticall__factory.d.ts +61 -0
  559. package/build/module/types/v3/factories/UniswapInterfaceMulticall__factory.js +123 -0
  560. package/build/module/util/addresses.d.ts +34 -0
  561. package/build/module/util/addresses.js +280 -0
  562. package/build/module/util/amounts.d.ts +10 -0
  563. package/build/module/util/amounts.js +82 -0
  564. package/build/module/util/callData.d.ts +1 -0
  565. package/build/module/util/callData.js +3 -0
  566. package/build/module/util/chains.d.ts +75 -0
  567. package/build/module/util/chains.js +772 -0
  568. package/build/module/util/defaultBlocksToLive.d.ts +4 -0
  569. package/build/module/util/defaultBlocksToLive.js +54 -0
  570. package/build/module/util/fewAddress.d.ts +48 -0
  571. package/build/module/util/fewAddress.js +627 -0
  572. package/build/module/util/gas-factory-helpers.d.ts +38 -0
  573. package/build/module/util/gas-factory-helpers.js +575 -0
  574. package/build/module/util/hooksOptions.d.ts +5 -0
  575. package/build/module/util/hooksOptions.js +7 -0
  576. package/build/module/util/index.d.ts +10 -0
  577. package/build/module/util/index.js +11 -0
  578. package/build/module/util/intent.d.ts +6 -0
  579. package/build/module/util/intent.js +10 -0
  580. package/build/module/util/l2FeeChains.d.ts +2 -0
  581. package/build/module/util/l2FeeChains.js +15 -0
  582. package/build/module/util/log.d.ts +3 -0
  583. package/build/module/util/log.js +93 -0
  584. package/build/module/util/methodParameters.d.ts +5 -0
  585. package/build/module/util/methodParameters.js +176 -0
  586. package/build/module/util/metric.d.ts +48 -0
  587. package/build/module/util/metric.js +53 -0
  588. package/build/module/util/mixedRouteFilterOutV4Pools.d.ts +3 -0
  589. package/build/module/util/mixedRouteFilterOutV4Pools.js +12 -0
  590. package/build/module/util/onchainQuoteProviderConfigs.d.ts +42 -0
  591. package/build/module/util/onchainQuoteProviderConfigs.js +74 -0
  592. package/build/module/util/pool.d.ts +5 -0
  593. package/build/module/util/pool.js +43 -0
  594. package/build/module/util/protocols.d.ts +2 -0
  595. package/build/module/util/protocols.js +18 -0
  596. package/build/module/util/routes.d.ts +11 -0
  597. package/build/module/util/routes.js +147 -0
  598. package/build/module/util/serializeRouteIds.d.ts +2 -0
  599. package/build/module/util/serializeRouteIds.js +7 -0
  600. package/build/module/util/simple-perf-tracker.d.ts +27 -0
  601. package/build/module/util/simple-perf-tracker.js +161 -0
  602. package/build/module/util/tenderlySimulationErrorBreakDown.d.ts +3 -0
  603. package/build/module/util/tenderlySimulationErrorBreakDown.js +29 -0
  604. package/build/module/util/unsupported-tokens.d.ts +37 -0
  605. package/build/module/util/unsupported-tokens.js +1116 -0
  606. package/package.json +127 -0
@@ -0,0 +1,2267 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AlphaRouter = exports.LowerCaseStringArray = exports.MapWithLowerCaseKey = void 0;
7
+ const bignumber_1 = require("@ethersproject/bignumber");
8
+ const providers_1 = require("@ethersproject/providers");
9
+ const default_token_list_1 = __importDefault(require("@uniswap/default-token-list"));
10
+ const router_sdk_1 = require("@ring-protocol/router-sdk");
11
+ const sdk_core_1 = require("@ring-protocol/sdk-core");
12
+ const v3_sdk_1 = require("@ring-protocol/v3-sdk");
13
+ const async_retry_1 = __importDefault(require("async-retry"));
14
+ const jsbi_1 = __importDefault(require("jsbi"));
15
+ const lodash_1 = __importDefault(require("lodash"));
16
+ const node_cache_1 = __importDefault(require("node-cache"));
17
+ const providers_2 = require("../../providers");
18
+ const caching_token_list_provider_1 = require("../../providers/caching-token-list-provider");
19
+ const portion_provider_1 = require("../../providers/portion-provider");
20
+ const token_fee_fetcher_1 = require("../../providers/token-fee-fetcher");
21
+ const token_provider_1 = require("../../providers/token-provider");
22
+ const token_validator_provider_1 = require("../../providers/token-validator-provider");
23
+ const pool_provider_1 = require("../../providers/v2/pool-provider");
24
+ const gas_data_provider_1 = require("../../providers/v3/gas-data-provider");
25
+ const pool_provider_2 = require("../../providers/v3/pool-provider");
26
+ const caching_pool_provider_1 = require("../../providers/v4/caching-pool-provider");
27
+ const pool_provider_3 = require("../../providers/v4/pool-provider");
28
+ const Erc20__factory_1 = require("../../types/other/factories/Erc20__factory");
29
+ const util_1 = require("../../util");
30
+ const amounts_1 = require("../../util/amounts");
31
+ const chains_1 = require("../../util/chains");
32
+ const gas_factory_helpers_1 = require("../../util/gas-factory-helpers");
33
+ const log_1 = require("../../util/log");
34
+ const methodParameters_1 = require("../../util/methodParameters");
35
+ const metric_1 = require("../../util/metric");
36
+ const onchainQuoteProviderConfigs_1 = require("../../util/onchainQuoteProviderConfigs");
37
+ const unsupported_tokens_1 = require("../../util/unsupported-tokens");
38
+ const router_1 = require("../router");
39
+ const universal_router_sdk_1 = require("@ring-protocol/universal-router-sdk");
40
+ const defaultBlocksToLive_1 = require("../../util/defaultBlocksToLive");
41
+ const intent_1 = require("../../util/intent");
42
+ const serializeRouteIds_1 = require("../../util/serializeRouteIds");
43
+ const config_1 = require("./config");
44
+ const best_swap_route_1 = require("./functions/best-swap-route");
45
+ const calculate_ratio_amount_in_1 = require("./functions/calculate-ratio-amount-in");
46
+ const get_candidate_pools_1 = require("./functions/get-candidate-pools");
47
+ const gas_costs_1 = require("./gas-models/gas-costs");
48
+ const mixed_route_heuristic_gas_model_1 = require("./gas-models/mixedRoute/mixed-route-heuristic-gas-model");
49
+ const v2_heuristic_gas_model_1 = require("./gas-models/v2/v2-heuristic-gas-model");
50
+ const v3_heuristic_gas_model_1 = require("./gas-models/v3/v3-heuristic-gas-model");
51
+ const v3_heuristic_gas_model_2 = require("./gas-models/uniswapFewV3/v3-heuristic-gas-model");
52
+ const v4_heuristic_gas_model_1 = require("./gas-models/v4/v4-heuristic-gas-model");
53
+ const v4_heuristic_gas_model_2 = require("./gas-models/uniswapFewV4/v4-heuristic-gas-model");
54
+ const quoters_1 = require("./quoters");
55
+ const v4_quoter_1 = require("./quoters/v4-quoter");
56
+ const uniswap_few_v4_quoter_1 = require("./quoters/uniswap-few-v4-quoter");
57
+ const uniswap_few_v3_quoter_1 = require("./quoters/uniswap-few-v3-quoter");
58
+ const few_v2_quoter_1 = require("./quoters/few-v2-quoter");
59
+ const v2_heuristic_gas_model_2 = require("./gas-models/fewV2/v2-heuristic-gas-model");
60
+ const few_v2_sdk_1 = require("@ring-protocol/few-v2-sdk");
61
+ const fewAddress_1 = require("../../util/fewAddress");
62
+ const simple_perf_tracker_1 = require("../../util/simple-perf-tracker");
63
+ class MapWithLowerCaseKey extends Map {
64
+ set(key, value) {
65
+ return super.set(key.toLowerCase(), value);
66
+ }
67
+ }
68
+ exports.MapWithLowerCaseKey = MapWithLowerCaseKey;
69
+ class LowerCaseStringArray extends Array {
70
+ constructor(...items) {
71
+ // Convert all items to lowercase before calling the parent constructor
72
+ super(...items.map((item) => item.toLowerCase()));
73
+ }
74
+ }
75
+ exports.LowerCaseStringArray = LowerCaseStringArray;
76
+ class AlphaRouter {
77
+ constructor({ chainId, provider, multicall2Provider, ringFewV2Multicall2Provider, v4SubgraphProvider, v4PoolProvider, v3PoolProvider, onChainQuoteProvider, v2PoolProvider, ringFewV2PoolProvider, v2QuoteProvider, ringFewV2QuoteProvider, v2SubgraphProvider, ringFewV2SubgraphProvider, tokenProvider, blockedTokenListProvider, v3SubgraphProvider, gasPriceProvider, v4GasModelFactory, uniswapFewV4GasModelFactory, v3GasModelFactory, uniswapFewV3GasModelFactory, v2GasModelFactory, ringFewV2GasModelFactory, mixedRouteGasModelFactory, swapRouterProvider, tokenValidatorProvider, arbitrumGasDataProvider, simulator, routeCachingProvider, tokenPropertiesProvider, portionProvider, v2Supported, ringFewV2Supported, v4Supported, mixedSupported, v4PoolParams, cachedRoutesCacheInvalidationFixRolloutPercentage, }) {
78
+ (0, simple_perf_tracker_1.clearPerfData)();
79
+ this.chainId = chainId;
80
+ this.provider = provider;
81
+ this.multicall2Provider =
82
+ multicall2Provider !== null && multicall2Provider !== void 0 ? multicall2Provider : new providers_2.UniswapMulticallProvider(chainId, provider, 375000);
83
+ this.ringFewV2Multicall2Provider =
84
+ ringFewV2Multicall2Provider !== null && ringFewV2Multicall2Provider !== void 0 ? ringFewV2Multicall2Provider : new providers_2.RingswapMulticallProvider(chainId, provider, 375000);
85
+ this.v4PoolProvider =
86
+ v4PoolProvider !== null && v4PoolProvider !== void 0 ? v4PoolProvider : new caching_pool_provider_1.CachingV4PoolProvider(this.chainId, new pool_provider_3.V4PoolProvider((0, chains_1.ID_TO_CHAIN_ID)(chainId), this.multicall2Provider), new providers_2.NodeJSCache(new node_cache_1.default({ stdTTL: 360, useClones: false })));
87
+ this.v3PoolProvider =
88
+ v3PoolProvider !== null && v3PoolProvider !== void 0 ? v3PoolProvider : new providers_2.CachingV3PoolProvider(this.chainId, new pool_provider_2.V3PoolProvider((0, chains_1.ID_TO_CHAIN_ID)(chainId), this.multicall2Provider), new providers_2.NodeJSCache(new node_cache_1.default({ stdTTL: 360, useClones: false })));
89
+ this.simulator = simulator;
90
+ this.routeCachingProvider = routeCachingProvider;
91
+ if (onChainQuoteProvider) {
92
+ this.onChainQuoteProvider = onChainQuoteProvider;
93
+ }
94
+ else {
95
+ switch (chainId) {
96
+ case sdk_core_1.ChainId.OPTIMISM:
97
+ case sdk_core_1.ChainId.OPTIMISM_GOERLI:
98
+ case sdk_core_1.ChainId.OPTIMISM_SEPOLIA:
99
+ this.onChainQuoteProvider = new providers_2.OnChainQuoteProvider(chainId, provider, this.multicall2Provider, this.ringFewV2Multicall2Provider, {
100
+ retries: 2,
101
+ minTimeout: 100,
102
+ maxTimeout: 1000,
103
+ }, (_) => {
104
+ return {
105
+ multicallChunk: 110,
106
+ gasLimitPerCall: 1200000,
107
+ quoteMinSuccessRate: 0.1,
108
+ };
109
+ }, (_) => {
110
+ return {
111
+ gasLimitOverride: 3000000,
112
+ multicallChunk: 45,
113
+ };
114
+ }, (_) => {
115
+ return {
116
+ gasLimitOverride: 3000000,
117
+ multicallChunk: 45,
118
+ };
119
+ }, (_) => {
120
+ return {
121
+ baseBlockOffset: -10,
122
+ rollback: {
123
+ enabled: true,
124
+ attemptsBeforeRollback: 1,
125
+ rollbackBlockOffset: -10,
126
+ },
127
+ };
128
+ });
129
+ break;
130
+ case sdk_core_1.ChainId.BASE:
131
+ case sdk_core_1.ChainId.BLAST:
132
+ case sdk_core_1.ChainId.ZORA:
133
+ case sdk_core_1.ChainId.WORLDCHAIN:
134
+ case sdk_core_1.ChainId.UNICHAIN_SEPOLIA:
135
+ case sdk_core_1.ChainId.MONAD_TESTNET:
136
+ case sdk_core_1.ChainId.BASE_SEPOLIA:
137
+ case sdk_core_1.ChainId.UNICHAIN:
138
+ case sdk_core_1.ChainId.BASE_GOERLI:
139
+ case sdk_core_1.ChainId.SONEIUM:
140
+ this.onChainQuoteProvider = new providers_2.OnChainQuoteProvider(chainId, provider, this.multicall2Provider, this.ringFewV2Multicall2Provider, {
141
+ retries: 2,
142
+ minTimeout: 100,
143
+ maxTimeout: 1000,
144
+ }, (_) => {
145
+ return {
146
+ multicallChunk: 80,
147
+ gasLimitPerCall: 1200000,
148
+ quoteMinSuccessRate: 0.1,
149
+ };
150
+ }, (_) => {
151
+ return {
152
+ gasLimitOverride: 3000000,
153
+ multicallChunk: 45,
154
+ };
155
+ }, (_) => {
156
+ return {
157
+ gasLimitOverride: 3000000,
158
+ multicallChunk: 45,
159
+ };
160
+ }, (_) => {
161
+ return {
162
+ baseBlockOffset: -10,
163
+ rollback: {
164
+ enabled: true,
165
+ attemptsBeforeRollback: 1,
166
+ rollbackBlockOffset: -10,
167
+ },
168
+ };
169
+ });
170
+ break;
171
+ case sdk_core_1.ChainId.ZKSYNC:
172
+ this.onChainQuoteProvider = new providers_2.OnChainQuoteProvider(chainId, provider, this.multicall2Provider, this.ringFewV2Multicall2Provider, {
173
+ retries: 2,
174
+ minTimeout: 100,
175
+ maxTimeout: 1000,
176
+ }, (_) => {
177
+ return {
178
+ multicallChunk: 27,
179
+ gasLimitPerCall: 3000000,
180
+ quoteMinSuccessRate: 0.1,
181
+ };
182
+ }, (_) => {
183
+ return {
184
+ gasLimitOverride: 6000000,
185
+ multicallChunk: 13,
186
+ };
187
+ }, (_) => {
188
+ return {
189
+ gasLimitOverride: 6000000,
190
+ multicallChunk: 13,
191
+ };
192
+ }, (_) => {
193
+ return {
194
+ baseBlockOffset: -10,
195
+ rollback: {
196
+ enabled: true,
197
+ attemptsBeforeRollback: 1,
198
+ rollbackBlockOffset: -10,
199
+ },
200
+ };
201
+ });
202
+ break;
203
+ case sdk_core_1.ChainId.ARBITRUM_ONE:
204
+ case sdk_core_1.ChainId.ARBITRUM_GOERLI:
205
+ case sdk_core_1.ChainId.ARBITRUM_SEPOLIA:
206
+ this.onChainQuoteProvider = new providers_2.OnChainQuoteProvider(chainId, provider, this.multicall2Provider, this.ringFewV2Multicall2Provider, {
207
+ retries: 2,
208
+ minTimeout: 100,
209
+ maxTimeout: 1000,
210
+ }, (_) => {
211
+ return {
212
+ multicallChunk: 10,
213
+ gasLimitPerCall: 12000000,
214
+ quoteMinSuccessRate: 0.1,
215
+ };
216
+ }, (_) => {
217
+ return {
218
+ gasLimitOverride: 30000000,
219
+ multicallChunk: 6,
220
+ };
221
+ }, (_) => {
222
+ return {
223
+ gasLimitOverride: 30000000,
224
+ multicallChunk: 6,
225
+ };
226
+ });
227
+ break;
228
+ case sdk_core_1.ChainId.CELO:
229
+ case sdk_core_1.ChainId.CELO_ALFAJORES:
230
+ this.onChainQuoteProvider = new providers_2.OnChainQuoteProvider(chainId, provider, this.multicall2Provider, this.ringFewV2Multicall2Provider, {
231
+ retries: 2,
232
+ minTimeout: 100,
233
+ maxTimeout: 1000,
234
+ }, (_) => {
235
+ return {
236
+ multicallChunk: 10,
237
+ gasLimitPerCall: 5000000,
238
+ quoteMinSuccessRate: 0.1,
239
+ };
240
+ }, (_) => {
241
+ return {
242
+ gasLimitOverride: 5000000,
243
+ multicallChunk: 5,
244
+ };
245
+ }, (_) => {
246
+ return {
247
+ gasLimitOverride: 6250000,
248
+ multicallChunk: 4,
249
+ };
250
+ });
251
+ break;
252
+ case sdk_core_1.ChainId.POLYGON_MUMBAI:
253
+ case sdk_core_1.ChainId.SEPOLIA:
254
+ case sdk_core_1.ChainId.MAINNET:
255
+ case sdk_core_1.ChainId.POLYGON:
256
+ this.onChainQuoteProvider = new providers_2.OnChainQuoteProvider(chainId, provider, this.multicall2Provider, this.ringFewV2Multicall2Provider, onchainQuoteProviderConfigs_1.RETRY_OPTIONS[chainId], (_) => onchainQuoteProviderConfigs_1.BATCH_PARAMS[chainId], (_) => onchainQuoteProviderConfigs_1.GAS_ERROR_FAILURE_OVERRIDES[chainId], (_) => onchainQuoteProviderConfigs_1.SUCCESS_RATE_FAILURE_OVERRIDES[chainId], (_) => onchainQuoteProviderConfigs_1.BLOCK_NUMBER_CONFIGS[chainId]);
257
+ break;
258
+ default:
259
+ this.onChainQuoteProvider = new providers_2.OnChainQuoteProvider(chainId, provider, this.multicall2Provider, this.ringFewV2Multicall2Provider, onchainQuoteProviderConfigs_1.DEFAULT_RETRY_OPTIONS, (_) => onchainQuoteProviderConfigs_1.DEFAULT_BATCH_PARAMS, (_) => onchainQuoteProviderConfigs_1.DEFAULT_GAS_ERROR_FAILURE_OVERRIDES, (_) => onchainQuoteProviderConfigs_1.DEFAULT_SUCCESS_RATE_FAILURE_OVERRIDES, (_) => onchainQuoteProviderConfigs_1.DEFAULT_BLOCK_NUMBER_CONFIGS);
260
+ break;
261
+ }
262
+ }
263
+ if (tokenValidatorProvider) {
264
+ this.tokenValidatorProvider = tokenValidatorProvider;
265
+ }
266
+ else if (this.chainId === sdk_core_1.ChainId.MAINNET) {
267
+ this.tokenValidatorProvider = new token_validator_provider_1.TokenValidatorProvider(this.chainId, this.multicall2Provider, new providers_2.NodeJSCache(new node_cache_1.default({ stdTTL: 30000, useClones: false })));
268
+ }
269
+ if (tokenPropertiesProvider) {
270
+ this.tokenPropertiesProvider = tokenPropertiesProvider;
271
+ }
272
+ else {
273
+ this.tokenPropertiesProvider = new providers_2.TokenPropertiesProvider(this.chainId, new providers_2.NodeJSCache(new node_cache_1.default({ stdTTL: 86400, useClones: false })), new token_fee_fetcher_1.OnChainTokenFeeFetcher(this.chainId, provider));
274
+ }
275
+ this.v2PoolProvider =
276
+ v2PoolProvider !== null && v2PoolProvider !== void 0 ? v2PoolProvider : new providers_2.CachingV2PoolProvider(chainId, new pool_provider_1.V2PoolProvider(chainId, this.multicall2Provider, this.tokenPropertiesProvider), new providers_2.NodeJSCache(new node_cache_1.default({ stdTTL: 60, useClones: false })));
277
+ this.ringFewV2PoolProvider =
278
+ ringFewV2PoolProvider !== null && ringFewV2PoolProvider !== void 0 ? ringFewV2PoolProvider : new providers_2.RingFewCachingV2PoolProvider(chainId, new providers_2.RingV2PoolProvider(chainId, this.multicall2Provider, this.tokenPropertiesProvider), new providers_2.NodeJSCache(new node_cache_1.default({ stdTTL: 60, useClones: false })));
279
+ this.v2QuoteProvider = v2QuoteProvider !== null && v2QuoteProvider !== void 0 ? v2QuoteProvider : new providers_2.V2QuoteProvider();
280
+ this.ringFewV2QuoteProvider = ringFewV2QuoteProvider !== null && ringFewV2QuoteProvider !== void 0 ? ringFewV2QuoteProvider : new providers_2.RingV2QuoteProvider();
281
+ this.blockedTokenListProvider =
282
+ blockedTokenListProvider !== null && blockedTokenListProvider !== void 0 ? blockedTokenListProvider : new caching_token_list_provider_1.CachingTokenListProvider(chainId, unsupported_tokens_1.UNSUPPORTED_TOKENS, new providers_2.NodeJSCache(new node_cache_1.default({ stdTTL: 3600, useClones: false })));
283
+ this.tokenProvider =
284
+ tokenProvider !== null && tokenProvider !== void 0 ? tokenProvider : new providers_2.CachingTokenProviderWithFallback(chainId, new providers_2.NodeJSCache(new node_cache_1.default({ stdTTL: 3600, useClones: false })), new caching_token_list_provider_1.CachingTokenListProvider(chainId, default_token_list_1.default, new providers_2.NodeJSCache(new node_cache_1.default({ stdTTL: 3600, useClones: false }))), new token_provider_1.TokenProvider(chainId, this.multicall2Provider));
285
+ this.portionProvider = portionProvider !== null && portionProvider !== void 0 ? portionProvider : new portion_provider_1.PortionProvider();
286
+ // const chainName = ID_TO_NETWORK_NAME(chainId);
287
+ // ipfs urls in the following format: `https://cloudflare-ipfs.com/ipns/api.uniswap.org/v1/pools/${protocol}/${chainName}.json`;
288
+ if (v2SubgraphProvider) {
289
+ this.v2SubgraphProvider = v2SubgraphProvider;
290
+ }
291
+ else {
292
+ this.v2SubgraphProvider = new providers_2.V2SubgraphProviderWithFallBacks([
293
+ // new CachingV2SubgraphProvider(
294
+ // chainId,
295
+ // new URISubgraphProvider(
296
+ // chainId,
297
+ // `https://cloudflare-ipfs.com/ipns/api.uniswap.org/v1/pools/v2/${chainName}.json`,
298
+ // undefined,
299
+ // 0
300
+ // ),
301
+ // new NodeJSCache(new NodeCache({ stdTTL: 300, useClones: false }))
302
+ // ),
303
+ new providers_2.StaticV2SubgraphProvider(chainId),
304
+ ]);
305
+ }
306
+ if (ringFewV2SubgraphProvider) {
307
+ this.ringFewV2SubgraphProvider = ringFewV2SubgraphProvider;
308
+ }
309
+ else {
310
+ this.ringFewV2SubgraphProvider = new providers_2.RingFewV2SubgraphProviderWithFallBacks([
311
+ // new RingFewCachingV2SubgraphProvider(
312
+ // chainId,
313
+ // new URISubgraphProvider(
314
+ // chainId,
315
+ // `https://cloudflare-ipfs.com/ipns/api.uniswap.org/v1/pools/v2/${chainName}.json`,
316
+ // undefined,
317
+ // 0
318
+ // ),
319
+ // new NodeJSCache(new NodeCache({ stdTTL: 300, useClones: false }))
320
+ // ),
321
+ new providers_2.RingFewStaticV2SubgraphProvider(chainId),
322
+ ]);
323
+ }
324
+ if (v3SubgraphProvider) {
325
+ this.v3SubgraphProvider = v3SubgraphProvider;
326
+ }
327
+ else {
328
+ this.v3SubgraphProvider = new providers_2.V3SubgraphProviderWithFallBacks([
329
+ // new CachingV3SubgraphProvider(
330
+ // chainId,
331
+ // new URISubgraphProvider(
332
+ // chainId,
333
+ // `https://cloudflare-ipfs.com/ipns/api.uniswap.org/v1/pools/v3/${chainName}.json`,
334
+ // undefined,
335
+ // 0
336
+ // ),
337
+ // new NodeJSCache(new NodeCache({ stdTTL: 300, useClones: false }))
338
+ // ),
339
+ new providers_2.StaticV3SubgraphProvider(chainId, this.v3PoolProvider),
340
+ ]);
341
+ }
342
+ this.v4PoolParams =
343
+ v4PoolParams !== null && v4PoolParams !== void 0 ? v4PoolParams : (0, util_1.getApplicableV4FeesTickspacingsHooks)(chainId);
344
+ if (v4SubgraphProvider) {
345
+ this.v4SubgraphProvider = v4SubgraphProvider;
346
+ }
347
+ else {
348
+ this.v4SubgraphProvider = new providers_2.V4SubgraphProviderWithFallBacks([
349
+ // new CachingV4SubgraphProvider(
350
+ // chainId,
351
+ // new URISubgraphProvider(
352
+ // chainId,
353
+ // `https://cloudflare-ipfs.com/ipns/api.uniswap.org/v1/pools/v4/${chainName}.json`,
354
+ // undefined,
355
+ // 0
356
+ // ),
357
+ // new NodeJSCache(new NodeCache({ stdTTL: 300, useClones: false }))
358
+ // ),
359
+ new providers_2.StaticV4SubgraphProvider(chainId, this.v4PoolProvider, this.v4PoolParams),
360
+ ]);
361
+ }
362
+ let gasPriceProviderInstance;
363
+ if (providers_1.JsonRpcProvider.isProvider(this.provider)) {
364
+ gasPriceProviderInstance = new providers_2.OnChainGasPriceProvider(chainId, new providers_2.EIP1559GasPriceProvider(this.provider), new providers_2.LegacyGasPriceProvider(this.provider));
365
+ }
366
+ else {
367
+ gasPriceProviderInstance = new providers_2.ETHGasStationInfoProvider(config_1.ETH_GAS_STATION_API_URL);
368
+ }
369
+ this.gasPriceProvider =
370
+ gasPriceProvider !== null && gasPriceProvider !== void 0 ? gasPriceProvider : new providers_2.CachingGasStationProvider(chainId, gasPriceProviderInstance, new providers_2.NodeJSCache(new node_cache_1.default({ stdTTL: 7, useClones: false })));
371
+ this.v4GasModelFactory =
372
+ v4GasModelFactory !== null && v4GasModelFactory !== void 0 ? v4GasModelFactory : new v4_heuristic_gas_model_1.V4HeuristicGasModelFactory(this.provider);
373
+ this.uniswapFewV4GasModelFactory =
374
+ uniswapFewV4GasModelFactory !== null && uniswapFewV4GasModelFactory !== void 0 ? uniswapFewV4GasModelFactory : new v4_heuristic_gas_model_2.UniswapFewV4HeuristicGasModelFactory(this.provider);
375
+ this.v3GasModelFactory =
376
+ v3GasModelFactory !== null && v3GasModelFactory !== void 0 ? v3GasModelFactory : new v3_heuristic_gas_model_1.V3HeuristicGasModelFactory(this.provider);
377
+ this.uniswapFewV3GasModelFactory =
378
+ uniswapFewV3GasModelFactory !== null && uniswapFewV3GasModelFactory !== void 0 ? uniswapFewV3GasModelFactory : new v3_heuristic_gas_model_2.UniswapFewV3HeuristicGasModelFactory(this.provider);
379
+ this.v2GasModelFactory =
380
+ v2GasModelFactory !== null && v2GasModelFactory !== void 0 ? v2GasModelFactory : new v2_heuristic_gas_model_1.V2HeuristicGasModelFactory(this.provider);
381
+ this.ringFewV2GasModelFactory =
382
+ ringFewV2GasModelFactory !== null && ringFewV2GasModelFactory !== void 0 ? ringFewV2GasModelFactory : new v2_heuristic_gas_model_2.RingFewV2HeuristicGasModelFactory(this.provider);
383
+ this.mixedRouteGasModelFactory =
384
+ mixedRouteGasModelFactory !== null && mixedRouteGasModelFactory !== void 0 ? mixedRouteGasModelFactory : new mixed_route_heuristic_gas_model_1.MixedRouteHeuristicGasModelFactory();
385
+ this.swapRouterProvider =
386
+ swapRouterProvider !== null && swapRouterProvider !== void 0 ? swapRouterProvider : new providers_2.SwapRouterProvider(this.multicall2Provider, this.chainId);
387
+ if (chainId === sdk_core_1.ChainId.ARBITRUM_ONE ||
388
+ chainId === sdk_core_1.ChainId.ARBITRUM_GOERLI) {
389
+ this.l2GasDataProvider =
390
+ arbitrumGasDataProvider !== null && arbitrumGasDataProvider !== void 0 ? arbitrumGasDataProvider : new gas_data_provider_1.ArbitrumGasDataProvider(chainId, this.provider);
391
+ }
392
+ // Initialize the Quoters.
393
+ // Quoters are an abstraction encapsulating the business logic of fetching routes and quotes.
394
+ this.v2Quoter = new quoters_1.V2Quoter(this.v2SubgraphProvider, this.v2PoolProvider, this.v2QuoteProvider, this.v2GasModelFactory, this.tokenProvider, this.chainId, this.blockedTokenListProvider, this.tokenValidatorProvider, this.l2GasDataProvider);
395
+ this.ringFewV2Quoter = new few_v2_quoter_1.RingFewV2Quoter(this.ringFewV2SubgraphProvider, this.ringFewV2PoolProvider, this.ringFewV2QuoteProvider, this.ringFewV2GasModelFactory, this.tokenProvider, this.chainId, this.blockedTokenListProvider, this.tokenValidatorProvider, this.l2GasDataProvider);
396
+ this.v3Quoter = new quoters_1.V3Quoter(this.v3SubgraphProvider, this.v3PoolProvider, this.onChainQuoteProvider, this.tokenProvider, this.chainId, this.blockedTokenListProvider, this.tokenValidatorProvider);
397
+ this.uniswapFewV3Quoter = new uniswap_few_v3_quoter_1.UniswapFewV3Quoter(this.v3SubgraphProvider, this.v3PoolProvider, this.onChainQuoteProvider, this.tokenProvider, this.chainId, this.blockedTokenListProvider, this.tokenValidatorProvider);
398
+ this.v4Quoter = new v4_quoter_1.V4Quoter(this.v4SubgraphProvider, this.v4PoolProvider, this.onChainQuoteProvider, this.tokenProvider, this.chainId, this.blockedTokenListProvider, this.tokenValidatorProvider);
399
+ this.uniswapFewV4Quoter = new uniswap_few_v4_quoter_1.UniswapFewV4Quoter(this.v4SubgraphProvider, this.v4PoolProvider, this.onChainQuoteProvider, this.tokenProvider, this.chainId, this.blockedTokenListProvider, this.tokenValidatorProvider);
400
+ this.mixedQuoter = new quoters_1.MixedQuoter(this.v4SubgraphProvider, this.v4PoolProvider, this.v3SubgraphProvider, this.v3PoolProvider, this.v2SubgraphProvider, this.v2PoolProvider, this.onChainQuoteProvider, this.tokenProvider, this.chainId, this.blockedTokenListProvider, this.tokenValidatorProvider);
401
+ this.v2Supported = v2Supported !== null && v2Supported !== void 0 ? v2Supported : chains_1.V2_SUPPORTED;
402
+ this.ringFewV2Supported = ringFewV2Supported !== null && ringFewV2Supported !== void 0 ? ringFewV2Supported : chains_1.RING_FEW_V2_SUPPORTED;
403
+ this.v4Supported = v4Supported !== null && v4Supported !== void 0 ? v4Supported : util_1.V4_SUPPORTED;
404
+ this.mixedSupported = mixedSupported !== null && mixedSupported !== void 0 ? mixedSupported : util_1.MIXED_SUPPORTED;
405
+ this.cachedRoutesCacheInvalidationFixRolloutPercentage =
406
+ cachedRoutesCacheInvalidationFixRolloutPercentage;
407
+ }
408
+ async routeToRatio(token0Balance, token1Balance, position, swapAndAddConfig, swapAndAddOptions, routingConfig = (0, config_1.DEFAULT_ROUTING_CONFIG_BY_CHAIN)(this.chainId)) {
409
+ if (token1Balance.currency.wrapped.sortsBefore(token0Balance.currency.wrapped)) {
410
+ [token0Balance, token1Balance] = [token1Balance, token0Balance];
411
+ }
412
+ let preSwapOptimalRatio = this.calculateOptimalRatio(position, position.pool.sqrtRatioX96, true);
413
+ // set up parameters according to which token will be swapped
414
+ let zeroForOne;
415
+ if (position.pool.tickCurrent > position.tickUpper) {
416
+ zeroForOne = true;
417
+ }
418
+ else if (position.pool.tickCurrent < position.tickLower) {
419
+ zeroForOne = false;
420
+ }
421
+ else {
422
+ zeroForOne = new sdk_core_1.Fraction(token0Balance.quotient, token1Balance.quotient).greaterThan(preSwapOptimalRatio);
423
+ if (!zeroForOne)
424
+ preSwapOptimalRatio = preSwapOptimalRatio.invert();
425
+ }
426
+ const [inputBalance, outputBalance] = zeroForOne
427
+ ? [token0Balance, token1Balance]
428
+ : [token1Balance, token0Balance];
429
+ let optimalRatio = preSwapOptimalRatio;
430
+ let postSwapTargetPool = position.pool;
431
+ let exchangeRate = zeroForOne
432
+ ? position.pool.token0Price
433
+ : position.pool.token1Price;
434
+ let swap = null;
435
+ let ratioAchieved = false;
436
+ let n = 0;
437
+ // iterate until we find a swap with a sufficient ratio or return null
438
+ while (!ratioAchieved) {
439
+ n++;
440
+ if (n > swapAndAddConfig.maxIterations) {
441
+ log_1.log.info('max iterations exceeded');
442
+ return {
443
+ status: router_1.SwapToRatioStatus.NO_ROUTE_FOUND,
444
+ error: 'max iterations exceeded',
445
+ };
446
+ }
447
+ const amountToSwap = (0, calculate_ratio_amount_in_1.calculateRatioAmountIn)(optimalRatio, exchangeRate, inputBalance, outputBalance);
448
+ if (amountToSwap.equalTo(0)) {
449
+ log_1.log.info(`no swap needed: amountToSwap = 0`);
450
+ return {
451
+ status: router_1.SwapToRatioStatus.NO_SWAP_NEEDED,
452
+ };
453
+ }
454
+ swap = await this.route(amountToSwap, outputBalance.currency, sdk_core_1.TradeType.EXACT_INPUT, undefined, Object.assign(Object.assign(Object.assign({}, (0, config_1.DEFAULT_ROUTING_CONFIG_BY_CHAIN)(this.chainId)), routingConfig), {
455
+ /// @dev We do not want to query for mixedRoutes for routeToRatio as they are not supported
456
+ /// [Protocol.V3, Protocol.V2] will make sure we only query for V3 and V2
457
+ protocols: [router_sdk_1.Protocol.V3, router_sdk_1.Protocol.V2] }));
458
+ if (!swap) {
459
+ log_1.log.info('no route found from this.route()');
460
+ return {
461
+ status: router_1.SwapToRatioStatus.NO_ROUTE_FOUND,
462
+ error: 'no route found',
463
+ };
464
+ }
465
+ const inputBalanceUpdated = inputBalance.subtract(swap.trade.inputAmount);
466
+ const outputBalanceUpdated = outputBalance.add(swap.trade.outputAmount);
467
+ const newRatio = inputBalanceUpdated.divide(outputBalanceUpdated);
468
+ let targetPoolPriceUpdate;
469
+ swap.route.forEach((route) => {
470
+ if (route.protocol === router_sdk_1.Protocol.V3) {
471
+ const v3Route = route;
472
+ v3Route.route.pools.forEach((pool, i) => {
473
+ if (pool.token0.equals(position.pool.token0) &&
474
+ pool.token1.equals(position.pool.token1) &&
475
+ pool.fee === position.pool.fee) {
476
+ targetPoolPriceUpdate = jsbi_1.default.BigInt(v3Route.sqrtPriceX96AfterList[i].toString());
477
+ optimalRatio = this.calculateOptimalRatio(position, jsbi_1.default.BigInt(targetPoolPriceUpdate.toString()), zeroForOne);
478
+ }
479
+ });
480
+ }
481
+ });
482
+ if (!targetPoolPriceUpdate) {
483
+ optimalRatio = preSwapOptimalRatio;
484
+ }
485
+ ratioAchieved =
486
+ newRatio.equalTo(optimalRatio) ||
487
+ this.absoluteValue(newRatio.asFraction.divide(optimalRatio).subtract(1)).lessThan(swapAndAddConfig.ratioErrorTolerance);
488
+ if (ratioAchieved && targetPoolPriceUpdate) {
489
+ postSwapTargetPool = new v3_sdk_1.Pool(position.pool.token0, position.pool.token1, position.pool.fee, targetPoolPriceUpdate, position.pool.liquidity, v3_sdk_1.TickMath.getTickAtSqrtRatio(targetPoolPriceUpdate), position.pool.tickDataProvider);
490
+ }
491
+ exchangeRate = swap.trade.outputAmount.divide(swap.trade.inputAmount);
492
+ log_1.log.info({
493
+ exchangeRate: exchangeRate.asFraction.toFixed(18),
494
+ optimalRatio: optimalRatio.asFraction.toFixed(18),
495
+ newRatio: newRatio.asFraction.toFixed(18),
496
+ inputBalanceUpdated: inputBalanceUpdated.asFraction.toFixed(18),
497
+ outputBalanceUpdated: outputBalanceUpdated.asFraction.toFixed(18),
498
+ ratioErrorTolerance: swapAndAddConfig.ratioErrorTolerance.toFixed(18),
499
+ iterationN: n.toString(),
500
+ }, 'QuoteToRatio Iteration Parameters');
501
+ if (exchangeRate.equalTo(0)) {
502
+ log_1.log.info('exchangeRate to 0');
503
+ return {
504
+ status: router_1.SwapToRatioStatus.NO_ROUTE_FOUND,
505
+ error: 'insufficient liquidity to swap to optimal ratio',
506
+ };
507
+ }
508
+ }
509
+ if (!swap) {
510
+ return {
511
+ status: router_1.SwapToRatioStatus.NO_ROUTE_FOUND,
512
+ error: 'no route found',
513
+ };
514
+ }
515
+ let methodParameters;
516
+ if (swapAndAddOptions) {
517
+ methodParameters = await this.buildSwapAndAddMethodParameters(swap.trade, swapAndAddOptions, {
518
+ initialBalanceTokenIn: inputBalance,
519
+ initialBalanceTokenOut: outputBalance,
520
+ preLiquidityPosition: position,
521
+ });
522
+ }
523
+ return {
524
+ status: router_1.SwapToRatioStatus.SUCCESS,
525
+ result: Object.assign(Object.assign({}, swap), { methodParameters, optimalRatio, postSwapTargetPool }),
526
+ };
527
+ }
528
+ /**
529
+ * @inheritdoc IRouter
530
+ */
531
+ async route(amount, quoteCurrency, tradeType, swapConfig, partialRoutingConfig = {}) {
532
+ var _a, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
533
+ const originalAmount = amount;
534
+ const fewAmountToken = (0, few_v2_sdk_1.getFewTokenFromOriginalToken)(originalAmount.currency.wrapped, this.chainId);
535
+ let fewAmount = amounts_1.CurrencyAmount.fromRawAmount(fewAmountToken, originalAmount.quotient); // 在 Blast 网络需要注意 origin token 和 fewtoken 的 decimals 差异
536
+ // const originalFewAmount = fewAmount;
537
+ const { currencyIn, currencyOut } = this.determineCurrencyInOutFromTradeType(tradeType, amount, quoteCurrency);
538
+ const fewTokenIn = currencyIn instanceof sdk_core_1.Token
539
+ ? (0, few_v2_sdk_1.getFewTokenFromOriginalToken)(currencyIn, this.chainId)
540
+ : currencyIn.isNative
541
+ ? (0, few_v2_sdk_1.getFewTokenFromOriginalToken)(currencyIn.wrapped, this.chainId)
542
+ : null;
543
+ const fewTokenOut = currencyOut instanceof sdk_core_1.Token
544
+ ? (0, few_v2_sdk_1.getFewTokenFromOriginalToken)(currencyOut, this.chainId)
545
+ : currencyOut.isNative
546
+ ? (0, few_v2_sdk_1.getFewTokenFromOriginalToken)(currencyOut.wrapped, this.chainId)
547
+ : null;
548
+ const fewQuoteToken = quoteCurrency instanceof sdk_core_1.Token
549
+ ? (0, few_v2_sdk_1.getFewTokenFromOriginalToken)(quoteCurrency, this.chainId)
550
+ : quoteCurrency.isNative
551
+ ? (0, few_v2_sdk_1.getFewTokenFromOriginalToken)(quoteCurrency.wrapped, this.chainId)
552
+ : null;
553
+ const tokenOutProperties = await this.tokenPropertiesProvider.getTokensProperties([currencyOut], partialRoutingConfig);
554
+ const feeTakenOnTransfer = (_c = (_a = tokenOutProperties[(0, util_1.getAddressLowerCase)(currencyOut)]) === null || _a === void 0 ? void 0 : _a.tokenFeeResult) === null || _c === void 0 ? void 0 : _c.feeTakenOnTransfer;
555
+ const externalTransferFailed = (_e = (_d = tokenOutProperties[(0, util_1.getAddressLowerCase)(currencyOut)]) === null || _d === void 0 ? void 0 : _d.tokenFeeResult) === null || _e === void 0 ? void 0 : _e.externalTransferFailed;
556
+ // We want to log the fee on transfer output tokens that we are taking fee or not
557
+ // Ideally the trade size (normalized in USD) would be ideal to log here, but we don't have spot price of output tokens here.
558
+ // We have to make sure token out is FOT with either buy/sell fee bps > 0
559
+ if (((_h = (_g = (_f = tokenOutProperties[(0, util_1.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)) ||
560
+ ((_l = (_k = (_j = tokenOutProperties[(0, util_1.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))) {
561
+ if (feeTakenOnTransfer || externalTransferFailed) {
562
+ // also to be extra safe, in case of FOT with feeTakenOnTransfer or externalTransferFailed,
563
+ // we nullify the fee and flat fee to avoid any potential issues.
564
+ // although neither web nor wallet should use the calldata returned from routing/SOR
565
+ if ((swapConfig === null || swapConfig === void 0 ? void 0 : swapConfig.type) === router_1.SwapType.UNIVERSAL_ROUTER) {
566
+ swapConfig.fee = undefined;
567
+ swapConfig.flatFee = undefined;
568
+ }
569
+ metric_1.metric.putMetric('TokenOutFeeOnTransferNotTakingFee', 1, metric_1.MetricLoggerUnit.Count);
570
+ }
571
+ else {
572
+ metric_1.metric.putMetric('TokenOutFeeOnTransferTakingFee', 1, metric_1.MetricLoggerUnit.Count);
573
+ }
574
+ }
575
+ if (tradeType === sdk_core_1.TradeType.EXACT_OUTPUT) {
576
+ const portionAmount = this.portionProvider.getPortionAmount(amount, tradeType, feeTakenOnTransfer, externalTransferFailed, swapConfig);
577
+ if (portionAmount && portionAmount.greaterThan(router_sdk_1.ZERO)) {
578
+ // In case of exact out swap, before we route, we need to make sure that the
579
+ // token out amount accounts for flat portion, and token in amount after the best swap route contains the token in equivalent of portion.
580
+ // 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.
581
+ // This is because instead of the swapper being responsible for the portion,
582
+ // the pool instead gets responsible for the portion.
583
+ // The addition below avoids that situation.
584
+ amount = amount.add(portionAmount);
585
+ }
586
+ const portionFewAmount = this.portionProvider.getPortionAmount(fewAmount, tradeType, feeTakenOnTransfer, externalTransferFailed, swapConfig);
587
+ if (portionFewAmount && portionFewAmount.greaterThan(router_sdk_1.ZERO)) {
588
+ // In case of exact out swap, before we route, we need to make sure that the
589
+ // token out few amount accounts for flat portion, and token in few amount after the best swap route contains the token in equivalent of portion.
590
+ // 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.
591
+ // This is because instead of the swapper being responsible for the portion,
592
+ // the pool instead gets responsible for the portion.
593
+ // The addition below avoids that situation.
594
+ fewAmount = fewAmount.add(portionFewAmount.wrapped);
595
+ }
596
+ }
597
+ metric_1.metric.setProperty('chainId', this.chainId);
598
+ metric_1.metric.setProperty('pair', `${currencyIn.symbol}/${currencyOut.symbol}`);
599
+ metric_1.metric.setProperty('tokenIn', (0, util_1.getAddress)(currencyIn));
600
+ metric_1.metric.setProperty('tokenOut', (0, util_1.getAddress)(currencyOut));
601
+ metric_1.metric.setProperty('tradeType', tradeType === sdk_core_1.TradeType.EXACT_INPUT ? 'ExactIn' : 'ExactOut');
602
+ metric_1.metric.putMetric(`QuoteRequestedForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
603
+ // Get a block number to specify in all our calls. Ensures data we fetch from chain is
604
+ // from the same block.
605
+ const blockNumber = (_m = partialRoutingConfig.blockNumber) !== null && _m !== void 0 ? _m : this.getBlockNumberPromise();
606
+ const routingConfig = lodash_1.default.merge({
607
+ // These settings could be changed by the partialRoutingConfig
608
+ useCachedRoutes: true,
609
+ writeToCachedRoutes: true,
610
+ optimisticCachedRoutes: false,
611
+ }, (0, config_1.DEFAULT_ROUTING_CONFIG_BY_CHAIN)(this.chainId), partialRoutingConfig, { blockNumber });
612
+ if (routingConfig.debugRouting) {
613
+ log_1.log.warn(`Finalized routing config is ${JSON.stringify(routingConfig)}`);
614
+ }
615
+ const gasPriceWei = await this.getGasPriceWei(await blockNumber, await partialRoutingConfig.blockNumber);
616
+ // const gasTokenAccessor = await this.tokenProvider.getTokens([routingConfig.gasToken!]);
617
+ const gasToken = routingConfig.gasToken
618
+ ? (await this.tokenProvider.getTokens([routingConfig.gasToken])).getTokenByAddress(routingConfig.gasToken)
619
+ : undefined;
620
+ const providerConfig = Object.assign(Object.assign({}, routingConfig), { blockNumber, additionalGasOverhead: (0, gas_costs_1.NATIVE_OVERHEAD)(this.chainId, amount.currency, quoteCurrency), gasToken,
621
+ externalTransferFailed,
622
+ feeTakenOnTransfer });
623
+ (0, simple_perf_tracker_1.startTimer)('alpha-router.route.getGasModels');
624
+ const { ringFewV2GasModel: ringFewV2GasModel, v2GasModel: v2GasModel, fewV2GasModel: fewV2GasModel, v3GasModel: v3GasModel, fewV3GasModel: fewV3GasModel, v4GasModel: v4GasModel, fewV4GasModel: fewV4GasModel, mixedRouteGasModel: mixedRouteGasModel, } = await this.getGasModels(gasPriceWei, amount.currency.wrapped, quoteCurrency.wrapped, providerConfig);
625
+ (0, simple_perf_tracker_1.endTimer)('alpha-router.route.getGasModels');
626
+ // Create a Set to sanitize the protocols input, a Set of undefined becomes an empty set,
627
+ // Then create an Array from the values of that Set.
628
+ const protocols = Array.from(new Set(routingConfig.protocols).values());
629
+ (0, simple_perf_tracker_1.startTimer)('alpha-router.route.getCacheMode');
630
+ 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)));
631
+ (0, simple_perf_tracker_1.endTimer)('alpha-router.route.getCacheMode');
632
+ // const fewCacheMode =
633
+ // routingConfig.overwriteCacheMode ??
634
+ // (await this.routeCachingProvider?.getCacheMode(
635
+ // this.chainId,
636
+ // fewAmount,
637
+ // fewQuoteToken!,
638
+ // tradeType,
639
+ // protocols
640
+ // ));
641
+ // Fetch CachedRoutes
642
+ let cachedRoutes;
643
+ // Fetch fewCachedRoutes
644
+ let fewCachedRoutes;
645
+ // Decide whether to use cached routes or not - If |enabledAndRequestedProtocolsMatch| is true we are good to use cached routes.
646
+ // In order to use cached routes, we need to have all enabled protocols specified in the request.
647
+ // By default, all protocols are enabled but for UniversalRouterVersion.V1_2, V4 is not.
648
+ // - ref: https://github.com/Uniswap/routing-api/blob/663b607d80d9249f85e7ab0925a611ec3701da2a/lib/util/supportedProtocolVersions.ts#L15
649
+ // So we take this into account when deciding whether to use cached routes or not.
650
+ // We only want to use cache if all enabled protocols are specified (V2,V3,V4? + MIXED). In any other case, use onchain path.
651
+ // - Cache is optimized for global search, not for specific protocol(s) search.
652
+ // For legacy systems (SWAP_ROUTER_02) or missing swapConfig, follow UniversalRouterVersion.V1_2 logic.
653
+ const availableProtocolsSet = new Set(Object.values(router_sdk_1.Protocol));
654
+ const requestedProtocolsSet = new Set(protocols);
655
+ const swapRouter = !swapConfig ||
656
+ swapConfig.type === router_1.SwapType.SWAP_ROUTER_02 ||
657
+ (swapConfig.type === router_1.SwapType.UNIVERSAL_ROUTER &&
658
+ swapConfig.version === universal_router_sdk_1.UniversalRouterVersion.V1_2);
659
+ if (swapRouter) {
660
+ availableProtocolsSet.delete(router_sdk_1.Protocol.V4);
661
+ if (requestedProtocolsSet.has(router_sdk_1.Protocol.V4)) {
662
+ requestedProtocolsSet.delete(router_sdk_1.Protocol.V4);
663
+ }
664
+ }
665
+ const enabledAndRequestedProtocolsMatch = availableProtocolsSet.size === requestedProtocolsSet.size &&
666
+ [...availableProtocolsSet].every((protocol) => requestedProtocolsSet.has(protocol));
667
+ // If the requested protocols do not match the enabled protocols, we need to set the hooks options to NO_HOOKS.
668
+ if (!requestedProtocolsSet.has(router_sdk_1.Protocol.V4)) {
669
+ routingConfig.hooksOptions = util_1.HooksOptions.NO_HOOKS;
670
+ }
671
+ // If hooksOptions not specified and it's not a swapRouter (i.e. Universal Router it is),
672
+ // we should also set it to HOOKS_INCLUSIVE, as this is default behavior even without hooksOptions.
673
+ if (!routingConfig.hooksOptions) {
674
+ routingConfig.hooksOptions = util_1.HooksOptions.HOOKS_INCLUSIVE;
675
+ }
676
+ log_1.log.debug('UniversalRouterVersion_CacheGate_Check', {
677
+ availableProtocolsSet: Array.from(availableProtocolsSet),
678
+ requestedProtocolsSet: Array.from(requestedProtocolsSet),
679
+ enabledAndRequestedProtocolsMatch,
680
+ swapConfigType: swapConfig === null || swapConfig === void 0 ? void 0 : swapConfig.type,
681
+ swapConfigUniversalRouterVersion: (swapConfig === null || swapConfig === void 0 ? void 0 : swapConfig.type) === router_1.SwapType.UNIVERSAL_ROUTER
682
+ ? swapConfig === null || swapConfig === void 0 ? void 0 : swapConfig.version
683
+ : 'N/A',
684
+ });
685
+ (0, simple_perf_tracker_1.startTimer)('alpha-router.route.isAllowedToEnterCachedRoutes');
686
+ const isAllowedToEnterCachedRoutes = AlphaRouter.isAllowedToEnterCachedRoutes(routingConfig.intent, routingConfig.hooksOptions, swapRouter);
687
+ if (routingConfig.useCachedRoutes &&
688
+ cacheMode !== providers_2.CacheMode.Darkmode &&
689
+ isAllowedToEnterCachedRoutes) {
690
+ if (enabledAndRequestedProtocolsMatch) {
691
+ if (protocols.includes(router_sdk_1.Protocol.V4) &&
692
+ (currencyIn.isNative || currencyOut.isNative)) {
693
+ const [wrappedNativeCachedRoutes, nativeCachedRoutes] = await Promise.all([
694
+ (_q = this.routeCachingProvider) === null || _q === void 0 ? void 0 : _q.getCachedRoute(this.chainId, amounts_1.CurrencyAmount.fromRawAmount(amount.currency.wrapped, amount.quotient), quoteCurrency.wrapped, tradeType, protocols, await blockNumber, routingConfig.optimisticCachedRoutes),
695
+ (_r = this.routeCachingProvider) === null || _r === void 0 ? void 0 : _r.getCachedRoute(this.chainId, amount, quoteCurrency, tradeType, [router_sdk_1.Protocol.V4], await blockNumber, routingConfig.optimisticCachedRoutes),
696
+ ]);
697
+ if ((wrappedNativeCachedRoutes &&
698
+ (wrappedNativeCachedRoutes === null || wrappedNativeCachedRoutes === void 0 ? void 0 : wrappedNativeCachedRoutes.routes.length) > 0) ||
699
+ (nativeCachedRoutes && (nativeCachedRoutes === null || nativeCachedRoutes === void 0 ? void 0 : nativeCachedRoutes.routes.length) > 0)) {
700
+ cachedRoutes = new providers_2.CachedRoutes({
701
+ routes: [
702
+ ...((_s = nativeCachedRoutes === null || nativeCachedRoutes === void 0 ? void 0 : nativeCachedRoutes.routes) !== null && _s !== void 0 ? _s : []),
703
+ ...((_t = wrappedNativeCachedRoutes === null || wrappedNativeCachedRoutes === void 0 ? void 0 : wrappedNativeCachedRoutes.routes) !== null && _t !== void 0 ? _t : []),
704
+ ],
705
+ chainId: this.chainId,
706
+ currencyIn: currencyIn,
707
+ currencyOut: currencyOut,
708
+ protocolsCovered: protocols,
709
+ blockNumber: await blockNumber,
710
+ tradeType: tradeType,
711
+ 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(),
712
+ 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 : defaultBlocksToLive_1.DEFAULT_BLOCKS_TO_LIVE[this.chainId],
713
+ });
714
+ }
715
+ }
716
+ else {
717
+ cachedRoutes = await ((_y = this.routeCachingProvider) === null || _y === void 0 ? void 0 : _y.getCachedRoute(this.chainId, amount, quoteCurrency, tradeType, protocols, await blockNumber, routingConfig.optimisticCachedRoutes));
718
+ fewCachedRoutes = await ((_z = this.routeCachingProvider) === null || _z === void 0 ? void 0 : _z.getCachedRoute(this.chainId, fewAmount, fewQuoteToken, tradeType, protocols, await blockNumber, routingConfig.optimisticCachedRoutes));
719
+ }
720
+ }
721
+ }
722
+ (0, simple_perf_tracker_1.endTimer)('alpha-router.route.isAllowedToEnterCachedRoutes');
723
+ if ((0, util_1.shouldWipeoutCachedRoutes)(cachedRoutes, routingConfig)) {
724
+ cachedRoutes = undefined;
725
+ }
726
+ if ((0, util_1.shouldWipeoutCachedRoutes)(fewCachedRoutes, routingConfig)) {
727
+ fewCachedRoutes = undefined;
728
+ }
729
+ metric_1.metric.putMetric(routingConfig.useCachedRoutes
730
+ ? 'GetQuoteUsingCachedRoutes'
731
+ : 'GetQuoteNotUsingCachedRoutes', 1, metric_1.MetricLoggerUnit.Count);
732
+ (0, simple_perf_tracker_1.startTimer)('alpha-router.route.getCachedRoute');
733
+ if (cacheMode &&
734
+ routingConfig.useCachedRoutes &&
735
+ cacheMode !== providers_2.CacheMode.Darkmode &&
736
+ !cachedRoutes) {
737
+ metric_1.metric.putMetric(`GetCachedRoute_miss_${cacheMode}`, 1, metric_1.MetricLoggerUnit.Count);
738
+ log_1.log.info({
739
+ currencyIn: currencyIn.symbol,
740
+ currencyInAddress: (0, util_1.getAddress)(currencyIn),
741
+ currencyOut: currencyOut.symbol,
742
+ currencyOutAddress: (0, util_1.getAddress)(currencyOut),
743
+ cacheMode,
744
+ amount: amount.toExact(),
745
+ chainId: this.chainId,
746
+ tradeType: this.tradeTypeStr(tradeType),
747
+ }, `GetCachedRoute miss ${cacheMode} for ${this.tokenPairSymbolTradeTypeChainId(currencyIn, currencyOut, tradeType)}`);
748
+ }
749
+ else if (cachedRoutes && routingConfig.useCachedRoutes) {
750
+ metric_1.metric.putMetric(`GetCachedRoute_hit_${cacheMode}`, 1, metric_1.MetricLoggerUnit.Count);
751
+ log_1.log.info({
752
+ currencyIn: currencyIn.symbol,
753
+ currencyInAddress: (0, util_1.getAddress)(currencyIn),
754
+ currencyOut: currencyOut.symbol,
755
+ currencyOutAddress: (0, util_1.getAddress)(currencyOut),
756
+ cacheMode,
757
+ amount: amount.toExact(),
758
+ chainId: this.chainId,
759
+ tradeType: this.tradeTypeStr(tradeType),
760
+ }, `GetCachedRoute hit ${cacheMode} for ${this.tokenPairSymbolTradeTypeChainId(currencyIn, currencyOut, tradeType)}`);
761
+ }
762
+ (0, simple_perf_tracker_1.endTimer)('alpha-router.route.getCachedRoute');
763
+ (0, simple_perf_tracker_1.startTimer)('alpha-router.route.getSwapRouteFromCache');
764
+ let swapRouteFromCachePromise = Promise.resolve(null);
765
+ if (cachedRoutes) {
766
+ swapRouteFromCachePromise = this.getSwapRouteFromCache(currencyIn, currencyOut, cachedRoutes, await blockNumber, amount, fewAmount, quoteCurrency, fewQuoteToken, tradeType, routingConfig, v3GasModel, v4GasModel, mixedRouteGasModel, gasPriceWei, v2GasModel, swapConfig, providerConfig);
767
+ }
768
+ (0, simple_perf_tracker_1.endTimer)('alpha-router.route.getSwapRouteFromCache');
769
+ (0, simple_perf_tracker_1.startTimer)('alpha-router.route.getUniswapFewTokenSwapRouteFromCache');
770
+ let uniswapFewSwapRouteFromCachePromise = Promise.resolve(null);
771
+ if (fewCachedRoutes) {
772
+ uniswapFewSwapRouteFromCachePromise = this.getUniswapFewTokenSwapRouteFromCache(fewTokenIn, fewTokenOut, fewCachedRoutes, await blockNumber, amount, fewAmount, quoteCurrency, fewQuoteToken, tradeType, routingConfig, v3GasModel, v4GasModel, mixedRouteGasModel, gasPriceWei, v2GasModel, swapConfig, providerConfig);
773
+ }
774
+ (0, simple_perf_tracker_1.endTimer)('alpha-router.route.getUniswapFewTokenSwapRouteFromCache');
775
+ (0, simple_perf_tracker_1.startTimer)('alpha-router.route.getSwapRouteFromChain');
776
+ let swapRouteFromChainPromise = Promise.resolve(null);
777
+ if (!cachedRoutes || cacheMode !== providers_2.CacheMode.Livemode) {
778
+ swapRouteFromChainPromise = this.getSwapRouteFromChain(amount, fewAmount, currencyIn, fewTokenIn, currencyOut, fewTokenOut, protocols, quoteCurrency, fewQuoteToken, tradeType, routingConfig, v3GasModel, v4GasModel, mixedRouteGasModel, gasPriceWei, v2GasModel, ringFewV2GasModel, swapConfig, providerConfig);
779
+ }
780
+ (0, simple_perf_tracker_1.endTimer)('alpha-router.route.getSwapRouteFromChain');
781
+ (0, simple_perf_tracker_1.startTimer)('alpha-router.route.getUniswapFewTokenSwapRouteFromChain');
782
+ let uniswapFewSwapRouteFromChainPromise = Promise.resolve(null);
783
+ if (!cachedRoutes || cacheMode !== providers_2.CacheMode.Livemode) {
784
+ //cachedRoutes is undefined
785
+ uniswapFewSwapRouteFromChainPromise = this.getUniswapFewTokenSwapRouteFromChain(amount, fewAmount, currencyIn, fewTokenIn, currencyOut, fewTokenOut, protocols, quoteCurrency, fewQuoteToken, tradeType, routingConfig,
786
+ // v3GasModel,
787
+ fewV3GasModel,
788
+ // v4GasModel,
789
+ fewV4GasModel, mixedRouteGasModel, gasPriceWei, v2GasModel, fewV2GasModel,
790
+ // ringFewV2GasModel,
791
+ providerConfig);
792
+ }
793
+ (0, simple_perf_tracker_1.endTimer)('alpha-router.route.getUniswapFewTokenSwapRouteFromChain');
794
+ // let swapRouteFromRingFewChainPromise: Promise<BestSwapRoute | null> =
795
+ // Promise.resolve(null);
796
+ // if (!fewCachedRoutes || cacheMode !== CacheMode.Livemode) {
797
+ // swapRouteFromRingFewChainPromise = this.getSwapRouteFromChain(
798
+ // fewAmount!,
799
+ // fewTokenIn!,
800
+ // fewTokenOut!,
801
+ // protocols,
802
+ // fewQuoteToken!,
803
+ // tradeType,
804
+ // routingConfig,
805
+ // v3GasModel,
806
+ // v4GasModel,
807
+ // mixedRouteGasModel,
808
+ // gasPriceWei,
809
+ // ringFewV2GasModel,
810
+ // swapConfig,
811
+ // providerConfig
812
+ // );
813
+ // }
814
+ (0, simple_perf_tracker_1.startTimer)('alpha-router.route.getSwapRouteFromCache_Chain');
815
+ const [swapRouteFromCache, uniswapFewSwapRouteFromCache,] = await Promise.all([
816
+ swapRouteFromCachePromise,
817
+ uniswapFewSwapRouteFromCachePromise
818
+ ]);
819
+ const [swapRouteFromChainRaw, uniswapFewSwapRouteFromChainRaw,] = await Promise.all([
820
+ swapRouteFromChainPromise,
821
+ uniswapFewSwapRouteFromChainPromise
822
+ ]);
823
+ const [percents] = this.getAmountDistribution(amount, routingConfig);
824
+ const allRoutesWithValidQuotes = [...(swapRouteFromChainRaw || []), ...(uniswapFewSwapRouteFromChainRaw || [])];
825
+ const swapRouteFromChain = await (0, best_swap_route_1.getBestSwapRoute)(amount, percents, allRoutesWithValidQuotes, tradeType, this.chainId, routingConfig, this.portionProvider, v2GasModel, v3GasModel, v4GasModel, swapConfig, providerConfig);
826
+ if (swapRouteFromChain) {
827
+ // this.emitPoolSelectionMetrics(
828
+ // swapRouteFromChain,
829
+ // [],
830
+ // currencyIn,
831
+ // currencyOut
832
+ // );
833
+ }
834
+ (0, simple_perf_tracker_1.endTimer)('alpha-router.route.getSwapRouteFromCache_Chain');
835
+ let swapRouteRaw;
836
+ let hitsCachedRoute = false;
837
+ if (cacheMode === providers_2.CacheMode.Livemode && swapRouteFromCache) {
838
+ log_1.log.info(`CacheMode is ${cacheMode}, and we are using swapRoute from cache`);
839
+ hitsCachedRoute = true;
840
+ swapRouteRaw = swapRouteFromCache;
841
+ }
842
+ else {
843
+ log_1.log.info(`CacheMode is ${cacheMode}, and we are using materialized swapRoute`);
844
+ swapRouteRaw = swapRouteFromChain;
845
+ }
846
+ let uniswapFewSwapRouteRaw;
847
+ if (cacheMode === providers_2.CacheMode.Livemode && uniswapFewSwapRouteFromCache) {
848
+ log_1.log.info(`CacheMode is ${cacheMode}, and we are using swapRoute from cache`);
849
+ hitsCachedRoute = true;
850
+ uniswapFewSwapRouteRaw = uniswapFewSwapRouteFromCache;
851
+ }
852
+ else {
853
+ log_1.log.info(`CacheMode is ${cacheMode}, and we are using materialized swapRoute`);
854
+ uniswapFewSwapRouteRaw = swapRouteFromChain;
855
+ }
856
+ // let ringFewSwapRouteRaw: BestSwapRoute | null;
857
+ // let hitsCachedRingFewSRoute = false;
858
+ // if (cacheMode === CacheMode.Livemode && swapRouteFromRingFewCache) {
859
+ // log.info(
860
+ // `CacheMode is ${cacheMode}, and we are using swapRoute from cache`
861
+ // );
862
+ // hitsCachedRingFewSRoute = true;
863
+ // ringFewSwapRouteRaw = swapRouteFromRingFewCache;
864
+ // } else {
865
+ // log.info(
866
+ // `CacheMode is ${cacheMode}, and we are using materialized swapRoute`
867
+ // );
868
+ // ringFewSwapRouteRaw = swapRouteFromRingFewChain;
869
+ // }
870
+ (0, simple_perf_tracker_1.startTimer)('alpha-router.route.tapcompareCachedRoute');
871
+ if (cacheMode === providers_2.CacheMode.Tapcompare &&
872
+ swapRouteFromCache &&
873
+ swapRouteFromChain) {
874
+ const quoteDiff = swapRouteFromChain.quote.subtract(swapRouteFromCache.quote);
875
+ const quoteGasAdjustedDiff = swapRouteFromChain.quoteGasAdjusted.subtract(swapRouteFromCache.quoteGasAdjusted);
876
+ const gasUsedDiff = swapRouteFromChain.estimatedGasUsed.sub(swapRouteFromCache.estimatedGasUsed);
877
+ // Only log if quoteDiff is different from 0, or if quoteGasAdjustedDiff and gasUsedDiff are both different from 0
878
+ if (!quoteDiff.equalTo(0) ||
879
+ !(quoteGasAdjustedDiff.equalTo(0) || gasUsedDiff.eq(0))) {
880
+ try {
881
+ // Calculates the percentage of the difference with respect to the quoteFromChain (not from cache)
882
+ const misquotePercent = quoteGasAdjustedDiff
883
+ .divide(swapRouteFromChain.quoteGasAdjusted)
884
+ .multiply(100);
885
+ metric_1.metric.putMetric(`TapcompareCachedRoute_quoteGasAdjustedDiffPercent`, Number(misquotePercent.toExact()), metric_1.MetricLoggerUnit.Percent);
886
+ log_1.log.warn({
887
+ quoteFromChain: swapRouteFromChain.quote.toExact(),
888
+ quoteFromCache: swapRouteFromCache.quote.toExact(),
889
+ quoteDiff: quoteDiff.toExact(),
890
+ quoteGasAdjustedFromChain: swapRouteFromChain.quoteGasAdjusted.toExact(),
891
+ quoteGasAdjustedFromCache: swapRouteFromCache.quoteGasAdjusted.toExact(),
892
+ quoteGasAdjustedDiff: quoteGasAdjustedDiff.toExact(),
893
+ gasUsedFromChain: swapRouteFromChain.estimatedGasUsed.toString(),
894
+ gasUsedFromCache: swapRouteFromCache.estimatedGasUsed.toString(),
895
+ gasUsedDiff: gasUsedDiff.toString(),
896
+ routesFromChain: swapRouteFromChain.routes.toString(),
897
+ routesFromCache: swapRouteFromCache.routes.toString(),
898
+ amount: amount.toExact(),
899
+ originalAmount: cachedRoutes === null || cachedRoutes === void 0 ? void 0 : cachedRoutes.originalAmount,
900
+ pair: this.tokenPairSymbolTradeTypeChainId(currencyIn, currencyOut, tradeType),
901
+ blockNumber,
902
+ }, `Comparing quotes between Chain and Cache for ${this.tokenPairSymbolTradeTypeChainId(currencyIn, currencyOut, tradeType)}`);
903
+ }
904
+ catch (error) {
905
+ // This is in response to the 'division by zero' error
906
+ // during https://uniswapteam.slack.com/archives/C059TGEC57W/p1723997015399579
907
+ if (error instanceof RangeError &&
908
+ error.message.includes('Division by zero')) {
909
+ log_1.log.error({
910
+ quoteGasAdjustedDiff: quoteGasAdjustedDiff.toExact(),
911
+ swapRouteFromChainQuoteGasAdjusted: swapRouteFromChain.quoteGasAdjusted.toExact(),
912
+ }, 'Error calculating misquote percent');
913
+ metric_1.metric.putMetric(`TapcompareCachedRoute_quoteGasAdjustedDiffPercent_divzero`, 1, metric_1.MetricLoggerUnit.Count);
914
+ }
915
+ // Log but don't throw here - this is only for logging.
916
+ }
917
+ }
918
+ }
919
+ (0, simple_perf_tracker_1.endTimer)('alpha-router.route.tapcompareCachedRoute');
920
+ if (!swapRouteRaw && !uniswapFewSwapRouteRaw) {
921
+ return null;
922
+ }
923
+ // Use either swapRouteRaw or uniswapFewSwapRouteRaw as the source of route data
924
+ // We already checked above that at least one is non-null, so we can safely assert non-null
925
+ const routeSource = swapRouteRaw;
926
+ // Now we can safely destructure since routeSource is guaranteed to be non-null
927
+ const { quote, quoteGasAdjusted, estimatedGasUsed, routes: routeAmounts, estimatedGasUsedQuoteToken, estimatedGasUsedUSD, estimatedGasUsedGasToken, } = routeSource;
928
+ metric_1.metric.putMetric(`QuoteFoundForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
929
+ // Build Trade object that represents the optimal swap.
930
+ const trade = (0, methodParameters_1.buildTrade)(currencyIn, fewTokenIn, currencyOut, fewTokenOut, tradeType, routeAmounts);
931
+ let methodParameters;
932
+ // If user provided recipient, deadline etc. we also generate the calldata required to execute
933
+ // the swap and return it too.
934
+ if (swapConfig) {
935
+ methodParameters = (0, methodParameters_1.buildSwapMethodParameters)(trade, swapConfig, this.chainId);
936
+ }
937
+ const tokenOutAmount = tradeType === sdk_core_1.TradeType.EXACT_OUTPUT
938
+ ? originalAmount // we need to pass in originalAmount instead of amount, because amount already added portionAmount in case of exact out swap
939
+ : quote;
940
+ const portionAmount = this.portionProvider.getPortionAmount(tokenOutAmount, tradeType, feeTakenOnTransfer, externalTransferFailed, swapConfig);
941
+ 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
942
+ portionAmount);
943
+ // we need to correct quote and quote gas adjusted for exact output when portion is part of the exact out swap
944
+ const correctedQuote = this.portionProvider.getQuote(tradeType, quote, portionQuoteAmount);
945
+ const correctedQuoteGasAdjusted = this.portionProvider.getQuoteGasAdjusted(tradeType, quoteGasAdjusted, portionQuoteAmount);
946
+ const quoteGasAndPortionAdjusted = this.portionProvider.getQuoteGasAndPortionAdjusted(tradeType, quoteGasAdjusted, portionAmount);
947
+ const swapRoute = {
948
+ quote: correctedQuote,
949
+ quoteGasAdjusted: correctedQuoteGasAdjusted,
950
+ estimatedGasUsed,
951
+ estimatedGasUsedQuoteToken,
952
+ estimatedGasUsedUSD,
953
+ estimatedGasUsedGasToken,
954
+ gasPriceWei,
955
+ route: routeAmounts,
956
+ trade,
957
+ methodParameters,
958
+ blockNumber: bignumber_1.BigNumber.from(await blockNumber),
959
+ hitsCachedRoute: hitsCachedRoute,
960
+ portionAmount: portionAmount,
961
+ quoteGasAndPortionAdjusted: quoteGasAndPortionAdjusted,
962
+ };
963
+ if (swapConfig &&
964
+ swapConfig.simulate &&
965
+ methodParameters &&
966
+ methodParameters.calldata) {
967
+ if (!this.simulator) {
968
+ throw new Error('Simulator not initialized!');
969
+ }
970
+ log_1.log.info(JSON.stringify({ swapConfig, methodParameters, providerConfig }, null, 2), `Starting simulation`);
971
+ const fromAddress = swapConfig.simulate.fromAddress;
972
+ const beforeSimulate = Date.now();
973
+ const swapRouteWithSimulation = await this.simulator.simulate(fromAddress, swapConfig, swapRoute, amount,
974
+ // Quote will be in WETH even if quoteCurrency is ETH
975
+ // So we init a new CurrencyAmount object here
976
+ amounts_1.CurrencyAmount.fromRawAmount(quoteCurrency, quote.quotient.toString()), providerConfig);
977
+ metric_1.metric.putMetric('SimulateTransaction', Date.now() - beforeSimulate, metric_1.MetricLoggerUnit.Milliseconds);
978
+ if (routingConfig.intent === intent_1.INTENT.CACHING) {
979
+ if (swapRouteWithSimulation.simulationStatus) {
980
+ await this.performCachingIntention(currencyIn, currencyOut, tradeType, amount, protocols, await blockNumber, routingConfig, swapRouteWithSimulation.simulationStatus, swapRouteWithSimulation.route);
981
+ }
982
+ else {
983
+ log_1.log.info('Simulation status is null');
984
+ }
985
+ }
986
+ return swapRouteWithSimulation;
987
+ }
988
+ (0, simple_perf_tracker_1.getPerfReport)();
989
+ return swapRoute;
990
+ }
991
+ /**
992
+ * Performs the caching intention for the given simulation status and route.
993
+ *
994
+ * @param currencyIn the currency in
995
+ * @param currencyOut the currency out
996
+ * @param tradeType the trade type
997
+ * @param amount the amount
998
+ * @param protocols the protocols
999
+ * @param blockNumber the block number
1000
+ * @param routingConfig the routing config
1001
+ * @param simulationStatus the simulation status
1002
+ * @param simulationRoute the simulation route
1003
+ */
1004
+ async performCachingIntention(currencyIn, currencyOut, tradeType, amount, protocols, blockNumber, routingConfig, simulationStatus, simulationRoute) {
1005
+ // due to fire and forget nature, we already take note that we should set new cached routes during the new path
1006
+ metric_1.metric.putMetric(`SetCachedRoute_NewPath`, 1, metric_1.MetricLoggerUnit.Count);
1007
+ log_1.log.info(simulationStatus, 'Simulation status');
1008
+ if (this.shouldCacheRoute(simulationStatus)) {
1009
+ const routesToCache = providers_2.CachedRoutes.fromRoutesWithValidQuotes(simulationRoute, this.chainId, currencyIn, currencyOut, protocols.sort(), blockNumber, tradeType, amount.toExact());
1010
+ await this.setCachedRoutesAndLog(amount, currencyIn, currencyOut, tradeType, 'SetCachedRoute_NewPath', routesToCache, routingConfig.cachedRoutesRouteIds);
1011
+ }
1012
+ }
1013
+ /**
1014
+ * @param simulationStatus the status of the simulation
1015
+ * @returns true if the route should be cached, false otherwise
1016
+ */
1017
+ shouldCacheRoute(simulationStatus) {
1018
+ // Do not cache the route for the following reasons:
1019
+ // 1. failed when tenderly sim failed for unknown reason
1020
+ // 2. slippage since we know swap is bound to fail
1021
+ // 3. transfer from failed since we know swap is bound to fail
1022
+ return (simulationStatus !== providers_2.SimulationStatus.Failed &&
1023
+ simulationStatus !== providers_2.SimulationStatus.SlippageTooLow &&
1024
+ simulationStatus !== providers_2.SimulationStatus.TransferFromFailed);
1025
+ }
1026
+ async setCachedRoutesAndLog(amount, currencyIn, currencyOut, tradeType, metricsPrefix, routesToCache, cachedRoutesRouteIds) {
1027
+ var _a;
1028
+ if (routesToCache) {
1029
+ const cachedRoutesChanged = cachedRoutesRouteIds !== undefined &&
1030
+ // it's possible that top cached routes may be split routes,
1031
+ // so that we always serialize all the top 8 retrieved cached routes vs the top routes.
1032
+ !cachedRoutesRouteIds.startsWith((0, serializeRouteIds_1.serializeRouteIds)(routesToCache.routes.map((r) => r.routeId)));
1033
+ if (cachedRoutesChanged) {
1034
+ metric_1.metric.putMetric('cachedRoutesChanged', 1, metric_1.MetricLoggerUnit.Count);
1035
+ metric_1.metric.putMetric(`cachedRoutesChanged_chainId${currencyIn.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
1036
+ metric_1.metric.putMetric(`cachedRoutesChanged_chainId${currencyOut.chainId}_pair${currencyIn.symbol}${currencyOut.symbol}`, 1, metric_1.MetricLoggerUnit.Count);
1037
+ }
1038
+ else {
1039
+ metric_1.metric.putMetric('cachedRoutesNotChanged', 1, metric_1.MetricLoggerUnit.Count);
1040
+ metric_1.metric.putMetric(`cachedRoutesNotChanged_chainId${currencyIn.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
1041
+ metric_1.metric.putMetric(`cachedRoutesNotChanged_chainId${currencyOut.chainId}_pair${currencyIn.symbol}${currencyOut.symbol}`, 1, metric_1.MetricLoggerUnit.Count);
1042
+ }
1043
+ await ((_a = this.routeCachingProvider) === null || _a === void 0 ? void 0 : _a.setCachedRoute(routesToCache, amount).then((success) => {
1044
+ const status = success ? 'success' : 'rejected';
1045
+ metric_1.metric.putMetric(`${metricsPrefix}_${status}`, 1, metric_1.MetricLoggerUnit.Count);
1046
+ }).catch((reason) => {
1047
+ log_1.log.error({
1048
+ reason: reason,
1049
+ tokenPair: this.tokenPairSymbolTradeTypeChainId(currencyIn, currencyOut, tradeType),
1050
+ }, `SetCachedRoute failure`);
1051
+ metric_1.metric.putMetric(`${metricsPrefix}_failure`, 1, metric_1.MetricLoggerUnit.Count);
1052
+ }));
1053
+ }
1054
+ else {
1055
+ metric_1.metric.putMetric(`${metricsPrefix}_unnecessary`, 1, metric_1.MetricLoggerUnit.Count);
1056
+ }
1057
+ }
1058
+ async getSwapRouteFromCache(currencyIn, currencyOut, cachedRoutes, blockNumber, amount, fewAmount, quoteCurrency, fewQuoteToken, tradeType, routingConfig, v3GasModel, v4GasModel, mixedRouteGasModel, gasPriceWei, v2GasModel, swapConfig, providerConfig) {
1059
+ var _a, _c, _d, _e, _f, _g;
1060
+ const tokenPairProperties = await this.tokenPropertiesProvider.getTokensProperties([currencyIn, currencyOut], providerConfig);
1061
+ const sellTokenIsFot = (_d = (_c = (_a = tokenPairProperties[(0, util_1.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);
1062
+ const buyTokenIsFot = (_g = (_f = (_e = tokenPairProperties[(0, util_1.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);
1063
+ const fotInDirectSwap = sellTokenIsFot || buyTokenIsFot;
1064
+ log_1.log.info({
1065
+ protocols: cachedRoutes.protocolsCovered,
1066
+ tradeType: cachedRoutes.tradeType,
1067
+ cachedBlockNumber: cachedRoutes.blockNumber,
1068
+ quoteBlockNumber: blockNumber,
1069
+ }, 'Routing across CachedRoute');
1070
+ const quotePromises = [];
1071
+ const v4Routes = cachedRoutes.routes.filter((route) => route.protocol === router_sdk_1.Protocol.V4);
1072
+ const v3Routes = cachedRoutes.routes.filter((route) => route.protocol === router_sdk_1.Protocol.V3);
1073
+ const v2Routes = cachedRoutes.routes.filter((route) => route.protocol === router_sdk_1.Protocol.V2);
1074
+ const ringFewV2Routes = cachedRoutes.routes.filter((route) => route.protocol === router_sdk_1.Protocol.FEWV2);
1075
+ const mixedRoutes = cachedRoutes.routes.filter((route) => route.protocol === router_sdk_1.Protocol.MIXED);
1076
+ let percents;
1077
+ let amounts;
1078
+ if (cachedRoutes.routes.length > 1) {
1079
+ // If we have more than 1 route, we will quote the different percents for it, following the regular process
1080
+ [percents, amounts] = this.getAmountDistribution(amount, routingConfig);
1081
+ }
1082
+ else if (cachedRoutes.routes.length == 1) {
1083
+ [percents, amounts] = [[100], [amount]];
1084
+ }
1085
+ else {
1086
+ // In this case this means that there's no route, so we return null
1087
+ return Promise.resolve(null);
1088
+ }
1089
+ let fewPercents;
1090
+ let fewAmounts;
1091
+ if (cachedRoutes.routes.length > 1) {
1092
+ // If we have more than 1 route, we will quote the different percents for it, following the regular process
1093
+ [fewPercents, fewAmounts] = this.getAmountDistribution(fewAmount, routingConfig);
1094
+ }
1095
+ else if (cachedRoutes.routes.length == 1) {
1096
+ [fewPercents, fewAmounts] = [[100], [fewAmount]];
1097
+ }
1098
+ else {
1099
+ // In this case this means that there's no route, so we return null
1100
+ return Promise.resolve(null);
1101
+ }
1102
+ if (v4Routes.length > 0) {
1103
+ const v4RoutesFromCache = v4Routes.map((cachedRoute) => cachedRoute.route);
1104
+ metric_1.metric.putMetric('SwapRouteFromCache_V4_GetQuotes_Request', 1, metric_1.MetricLoggerUnit.Count);
1105
+ const beforeGetQuotes = Date.now();
1106
+ quotePromises.push(this.v4Quoter
1107
+ .getQuotes(v4RoutesFromCache, amounts, percents, quoteCurrency, tradeType, routingConfig, undefined, v4GasModel)
1108
+ .then((result) => {
1109
+ metric_1.metric.putMetric(`SwapRouteFromCache_V4_GetQuotes_Load`, Date.now() - beforeGetQuotes, metric_1.MetricLoggerUnit.Milliseconds);
1110
+ return result;
1111
+ }));
1112
+ }
1113
+ if (!fotInDirectSwap) {
1114
+ if (v3Routes.length > 0) {
1115
+ const v3RoutesFromCache = v3Routes.map((cachedRoute) => cachedRoute.route);
1116
+ metric_1.metric.putMetric('SwapRouteFromCache_V3_GetQuotes_Request', 1, metric_1.MetricLoggerUnit.Count);
1117
+ const beforeGetQuotes = Date.now();
1118
+ quotePromises.push(this.v3Quoter
1119
+ .getQuotes(v3RoutesFromCache, amounts, percents, quoteCurrency.wrapped, tradeType, routingConfig, undefined, v3GasModel)
1120
+ .then((result) => {
1121
+ metric_1.metric.putMetric(`SwapRouteFromCache_V3_GetQuotes_Load`, Date.now() - beforeGetQuotes, metric_1.MetricLoggerUnit.Milliseconds);
1122
+ return result;
1123
+ }));
1124
+ }
1125
+ }
1126
+ if (v2Routes.length > 0) {
1127
+ const v2RoutesFromCache = v2Routes.map((cachedRoute) => cachedRoute.route);
1128
+ metric_1.metric.putMetric('SwapRouteFromCache_V2_GetQuotes_Request', 1, metric_1.MetricLoggerUnit.Count);
1129
+ const beforeGetQuotes = Date.now();
1130
+ quotePromises.push(this.v2Quoter
1131
+ .refreshRoutesThenGetQuotes(cachedRoutes.currencyIn.wrapped, cachedRoutes.currencyOut.wrapped, v2RoutesFromCache, amounts, percents, quoteCurrency.wrapped, tradeType, routingConfig, gasPriceWei)
1132
+ .then((result) => {
1133
+ metric_1.metric.putMetric(`SwapRouteFromCache_V2_GetQuotes_Load`, Date.now() - beforeGetQuotes, metric_1.MetricLoggerUnit.Milliseconds);
1134
+ return result;
1135
+ }));
1136
+ }
1137
+ if (ringFewV2Routes.length > 0) {
1138
+ const ringFewV2RoutesFromCache = ringFewV2Routes.map((cachedRoute) => cachedRoute.route);
1139
+ metric_1.metric.putMetric('SwapRouteFromCache_RingFewV2_GetQuotes_Request', 1, metric_1.MetricLoggerUnit.Count);
1140
+ const beforeGetQuotes = Date.now();
1141
+ quotePromises.push(this.ringFewV2Quoter
1142
+ .refreshRoutesThenGetQuotes(cachedRoutes.currencyIn.wrapped, cachedRoutes.currencyOut.wrapped, ringFewV2RoutesFromCache, fewAmounts, fewPercents, fewQuoteToken.wrapped, tradeType, routingConfig, gasPriceWei)
1143
+ .then((result) => {
1144
+ metric_1.metric.putMetric(`SwapRouteFromCache_RingFewV2_GetQuotes_Load`, Date.now() - beforeGetQuotes, metric_1.MetricLoggerUnit.Milliseconds);
1145
+ return result;
1146
+ }));
1147
+ }
1148
+ if (!fotInDirectSwap) {
1149
+ if (mixedRoutes.length > 0) {
1150
+ const mixedRoutesFromCache = mixedRoutes.map((cachedRoute) => cachedRoute.route);
1151
+ metric_1.metric.putMetric('SwapRouteFromCache_Mixed_GetQuotes_Request', 1, metric_1.MetricLoggerUnit.Count);
1152
+ const beforeGetQuotes = Date.now();
1153
+ quotePromises.push(this.mixedQuoter
1154
+ .getQuotes(mixedRoutesFromCache, amounts, percents, quoteCurrency.wrapped, tradeType, routingConfig, undefined, mixedRouteGasModel)
1155
+ .then((result) => {
1156
+ metric_1.metric.putMetric(`SwapRouteFromCache_Mixed_GetQuotes_Load`, Date.now() - beforeGetQuotes, metric_1.MetricLoggerUnit.Milliseconds);
1157
+ return result;
1158
+ }));
1159
+ }
1160
+ }
1161
+ const getQuotesResults = await Promise.all(quotePromises);
1162
+ const allRoutesWithValidQuotes = lodash_1.default.flatMap(getQuotesResults, (quoteResult) => quoteResult.routesWithValidQuotes);
1163
+ return (0, best_swap_route_1.getBestSwapRoute)(amount, percents, allRoutesWithValidQuotes, tradeType, this.chainId, routingConfig, this.portionProvider, v2GasModel, v3GasModel, v4GasModel, swapConfig, providerConfig);
1164
+ }
1165
+ async getUniswapFewTokenSwapRouteFromCache(fewTokenIn, fewTokenOut, fewCachedRoutes, blockNumber, amount, fewAmount, quoteCurrency, fewQuoteToken, tradeType, routingConfig, v3GasModel, v4GasModel, mixedRouteGasModel, gasPriceWei, v2GasModel, swapConfig, providerConfig) {
1166
+ var _a, _c, _d, _e, _f, _g;
1167
+ const tokenPairProperties = await this.tokenPropertiesProvider.getTokensProperties([fewTokenIn, fewTokenOut], providerConfig);
1168
+ const sellTokenIsFot = (_d = (_c = (_a = tokenPairProperties[(0, util_1.getAddressLowerCase)(fewTokenIn)]) === 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);
1169
+ const buyTokenIsFot = (_g = (_f = (_e = tokenPairProperties[(0, util_1.getAddressLowerCase)(fewTokenOut)]) === 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);
1170
+ const fotInDirectSwap = sellTokenIsFot || buyTokenIsFot;
1171
+ log_1.log.info({
1172
+ protocols: fewCachedRoutes.protocolsCovered,
1173
+ tradeType: fewCachedRoutes.tradeType,
1174
+ cachedBlockNumber: fewCachedRoutes.blockNumber,
1175
+ quoteBlockNumber: blockNumber,
1176
+ }, 'Routing across CachedRoute');
1177
+ const quotePromises = [];
1178
+ const v4Routes = fewCachedRoutes.routes.filter((route) => route.protocol === router_sdk_1.Protocol.V4);
1179
+ const v3Routes = fewCachedRoutes.routes.filter((route) => route.protocol === router_sdk_1.Protocol.V3);
1180
+ const v2Routes = fewCachedRoutes.routes.filter((route) => route.protocol === router_sdk_1.Protocol.V2);
1181
+ const ringFewV2Routes = fewCachedRoutes.routes.filter((route) => route.protocol === router_sdk_1.Protocol.FEWV2);
1182
+ const mixedRoutes = fewCachedRoutes.routes.filter((route) => route.protocol === router_sdk_1.Protocol.MIXED);
1183
+ let percents;
1184
+ let amounts;
1185
+ if (fewCachedRoutes.routes.length > 1) {
1186
+ // If we have more than 1 route, we will quote the different percents for it, following the regular process
1187
+ [percents, amounts] = this.getAmountDistribution(amount, routingConfig);
1188
+ }
1189
+ else if (fewCachedRoutes.routes.length == 1) {
1190
+ [percents, amounts] = [[100], [amount]];
1191
+ }
1192
+ else {
1193
+ // In this case this means that there's no route, so we return null
1194
+ return Promise.resolve(null);
1195
+ }
1196
+ let fewPercents;
1197
+ let fewAmounts;
1198
+ if (fewCachedRoutes.routes.length > 1) {
1199
+ // If we have more than 1 route, we will quote the different percents for it, following the regular process
1200
+ [fewPercents, fewAmounts] = this.getAmountDistribution(fewAmount, routingConfig);
1201
+ }
1202
+ else if (fewCachedRoutes.routes.length == 1) {
1203
+ [fewPercents, fewAmounts] = [[100], [fewAmount]];
1204
+ }
1205
+ else {
1206
+ // In this case this means that there's no route, so we return null
1207
+ return Promise.resolve(null);
1208
+ }
1209
+ if (v4Routes.length > 0) {
1210
+ const v4RoutesFromCache = v4Routes.map((cachedRoute) => cachedRoute.route);
1211
+ metric_1.metric.putMetric('SwapRouteFromCache_V4_GetQuotes_Request', 1, metric_1.MetricLoggerUnit.Count);
1212
+ const beforeGetQuotes = Date.now();
1213
+ quotePromises.push(this.v4Quoter
1214
+ .getQuotes(v4RoutesFromCache, amounts, percents, quoteCurrency, tradeType, routingConfig, undefined, v4GasModel)
1215
+ .then((result) => {
1216
+ metric_1.metric.putMetric(`SwapRouteFromCache_V4_GetQuotes_Load`, Date.now() - beforeGetQuotes, metric_1.MetricLoggerUnit.Milliseconds);
1217
+ return result;
1218
+ }));
1219
+ }
1220
+ if (!fotInDirectSwap) {
1221
+ if (v3Routes.length > 0) {
1222
+ const v3RoutesFromCache = v3Routes.map((cachedRoute) => cachedRoute.route);
1223
+ metric_1.metric.putMetric('SwapRouteFromCache_V3_GetQuotes_Request', 1, metric_1.MetricLoggerUnit.Count);
1224
+ const beforeGetQuotes = Date.now();
1225
+ quotePromises.push(this.v3Quoter
1226
+ .getQuotes(v3RoutesFromCache, amounts, percents, quoteCurrency.wrapped, tradeType, routingConfig, undefined, v3GasModel)
1227
+ .then((result) => {
1228
+ metric_1.metric.putMetric(`SwapRouteFromCache_V3_GetQuotes_Load`, Date.now() - beforeGetQuotes, metric_1.MetricLoggerUnit.Milliseconds);
1229
+ return result;
1230
+ }));
1231
+ }
1232
+ }
1233
+ if (v2Routes.length > 0) {
1234
+ const v2RoutesFromCache = v2Routes.map((cachedRoute) => cachedRoute.route);
1235
+ metric_1.metric.putMetric('SwapRouteFromCache_V2_GetQuotes_Request', 1, metric_1.MetricLoggerUnit.Count);
1236
+ const beforeGetQuotes = Date.now();
1237
+ quotePromises.push(this.v2Quoter
1238
+ .refreshRoutesThenGetQuotes(fewCachedRoutes.currencyIn.wrapped, fewCachedRoutes.currencyOut.wrapped, v2RoutesFromCache, amounts, percents, quoteCurrency.wrapped, tradeType, routingConfig, gasPriceWei)
1239
+ .then((result) => {
1240
+ metric_1.metric.putMetric(`SwapRouteFromCache_V2_GetQuotes_Load`, Date.now() - beforeGetQuotes, metric_1.MetricLoggerUnit.Milliseconds);
1241
+ return result;
1242
+ }));
1243
+ }
1244
+ if (ringFewV2Routes.length > 0) {
1245
+ const ringFewV2RoutesFromCache = ringFewV2Routes.map((cachedRoute) => cachedRoute.route);
1246
+ metric_1.metric.putMetric('SwapRouteFromCache_RingFewV2_GetQuotes_Request', 1, metric_1.MetricLoggerUnit.Count);
1247
+ const beforeGetQuotes = Date.now();
1248
+ quotePromises.push(this.ringFewV2Quoter
1249
+ .refreshRoutesThenGetQuotes(fewCachedRoutes.currencyIn.wrapped, fewCachedRoutes.currencyOut.wrapped, ringFewV2RoutesFromCache, fewAmounts, fewPercents, fewQuoteToken.wrapped, tradeType, routingConfig, gasPriceWei)
1250
+ .then((result) => {
1251
+ metric_1.metric.putMetric(`SwapRouteFromCache_RingFewV2_GetQuotes_Load`, Date.now() - beforeGetQuotes, metric_1.MetricLoggerUnit.Milliseconds);
1252
+ return result;
1253
+ }));
1254
+ }
1255
+ if (!fotInDirectSwap) {
1256
+ if (mixedRoutes.length > 0) {
1257
+ const mixedRoutesFromCache = mixedRoutes.map((cachedRoute) => cachedRoute.route);
1258
+ metric_1.metric.putMetric('SwapRouteFromCache_Mixed_GetQuotes_Request', 1, metric_1.MetricLoggerUnit.Count);
1259
+ const beforeGetQuotes = Date.now();
1260
+ quotePromises.push(this.mixedQuoter
1261
+ .getQuotes(mixedRoutesFromCache, amounts, percents, quoteCurrency.wrapped, tradeType, routingConfig, undefined, mixedRouteGasModel)
1262
+ .then((result) => {
1263
+ metric_1.metric.putMetric(`SwapRouteFromCache_Mixed_GetQuotes_Load`, Date.now() - beforeGetQuotes, metric_1.MetricLoggerUnit.Milliseconds);
1264
+ return result;
1265
+ }));
1266
+ }
1267
+ }
1268
+ const getQuotesResults = await Promise.all(quotePromises);
1269
+ const allRoutesWithValidQuotes = lodash_1.default.flatMap(getQuotesResults, (quoteResult) => quoteResult.routesWithValidQuotes);
1270
+ return (0, best_swap_route_1.getBestSwapRoute)(amount, percents, allRoutesWithValidQuotes, tradeType, this.chainId, routingConfig, this.portionProvider, v2GasModel, v3GasModel, v4GasModel, swapConfig, providerConfig);
1271
+ }
1272
+ async getSwapRouteFromChain(amount, fewAmount, currencyIn, fewTokenIn, currencyOut, fewTokenOut, protocols, quoteCurrency, fewQuoteToken, tradeType, routingConfig, v3GasModel, v4GasModel, mixedRouteGasModel, gasPriceWei, v2GasModel, ringFewV2GasModel, swapConfig, providerConfig) {
1273
+ var _a, _c, _d, _e, _f, _g, _h, _j, _k, _l;
1274
+ const tokenPairProperties = await this.tokenPropertiesProvider.getTokensProperties([currencyIn, currencyOut], providerConfig);
1275
+ if (!swapConfig) {
1276
+ //
1277
+ }
1278
+ // const fewTokenPairProperties =
1279
+ // await this.tokenPropertiesProvider.getTokensProperties(
1280
+ // [fewTokenIn, fewTokenOut],
1281
+ // providerConfig
1282
+ // );
1283
+ const sellTokenIsFot = (_d = (_c = (_a = tokenPairProperties[(0, util_1.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);
1284
+ const buyTokenIsFot = (_g = (_f = (_e = tokenPairProperties[(0, util_1.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);
1285
+ const fotInDirectSwap = sellTokenIsFot || buyTokenIsFot;
1286
+ // const sellTokenIsFewFot =
1287
+ // fewTokenPairProperties[
1288
+ // getAddressLowerCase(fewTokenIn)
1289
+ // ]?.tokenFeeResult?.sellFeeBps?.gt(0);
1290
+ // const buyTokenIsFewFot =
1291
+ // fewTokenPairProperties[
1292
+ // getAddressLowerCase(fewTokenOut)
1293
+ // ]?.tokenFeeResult?.buyFeeBps?.gt(0);
1294
+ // const fewFotInDirectSwap = sellTokenIsFewFot || buyTokenIsFewFot;
1295
+ // Generate our distribution of amounts, i.e. fractions of the input amount.
1296
+ // We will get quotes for fractions of the input amount for different routes, then
1297
+ // combine to generate split routes.
1298
+ const [percents, amounts] = this.getAmountDistribution(amount, routingConfig);
1299
+ const [fewPercents, fewAmounts] = this.getAmountDistribution(fewAmount, routingConfig);
1300
+ const noProtocolsSpecified = protocols.length === 0;
1301
+ const v4ProtocolSpecified = protocols.includes(router_sdk_1.Protocol.V4);
1302
+ const v3ProtocolSpecified = protocols.includes(router_sdk_1.Protocol.V3);
1303
+ const v2ProtocolSpecified = protocols.includes(router_sdk_1.Protocol.V2);
1304
+ const ringFewV2ProtocolSpecified = protocols.includes(router_sdk_1.Protocol.FEWV2);
1305
+ const v2SupportedInChain = (_h = this.v2Supported) === null || _h === void 0 ? void 0 : _h.includes(this.chainId);
1306
+ const ringFewV2SupportedInChain = (_j = this.ringFewV2Supported) === null || _j === void 0 ? void 0 : _j.includes(this.chainId);
1307
+ const v4SupportedInChain = (_k = this.v4Supported) === null || _k === void 0 ? void 0 : _k.includes(this.chainId);
1308
+ const shouldQueryMixedProtocol = protocols.includes(router_sdk_1.Protocol.MIXED) ||
1309
+ (noProtocolsSpecified && v2SupportedInChain && ringFewV2SupportedInChain && v4SupportedInChain);
1310
+ // const shouldQueryRingFewV2Protocol =
1311
+ // protocols.includes(Protocol.FEWV2) ||
1312
+ // (noProtocolsSpecified && ringFewV2SupportedInChain);
1313
+ const mixedProtocolAllowed = ((_l = this.mixedSupported) === null || _l === void 0 ? void 0 : _l.includes(this.chainId)) &&
1314
+ tradeType === sdk_core_1.TradeType.EXACT_INPUT;
1315
+ const beforeGetCandidates = Date.now();
1316
+ let v4CandidatePoolsPromise = Promise.resolve(undefined);
1317
+ // we are explicitly requiring people to specify v4 for now
1318
+ if (v4SupportedInChain && (v4ProtocolSpecified || noProtocolsSpecified)) {
1319
+ // if (v4ProtocolSpecified || noProtocolsSpecified) {
1320
+ v4CandidatePoolsPromise = (0, get_candidate_pools_1.getV4CandidatePools)({
1321
+ currencyIn: currencyIn,
1322
+ currencyOut: currencyOut,
1323
+ tokenProvider: this.tokenProvider,
1324
+ blockedTokenListProvider: this.blockedTokenListProvider,
1325
+ poolProvider: this.v4PoolProvider,
1326
+ routeType: tradeType,
1327
+ subgraphProvider: this.v4SubgraphProvider,
1328
+ routingConfig,
1329
+ chainId: this.chainId,
1330
+ v4PoolParams: this.v4PoolParams,
1331
+ }).then((candidatePools) => {
1332
+ metric_1.metric.putMetric('GetV4CandidatePools', Date.now() - beforeGetCandidates, metric_1.MetricLoggerUnit.Milliseconds);
1333
+ return candidatePools;
1334
+ });
1335
+ }
1336
+ let v3CandidatePoolsPromise = Promise.resolve(undefined);
1337
+ if (!fotInDirectSwap) {
1338
+ if (v3ProtocolSpecified || noProtocolsSpecified) {
1339
+ const tokenIn = currencyIn.wrapped;
1340
+ const tokenOut = currencyOut.wrapped;
1341
+ v3CandidatePoolsPromise = (0, get_candidate_pools_1.getV3CandidatePools)({
1342
+ tokenIn,
1343
+ tokenOut,
1344
+ tokenProvider: this.tokenProvider,
1345
+ blockedTokenListProvider: this.blockedTokenListProvider,
1346
+ poolProvider: this.v3PoolProvider,
1347
+ routeType: tradeType,
1348
+ subgraphProvider: this.v3SubgraphProvider,
1349
+ routingConfig,
1350
+ chainId: this.chainId,
1351
+ }).then((candidatePools) => {
1352
+ metric_1.metric.putMetric('GetV3CandidatePools', Date.now() - beforeGetCandidates, metric_1.MetricLoggerUnit.Milliseconds);
1353
+ return candidatePools;
1354
+ });
1355
+ }
1356
+ }
1357
+ let v2CandidatePoolsPromise = Promise.resolve(undefined);
1358
+ if (v2SupportedInChain && (v2ProtocolSpecified || noProtocolsSpecified)) {
1359
+ const tokenIn = currencyIn.wrapped;
1360
+ const tokenOut = currencyOut.wrapped;
1361
+ // Fetch all the pools that we will consider routing via. There are thousands
1362
+ // of pools, so we filter them to a set of candidate pools that we expect will
1363
+ // result in good prices.
1364
+ v2CandidatePoolsPromise = (0, get_candidate_pools_1.getV2CandidatePools)({
1365
+ tokenIn,
1366
+ tokenOut,
1367
+ tokenProvider: this.tokenProvider,
1368
+ blockedTokenListProvider: this.blockedTokenListProvider,
1369
+ poolProvider: this.v2PoolProvider,
1370
+ routeType: tradeType,
1371
+ subgraphProvider: this.v2SubgraphProvider,
1372
+ routingConfig,
1373
+ chainId: this.chainId,
1374
+ }).then((candidatePools) => {
1375
+ metric_1.metric.putMetric('GetV2CandidatePools', Date.now() - beforeGetCandidates, metric_1.MetricLoggerUnit.Milliseconds);
1376
+ return candidatePools;
1377
+ });
1378
+ }
1379
+ let ringFewV2CandidatePoolsPromise = Promise.resolve(undefined);
1380
+ if (ringFewV2SupportedInChain && (ringFewV2ProtocolSpecified || noProtocolsSpecified)) {
1381
+ const tokenIn = fewTokenIn;
1382
+ const tokenOut = fewTokenOut;
1383
+ ringFewV2CandidatePoolsPromise = (0, get_candidate_pools_1.getRingFewV2CandidatePools)({
1384
+ tokenIn,
1385
+ tokenOut,
1386
+ tokenProvider: this.tokenProvider,
1387
+ blockedTokenListProvider: this.blockedTokenListProvider,
1388
+ poolProvider: this.ringFewV2PoolProvider,
1389
+ routeType: tradeType,
1390
+ subgraphProvider: this.ringFewV2SubgraphProvider,
1391
+ routingConfig,
1392
+ chainId: this.chainId,
1393
+ }).then((candidatePools) => {
1394
+ metric_1.metric.putMetric('GetRingFewV2CandidatePools', Date.now() - beforeGetCandidates, metric_1.MetricLoggerUnit.Milliseconds);
1395
+ return candidatePools;
1396
+ });
1397
+ }
1398
+ const quotePromises = [];
1399
+ // for v4, for now we explicitly require people to specify
1400
+ if (v4SupportedInChain && v4ProtocolSpecified) {
1401
+ log_1.log.info({ protocols, tradeType }, 'Routing across V4');
1402
+ metric_1.metric.putMetric('SwapRouteFromChain_V4_GetRoutesThenQuotes_Request', 1, metric_1.MetricLoggerUnit.Count);
1403
+ const beforeGetRoutesThenQuotes = Date.now();
1404
+ quotePromises.push(v4CandidatePoolsPromise.then((v4CandidatePools) => this.v4Quoter
1405
+ .getRoutesThenQuotes(currencyIn, currencyOut, amount, amounts, percents, quoteCurrency, v4CandidatePools, tradeType, routingConfig, v4GasModel)
1406
+ .then((result) => {
1407
+ metric_1.metric.putMetric(`SwapRouteFromChain_V4_GetRoutesThenQuotes_Load`, Date.now() - beforeGetRoutesThenQuotes, metric_1.MetricLoggerUnit.Milliseconds);
1408
+ return result;
1409
+ })));
1410
+ }
1411
+ if (!fotInDirectSwap) {
1412
+ // Maybe Quote V3 - if V3 is specified, or no protocol is specified
1413
+ if (v3ProtocolSpecified || noProtocolsSpecified) {
1414
+ log_1.log.info({ protocols, tradeType }, 'Routing across V3');
1415
+ metric_1.metric.putMetric('SwapRouteFromChain_V3_GetRoutesThenQuotes_Request', 1, metric_1.MetricLoggerUnit.Count);
1416
+ const beforeGetRoutesThenQuotes = Date.now();
1417
+ const tokenIn = currencyIn.wrapped;
1418
+ const tokenOut = currencyOut.wrapped;
1419
+ quotePromises.push(v3CandidatePoolsPromise.then((v3CandidatePools) => this.v3Quoter
1420
+ .getRoutesThenQuotes(tokenIn, tokenOut, amount, amounts, percents, quoteCurrency.wrapped, v3CandidatePools, tradeType, routingConfig, v3GasModel)
1421
+ .then((result) => {
1422
+ metric_1.metric.putMetric(`SwapRouteFromChain_V3_GetRoutesThenQuotes_Load`, Date.now() - beforeGetRoutesThenQuotes, metric_1.MetricLoggerUnit.Milliseconds);
1423
+ return result;
1424
+ })));
1425
+ }
1426
+ }
1427
+ // Maybe Quote V2 - if V2 is specified, or no protocol is specified AND v2 is supported in this chain
1428
+ if (v2SupportedInChain && (v2ProtocolSpecified || noProtocolsSpecified)) {
1429
+ log_1.log.info({ protocols, tradeType }, 'Routing across V2');
1430
+ metric_1.metric.putMetric('SwapRouteFromChain_V2_GetRoutesThenQuotes_Request', 1, metric_1.MetricLoggerUnit.Count);
1431
+ const beforeGetRoutesThenQuotes = Date.now();
1432
+ const tokenIn = currencyIn.wrapped;
1433
+ const tokenOut = currencyOut.wrapped;
1434
+ quotePromises.push(v2CandidatePoolsPromise.then((v2CandidatePools) => this.v2Quoter
1435
+ .getRoutesThenQuotes(tokenIn, tokenOut, amount, amounts, percents, quoteCurrency.wrapped, v2CandidatePools, tradeType, routingConfig, v2GasModel, gasPriceWei)
1436
+ .then((result) => {
1437
+ metric_1.metric.putMetric(`SwapRouteFromChain_V2_GetRoutesThenQuotes_Load`, Date.now() - beforeGetRoutesThenQuotes, metric_1.MetricLoggerUnit.Milliseconds);
1438
+ return result;
1439
+ })));
1440
+ }
1441
+ // Maybe Quote RingFewV2 - if RingFewV2 is specified, or no protocol is specified AND ringFewV2 is supported in this chain
1442
+ if (ringFewV2SupportedInChain && (ringFewV2ProtocolSpecified || noProtocolsSpecified)) {
1443
+ log_1.log.info({ protocols, tradeType }, 'Routing across RingFewV2');
1444
+ metric_1.metric.putMetric('SwapRouteFromChain_RingFewV2_GetRoutesThenQuotes_Request', 1, metric_1.MetricLoggerUnit.Count);
1445
+ const beforeGetRoutesThenQuotes = Date.now();
1446
+ const tokenIn = fewTokenIn;
1447
+ const tokenOut = fewTokenOut;
1448
+ quotePromises.push(ringFewV2CandidatePoolsPromise.then((ringFewV2CandidatePools) => this.ringFewV2Quoter
1449
+ .getRoutesThenQuotes(tokenIn, tokenOut, fewAmount, fewAmounts, fewPercents, fewQuoteToken.wrapped, ringFewV2CandidatePools, tradeType, routingConfig, ringFewV2GasModel, gasPriceWei)
1450
+ .then((result) => {
1451
+ metric_1.metric.putMetric(`SwapRouteFromChain_RingFewV2_GetRoutesThenQuotes_Load`, Date.now() - beforeGetRoutesThenQuotes, metric_1.MetricLoggerUnit.Milliseconds);
1452
+ return result;
1453
+ })));
1454
+ }
1455
+ if (!fotInDirectSwap) {
1456
+ // Maybe Quote mixed routes
1457
+ // if MixedProtocol is specified or no protocol is specified and v2 is supported AND tradeType is ExactIn
1458
+ // AND is Mainnet or Gorli
1459
+ // Also make sure there are at least 2 protocols provided besides MIXED, before entering mixed quoter
1460
+ if (shouldQueryMixedProtocol &&
1461
+ mixedProtocolAllowed &&
1462
+ protocols.filter((protocol) => protocol !== router_sdk_1.Protocol.MIXED).length >= 2) {
1463
+ log_1.log.info({ protocols, tradeType }, 'Routing across MixedRoutes');
1464
+ metric_1.metric.putMetric('SwapRouteFromChain_Mixed_GetRoutesThenQuotes_Request', 1, metric_1.MetricLoggerUnit.Count);
1465
+ const beforeGetRoutesThenQuotes = Date.now();
1466
+ quotePromises.push(Promise.all([
1467
+ v4CandidatePoolsPromise,
1468
+ v3CandidatePoolsPromise,
1469
+ v2CandidatePoolsPromise,
1470
+ ringFewV2CandidatePoolsPromise,
1471
+ ]).then(async ([v4CandidatePools, v3CandidatePools, v2CandidatePools, ringFewV2CandidatePools]) => {
1472
+ const tokenIn = currencyIn.wrapped;
1473
+ const tokenOut = currencyOut.wrapped;
1474
+ const crossLiquidityPools = await (0, get_candidate_pools_1.getMixedCrossLiquidityCandidatePools)({
1475
+ tokenIn,
1476
+ tokenOut,
1477
+ blockNumber: routingConfig.blockNumber,
1478
+ v2SubgraphProvider: this.v2SubgraphProvider,
1479
+ v3SubgraphProvider: this.v3SubgraphProvider,
1480
+ v2Candidates: v2CandidatePools,
1481
+ v3Candidates: v3CandidatePools,
1482
+ v4Candidates: v4CandidatePools,
1483
+ });
1484
+ return this.mixedQuoter
1485
+ .getRoutesThenQuotes(tokenIn, tokenOut, amount, amounts, percents, quoteCurrency.wrapped, [
1486
+ v4CandidatePools,
1487
+ v3CandidatePools,
1488
+ v2CandidatePools,
1489
+ ringFewV2CandidatePools,
1490
+ crossLiquidityPools,
1491
+ ], tradeType, routingConfig, mixedRouteGasModel)
1492
+ .then((result) => {
1493
+ metric_1.metric.putMetric(`SwapRouteFromChain_Mixed_GetRoutesThenQuotes_Load`, Date.now() - beforeGetRoutesThenQuotes, metric_1.MetricLoggerUnit.Milliseconds);
1494
+ return result;
1495
+ });
1496
+ }));
1497
+ }
1498
+ }
1499
+ const getQuotesResults = await Promise.all(quotePromises);
1500
+ const allRoutesWithValidQuotes = [];
1501
+ const allCandidatePools = [];
1502
+ getQuotesResults.forEach((getQuoteResult) => {
1503
+ allRoutesWithValidQuotes.push(...getQuoteResult.routesWithValidQuotes);
1504
+ if (getQuoteResult.candidatePools) {
1505
+ allCandidatePools.push(getQuoteResult.candidatePools);
1506
+ }
1507
+ });
1508
+ if (allRoutesWithValidQuotes.length === 0) {
1509
+ log_1.log.info({ allRoutesWithValidQuotes }, 'Received no valid quotes');
1510
+ return null;
1511
+ }
1512
+ return allRoutesWithValidQuotes;
1513
+ /*
1514
+ // Given all the quotes for all the amounts for all the routes, find the best combination.
1515
+ const bestSwapRoute = await getBestSwapRoute(
1516
+ amount,
1517
+ percents,
1518
+ allRoutesWithValidQuotes,
1519
+ tradeType,
1520
+ this.chainId,
1521
+ routingConfig,
1522
+ this.portionProvider,
1523
+ v2GasModel,
1524
+ v3GasModel,
1525
+ v4GasModel,
1526
+ swapConfig,
1527
+ providerConfig
1528
+ );
1529
+
1530
+ if (bestSwapRoute) {
1531
+ this.emitPoolSelectionMetrics(
1532
+ bestSwapRoute,
1533
+ allCandidatePools,
1534
+ currencyIn,
1535
+ currencyOut
1536
+ );
1537
+ }
1538
+
1539
+ return bestSwapRoute;
1540
+ */
1541
+ }
1542
+ // for uniswap fewToken
1543
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1544
+ async getUniswapFewTokenSwapRouteFromChain(amount, fewAmount, currencyIn, fewTokenIn, currencyOut, fewTokenOut, protocols, _quoteCurrency, fewQuoteToken, tradeType, routingConfig,
1545
+ // v3GasModel: IGasModel<V3RouteWithValidQuote>,
1546
+ fewV3GasModel,
1547
+ // v4GasModel: IGasModel<V4RouteWithValidQuote>,
1548
+ fewV4GasModel, _mixedRouteGasModel, gasPriceWei, _v2GasModel, fewV2GasModel,
1549
+ // ringFewV2GasModel?: IGasModel<RingFewV2RouteWithValidQuote>,
1550
+ providerConfig) {
1551
+ var _a, _c, _d, _e, _f, _g, _h, _j, _k, _l;
1552
+ const tokenPairProperties = await this.tokenPropertiesProvider.getTokensProperties([currencyIn, currencyOut], providerConfig);
1553
+ const sellTokenIsFot = (_d = (_c = (_a = tokenPairProperties[(0, util_1.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);
1554
+ const buyTokenIsFot = (_g = (_f = (_e = tokenPairProperties[(0, util_1.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);
1555
+ const fotInDirectSwap = sellTokenIsFot || buyTokenIsFot;
1556
+ // Generate our distribution of amounts, i.e. fractions of the input amount.
1557
+ // We will get quotes for fractions of the input amount for different routes, then
1558
+ // combine to generate split routes.
1559
+ const [_amounts] = this.getAmountDistribution(amount, routingConfig);
1560
+ const [fewPercents, fewAmounts] = this.getAmountDistribution(fewAmount, routingConfig);
1561
+ // const tokenIn = fewTokenIn;
1562
+ // const tokenOut = fewTokenOut;
1563
+ const noProtocolsSpecified = protocols.length === 0;
1564
+ const v4ProtocolSpecified = protocols.includes(router_sdk_1.Protocol.V4);
1565
+ const v3ProtocolSpecified = protocols.includes(router_sdk_1.Protocol.V3);
1566
+ const v2ProtocolSpecified = protocols.includes(router_sdk_1.Protocol.V2);
1567
+ //@ts-ignore
1568
+ const _ringFewV2ProtocolSpecified = protocols.includes(router_sdk_1.Protocol.FEWV2);
1569
+ const v2SupportedInChain = (_h = this.v2Supported) === null || _h === void 0 ? void 0 : _h.includes(this.chainId);
1570
+ const ringFewV2SupportedInChain = (_j = this.ringFewV2Supported) === null || _j === void 0 ? void 0 : _j.includes(this.chainId);
1571
+ const v4SupportedInChain = (_k = this.v4Supported) === null || _k === void 0 ? void 0 : _k.includes(this.chainId);
1572
+ //@ts-ignore
1573
+ const _shouldQueryMixedProtocol = protocols.includes(router_sdk_1.Protocol.MIXED) ||
1574
+ (noProtocolsSpecified && v2SupportedInChain && ringFewV2SupportedInChain && v4SupportedInChain);
1575
+ //@ts-ignore
1576
+ const _mixedProtocolAllowed = ((_l = this.mixedSupported) === null || _l === void 0 ? void 0 : _l.includes(this.chainId)) &&
1577
+ tradeType === sdk_core_1.TradeType.EXACT_INPUT;
1578
+ const beforeGetCandidates = Date.now();
1579
+ let v4CandidatePoolsPromise = Promise.resolve(undefined);
1580
+ // we are explicitly requiring people to specify v4 for now
1581
+ if (v4SupportedInChain && (v4ProtocolSpecified || noProtocolsSpecified)) {
1582
+ // if (v4ProtocolSpecified || noProtocolsSpecified) {
1583
+ v4CandidatePoolsPromise = (0, get_candidate_pools_1.getUniswapV4FewTokenCandidatePools)({
1584
+ currencyIn: fewTokenIn,
1585
+ currencyOut: fewTokenOut,
1586
+ tokenProvider: this.tokenProvider,
1587
+ blockedTokenListProvider: this.blockedTokenListProvider,
1588
+ poolProvider: this.v4PoolProvider,
1589
+ routeType: tradeType,
1590
+ subgraphProvider: this.v4SubgraphProvider,
1591
+ routingConfig,
1592
+ chainId: this.chainId,
1593
+ v4PoolParams: this.v4PoolParams,
1594
+ }).then((candidatePools) => {
1595
+ metric_1.metric.putMetric('GetV4CandidatePools', Date.now() - beforeGetCandidates, metric_1.MetricLoggerUnit.Milliseconds);
1596
+ return candidatePools;
1597
+ });
1598
+ }
1599
+ let v3CandidatePoolsPromise = Promise.resolve(undefined);
1600
+ if (!fotInDirectSwap) {
1601
+ if (v3ProtocolSpecified || noProtocolsSpecified) {
1602
+ v3CandidatePoolsPromise = (0, get_candidate_pools_1.getUniswapFewTokenV3CandidatePools)({
1603
+ tokenIn: fewTokenIn,
1604
+ tokenOut: fewTokenOut,
1605
+ tokenProvider: this.tokenProvider,
1606
+ blockedTokenListProvider: this.blockedTokenListProvider,
1607
+ poolProvider: this.v3PoolProvider,
1608
+ routeType: tradeType,
1609
+ subgraphProvider: this.v3SubgraphProvider,
1610
+ routingConfig,
1611
+ chainId: this.chainId,
1612
+ }).then((candidatePools) => {
1613
+ metric_1.metric.putMetric('GetV3CandidatePools', Date.now() - beforeGetCandidates, metric_1.MetricLoggerUnit.Milliseconds);
1614
+ return candidatePools;
1615
+ });
1616
+ }
1617
+ }
1618
+ let v2CandidatePoolsPromise = Promise.resolve(undefined);
1619
+ if (v2SupportedInChain && (v2ProtocolSpecified || noProtocolsSpecified)) {
1620
+ // Fetch all the pools that we will consider routing via. There are thousands
1621
+ // of pools, so we filter them to a set of candidate pools that we expect will
1622
+ // result in good prices.
1623
+ v2CandidatePoolsPromise = (0, get_candidate_pools_1.getUniswapFewTokenV2CandidatePools)({
1624
+ tokenIn: fewTokenIn,
1625
+ tokenOut: fewTokenOut,
1626
+ tokenProvider: this.tokenProvider,
1627
+ blockedTokenListProvider: this.blockedTokenListProvider,
1628
+ poolProvider: this.v2PoolProvider,
1629
+ routeType: tradeType,
1630
+ subgraphProvider: this.v2SubgraphProvider,
1631
+ routingConfig,
1632
+ chainId: this.chainId,
1633
+ }).then((candidatePools) => {
1634
+ metric_1.metric.putMetric('getUniswapFewTokenV2CandidatePools', Date.now() - beforeGetCandidates, metric_1.MetricLoggerUnit.Milliseconds);
1635
+ return candidatePools;
1636
+ });
1637
+ }
1638
+ // FEWV2 这里查询的是 origin token 的 pool
1639
+ // let ringFewV2CandidatePoolsPromise: Promise<RingFewV2CandidatePools | undefined> =
1640
+ // Promise.resolve(undefined);
1641
+ // if (ringFewV2SupportedInChain && (ringFewV2ProtocolSpecified || noProtocolsSpecified)) {
1642
+ // const tokenIn = currencyIn.wrapped;
1643
+ // const tokenOut = currencyOut.wrapped;
1644
+ // ringFewV2CandidatePoolsPromise = getRingFewV2CandidatePools({
1645
+ // tokenIn,
1646
+ // tokenOut,
1647
+ // tokenProvider: this.tokenProvider,
1648
+ // blockedTokenListProvider: this.blockedTokenListProvider,
1649
+ // poolProvider: this.ringFewV2PoolProvider,
1650
+ // routeType: tradeType,
1651
+ // subgraphProvider: this.ringFewV2SubgraphProvider,
1652
+ // routingConfig,
1653
+ // chainId: this.chainId,
1654
+ // }).then((candidatePools) => {
1655
+ // metric.putMetric(
1656
+ // 'GetRingFewV2CandidatePools',
1657
+ // Date.now() - beforeGetCandidates,
1658
+ // MetricLoggerUnit.Milliseconds
1659
+ // );
1660
+ // return candidatePools;
1661
+ // });
1662
+ // }
1663
+ const quotePromises = [];
1664
+ // for v4, for now we explicitly require people to specify
1665
+ if (v4SupportedInChain && v4ProtocolSpecified) {
1666
+ log_1.log.info({ protocols, tradeType }, 'Routing across V4');
1667
+ metric_1.metric.putMetric('SwapRouteFromChain_V4_GetRoutesThenQuotes_Request', 1, metric_1.MetricLoggerUnit.Count);
1668
+ const beforeGetRoutesThenQuotes = Date.now();
1669
+ quotePromises.push(v4CandidatePoolsPromise.then((v4CandidatePools) => this.uniswapFewV4Quoter
1670
+ .getRoutesThenQuotes(fewTokenIn, fewTokenOut, fewAmount, fewAmounts, fewPercents, fewQuoteToken, v4CandidatePools, tradeType, routingConfig, fewV4GasModel)
1671
+ .then((result) => {
1672
+ metric_1.metric.putMetric(`SwapRouteFromChain_V4_GetRoutesThenQuotes_Load`, Date.now() - beforeGetRoutesThenQuotes, metric_1.MetricLoggerUnit.Milliseconds);
1673
+ return result;
1674
+ })));
1675
+ }
1676
+ if (!fotInDirectSwap) {
1677
+ // Maybe Quote V3 - if V3 is specified, or no protocol is specified
1678
+ if (v3ProtocolSpecified || noProtocolsSpecified) {
1679
+ log_1.log.info({ protocols, tradeType }, 'Routing across V3');
1680
+ metric_1.metric.putMetric('SwapRouteFromChain_V3_GetRoutesThenQuotes_Request', 1, metric_1.MetricLoggerUnit.Count);
1681
+ const beforeGetRoutesThenQuotes = Date.now();
1682
+ quotePromises.push(v3CandidatePoolsPromise.then((v3CandidatePools) => this.uniswapFewV3Quoter
1683
+ .getRoutesThenQuotes(fewTokenIn, fewTokenOut, fewAmount, fewAmounts, fewPercents, fewQuoteToken, v3CandidatePools, tradeType, routingConfig, fewV3GasModel)
1684
+ .then((result) => {
1685
+ metric_1.metric.putMetric(`SwapRouteFromChain_V3_GetRoutesThenQuotes_Load`, Date.now() - beforeGetRoutesThenQuotes, metric_1.MetricLoggerUnit.Milliseconds);
1686
+ return result;
1687
+ })));
1688
+ }
1689
+ }
1690
+ // Maybe Quote V2 - if V2 is specified, or no protocol is specified AND v2 is supported in this chain
1691
+ if (v2SupportedInChain && (v2ProtocolSpecified || noProtocolsSpecified)) {
1692
+ log_1.log.info({ protocols, tradeType }, 'Routing across V2');
1693
+ metric_1.metric.putMetric('SwapRouteFromChain_V2_GetRoutesThenQuotes_Request', 1, metric_1.MetricLoggerUnit.Count);
1694
+ const beforeGetRoutesThenQuotes = Date.now();
1695
+ quotePromises.push(v2CandidatePoolsPromise.then((v2CandidatePools) => this.v2Quoter
1696
+ .getRoutesThenQuotes(fewTokenIn, fewTokenOut, fewAmount, fewAmounts, fewPercents, fewQuoteToken, v2CandidatePools, tradeType, routingConfig, fewV2GasModel, gasPriceWei)
1697
+ .then((result) => {
1698
+ metric_1.metric.putMetric(`SwapRouteFromChain_V2_GetRoutesThenQuotes_Load`, Date.now() - beforeGetRoutesThenQuotes, metric_1.MetricLoggerUnit.Milliseconds);
1699
+ return result;
1700
+ })));
1701
+ }
1702
+ // Maybe Quote RingFewV2 - if RingFewV2 is specified, or no protocol is specified AND ringFewV2 is supported in this chain
1703
+ // if (ringFewV2SupportedInChain && (ringFewV2ProtocolSpecified || noProtocolsSpecified)) {
1704
+ // log.info({ protocols, tradeType }, 'Routing across RingFewV2');
1705
+ // metric.putMetric(
1706
+ // 'SwapRouteFromChain_RingFewV2_GetRoutesThenQuotes_Request',
1707
+ // 1,
1708
+ // MetricLoggerUnit.Count
1709
+ // );
1710
+ // const beforeGetRoutesThenQuotes = Date.now();
1711
+ // const tokenIn = currencyIn.wrapped;
1712
+ // const tokenOut = currencyOut.wrapped;
1713
+ // quotePromises.push(
1714
+ // ringFewV2CandidatePoolsPromise.then((ringFewV2CandidatePools) =>
1715
+ // this.ringFewV2Quoter
1716
+ // .getRoutesThenQuotes(
1717
+ // tokenIn,
1718
+ // tokenOut,
1719
+ // amount,
1720
+ // amounts,
1721
+ // percents,
1722
+ // quoteCurrency.wrapped,
1723
+ // ringFewV2CandidatePools!,
1724
+ // tradeType,
1725
+ // routingConfig,
1726
+ // v2GasModel,
1727
+ // gasPriceWei
1728
+ // )
1729
+ // .then((result) => {
1730
+ // metric.putMetric(
1731
+ // `SwapRouteFromChain_RingFewV2_GetRoutesThenQuotes_Load`,
1732
+ // Date.now() - beforeGetRoutesThenQuotes,
1733
+ // MetricLoggerUnit.Milliseconds
1734
+ // );
1735
+ // return result;
1736
+ // })
1737
+ // )
1738
+ // );
1739
+ // }
1740
+ // if (!fotInDirectSwap) {
1741
+ // // Maybe Quote mixed routes
1742
+ // // if MixedProtocol is specified or no protocol is specified and v2 is supported AND tradeType is ExactIn
1743
+ // // AND is Mainnet or Gorli
1744
+ // // Also make sure there are at least 2 protocols provided besides MIXED, before entering mixed quoter
1745
+ // if (
1746
+ // shouldQueryMixedProtocol &&
1747
+ // mixedProtocolAllowed &&
1748
+ // protocols.filter((protocol) => protocol !== Protocol.MIXED).length >= 2
1749
+ // ) {
1750
+ // log.info({ protocols, tradeType }, 'Routing across MixedRoutes');
1751
+ // metric.putMetric(
1752
+ // 'SwapRouteFromChain_Mixed_GetRoutesThenQuotes_Request',
1753
+ // 1,
1754
+ // MetricLoggerUnit.Count
1755
+ // );
1756
+ // const beforeGetRoutesThenQuotes = Date.now();
1757
+ // quotePromises.push(
1758
+ // Promise.all([
1759
+ // v4CandidatePoolsPromise,
1760
+ // v3CandidatePoolsPromise,
1761
+ // v2CandidatePoolsPromise,
1762
+ // ringFewV2CandidatePoolsPromise,
1763
+ // ]).then(
1764
+ // async ([v4CandidatePools, v3CandidatePools, v2CandidatePools, ringFewV2CandidatePools]) => {
1765
+ // const tokenIn = currencyIn.wrapped;
1766
+ // const tokenOut = currencyOut.wrapped;
1767
+ // const crossLiquidityPools =
1768
+ // await getMixedCrossLiquidityCandidatePools({
1769
+ // tokenIn,
1770
+ // tokenOut,
1771
+ // blockNumber: routingConfig.blockNumber,
1772
+ // v2SubgraphProvider: this.v2SubgraphProvider,
1773
+ // v3SubgraphProvider: this.v3SubgraphProvider,
1774
+ // v2Candidates: v2CandidatePools,
1775
+ // v3Candidates: v3CandidatePools,
1776
+ // v4Candidates: v4CandidatePools,
1777
+ // });
1778
+ // return this.mixedQuoter
1779
+ // .getRoutesThenQuotes(
1780
+ // tokenIn,
1781
+ // tokenOut,
1782
+ // amount,
1783
+ // amounts,
1784
+ // percents,
1785
+ // quoteCurrency.wrapped,
1786
+ // [
1787
+ // v4CandidatePools,
1788
+ // v3CandidatePools,
1789
+ // v2CandidatePools,
1790
+ // ringFewV2CandidatePools,
1791
+ // crossLiquidityPools,
1792
+ // ],
1793
+ // tradeType,
1794
+ // routingConfig,
1795
+ // mixedRouteGasModel
1796
+ // )
1797
+ // .then((result) => {
1798
+ // metric.putMetric(
1799
+ // `SwapRouteFromChain_Mixed_GetRoutesThenQuotes_Load`,
1800
+ // Date.now() - beforeGetRoutesThenQuotes,
1801
+ // MetricLoggerUnit.Milliseconds
1802
+ // );
1803
+ // return result;
1804
+ // });
1805
+ // }
1806
+ // )
1807
+ // );
1808
+ // }
1809
+ // }
1810
+ const getQuotesResults = await Promise.all(quotePromises);
1811
+ const allRoutesWithValidQuotes = [];
1812
+ const allCandidatePools = [];
1813
+ getQuotesResults.forEach((getQuoteResult) => {
1814
+ allRoutesWithValidQuotes.push(...getQuoteResult.routesWithValidQuotes);
1815
+ if (getQuoteResult.candidatePools) {
1816
+ allCandidatePools.push(getQuoteResult.candidatePools);
1817
+ }
1818
+ });
1819
+ if (allRoutesWithValidQuotes.length === 0) {
1820
+ log_1.log.info({ allRoutesWithValidQuotes }, 'Received no valid fewtokens quotes');
1821
+ return null;
1822
+ }
1823
+ return allRoutesWithValidQuotes;
1824
+ /*
1825
+ // Given all the quotes for all the amounts for all the routes, find the best combination.
1826
+ const bestSwapRoute = await getBestSwapRoute(
1827
+ amount,
1828
+ percents,
1829
+ allRoutesWithValidQuotes,
1830
+ tradeType,
1831
+ this.chainId,
1832
+ routingConfig,
1833
+ this.portionProvider,
1834
+ fewV2GasModel,
1835
+ fewV3GasModel,
1836
+ fewV4GasModel,
1837
+ swapConfig,
1838
+ providerConfig
1839
+ );
1840
+
1841
+ if (bestSwapRoute) {
1842
+ this.emitPoolSelectionMetrics(
1843
+ bestSwapRoute,
1844
+ allCandidatePools,
1845
+ currencyIn,
1846
+ currencyOut
1847
+ );
1848
+ }
1849
+
1850
+ return bestSwapRoute;
1851
+ */
1852
+ }
1853
+ tradeTypeStr(tradeType) {
1854
+ return tradeType === sdk_core_1.TradeType.EXACT_INPUT ? 'ExactIn' : 'ExactOut';
1855
+ }
1856
+ tokenPairSymbolTradeTypeChainId(currencyIn, currencyOut, tradeType) {
1857
+ return `${currencyIn.symbol}/${currencyOut.symbol}/${this.tradeTypeStr(tradeType)}/${this.chainId}`;
1858
+ }
1859
+ determineCurrencyInOutFromTradeType(tradeType, amount, quoteCurrency) {
1860
+ if (tradeType === sdk_core_1.TradeType.EXACT_INPUT) {
1861
+ return {
1862
+ currencyIn: amount.currency,
1863
+ currencyOut: quoteCurrency,
1864
+ };
1865
+ }
1866
+ else {
1867
+ return {
1868
+ currencyIn: quoteCurrency,
1869
+ currencyOut: amount.currency,
1870
+ };
1871
+ }
1872
+ }
1873
+ async getGasPriceWei(latestBlockNumber, requestBlockNumber) {
1874
+ // Track how long it takes to resolve this async call.
1875
+ const beforeGasTimestamp = Date.now();
1876
+ // Get an estimate of the gas price to use when estimating gas cost of different routes.
1877
+ const { gasPriceWei } = await this.gasPriceProvider.getGasPrice(latestBlockNumber, requestBlockNumber);
1878
+ metric_1.metric.putMetric('GasPriceLoad', Date.now() - beforeGasTimestamp, metric_1.MetricLoggerUnit.Milliseconds);
1879
+ return gasPriceWei;
1880
+ }
1881
+ async getGasModels(gasPriceWei, amountToken, quoteToken, providerConfig) {
1882
+ var _a, _c, _d;
1883
+ const beforeGasModel = Date.now();
1884
+ const fewQuoteToken = (0, fewAddress_1.isFewToken)(quoteToken)
1885
+ ? quoteToken
1886
+ : (0, few_v2_sdk_1.getFewTokenFromOriginalToken)(quoteToken, this.chainId);
1887
+ const fewAmountToken = (0, fewAddress_1.isFewToken)(amountToken)
1888
+ ? amountToken
1889
+ : (0, few_v2_sdk_1.getFewTokenFromOriginalToken)(amountToken, this.chainId);
1890
+ const usdPoolPromise = (0, gas_factory_helpers_1.getHighestLiquidityV3USDPool)(this.chainId, this.v3PoolProvider, providerConfig);
1891
+ const fewUsdPoolPromise = (0, gas_factory_helpers_1.getHighestLiquidityV3FewTokenUSDPool)(this.chainId, this.v3PoolProvider, providerConfig);
1892
+ const nativeCurrency = util_1.WRAPPED_NATIVE_CURRENCY[this.chainId];
1893
+ const fewNativeCurrency = chains_1.FEW_WRAPPED_NATIVE_CURRENCY[this.chainId];
1894
+ const nativeAndQuoteTokenV3PoolPromise = !quoteToken.equals(nativeCurrency)
1895
+ ? (0, gas_factory_helpers_1.getHighestLiquidityV3NativePool)(quoteToken, this.v3PoolProvider, providerConfig)
1896
+ : Promise.resolve(null);
1897
+ const nativeAndAmountTokenV3PoolPromise = !amountToken.equals(nativeCurrency)
1898
+ ? (0, gas_factory_helpers_1.getHighestLiquidityV3NativePool)(amountToken, this.v3PoolProvider, providerConfig)
1899
+ : Promise.resolve(null);
1900
+ const fewNativeAndQuoteTokenV3PoolPromise = !fewQuoteToken.equals(fewNativeCurrency)
1901
+ ? (0, gas_factory_helpers_1.getHighestLiquidityV3NativeFewTokenPool)(fewQuoteToken, this.v3PoolProvider, providerConfig)
1902
+ : Promise.resolve(null);
1903
+ const fewNativeAndAmountTokenV3PoolPromise = !fewAmountToken.equals(fewNativeCurrency)
1904
+ ? (0, gas_factory_helpers_1.getHighestLiquidityV3NativeFewTokenPool)(fewAmountToken, this.v3PoolProvider, providerConfig)
1905
+ : Promise.resolve(null);
1906
+ // If a specific gas token is specified in the provider config
1907
+ // fetch the highest liq V3 pool with it and the native currency
1908
+ const nativeAndSpecifiedGasTokenV3PoolPromise = (providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.gasToken) &&
1909
+ !(providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.gasToken.equals(nativeCurrency))
1910
+ ? (0, gas_factory_helpers_1.getHighestLiquidityV3NativePool)(providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.gasToken, this.v3PoolProvider, providerConfig)
1911
+ : Promise.resolve(null);
1912
+ // If a specific gas token is specified in the provider config
1913
+ // fetch the highest liq V3 pool with it and the native currency
1914
+ const fewNativeAndSpecifiedGasTokenV3PoolPromise = (providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.gasToken) &&
1915
+ !(providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.gasToken.equals(fewNativeCurrency))
1916
+ ? (0, gas_factory_helpers_1.getHighestLiquidityV3NativeFewTokenPool)(providerConfig === null || providerConfig === void 0 ? void 0 : providerConfig.gasToken, this.v3PoolProvider, providerConfig)
1917
+ : Promise.resolve(null);
1918
+ const [usdPool, fewUsdPool, nativeAndQuoteTokenV3Pool, fewNativeAndQuoteTokenV3Pool, nativeAndAmountTokenV3Pool, fewNativeAndAmountTokenV3Pool, nativeAndSpecifiedGasTokenV3Pool, fewNativeAndSpecifiedGasTokenV3Pool,] = await Promise.all([
1919
+ usdPoolPromise,
1920
+ fewUsdPoolPromise,
1921
+ nativeAndQuoteTokenV3PoolPromise,
1922
+ fewNativeAndQuoteTokenV3PoolPromise,
1923
+ nativeAndAmountTokenV3PoolPromise,
1924
+ fewNativeAndAmountTokenV3PoolPromise,
1925
+ nativeAndSpecifiedGasTokenV3PoolPromise,
1926
+ fewNativeAndSpecifiedGasTokenV3PoolPromise,
1927
+ ]);
1928
+ const pools = {
1929
+ usdPool: usdPool,
1930
+ nativeAndQuoteTokenV3Pool: nativeAndQuoteTokenV3Pool,
1931
+ nativeAndAmountTokenV3Pool: nativeAndAmountTokenV3Pool,
1932
+ nativeAndSpecifiedGasTokenV3Pool: nativeAndSpecifiedGasTokenV3Pool,
1933
+ };
1934
+ const fewPools = {
1935
+ usdPool: fewUsdPool,
1936
+ nativeAndQuoteTokenV3Pool: fewNativeAndQuoteTokenV3Pool,
1937
+ nativeAndAmountTokenV3Pool: fewNativeAndAmountTokenV3Pool,
1938
+ nativeAndSpecifiedGasTokenV3Pool: fewNativeAndSpecifiedGasTokenV3Pool,
1939
+ };
1940
+ const v2GasModelPromise = ((_a = this.v2Supported) === null || _a === void 0 ? void 0 : _a.includes(this.chainId))
1941
+ ? this.v2GasModelFactory
1942
+ .buildGasModel({
1943
+ chainId: this.chainId,
1944
+ gasPriceWei,
1945
+ poolProvider: this.v2PoolProvider,
1946
+ token: quoteToken,
1947
+ l2GasDataProvider: this.l2GasDataProvider,
1948
+ providerConfig: providerConfig,
1949
+ })
1950
+ .catch((_) => undefined) // If v2 model throws uncaught exception, we return undefined v2 gas model, so there's a chance v3 route can go through
1951
+ : Promise.resolve(undefined);
1952
+ // uniswap fewtoken
1953
+ const fewV2GasModelPromise = ((_c = this.v2Supported) === null || _c === void 0 ? void 0 : _c.includes(this.chainId))
1954
+ ? this.v2GasModelFactory
1955
+ .buildGasModel({
1956
+ chainId: this.chainId,
1957
+ gasPriceWei,
1958
+ poolProvider: this.v2PoolProvider,
1959
+ token: fewQuoteToken,
1960
+ l2GasDataProvider: this.l2GasDataProvider,
1961
+ providerConfig: providerConfig,
1962
+ })
1963
+ .catch((_) => undefined) // If v2 model throws uncaught exception, we return undefined v2 gas model, so there's a chance v3 route can go through
1964
+ : Promise.resolve(undefined);
1965
+ const ringFewV2GasModelPromise = ((_d = this.ringFewV2Supported) === null || _d === void 0 ? void 0 : _d.includes(this.chainId))
1966
+ ? this.ringFewV2GasModelFactory
1967
+ .buildGasModel({
1968
+ chainId: this.chainId,
1969
+ gasPriceWei,
1970
+ poolProvider: this.ringFewV2PoolProvider,
1971
+ token: quoteToken,
1972
+ l2GasDataProvider: this.l2GasDataProvider,
1973
+ providerConfig: providerConfig,
1974
+ })
1975
+ .catch((_) => undefined) // If v2 model throws uncaught exception, we return undefined v2 gas model, so there's a chance v3 route can go through
1976
+ : Promise.resolve(undefined);
1977
+ const v3GasModelPromise = this.v3GasModelFactory.buildGasModel({
1978
+ chainId: this.chainId,
1979
+ gasPriceWei,
1980
+ pools,
1981
+ amountToken,
1982
+ quoteToken,
1983
+ v2poolProvider: this.v2PoolProvider,
1984
+ l2GasDataProvider: this.l2GasDataProvider,
1985
+ providerConfig: providerConfig,
1986
+ });
1987
+ const fewV3GasModelPromise = this.uniswapFewV3GasModelFactory.buildGasModel({
1988
+ chainId: this.chainId,
1989
+ gasPriceWei,
1990
+ pools: fewPools,
1991
+ amountToken: fewAmountToken,
1992
+ quoteToken: fewQuoteToken,
1993
+ v2poolProvider: this.v2PoolProvider,
1994
+ l2GasDataProvider: this.l2GasDataProvider,
1995
+ providerConfig: providerConfig,
1996
+ });
1997
+ const v4GasModelPromise = this.v4GasModelFactory.buildGasModel({
1998
+ chainId: this.chainId,
1999
+ gasPriceWei,
2000
+ pools,
2001
+ amountToken,
2002
+ quoteToken,
2003
+ v2poolProvider: this.v2PoolProvider,
2004
+ l2GasDataProvider: this.l2GasDataProvider,
2005
+ providerConfig: providerConfig,
2006
+ });
2007
+ const fewV4GasModelPromise = this.uniswapFewV4GasModelFactory.buildGasModel({
2008
+ chainId: this.chainId,
2009
+ gasPriceWei,
2010
+ pools: fewPools,
2011
+ amountToken: fewAmountToken,
2012
+ quoteToken: fewQuoteToken,
2013
+ v2poolProvider: this.v2PoolProvider,
2014
+ l2GasDataProvider: this.l2GasDataProvider,
2015
+ providerConfig: providerConfig,
2016
+ });
2017
+ const mixedRouteGasModelPromise = this.mixedRouteGasModelFactory.buildGasModel({
2018
+ chainId: this.chainId,
2019
+ gasPriceWei,
2020
+ pools,
2021
+ amountToken,
2022
+ quoteToken,
2023
+ v2poolProvider: this.v2PoolProvider,
2024
+ providerConfig: providerConfig,
2025
+ });
2026
+ const [ringFewV2GasModel, v2GasModel, fewV2GasModel, v3GasModel, fewV3GasModel, v4GasModel, fewV4GasModel, mixedRouteGasModel] = await Promise.all([
2027
+ ringFewV2GasModelPromise,
2028
+ v2GasModelPromise,
2029
+ fewV2GasModelPromise,
2030
+ v3GasModelPromise,
2031
+ fewV3GasModelPromise,
2032
+ v4GasModelPromise,
2033
+ fewV4GasModelPromise,
2034
+ mixedRouteGasModelPromise,
2035
+ ]);
2036
+ metric_1.metric.putMetric('GasModelCreation', Date.now() - beforeGasModel, metric_1.MetricLoggerUnit.Milliseconds);
2037
+ return {
2038
+ ringFewV2GasModel: ringFewV2GasModel,
2039
+ v2GasModel: v2GasModel,
2040
+ fewV2GasModel: fewV2GasModel,
2041
+ v3GasModel: v3GasModel,
2042
+ fewV3GasModel: fewV3GasModel,
2043
+ v4GasModel: v4GasModel,
2044
+ fewV4GasModel: fewV4GasModel,
2045
+ mixedRouteGasModel: mixedRouteGasModel,
2046
+ };
2047
+ }
2048
+ // Note multiplications here can result in a loss of precision in the amounts (e.g. taking 50% of 101)
2049
+ // This is reconcilled at the end of the algorithm by adding any lost precision to one of
2050
+ // the splits in the route.
2051
+ getAmountDistribution(amount, routingConfig) {
2052
+ const { distributionPercent } = routingConfig;
2053
+ const percents = [];
2054
+ const amounts = [];
2055
+ for (let i = 1; i <= 100 / distributionPercent; i++) {
2056
+ percents.push(i * distributionPercent);
2057
+ amounts.push(amount.multiply(new sdk_core_1.Fraction(i * distributionPercent, 100)));
2058
+ }
2059
+ return [percents, amounts];
2060
+ }
2061
+ async buildSwapAndAddMethodParameters(trade, swapAndAddOptions, swapAndAddParameters) {
2062
+ const { swapOptions: { recipient, slippageTolerance, deadline, inputTokenPermit }, addLiquidityOptions: addLiquidityConfig, } = swapAndAddOptions;
2063
+ const preLiquidityPosition = swapAndAddParameters.preLiquidityPosition;
2064
+ const finalBalanceTokenIn = swapAndAddParameters.initialBalanceTokenIn.subtract(trade.inputAmount);
2065
+ const finalBalanceTokenOut = swapAndAddParameters.initialBalanceTokenOut.add(trade.outputAmount);
2066
+ const approvalTypes = await this.swapRouterProvider.getApprovalType(finalBalanceTokenIn, finalBalanceTokenOut);
2067
+ const zeroForOne = finalBalanceTokenIn.currency.wrapped.sortsBefore(finalBalanceTokenOut.currency.wrapped);
2068
+ return Object.assign(Object.assign({}, router_sdk_1.SwapRouter.swapAndAddCallParameters(trade, {
2069
+ recipient,
2070
+ slippageTolerance,
2071
+ deadlineOrPreviousBlockhash: deadline,
2072
+ inputTokenPermit,
2073
+ }, v3_sdk_1.Position.fromAmounts({
2074
+ pool: preLiquidityPosition.pool,
2075
+ tickLower: preLiquidityPosition.tickLower,
2076
+ tickUpper: preLiquidityPosition.tickUpper,
2077
+ amount0: zeroForOne
2078
+ ? finalBalanceTokenIn.quotient.toString()
2079
+ : finalBalanceTokenOut.quotient.toString(),
2080
+ amount1: zeroForOne
2081
+ ? finalBalanceTokenOut.quotient.toString()
2082
+ : finalBalanceTokenIn.quotient.toString(),
2083
+ useFullPrecision: false,
2084
+ }), addLiquidityConfig, approvalTypes.approvalTokenIn, approvalTypes.approvalTokenOut)), { to: (0, util_1.SWAP_ROUTER_02_ADDRESSES)(this.chainId) });
2085
+ }
2086
+ // @ts-ignore
2087
+ emitPoolSelectionMetrics(swapRouteRaw, allPoolsBySelection, currencyIn, currencyOut) {
2088
+ const poolAddressesUsed = new Set();
2089
+ const { routes: routeAmounts } = swapRouteRaw;
2090
+ (0, lodash_1.default)(routeAmounts)
2091
+ .flatMap((routeAmount) => {
2092
+ const { poolIdentifiers: poolAddresses } = routeAmount;
2093
+ return poolAddresses;
2094
+ })
2095
+ .forEach((address) => {
2096
+ poolAddressesUsed.add(address.toLowerCase());
2097
+ });
2098
+ for (const poolsBySelection of allPoolsBySelection) {
2099
+ const { protocol } = poolsBySelection;
2100
+ lodash_1.default.forIn(poolsBySelection.selections, (pools, topNSelection) => {
2101
+ const topNUsed = lodash_1.default.findLastIndex(pools, (pool) => poolAddressesUsed.has(pool.id.toLowerCase())) + 1;
2102
+ metric_1.metric.putMetric(lodash_1.default.capitalize(`${protocol}${topNSelection}`), topNUsed, metric_1.MetricLoggerUnit.Count);
2103
+ });
2104
+ }
2105
+ let hasV4Route = false;
2106
+ let hasV3Route = false;
2107
+ let hasV2Route = false;
2108
+ let hasMixedRoute = false;
2109
+ for (const routeAmount of routeAmounts) {
2110
+ if (routeAmount.protocol === router_sdk_1.Protocol.V4) {
2111
+ hasV4Route = true;
2112
+ }
2113
+ if (routeAmount.protocol === router_sdk_1.Protocol.V3) {
2114
+ hasV3Route = true;
2115
+ }
2116
+ if (routeAmount.protocol === router_sdk_1.Protocol.V2) {
2117
+ hasV2Route = true;
2118
+ }
2119
+ if (routeAmount.protocol === router_sdk_1.Protocol.MIXED) {
2120
+ hasMixedRoute = true;
2121
+ }
2122
+ }
2123
+ if (hasMixedRoute && (hasV4Route || hasV3Route || hasV2Route)) {
2124
+ let metricsPrefix = 'Mixed';
2125
+ if (hasV4Route) {
2126
+ metricsPrefix += 'AndV4';
2127
+ }
2128
+ if (hasV3Route) {
2129
+ metricsPrefix += 'AndV3';
2130
+ }
2131
+ if (hasV2Route) {
2132
+ metricsPrefix += 'AndV2';
2133
+ }
2134
+ metric_1.metric.putMetric(`${metricsPrefix}SplitRoute`, 1, metric_1.MetricLoggerUnit.Count);
2135
+ metric_1.metric.putMetric(`${metricsPrefix}SplitRouteForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
2136
+ if (hasV4Route && (currencyIn.isNative || currencyOut.isNative)) {
2137
+ // 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
2138
+ metric_1.metric.putMetric(`${metricsPrefix}SplitRouteWithNativeToken`, 1, metric_1.MetricLoggerUnit.Count);
2139
+ metric_1.metric.putMetric(`${metricsPrefix}SplitRouteWithNativeTokenForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
2140
+ }
2141
+ }
2142
+ else if (hasV4Route && hasV3Route && hasV2Route) {
2143
+ metric_1.metric.putMetric(`V4AndV3AndV2SplitRoute`, 1, metric_1.MetricLoggerUnit.Count);
2144
+ metric_1.metric.putMetric(`V4AndV3AndV2SplitRouteForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
2145
+ if (currencyIn.isNative || currencyOut.isNative) {
2146
+ // 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
2147
+ metric_1.metric.putMetric(`V4AndV3AndV2SplitRouteWithNativeToken`, 1, metric_1.MetricLoggerUnit.Count);
2148
+ metric_1.metric.putMetric(`V4AndV3AndV2SplitRouteWithNativeTokenForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
2149
+ }
2150
+ }
2151
+ else if (hasMixedRoute) {
2152
+ if (routeAmounts.length > 1) {
2153
+ metric_1.metric.putMetric(`MixedSplitRoute`, 1, metric_1.MetricLoggerUnit.Count);
2154
+ metric_1.metric.putMetric(`MixedSplitRouteForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
2155
+ }
2156
+ else {
2157
+ metric_1.metric.putMetric(`MixedRoute`, 1, metric_1.MetricLoggerUnit.Count);
2158
+ metric_1.metric.putMetric(`MixedRouteForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
2159
+ }
2160
+ }
2161
+ else if (hasV4Route) {
2162
+ if (routeAmounts.length > 1) {
2163
+ metric_1.metric.putMetric(`V4SplitRoute`, 1, metric_1.MetricLoggerUnit.Count);
2164
+ metric_1.metric.putMetric(`V4SplitRouteForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
2165
+ }
2166
+ }
2167
+ else if (hasV3Route) {
2168
+ if (routeAmounts.length > 1) {
2169
+ metric_1.metric.putMetric(`V3SplitRoute`, 1, metric_1.MetricLoggerUnit.Count);
2170
+ metric_1.metric.putMetric(`V3SplitRouteForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
2171
+ }
2172
+ else {
2173
+ metric_1.metric.putMetric(`V3Route`, 1, metric_1.MetricLoggerUnit.Count);
2174
+ metric_1.metric.putMetric(`V3RouteForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
2175
+ }
2176
+ }
2177
+ else if (hasV2Route) {
2178
+ if (routeAmounts.length > 1) {
2179
+ metric_1.metric.putMetric(`V2SplitRoute`, 1, metric_1.MetricLoggerUnit.Count);
2180
+ metric_1.metric.putMetric(`V2SplitRouteForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
2181
+ }
2182
+ else {
2183
+ metric_1.metric.putMetric(`V2Route`, 1, metric_1.MetricLoggerUnit.Count);
2184
+ metric_1.metric.putMetric(`V2RouteForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
2185
+ }
2186
+ }
2187
+ }
2188
+ calculateOptimalRatio(position, sqrtRatioX96, zeroForOne) {
2189
+ const upperSqrtRatioX96 = v3_sdk_1.TickMath.getSqrtRatioAtTick(position.tickUpper);
2190
+ const lowerSqrtRatioX96 = v3_sdk_1.TickMath.getSqrtRatioAtTick(position.tickLower);
2191
+ // returns Fraction(0, 1) for any out of range position regardless of zeroForOne. Implication: function
2192
+ // cannot be used to determine the trading direction of out of range positions.
2193
+ if (jsbi_1.default.greaterThan(sqrtRatioX96, upperSqrtRatioX96) ||
2194
+ jsbi_1.default.lessThan(sqrtRatioX96, lowerSqrtRatioX96)) {
2195
+ return new sdk_core_1.Fraction(0, 1);
2196
+ }
2197
+ const precision = jsbi_1.default.BigInt('1' + '0'.repeat(18));
2198
+ let optimalRatio = new sdk_core_1.Fraction(v3_sdk_1.SqrtPriceMath.getAmount0Delta(sqrtRatioX96, upperSqrtRatioX96, precision, true), v3_sdk_1.SqrtPriceMath.getAmount1Delta(sqrtRatioX96, lowerSqrtRatioX96, precision, true));
2199
+ if (!zeroForOne)
2200
+ optimalRatio = optimalRatio.invert();
2201
+ return optimalRatio;
2202
+ }
2203
+ async userHasSufficientBalance(fromAddress, tradeType, amount, quote) {
2204
+ try {
2205
+ const neededBalance = tradeType === sdk_core_1.TradeType.EXACT_INPUT ? amount : quote;
2206
+ let balance;
2207
+ if (neededBalance.currency.isNative) {
2208
+ balance = await this.provider.getBalance(fromAddress);
2209
+ }
2210
+ else {
2211
+ const tokenContract = Erc20__factory_1.Erc20__factory.connect(neededBalance.currency.address, this.provider);
2212
+ balance = await tokenContract.balanceOf(fromAddress);
2213
+ }
2214
+ return balance.gte(bignumber_1.BigNumber.from(neededBalance.quotient.toString()));
2215
+ }
2216
+ catch (e) {
2217
+ log_1.log.error(e, 'Error while checking user balance');
2218
+ return false;
2219
+ }
2220
+ }
2221
+ absoluteValue(fraction) {
2222
+ const numeratorAbs = jsbi_1.default.lessThan(fraction.numerator, jsbi_1.default.BigInt(0))
2223
+ ? jsbi_1.default.unaryMinus(fraction.numerator)
2224
+ : fraction.numerator;
2225
+ const denominatorAbs = jsbi_1.default.lessThan(fraction.denominator, jsbi_1.default.BigInt(0))
2226
+ ? jsbi_1.default.unaryMinus(fraction.denominator)
2227
+ : fraction.denominator;
2228
+ return new sdk_core_1.Fraction(numeratorAbs, denominatorAbs);
2229
+ }
2230
+ getBlockNumberPromise() {
2231
+ return (0, async_retry_1.default)(async (_b, attempt) => {
2232
+ if (attempt > 1) {
2233
+ log_1.log.info(`Get block number attempt ${attempt}`);
2234
+ }
2235
+ return this.provider.getBlockNumber();
2236
+ }, {
2237
+ retries: 2,
2238
+ minTimeout: 100,
2239
+ maxTimeout: 1000,
2240
+ });
2241
+ }
2242
+ // If we are requesting URv1.2, we need to keep entering cache
2243
+ // We want to skip cached routes access whenever "intent === INTENT.CACHING" or "hooksOption !== HooksOption.HOOKS_INCLUSIVE"
2244
+ // We keep this method as we might want to add more conditions in the future.
2245
+ static isAllowedToEnterCachedRoutes(intent, hooksOptions, swapRouter) {
2246
+ // intent takes highest precedence, as we need to ensure during caching intent, we do not enter cache no matter what
2247
+ if (intent !== undefined && intent === intent_1.INTENT.CACHING) {
2248
+ return false;
2249
+ }
2250
+ // 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
2251
+ // or v2/v3 is the best.
2252
+ // implicitly it means hooksOptions no longer matters for URv1.2
2253
+ // swapRouter has higher precedence than hooksOptions, because in case of URv1.2, we set hooksOptions = NO_HOOKS as default,
2254
+ // but swapRouter does not have any v4 pool for routing, so swapRouter should always use caching during QUOTE intent.
2255
+ if (swapRouter) {
2256
+ return true;
2257
+ }
2258
+ // in case we have URv2.0, and we are in QUOTE intent, we only want to enter cache when hooksOptions is default, HOOKS_INCLUSIVE
2259
+ if (hooksOptions !== undefined &&
2260
+ hooksOptions !== util_1.HooksOptions.HOOKS_INCLUSIVE) {
2261
+ return false;
2262
+ }
2263
+ return true;
2264
+ }
2265
+ }
2266
+ exports.AlphaRouter = AlphaRouter;
2267
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxwaGEtcm91dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3JvdXRlcnMvYWxwaGEtcm91dGVyL2FscGhhLXJvdXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSx3REFBcUQ7QUFDckQsd0RBQXlFO0FBQ3pFLHFGQUE2RDtBQUM3RCwwREFBOEU7QUFDOUUsc0RBTWlDO0FBRWpDLGtEQUFnRjtBQUNoRiw4REFBZ0M7QUFDaEMsZ0RBQXdCO0FBQ3hCLG9EQUF1QjtBQUN2Qiw0REFBbUM7QUFFbkMsK0NBOEN5QjtBQUN6Qiw2RkFHcUQ7QUFLckQsdUVBRzBDO0FBRTFDLHlFQUEyRTtBQUMzRSxtRUFBK0U7QUFDL0UsdUZBR2tEO0FBQ2xELG9FQUcwQztBQUMxQyw0RUFJOEM7QUFDOUMsb0VBRzBDO0FBRTFDLG9GQUFpRjtBQUNqRixvRUFHMEM7QUFDMUMsK0VBQTRFO0FBQzVFLHFDQVVvQjtBQUNwQixnREFBb0Q7QUFDcEQsOENBTTJCO0FBQzNCLHdFQUt3QztBQUN4Qyx3Q0FBcUM7QUFDckMsa0VBR3FDO0FBQ3JDLDhDQUE2RDtBQUM3RCx3RkFXZ0Q7QUFDaEQsc0VBQW1FO0FBQ25FLHNDQWlCbUI7QUFFbkIsOEVBQTZFO0FBQzdFLHdFQUF3RTtBQUN4RSw4Q0FBMkM7QUFDM0Msb0VBQWlFO0FBQ2pFLHFDQUdrQjtBQVdsQixpRUFBOEU7QUFDOUUscUZBQStFO0FBQy9FLHlFQWV5QztBQUN6QyxzREFBeUQ7QUFTekQsNkdBQTZHO0FBQzdHLG1GQUFvRjtBQUNwRixtRkFBb0Y7QUFDcEYsNkZBQXdHO0FBQ3hHLG1GQUFvRjtBQUNwRiw2RkFBd0c7QUFDeEcsdUNBQTZFO0FBQzdFLG1EQUErQztBQUMvQywyRUFBcUU7QUFDckUsMkVBQXFFO0FBRXJFLDJEQUEwRDtBQUMxRCxzRkFBOEY7QUFDOUYsMERBQXlFO0FBQ3pFLHNEQUFtRDtBQUNuRCx3RUFBb0c7QUE0THBHLE1BQWEsbUJBQXVCLFNB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