1use alloy::dyn_abi::DynSolType;
8use alloy::dyn_abi::DynSolValue;
9use alloy::primitives::{Address, Log};
10use pool_structures::balancer_v2_structure::BalancerV2Pool;
11use pool_structures::maverick_structure::MaverickPool;
12use pool_structures::tri_crypto_curve_structure::CurveTriCryptoPool;
13use pool_structures::two_crypto_curve_structure::CurveTwoCryptoPool;
14use pool_structures::v2_structure::UniswapV2Pool;
15use pool_structures::v3_structure::UniswapV3Pool;
16
17use serde::{Deserialize, Serialize};
18use std::fmt;
19
20use crate::chain::Chain;
21use crate::impl_pool_info;
22
23mod gen;
24pub mod pool_builder;
25pub mod pool_fetchers;
26pub mod pool_structures;
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
30pub enum PoolType {
31 UniswapV2,
32 SushiSwapV2,
33 PancakeSwapV2,
34 UniswapV3,
35 SushiSwapV3,
36 PancakeSwapV3,
37 Aerodrome,
38 Slipstream,
39 BaseSwapV2,
40 BaseSwapV3,
41 AlienBaseV2,
42 AlienBaseV3,
43 MaverickV1,
44 MaverickV2,
45 CurveTwoCrypto,
46 CurveTriCrypto,
47 BalancerV2,
48 SwapBasedV2,
49 SwapBasedV3,
50 DackieSwapV2,
51 DackieSwapV3,
52}
53
54impl PoolType {
55 pub fn is_v2(&self) -> bool {
56 matches!(
57 self,
58 PoolType::UniswapV2
59 | PoolType::SushiSwapV2
60 | PoolType::PancakeSwapV2
61 | PoolType::Aerodrome
62 | PoolType::BaseSwapV2
63 | PoolType::SwapBasedV2
64 | PoolType::DackieSwapV2
65 | PoolType::AlienBaseV2
66 )
67 }
68
69 pub fn is_v3(&self) -> bool {
70 matches!(
71 self,
72 PoolType::UniswapV3
73 | PoolType::SushiSwapV3
74 | PoolType::PancakeSwapV3
75 | PoolType::Slipstream
76 | PoolType::BaseSwapV3
77 | PoolType::AlienBaseV3
78 | PoolType::SwapBasedV3
79 | PoolType::DackieSwapV3
80 )
81 }
82
83 pub fn is_maverick(&self) -> bool {
84 matches!(self, PoolType::MaverickV1 | PoolType::MaverickV2)
85 }
86
87 pub fn is_curve_two(&self) -> bool {
88 matches!(self, PoolType::CurveTwoCrypto)
89 }
90
91 pub fn is_curve_tri(&self) -> bool {
92 matches!(self, PoolType::CurveTriCrypto)
93 }
94
95 pub fn is_balancer(&self) -> bool {
96 matches!(self, PoolType::BalancerV2)
97 }
98
99 pub fn build_pool(&self, pool_data: &[DynSolValue]) -> Pool {
100 if self.is_v2() {
101 let pool = UniswapV2Pool::from(pool_data);
102 Pool::new_v2(*self, pool)
103 } else if self.is_v3() {
104 let pool = UniswapV3Pool::from(pool_data);
105 Pool::new_v3(*self, pool)
106 } else if self.is_maverick() {
107 let pool = MaverickPool::from(pool_data);
108 Pool::new_maverick(*self, pool)
109 } else if self.is_balancer() {
110 let pool = BalancerV2Pool::from(pool_data);
111 Pool::new_balancer(*self, pool)
112 } else if self.is_curve_two() {
113 let pool = CurveTwoCryptoPool::from(pool_data);
114 Pool::new_curve_two(*self, pool)
115 } else if self.is_curve_tri() {
116 let pool = CurveTriCryptoPool::from(pool_data);
117 Pool::new_curve_tri(*self, pool)
118 } else {
119 panic!("Invalid pool type");
120 }
121 }
122}
123
124#[derive(Debug, Clone, Serialize, Deserialize)]
126pub enum Pool {
127 UniswapV2(UniswapV2Pool),
128 SushiSwapV2(UniswapV2Pool),
129 PancakeSwapV2(UniswapV2Pool),
130 BaseSwapV2(UniswapV2Pool),
131 AlienBaseV2(UniswapV2Pool),
132 SwapBasedV2(UniswapV2Pool),
133 DackieSwapV2(UniswapV2Pool),
134
135 Aerodrome(UniswapV2Pool),
136 Slipstream(UniswapV3Pool),
137
138 UniswapV3(UniswapV3Pool),
139 SushiSwapV3(UniswapV3Pool),
140 PancakeSwapV3(UniswapV3Pool),
141 BaseSwapV3(UniswapV3Pool),
142 AlienBaseV3(UniswapV3Pool),
143 SwapBasedV3(UniswapV3Pool),
144 DackieSwapV3(UniswapV3Pool),
145
146 MaverickV1(MaverickPool),
147 MaverickV2(MaverickPool),
148
149 CurveTwoCrypto(CurveTwoCryptoPool),
150 CurveTriCrypto(CurveTriCryptoPool),
151
152 BalancerV2(BalancerV2Pool),
153}
154
155impl Pool {
156 pub fn new_v2(pool_type: PoolType, pool: UniswapV2Pool) -> Self {
157 match pool_type {
158 PoolType::UniswapV2 => Pool::UniswapV2(pool),
159 PoolType::SushiSwapV2 => Pool::SushiSwapV2(pool),
160 PoolType::PancakeSwapV2 => Pool::PancakeSwapV2(pool),
161 PoolType::Aerodrome => Pool::Aerodrome(pool),
162 PoolType::BaseSwapV2 => Pool::BaseSwapV2(pool),
163 PoolType::SwapBasedV2 => Pool::SwapBasedV2(pool),
164 PoolType::DackieSwapV2 => Pool::DackieSwapV2(pool),
165 PoolType::AlienBaseV2 => Pool::AlienBaseV2(pool),
166 _ => panic!("Invalid pool type"),
167 }
168 }
169
170 pub fn new_v3(pool_type: PoolType, pool: UniswapV3Pool) -> Self {
171 match pool_type {
172 PoolType::UniswapV3 => Pool::UniswapV3(pool),
173 PoolType::SushiSwapV3 => Pool::SushiSwapV3(pool),
174 PoolType::PancakeSwapV3 => Pool::PancakeSwapV3(pool),
175 PoolType::Slipstream => Pool::Slipstream(pool),
176 PoolType::BaseSwapV3 => Pool::BaseSwapV3(pool),
177 PoolType::SwapBasedV3 => Pool::SwapBasedV3(pool),
178 PoolType::DackieSwapV3 => Pool::DackieSwapV3(pool),
179 PoolType::AlienBaseV3 => Pool::AlienBaseV3(pool),
180 _ => panic!("Invalid pool type"),
181 }
182 }
183
184 pub fn new_maverick(pool_type: PoolType, pool: MaverickPool) -> Self {
185 match pool_type {
186 PoolType::MaverickV1 => Pool::MaverickV1(pool),
187 PoolType::MaverickV2 => Pool::MaverickV2(pool),
188 _ => panic!("Invalid pool type"),
189 }
190 }
191
192 pub fn new_curve_two(pool_type: PoolType, pool: CurveTwoCryptoPool) -> Self {
193 match pool_type {
194 PoolType::CurveTwoCrypto => Pool::CurveTwoCrypto(pool),
195 _ => panic!("Invalid pool type"),
196 }
197 }
198
199 pub fn new_curve_tri(pool_type: PoolType, pool: CurveTriCryptoPool) -> Self {
200 match pool_type {
201 PoolType::CurveTriCrypto => Pool::CurveTriCrypto(pool),
202 _ => panic!("Invalid pool type"),
203 }
204 }
205
206 pub fn new_balancer(pool_type: PoolType, pool: BalancerV2Pool) -> Self {
207 match pool_type {
208 PoolType::BalancerV2 => Pool::BalancerV2(pool),
209 _ => panic!("Invalid pool type"),
210 }
211 }
212
213 pub fn is_v2(&self) -> bool {
214 match self {
215 Pool::UniswapV2(_) => true,
216 Pool::SushiSwapV2(_) => true,
217 Pool::PancakeSwapV2(_) => true,
218 Pool::Aerodrome(_) => true,
219 Pool::BaseSwapV2(_) => true,
220 Pool::AlienBaseV2(_) => true,
221 Pool::SwapBasedV2(_) => true,
222 Pool::DackieSwapV2(_) => true,
223 _ => false,
224 }
225 }
226
227 pub fn is_v3(&self) -> bool {
228 match self {
229 Pool::UniswapV3(_) => true,
230 Pool::SushiSwapV3(_) => true,
231 Pool::PancakeSwapV3(_) => true,
232 Pool::Slipstream(_) => true,
233 Pool::BaseSwapV3(_) => true,
234 Pool::AlienBaseV3(_) => true,
235 Pool::SwapBasedV3(_) => true,
236 Pool::DackieSwapV3(_) => true,
237 _ => false,
238 }
239 }
240
241 pub fn is_maverick(&self) -> bool {
242 match self {
243 Pool::MaverickV1(_) => true,
244 Pool::MaverickV2(_) => true,
245 _ => false,
246 }
247 }
248
249 pub fn is_curve_two(&self) -> bool {
250 match self {
251 Pool::CurveTwoCrypto(_) => true,
252 _ => false,
253 }
254 }
255
256 pub fn is_curve_tri(&self) -> bool {
257 match self {
258 Pool::CurveTriCrypto(_) => true,
259 _ => false,
260 }
261 }
262
263 pub fn is_balancer(&self) -> bool {
264 match self {
265 Pool::BalancerV2(_) => true,
266 _ => false,
267 }
268 }
269
270 pub fn get_v2(&self) -> Option<&UniswapV2Pool> {
271 match self {
272 Pool::UniswapV2(pool) => Some(pool),
273 Pool::SushiSwapV2(pool) => Some(pool),
274 Pool::PancakeSwapV2(pool) => Some(pool),
275 Pool::Aerodrome(pool) => Some(pool),
276 Pool::BaseSwapV2(pool) => Some(pool),
277 Pool::SwapBasedV2(pool) => Some(pool),
278 Pool::DackieSwapV2(pool) => Some(pool),
279 Pool::AlienBaseV2(pool) => Some(pool),
280 _ => None,
281 }
282 }
283
284 pub fn get_v3(&self) -> Option<&UniswapV3Pool> {
285 match self {
286 Pool::UniswapV3(pool) => Some(pool),
287 Pool::SushiSwapV3(pool) => Some(pool),
288 Pool::PancakeSwapV3(pool) => Some(pool),
289 Pool::Slipstream(pool) => Some(pool),
290 Pool::BaseSwapV3(pool) => Some(pool),
291 Pool::AlienBaseV3(pool) => Some(pool),
292 Pool::SwapBasedV3(pool) => Some(pool),
293 Pool::DackieSwapV3(pool) => Some(pool),
294 _ => None,
295 }
296 }
297
298 pub fn get_maverick(&self) -> Option<&MaverickPool> {
299 match self {
300 Pool::MaverickV1(pool) => Some(pool),
301 Pool::MaverickV2(pool) => Some(pool),
302 _ => None,
303 }
304 }
305
306 pub fn get_curve_two(&self) -> Option<&CurveTwoCryptoPool> {
307 match self {
308 Pool::CurveTwoCrypto(pool) => Some(pool),
309 _ => None,
310 }
311 }
312
313 pub fn get_curve_tri(&self) -> Option<&CurveTriCryptoPool> {
314 match self {
315 Pool::CurveTriCrypto(pool) => Some(pool),
316 _ => None,
317 }
318 }
319
320 pub fn get_balancer(&self) -> Option<&BalancerV2Pool> {
321 match self {
322 Pool::BalancerV2(pool) => Some(pool),
323 _ => None,
324 }
325 }
326
327 pub fn get_v2_mut(&mut self) -> Option<&mut UniswapV2Pool> {
328 match self {
329 Pool::UniswapV2(pool) => Some(pool),
330 Pool::SushiSwapV2(pool) => Some(pool),
331 Pool::PancakeSwapV2(pool) => Some(pool),
332 Pool::Aerodrome(pool) => Some(pool),
333 Pool::BaseSwapV2(pool) => Some(pool),
334 Pool::AlienBaseV2(pool) => Some(pool),
335 Pool::SwapBasedV2(pool) => Some(pool),
336 Pool::DackieSwapV2(pool) => Some(pool),
337 _ => None,
338 }
339 }
340
341 pub fn get_v3_mut(&mut self) -> Option<&mut UniswapV3Pool> {
342 match self {
343 Pool::UniswapV3(pool) => Some(pool),
344 Pool::SushiSwapV3(pool) => Some(pool),
345 Pool::PancakeSwapV3(pool) => Some(pool),
346 Pool::Slipstream(pool) => Some(pool),
347 Pool::BaseSwapV3(pool) => Some(pool),
348 Pool::AlienBaseV3(pool) => Some(pool),
349 Pool::SwapBasedV3(pool) => Some(pool),
350 Pool::DackieSwapV3(pool) => Some(pool),
351 _ => None,
352 }
353 }
354
355 pub fn get_maverick_mut(&mut self) -> Option<&mut MaverickPool> {
356 match self {
357 Pool::MaverickV1(pool) => Some(pool),
358 Pool::MaverickV2(pool) => Some(pool),
359 _ => None,
360 }
361 }
362
363 pub fn get_curve_two_mut(&mut self) -> Option<&mut CurveTwoCryptoPool> {
364 match self {
365 Pool::CurveTwoCrypto(pool) => Some(pool),
366 _ => None,
367 }
368 }
369
370 pub fn get_curve_tri_mut(&mut self) -> Option<&mut CurveTriCryptoPool> {
371 match self {
372 Pool::CurveTriCrypto(pool) => Some(pool),
373 _ => None,
374 }
375 }
376
377 pub fn get_balancer_mut(&mut self) -> Option<&mut BalancerV2Pool> {
378 match self {
379 Pool::BalancerV2(pool) => Some(pool),
380 _ => None,
381 }
382 }
383
384 pub fn is_valid(&self) -> bool {
385 self.address() != Address::ZERO
386 && self.token0_address() != Address::ZERO
387 && self.token1_address() != Address::ZERO
388 }
389
390 fn update_token0_name(pool: &mut Pool, token0: String) {
391 if pool.is_v2() {
392 let pool = pool.get_v2_mut().unwrap();
393 pool.token0_name = token0;
394 } else if pool.is_v3() {
395 let pool = pool.get_v3_mut().unwrap();
396 pool.token0_name = token0;
397 } else if pool.is_curve_two() {
398 let pool = pool.get_curve_two_mut().unwrap();
399 pool.token0_name = token0;
400 } else if pool.is_curve_tri() {
401 let pool = pool.get_curve_tri_mut().unwrap();
402 pool.token0_name = token0;
403 } else if pool.is_balancer() {
404 let pool = pool.get_balancer_mut().unwrap();
405 pool.token0_name = token0;
406 } else if pool.is_maverick() {
407 let pool = pool.get_maverick_mut().unwrap();
408 pool.token0_name = token0;
409 }
410 }
411
412 pub fn update_token1_name(pool: &mut Pool, token1: String) {
413 if pool.is_v2() {
414 let pool = pool.get_v2_mut().unwrap();
415 pool.token1_name = token1;
416 } else if pool.is_v3() {
417 let pool = pool.get_v3_mut().unwrap();
418 pool.token1_name = token1;
419 } else if pool.is_curve_two() {
420 let pool = pool.get_curve_two_mut().unwrap();
421 pool.token1_name = token1;
422 } else if pool.is_curve_tri() {
423 let pool = pool.get_curve_tri_mut().unwrap();
424 pool.token1_name = token1;
425 } else if pool.is_balancer() {
426 let pool = pool.get_balancer_mut().unwrap();
427 pool.token1_name = token1;
428 } else if pool.is_maverick() {
429 let pool = pool.get_maverick_mut().unwrap();
430 pool.token1_name = token1;
431 }
432 }
433}
434
435impl fmt::Display for PoolType {
436 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
437 write!(f, "{:?}", self)
438 }
439}
440
441impl_pool_info!(
443 Pool,
444 UniswapV2,
445 SushiSwapV2,
446 PancakeSwapV2,
447 UniswapV3,
448 SushiSwapV3,
449 PancakeSwapV3,
450 Aerodrome,
451 Slipstream,
452 BaseSwapV2,
453 BaseSwapV3,
454 AlienBaseV2,
455 AlienBaseV3,
456 MaverickV1,
457 MaverickV2,
458 CurveTwoCrypto,
459 CurveTriCrypto,
460 BalancerV2,
461 SwapBasedV2,
462 SwapBasedV3,
463 DackieSwapV2,
464 DackieSwapV3
465);
466
467pub trait PoolFetcher: Send + Sync {
472 fn pool_type(&self) -> PoolType;
474
475 fn factory_address(&self, chain: Chain) -> Address;
477
478 fn pair_created_signature(&self) -> &str;
480
481 fn log_to_address(&self, log: &Log) -> Address;
483
484 fn get_pool_repr(&self) -> DynSolType;
486}
487
488pub trait PoolInfo {
490 fn address(&self) -> Address;
491 fn token0_address(&self) -> Address;
492 fn token1_address(&self) -> Address;
493 fn token0_name(&self) -> String;
494 fn token1_name(&self) -> String;
495 fn token0_decimals(&self) -> u8;
496 fn token1_decimals(&self) -> u8;
497 fn pool_type(&self) -> PoolType;
498 fn fee(&self) -> u32;
499 fn stable(&self) -> bool;
500}
501
502#[macro_export]
518macro_rules! impl_pool_info {
519 ($enum_name:ident, $($variant:ident),+) => {
520 impl PoolInfo for $enum_name {
521 fn address(&self) -> Address {
522 match self {
523 $(
524 $enum_name::$variant(pool) => pool.address,
525
526 )+
527 }
528 }
529
530 fn token0_address(&self) -> Address {
531 match self {
532 $(
533 $enum_name::$variant(pool) => pool.token0,
534 )+
535 }
536 }
537
538 fn token1_address(&self) -> Address {
539 match self {
540 $(
541 $enum_name::$variant(pool) => pool.token1,
542 )+
543 }
544 }
545
546 fn token0_name(&self) -> String {
547 match self {
548 $(
549 $enum_name::$variant(pool) => pool.token0_name.clone(),
550 )+
551 }
552 }
553 fn token1_name(&self) -> String {
554 match self {
555 $(
556 $enum_name::$variant(pool) => pool.token1_name.clone(),
557 )+
558 }
559 }
560
561 fn token0_decimals(&self) -> u8 {
562 match self {
563 $(
564 $enum_name::$variant(pool) => pool.token0_decimals,
565 )+
566 }
567 }
568 fn token1_decimals(&self) -> u8 {
569 match self {
570 $(
571 $enum_name::$variant(pool) => pool.token1_decimals,
572 )+
573 }
574 }
575
576 fn pool_type(&self) -> PoolType {
577 match self {
578 $(
579 $enum_name::$variant(_) => PoolType::$variant,
580 )+
581 }
582 }
583
584 fn fee(&self) -> u32 {
585 match self {
586 Pool::UniswapV3(pool) | Pool::SushiSwapV3(pool) | Pool::PancakeSwapV3(pool) | Pool::Slipstream(pool) => pool.fee,
587 _ => 0
588 }
589 }
590
591 fn stable(&self) -> bool {
592 match self {
593 Pool::Aerodrome(pool) => pool.stable.unwrap(),
594 _=> false
595 }
596 }
597 }
598 };
599}