Skip to main content

evm_sdk/
global.rs

1// Ethereum Mainnet
2pub 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
8// Arbitrum Mainnet
9pub 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
15// BSC Mainnet
16pub 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
23// Base Mainnet
24pub 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
29// HyperEVM Mainnet
30pub 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
35// Plasma Mainnet
36pub const WXPL_PLASMA_MAINNET: &'static str = "0x6100E367285b01F48D07953803A2d8dCA5D19873";
37
38// Polygon Mainnet
39pub 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
44// Optimism Mainnet
45pub 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
50// zkSync Mainnet
51pub const ETH_ZKSYNC_MAINNET: &'static str = "0x000000000000000000000000000000000000800A";
52pub const USDC_ZKSYNC_MAINNET: &'static str = "0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4";
53pub const ZK_ZKSYNC_MAINNET: &'static str = "0x5A7d6b2F92C77FAD6CCaBd7EE0624E64907Eaf3E";
54
55// StarkNet Mainnet
56pub 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
65// Avalanche Mainnet
66pub 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
178// ============== Ethereum Mainnet ==============
179pub 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
194// ============== Arbitrum Mainnet ==============
195pub 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
201// ============== BSC Mainnet ==============
202pub 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
210// ============== Polygon Mainnet ==============
211pub 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
219// ============== Optimism Mainnet ==============
220pub 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
227// ============== Avalanche Mainnet ==============
228pub 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
234// ============== Base Mainnet ==============
235pub 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
241// ============== Fantom Mainnet ==============
242pub const SPOOKYSWAP_FACTORY_FANTOM: &'static str = "0x152eE697f2E276fA89E96742e9bB9aB1F2E61bE3";
243pub const SPOOKYSWAP_ROUTER_FANTOM: &'static str = "0xF491e7B69E4244ad4002BC14e878a34207E38c29";
244
245// ============== zkSync Mainnet ==============
246pub const SYNC_SWAP_FACTORY_ZKSYNC: &'static str = "0xf2DAd89f2788a8CD54625C60b55cD3d2D0ACa7Cb";
247pub const SYNC_SWAP_ROUTER_ZKSYNC: &'static str = "0x2da10A1e27bF85cEdD8FFb1AbBe97e53391C0295";
248
249// ============== StarkNet Mainnet ==============
250pub 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        // Ethereum
310        (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        // Arbitrum
321        (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        // BSC
326        (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        // Polygon
333        (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        // Optimism
340        (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        // Avalanche
345        (
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        // Base
353        (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        // Fantom
358        (SPOOKYSWAP_FACTORY_FANTOM, "SpookySwap Factory"),
359        (SPOOKYSWAP_ROUTER_FANTOM, "SpookySwap Router"),
360        // zkSync
361        (SYNC_SWAP_FACTORY_ZKSYNC, "SyncSwap Factory"),
362        (SYNC_SWAP_ROUTER_ZKSYNC, "SyncSwap Router"),
363        // StarkNet
364        (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}