pool_sync_mantle/pools/
mod.rs

1//! Core definitions for pool synchronization
2//!
3//! This module defines the core structures and traits used in the pool synchronization system.
4//! It includes enumerations for supported pool types, a unified `Pool` enum, and a trait for
5//! fetching and decoding pool creation events.
6
7use alloy::dyn_abi::DynSolType;
8use alloy::dyn_abi::DynSolValue;
9use alloy::primitives::{Address, Log};
10use pool_structures::v3_structure::UniswapV3Pool;
11use pool_structures::v2_structure::MerchantMoeV2Pool;
12
13use serde::{Deserialize, Serialize};
14use std::fmt;
15
16use crate::chain::Chain;
17use crate::impl_pool_info;
18
19mod gen;
20pub mod pool_builder;
21pub mod pool_fetchers;
22pub mod pool_structures;
23
24/// Enumerates the supported pool types
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
26pub enum PoolType {
27    UniswapV3,
28    MerchantMoe,
29    Agni,
30}
31
32impl PoolType {
33    pub fn is_v3(&self) -> bool {
34        matches!(self, PoolType::UniswapV3 | PoolType::Agni)
35    }
36    
37    pub fn is_v2(&self) -> bool {
38        matches!(self, PoolType::MerchantMoe)
39    }
40
41    pub fn build_pool(&self, pool_data: &[DynSolValue]) -> Pool {
42        if self.is_v3() {
43            let pool = UniswapV3Pool::from(pool_data);
44            Pool::new_v3(*self, pool)
45        } else if self.is_v2() {
46            let pool = MerchantMoeV2Pool::from(pool_data);
47            Pool::new_v2(*self, pool)
48        } else {
49            panic!("Invalid pool type");
50        }
51    }
52}
53
54/// Represents a populated pool from any of the supported protocols
55#[derive(Debug, Clone, Serialize, Deserialize)]
56pub enum Pool {
57    UniswapV3(UniswapV3Pool),
58    MerchantMoe(MerchantMoeV2Pool),
59    Agni(UniswapV3Pool),
60}
61
62impl Pool {
63    pub fn new_v3(pool_type: PoolType, pool: UniswapV3Pool) -> Self {
64        match pool_type {
65            PoolType::UniswapV3 => Pool::UniswapV3(pool),
66            PoolType::Agni => Pool::Agni(pool),
67            _ => panic!("Invalid pool type for V3"),
68        }
69    }
70    
71    pub fn new_v2(pool_type: PoolType, pool: MerchantMoeV2Pool) -> Self {
72        match pool_type {
73            PoolType::MerchantMoe => Pool::MerchantMoe(pool),
74            _ => panic!("Invalid pool type for V2"),
75        }
76    }
77
78    pub fn is_v3(&self) -> bool {
79        matches!(self, Pool::UniswapV3(_) | Pool::Agni(_))
80    }
81    
82    pub fn is_v2(&self) -> bool {
83        matches!(self, Pool::MerchantMoe(_))
84    }
85
86    pub fn get_v3(&self) -> Option<&UniswapV3Pool> {
87        match self {
88            Pool::UniswapV3(pool) | Pool::Agni(pool) => Some(pool),
89            _ => None,
90        }
91    }
92
93    pub fn get_v3_mut(&mut self) -> Option<&mut UniswapV3Pool> {
94        match self {
95            Pool::UniswapV3(pool) | Pool::Agni(pool) => Some(pool),
96            _ => None,
97        }
98    }
99    
100    pub fn get_v2(&self) -> Option<&MerchantMoeV2Pool> {
101        match self {
102            Pool::MerchantMoe(pool) => Some(pool),
103            _ => None,
104        }
105    }
106
107    pub fn get_v2_mut(&mut self) -> Option<&mut MerchantMoeV2Pool> {
108        match self {
109            Pool::MerchantMoe(pool) => Some(pool),
110            _ => None,
111        }
112    }
113
114
115
116    pub fn is_valid(&self) -> bool {
117        self.address() != Address::ZERO
118            && self.token0_address() != Address::ZERO
119            && self.token1_address() != Address::ZERO
120    }
121
122    fn update_token0_name(pool: &mut Pool, token0: String) {
123        if let Some(pool) = pool.get_v3_mut() {
124            pool.token0_name = token0;
125        } else if let Some(pool) = pool.get_v2_mut() {
126            pool.token0_name = token0;
127        }
128    }
129
130    pub fn update_token1_name(pool: &mut Pool, token1: String) {
131        if let Some(pool) = pool.get_v3_mut() {
132            pool.token1_name = token1;
133        } else if let Some(pool) = pool.get_v2_mut() {
134            pool.token1_name = token1;
135        }
136    }
137}
138
139impl fmt::Display for PoolType {
140    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141        write!(f, "{:?}", self)
142    }
143}
144
145// Implement the PoolInfo trait for all pool variants that are supported
146impl_pool_info!(
147    Pool,
148    UniswapV3,
149    MerchantMoe,
150    Agni
151);
152
153/// Defines common functionality for fetching and decoding pool creation events
154///
155/// This trait provides a unified interface for different pool types to implement
156/// their specific logic for identifying and parsing pool creation events.
157pub trait PoolFetcher: Send + Sync {
158    /// Returns the type of pool this fetcher is responsible for
159    fn pool_type(&self) -> PoolType;
160
161    /// Returns the factory address for the given chain
162    fn factory_address(&self, chain: Chain) -> Address;
163
164    /// Returns the event signature for pool creation
165    fn pair_created_signature(&self) -> &str;
166
167    /// Attempts to create a `Pool` instance from a log entry
168    fn log_to_address(&self, log: &Log) -> Address;
169
170    /// Get the DynSolType for the pool
171    fn get_pool_repr(&self) -> DynSolType;
172}
173
174/// Defines common methods that are used to access information about the pools
175pub trait PoolInfo {
176    fn address(&self) -> Address;
177    fn token0_address(&self) -> Address;
178    fn token1_address(&self) -> Address;
179    fn token0_name(&self) -> String;
180    fn token1_name(&self) -> String;
181    fn token0_decimals(&self) -> u8;
182    fn token1_decimals(&self) -> u8;
183    fn pool_type(&self) -> PoolType;
184    fn fee(&self) -> u32;
185    fn stable(&self) -> bool;
186}
187
188/* 
189pub trait V2PoolInfo {
190    fn token0_reserves(&self) -> U128;
191    fn token1_reserves(&self) -> U128;
192}
193
194pub trait V3PoolInfo {
195    fn fee(&self) -> u32;
196    fn tick_spacing(&self) -> i32;
197    fn tick_bitmap(&self) -> HashMap<i16, U256>;
198    fn ticks(&self) -> HashMap<i32, TickInfo>;
199}
200*/
201
202/// Macro for generating getter methods for all of the suppored pools
203#[macro_export]
204macro_rules! impl_pool_info {
205    ($enum_name:ident, $($variant:ident),+) => {
206        impl PoolInfo for $enum_name {
207            fn address(&self) -> Address {
208                match self {
209                    $(
210                        $enum_name::$variant(pool) => pool.address,
211
212                    )+
213                }
214            }
215
216            fn token0_address(&self) -> Address {
217                match self {
218                    $(
219                        $enum_name::$variant(pool) => pool.token0,
220                    )+
221                }
222            }
223
224            fn token1_address(&self) -> Address {
225                match self {
226                    $(
227                        $enum_name::$variant(pool) => pool.token1,
228                    )+
229                }
230            }
231
232            fn token0_name(&self) -> String {
233                match self {
234                    $(
235                        $enum_name::$variant(pool) => pool.token0_name.clone(),
236                    )+
237                }
238            }
239            fn token1_name(&self) -> String {
240                match self {
241                    $(
242                        $enum_name::$variant(pool) => pool.token1_name.clone(),
243                    )+
244                }
245            }
246
247            fn token0_decimals(&self) -> u8 {
248                match self {
249                    $(
250                        $enum_name::$variant(pool) => pool.token0_decimals,
251                    )+
252                }
253            }
254            fn token1_decimals(&self) -> u8 {
255                match self {
256                    $(
257                        $enum_name::$variant(pool) => pool.token1_decimals,
258                    )+
259                }
260            }
261
262            fn pool_type(&self) -> PoolType {
263                match self {
264                    $(
265                        $enum_name::$variant(_) => PoolType::$variant,
266                    )+
267                }
268            }
269
270            fn fee(&self) -> u32 {
271                match self {
272                    Pool::UniswapV3(pool) | Pool::Agni(pool) => pool.fee,
273                    Pool::MerchantMoe(_) => 0, // V2 pools don't have fees in the same way
274                }
275            }
276
277            fn stable(&self) -> bool {
278                false
279            }
280        }
281    };
282}