@xspswap/smart-order-router 1.0.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 (402) hide show
  1. package/CHANGELOG.md +255 -0
  2. package/LICENSE +674 -0
  3. package/README.md +189 -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 +9 -0
  7. package/build/main/providers/cache-node.js +19 -0
  8. package/build/main/providers/cache.d.ts +13 -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 +23 -0
  15. package/build/main/providers/caching/route/model/cached-route.js +24 -0
  16. package/build/main/providers/caching/route/model/cached-routes.d.ts +63 -0
  17. package/build/main/providers/caching/route/model/cached-routes.js +73 -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 +91 -0
  21. package/build/main/providers/caching/route/route-caching-provider.js +65 -0
  22. package/build/main/providers/caching-gas-provider.d.ts +23 -0
  23. package/build/main/providers/caching-gas-provider.js +37 -0
  24. package/build/main/providers/caching-token-list-provider.d.ts +40 -0
  25. package/build/main/providers/caching-token-list-provider.js +123 -0
  26. package/build/main/providers/caching-token-provider.d.ts +25 -0
  27. package/build/main/providers/caching-token-provider.js +113 -0
  28. package/build/main/providers/eip-1559-gas-price-provider.d.ts +31 -0
  29. package/build/main/providers/eip-1559-gas-price-provider.js +66 -0
  30. package/build/main/providers/eth-estimate-gas-provider.d.ts +14 -0
  31. package/build/main/providers/eth-estimate-gas-provider.js +72 -0
  32. package/build/main/providers/eth-gas-station-info-gas-price-provider.d.ts +19 -0
  33. package/build/main/providers/eth-gas-station-info-gas-price-provider.js +37 -0
  34. package/build/main/providers/gas-price-provider.d.ts +10 -0
  35. package/build/main/providers/gas-price-provider.js +10 -0
  36. package/build/main/providers/index.d.ts +37 -0
  37. package/build/main/providers/index.js +54 -0
  38. package/build/main/providers/legacy-gas-price-provider.d.ts +7 -0
  39. package/build/main/providers/legacy-gas-price-provider.js +20 -0
  40. package/build/main/providers/multicall-provider.d.ts +82 -0
  41. package/build/main/providers/multicall-provider.js +15 -0
  42. package/build/main/providers/multicall-uniswap-provider.d.ts +37 -0
  43. package/build/main/providers/multicall-uniswap-provider.js +163 -0
  44. package/build/main/providers/on-chain-gas-price-provider.d.ts +19 -0
  45. package/build/main/providers/on-chain-gas-price-provider.js +33 -0
  46. package/build/main/providers/on-chain-quote-provider.d.ts +221 -0
  47. package/build/main/providers/on-chain-quote-provider.js +511 -0
  48. package/build/main/providers/provider.d.ts +10 -0
  49. package/build/main/providers/provider.js +3 -0
  50. package/build/main/providers/simulation-provider.d.ts +42 -0
  51. package/build/main/providers/simulation-provider.js +130 -0
  52. package/build/main/providers/static-gas-price-provider.d.ts +7 -0
  53. package/build/main/providers/static-gas-price-provider.js +13 -0
  54. package/build/main/providers/swap-router-provider.d.ts +31 -0
  55. package/build/main/providers/swap-router-provider.js +42 -0
  56. package/build/main/providers/tenderly-simulation-provider.d.ts +43 -0
  57. package/build/main/providers/tenderly-simulation-provider.js +244 -0
  58. package/build/main/providers/token-provider.d.ts +45 -0
  59. package/build/main/providers/token-provider.js +121 -0
  60. package/build/main/providers/token-validator-provider.d.ts +42 -0
  61. package/build/main/providers/token-validator-provider.js +95 -0
  62. package/build/main/providers/uri-subgraph-provider.d.ts +20 -0
  63. package/build/main/providers/uri-subgraph-provider.js +65 -0
  64. package/build/main/providers/v2/caching-pool-provider.d.ts +34 -0
  65. package/build/main/providers/v2/caching-pool-provider.js +88 -0
  66. package/build/main/providers/v2/caching-subgraph-provider.d.ts +23 -0
  67. package/build/main/providers/v2/caching-subgraph-provider.js +34 -0
  68. package/build/main/providers/v2/pool-provider.d.ts +60 -0
  69. package/build/main/providers/v2/pool-provider.js +110 -0
  70. package/build/main/providers/v2/quote-provider.d.ts +33 -0
  71. package/build/main/providers/v2/quote-provider.js +91 -0
  72. package/build/main/providers/v2/static-subgraph-provider.d.ts +20 -0
  73. package/build/main/providers/v2/static-subgraph-provider.js +73 -0
  74. package/build/main/providers/v2/subgraph-provider-with-fallback.d.ts +19 -0
  75. package/build/main/providers/v2/subgraph-provider-with-fallback.js +35 -0
  76. package/build/main/providers/v2/subgraph-provider.d.ts +34 -0
  77. package/build/main/providers/v2/subgraph-provider.js +135 -0
  78. package/build/main/providers/v2/uri-subgraph-provider.d.ts +4 -0
  79. package/build/main/providers/v2/uri-subgraph-provider.js +8 -0
  80. package/build/main/providers/v3/caching-pool-provider.d.ts +33 -0
  81. package/build/main/providers/v3/caching-pool-provider.js +77 -0
  82. package/build/main/providers/v3/caching-subgraph-provider.d.ts +23 -0
  83. package/build/main/providers/v3/caching-subgraph-provider.js +34 -0
  84. package/build/main/providers/v3/gas-data-provider.d.ts +30 -0
  85. package/build/main/providers/v3/gas-data-provider.js +3 -0
  86. package/build/main/providers/v3/pool-provider.d.ts +61 -0
  87. package/build/main/providers/v3/pool-provider.js +125 -0
  88. package/build/main/providers/v3/static-subgraph-provider.d.ts +21 -0
  89. package/build/main/providers/v3/static-subgraph-provider.js +100 -0
  90. package/build/main/providers/v3/subgraph-provider-with-fallback.d.ts +15 -0
  91. package/build/main/providers/v3/subgraph-provider-with-fallback.js +31 -0
  92. package/build/main/providers/v3/subgraph-provider.d.ts +37 -0
  93. package/build/main/providers/v3/subgraph-provider.js +137 -0
  94. package/build/main/providers/v3/uri-subgraph-provider.d.ts +4 -0
  95. package/build/main/providers/v3/uri-subgraph-provider.js +8 -0
  96. package/build/main/routers/alpha-router/alpha-router.d.ts +267 -0
  97. package/build/main/routers/alpha-router/alpha-router.js +762 -0
  98. package/build/main/routers/alpha-router/config.d.ts +4 -0
  99. package/build/main/routers/alpha-router/config.js +61 -0
  100. package/build/main/routers/alpha-router/entities/index.d.ts +1 -0
  101. package/build/main/routers/alpha-router/entities/index.js +18 -0
  102. package/build/main/routers/alpha-router/entities/route-with-valid-quote.d.ts +163 -0
  103. package/build/main/routers/alpha-router/entities/route-with-valid-quote.js +143 -0
  104. package/build/main/routers/alpha-router/functions/best-swap-route.d.ts +19 -0
  105. package/build/main/routers/alpha-router/functions/best-swap-route.js +344 -0
  106. package/build/main/routers/alpha-router/functions/calculate-ratio-amount-in.d.ts +3 -0
  107. package/build/main/routers/alpha-router/functions/calculate-ratio-amount-in.js +18 -0
  108. package/build/main/routers/alpha-router/functions/compute-all-routes.d.ts +8 -0
  109. package/build/main/routers/alpha-router/functions/compute-all-routes.js +72 -0
  110. package/build/main/routers/alpha-router/functions/get-candidate-pools.d.ts +78 -0
  111. package/build/main/routers/alpha-router/functions/get-candidate-pools.js +704 -0
  112. package/build/main/routers/alpha-router/gas-models/gas-model.d.ts +83 -0
  113. package/build/main/routers/alpha-router/gas-models/gas-model.js +39 -0
  114. package/build/main/routers/alpha-router/gas-models/index.d.ts +2 -0
  115. package/build/main/routers/alpha-router/gas-models/index.js +19 -0
  116. package/build/main/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.d.ts +25 -0
  117. package/build/main/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.js +171 -0
  118. package/build/main/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.d.ts +29 -0
  119. package/build/main/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.js +167 -0
  120. package/build/main/routers/alpha-router/gas-models/v3/gas-costs.d.ts +6 -0
  121. package/build/main/routers/alpha-router/gas-models/v3/gas-costs.js +43 -0
  122. package/build/main/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.d.ts +25 -0
  123. package/build/main/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.js +223 -0
  124. package/build/main/routers/alpha-router/index.d.ts +4 -0
  125. package/build/main/routers/alpha-router/index.js +21 -0
  126. package/build/main/routers/alpha-router/quoters/base-quoter.d.ts +68 -0
  127. package/build/main/routers/alpha-router/quoters/base-quoter.js +61 -0
  128. package/build/main/routers/alpha-router/quoters/index.d.ts +5 -0
  129. package/build/main/routers/alpha-router/quoters/index.js +22 -0
  130. package/build/main/routers/alpha-router/quoters/mixed-quoter.d.ts +20 -0
  131. package/build/main/routers/alpha-router/quoters/mixed-quoter.js +130 -0
  132. package/build/main/routers/alpha-router/quoters/model/index.d.ts +1 -0
  133. package/build/main/routers/alpha-router/quoters/model/index.js +18 -0
  134. package/build/main/routers/alpha-router/quoters/model/results/get-quotes-result.d.ts +6 -0
  135. package/build/main/routers/alpha-router/quoters/model/results/get-quotes-result.js +3 -0
  136. package/build/main/routers/alpha-router/quoters/model/results/get-routes-result.d.ts +6 -0
  137. package/build/main/routers/alpha-router/quoters/model/results/get-routes-result.js +3 -0
  138. package/build/main/routers/alpha-router/quoters/model/results/index.d.ts +2 -0
  139. package/build/main/routers/alpha-router/quoters/model/results/index.js +19 -0
  140. package/build/main/routers/alpha-router/quoters/v2-quoter.d.ts +21 -0
  141. package/build/main/routers/alpha-router/quoters/v2-quoter.js +122 -0
  142. package/build/main/routers/alpha-router/quoters/v3-quoter.d.ts +19 -0
  143. package/build/main/routers/alpha-router/quoters/v3-quoter.js +125 -0
  144. package/build/main/routers/index.d.ts +4 -0
  145. package/build/main/routers/index.js +21 -0
  146. package/build/main/routers/legacy-router/bases.d.ts +28 -0
  147. package/build/main/routers/legacy-router/bases.js +58 -0
  148. package/build/main/routers/legacy-router/index.d.ts +1 -0
  149. package/build/main/routers/legacy-router/index.js +18 -0
  150. package/build/main/routers/legacy-router/legacy-router.d.ts +42 -0
  151. package/build/main/routers/legacy-router/legacy-router.js +289 -0
  152. package/build/main/routers/router.d.ts +165 -0
  153. package/build/main/routers/router.js +52 -0
  154. package/build/main/tsconfig.tsbuildinfo +1 -0
  155. package/build/main/types/other/factories/Erc20__factory.d.ts +45 -0
  156. package/build/main/types/other/factories/Erc20__factory.js +240 -0
  157. package/build/main/types/other/factories/GasDataArbitrum__factory.d.ts +18 -0
  158. package/build/main/types/other/factories/GasDataArbitrum__factory.js +58 -0
  159. package/build/main/types/other/factories/GasPriceOracle__factory.d.ts +46 -0
  160. package/build/main/types/other/factories/GasPriceOracle__factory.js +316 -0
  161. package/build/main/types/other/factories/IMixedRouteQuoterV1__factory.d.ts +41 -0
  162. package/build/main/types/other/factories/IMixedRouteQuoterV1__factory.js +156 -0
  163. package/build/main/types/other/factories/ITokenValidator__factory.d.ts +22 -0
  164. package/build/main/types/other/factories/ITokenValidator__factory.js +78 -0
  165. package/build/main/types/other/factories/Permit2__factory.d.ts +87 -0
  166. package/build/main/types/other/factories/Permit2__factory.js +941 -0
  167. package/build/main/types/other/factories/SwapRouter02__factory.d.ts +67 -0
  168. package/build/main/types/other/factories/SwapRouter02__factory.js +1103 -0
  169. package/build/main/types/v2/factories/IUniswapV2Pair__factory.d.ts +35 -0
  170. package/build/main/types/v2/factories/IUniswapV2Pair__factory.js +671 -0
  171. package/build/main/types/v3/factories/IERC20Metadata__factory.d.ts +35 -0
  172. package/build/main/types/v3/factories/IERC20Metadata__factory.js +242 -0
  173. package/build/main/types/v3/factories/IQuoterV2__factory.d.ts +41 -0
  174. package/build/main/types/v3/factories/IQuoterV2__factory.js +220 -0
  175. package/build/main/types/v3/factories/IUniswapV3PoolState__factory.d.ts +22 -0
  176. package/build/main/types/v3/factories/IUniswapV3PoolState__factory.js +266 -0
  177. package/build/main/types/v3/factories/UniswapInterfaceMulticall__factory.d.ts +61 -0
  178. package/build/main/types/v3/factories/UniswapInterfaceMulticall__factory.js +132 -0
  179. package/build/main/util/addresses.d.ts +25 -0
  180. package/build/main/util/addresses.js +59 -0
  181. package/build/main/util/amounts.d.ts +8 -0
  182. package/build/main/util/amounts.js +51 -0
  183. package/build/main/util/callData.d.ts +1 -0
  184. package/build/main/util/callData.js +6 -0
  185. package/build/main/util/chains.d.ts +34 -0
  186. package/build/main/util/chains.js +128 -0
  187. package/build/main/util/gas-factory-helpers.d.ts +24 -0
  188. package/build/main/util/gas-factory-helpers.js +294 -0
  189. package/build/main/util/index.d.ts +7 -0
  190. package/build/main/util/index.js +24 -0
  191. package/build/main/util/log.d.ts +3 -0
  192. package/build/main/util/log.js +97 -0
  193. package/build/main/util/methodParameters.d.ts +5 -0
  194. package/build/main/util/methodParameters.js +108 -0
  195. package/build/main/util/metric.d.ts +48 -0
  196. package/build/main/util/metric.js +59 -0
  197. package/build/main/util/protocols.d.ts +2 -0
  198. package/build/main/util/protocols.js +18 -0
  199. package/build/main/util/routes.d.ts +8 -0
  200. package/build/main/util/routes.js +60 -0
  201. package/build/main/util/unsupported-tokens.d.ts +37 -0
  202. package/build/main/util/unsupported-tokens.js +1119 -0
  203. package/build/module/index.d.ts +3 -0
  204. package/build/module/index.js +4 -0
  205. package/build/module/providers/cache-node.d.ts +9 -0
  206. package/build/module/providers/cache-node.js +15 -0
  207. package/build/module/providers/cache.d.ts +13 -0
  208. package/build/module/providers/cache.js +2 -0
  209. package/build/module/providers/caching/route/index.d.ts +2 -0
  210. package/build/module/providers/caching/route/index.js +3 -0
  211. package/build/module/providers/caching/route/model/cache-mode.d.ts +16 -0
  212. package/build/module/providers/caching/route/model/cache-mode.js +18 -0
  213. package/build/module/providers/caching/route/model/cached-route.d.ts +23 -0
  214. package/build/module/providers/caching/route/model/cached-route.js +20 -0
  215. package/build/module/providers/caching/route/model/cached-routes.d.ts +63 -0
  216. package/build/module/providers/caching/route/model/cached-routes.js +66 -0
  217. package/build/module/providers/caching/route/model/index.d.ts +3 -0
  218. package/build/module/providers/caching/route/model/index.js +4 -0
  219. package/build/module/providers/caching/route/route-caching-provider.d.ts +91 -0
  220. package/build/module/providers/caching/route/route-caching-provider.js +61 -0
  221. package/build/module/providers/caching-gas-provider.d.ts +23 -0
  222. package/build/module/providers/caching-gas-provider.js +33 -0
  223. package/build/module/providers/caching-token-list-provider.d.ts +40 -0
  224. package/build/module/providers/caching-token-list-provider.js +116 -0
  225. package/build/module/providers/caching-token-provider.d.ts +25 -0
  226. package/build/module/providers/caching-token-provider.js +106 -0
  227. package/build/module/providers/eip-1559-gas-price-provider.d.ts +31 -0
  228. package/build/module/providers/eip-1559-gas-price-provider.js +59 -0
  229. package/build/module/providers/eth-estimate-gas-provider.d.ts +14 -0
  230. package/build/module/providers/eth-estimate-gas-provider.js +80 -0
  231. package/build/module/providers/eth-gas-station-info-gas-price-provider.d.ts +19 -0
  232. package/build/module/providers/eth-gas-station-info-gas-price-provider.js +30 -0
  233. package/build/module/providers/gas-price-provider.d.ts +10 -0
  234. package/build/module/providers/gas-price-provider.js +6 -0
  235. package/build/module/providers/index.d.ts +37 -0
  236. package/build/module/providers/index.js +38 -0
  237. package/build/module/providers/legacy-gas-price-provider.d.ts +7 -0
  238. package/build/module/providers/legacy-gas-price-provider.js +16 -0
  239. package/build/module/providers/multicall-provider.d.ts +82 -0
  240. package/build/module/providers/multicall-provider.js +11 -0
  241. package/build/module/providers/multicall-uniswap-provider.d.ts +37 -0
  242. package/build/module/providers/multicall-uniswap-provider.js +156 -0
  243. package/build/module/providers/on-chain-gas-price-provider.d.ts +19 -0
  244. package/build/module/providers/on-chain-gas-price-provider.js +29 -0
  245. package/build/module/providers/on-chain-quote-provider.d.ts +221 -0
  246. package/build/module/providers/on-chain-quote-provider.js +505 -0
  247. package/build/module/providers/provider.d.ts +10 -0
  248. package/build/module/providers/provider.js +2 -0
  249. package/build/module/providers/simulation-provider.d.ts +42 -0
  250. package/build/module/providers/simulation-provider.js +132 -0
  251. package/build/module/providers/static-gas-price-provider.d.ts +7 -0
  252. package/build/module/providers/static-gas-price-provider.js +9 -0
  253. package/build/module/providers/swap-router-provider.d.ts +31 -0
  254. package/build/module/providers/swap-router-provider.js +38 -0
  255. package/build/module/providers/tenderly-simulation-provider.d.ts +43 -0
  256. package/build/module/providers/tenderly-simulation-provider.js +239 -0
  257. package/build/module/providers/token-provider.d.ts +45 -0
  258. package/build/module/providers/token-provider.js +110 -0
  259. package/build/module/providers/token-validator-provider.d.ts +42 -0
  260. package/build/module/providers/token-validator-provider.js +88 -0
  261. package/build/module/providers/uri-subgraph-provider.d.ts +20 -0
  262. package/build/module/providers/uri-subgraph-provider.js +58 -0
  263. package/build/module/providers/v2/caching-pool-provider.d.ts +34 -0
  264. package/build/module/providers/v2/caching-pool-provider.js +81 -0
  265. package/build/module/providers/v2/caching-subgraph-provider.d.ts +23 -0
  266. package/build/module/providers/v2/caching-subgraph-provider.js +30 -0
  267. package/build/module/providers/v2/pool-provider.d.ts +60 -0
  268. package/build/module/providers/v2/pool-provider.js +103 -0
  269. package/build/module/providers/v2/quote-provider.d.ts +33 -0
  270. package/build/module/providers/v2/quote-provider.js +87 -0
  271. package/build/module/providers/v2/static-subgraph-provider.d.ts +20 -0
  272. package/build/module/providers/v2/static-subgraph-provider.js +66 -0
  273. package/build/module/providers/v2/subgraph-provider-with-fallback.d.ts +19 -0
  274. package/build/module/providers/v2/subgraph-provider-with-fallback.js +31 -0
  275. package/build/module/providers/v2/subgraph-provider.d.ts +34 -0
  276. package/build/module/providers/v2/subgraph-provider.js +136 -0
  277. package/build/module/providers/v2/uri-subgraph-provider.d.ts +4 -0
  278. package/build/module/providers/v2/uri-subgraph-provider.js +4 -0
  279. package/build/module/providers/v3/caching-pool-provider.d.ts +33 -0
  280. package/build/module/providers/v3/caching-pool-provider.js +70 -0
  281. package/build/module/providers/v3/caching-subgraph-provider.d.ts +23 -0
  282. package/build/module/providers/v3/caching-subgraph-provider.js +30 -0
  283. package/build/module/providers/v3/gas-data-provider.d.ts +30 -0
  284. package/build/module/providers/v3/gas-data-provider.js +2 -0
  285. package/build/module/providers/v3/pool-provider.d.ts +61 -0
  286. package/build/module/providers/v3/pool-provider.js +118 -0
  287. package/build/module/providers/v3/static-subgraph-provider.d.ts +21 -0
  288. package/build/module/providers/v3/static-subgraph-provider.js +93 -0
  289. package/build/module/providers/v3/subgraph-provider-with-fallback.d.ts +15 -0
  290. package/build/module/providers/v3/subgraph-provider-with-fallback.js +27 -0
  291. package/build/module/providers/v3/subgraph-provider.d.ts +37 -0
  292. package/build/module/providers/v3/subgraph-provider.js +124 -0
  293. package/build/module/providers/v3/uri-subgraph-provider.d.ts +4 -0
  294. package/build/module/providers/v3/uri-subgraph-provider.js +4 -0
  295. package/build/module/routers/alpha-router/alpha-router.d.ts +267 -0
  296. package/build/module/routers/alpha-router/alpha-router.js +760 -0
  297. package/build/module/routers/alpha-router/config.d.ts +4 -0
  298. package/build/module/routers/alpha-router/config.js +57 -0
  299. package/build/module/routers/alpha-router/entities/index.d.ts +1 -0
  300. package/build/module/routers/alpha-router/entities/index.js +2 -0
  301. package/build/module/routers/alpha-router/entities/route-with-valid-quote.d.ts +163 -0
  302. package/build/module/routers/alpha-router/entities/route-with-valid-quote.js +134 -0
  303. package/build/module/routers/alpha-router/functions/best-swap-route.d.ts +19 -0
  304. package/build/module/routers/alpha-router/functions/best-swap-route.js +336 -0
  305. package/build/module/routers/alpha-router/functions/calculate-ratio-amount-in.d.ts +3 -0
  306. package/build/module/routers/alpha-router/functions/calculate-ratio-amount-in.js +14 -0
  307. package/build/module/routers/alpha-router/functions/compute-all-routes.d.ts +8 -0
  308. package/build/module/routers/alpha-router/functions/compute-all-routes.js +65 -0
  309. package/build/module/routers/alpha-router/functions/get-candidate-pools.d.ts +78 -0
  310. package/build/module/routers/alpha-router/functions/get-candidate-pools.js +715 -0
  311. package/build/module/routers/alpha-router/gas-models/gas-model.d.ts +83 -0
  312. package/build/module/routers/alpha-router/gas-models/gas-model.js +34 -0
  313. package/build/module/routers/alpha-router/gas-models/index.d.ts +2 -0
  314. package/build/module/routers/alpha-router/gas-models/index.js +3 -0
  315. package/build/module/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.d.ts +25 -0
  316. package/build/module/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.js +164 -0
  317. package/build/module/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.d.ts +29 -0
  318. package/build/module/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.js +160 -0
  319. package/build/module/routers/alpha-router/gas-models/v3/gas-costs.d.ts +6 -0
  320. package/build/module/routers/alpha-router/gas-models/v3/gas-costs.js +37 -0
  321. package/build/module/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.d.ts +25 -0
  322. package/build/module/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.js +216 -0
  323. package/build/module/routers/alpha-router/index.d.ts +4 -0
  324. package/build/module/routers/alpha-router/index.js +5 -0
  325. package/build/module/routers/alpha-router/quoters/base-quoter.d.ts +68 -0
  326. package/build/module/routers/alpha-router/quoters/base-quoter.js +54 -0
  327. package/build/module/routers/alpha-router/quoters/index.d.ts +5 -0
  328. package/build/module/routers/alpha-router/quoters/index.js +6 -0
  329. package/build/module/routers/alpha-router/quoters/mixed-quoter.d.ts +20 -0
  330. package/build/module/routers/alpha-router/quoters/mixed-quoter.js +123 -0
  331. package/build/module/routers/alpha-router/quoters/model/index.d.ts +1 -0
  332. package/build/module/routers/alpha-router/quoters/model/index.js +2 -0
  333. package/build/module/routers/alpha-router/quoters/model/results/get-quotes-result.d.ts +6 -0
  334. package/build/module/routers/alpha-router/quoters/model/results/get-quotes-result.js +2 -0
  335. package/build/module/routers/alpha-router/quoters/model/results/get-routes-result.d.ts +6 -0
  336. package/build/module/routers/alpha-router/quoters/model/results/get-routes-result.js +2 -0
  337. package/build/module/routers/alpha-router/quoters/model/results/index.d.ts +2 -0
  338. package/build/module/routers/alpha-router/quoters/model/results/index.js +3 -0
  339. package/build/module/routers/alpha-router/quoters/v2-quoter.d.ts +21 -0
  340. package/build/module/routers/alpha-router/quoters/v2-quoter.js +115 -0
  341. package/build/module/routers/alpha-router/quoters/v3-quoter.d.ts +19 -0
  342. package/build/module/routers/alpha-router/quoters/v3-quoter.js +118 -0
  343. package/build/module/routers/index.d.ts +4 -0
  344. package/build/module/routers/index.js +5 -0
  345. package/build/module/routers/legacy-router/bases.d.ts +28 -0
  346. package/build/module/routers/legacy-router/bases.js +54 -0
  347. package/build/module/routers/legacy-router/index.d.ts +1 -0
  348. package/build/module/routers/legacy-router/index.js +2 -0
  349. package/build/module/routers/legacy-router/legacy-router.d.ts +42 -0
  350. package/build/module/routers/legacy-router/legacy-router.js +290 -0
  351. package/build/module/routers/router.d.ts +165 -0
  352. package/build/module/routers/router.js +44 -0
  353. package/build/module/tsconfig.module.tsbuildinfo +1 -0
  354. package/build/module/types/other/factories/Erc20__factory.d.ts +45 -0
  355. package/build/module/types/other/factories/Erc20__factory.js +236 -0
  356. package/build/module/types/other/factories/GasDataArbitrum__factory.d.ts +18 -0
  357. package/build/module/types/other/factories/GasDataArbitrum__factory.js +54 -0
  358. package/build/module/types/other/factories/GasPriceOracle__factory.d.ts +46 -0
  359. package/build/module/types/other/factories/GasPriceOracle__factory.js +312 -0
  360. package/build/module/types/other/factories/IMixedRouteQuoterV1__factory.d.ts +41 -0
  361. package/build/module/types/other/factories/IMixedRouteQuoterV1__factory.js +152 -0
  362. package/build/module/types/other/factories/ITokenValidator__factory.d.ts +22 -0
  363. package/build/module/types/other/factories/ITokenValidator__factory.js +74 -0
  364. package/build/module/types/other/factories/Permit2__factory.d.ts +87 -0
  365. package/build/module/types/other/factories/Permit2__factory.js +937 -0
  366. package/build/module/types/other/factories/SwapRouter02__factory.d.ts +67 -0
  367. package/build/module/types/other/factories/SwapRouter02__factory.js +1099 -0
  368. package/build/module/types/v2/factories/IUniswapV2Pair__factory.d.ts +35 -0
  369. package/build/module/types/v2/factories/IUniswapV2Pair__factory.js +667 -0
  370. package/build/module/types/v3/factories/IERC20Metadata__factory.d.ts +35 -0
  371. package/build/module/types/v3/factories/IERC20Metadata__factory.js +238 -0
  372. package/build/module/types/v3/factories/IQuoterV2__factory.d.ts +41 -0
  373. package/build/module/types/v3/factories/IQuoterV2__factory.js +216 -0
  374. package/build/module/types/v3/factories/IUniswapV3PoolState__factory.d.ts +22 -0
  375. package/build/module/types/v3/factories/IUniswapV3PoolState__factory.js +262 -0
  376. package/build/module/types/v3/factories/UniswapInterfaceMulticall__factory.d.ts +61 -0
  377. package/build/module/types/v3/factories/UniswapInterfaceMulticall__factory.js +128 -0
  378. package/build/module/util/addresses.d.ts +25 -0
  379. package/build/module/util/addresses.js +70 -0
  380. package/build/module/util/amounts.d.ts +8 -0
  381. package/build/module/util/amounts.js +41 -0
  382. package/build/module/util/callData.d.ts +1 -0
  383. package/build/module/util/callData.js +3 -0
  384. package/build/module/util/chains.d.ts +34 -0
  385. package/build/module/util/chains.js +120 -0
  386. package/build/module/util/gas-factory-helpers.d.ts +24 -0
  387. package/build/module/util/gas-factory-helpers.js +277 -0
  388. package/build/module/util/index.d.ts +7 -0
  389. package/build/module/util/index.js +8 -0
  390. package/build/module/util/log.d.ts +3 -0
  391. package/build/module/util/log.js +93 -0
  392. package/build/module/util/methodParameters.d.ts +5 -0
  393. package/build/module/util/methodParameters.js +106 -0
  394. package/build/module/util/metric.d.ts +48 -0
  395. package/build/module/util/metric.js +53 -0
  396. package/build/module/util/protocols.d.ts +2 -0
  397. package/build/module/util/protocols.js +14 -0
  398. package/build/module/util/routes.d.ts +8 -0
  399. package/build/module/util/routes.js +50 -0
  400. package/build/module/util/unsupported-tokens.d.ts +37 -0
  401. package/build/module/util/unsupported-tokens.js +1116 -0
  402. package/package.json +133 -0
@@ -0,0 +1,762 @@
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.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("@xswap-v3/router-sdk");
11
+ const sdk_core_1 = require("@uniswap/sdk-core");
12
+ const v3_sdk_1 = require("@uniswap/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 token_provider_1 = require("../../providers/token-provider");
20
+ const token_validator_provider_1 = require("../../providers/token-validator-provider");
21
+ const pool_provider_1 = require("../../providers/v2/pool-provider");
22
+ const pool_provider_2 = require("../../providers/v3/pool-provider");
23
+ const Erc20__factory_1 = require("../../types/other/factories/Erc20__factory");
24
+ const util_1 = require("../../util");
25
+ const amounts_1 = require("../../util/amounts");
26
+ const chains_1 = require("../../util/chains");
27
+ const log_1 = require("../../util/log");
28
+ const methodParameters_1 = require("../../util/methodParameters");
29
+ const metric_1 = require("../../util/metric");
30
+ const unsupported_tokens_1 = require("../../util/unsupported-tokens");
31
+ const router_1 = require("../router");
32
+ const config_1 = require("./config");
33
+ const best_swap_route_1 = require("./functions/best-swap-route");
34
+ const calculate_ratio_amount_in_1 = require("./functions/calculate-ratio-amount-in");
35
+ const mixed_route_heuristic_gas_model_1 = require("./gas-models/mixedRoute/mixed-route-heuristic-gas-model");
36
+ const v2_heuristic_gas_model_1 = require("./gas-models/v2/v2-heuristic-gas-model");
37
+ const v3_heuristic_gas_model_1 = require("./gas-models/v3/v3-heuristic-gas-model");
38
+ const quoters_1 = require("./quoters");
39
+ class MapWithLowerCaseKey extends Map {
40
+ set(key, value) {
41
+ return super.set(key.toLowerCase(), value);
42
+ }
43
+ }
44
+ exports.MapWithLowerCaseKey = MapWithLowerCaseKey;
45
+ class AlphaRouter {
46
+ constructor({ chainId, provider, multicall2Provider, v3PoolProvider, onChainQuoteProvider, v2PoolProvider, v2QuoteProvider, v2SubgraphProvider, tokenProvider, blockedTokenListProvider, v3SubgraphProvider, gasPriceProvider, v3GasModelFactory, v2GasModelFactory, mixedRouteGasModelFactory, swapRouterProvider, tokenValidatorProvider, simulator, routeCachingProvider, }) {
47
+ this.chainId = chainId;
48
+ this.provider = provider;
49
+ this.multicall2Provider =
50
+ multicall2Provider !== null && multicall2Provider !== void 0 ? multicall2Provider : new providers_2.UniswapMulticallProvider(chainId, provider, 375000);
51
+ this.v3PoolProvider =
52
+ 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 })));
53
+ this.simulator = simulator;
54
+ this.routeCachingProvider = routeCachingProvider;
55
+ if (onChainQuoteProvider) {
56
+ this.onChainQuoteProvider = onChainQuoteProvider;
57
+ }
58
+ else {
59
+ switch (chainId) {
60
+ // case ChainId.ARBITRUM_ONE:
61
+ // this.onChainQuoteProvider = new OnChainQuoteProvider(
62
+ // chainId,
63
+ // provider,
64
+ // this.multicall2Provider,
65
+ // {
66
+ // retries: 2,
67
+ // minTimeout: 100,
68
+ // maxTimeout: 1000,
69
+ // },
70
+ // {
71
+ // multicallChunk: 10,
72
+ // gasLimitPerCall: 12_000_000,
73
+ // quoteMinSuccessRate: 0.1,
74
+ // },
75
+ // {
76
+ // gasLimitOverride: 30_000_000,
77
+ // multicallChunk: 6,
78
+ // },
79
+ // {
80
+ // gasLimitOverride: 30_000_000,
81
+ // multicallChunk: 6,
82
+ // }
83
+ // );
84
+ // break;
85
+ default:
86
+ this.onChainQuoteProvider = new providers_2.OnChainQuoteProvider(chainId, provider, this.multicall2Provider, {
87
+ retries: 2,
88
+ minTimeout: 100,
89
+ maxTimeout: 1000,
90
+ }, {
91
+ multicallChunk: 210,
92
+ gasLimitPerCall: 705000,
93
+ quoteMinSuccessRate: 0.15,
94
+ }, {
95
+ gasLimitOverride: 2000000,
96
+ multicallChunk: 70,
97
+ });
98
+ break;
99
+ }
100
+ }
101
+ this.v2PoolProvider =
102
+ v2PoolProvider !== null && v2PoolProvider !== void 0 ? v2PoolProvider : new providers_2.CachingV2PoolProvider(chainId, new pool_provider_1.V2PoolProvider(chainId, this.multicall2Provider), new providers_2.NodeJSCache(new node_cache_1.default({ stdTTL: 60, useClones: false })));
103
+ this.v2QuoteProvider = v2QuoteProvider !== null && v2QuoteProvider !== void 0 ? v2QuoteProvider : new providers_2.V2QuoteProvider();
104
+ this.blockedTokenListProvider =
105
+ 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 })));
106
+ this.tokenProvider =
107
+ 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));
108
+ const chainName = (0, chains_1.ID_TO_NETWORK_NAME)(chainId);
109
+ // ipfs urls in the following format: `https://cloudflare-ipfs.com/ipns/api.uniswap.org/v1/pools/${protocol}/${chainName}.json`;
110
+ if (v2SubgraphProvider) {
111
+ this.v2SubgraphProvider = v2SubgraphProvider;
112
+ }
113
+ else {
114
+ this.v2SubgraphProvider = new providers_2.V2SubgraphProviderWithFallBacks([
115
+ new providers_2.CachingV2SubgraphProvider(chainId, new providers_2.URISubgraphProvider(chainId, `https://cloudflare-ipfs.com/ipns/api.uniswap.org/v1/pools/v2/${chainName}.json`, undefined, 0), new providers_2.NodeJSCache(new node_cache_1.default({ stdTTL: 300, useClones: false }))),
116
+ new providers_2.StaticV2SubgraphProvider(chainId),
117
+ ]);
118
+ }
119
+ if (v3SubgraphProvider) {
120
+ this.v3SubgraphProvider = v3SubgraphProvider;
121
+ }
122
+ else {
123
+ this.v3SubgraphProvider = new providers_2.V3SubgraphProviderWithFallBacks([
124
+ new providers_2.CachingV3SubgraphProvider(chainId, new providers_2.URISubgraphProvider(chainId, `https://cloudflare-ipfs.com/ipns/api.uniswap.org/v1/pools/v3/${chainName}.json`, undefined, 0), new providers_2.NodeJSCache(new node_cache_1.default({ stdTTL: 300, useClones: false }))),
125
+ new providers_2.StaticV3SubgraphProvider(chainId, this.v3PoolProvider),
126
+ ]);
127
+ }
128
+ let gasPriceProviderInstance;
129
+ if (providers_1.JsonRpcProvider.isProvider(this.provider)) {
130
+ gasPriceProviderInstance = new providers_2.OnChainGasPriceProvider(chainId, new providers_2.EIP1559GasPriceProvider(this.provider), new providers_2.LegacyGasPriceProvider(this.provider));
131
+ }
132
+ else {
133
+ gasPriceProviderInstance = new providers_2.ETHGasStationInfoProvider(config_1.ETH_GAS_STATION_API_URL);
134
+ }
135
+ this.gasPriceProvider =
136
+ gasPriceProvider !== null && gasPriceProvider !== void 0 ? gasPriceProvider : new providers_2.CachingGasStationProvider(chainId, gasPriceProviderInstance, new providers_2.NodeJSCache(new node_cache_1.default({ stdTTL: 15, useClones: false })));
137
+ this.v3GasModelFactory =
138
+ v3GasModelFactory !== null && v3GasModelFactory !== void 0 ? v3GasModelFactory : new v3_heuristic_gas_model_1.V3HeuristicGasModelFactory();
139
+ this.v2GasModelFactory =
140
+ v2GasModelFactory !== null && v2GasModelFactory !== void 0 ? v2GasModelFactory : new v2_heuristic_gas_model_1.V2HeuristicGasModelFactory();
141
+ this.mixedRouteGasModelFactory =
142
+ mixedRouteGasModelFactory !== null && mixedRouteGasModelFactory !== void 0 ? mixedRouteGasModelFactory : new mixed_route_heuristic_gas_model_1.MixedRouteHeuristicGasModelFactory();
143
+ this.swapRouterProvider =
144
+ swapRouterProvider !== null && swapRouterProvider !== void 0 ? swapRouterProvider : new providers_2.SwapRouterProvider(this.multicall2Provider, this.chainId);
145
+ if (tokenValidatorProvider) {
146
+ this.tokenValidatorProvider = tokenValidatorProvider;
147
+ }
148
+ else if (this.chainId === chains_1.ChainId.XDC) {
149
+ 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 })));
150
+ }
151
+ // Initialize the Quoters.
152
+ // Quoters are an abstraction encapsulating the business logic of fetching routes and quotes.
153
+ this.v2Quoter = new quoters_1.V2Quoter(this.v2SubgraphProvider, this.v2PoolProvider, this.v2QuoteProvider, this.v2GasModelFactory, this.tokenProvider, this.chainId, this.blockedTokenListProvider, this.tokenValidatorProvider);
154
+ this.v3Quoter = new quoters_1.V3Quoter(this.v3SubgraphProvider, this.v3PoolProvider, this.onChainQuoteProvider, this.tokenProvider, this.chainId, this.blockedTokenListProvider, this.tokenValidatorProvider);
155
+ this.mixedQuoter = new quoters_1.MixedQuoter(this.v3SubgraphProvider, this.v3PoolProvider, this.v2SubgraphProvider, this.v2PoolProvider, this.onChainQuoteProvider, this.tokenProvider, this.chainId, this.blockedTokenListProvider, this.tokenValidatorProvider);
156
+ }
157
+ async routeToRatio(token0Balance, token1Balance, position, swapAndAddConfig, swapAndAddOptions, routingConfig = (0, config_1.DEFAULT_ROUTING_CONFIG_BY_CHAIN)(this.chainId)) {
158
+ if (token1Balance.currency.wrapped.sortsBefore(token0Balance.currency.wrapped)) {
159
+ [token0Balance, token1Balance] = [token1Balance, token0Balance];
160
+ }
161
+ let preSwapOptimalRatio = this.calculateOptimalRatio(position, position.pool.sqrtRatioX96, true);
162
+ // set up parameters according to which token will be swapped
163
+ let zeroForOne;
164
+ if (position.pool.tickCurrent > position.tickUpper) {
165
+ zeroForOne = true;
166
+ }
167
+ else if (position.pool.tickCurrent < position.tickLower) {
168
+ zeroForOne = false;
169
+ }
170
+ else {
171
+ zeroForOne = new sdk_core_1.Fraction(token0Balance.quotient, token1Balance.quotient).greaterThan(preSwapOptimalRatio);
172
+ if (!zeroForOne)
173
+ preSwapOptimalRatio = preSwapOptimalRatio.invert();
174
+ }
175
+ const [inputBalance, outputBalance] = zeroForOne
176
+ ? [token0Balance, token1Balance]
177
+ : [token1Balance, token0Balance];
178
+ let optimalRatio = preSwapOptimalRatio;
179
+ let postSwapTargetPool = position.pool;
180
+ let exchangeRate = zeroForOne
181
+ ? position.pool.token0Price
182
+ : position.pool.token1Price;
183
+ let swap = null;
184
+ let ratioAchieved = false;
185
+ let n = 0;
186
+ // iterate until we find a swap with a sufficient ratio or return null
187
+ while (!ratioAchieved) {
188
+ n++;
189
+ if (n > swapAndAddConfig.maxIterations) {
190
+ log_1.log.info('max iterations exceeded');
191
+ return {
192
+ status: router_1.SwapToRatioStatus.NO_ROUTE_FOUND,
193
+ error: 'max iterations exceeded',
194
+ };
195
+ }
196
+ const amountToSwap = (0, calculate_ratio_amount_in_1.calculateRatioAmountIn)(optimalRatio, exchangeRate, inputBalance, outputBalance);
197
+ if (amountToSwap.equalTo(0)) {
198
+ log_1.log.info(`no swap needed: amountToSwap = 0`);
199
+ return {
200
+ status: router_1.SwapToRatioStatus.NO_SWAP_NEEDED,
201
+ };
202
+ }
203
+ 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), {
204
+ /// @dev We do not want to query for mixedRoutes for routeToRatio as they are not supported
205
+ /// [Protocol.V3, Protocol.V2] will make sure we only query for V3 and V2
206
+ protocols: [router_sdk_1.Protocol.V3, router_sdk_1.Protocol.V2] }));
207
+ if (!swap) {
208
+ log_1.log.info('no route found from this.route()');
209
+ return {
210
+ status: router_1.SwapToRatioStatus.NO_ROUTE_FOUND,
211
+ error: 'no route found',
212
+ };
213
+ }
214
+ const inputBalanceUpdated = inputBalance.subtract(swap.trade.inputAmount);
215
+ const outputBalanceUpdated = outputBalance.add(swap.trade.outputAmount);
216
+ const newRatio = inputBalanceUpdated.divide(outputBalanceUpdated);
217
+ let targetPoolPriceUpdate;
218
+ swap.route.forEach((route) => {
219
+ if (route.protocol === router_sdk_1.Protocol.V3) {
220
+ const v3Route = route;
221
+ v3Route.route.pools.forEach((pool, i) => {
222
+ if (pool.token0.equals(position.pool.token0) &&
223
+ pool.token1.equals(position.pool.token1) &&
224
+ pool.fee === position.pool.fee) {
225
+ targetPoolPriceUpdate = jsbi_1.default.BigInt(v3Route.sqrtPriceX96AfterList[i].toString());
226
+ optimalRatio = this.calculateOptimalRatio(position, jsbi_1.default.BigInt(targetPoolPriceUpdate.toString()), zeroForOne);
227
+ }
228
+ });
229
+ }
230
+ });
231
+ if (!targetPoolPriceUpdate) {
232
+ optimalRatio = preSwapOptimalRatio;
233
+ }
234
+ ratioAchieved =
235
+ newRatio.equalTo(optimalRatio) ||
236
+ this.absoluteValue(newRatio.asFraction.divide(optimalRatio).subtract(1)).lessThan(swapAndAddConfig.ratioErrorTolerance);
237
+ if (ratioAchieved && targetPoolPriceUpdate) {
238
+ 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);
239
+ }
240
+ exchangeRate = swap.trade.outputAmount.divide(swap.trade.inputAmount);
241
+ log_1.log.info({
242
+ exchangeRate: exchangeRate.asFraction.toFixed(18),
243
+ optimalRatio: optimalRatio.asFraction.toFixed(18),
244
+ newRatio: newRatio.asFraction.toFixed(18),
245
+ inputBalanceUpdated: inputBalanceUpdated.asFraction.toFixed(18),
246
+ outputBalanceUpdated: outputBalanceUpdated.asFraction.toFixed(18),
247
+ ratioErrorTolerance: swapAndAddConfig.ratioErrorTolerance.toFixed(18),
248
+ iterationN: n.toString(),
249
+ }, 'QuoteToRatio Iteration Parameters');
250
+ if (exchangeRate.equalTo(0)) {
251
+ log_1.log.info('exchangeRate to 0');
252
+ return {
253
+ status: router_1.SwapToRatioStatus.NO_ROUTE_FOUND,
254
+ error: 'insufficient liquidity to swap to optimal ratio',
255
+ };
256
+ }
257
+ }
258
+ if (!swap) {
259
+ return {
260
+ status: router_1.SwapToRatioStatus.NO_ROUTE_FOUND,
261
+ error: 'no route found',
262
+ };
263
+ }
264
+ let methodParameters;
265
+ if (swapAndAddOptions) {
266
+ methodParameters = await this.buildSwapAndAddMethodParameters(swap.trade, swapAndAddOptions, {
267
+ initialBalanceTokenIn: inputBalance,
268
+ initialBalanceTokenOut: outputBalance,
269
+ preLiquidityPosition: position,
270
+ });
271
+ }
272
+ return {
273
+ status: router_1.SwapToRatioStatus.SUCCESS,
274
+ result: Object.assign(Object.assign({}, swap), { methodParameters, optimalRatio, postSwapTargetPool }),
275
+ };
276
+ }
277
+ /**
278
+ * @inheritdoc IRouter
279
+ */
280
+ async route(amount, quoteCurrency, tradeType, swapConfig, partialRoutingConfig = {}) {
281
+ var _a, _c, _d;
282
+ const { currencyIn, currencyOut } = this.determineCurrencyInOutFromTradeType(tradeType, amount, quoteCurrency);
283
+ const tokenIn = currencyIn.wrapped;
284
+ const tokenOut = currencyOut.wrapped;
285
+ metric_1.metric.setProperty('chainId', this.chainId);
286
+ metric_1.metric.setProperty('pair', `${tokenIn.symbol}/${tokenOut.symbol}`);
287
+ metric_1.metric.setProperty('tokenIn', tokenIn.address);
288
+ metric_1.metric.setProperty('tokenOut', tokenOut.address);
289
+ metric_1.metric.setProperty('tradeType', tradeType === sdk_core_1.TradeType.EXACT_INPUT ? 'ExactIn' : 'ExactOut');
290
+ metric_1.metric.putMetric(`QuoteRequestedForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
291
+ // Get a block number to specify in all our calls. Ensures data we fetch from chain is
292
+ // from the same block.
293
+ const blockNumber = (_a = partialRoutingConfig.blockNumber) !== null && _a !== void 0 ? _a : this.getBlockNumberPromise();
294
+ const routingConfig = lodash_1.default.merge({}, (0, config_1.DEFAULT_ROUTING_CONFIG_BY_CHAIN)(this.chainId), partialRoutingConfig, { blockNumber });
295
+ const gasPriceWei = await this.getGasPriceWei();
296
+ const quoteToken = quoteCurrency.wrapped;
297
+ const [v3GasModel, mixedRouteGasModel] = await this.getGasModels(gasPriceWei, amount.currency.wrapped, quoteToken);
298
+ // Create a Set to sanitize the protocols input, a Set of undefined becomes an empty set,
299
+ // Then create an Array from the values of that Set.
300
+ const protocols = Array.from(new Set(routingConfig.protocols).values());
301
+ const cacheMode = await ((_c = this.routeCachingProvider) === null || _c === void 0 ? void 0 : _c.getCacheMode(this.chainId, amount, quoteToken, tradeType, protocols));
302
+ // Fetch CachedRoutes
303
+ let cachedRoutes;
304
+ if (cacheMode !== providers_2.CacheMode.Darkmode) {
305
+ cachedRoutes = await ((_d = this.routeCachingProvider) === null || _d === void 0 ? void 0 : _d.getCachedRoute(this.chainId, amount, quoteToken, tradeType, protocols, await blockNumber));
306
+ }
307
+ if (cacheMode && cacheMode !== providers_2.CacheMode.Darkmode && !cachedRoutes) {
308
+ metric_1.metric.putMetric(`GetCachedRoute_miss_${cacheMode}`, 1, metric_1.MetricLoggerUnit.Count);
309
+ log_1.log.info({
310
+ tokenIn: tokenIn.symbol,
311
+ tokenInAddress: tokenIn.address,
312
+ tokenOut: tokenOut.symbol,
313
+ tokenOutAddress: tokenOut.address,
314
+ cacheMode,
315
+ amount: amount.toExact(),
316
+ chainId: this.chainId,
317
+ tradeType: this.tradeTypeStr(tradeType),
318
+ }, `GetCachedRoute miss ${cacheMode} for ${this.tokenPairSymbolTradeTypeChainId(tokenIn, tokenOut, tradeType)}`);
319
+ }
320
+ else if (cachedRoutes) {
321
+ metric_1.metric.putMetric(`GetCachedRoute_hit_${cacheMode}`, 1, metric_1.MetricLoggerUnit.Count);
322
+ log_1.log.info({
323
+ tokenIn: tokenIn.symbol,
324
+ tokenInAddress: tokenIn.address,
325
+ tokenOut: tokenOut.symbol,
326
+ tokenOutAddress: tokenOut.address,
327
+ cacheMode,
328
+ amount: amount.toExact(),
329
+ chainId: this.chainId,
330
+ tradeType: this.tradeTypeStr(tradeType),
331
+ }, `GetCachedRoute hit ${cacheMode} for ${this.tokenPairSymbolTradeTypeChainId(tokenIn, tokenOut, tradeType)}`);
332
+ }
333
+ let swapRouteFromCachePromise = Promise.resolve(null);
334
+ if (cachedRoutes) {
335
+ swapRouteFromCachePromise = this.getSwapRouteFromCache(cachedRoutes, await blockNumber, amount, quoteToken, tradeType, routingConfig, v3GasModel, mixedRouteGasModel, gasPriceWei);
336
+ }
337
+ let swapRouteFromChainPromise = Promise.resolve(null);
338
+ if (!cachedRoutes || cacheMode !== providers_2.CacheMode.Livemode) {
339
+ swapRouteFromChainPromise = this.getSwapRouteFromChain(amount, tokenIn, tokenOut, protocols, quoteToken, tradeType, routingConfig, v3GasModel, mixedRouteGasModel, gasPriceWei);
340
+ }
341
+ const [swapRouteFromCache, swapRouteFromChain] = await Promise.all([
342
+ swapRouteFromCachePromise,
343
+ swapRouteFromChainPromise,
344
+ ]);
345
+ let swapRouteRaw;
346
+ if (cacheMode === providers_2.CacheMode.Livemode && swapRouteFromCache) {
347
+ log_1.log.info(`CacheMode is ${cacheMode}, and we are using swapRoute from cache`);
348
+ swapRouteRaw = swapRouteFromCache;
349
+ }
350
+ else {
351
+ log_1.log.info(`CacheMode is ${cacheMode}, and we are using materialized swapRoute`);
352
+ swapRouteRaw = swapRouteFromChain;
353
+ }
354
+ if (cacheMode === providers_2.CacheMode.Tapcompare &&
355
+ swapRouteFromCache &&
356
+ swapRouteFromChain) {
357
+ const quoteDiff = swapRouteFromChain.quote.subtract(swapRouteFromCache.quote);
358
+ const quoteGasAdjustedDiff = swapRouteFromChain.quoteGasAdjusted.subtract(swapRouteFromCache.quoteGasAdjusted);
359
+ const gasUsedDiff = swapRouteFromChain.estimatedGasUsed.sub(swapRouteFromCache.estimatedGasUsed);
360
+ log_1.log.info({
361
+ quoteFromChain: swapRouteFromChain.quote.toExact(),
362
+ quoteFromCache: swapRouteFromCache.quote.toExact(),
363
+ quoteDiff: quoteDiff.toExact(),
364
+ quoteGasAdjustedFromChain: swapRouteFromChain.quoteGasAdjusted.toExact(),
365
+ quoteGasAdjustedFromCache: swapRouteFromCache.quoteGasAdjusted.toExact(),
366
+ quoteGasAdjustedDiff: quoteGasAdjustedDiff.toExact(),
367
+ gasUsedFromChain: swapRouteFromChain.estimatedGasUsed.toString(),
368
+ gasUsedFromCache: swapRouteFromCache.estimatedGasUsed.toString(),
369
+ gasUsedDiff: gasUsedDiff.toString(),
370
+ routesFromChain: swapRouteFromChain.routes.toString(),
371
+ routesFromCache: swapRouteFromCache.routes.toString(),
372
+ amount: amount.toExact(),
373
+ pair: this.tokenPairSymbolTradeTypeChainId(tokenIn, tokenOut, tradeType),
374
+ }, `Comparing quotes between Chain and Cache for ${this.tokenPairSymbolTradeTypeChainId(tokenIn, tokenOut, tradeType)}`);
375
+ }
376
+ if (!swapRouteRaw) {
377
+ return null;
378
+ }
379
+ const { quote, quoteGasAdjusted, estimatedGasUsed, routes: routeAmounts, estimatedGasUsedQuoteToken, estimatedGasUsedUSD, } = swapRouteRaw;
380
+ if (this.routeCachingProvider &&
381
+ cacheMode !== providers_2.CacheMode.Darkmode &&
382
+ swapRouteFromChain) {
383
+ // Generate the object to be cached
384
+ const routesToCache = providers_2.CachedRoutes.fromRoutesWithValidQuotes(swapRouteFromChain.routes, this.chainId, tokenIn, tokenOut, protocols.sort(), // sort it for consistency in the order of the protocols.
385
+ await blockNumber, tradeType);
386
+ if (routesToCache) {
387
+ const tokenPairSymbolTradeTypeChainId = this.tokenPairSymbolTradeTypeChainId(tokenIn, tokenOut, tradeType);
388
+ // Attempt to insert the entry in cache. This is fire and forget promise.
389
+ // The catch method will prevent any exception from blocking the normal code execution.
390
+ this.routeCachingProvider
391
+ .setCachedRoute(routesToCache, amount)
392
+ .then((success) => {
393
+ const status = success ? 'success' : 'rejected';
394
+ metric_1.metric.putMetric(`SetCachedRoute_${tokenPairSymbolTradeTypeChainId}_${status}`, 1, metric_1.MetricLoggerUnit.Count);
395
+ })
396
+ .catch((reason) => {
397
+ log_1.log.info({
398
+ reason: reason,
399
+ tokenPair: tokenPairSymbolTradeTypeChainId,
400
+ }, `SetCachedRoute failure`);
401
+ metric_1.metric.putMetric(`SetCachedRoute_${tokenPairSymbolTradeTypeChainId}_failure`, 1, metric_1.MetricLoggerUnit.Count);
402
+ });
403
+ }
404
+ }
405
+ metric_1.metric.putMetric(`QuoteFoundForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
406
+ // Build Trade object that represents the optimal swap.
407
+ const trade = (0, methodParameters_1.buildTrade)(currencyIn, currencyOut, tradeType, routeAmounts);
408
+ let methodParameters;
409
+ // If user provided recipient, deadline etc. we also generate the calldata required to execute
410
+ // the swap and return it too.
411
+ if (swapConfig) {
412
+ methodParameters = (0, methodParameters_1.buildSwapMethodParameters)(trade, swapConfig, this.chainId);
413
+ }
414
+ const swapRoute = {
415
+ quote,
416
+ quoteGasAdjusted,
417
+ estimatedGasUsed,
418
+ estimatedGasUsedQuoteToken,
419
+ estimatedGasUsedUSD,
420
+ gasPriceWei,
421
+ route: routeAmounts,
422
+ trade,
423
+ methodParameters,
424
+ blockNumber: bignumber_1.BigNumber.from(await blockNumber),
425
+ };
426
+ if (swapConfig &&
427
+ swapConfig.simulate &&
428
+ methodParameters &&
429
+ methodParameters.calldata) {
430
+ if (!this.simulator) {
431
+ throw new Error('Simulator not initialized!');
432
+ }
433
+ log_1.log.info({ swapConfig, methodParameters }, 'Starting simulation');
434
+ const fromAddress = swapConfig.simulate.fromAddress;
435
+ const beforeSimulate = Date.now();
436
+ const swapRouteWithSimulation = await this.simulator.simulate(fromAddress, swapConfig, swapRoute, amount,
437
+ // Quote will be in WETH even if quoteCurrency is ETH
438
+ // So we init a new CurrencyAmount object here
439
+ amounts_1.CurrencyAmount.fromRawAmount(quoteCurrency, quote.quotient.toString()));
440
+ metric_1.metric.putMetric('SimulateTransaction', Date.now() - beforeSimulate, metric_1.MetricLoggerUnit.Milliseconds);
441
+ return swapRouteWithSimulation;
442
+ }
443
+ return swapRoute;
444
+ }
445
+ async getSwapRouteFromCache(cachedRoutes, blockNumber, amount, quoteToken, tradeType, routingConfig, v3GasModel, mixedRouteGasModel, gasPriceWei) {
446
+ log_1.log.info({
447
+ protocols: cachedRoutes.protocolsCovered,
448
+ tradeType: cachedRoutes.tradeType,
449
+ cachedBlockNumber: cachedRoutes.blockNumber,
450
+ quoteBlockNumber: blockNumber,
451
+ }, 'Routing across CachedRoute');
452
+ const quotePromises = [];
453
+ const v3Routes = cachedRoutes.routes.filter((route) => route.protocol === router_sdk_1.Protocol.V3);
454
+ const v2Routes = cachedRoutes.routes.filter((route) => route.protocol === router_sdk_1.Protocol.V2);
455
+ const mixedRoutes = cachedRoutes.routes.filter((route) => route.protocol === router_sdk_1.Protocol.MIXED);
456
+ const percents = [];
457
+ if (v3Routes) {
458
+ const v3RoutesFromCache = v3Routes.map((cachedRoute) => cachedRoute.route);
459
+ const v3PercentsFromCache = v3Routes.map((cachedRoute) => cachedRoute.percent);
460
+ percents.push(...v3PercentsFromCache);
461
+ const v3Amounts = v3PercentsFromCache.map((percent) => amount.multiply(new sdk_core_1.Fraction(percent, 100)));
462
+ quotePromises.push(this.v3Quoter.getQuotes(v3RoutesFromCache, v3Amounts, v3PercentsFromCache, quoteToken, tradeType, routingConfig, undefined, v3GasModel));
463
+ }
464
+ if (v2Routes) {
465
+ const v2RoutesFromCache = v2Routes.map((cachedRoute) => cachedRoute.route);
466
+ const v2PercentsFromCache = v2Routes.map((cachedRoute) => cachedRoute.percent);
467
+ percents.push(...v2PercentsFromCache);
468
+ const v2Amounts = v2PercentsFromCache.map((percent) => amount.multiply(new sdk_core_1.Fraction(percent, 100)));
469
+ quotePromises.push(this.v2Quoter.getQuotes(v2RoutesFromCache, v2Amounts, v2PercentsFromCache, quoteToken, tradeType, routingConfig, undefined, undefined, gasPriceWei));
470
+ }
471
+ if (mixedRoutes) {
472
+ const mixedRoutesFromCache = mixedRoutes.map((cachedRoute) => cachedRoute.route);
473
+ const mixedPercentsFromCache = mixedRoutes.map((cachedRoute) => cachedRoute.percent);
474
+ percents.push(...mixedPercentsFromCache);
475
+ const mixedAmounts = mixedPercentsFromCache.map((percent) => amount.multiply(new sdk_core_1.Fraction(percent, 100)));
476
+ quotePromises.push(this.mixedQuoter.getQuotes(mixedRoutesFromCache, mixedAmounts, mixedPercentsFromCache, quoteToken, tradeType, routingConfig, undefined, mixedRouteGasModel));
477
+ }
478
+ const getQuotesResults = await Promise.all(quotePromises);
479
+ const allRoutesWithValidQuotes = lodash_1.default.flatMap(getQuotesResults, (quoteResult) => quoteResult.routesWithValidQuotes);
480
+ return (0, best_swap_route_1.getBestSwapRoute)(amount, percents, allRoutesWithValidQuotes, tradeType, this.chainId, routingConfig, v3GasModel);
481
+ }
482
+ async getSwapRouteFromChain(amount, tokenIn, tokenOut, protocols, quoteToken, tradeType, routingConfig, v3GasModel, mixedRouteGasModel, gasPriceWei) {
483
+ // Generate our distribution of amounts, i.e. fractions of the input amount.
484
+ // We will get quotes for fractions of the input amount for different routes, then
485
+ // combine to generate split routes.
486
+ const [percents, amounts] = this.getAmountDistribution(amount, routingConfig);
487
+ const noProtocolsSpecified = protocols.length === 0;
488
+ const v3ProtocolSpecified = protocols.includes(router_sdk_1.Protocol.V3);
489
+ const v2ProtocolSpecified = protocols.includes(router_sdk_1.Protocol.V2);
490
+ const v2SupportedInChain = chains_1.V2_SUPPORTED.includes(this.chainId);
491
+ const shouldQueryMixedProtocol = protocols.includes(router_sdk_1.Protocol.MIXED) ||
492
+ (noProtocolsSpecified && v2SupportedInChain);
493
+ const mixedProtocolAllowed = [chains_1.ChainId.XDC, chains_1.ChainId.XDC_APOTHEM].includes(this.chainId) &&
494
+ tradeType === sdk_core_1.TradeType.EXACT_INPUT;
495
+ const quotePromises = [];
496
+ // Maybe Quote V3 - if V3 is specified, or no protocol is specified
497
+ if (v3ProtocolSpecified || noProtocolsSpecified) {
498
+ log_1.log.info({ protocols, tradeType }, 'Routing across V3');
499
+ quotePromises.push(this.v3Quoter.getRoutesThenQuotes(tokenIn, tokenOut, amounts, percents, quoteToken, tradeType, routingConfig, v3GasModel));
500
+ }
501
+ // Maybe Quote V2 - if V2 is specified, or no protocol is specified AND v2 is supported in this chain
502
+ if (v2SupportedInChain && (v2ProtocolSpecified || noProtocolsSpecified)) {
503
+ log_1.log.info({ protocols, tradeType }, 'Routing across V2');
504
+ quotePromises.push(this.v2Quoter.getRoutesThenQuotes(tokenIn, tokenOut, amounts, percents, quoteToken, tradeType, routingConfig, undefined, gasPriceWei));
505
+ }
506
+ // Maybe Quote mixed routes
507
+ // if MixedProtocol is specified or no protocol is specified and v2 is supported AND tradeType is ExactIn
508
+ // AND is Mainnet or Gorli
509
+ if (shouldQueryMixedProtocol && mixedProtocolAllowed) {
510
+ log_1.log.info({ protocols, tradeType }, 'Routing across MixedRoutes');
511
+ quotePromises.push(this.mixedQuoter.getRoutesThenQuotes(tokenIn, tokenOut, amounts, percents, quoteToken, tradeType, routingConfig, mixedRouteGasModel));
512
+ }
513
+ const getQuotesResults = await Promise.all(quotePromises);
514
+ const allRoutesWithValidQuotes = [];
515
+ const allCandidatePools = [];
516
+ getQuotesResults.forEach((getQuoteResult) => {
517
+ allRoutesWithValidQuotes.push(...getQuoteResult.routesWithValidQuotes);
518
+ if (getQuoteResult.candidatePools) {
519
+ allCandidatePools.push(getQuoteResult.candidatePools);
520
+ }
521
+ });
522
+ if (allRoutesWithValidQuotes.length === 0) {
523
+ log_1.log.info({ allRoutesWithValidQuotes }, 'Received no valid quotes');
524
+ return null;
525
+ }
526
+ // Given all the quotes for all the amounts for all the routes, find the best combination.
527
+ const bestSwapRoute = await (0, best_swap_route_1.getBestSwapRoute)(amount, percents, allRoutesWithValidQuotes, tradeType, this.chainId, routingConfig, v3GasModel);
528
+ if (bestSwapRoute) {
529
+ this.emitPoolSelectionMetrics(bestSwapRoute, allCandidatePools);
530
+ }
531
+ return bestSwapRoute;
532
+ }
533
+ tradeTypeStr(tradeType) {
534
+ return tradeType === sdk_core_1.TradeType.EXACT_INPUT ? 'ExactIn' : 'ExactOut';
535
+ }
536
+ tokenPairSymbolTradeTypeChainId(tokenIn, tokenOut, tradeType) {
537
+ return `${tokenIn.symbol}/${tokenOut.symbol}/${this.tradeTypeStr(tradeType)}/${this.chainId}`;
538
+ }
539
+ determineCurrencyInOutFromTradeType(tradeType, amount, quoteCurrency) {
540
+ if (tradeType === sdk_core_1.TradeType.EXACT_INPUT) {
541
+ return {
542
+ currencyIn: amount.currency,
543
+ currencyOut: quoteCurrency,
544
+ };
545
+ }
546
+ else {
547
+ return {
548
+ currencyIn: quoteCurrency,
549
+ currencyOut: amount.currency,
550
+ };
551
+ }
552
+ }
553
+ async getGasPriceWei() {
554
+ // Track how long it takes to resolve this async call.
555
+ const beforeGasTimestamp = Date.now();
556
+ // Get an estimate of the gas price to use when estimating gas cost of different routes.
557
+ const { gasPriceWei } = await this.gasPriceProvider.getGasPrice();
558
+ metric_1.metric.putMetric('GasPriceLoad', Date.now() - beforeGasTimestamp, metric_1.MetricLoggerUnit.Milliseconds);
559
+ return gasPriceWei;
560
+ }
561
+ async getGasModels(gasPriceWei, amountToken, quoteToken) {
562
+ const beforeGasModel = Date.now();
563
+ const v3GasModelPromise = this.v3GasModelFactory.buildGasModel({
564
+ chainId: this.chainId,
565
+ gasPriceWei,
566
+ v3poolProvider: this.v3PoolProvider,
567
+ amountToken,
568
+ quoteToken,
569
+ v2poolProvider: this.v2PoolProvider,
570
+ // l2GasDataProvider: this.l2GasDataProvider,
571
+ });
572
+ const mixedRouteGasModelPromise = this.mixedRouteGasModelFactory.buildGasModel({
573
+ chainId: this.chainId,
574
+ gasPriceWei,
575
+ v3poolProvider: this.v3PoolProvider,
576
+ amountToken,
577
+ quoteToken,
578
+ v2poolProvider: this.v2PoolProvider,
579
+ });
580
+ const [v3GasModel, mixedRouteGasModel] = await Promise.all([
581
+ v3GasModelPromise,
582
+ mixedRouteGasModelPromise,
583
+ ]);
584
+ metric_1.metric.putMetric('GasModelCreation', Date.now() - beforeGasModel, metric_1.MetricLoggerUnit.Milliseconds);
585
+ return [v3GasModel, mixedRouteGasModel];
586
+ }
587
+ // Note multiplications here can result in a loss of precision in the amounts (e.g. taking 50% of 101)
588
+ // This is reconcilled at the end of the algorithm by adding any lost precision to one of
589
+ // the splits in the route.
590
+ getAmountDistribution(amount, routingConfig) {
591
+ const { distributionPercent } = routingConfig;
592
+ const percents = [];
593
+ const amounts = [];
594
+ for (let i = 1; i <= 100 / distributionPercent; i++) {
595
+ percents.push(i * distributionPercent);
596
+ amounts.push(amount.multiply(new sdk_core_1.Fraction(i * distributionPercent, 100)));
597
+ }
598
+ return [percents, amounts];
599
+ }
600
+ async buildSwapAndAddMethodParameters(trade, swapAndAddOptions, swapAndAddParameters) {
601
+ const { swapOptions: { recipient, slippageTolerance, deadline, inputTokenPermit }, addLiquidityOptions: addLiquidityConfig, } = swapAndAddOptions;
602
+ const preLiquidityPosition = swapAndAddParameters.preLiquidityPosition;
603
+ const finalBalanceTokenIn = swapAndAddParameters.initialBalanceTokenIn.subtract(trade.inputAmount);
604
+ const finalBalanceTokenOut = swapAndAddParameters.initialBalanceTokenOut.add(trade.outputAmount);
605
+ const approvalTypes = await this.swapRouterProvider.getApprovalType(finalBalanceTokenIn, finalBalanceTokenOut);
606
+ const zeroForOne = finalBalanceTokenIn.currency.wrapped.sortsBefore(finalBalanceTokenOut.currency.wrapped);
607
+ return Object.assign(Object.assign({}, router_sdk_1.SwapRouter.swapAndAddCallParameters(trade, {
608
+ recipient,
609
+ slippageTolerance,
610
+ deadlineOrPreviousBlockhash: deadline,
611
+ inputTokenPermit,
612
+ }, v3_sdk_1.Position.fromAmounts({
613
+ pool: preLiquidityPosition.pool,
614
+ tickLower: preLiquidityPosition.tickLower,
615
+ tickUpper: preLiquidityPosition.tickUpper,
616
+ amount0: zeroForOne
617
+ ? finalBalanceTokenIn.quotient.toString()
618
+ : finalBalanceTokenOut.quotient.toString(),
619
+ amount1: zeroForOne
620
+ ? finalBalanceTokenOut.quotient.toString()
621
+ : finalBalanceTokenIn.quotient.toString(),
622
+ useFullPrecision: false,
623
+ }), addLiquidityConfig, approvalTypes.approvalTokenIn, approvalTypes.approvalTokenOut)), { to: (0, util_1.SWAP_ROUTER_02_ADDRESSES)(this.chainId) });
624
+ }
625
+ emitPoolSelectionMetrics(swapRouteRaw, allPoolsBySelection) {
626
+ const poolAddressesUsed = new Set();
627
+ const { routes: routeAmounts } = swapRouteRaw;
628
+ (0, lodash_1.default)(routeAmounts)
629
+ .flatMap((routeAmount) => {
630
+ const { poolAddresses } = routeAmount;
631
+ return poolAddresses;
632
+ })
633
+ .forEach((address) => {
634
+ poolAddressesUsed.add(address.toLowerCase());
635
+ });
636
+ for (const poolsBySelection of allPoolsBySelection) {
637
+ const { protocol } = poolsBySelection;
638
+ lodash_1.default.forIn(poolsBySelection.selections, (pools, topNSelection) => {
639
+ const topNUsed = lodash_1.default.findLastIndex(pools, (pool) => poolAddressesUsed.has(pool.id.toLowerCase())) + 1;
640
+ metric_1.metric.putMetric(lodash_1.default.capitalize(`${protocol}${topNSelection}`), topNUsed, metric_1.MetricLoggerUnit.Count);
641
+ });
642
+ }
643
+ let hasV3Route = false;
644
+ let hasV2Route = false;
645
+ let hasMixedRoute = false;
646
+ for (const routeAmount of routeAmounts) {
647
+ if (routeAmount.protocol === router_sdk_1.Protocol.V3) {
648
+ hasV3Route = true;
649
+ }
650
+ if (routeAmount.protocol === router_sdk_1.Protocol.V2) {
651
+ hasV2Route = true;
652
+ }
653
+ if (routeAmount.protocol === router_sdk_1.Protocol.MIXED) {
654
+ hasMixedRoute = true;
655
+ }
656
+ }
657
+ if (hasMixedRoute && (hasV3Route || hasV2Route)) {
658
+ if (hasV3Route && hasV2Route) {
659
+ metric_1.metric.putMetric(`MixedAndV3AndV2SplitRoute`, 1, metric_1.MetricLoggerUnit.Count);
660
+ metric_1.metric.putMetric(`MixedAndV3AndV2SplitRouteForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
661
+ }
662
+ else if (hasV3Route) {
663
+ metric_1.metric.putMetric(`MixedAndV3SplitRoute`, 1, metric_1.MetricLoggerUnit.Count);
664
+ metric_1.metric.putMetric(`MixedAndV3SplitRouteForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
665
+ }
666
+ else if (hasV2Route) {
667
+ metric_1.metric.putMetric(`MixedAndV2SplitRoute`, 1, metric_1.MetricLoggerUnit.Count);
668
+ metric_1.metric.putMetric(`MixedAndV2SplitRouteForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
669
+ }
670
+ }
671
+ else if (hasV3Route && hasV2Route) {
672
+ metric_1.metric.putMetric(`V3AndV2SplitRoute`, 1, metric_1.MetricLoggerUnit.Count);
673
+ metric_1.metric.putMetric(`V3AndV2SplitRouteForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
674
+ }
675
+ else if (hasMixedRoute) {
676
+ if (routeAmounts.length > 1) {
677
+ metric_1.metric.putMetric(`MixedSplitRoute`, 1, metric_1.MetricLoggerUnit.Count);
678
+ metric_1.metric.putMetric(`MixedSplitRouteForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
679
+ }
680
+ else {
681
+ metric_1.metric.putMetric(`MixedRoute`, 1, metric_1.MetricLoggerUnit.Count);
682
+ metric_1.metric.putMetric(`MixedRouteForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
683
+ }
684
+ }
685
+ else if (hasV3Route) {
686
+ if (routeAmounts.length > 1) {
687
+ metric_1.metric.putMetric(`V3SplitRoute`, 1, metric_1.MetricLoggerUnit.Count);
688
+ metric_1.metric.putMetric(`V3SplitRouteForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
689
+ }
690
+ else {
691
+ metric_1.metric.putMetric(`V3Route`, 1, metric_1.MetricLoggerUnit.Count);
692
+ metric_1.metric.putMetric(`V3RouteForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
693
+ }
694
+ }
695
+ else if (hasV2Route) {
696
+ if (routeAmounts.length > 1) {
697
+ metric_1.metric.putMetric(`V2SplitRoute`, 1, metric_1.MetricLoggerUnit.Count);
698
+ metric_1.metric.putMetric(`V2SplitRouteForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
699
+ }
700
+ else {
701
+ metric_1.metric.putMetric(`V2Route`, 1, metric_1.MetricLoggerUnit.Count);
702
+ metric_1.metric.putMetric(`V2RouteForChain${this.chainId}`, 1, metric_1.MetricLoggerUnit.Count);
703
+ }
704
+ }
705
+ }
706
+ calculateOptimalRatio(position, sqrtRatioX96, zeroForOne) {
707
+ const upperSqrtRatioX96 = v3_sdk_1.TickMath.getSqrtRatioAtTick(position.tickUpper);
708
+ const lowerSqrtRatioX96 = v3_sdk_1.TickMath.getSqrtRatioAtTick(position.tickLower);
709
+ // returns Fraction(0, 1) for any out of range position regardless of zeroForOne. Implication: function
710
+ // cannot be used to determine the trading direction of out of range positions.
711
+ if (jsbi_1.default.greaterThan(sqrtRatioX96, upperSqrtRatioX96) ||
712
+ jsbi_1.default.lessThan(sqrtRatioX96, lowerSqrtRatioX96)) {
713
+ return new sdk_core_1.Fraction(0, 1);
714
+ }
715
+ const precision = jsbi_1.default.BigInt('1' + '0'.repeat(18));
716
+ 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));
717
+ if (!zeroForOne)
718
+ optimalRatio = optimalRatio.invert();
719
+ return optimalRatio;
720
+ }
721
+ async userHasSufficientBalance(fromAddress, tradeType, amount, quote) {
722
+ try {
723
+ const neededBalance = tradeType === sdk_core_1.TradeType.EXACT_INPUT ? amount : quote;
724
+ let balance;
725
+ if (neededBalance.currency.isNative) {
726
+ balance = await this.provider.getBalance(fromAddress);
727
+ }
728
+ else {
729
+ const tokenContract = Erc20__factory_1.Erc20__factory.connect(neededBalance.currency.address, this.provider);
730
+ balance = await tokenContract.balanceOf(fromAddress);
731
+ }
732
+ return balance.gte(bignumber_1.BigNumber.from(neededBalance.quotient.toString()));
733
+ }
734
+ catch (e) {
735
+ log_1.log.error(e, 'Error while checking user balance');
736
+ return false;
737
+ }
738
+ }
739
+ absoluteValue(fraction) {
740
+ const numeratorAbs = jsbi_1.default.lessThan(fraction.numerator, jsbi_1.default.BigInt(0))
741
+ ? jsbi_1.default.unaryMinus(fraction.numerator)
742
+ : fraction.numerator;
743
+ const denominatorAbs = jsbi_1.default.lessThan(fraction.denominator, jsbi_1.default.BigInt(0))
744
+ ? jsbi_1.default.unaryMinus(fraction.denominator)
745
+ : fraction.denominator;
746
+ return new sdk_core_1.Fraction(numeratorAbs, denominatorAbs);
747
+ }
748
+ getBlockNumberPromise() {
749
+ return (0, async_retry_1.default)(async (_b, attempt) => {
750
+ if (attempt > 1) {
751
+ log_1.log.info(`Get block number attempt ${attempt}`);
752
+ }
753
+ return this.provider.getBlockNumber();
754
+ }, {
755
+ retries: 2,
756
+ minTimeout: 100,
757
+ maxTimeout: 1000,
758
+ });
759
+ }
760
+ }
761
+ exports.AlphaRouter = AlphaRouter;
762
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxwaGEtcm91dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3JvdXRlcnMvYWxwaGEtcm91dGVyL2FscGhhLXJvdXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSx3REFBcUQ7QUFDckQsd0RBQXlFO0FBQ3pFLHFGQUE2RDtBQUM3RCxxREFBbUU7QUFDbkUsZ0RBQXlFO0FBRXpFLDRDQUEwRTtBQUMxRSw4REFBZ0M7QUFDaEMsZ0RBQXdCO0FBQ3hCLG9EQUF1QjtBQUN2Qiw0REFBbUM7QUFFbkMsK0NBNkJ5QjtBQUN6Qiw2RkFHcUQ7QUFLckQsbUVBQStFO0FBQy9FLHVGQUdrRDtBQUNsRCxvRUFHMEM7QUFNMUMsb0VBRzBDO0FBRTFDLCtFQUE0RTtBQUM1RSxxQ0FBc0Q7QUFDdEQsZ0RBQW9EO0FBQ3BELDhDQUsyQjtBQUMzQix3Q0FBcUM7QUFDckMsa0VBR3FDO0FBQ3JDLDhDQUE2RDtBQUM3RCxzRUFBbUU7QUFDbkUsc0NBY21CO0FBRW5CLHFDQUdrQjtBQU1sQixpRUFBOEU7QUFDOUUscUZBQStFO0FBVS9FLDZHQUE2RztBQUM3RyxtRkFBb0Y7QUFDcEYsbUZBQW9GO0FBQ3BGLHVDQUE2RTtBQXdHN0UsTUFBYSxtQkFBdUIsU0FBUSxHQUFjO0lBQy9DLEdBQUcsQ0FBQyxHQUFXLEVBQUUsS0FBUTtRQUNoQyxPQUFPLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzdDLENBQUM7Q0FDRjtBQUpELGtEQUlDO0FBOEdELE1BQWEsV0FBVztJQStCdEIsWUFBWSxFQUNWLE9BQU8sRUFDUCxRQUFRLEVBQ1Isa0JBQWtCLEVBQ2xCLGNBQWMsRUFDZCxvQkFBb0IsRUFDcEIsY0FBYyxFQUNkLGVBQWUsRUFDZixrQkFBa0IsRUFDbEIsYUFBYSxFQUNiLHdCQUF3QixFQUN4QixrQkFBa0IsRUFDbEIsZ0JBQWdCLEVBQ2hCLGlCQUFp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