1pub const ETH_ETHEREUM_MAINNET: &'static str = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
3pub const USDT_ETHEREUM_MAINNET: &'static str = "0xdAC17F958D2ee523a2206206994597C13D831ec7";
4pub const USDC_ETHEREUM_MAINNET: &'static str = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
5pub const DAI_ETHEREUM_MAINNET: &'static str = "0x6B175474E89094C44Da98b954EedeAC495271d0F";
6pub const WBTC_ETHEREUM_MAINNET: &'static str = "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599";
7
8pub const ETH_ARB_MAINNET: &'static str = "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1";
10pub const USDT_ARB_MAINNET: &'static str = "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9";
11pub const USDC_ARB_MAINNET: &'static str = "0xaf88d065e77c8cC2239327C5EDb3A432268e5831";
12pub const DAI_ARB_MAINNET: &'static str = "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1";
13pub const WBTC_ARB_MAINNET: &'static str = "0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f";
14
15pub const BNB_BSC_MAINNET: &'static str = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c";
17pub const USDT_BSC_MAINNET: &'static str = "0x55d398326f99059fF775485246999027B3197955";
18pub const USDC_BSC_MAINNET: &'static str = "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d";
19pub const BUSD_BSC_MAINNET: &'static str = "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56";
20pub const ETH_BSC_MAINNET: &'static str = "0x2170Ed0880ac9A755fd29B2688956BD959F933F8";
21pub const WBTC_BSC_MAINNET: &'static str = "0x0555E30da8f98308EdB960aa94C0Db47230d2B9c";
22
23pub const ETH_BASE_MAINNET: &'static str = "0x4200000000000000000000000000000000000006";
25pub const USDC_BASE_MAINNET: &'static str = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
26pub const DAI_BASE_MAINNET: &'static str = "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb";
27pub const WBTC_BASE_MAINNET: &'static str = "0x1ceA4b36B8F8b2e40A61d0B7ed03D70Cb5AA6d8C";
28
29pub const HYPE_HYPEREVM_MAINNET: &'static str = "0x5555555555555555555555555555555555555555";
31pub const ETH_HYPEREVM_MAINNET: &'static str = "0xBe6727B535545C67d5cAa73dEa54865B92CF7907";
32pub const USDT_HYPEREVM_MAINNET: &'static str = "0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb";
33pub const USDC_HYPEREVM_MAINNET: &'static str = "0xb88339CB7199b77E23DB6E890353E22632Ba630f";
34
35pub const WXPL_PLASMA_MAINNET: &'static str = "0x6100E367285b01F48D07953803A2d8dCA5D19873";
37
38pub const POL_POLYGON_MAINNET: &'static str = "0x0000000000000000000000000000000000001010";
40pub const USDT_POLYGON_MAINNET: &'static str = "0xc2132D05D31c914a87C6611C10748AEb04B58e8F";
41pub const USDC_POLYGON_MAINNET: &'static str = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174";
42pub const WETH_POLYGON_MAINNET: &'static str = "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619";
43
44pub const ETH_OPTIMISM_MAINNET: &'static str = "0x4200000000000000000000000000000000000006";
46pub const USDT_OPTIMISM_MAINNET: &'static str = "0x94b008aA00579c1307B0EF2c499aD98a8ce58e58";
47pub const USDC_OPTIMISM_MAINNET: &'static str = "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85";
48pub const DAI_OPTIMISM_MAINNET: &'static str = "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1";
49
50pub const ETH_ZKSYNC_MAINNET: &'static str = "0x000000000000000000000000000000000000800A";
52pub const USDC_ZKSYNC_MAINNET: &'static str = "0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4";
53pub const ZK_ZKSYNC_MAINNET: &'static str = "0x5A7d6b2F92C77FAD6CCaBd7EE0624E64907Eaf3E";
54
55pub const ETH_STARKNET_MAINNET: &'static str =
57 "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7";
58pub const USDT_STARKNET_MAINNET: &'static str =
59 "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8";
60pub const USDC_STARKNET_MAINNET: &'static str =
61 "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8";
62pub const WBTC_STARKNET_MAINNET: &'static str =
63 "0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac";
64
65pub const WAVAX_AVALANCHE_MAINNET: &'static str = "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7";
67pub const USDT_AVALANCHE_MAINNET: &'static str = "0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7";
68pub const USDC_AVALANCHE_MAINNET: &'static str = "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E";
69pub const DAI_AVALANCHE_MAINNET: &'static str = "0xd586E7F844cEa2F87f50152665BCbc2C279D8d70";
70
71pub fn is_quote(address: &str) -> bool {
72 let address_lower = address.to_lowercase();
73 address_lower == ETH_ETHEREUM_MAINNET.to_lowercase()
74 || address_lower == USDT_ETHEREUM_MAINNET.to_lowercase()
75 || address_lower == USDC_ETHEREUM_MAINNET.to_lowercase()
76 || address_lower == DAI_ETHEREUM_MAINNET.to_lowercase()
77 || address_lower == WBTC_ETHEREUM_MAINNET.to_lowercase()
78 || address_lower == ETH_ARB_MAINNET.to_lowercase()
79 || address_lower == USDT_ARB_MAINNET.to_lowercase()
80 || address_lower == USDC_ARB_MAINNET.to_lowercase()
81 || address_lower == DAI_ARB_MAINNET.to_lowercase()
82 || address_lower == WBTC_ARB_MAINNET.to_lowercase()
83 || address_lower == BNB_BSC_MAINNET.to_lowercase()
84 || address_lower == USDT_BSC_MAINNET.to_lowercase()
85 || address_lower == USDC_BSC_MAINNET.to_lowercase()
86 || address_lower == BUSD_BSC_MAINNET.to_lowercase()
87 || address_lower == ETH_BSC_MAINNET.to_lowercase()
88 || address_lower == WBTC_BSC_MAINNET.to_lowercase()
89 || address_lower == ETH_BASE_MAINNET.to_lowercase()
90 || address_lower == USDC_BASE_MAINNET.to_lowercase()
91 || address_lower == DAI_BASE_MAINNET.to_lowercase()
92 || address_lower == WBTC_BASE_MAINNET.to_lowercase()
93 || address_lower == HYPE_HYPEREVM_MAINNET.to_lowercase()
94 || address_lower == ETH_HYPEREVM_MAINNET.to_lowercase()
95 || address_lower == USDT_HYPEREVM_MAINNET.to_lowercase()
96 || address_lower == USDC_HYPEREVM_MAINNET.to_lowercase()
97 || address_lower == WXPL_PLASMA_MAINNET.to_lowercase()
98 || address_lower == POL_POLYGON_MAINNET.to_lowercase()
99 || address_lower == USDT_POLYGON_MAINNET.to_lowercase()
100 || address_lower == USDC_POLYGON_MAINNET.to_lowercase()
101 || address_lower == WETH_POLYGON_MAINNET.to_lowercase()
102 || address_lower == ETH_OPTIMISM_MAINNET.to_lowercase()
103 || address_lower == USDT_OPTIMISM_MAINNET.to_lowercase()
104 || address_lower == USDC_OPTIMISM_MAINNET.to_lowercase()
105 || address_lower == DAI_OPTIMISM_MAINNET.to_lowercase()
106 || address_lower == ETH_ZKSYNC_MAINNET.to_lowercase()
107 || address_lower == USDC_ZKSYNC_MAINNET.to_lowercase()
108 || address_lower == ZK_ZKSYNC_MAINNET.to_lowercase()
109 || address_lower == ETH_STARKNET_MAINNET.to_lowercase()
110 || address_lower == USDT_STARKNET_MAINNET.to_lowercase()
111 || address_lower == USDC_STARKNET_MAINNET.to_lowercase()
112 || address_lower == WBTC_STARKNET_MAINNET.to_lowercase()
113 || address_lower == WAVAX_AVALANCHE_MAINNET.to_lowercase()
114 || address_lower == USDT_AVALANCHE_MAINNET.to_lowercase()
115 || address_lower == USDC_AVALANCHE_MAINNET.to_lowercase()
116 || address_lower == DAI_AVALANCHE_MAINNET.to_lowercase()
117}
118
119pub fn get_block_time_by_address(address: &str) -> Option<u64> {
120 let addr = address.to_lowercase();
121 if addr == ETH_ETHEREUM_MAINNET.to_lowercase()
122 || addr == USDT_ETHEREUM_MAINNET.to_lowercase()
123 || addr == USDC_ETHEREUM_MAINNET.to_lowercase()
124 {
125 return Some(12);
126 }
127 if addr == ETH_ARB_MAINNET.to_lowercase()
128 || addr == USDT_ARB_MAINNET.to_lowercase()
129 || addr == USDC_ARB_MAINNET.to_lowercase()
130 {
131 return Some(1);
132 }
133 if addr == BNB_BSC_MAINNET.to_lowercase()
134 || addr == USDT_BSC_MAINNET.to_lowercase()
135 || addr == USDC_BSC_MAINNET.to_lowercase()
136 {
137 return Some(3);
138 }
139 if addr == ETH_BASE_MAINNET.to_lowercase() || addr == USDC_BASE_MAINNET.to_lowercase() {
140 return Some(2);
141 }
142 if addr == HYPE_HYPEREVM_MAINNET.to_lowercase() || addr == ETH_HYPEREVM_MAINNET.to_lowercase() {
143 return Some(2);
144 }
145 if addr == WXPL_PLASMA_MAINNET.to_lowercase() {
146 return Some(2);
147 }
148 if addr == POL_POLYGON_MAINNET.to_lowercase()
149 || addr == USDT_POLYGON_MAINNET.to_lowercase()
150 || addr == USDC_POLYGON_MAINNET.to_lowercase()
151 {
152 return Some(2);
153 }
154 if addr == ETH_OPTIMISM_MAINNET.to_lowercase()
155 || addr == USDT_OPTIMISM_MAINNET.to_lowercase()
156 || addr == USDC_OPTIMISM_MAINNET.to_lowercase()
157 {
158 return Some(2);
159 }
160 if addr == ETH_ZKSYNC_MAINNET.to_lowercase() || addr == USDC_ZKSYNC_MAINNET.to_lowercase() {
161 return Some(2);
162 }
163 if addr == ETH_STARKNET_MAINNET.to_lowercase()
164 || addr == USDT_STARKNET_MAINNET.to_lowercase()
165 || addr == USDC_STARKNET_MAINNET.to_lowercase()
166 {
167 return Some(10);
168 }
169 if addr == WAVAX_AVALANCHE_MAINNET.to_lowercase()
170 || addr == USDT_AVALANCHE_MAINNET.to_lowercase()
171 || addr == USDC_AVALANCHE_MAINNET.to_lowercase()
172 {
173 return Some(2);
174 }
175 None
176}
177
178pub const UNISWAP_V2_FACTORY_ETHEREUM: &'static str = "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f";
180pub const UNISWAP_V2_ROUTER_ETHEREUM: &'static str = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D";
181pub const UNISWAP_V3_FACTORY_ETHEREUM: &'static str = "0x1F98431c8aD98523631AE4a59f267346ea31F984";
182pub const UNISWAP_V3_ROUTER_ETHEREUM: &'static str = "0xE592427A0AEce92De3Edee1F18E0157C05861564";
183
184pub const SUSHI_FACTORY_ETHEREUM: &'static str = "0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac";
185pub const SUSHI_ROUTER_ETHEREUM: &'static str = "0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F";
186
187pub const CURVE_FACTORY_ETHEREUM: &'static str = "0xB9fC157394Af804a3578134A6585C0dc9cc990d4";
188pub const CURVE_3POOL_ETHEREUM: &'static str = "0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7";
189
190pub const BALANCER_VAULT_ETHEREUM: &'static str = "0xBA12222222228d8Ba445958a75a0704d566BF2C8";
191
192pub const INCH_V4_ROUTER_ETHEREUM: &'static str = "0x1111111254EEB25477B68fb85Ed929f73A960582";
193
194pub const UNISWAP_V3_FACTORY_ARBITRUM: &'static str = "0x1F98431c8aD98523631AE4a59f267346ea31F984";
196pub const UNISWAP_V3_ROUTER_ARBITRUM: &'static str = "0xE592427A0AEce92De3Edee1F18E0157C05861564";
197
198pub const SUSHI_FACTORY_ARBITRUM: &'static str = "0xc35DADB65012eC5796536bD9864eD8773aBc74C4";
199pub const SUSHI_ROUTER_ARBITRUM: &'static str = "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506";
200
201pub const PANCAKE_V2_FACTORY_BSC: &'static str = "0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73";
203pub const PANCAKE_V2_ROUTER_BSC: &'static str = "0x10ED43C718714eb63d5aA57B78B54704E256024E";
204pub const PANCAKE_V3_FACTORY_BSC: &'static str = "0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865";
205pub const PANCAKE_V3_ROUTER_BSC: &'static str = "0x13f4EA83D0bd40E75C8222255bc855a974568Dd4";
206
207pub const BISWAP_FACTORY_BSC: &'static str = "0x858E3312ed3A876947EA49d572A7C42DE08af7EE";
208pub const BISWAP_ROUTER_BSC: &'static str = "0x3a6d8cA21D1CF76F653A67577FA0D27453350dD8";
209
210pub const UNISWAP_V3_FACTORY_POLYGON: &'static str = "0x1F98431c8aD98523631AE4a59f267346ea31F984";
212pub const UNISWAP_V3_ROUTER_POLYGON: &'static str = "0xE592427A0AEce92De3Edee1F18E0157C05861564";
213pub const QUICKSWAP_FACTORY_POLYGON: &'static str = "0x5757371414417b8C6CAad45bAeF941aBc7d3Ab32";
214pub const QUICKSWAP_ROUTER_POLYGON: &'static str = "0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff";
215
216pub const SUSHI_FACTORY_POLYGON: &'static str = "0xc35DADB65012eC5796536bD9864eD8773aBc74C4";
217pub const SUSHI_ROUTER_POLYGON: &'static str = "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506";
218
219pub const UNISWAP_V3_FACTORY_OPTIMISM: &'static str = "0x1F98431c8aD98523631AE4a59f267346ea31F984";
221pub const UNISWAP_V3_ROUTER_OPTIMISM: &'static str = "0xE592427A0AEce92De3Edee1F18E0157C05861564";
222
223pub const VELODROME_V2_FACTORY_OPTIMISM: &'static str =
224 "0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a";
225pub const VELODROME_V2_ROUTER_OPTIMISM: &'static str = "0xa062aE8A9c5e11aaA026fc2670B0D65cCc8B2858";
226
227pub const UNISWAP_V3_FACTORY_AVALANCHE: &'static str = "0x740b1c1de25031C31FF4fC9A62f554A55cdC1baD";
229pub const UNISWAP_V3_ROUTER_AVALANCHE: &'static str = "0xbb00FF08d01D300023C629E8fFfFcb65A5a578cE";
230
231pub const TRADER_JOE_FACTORY_AVALANCHE: &'static str = "0x9Ad6C38BE94206cA50bb0d90783181662f0Cfa10";
232pub const TRADER_JOE_ROUTER_AVALANCHE: &'static str = "0x60aE616a2155Ee3d9A68541Ba4544862310933d4";
233
234pub const UNISWAP_V3_FACTORY_BASE: &'static str = "0x33128a8fC17869897dcE68Ed026d694621f6FDfD";
236pub const UNISWAP_V3_ROUTER_BASE: &'static str = "0x2626664c2603336E57B271c5C0b26F421741e481";
237
238pub const BASESWAP_FACTORY_BASE: &'static str = "0xFDa619b6d20975be80A10332cD39b9a4b0FAa8BB";
239pub const BASESWAP_ROUTER_BASE: &'static str = "0x327Df1E6de05895d2ab08513aaDD9313Fe505d86";
240
241pub const SPOOKYSWAP_FACTORY_FANTOM: &'static str = "0x152eE697f2E276fA89E96742e9bB9aB1F2E61bE3";
243pub const SPOOKYSWAP_ROUTER_FANTOM: &'static str = "0xF491e7B69E4244ad4002BC14e878a34207E38c29";
244
245pub const SYNC_SWAP_FACTORY_ZKSYNC: &'static str = "0xf2DAd89f2788a8CD54625C60b55cD3d2D0ACa7Cb";
247pub const SYNC_SWAP_ROUTER_ZKSYNC: &'static str = "0x2da10A1e27bF85cEdD8FFb1AbBe97e53391C0295";
248
249pub const MY_SWAP_ROUTER_STARKNET: &'static str =
251 "0x010884171baf1914edc28d7afb619b40a4051cfae78a094a55d230f19e944a28";
252
253pub fn get_common_dex_event_signatures() -> Vec<(&'static str, &'static str)> {
254 vec![
255 (
256 "Swap(address,uint256,uint256,uint256,uint256,address)",
257 "Uniswap V2",
258 ),
259 ("Mint(address,uint256,uint256)", "Uniswap V2"),
260 ("Burn(address,uint256,uint256)", "Uniswap V2"),
261 ("Sync(uint112,uint112)", "Uniswap V2"),
262 (
263 "Swap(address,address,int256,int256,uint160,uint128,int24)",
264 "Uniswap V3",
265 ),
266 (
267 "Mint(address,address,int24,int24,uint128,uint256,uint256)",
268 "Uniswap V3",
269 ),
270 (
271 "Burn(address,int24,int24,uint128,uint256,uint256)",
272 "Uniswap V3",
273 ),
274 (
275 "Collect(address,address,int24,int24,uint128,uint128)",
276 "Uniswap V3",
277 ),
278 (
279 "TokenExchange(address,int128,uint256,int128,uint256)",
280 "Curve",
281 ),
282 (
283 "AddLiquidity(address,uint256[2],uint256[2],uint256,uint256)",
284 "Curve",
285 ),
286 ("RemoveLiquidity(address,uint256[2],uint256[2])", "Curve"),
287 ("Swap(address,address,uint256,uint256)", "PancakeSwap"),
288 (
289 "Swap(address,uint256,uint256,uint256,uint256,address)",
290 "SushiSwap",
291 ),
292 ("Swap(address,address,uint256,uint256)", "Trader Joe"),
293 ("Swap(address,address,uint256,uint256,uint256)", "Balancer"),
294 (
295 "Swapped(address,address,address,address,uint256,uint256)",
296 "1inch",
297 ),
298 ("DODOSwap(address,address,uint256,uint256)", "DODO"),
299 (
300 "Swap(address,address,int256,int256,uint160,address)",
301 "KyberSwap",
302 ),
303 ]
304}
305
306pub fn get_dex_name_by_address(address: &str) -> Option<&'static str> {
307 let address_lower = address.to_lowercase();
308 let verified_dex_mappings: [(&str, &str); 43] = [
309 (UNISWAP_V2_FACTORY_ETHEREUM, "Uniswap V2 Factory"),
311 (UNISWAP_V2_ROUTER_ETHEREUM, "Uniswap V2 Router"),
312 (UNISWAP_V3_FACTORY_ETHEREUM, "Uniswap V3 Factory"),
313 (UNISWAP_V3_ROUTER_ETHEREUM, "Uniswap V3 Router"),
314 (SUSHI_FACTORY_ETHEREUM, "SushiSwap Factory"),
315 (SUSHI_ROUTER_ETHEREUM, "SushiSwap Router"),
316 (CURVE_FACTORY_ETHEREUM, "Curve Factory"),
317 (CURVE_3POOL_ETHEREUM, "Curve 3pool"),
318 (BALANCER_VAULT_ETHEREUM, "Balancer Vault"),
319 (INCH_V4_ROUTER_ETHEREUM, "1inch V4 Router"),
320 (UNISWAP_V3_FACTORY_ARBITRUM, "Uniswap V3 Factory (Arbitrum)"),
322 (UNISWAP_V3_ROUTER_ARBITRUM, "Uniswap V3 Router (Arbitrum)"),
323 (SUSHI_FACTORY_ARBITRUM, "SushiSwap Factory (Arbitrum)"),
324 (SUSHI_ROUTER_ARBITRUM, "SushiSwap Router (Arbitrum)"),
325 (PANCAKE_V2_FACTORY_BSC, "PancakeSwap V2 Factory"),
327 (PANCAKE_V2_ROUTER_BSC, "PancakeSwap V2 Router"),
328 (PANCAKE_V3_FACTORY_BSC, "PancakeSwap V3 Factory"),
329 (PANCAKE_V3_ROUTER_BSC, "PancakeSwap V3 Router"),
330 (BISWAP_FACTORY_BSC, "BiSwap Factory"),
331 (BISWAP_ROUTER_BSC, "BiSwap Router"),
332 (UNISWAP_V3_FACTORY_POLYGON, "Uniswap V3 Factory (Polygon)"),
334 (UNISWAP_V3_ROUTER_POLYGON, "Uniswap V3 Router (Polygon)"),
335 (QUICKSWAP_FACTORY_POLYGON, "QuickSwap Factory"),
336 (QUICKSWAP_ROUTER_POLYGON, "QuickSwap Router"),
337 (SUSHI_FACTORY_POLYGON, "SushiSwap Factory (Polygon)"),
338 (SUSHI_ROUTER_POLYGON, "SushiSwap Router (Polygon)"),
339 (UNISWAP_V3_FACTORY_OPTIMISM, "Uniswap V3 Factory (Optimism)"),
341 (UNISWAP_V3_ROUTER_OPTIMISM, "Uniswap V3 Router (Optimism)"),
342 (VELODROME_V2_FACTORY_OPTIMISM, "Velodrome V2 Factory"),
343 (VELODROME_V2_ROUTER_OPTIMISM, "Velodrome V2 Router"),
344 (
346 UNISWAP_V3_FACTORY_AVALANCHE,
347 "Uniswap V3 Factory (Avalanche)",
348 ),
349 (UNISWAP_V3_ROUTER_AVALANCHE, "Uniswap V3 Router (Avalanche)"),
350 (TRADER_JOE_FACTORY_AVALANCHE, "Trader Joe Factory"),
351 (TRADER_JOE_ROUTER_AVALANCHE, "Trader Joe Router"),
352 (UNISWAP_V3_FACTORY_BASE, "Uniswap V3 Factory (Base)"),
354 (UNISWAP_V3_ROUTER_BASE, "Uniswap V3 Router (Base)"),
355 (BASESWAP_FACTORY_BASE, "BaseSwap Factory"),
356 (BASESWAP_ROUTER_BASE, "BaseSwap Router"),
357 (SPOOKYSWAP_FACTORY_FANTOM, "SpookySwap Factory"),
359 (SPOOKYSWAP_ROUTER_FANTOM, "SpookySwap Router"),
360 (SYNC_SWAP_FACTORY_ZKSYNC, "SyncSwap Factory"),
362 (SYNC_SWAP_ROUTER_ZKSYNC, "SyncSwap Router"),
363 (MY_SWAP_ROUTER_STARKNET, "MySwap Router (StarkNet)"),
365 ];
366 for (dex_addr, dex_name) in &verified_dex_mappings {
367 if address_lower == dex_addr.to_lowercase() {
368 return Some(dex_name);
369 }
370 }
371 None
372}
373
374pub fn get_known_dexes_for_network(evm_type: &str) -> Vec<&'static str> {
375 match evm_type {
376 "ETHEREUM_MAINNET" => vec!["Uniswap", "SushiSwap", "Curve", "Balancer", "1inch"],
377 "ARB_MAINNET" => vec!["Uniswap", "SushiSwap"],
378 "BSC_MAINNET" => vec!["PancakeSwap", "BiSwap"],
379 "POLYGON_MAINNET" => vec!["Uniswap", "QuickSwap", "SushiSwap"],
380 "OPTIMISM_MAINNET" => vec!["Uniswap", "Velodrome"],
381 "AVALANCHE_MAINNET" => vec!["Uniswap", "Trader Joe"],
382 "BASE_MAINNET" => vec!["Uniswap", "BaseSwap"],
383 "FANTOM_MAINNET" => vec!["SpookySwap"],
384 "ZKSYNC_MAINNET" => vec!["SyncSwap"],
385 "STARKNET_MAINNET" => vec!["MySwap"],
386 "HYPEREVM_MAINNET" => vec![],
387 "PLASMA_MAINNET" => vec![],
388 "RONIN_MAINNET" => vec![],
389 "SKALE_MAINNET" => vec![],
390 "IMMUTABLE_MAINNET" => vec![],
391 _ => vec![],
392 }
393}
394
395pub fn is_dex_contract(address: &str) -> bool {
396 get_dex_name_by_address(address).is_some()
397}
398
399pub mod dex_events {
400 use ethers::core::utils::keccak256;
401
402 pub fn uniswap_v2_swap() -> [u8; 32] {
403 keccak256(b"Swap(address,uint256,uint256,uint256,uint256,address)")
404 }
405
406 pub fn uniswap_v2_mint() -> [u8; 32] {
407 keccak256(b"Mint(address,uint256,uint256)")
408 }
409
410 pub fn uniswap_v2_burn() -> [u8; 32] {
411 keccak256(b"Burn(address,uint256,uint256)")
412 }
413
414 pub fn uniswap_v2_sync() -> [u8; 32] {
415 keccak256(b"Sync(uint112,uint112)")
416 }
417
418 pub fn uniswap_v3_swap() -> [u8; 32] {
419 keccak256(b"Swap(address,address,int256,int256,uint160,uint128,int24)")
420 }
421
422 pub fn uniswap_v3_mint() -> [u8; 32] {
423 keccak256(b"Mint(address,address,int24,int24,uint128,uint256,uint256)")
424 }
425
426 pub fn uniswap_v3_burn() -> [u8; 32] {
427 keccak256(b"Burn(address,int24,int24,uint128,uint256,uint256)")
428 }
429
430 pub fn uniswap_v3_collect() -> [u8; 32] {
431 keccak256(b"Collect(address,address,int24,int24,uint128,uint128)")
432 }
433
434 pub fn curve_token_exchange() -> [u8; 32] {
435 keccak256(b"TokenExchange(address,int128,uint256,int128,uint256)")
436 }
437
438 pub fn curve_add_liquidity() -> [u8; 32] {
439 keccak256(b"AddLiquidity(address,uint256[2],uint256[2],uint256,uint256)")
440 }
441
442 pub fn curve_remove_liquidity() -> [u8; 32] {
443 keccak256(b"RemoveLiquidity(address,uint256[2],uint256[2])")
444 }
445
446 pub fn erc20_transfer() -> [u8; 32] {
447 keccak256(b"Transfer(address,address,uint256)")
448 }
449
450 pub fn pancake_swap() -> [u8; 32] {
451 keccak256(b"Swap(address,address,uint256,uint256)")
452 }
453
454 pub fn sushi_swap() -> [u8; 32] {
455 keccak256(b"Swap(address,uint256,uint256,uint256,uint256,address)")
456 }
457
458 pub fn balancer_swap() -> [u8; 32] {
459 keccak256(b"Swap(address,address,uint256,uint256,uint256)")
460 }
461
462 pub fn is_dex_event(topic0: &[u8]) -> bool {
463 topic0 == &uniswap_v2_swap()[..]
464 || topic0 == &uniswap_v2_mint()[..]
465 || topic0 == &uniswap_v2_burn()[..]
466 || topic0 == &uniswap_v2_sync()[..]
467 || topic0 == &uniswap_v3_swap()[..]
468 || topic0 == &uniswap_v3_mint()[..]
469 || topic0 == &uniswap_v3_burn()[..]
470 || topic0 == &uniswap_v3_collect()[..]
471 || topic0 == &curve_token_exchange()[..]
472 || topic0 == &curve_add_liquidity()[..]
473 || topic0 == &curve_remove_liquidity()[..]
474 || topic0 == &pancake_swap()[..]
475 || topic0 == &sushi_swap()[..]
476 || topic0 == &balancer_swap()[..]
477 }
478
479 pub fn identify_dex_by_event(topic0: &[u8]) -> Option<&'static str> {
480 if topic0 == &uniswap_v2_swap()[..]
481 || topic0 == &uniswap_v2_mint()[..]
482 || topic0 == &uniswap_v2_burn()[..]
483 || topic0 == &uniswap_v2_sync()[..]
484 {
485 Some("Uniswap V2")
486 } else if topic0 == &uniswap_v3_swap()[..]
487 || topic0 == &uniswap_v3_mint()[..]
488 || topic0 == &uniswap_v3_burn()[..]
489 || topic0 == &uniswap_v3_collect()[..]
490 {
491 Some("Uniswap V3")
492 } else if topic0 == &curve_token_exchange()[..]
493 || topic0 == &curve_add_liquidity()[..]
494 || topic0 == &curve_remove_liquidity()[..]
495 {
496 Some("Curve")
497 } else if topic0 == &pancake_swap()[..] {
498 Some("PancakeSwap")
499 } else if topic0 == &sushi_swap()[..] {
500 Some("SushiSwap")
501 } else if topic0 == &balancer_swap()[..] {
502 Some("Balancer")
503 } else if is_dex_event(topic0) {
504 Some("Unknown DEX")
505 } else {
506 None
507 }
508 }
509}