@fanx-protocol/smart-order-router 0.0.1

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 (438) hide show
  1. package/CHANGELOG.md +255 -0
  2. package/LICENSE +674 -0
  3. package/README.md +273 -0
  4. package/build/main/index.d.ts +3 -0
  5. package/build/main/index.js +20 -0
  6. package/build/main/providers/cache-node.d.ts +10 -0
  7. package/build/main/providers/cache-node.js +33 -0
  8. package/build/main/providers/cache.d.ts +14 -0
  9. package/build/main/providers/cache.js +3 -0
  10. package/build/main/providers/caching/route/index.d.ts +2 -0
  11. package/build/main/providers/caching/route/index.js +19 -0
  12. package/build/main/providers/caching/route/model/cache-mode.d.ts +16 -0
  13. package/build/main/providers/caching/route/model/cache-mode.js +21 -0
  14. package/build/main/providers/caching/route/model/cached-route.d.ts +29 -0
  15. package/build/main/providers/caching/route/model/cached-route.js +89 -0
  16. package/build/main/providers/caching/route/model/cached-routes.d.ts +67 -0
  17. package/build/main/providers/caching/route/model/cached-routes.js +81 -0
  18. package/build/main/providers/caching/route/model/index.d.ts +3 -0
  19. package/build/main/providers/caching/route/model/index.js +20 -0
  20. package/build/main/providers/caching/route/route-caching-provider.d.ts +88 -0
  21. package/build/main/providers/caching/route/route-caching-provider.js +72 -0
  22. package/build/main/providers/caching-gas-provider.d.ts +23 -0
  23. package/build/main/providers/caching-gas-provider.js +41 -0
  24. package/build/main/providers/caching-subgraph-provider.d.ts +33 -0
  25. package/build/main/providers/caching-subgraph-provider.js +37 -0
  26. package/build/main/providers/caching-token-list-provider.d.ts +52 -0
  27. package/build/main/providers/caching-token-list-provider.js +147 -0
  28. package/build/main/providers/caching-token-provider.d.ts +24 -0
  29. package/build/main/providers/caching-token-provider.js +108 -0
  30. package/build/main/providers/eip-1559-gas-price-provider.d.ts +31 -0
  31. package/build/main/providers/eip-1559-gas-price-provider.js +71 -0
  32. package/build/main/providers/eth-estimate-gas-provider.d.ts +19 -0
  33. package/build/main/providers/eth-estimate-gas-provider.js +94 -0
  34. package/build/main/providers/eth-gas-station-info-gas-price-provider.d.ts +19 -0
  35. package/build/main/providers/eth-gas-station-info-gas-price-provider.js +36 -0
  36. package/build/main/providers/gas-price-provider.d.ts +10 -0
  37. package/build/main/providers/gas-price-provider.js +10 -0
  38. package/build/main/providers/index.d.ts +38 -0
  39. package/build/main/providers/index.js +55 -0
  40. package/build/main/providers/legacy-gas-price-provider.d.ts +7 -0
  41. package/build/main/providers/legacy-gas-price-provider.js +18 -0
  42. package/build/main/providers/multicall-provider.d.ts +83 -0
  43. package/build/main/providers/multicall-provider.js +15 -0
  44. package/build/main/providers/multicall-uniswap-provider.d.ts +37 -0
  45. package/build/main/providers/multicall-uniswap-provider.js +164 -0
  46. package/build/main/providers/on-chain-gas-price-provider.d.ts +19 -0
  47. package/build/main/providers/on-chain-gas-price-provider.js +36 -0
  48. package/build/main/providers/on-chain-quote-provider.d.ts +258 -0
  49. package/build/main/providers/on-chain-quote-provider.js +693 -0
  50. package/build/main/providers/pool-provider.d.ts +44 -0
  51. package/build/main/providers/pool-provider.js +73 -0
  52. package/build/main/providers/portion-provider.d.ts +86 -0
  53. package/build/main/providers/portion-provider.js +118 -0
  54. package/build/main/providers/provider.d.ts +38 -0
  55. package/build/main/providers/provider.js +3 -0
  56. package/build/main/providers/simulation-provider.d.ts +43 -0
  57. package/build/main/providers/simulation-provider.js +136 -0
  58. package/build/main/providers/static-gas-price-provider.d.ts +7 -0
  59. package/build/main/providers/static-gas-price-provider.js +13 -0
  60. package/build/main/providers/subgraph-provider-with-fallback.d.ts +11 -0
  61. package/build/main/providers/subgraph-provider-with-fallback.js +25 -0
  62. package/build/main/providers/subgraph-provider.d.ts +51 -0
  63. package/build/main/providers/subgraph-provider.js +120 -0
  64. package/build/main/providers/swap-router-provider.d.ts +30 -0
  65. package/build/main/providers/swap-router-provider.js +42 -0
  66. package/build/main/providers/token-fee-fetcher.d.ts +31 -0
  67. package/build/main/providers/token-fee-fetcher.js +108 -0
  68. package/build/main/providers/token-properties-provider.d.ts +31 -0
  69. package/build/main/providers/token-properties-provider.js +118 -0
  70. package/build/main/providers/token-provider.d.ts +38 -0
  71. package/build/main/providers/token-provider.js +175 -0
  72. package/build/main/providers/token-validator-provider.d.ts +42 -0
  73. package/build/main/providers/token-validator-provider.js +99 -0
  74. package/build/main/providers/uri-subgraph-provider.d.ts +20 -0
  75. package/build/main/providers/uri-subgraph-provider.js +65 -0
  76. package/build/main/providers/v2/caching-pool-provider.d.ts +33 -0
  77. package/build/main/providers/v2/caching-pool-provider.js +89 -0
  78. package/build/main/providers/v2/caching-subgraph-provider.d.ts +19 -0
  79. package/build/main/providers/v2/caching-subgraph-provider.js +24 -0
  80. package/build/main/providers/v2/pool-provider.d.ts +63 -0
  81. package/build/main/providers/v2/pool-provider.js +138 -0
  82. package/build/main/providers/v2/quote-provider.d.ts +34 -0
  83. package/build/main/providers/v2/quote-provider.js +90 -0
  84. package/build/main/providers/v2/static-subgraph-provider.d.ts +19 -0
  85. package/build/main/providers/v2/static-subgraph-provider.js +75 -0
  86. package/build/main/providers/v2/subgraph-provider-with-fallback.d.ts +16 -0
  87. package/build/main/providers/v2/subgraph-provider-with-fallback.js +23 -0
  88. package/build/main/providers/v2/subgraph-provider.d.ts +36 -0
  89. package/build/main/providers/v2/subgraph-provider.js +174 -0
  90. package/build/main/providers/v2/uri-subgraph-provider.d.ts +4 -0
  91. package/build/main/providers/v2/uri-subgraph-provider.js +8 -0
  92. package/build/main/providers/v3/caching-pool-provider.d.ts +32 -0
  93. package/build/main/providers/v3/caching-pool-provider.js +84 -0
  94. package/build/main/providers/v3/caching-subgraph-provider.d.ts +19 -0
  95. package/build/main/providers/v3/caching-subgraph-provider.js +24 -0
  96. package/build/main/providers/v3/gas-data-provider.d.ts +39 -0
  97. package/build/main/providers/v3/gas-data-provider.js +26 -0
  98. package/build/main/providers/v3/pool-provider.d.ts +77 -0
  99. package/build/main/providers/v3/pool-provider.js +108 -0
  100. package/build/main/providers/v3/static-subgraph-provider.d.ts +21 -0
  101. package/build/main/providers/v3/static-subgraph-provider.js +89 -0
  102. package/build/main/providers/v3/subgraph-provider-with-fallback.d.ts +12 -0
  103. package/build/main/providers/v3/subgraph-provider-with-fallback.js +19 -0
  104. package/build/main/providers/v3/subgraph-provider.d.ts +46 -0
  105. package/build/main/providers/v3/subgraph-provider.js +54 -0
  106. package/build/main/providers/v3/uri-subgraph-provider.d.ts +4 -0
  107. package/build/main/providers/v3/uri-subgraph-provider.js +8 -0
  108. package/build/main/routers/alpha-router/alpha-router.d.ts +347 -0
  109. package/build/main/routers/alpha-router/alpha-router.js +1219 -0
  110. package/build/main/routers/alpha-router/config.d.ts +4 -0
  111. package/build/main/routers/alpha-router/config.js +40 -0
  112. package/build/main/routers/alpha-router/entities/index.d.ts +1 -0
  113. package/build/main/routers/alpha-router/entities/index.js +18 -0
  114. package/build/main/routers/alpha-router/entities/route-with-valid-quote.d.ts +167 -0
  115. package/build/main/routers/alpha-router/entities/route-with-valid-quote.js +166 -0
  116. package/build/main/routers/alpha-router/functions/best-swap-route.d.ts +22 -0
  117. package/build/main/routers/alpha-router/functions/best-swap-route.js +534 -0
  118. package/build/main/routers/alpha-router/functions/calculate-ratio-amount-in.d.ts +3 -0
  119. package/build/main/routers/alpha-router/functions/calculate-ratio-amount-in.js +18 -0
  120. package/build/main/routers/alpha-router/functions/compute-all-routes.d.ts +9 -0
  121. package/build/main/routers/alpha-router/functions/compute-all-routes.js +104 -0
  122. package/build/main/routers/alpha-router/functions/get-candidate-pools.d.ts +100 -0
  123. package/build/main/routers/alpha-router/functions/get-candidate-pools.js +1008 -0
  124. package/build/main/routers/alpha-router/gas-models/gas-costs.d.ts +12 -0
  125. package/build/main/routers/alpha-router/gas-models/gas-costs.js +90 -0
  126. package/build/main/routers/alpha-router/gas-models/gas-model.d.ts +106 -0
  127. package/build/main/routers/alpha-router/gas-models/gas-model.js +68 -0
  128. package/build/main/routers/alpha-router/gas-models/index.d.ts +2 -0
  129. package/build/main/routers/alpha-router/gas-models/index.js +19 -0
  130. package/build/main/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.d.ts +24 -0
  131. package/build/main/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.js +161 -0
  132. package/build/main/routers/alpha-router/gas-models/tick-based-heuristic-gas-model.d.ts +15 -0
  133. package/build/main/routers/alpha-router/gas-models/tick-based-heuristic-gas-model.js +185 -0
  134. package/build/main/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.d.ts +31 -0
  135. package/build/main/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.js +169 -0
  136. package/build/main/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.d.ts +26 -0
  137. package/build/main/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.js +41 -0
  138. package/build/main/routers/alpha-router/index.d.ts +4 -0
  139. package/build/main/routers/alpha-router/index.js +21 -0
  140. package/build/main/routers/alpha-router/quoters/base-quoter.d.ts +76 -0
  141. package/build/main/routers/alpha-router/quoters/base-quoter.js +76 -0
  142. package/build/main/routers/alpha-router/quoters/index.d.ts +5 -0
  143. package/build/main/routers/alpha-router/quoters/index.js +22 -0
  144. package/build/main/routers/alpha-router/quoters/mixed-quoter.d.ts +28 -0
  145. package/build/main/routers/alpha-router/quoters/mixed-quoter.js +154 -0
  146. package/build/main/routers/alpha-router/quoters/model/index.d.ts +1 -0
  147. package/build/main/routers/alpha-router/quoters/model/index.js +18 -0
  148. package/build/main/routers/alpha-router/quoters/model/results/get-quotes-result.d.ts +6 -0
  149. package/build/main/routers/alpha-router/quoters/model/results/get-quotes-result.js +3 -0
  150. package/build/main/routers/alpha-router/quoters/model/results/get-routes-result.d.ts +6 -0
  151. package/build/main/routers/alpha-router/quoters/model/results/get-routes-result.js +3 -0
  152. package/build/main/routers/alpha-router/quoters/model/results/index.d.ts +2 -0
  153. package/build/main/routers/alpha-router/quoters/model/results/index.js +19 -0
  154. package/build/main/routers/alpha-router/quoters/v2-quoter.d.ts +24 -0
  155. package/build/main/routers/alpha-router/quoters/v2-quoter.js +140 -0
  156. package/build/main/routers/alpha-router/quoters/v3-quoter.d.ts +19 -0
  157. package/build/main/routers/alpha-router/quoters/v3-quoter.js +117 -0
  158. package/build/main/routers/index.d.ts +3 -0
  159. package/build/main/routers/index.js +20 -0
  160. package/build/main/routers/router.d.ts +186 -0
  161. package/build/main/routers/router.js +55 -0
  162. package/build/main/tsconfig.tsbuildinfo +1 -0
  163. package/build/main/types/other/commons.d.ts +16 -0
  164. package/build/main/types/other/commons.js +6 -0
  165. package/build/main/types/other/factories/Erc20__factory.d.ts +45 -0
  166. package/build/main/types/other/factories/Erc20__factory.js +240 -0
  167. package/build/main/types/other/factories/GasDataArbitrum__factory.d.ts +18 -0
  168. package/build/main/types/other/factories/GasDataArbitrum__factory.js +58 -0
  169. package/build/main/types/other/factories/IMixedRouteQuoterV1__factory.d.ts +41 -0
  170. package/build/main/types/other/factories/IMixedRouteQuoterV1__factory.js +156 -0
  171. package/build/main/types/other/factories/ITokenValidator__factory.d.ts +22 -0
  172. package/build/main/types/other/factories/ITokenValidator__factory.js +78 -0
  173. package/build/main/types/other/factories/MixedRouteQuoterV2__factory.d.ts +86 -0
  174. package/build/main/types/other/factories/MixedRouteQuoterV2__factory.js +477 -0
  175. package/build/main/types/other/factories/Permit2__factory.d.ts +87 -0
  176. package/build/main/types/other/factories/Permit2__factory.js +936 -0
  177. package/build/main/types/other/factories/SwapRouter02__factory.d.ts +67 -0
  178. package/build/main/types/other/factories/SwapRouter02__factory.js +1098 -0
  179. package/build/main/types/other/factories/TokenFeeDetector__factory.d.ts +47 -0
  180. package/build/main/types/other/factories/TokenFeeDetector__factory.js +243 -0
  181. package/build/main/types/v2/commons.d.ts +16 -0
  182. package/build/main/types/v2/commons.js +6 -0
  183. package/build/main/types/v2/factories/IUniswapV2Pair__factory.d.ts +35 -0
  184. package/build/main/types/v2/factories/IUniswapV2Pair__factory.js +671 -0
  185. package/build/main/types/v3/commons.d.ts +16 -0
  186. package/build/main/types/v3/commons.js +6 -0
  187. package/build/main/types/v3/factories/IERC20Metadata__factory.d.ts +35 -0
  188. package/build/main/types/v3/factories/IERC20Metadata__factory.js +242 -0
  189. package/build/main/types/v3/factories/IQuoterV2__factory.d.ts +41 -0
  190. package/build/main/types/v3/factories/IQuoterV2__factory.js +220 -0
  191. package/build/main/types/v3/factories/IUniswapV3PoolState__factory.d.ts +22 -0
  192. package/build/main/types/v3/factories/IUniswapV3PoolState__factory.js +266 -0
  193. package/build/main/types/v3/factories/UniswapInterfaceMulticall__factory.d.ts +61 -0
  194. package/build/main/types/v3/factories/UniswapInterfaceMulticall__factory.js +127 -0
  195. package/build/main/util/addresses.d.ts +24 -0
  196. package/build/main/util/addresses.js +76 -0
  197. package/build/main/util/amounts.d.ts +9 -0
  198. package/build/main/util/amounts.js +73 -0
  199. package/build/main/util/chains.d.ts +31 -0
  200. package/build/main/util/chains.js +97 -0
  201. package/build/main/util/gas-factory-helpers.d.ts +33 -0
  202. package/build/main/util/gas-factory-helpers.js +463 -0
  203. package/build/main/util/index.d.ts +7 -0
  204. package/build/main/util/index.js +24 -0
  205. package/build/main/util/l2FeeChains.d.ts +2 -0
  206. package/build/main/util/l2FeeChains.js +13 -0
  207. package/build/main/util/log.d.ts +3 -0
  208. package/build/main/util/log.js +97 -0
  209. package/build/main/util/methodParameters.d.ts +5 -0
  210. package/build/main/util/methodParameters.js +183 -0
  211. package/build/main/util/metric.d.ts +48 -0
  212. package/build/main/util/metric.js +59 -0
  213. package/build/main/util/onchainQuoteProviderConfigs.d.ts +42 -0
  214. package/build/main/util/onchainQuoteProviderConfigs.js +74 -0
  215. package/build/main/util/protocols.d.ts +2 -0
  216. package/build/main/util/protocols.js +20 -0
  217. package/build/main/util/routes.d.ts +11 -0
  218. package/build/main/util/routes.js +149 -0
  219. package/build/main/util/unsupported-tokens.d.ts +37 -0
  220. package/build/main/util/unsupported-tokens.js +1119 -0
  221. package/build/module/index.d.ts +3 -0
  222. package/build/module/index.js +4 -0
  223. package/build/module/providers/cache-node.d.ts +10 -0
  224. package/build/module/providers/cache-node.js +29 -0
  225. package/build/module/providers/cache.d.ts +14 -0
  226. package/build/module/providers/cache.js +2 -0
  227. package/build/module/providers/caching/route/index.d.ts +2 -0
  228. package/build/module/providers/caching/route/index.js +3 -0
  229. package/build/module/providers/caching/route/model/cache-mode.d.ts +16 -0
  230. package/build/module/providers/caching/route/model/cache-mode.js +18 -0
  231. package/build/module/providers/caching/route/model/cached-route.d.ts +29 -0
  232. package/build/module/providers/caching/route/model/cached-route.js +85 -0
  233. package/build/module/providers/caching/route/model/cached-routes.d.ts +67 -0
  234. package/build/module/providers/caching/route/model/cached-routes.js +74 -0
  235. package/build/module/providers/caching/route/model/index.d.ts +3 -0
  236. package/build/module/providers/caching/route/model/index.js +4 -0
  237. package/build/module/providers/caching/route/route-caching-provider.d.ts +88 -0
  238. package/build/module/providers/caching/route/route-caching-provider.js +68 -0
  239. package/build/module/providers/caching-gas-provider.d.ts +23 -0
  240. package/build/module/providers/caching-gas-provider.js +37 -0
  241. package/build/module/providers/caching-subgraph-provider.d.ts +33 -0
  242. package/build/module/providers/caching-subgraph-provider.js +33 -0
  243. package/build/module/providers/caching-token-list-provider.d.ts +52 -0
  244. package/build/module/providers/caching-token-list-provider.js +140 -0
  245. package/build/module/providers/caching-token-provider.d.ts +24 -0
  246. package/build/module/providers/caching-token-provider.js +101 -0
  247. package/build/module/providers/eip-1559-gas-price-provider.d.ts +31 -0
  248. package/build/module/providers/eip-1559-gas-price-provider.js +64 -0
  249. package/build/module/providers/eth-estimate-gas-provider.d.ts +19 -0
  250. package/build/module/providers/eth-estimate-gas-provider.js +102 -0
  251. package/build/module/providers/eth-gas-station-info-gas-price-provider.d.ts +19 -0
  252. package/build/module/providers/eth-gas-station-info-gas-price-provider.js +29 -0
  253. package/build/module/providers/gas-price-provider.d.ts +10 -0
  254. package/build/module/providers/gas-price-provider.js +6 -0
  255. package/build/module/providers/index.d.ts +38 -0
  256. package/build/module/providers/index.js +39 -0
  257. package/build/module/providers/legacy-gas-price-provider.d.ts +7 -0
  258. package/build/module/providers/legacy-gas-price-provider.js +14 -0
  259. package/build/module/providers/multicall-provider.d.ts +83 -0
  260. package/build/module/providers/multicall-provider.js +11 -0
  261. package/build/module/providers/multicall-uniswap-provider.d.ts +37 -0
  262. package/build/module/providers/multicall-uniswap-provider.js +157 -0
  263. package/build/module/providers/on-chain-gas-price-provider.d.ts +19 -0
  264. package/build/module/providers/on-chain-gas-price-provider.js +32 -0
  265. package/build/module/providers/on-chain-quote-provider.d.ts +258 -0
  266. package/build/module/providers/on-chain-quote-provider.js +687 -0
  267. package/build/module/providers/pool-provider.d.ts +44 -0
  268. package/build/module/providers/pool-provider.js +66 -0
  269. package/build/module/providers/portion-provider.d.ts +86 -0
  270. package/build/module/providers/portion-provider.js +114 -0
  271. package/build/module/providers/provider.d.ts +38 -0
  272. package/build/module/providers/provider.js +2 -0
  273. package/build/module/providers/simulation-provider.d.ts +43 -0
  274. package/build/module/providers/simulation-provider.js +138 -0
  275. package/build/module/providers/static-gas-price-provider.d.ts +7 -0
  276. package/build/module/providers/static-gas-price-provider.js +9 -0
  277. package/build/module/providers/subgraph-provider-with-fallback.d.ts +11 -0
  278. package/build/module/providers/subgraph-provider-with-fallback.js +21 -0
  279. package/build/module/providers/subgraph-provider.d.ts +51 -0
  280. package/build/module/providers/subgraph-provider.js +113 -0
  281. package/build/module/providers/swap-router-provider.d.ts +30 -0
  282. package/build/module/providers/swap-router-provider.js +38 -0
  283. package/build/module/providers/token-fee-fetcher.d.ts +31 -0
  284. package/build/module/providers/token-fee-fetcher.js +104 -0
  285. package/build/module/providers/token-properties-provider.d.ts +31 -0
  286. package/build/module/providers/token-properties-provider.js +114 -0
  287. package/build/module/providers/token-provider.d.ts +38 -0
  288. package/build/module/providers/token-provider.js +164 -0
  289. package/build/module/providers/token-validator-provider.d.ts +42 -0
  290. package/build/module/providers/token-validator-provider.js +92 -0
  291. package/build/module/providers/uri-subgraph-provider.d.ts +20 -0
  292. package/build/module/providers/uri-subgraph-provider.js +58 -0
  293. package/build/module/providers/v2/caching-pool-provider.d.ts +33 -0
  294. package/build/module/providers/v2/caching-pool-provider.js +85 -0
  295. package/build/module/providers/v2/caching-subgraph-provider.d.ts +19 -0
  296. package/build/module/providers/v2/caching-subgraph-provider.js +20 -0
  297. package/build/module/providers/v2/pool-provider.d.ts +63 -0
  298. package/build/module/providers/v2/pool-provider.js +131 -0
  299. package/build/module/providers/v2/quote-provider.d.ts +34 -0
  300. package/build/module/providers/v2/quote-provider.js +86 -0
  301. package/build/module/providers/v2/static-subgraph-provider.d.ts +19 -0
  302. package/build/module/providers/v2/static-subgraph-provider.js +68 -0
  303. package/build/module/providers/v2/subgraph-provider-with-fallback.d.ts +16 -0
  304. package/build/module/providers/v2/subgraph-provider-with-fallback.js +19 -0
  305. package/build/module/providers/v2/subgraph-provider.d.ts +36 -0
  306. package/build/module/providers/v2/subgraph-provider.js +167 -0
  307. package/build/module/providers/v2/uri-subgraph-provider.d.ts +4 -0
  308. package/build/module/providers/v2/uri-subgraph-provider.js +4 -0
  309. package/build/module/providers/v3/caching-pool-provider.d.ts +32 -0
  310. package/build/module/providers/v3/caching-pool-provider.js +77 -0
  311. package/build/module/providers/v3/caching-subgraph-provider.d.ts +19 -0
  312. package/build/module/providers/v3/caching-subgraph-provider.js +20 -0
  313. package/build/module/providers/v3/gas-data-provider.d.ts +39 -0
  314. package/build/module/providers/v3/gas-data-provider.js +22 -0
  315. package/build/module/providers/v3/pool-provider.d.ts +77 -0
  316. package/build/module/providers/v3/pool-provider.js +101 -0
  317. package/build/module/providers/v3/static-subgraph-provider.d.ts +21 -0
  318. package/build/module/providers/v3/static-subgraph-provider.js +82 -0
  319. package/build/module/providers/v3/subgraph-provider-with-fallback.d.ts +12 -0
  320. package/build/module/providers/v3/subgraph-provider-with-fallback.js +15 -0
  321. package/build/module/providers/v3/subgraph-provider.d.ts +46 -0
  322. package/build/module/providers/v3/subgraph-provider.js +50 -0
  323. package/build/module/providers/v3/uri-subgraph-provider.d.ts +4 -0
  324. package/build/module/providers/v3/uri-subgraph-provider.js +4 -0
  325. package/build/module/routers/alpha-router/alpha-router.d.ts +347 -0
  326. package/build/module/routers/alpha-router/alpha-router.js +1229 -0
  327. package/build/module/routers/alpha-router/config.d.ts +4 -0
  328. package/build/module/routers/alpha-router/config.js +36 -0
  329. package/build/module/routers/alpha-router/entities/index.d.ts +1 -0
  330. package/build/module/routers/alpha-router/entities/index.js +2 -0
  331. package/build/module/routers/alpha-router/entities/route-with-valid-quote.d.ts +167 -0
  332. package/build/module/routers/alpha-router/entities/route-with-valid-quote.js +157 -0
  333. package/build/module/routers/alpha-router/functions/best-swap-route.d.ts +22 -0
  334. package/build/module/routers/alpha-router/functions/best-swap-route.js +526 -0
  335. package/build/module/routers/alpha-router/functions/calculate-ratio-amount-in.d.ts +3 -0
  336. package/build/module/routers/alpha-router/functions/calculate-ratio-amount-in.js +14 -0
  337. package/build/module/routers/alpha-router/functions/compute-all-routes.d.ts +9 -0
  338. package/build/module/routers/alpha-router/functions/compute-all-routes.js +97 -0
  339. package/build/module/routers/alpha-router/functions/get-candidate-pools.d.ts +100 -0
  340. package/build/module/routers/alpha-router/functions/get-candidate-pools.js +998 -0
  341. package/build/module/routers/alpha-router/gas-models/gas-costs.d.ts +12 -0
  342. package/build/module/routers/alpha-router/gas-models/gas-costs.js +79 -0
  343. package/build/module/routers/alpha-router/gas-models/gas-model.d.ts +106 -0
  344. package/build/module/routers/alpha-router/gas-models/gas-model.js +102 -0
  345. package/build/module/routers/alpha-router/gas-models/index.d.ts +2 -0
  346. package/build/module/routers/alpha-router/gas-models/index.js +3 -0
  347. package/build/module/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.d.ts +24 -0
  348. package/build/module/routers/alpha-router/gas-models/mixedRoute/mixed-route-heuristic-gas-model.js +154 -0
  349. package/build/module/routers/alpha-router/gas-models/tick-based-heuristic-gas-model.d.ts +15 -0
  350. package/build/module/routers/alpha-router/gas-models/tick-based-heuristic-gas-model.js +181 -0
  351. package/build/module/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.d.ts +31 -0
  352. package/build/module/routers/alpha-router/gas-models/v2/v2-heuristic-gas-model.js +162 -0
  353. package/build/module/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.d.ts +26 -0
  354. package/build/module/routers/alpha-router/gas-models/v3/v3-heuristic-gas-model.js +37 -0
  355. package/build/module/routers/alpha-router/index.d.ts +4 -0
  356. package/build/module/routers/alpha-router/index.js +5 -0
  357. package/build/module/routers/alpha-router/quoters/base-quoter.d.ts +76 -0
  358. package/build/module/routers/alpha-router/quoters/base-quoter.js +69 -0
  359. package/build/module/routers/alpha-router/quoters/index.d.ts +5 -0
  360. package/build/module/routers/alpha-router/quoters/index.js +6 -0
  361. package/build/module/routers/alpha-router/quoters/mixed-quoter.d.ts +28 -0
  362. package/build/module/routers/alpha-router/quoters/mixed-quoter.js +152 -0
  363. package/build/module/routers/alpha-router/quoters/model/index.d.ts +1 -0
  364. package/build/module/routers/alpha-router/quoters/model/index.js +2 -0
  365. package/build/module/routers/alpha-router/quoters/model/results/get-quotes-result.d.ts +6 -0
  366. package/build/module/routers/alpha-router/quoters/model/results/get-quotes-result.js +2 -0
  367. package/build/module/routers/alpha-router/quoters/model/results/get-routes-result.d.ts +6 -0
  368. package/build/module/routers/alpha-router/quoters/model/results/get-routes-result.js +2 -0
  369. package/build/module/routers/alpha-router/quoters/model/results/index.d.ts +2 -0
  370. package/build/module/routers/alpha-router/quoters/model/results/index.js +3 -0
  371. package/build/module/routers/alpha-router/quoters/v2-quoter.d.ts +24 -0
  372. package/build/module/routers/alpha-router/quoters/v2-quoter.js +137 -0
  373. package/build/module/routers/alpha-router/quoters/v3-quoter.d.ts +19 -0
  374. package/build/module/routers/alpha-router/quoters/v3-quoter.js +110 -0
  375. package/build/module/routers/index.d.ts +3 -0
  376. package/build/module/routers/index.js +4 -0
  377. package/build/module/routers/router.d.ts +186 -0
  378. package/build/module/routers/router.js +47 -0
  379. package/build/module/tsconfig.module.tsbuildinfo +1 -0
  380. package/build/module/types/other/commons.d.ts +16 -0
  381. package/build/module/types/other/commons.js +5 -0
  382. package/build/module/types/other/factories/Erc20__factory.d.ts +45 -0
  383. package/build/module/types/other/factories/Erc20__factory.js +236 -0
  384. package/build/module/types/other/factories/GasDataArbitrum__factory.d.ts +18 -0
  385. package/build/module/types/other/factories/GasDataArbitrum__factory.js +54 -0
  386. package/build/module/types/other/factories/IMixedRouteQuoterV1__factory.d.ts +41 -0
  387. package/build/module/types/other/factories/IMixedRouteQuoterV1__factory.js +152 -0
  388. package/build/module/types/other/factories/ITokenValidator__factory.d.ts +22 -0
  389. package/build/module/types/other/factories/ITokenValidator__factory.js +74 -0
  390. package/build/module/types/other/factories/MixedRouteQuoterV2__factory.d.ts +86 -0
  391. package/build/module/types/other/factories/MixedRouteQuoterV2__factory.js +473 -0
  392. package/build/module/types/other/factories/Permit2__factory.d.ts +87 -0
  393. package/build/module/types/other/factories/Permit2__factory.js +932 -0
  394. package/build/module/types/other/factories/SwapRouter02__factory.d.ts +67 -0
  395. package/build/module/types/other/factories/SwapRouter02__factory.js +1094 -0
  396. package/build/module/types/other/factories/TokenFeeDetector__factory.d.ts +47 -0
  397. package/build/module/types/other/factories/TokenFeeDetector__factory.js +239 -0
  398. package/build/module/types/v2/commons.d.ts +16 -0
  399. package/build/module/types/v2/commons.js +5 -0
  400. package/build/module/types/v2/factories/IUniswapV2Pair__factory.d.ts +35 -0
  401. package/build/module/types/v2/factories/IUniswapV2Pair__factory.js +667 -0
  402. package/build/module/types/v3/commons.d.ts +16 -0
  403. package/build/module/types/v3/commons.js +5 -0
  404. package/build/module/types/v3/factories/IERC20Metadata__factory.d.ts +35 -0
  405. package/build/module/types/v3/factories/IERC20Metadata__factory.js +238 -0
  406. package/build/module/types/v3/factories/IQuoterV2__factory.d.ts +41 -0
  407. package/build/module/types/v3/factories/IQuoterV2__factory.js +216 -0
  408. package/build/module/types/v3/factories/IUniswapV3PoolState__factory.d.ts +22 -0
  409. package/build/module/types/v3/factories/IUniswapV3PoolState__factory.js +262 -0
  410. package/build/module/types/v3/factories/UniswapInterfaceMulticall__factory.d.ts +61 -0
  411. package/build/module/types/v3/factories/UniswapInterfaceMulticall__factory.js +123 -0
  412. package/build/module/util/addresses.d.ts +24 -0
  413. package/build/module/util/addresses.js +69 -0
  414. package/build/module/util/amounts.d.ts +9 -0
  415. package/build/module/util/amounts.js +62 -0
  416. package/build/module/util/chains.d.ts +31 -0
  417. package/build/module/util/chains.js +89 -0
  418. package/build/module/util/gas-factory-helpers.d.ts +33 -0
  419. package/build/module/util/gas-factory-helpers.js +446 -0
  420. package/build/module/util/index.d.ts +7 -0
  421. package/build/module/util/index.js +8 -0
  422. package/build/module/util/l2FeeChains.d.ts +2 -0
  423. package/build/module/util/l2FeeChains.js +10 -0
  424. package/build/module/util/log.d.ts +3 -0
  425. package/build/module/util/log.js +93 -0
  426. package/build/module/util/methodParameters.d.ts +5 -0
  427. package/build/module/util/methodParameters.js +181 -0
  428. package/build/module/util/metric.d.ts +48 -0
  429. package/build/module/util/metric.js +53 -0
  430. package/build/module/util/onchainQuoteProviderConfigs.d.ts +42 -0
  431. package/build/module/util/onchainQuoteProviderConfigs.js +76 -0
  432. package/build/module/util/protocols.d.ts +2 -0
  433. package/build/module/util/protocols.js +16 -0
  434. package/build/module/util/routes.d.ts +11 -0
  435. package/build/module/util/routes.js +137 -0
  436. package/build/module/util/unsupported-tokens.d.ts +37 -0
  437. package/build/module/util/unsupported-tokens.js +1116 -0
  438. package/package.json +133 -0
@@ -0,0 +1,687 @@
1
+ import { BigNumber } from '@ethersproject/bignumber';
2
+ import { encodeMixedRouteToPath, MixedRouteSDK, Protocol, } from '@fanx-protocol/router-sdk';
3
+ import { encodeRouteToPath as encodeV3RouteToPath } from '@fanx-protocol/v3-sdk';
4
+ // import {
5
+ // encodeRouteToPath as encodeV4RouteToPath,
6
+ // Pool as V4Pool,
7
+ // } from '@fanx-protocol/v4-sdk';
8
+ import retry from 'async-retry';
9
+ import _ from 'lodash';
10
+ import stats from 'stats-lite';
11
+ import { V2Route } from '../routers/router';
12
+ import { IMixedRouteQuoterV1__factory } from '../types/other/factories/IMixedRouteQuoterV1__factory';
13
+ import { MixedRouteQuoterV2__factory } from '../types/other/factories/MixedRouteQuoterV2__factory';
14
+ // import { V4Quoter__factory } from '../types/other/factories/V4Quoter__factory';
15
+ import { IQuoterV2__factory } from '../types/v3/factories/IQuoterV2__factory';
16
+ import { ID_TO_NETWORK_NAME, metric, MetricLoggerUnit, MIXED_ROUTE_QUOTER_V1_ADDRESSES, MIXED_ROUTE_QUOTER_V2_ADDRESSES, NEW_QUOTER_V2_ADDRESSES, } from '../util';
17
+ import { log } from '../util/log';
18
+ import { DEFAULT_BLOCK_NUMBER_CONFIGS, DEFAULT_SUCCESS_RATE_FAILURE_OVERRIDES, } from '../util/onchainQuoteProviderConfigs';
19
+ import { routeToString } from '../util/routes';
20
+ export class BlockConflictError extends Error {
21
+ constructor() {
22
+ super(...arguments);
23
+ this.name = 'BlockConflictError';
24
+ }
25
+ }
26
+ export class SuccessRateError extends Error {
27
+ constructor() {
28
+ super(...arguments);
29
+ this.name = 'SuccessRateError';
30
+ }
31
+ }
32
+ export class ProviderBlockHeaderError extends Error {
33
+ constructor() {
34
+ super(...arguments);
35
+ this.name = 'ProviderBlockHeaderError';
36
+ }
37
+ }
38
+ export class ProviderTimeoutError extends Error {
39
+ constructor() {
40
+ super(...arguments);
41
+ this.name = 'ProviderTimeoutError';
42
+ }
43
+ }
44
+ /**
45
+ * This error typically means that the gas used by the multicall has
46
+ * exceeded the total call gas limit set by the node provider.
47
+ *
48
+ * This can be resolved by modifying BatchParams to request fewer
49
+ * quotes per call, or to set a lower gas limit per quote.
50
+ *
51
+ * @export
52
+ * @class ProviderGasError
53
+ */
54
+ export class ProviderGasError extends Error {
55
+ constructor() {
56
+ super(...arguments);
57
+ this.name = 'ProviderGasError';
58
+ }
59
+ }
60
+ const DEFAULT_BATCH_RETRIES = 2;
61
+ /**
62
+ * Computes on chain quotes for swaps. For pure V3 routes, quotes are computed on-chain using
63
+ * the 'QuoterV2' smart contract. For exactIn mixed and V2 routes, quotes are computed using the 'MixedRouteQuoterV1' contract
64
+ * This is because computing quotes off-chain would require fetching all the tick data for each pool, which is a lot of data.
65
+ *
66
+ * To minimize the number of requests for quotes we use a Multicall contract. Generally
67
+ * the number of quotes to fetch exceeds the maximum we can fit in a single multicall
68
+ * while staying under gas limits, so we also batch these quotes across multiple multicalls.
69
+ *
70
+ * The biggest challenge with the quote provider is dealing with various gas limits.
71
+ * Each provider sets a limit on the amount of gas a call can consume (on Infura this
72
+ * is approximately 10x the block max size), so we must ensure each multicall does not
73
+ * exceed this limit. Additionally, each quote on V3 can consume a large number of gas if
74
+ * the pool lacks liquidity and the swap would cause all the ticks to be traversed.
75
+ *
76
+ * To ensure we don't exceed the node's call limit, we limit the gas used by each quote to
77
+ * a specific value, and we limit the number of quotes in each multicall request. Users of this
78
+ * class should set BatchParams such that multicallChunk * gasLimitPerCall is less than their node
79
+ * providers total gas limit per call.
80
+ *
81
+ * @export
82
+ * @class OnChainQuoteProvider
83
+ */
84
+ export class OnChainQuoteProvider {
85
+ /**
86
+ * Creates an instance of OnChainQuoteProvider.
87
+ *
88
+ * @param chainId The chain to get quotes for.
89
+ * @param provider The web 3 provider.
90
+ * @param multicall2Provider The multicall provider to use to get the quotes on-chain.
91
+ * Only supports the Uniswap Multicall contract as it needs the gas limitting functionality.
92
+ * @param retryOptions The retry options for each call to the multicall.
93
+ * @param batchParams The parameters for each batched call to the multicall.
94
+ * @param gasErrorFailureOverride The gas and chunk parameters to use when retrying a batch that failed due to out of gas.
95
+ * @param successRateFailureOverrides The parameters for retries when we fail to get quotes.
96
+ * @param blockNumberConfig Parameters for adjusting which block we get quotes from, and how to handle block header not found errors.
97
+ * @param [quoterAddressOverride] Overrides the address of the quoter contract to use.
98
+ * @param metricsPrefix metrics prefix to differentiate between different instances of the quote provider.
99
+ */
100
+ constructor(chainId, provider,
101
+ // Only supports Uniswap Multicall as it needs the gas limitting functionality.
102
+ multicall2Provider,
103
+ // retryOptions, batchParams, and gasErrorFailureOverride are always override in alpha-router
104
+ // so below default values are always not going to be picked up in prod.
105
+ // So we will not extract out below default values into constants.
106
+ retryOptions = {
107
+ retries: DEFAULT_BATCH_RETRIES,
108
+ minTimeout: 25,
109
+ maxTimeout: 250,
110
+ }, batchParams = (_optimisticCachedRoutes, _useMixedRouteQuoter) => {
111
+ return {
112
+ multicallChunk: 150,
113
+ gasLimitPerCall: 1000000,
114
+ quoteMinSuccessRate: 0.2,
115
+ };
116
+ }, gasErrorFailureOverride = {
117
+ gasLimitOverride: 1500000,
118
+ multicallChunk: 100,
119
+ },
120
+ // successRateFailureOverrides and blockNumberConfig are not always override in alpha-router.
121
+ // So we will extract out below default values into constants.
122
+ // In alpha-router default case, we will also define the constants with same values as below.
123
+ successRateFailureOverrides = DEFAULT_SUCCESS_RATE_FAILURE_OVERRIDES, blockNumberConfig = DEFAULT_BLOCK_NUMBER_CONFIGS, quoterAddressOverride, metricsPrefix = (chainId, useMixedRouteQuoter, optimisticCachedRoutes) => useMixedRouteQuoter
124
+ ? `ChainId_${chainId}_MixedQuoter_OptimisticCachedRoutes${optimisticCachedRoutes}_`
125
+ : `ChainId_${chainId}_V3Quoter_OptimisticCachedRoutes${optimisticCachedRoutes}_`) {
126
+ this.chainId = chainId;
127
+ this.provider = provider;
128
+ this.multicall2Provider = multicall2Provider;
129
+ this.retryOptions = retryOptions;
130
+ this.batchParams = batchParams;
131
+ this.gasErrorFailureOverride = gasErrorFailureOverride;
132
+ this.successRateFailureOverrides = successRateFailureOverrides;
133
+ this.blockNumberConfig = blockNumberConfig;
134
+ this.quoterAddressOverride = quoterAddressOverride;
135
+ this.metricsPrefix = metricsPrefix;
136
+ }
137
+ getQuoterAddress(useMixedRouteQuoter, mixedRouteContainsV4Pool, protocol) {
138
+ if (this.quoterAddressOverride) {
139
+ const quoterAddress = this.quoterAddressOverride(useMixedRouteQuoter, mixedRouteContainsV4Pool, protocol);
140
+ if (!quoterAddress) {
141
+ throw new Error(`No address for the quoter contract on chain id: ${this.chainId}`);
142
+ }
143
+ return quoterAddress;
144
+ }
145
+ const quoterAddress = useMixedRouteQuoter
146
+ ? mixedRouteContainsV4Pool
147
+ ? MIXED_ROUTE_QUOTER_V2_ADDRESSES[this.chainId]
148
+ : MIXED_ROUTE_QUOTER_V1_ADDRESSES[this.chainId]
149
+ : protocol === Protocol.V3
150
+ ? NEW_QUOTER_V2_ADDRESSES[this.chainId]
151
+ : // PROTOCOL_V4_QUOTER_ADDRESSES[this.chainId]
152
+ undefined;
153
+ if (!quoterAddress) {
154
+ throw new Error(`No address for the quoter contract on chain id: ${this.chainId}`);
155
+ }
156
+ return quoterAddress;
157
+ }
158
+ async getQuotesManyExactIn(amountIns, routes, providerConfig) {
159
+ return this.getQuotesManyData(amountIns, routes, 'quoteExactInput', providerConfig);
160
+ }
161
+ async getQuotesManyExactOut(amountOuts, routes, providerConfig) {
162
+ return this.getQuotesManyData(amountOuts, routes, 'quoteExactOutput', providerConfig);
163
+ }
164
+ encodeRouteToPath(route, functionName) {
165
+ switch (route.protocol) {
166
+ case Protocol.V3:
167
+ return encodeV3RouteToPath(route, functionName == 'quoteExactOutput' // For exactOut must be true to ensure the routes are reversed.
168
+ );
169
+ // case Protocol.V4:
170
+ // return encodeV4RouteToPath(
171
+ // route,
172
+ // functionName == 'quoteExactOutput'
173
+ // ) as TPath;
174
+ // We don't have onchain V2 quoter, but we do have a mixed quoter that can quote against v2 routes onchain
175
+ // Hence in case of V2 or mixed, we explicitly encode into mixed routes.
176
+ case Protocol.V2:
177
+ case Protocol.MIXED:
178
+ return encodeMixedRouteToPath(route instanceof V2Route
179
+ ? new MixedRouteSDK(route.pairs, route.input, route.output)
180
+ : route);
181
+ default:
182
+ throw new Error(`Unsupported protocol for the route: ${JSON.stringify(route)}`);
183
+ }
184
+ }
185
+ getContractInterface(useMixedRouteQuoter, mixedRouteContainsV4Pool, protocol) {
186
+ if (useMixedRouteQuoter) {
187
+ if (mixedRouteContainsV4Pool) {
188
+ return MixedRouteQuoterV2__factory.createInterface();
189
+ }
190
+ else {
191
+ return IMixedRouteQuoterV1__factory.createInterface();
192
+ }
193
+ }
194
+ switch (protocol) {
195
+ case Protocol.V3:
196
+ return IQuoterV2__factory.createInterface();
197
+ // case Protocol.V4:
198
+ // return V4Quoter__factory.createInterface();
199
+ default:
200
+ throw new Error(`Unsupported protocol: ${protocol}`);
201
+ }
202
+ }
203
+ async consolidateResults(protocol, useMixedRouteQuoter, mixedRouteContainsV4Pool, functionName, inputs, providerConfig, gasLimitOverride) {
204
+ if (protocol === Protocol.MIXED &&
205
+ mixedRouteContainsV4Pool
206
+ // || protocol === Protocol.V4
207
+ ) {
208
+ const mixedQuote = await this.multicall2Provider.callSameFunctionOnContractWithMultipleParams({
209
+ address: this.getQuoterAddress(useMixedRouteQuoter, mixedRouteContainsV4Pool, protocol),
210
+ contractInterface: this.getContractInterface(useMixedRouteQuoter, mixedRouteContainsV4Pool, protocol),
211
+ functionName,
212
+ functionParams: inputs,
213
+ providerConfig,
214
+ additionalConfig: {
215
+ gasLimitPerCallOverride: gasLimitOverride,
216
+ },
217
+ });
218
+ return {
219
+ blockNumber: mixedQuote.blockNumber,
220
+ approxGasUsedPerSuccessCall: mixedQuote.approxGasUsedPerSuccessCall,
221
+ results: mixedQuote.results.map((result) => {
222
+ if (result.success) {
223
+ switch (functionName) {
224
+ case 'quoteExactInput':
225
+ case 'quoteExactOutput':
226
+ return {
227
+ success: true,
228
+ result: [
229
+ result.result[0],
230
+ Array(inputs.length),
231
+ Array(inputs.length),
232
+ result.result[1],
233
+ ],
234
+ };
235
+ default:
236
+ throw new Error(`Unsupported function name: ${functionName}`);
237
+ }
238
+ }
239
+ else {
240
+ return result;
241
+ }
242
+ }),
243
+ };
244
+ }
245
+ else {
246
+ return await this.multicall2Provider.callSameFunctionOnContractWithMultipleParams({
247
+ address: this.getQuoterAddress(useMixedRouteQuoter, mixedRouteContainsV4Pool, protocol),
248
+ contractInterface: this.getContractInterface(useMixedRouteQuoter, mixedRouteContainsV4Pool, protocol),
249
+ functionName,
250
+ functionParams: inputs,
251
+ providerConfig,
252
+ additionalConfig: {
253
+ gasLimitPerCallOverride: gasLimitOverride,
254
+ },
255
+ });
256
+ }
257
+ }
258
+ async getQuotesManyData(amounts, routes, functionName, _providerConfig) {
259
+ var _a, _b;
260
+ const useMixedRouteQuoter = routes.some((route) => route.protocol === Protocol.V2) ||
261
+ routes.some((route) => route.protocol === Protocol.MIXED);
262
+ // const useV4RouteQuoter =
263
+ // routes.some((route) => route.protocol === Protocol.V4) &&
264
+ // !useMixedRouteQuoter;
265
+ // const mixedRouteContainsV4Pool = useMixedRouteQuoter
266
+ // ? routes.some(
267
+ // (route) =>
268
+ // route.protocol === Protocol.MIXED &&
269
+ // (route as MixedRoute).pools.some((pool) => pool instanceof V4Pool)
270
+ // )
271
+ // : false;
272
+ const mixedRouteContainsV4Pool = false;
273
+ const optimisticCachedRoutes = (_a = _providerConfig === null || _providerConfig === void 0 ? void 0 : _providerConfig.optimisticCachedRoutes) !== null && _a !== void 0 ? _a : false;
274
+ /// Validate that there are no incorrect routes / function combinations
275
+ this.validateRoutes(routes, functionName, useMixedRouteQuoter);
276
+ let multicallChunk = this.batchParams(optimisticCachedRoutes, useMixedRouteQuoter).multicallChunk;
277
+ let gasLimitOverride = this.batchParams(optimisticCachedRoutes, useMixedRouteQuoter).gasLimitPerCall;
278
+ const { baseBlockOffset, rollback } = this.blockNumberConfig;
279
+ // Apply the base block offset if provided
280
+ const originalBlockNumber = await this.provider.getBlockNumber();
281
+ const providerConfig = {
282
+ ..._providerConfig,
283
+ blockNumber: (_b = _providerConfig === null || _providerConfig === void 0 ? void 0 : _providerConfig.blockNumber) !== null && _b !== void 0 ? _b : originalBlockNumber + baseBlockOffset,
284
+ };
285
+ const inputs = _(routes)
286
+ .flatMap((route) => {
287
+ const encodedRoute = this.encodeRouteToPath(route, functionName);
288
+ const routeInputs = amounts.map((amount) => {
289
+ switch (route.protocol) {
290
+ // case Protocol.V4:
291
+ // return [
292
+ // {
293
+ // exactCurrency: amount.currency.wrapped.address,
294
+ // path: encodedRoute as PathKey[],
295
+ // exactAmount: amount.quotient.toString(),
296
+ // },
297
+ // ] as QuoteExactParams[];
298
+ case Protocol.MIXED:
299
+ if (mixedRouteContainsV4Pool) {
300
+ return [
301
+ encodedRoute,
302
+ {
303
+ nonEncodableData: route.pools.map((_) => {
304
+ return {
305
+ hookData: '0x',
306
+ };
307
+ }),
308
+ },
309
+ amount.quotient.toString(),
310
+ ];
311
+ }
312
+ else {
313
+ return [encodedRoute, amount.quotient.toString()];
314
+ }
315
+ default:
316
+ return [
317
+ encodedRoute,
318
+ `0x${amount.quotient.toString(16)}`,
319
+ ];
320
+ }
321
+ });
322
+ return routeInputs;
323
+ })
324
+ .value();
325
+ const normalizedChunk = Math.ceil(inputs.length / Math.ceil(inputs.length / multicallChunk));
326
+ const inputsChunked = _.chunk(inputs, normalizedChunk);
327
+ let quoteStates = _.map(inputsChunked, (inputChunk) => {
328
+ return {
329
+ status: 'pending',
330
+ inputs: inputChunk,
331
+ };
332
+ });
333
+ log.info(`About to get ${inputs.length} quotes in chunks of ${normalizedChunk} [${_.map(inputsChunked, (i) => i.length).join(',')}] ${gasLimitOverride
334
+ ? `with a gas limit override of ${gasLimitOverride}`
335
+ : ''} and block number: ${await providerConfig.blockNumber} [Original before offset: ${originalBlockNumber}].`);
336
+ metric.putMetric(`${this.metricsPrefix(this.chainId, useMixedRouteQuoter, optimisticCachedRoutes)}QuoteBatchSize`, inputs.length, MetricLoggerUnit.Count);
337
+ metric.putMetric(`${this.metricsPrefix(this.chainId, useMixedRouteQuoter, optimisticCachedRoutes)}QuoteBatchSize_${ID_TO_NETWORK_NAME(this.chainId)}`, inputs.length, MetricLoggerUnit.Count);
338
+ const startTime = Date.now();
339
+ let haveRetriedForSuccessRate = false;
340
+ let haveRetriedForBlockHeader = false;
341
+ let blockHeaderRetryAttemptNumber = 0;
342
+ let haveIncrementedBlockHeaderFailureCounter = false;
343
+ let blockHeaderRolledBack = false;
344
+ let haveRetriedForBlockConflictError = false;
345
+ let haveRetriedForOutOfGas = false;
346
+ let haveRetriedForTimeout = false;
347
+ let haveRetriedForUnknownReason = false;
348
+ let finalAttemptNumber = 1;
349
+ const expectedCallsMade = quoteStates.length;
350
+ let totalCallsMade = 0;
351
+ const { results: quoteResults, blockNumber, approxGasUsedPerSuccessCall, } = await retry(async (_bail, attemptNumber) => {
352
+ haveIncrementedBlockHeaderFailureCounter = false;
353
+ finalAttemptNumber = attemptNumber;
354
+ const [success, failed, pending] = this.partitionQuotes(quoteStates);
355
+ log.info(`Starting attempt: ${attemptNumber}.
356
+ Currently ${success.length} success, ${failed.length} failed, ${pending.length} pending.
357
+ Gas limit override: ${gasLimitOverride} Block number override: ${providerConfig.blockNumber}.`);
358
+ quoteStates = await Promise.all(_.map(quoteStates, async (quoteState, idx) => {
359
+ if (quoteState.status == 'success') {
360
+ return quoteState;
361
+ }
362
+ // QuoteChunk is pending or failed, so we try again
363
+ const { inputs } = quoteState;
364
+ try {
365
+ totalCallsMade = totalCallsMade + 1;
366
+ const protocol = useMixedRouteQuoter
367
+ ? Protocol.MIXED
368
+ : // useV4RouteQuoter
369
+ // ? Protocol.V4
370
+ Protocol.V3;
371
+ const results = await this.consolidateResults(protocol, useMixedRouteQuoter, mixedRouteContainsV4Pool, functionName, inputs, providerConfig, gasLimitOverride);
372
+ const successRateError = this.validateSuccessRate(results.results, haveRetriedForSuccessRate, useMixedRouteQuoter, optimisticCachedRoutes);
373
+ if (successRateError) {
374
+ return {
375
+ status: 'failed',
376
+ inputs,
377
+ reason: successRateError,
378
+ results,
379
+ };
380
+ }
381
+ return {
382
+ status: 'success',
383
+ inputs,
384
+ results,
385
+ };
386
+ }
387
+ catch (err) {
388
+ // Error from providers have huge messages that include all the calldata and fill the logs.
389
+ // Catch them and rethrow with shorter message.
390
+ if (err.message.includes('header not found')) {
391
+ return {
392
+ status: 'failed',
393
+ inputs,
394
+ reason: new ProviderBlockHeaderError(err.message.slice(0, 500)),
395
+ };
396
+ }
397
+ if (err.message.includes('timeout')) {
398
+ return {
399
+ status: 'failed',
400
+ inputs,
401
+ reason: new ProviderTimeoutError(`Req ${idx}/${quoteStates.length}. Request had ${inputs.length} inputs. ${err.message.slice(0, 500)}`),
402
+ };
403
+ }
404
+ if (err.message.includes('out of gas')) {
405
+ return {
406
+ status: 'failed',
407
+ inputs,
408
+ reason: new ProviderGasError(err.message.slice(0, 500)),
409
+ };
410
+ }
411
+ return {
412
+ status: 'failed',
413
+ inputs,
414
+ reason: new Error(`Unknown error from provider: ${err.message.slice(0, 500)}`),
415
+ };
416
+ }
417
+ }));
418
+ const [successfulQuoteStates, failedQuoteStates, pendingQuoteStates] = this.partitionQuotes(quoteStates);
419
+ if (pendingQuoteStates.length > 0) {
420
+ throw new Error('Pending quote after waiting for all promises.');
421
+ }
422
+ let retryAll = false;
423
+ const blockNumberError = this.validateBlockNumbers(successfulQuoteStates, inputsChunked.length, gasLimitOverride);
424
+ // If there is a block number conflict we retry all the quotes.
425
+ if (blockNumberError) {
426
+ retryAll = true;
427
+ }
428
+ const reasonForFailureStr = _.map(failedQuoteStates, (failedQuoteState) => failedQuoteState.reason.name).join(', ');
429
+ if (failedQuoteStates.length > 0) {
430
+ log.info(`On attempt ${attemptNumber}: ${failedQuoteStates.length}/${quoteStates.length} quotes failed. Reasons: ${reasonForFailureStr}`);
431
+ for (const failedQuoteState of failedQuoteStates) {
432
+ const { reason: error } = failedQuoteState;
433
+ log.info({ error }, `[QuoteFetchError] Attempt ${attemptNumber}. ${error.message}`);
434
+ if (error instanceof BlockConflictError) {
435
+ if (!haveRetriedForBlockConflictError) {
436
+ metric.putMetric(`${this.metricsPrefix(this.chainId, useMixedRouteQuoter, optimisticCachedRoutes)}QuoteBlockConflictErrorRetry`, 1, MetricLoggerUnit.Count);
437
+ haveRetriedForBlockConflictError = true;
438
+ }
439
+ retryAll = true;
440
+ }
441
+ else if (error instanceof ProviderBlockHeaderError) {
442
+ if (!haveRetriedForBlockHeader) {
443
+ metric.putMetric(`${this.metricsPrefix(this.chainId, useMixedRouteQuoter, optimisticCachedRoutes)}QuoteBlockHeaderNotFoundRetry`, 1, MetricLoggerUnit.Count);
444
+ haveRetriedForBlockHeader = true;
445
+ }
446
+ // Ensure that if multiple calls fail due to block header in the current pending batch,
447
+ // we only count once.
448
+ if (!haveIncrementedBlockHeaderFailureCounter) {
449
+ blockHeaderRetryAttemptNumber =
450
+ blockHeaderRetryAttemptNumber + 1;
451
+ haveIncrementedBlockHeaderFailureCounter = true;
452
+ }
453
+ if (rollback.enabled) {
454
+ const { rollbackBlockOffset, attemptsBeforeRollback } = rollback;
455
+ if (blockHeaderRetryAttemptNumber >= attemptsBeforeRollback &&
456
+ !blockHeaderRolledBack) {
457
+ log.info(`Attempt ${attemptNumber}. Have failed due to block header ${blockHeaderRetryAttemptNumber - 1} times. Rolling back block number by ${rollbackBlockOffset} for next retry`);
458
+ providerConfig.blockNumber = providerConfig.blockNumber
459
+ ? (await providerConfig.blockNumber) + rollbackBlockOffset
460
+ : (await this.provider.getBlockNumber()) +
461
+ rollbackBlockOffset;
462
+ retryAll = true;
463
+ blockHeaderRolledBack = true;
464
+ }
465
+ }
466
+ }
467
+ else if (error instanceof ProviderTimeoutError) {
468
+ if (!haveRetriedForTimeout) {
469
+ metric.putMetric(`${this.metricsPrefix(this.chainId, useMixedRouteQuoter, optimisticCachedRoutes)}QuoteTimeoutRetry`, 1, MetricLoggerUnit.Count);
470
+ haveRetriedForTimeout = true;
471
+ }
472
+ }
473
+ else if (error instanceof ProviderGasError) {
474
+ if (!haveRetriedForOutOfGas) {
475
+ metric.putMetric(`${this.metricsPrefix(this.chainId, useMixedRouteQuoter, optimisticCachedRoutes)}QuoteOutOfGasExceptionRetry`, 1, MetricLoggerUnit.Count);
476
+ haveRetriedForOutOfGas = true;
477
+ }
478
+ gasLimitOverride = this.gasErrorFailureOverride.gasLimitOverride;
479
+ multicallChunk = this.gasErrorFailureOverride.multicallChunk;
480
+ retryAll = true;
481
+ }
482
+ else if (error instanceof SuccessRateError) {
483
+ if (!haveRetriedForSuccessRate) {
484
+ metric.putMetric(`${this.metricsPrefix(this.chainId, useMixedRouteQuoter, optimisticCachedRoutes)}QuoteSuccessRateRetry`, 1, MetricLoggerUnit.Count);
485
+ haveRetriedForSuccessRate = true;
486
+ // Low success rate can indicate too little gas given to each call.
487
+ gasLimitOverride =
488
+ this.successRateFailureOverrides.gasLimitOverride;
489
+ multicallChunk =
490
+ this.successRateFailureOverrides.multicallChunk;
491
+ retryAll = true;
492
+ }
493
+ }
494
+ else {
495
+ if (!haveRetriedForUnknownReason) {
496
+ metric.putMetric(`${this.metricsPrefix(this.chainId, useMixedRouteQuoter, optimisticCachedRoutes)}QuoteUnknownReasonRetry`, 1, MetricLoggerUnit.Count);
497
+ haveRetriedForUnknownReason = true;
498
+ }
499
+ }
500
+ }
501
+ }
502
+ if (retryAll) {
503
+ log.info(`Attempt ${attemptNumber}. Resetting all requests to pending for next attempt.`);
504
+ const normalizedChunk = Math.ceil(inputs.length / Math.ceil(inputs.length / multicallChunk));
505
+ const inputsChunked = _.chunk(inputs, normalizedChunk);
506
+ quoteStates = _.map(inputsChunked, (inputChunk) => {
507
+ return {
508
+ status: 'pending',
509
+ inputs: inputChunk,
510
+ };
511
+ });
512
+ }
513
+ // if (failedQuoteStates.length > 0) {
514
+ // // TODO: Work with Arbitrum to find a solution for making large multicalls with gas limits that always
515
+ // // successfully.
516
+ // //
517
+ // // On Arbitrum we can not set a gas limit for every call in the multicall and guarantee that
518
+ // // we will not run out of gas on the node. This is because they have a different way of accounting
519
+ // // for gas, that seperates storage and compute gas costs, and we can not cover both in a single limit.
520
+ // //
521
+ // // To work around this and avoid throwing errors when really we just couldn't get a quote, we catch this
522
+ // // case and return 0 quotes found.
523
+ // if (
524
+ // (this.chainId == ChainId.ARBITRUM_ONE ||
525
+ // this.chainId == ChainId.ARBITRUM_GOERLI) &&
526
+ // _.every(
527
+ // failedQuoteStates,
528
+ // (failedQuoteState) =>
529
+ // failedQuoteState.reason instanceof ProviderGasError
530
+ // ) &&
531
+ // attemptNumber == this.retryOptions.retries
532
+ // ) {
533
+ // log.error(
534
+ // `Failed to get quotes on Arbitrum due to provider gas error issue. Overriding error to return 0 quotes.`
535
+ // );
536
+ // return {
537
+ // results: [],
538
+ // blockNumber: BigNumber.from(0),
539
+ // approxGasUsedPerSuccessCall: 0,
540
+ // };
541
+ // }
542
+ // throw new Error(
543
+ // `Failed to get ${failedQuoteStates.length} quotes. Reasons: ${reasonForFailureStr}`
544
+ // );
545
+ // }
546
+ const callResults = _.map(successfulQuoteStates, (quoteState) => quoteState.results);
547
+ return {
548
+ results: _.flatMap(callResults, (result) => result.results),
549
+ blockNumber: BigNumber.from(callResults[0].blockNumber),
550
+ approxGasUsedPerSuccessCall: stats.percentile(_.map(callResults, (result) => result.approxGasUsedPerSuccessCall), 100),
551
+ };
552
+ }, {
553
+ retries: DEFAULT_BATCH_RETRIES,
554
+ ...this.retryOptions,
555
+ });
556
+ const routesQuotes = this.processQuoteResults(quoteResults, routes, amounts, BigNumber.from(gasLimitOverride));
557
+ const endTime = Date.now();
558
+ metric.putMetric(`${this.metricsPrefix(this.chainId, useMixedRouteQuoter, optimisticCachedRoutes)}QuoteLatency`, endTime - startTime, MetricLoggerUnit.Milliseconds);
559
+ metric.putMetric(`${this.metricsPrefix(this.chainId, useMixedRouteQuoter, optimisticCachedRoutes)}QuoteApproxGasUsedPerSuccessfulCall`, approxGasUsedPerSuccessCall, MetricLoggerUnit.Count);
560
+ metric.putMetric(`${this.metricsPrefix(this.chainId, useMixedRouteQuoter, optimisticCachedRoutes)}QuoteNumRetryLoops`, finalAttemptNumber - 1, MetricLoggerUnit.Count);
561
+ metric.putMetric(`${this.metricsPrefix(this.chainId, useMixedRouteQuoter, optimisticCachedRoutes)}QuoteTotalCallsToProvider`, totalCallsMade, MetricLoggerUnit.Count);
562
+ metric.putMetric(`${this.metricsPrefix(this.chainId, useMixedRouteQuoter, optimisticCachedRoutes)}QuoteExpectedCallsToProvider`, expectedCallsMade, MetricLoggerUnit.Count);
563
+ metric.putMetric(`${this.metricsPrefix(this.chainId, useMixedRouteQuoter, optimisticCachedRoutes)}QuoteNumRetriedCalls`, totalCallsMade - expectedCallsMade, MetricLoggerUnit.Count);
564
+ const [successfulQuotes, failedQuotes] = _(routesQuotes)
565
+ .flatMap((routeWithQuotes) => routeWithQuotes[1])
566
+ .partition((quote) => quote.quote != null)
567
+ .value();
568
+ log.info(`Got ${successfulQuotes.length} successful quotes, ${failedQuotes.length} failed quotes. Took ${finalAttemptNumber - 1} attempt loops. Total calls made to provider: ${totalCallsMade}. Have retried for timeout: ${haveRetriedForTimeout}`);
569
+ return {
570
+ routesWithQuotes: routesQuotes,
571
+ blockNumber,
572
+ };
573
+ }
574
+ partitionQuotes(quoteStates) {
575
+ const successfulQuoteStates = _.filter(quoteStates, (quoteState) => quoteState.status == 'success');
576
+ const failedQuoteStates = _.filter(quoteStates, (quoteState) => quoteState.status == 'failed');
577
+ const pendingQuoteStates = _.filter(quoteStates, (quoteState) => quoteState.status == 'pending');
578
+ return [successfulQuoteStates, failedQuoteStates, pendingQuoteStates];
579
+ }
580
+ processQuoteResults(quoteResults, routes, amounts, gasLimit) {
581
+ const routesQuotes = [];
582
+ const quotesResultsByRoute = _.chunk(quoteResults, amounts.length);
583
+ const debugFailedQuotes = [];
584
+ for (let i = 0; i < quotesResultsByRoute.length; i++) {
585
+ const route = routes[i];
586
+ const quoteResults = quotesResultsByRoute[i];
587
+ const quotes = _.map(quoteResults, (quoteResult, index) => {
588
+ var _a;
589
+ const amount = amounts[index];
590
+ if (!quoteResult.success) {
591
+ const percent = (100 / amounts.length) * (index + 1);
592
+ const amountStr = amount.toFixed(Math.min(amount.currency.decimals, 2));
593
+ const routeStr = routeToString(route);
594
+ debugFailedQuotes.push({
595
+ route: routeStr,
596
+ percent,
597
+ amount: amountStr,
598
+ });
599
+ return {
600
+ amount,
601
+ quote: null,
602
+ sqrtPriceX96AfterList: null,
603
+ gasEstimate: (_a = quoteResult.gasUsed) !== null && _a !== void 0 ? _a : null,
604
+ gasLimit: gasLimit,
605
+ initializedTicksCrossedList: null,
606
+ };
607
+ }
608
+ return {
609
+ amount,
610
+ quote: quoteResult.result[0],
611
+ sqrtPriceX96AfterList: quoteResult.result[1],
612
+ initializedTicksCrossedList: quoteResult.result[2],
613
+ gasEstimate: quoteResult.result[3],
614
+ gasLimit: gasLimit,
615
+ };
616
+ });
617
+ routesQuotes.push([route, quotes]);
618
+ }
619
+ // For routes and amounts that we failed to get a quote for, group them by route
620
+ // and batch them together before logging to minimize number of logs.
621
+ const debugChunk = 80;
622
+ _.forEach(_.chunk(debugFailedQuotes, debugChunk), (quotes, idx) => {
623
+ const failedQuotesByRoute = _.groupBy(quotes, (q) => q.route);
624
+ const failedFlat = _.mapValues(failedQuotesByRoute, (f) => _(f)
625
+ .map((f) => `${f.percent}%[${f.amount}]`)
626
+ .join(','));
627
+ log.info({
628
+ failedQuotes: _.map(failedFlat, (amounts, routeStr) => `${routeStr} : ${amounts}`),
629
+ }, `Failed on chain quotes for routes Part ${idx}/${Math.ceil(debugFailedQuotes.length / debugChunk)}`);
630
+ });
631
+ return routesQuotes;
632
+ }
633
+ validateBlockNumbers(successfulQuoteStates, totalCalls, gasLimitOverride) {
634
+ if (successfulQuoteStates.length <= 1) {
635
+ return null;
636
+ }
637
+ const results = _.map(successfulQuoteStates, (quoteState) => quoteState.results);
638
+ const blockNumbers = _.map(results, (result) => result.blockNumber);
639
+ const uniqBlocks = _(blockNumbers)
640
+ .map((blockNumber) => blockNumber.toNumber())
641
+ .uniq()
642
+ .value();
643
+ if (uniqBlocks.length == 1) {
644
+ return null;
645
+ }
646
+ /* if (
647
+ uniqBlocks.length == 2 &&
648
+ Math.abs(uniqBlocks[0]! - uniqBlocks[1]!) <= 1
649
+ ) {
650
+ return null;
651
+ } */
652
+ return new BlockConflictError(`Quotes returned from different blocks. ${uniqBlocks}. ${totalCalls} calls were made with gas limit ${gasLimitOverride}`);
653
+ }
654
+ validateSuccessRate(allResults, haveRetriedForSuccessRate, useMixedRouteQuoter, optimisticCachedRoutes) {
655
+ const numResults = allResults.length;
656
+ const numSuccessResults = allResults.filter((result) => result.success).length;
657
+ const successRate = (1.0 * numSuccessResults) / numResults;
658
+ const { quoteMinSuccessRate } = this.batchParams(optimisticCachedRoutes, useMixedRouteQuoter);
659
+ if (successRate < quoteMinSuccessRate) {
660
+ if (haveRetriedForSuccessRate) {
661
+ log.info(`Quote success rate still below threshold despite retry. Continuing. ${quoteMinSuccessRate}: ${successRate}`);
662
+ metric.putMetric(`${this.metricsPrefix(this.chainId, useMixedRouteQuoter, optimisticCachedRoutes)}QuoteRetriedSuccessRateLow`, successRate, MetricLoggerUnit.Percent);
663
+ return;
664
+ }
665
+ metric.putMetric(`${this.metricsPrefix(this.chainId, useMixedRouteQuoter, optimisticCachedRoutes)}QuoteSuccessRateLow`, successRate, MetricLoggerUnit.Percent);
666
+ return new SuccessRateError(`Quote success rate below threshold of ${quoteMinSuccessRate}: ${successRate}`);
667
+ }
668
+ }
669
+ /**
670
+ * Throw an error for incorrect routes / function combinations
671
+ * @param routes Any combination of V3, V2, and Mixed routes.
672
+ * @param functionName
673
+ * @param useMixedRouteQuoter true if there are ANY V2Routes or MixedRoutes in the routes parameter
674
+ */
675
+ validateRoutes(routes, functionName, useMixedRouteQuoter) {
676
+ /// We do not send any V3Routes to new qutoer becuase it is not deployed on chains besides mainnet
677
+ if (routes.some((route) => route.protocol === Protocol.V3) &&
678
+ useMixedRouteQuoter) {
679
+ throw new Error(`Cannot use mixed route quoter with V3 routes`);
680
+ }
681
+ /// We cannot call quoteExactOutput with V2 or Mixed routes
682
+ if (functionName === 'quoteExactOutput' && useMixedRouteQuoter) {
683
+ throw new Error('Cannot call quoteExactOutput with V2 or Mixed routes');
684
+ }
685
+ }
686
+ }
687
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib24tY2hhaW4tcXVvdGUtcHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcHJvdmlkZXJzL29uLWNoYWluLXF1b3RlLXByb3ZpZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxTQUFTLEVBQWdCLE1BQU0sMEJBQTBCLENBQUM7QUFHbkUsT0FBTyxFQUNMLHNCQUFzQixFQUN0QixhQUFhLEVBQ2IsUUFBUSxHQUNULE1BQU0sMkJBQTJCLENBQUM7QUFFbkMsT0FBTyxFQUFFLGlCQUFpQixJQUFJLG1CQUFtQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDakYsV0FBVztBQUNYLDhDQUE4QztBQUM5QyxvQkFBb0I7QUFDcEIsa0NBQWtDO0FBQ2xDLE9BQU8sS0FBa0MsTUFBTSxhQUFhLENBQUM7QUFDN0QsT0FBTyxDQUFDLE1BQU0sUUFBUSxDQUFDO0FBQ3ZCLE9BQU8sS0FBSyxNQUFNLFlBQVksQ0FBQztBQUUvQixPQUFPLEVBQW1CLE9BQU8sRUFBVyxNQUFNLG1CQUFtQixDQUFDO0FBQ3RFLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLHVEQUF1RCxDQUFDO0FBQ3JHLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLHNEQUFzRCxDQUFDO0FBQ25HLGtGQUFrRjtBQUNsRixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUM5RSxPQUFPLEVBQ0wsa0JBQWtCLEVBQ2xCLE1BQU0sRUFDTixnQkFBZ0IsRUFDaEIsK0JBQStCLEVBQy9CLCtCQUErQixFQUMvQix1QkFBdUIsR0FDeEIsTUFBTSxTQUFTLENBQUM7QUFFakIsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsQyxPQUFPLEVBQ0wsNEJBQTRCLEVBQzVCLHNDQUFzQyxHQUN2QyxNQUFNLHFDQUFxQyxDQUFDO0FBQzdDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxnQkFBZ0IsQ0FB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