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