1use std::collections::HashMap;
6
7#[derive(Debug, Clone)]
9pub struct MevConfig {
10 pub enabled: bool,
12 pub relay_url: Option<String>,
14 pub auto_detect: bool,
16}
17
18impl Default for MevConfig {
19 fn default() -> Self {
20 Self {
21 enabled: false,
22 relay_url: None,
23 auto_detect: true,
24 }
25 }
26}
27
28pub fn relay_urls() -> HashMap<u64, &'static str> {
30 let mut urls = HashMap::new();
31 urls.insert(1, "https://rpc.flashbots.net"); urls.insert(5, "https://rpc-goerli.flashbots.net"); urls
34}
35
36const MEV_SUSCEPTIBLE_SELECTORS: &[&str] = &[
40 "0x38ed1739", "0x8803dbee", "0x7ff36ab5", "0x18cbafe5", "0x5ae401dc", "0xac9650d8", "0x04e45aaf", "0xb858183f", "0x414bf389", "0xc04b8d59", "0x2e1a7d4d", "0xd0e30db0", ];
53
54pub fn is_mev_susceptible(input: &str) -> bool {
58 let input = input.strip_prefix("0x").unwrap_or(input);
59 if input.len() < 8 {
60 return false;
61 }
62 let selector = format!("0x{}", &input[..8]);
63 MEV_SUSCEPTIBLE_SELECTORS.contains(&selector.as_str())
64}
65
66pub fn should_use_relay(config: &MevConfig, input: &str) -> bool {
68 if !config.enabled {
69 return false;
70 }
71 if config.relay_url.is_none() {
72 return false;
73 }
74 if config.auto_detect {
75 is_mev_susceptible(input)
76 } else {
77 true
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85
86 #[test]
87 fn detect_uniswap_v2_swap() {
88 assert!(is_mev_susceptible("0x38ed1739000000000000000000000000"));
90 }
91
92 #[test]
93 fn detect_uniswap_v3_multicall() {
94 assert!(is_mev_susceptible("0x5ae401dc000000000000000000000000"));
95 }
96
97 #[test]
98 fn non_mev_transaction() {
99 assert!(!is_mev_susceptible("0xa9059cbb000000000000000000000000"));
101 }
102
103 #[test]
104 fn short_input() {
105 assert!(!is_mev_susceptible("0x"));
106 assert!(!is_mev_susceptible(""));
107 assert!(!is_mev_susceptible("0x1234"));
108 }
109
110 #[test]
111 fn should_use_relay_disabled() {
112 let config = MevConfig::default(); assert!(!should_use_relay(&config, "0x38ed1739"));
114 }
115
116 #[test]
117 fn should_use_relay_enabled_auto() {
118 let config = MevConfig {
119 enabled: true,
120 relay_url: Some("https://rpc.flashbots.net".into()),
121 auto_detect: true,
122 };
123 assert!(should_use_relay(&config, "0x38ed1739")); assert!(!should_use_relay(&config, "0xa9059cbb")); }
126
127 #[test]
128 fn should_use_relay_always_when_no_autodetect() {
129 let config = MevConfig {
130 enabled: true,
131 relay_url: Some("https://rpc.flashbots.net".into()),
132 auto_detect: false,
133 };
134 assert!(should_use_relay(&config, "0xa9059cbb")); }
136
137 #[test]
138 fn relay_urls_has_mainnet() {
139 let urls = relay_urls();
140 assert!(urls.contains_key(&1));
141 }
142
143 #[test]
144 fn without_0x_prefix() {
145 assert!(is_mev_susceptible("38ed1739000000000000000000000000"));
146 }
147}