mev_engine/amm/
factory.rs

1use std::sync::Arc;
2
3use async_trait::async_trait;
4use futures::stream::FuturesUnordered;
5use serde::{Deserialize, Serialize};
6use starknet::{
7    core::types::{BlockId, EventFilter, Felt},
8    providers::Provider,
9};
10
11use super::{jediswap::factory::JediswapFactory, pool::AMM, tenkswap::factory::TenKFactory};
12use crate::errors::AMMError;
13
14#[async_trait]
15pub trait AutomatedMarketMakerFactory {
16    /// Returns the address of the AMM.
17    fn address(&self) -> Felt;
18
19    async fn fetch_all_pools<P>(&mut self, provider: Arc<P>) -> Result<Vec<AMM>, AMMError>
20    where
21        P: Provider + Sync + Send;
22
23    fn amm_created_event_signature(&self) -> Vec<Vec<Felt>>;
24
25    /// Populates all AMMs data via batched static calls.
26    async fn populate_amm_data<P>(
27        &self,
28        amms: &mut [AMM],
29        block_number: Option<u64>,
30        provider: Arc<P>,
31    ) -> Result<(), AMMError>
32    where
33        P: Provider + Send + Sync;
34}
35
36macro_rules! factory {
37    ($($factory_type:ident),+ $(,)?) => {
38        #[derive(Debug, Clone, Serialize, Deserialize)]
39        pub enum Factory {
40            $($factory_type($factory_type),)+
41        }
42
43        #[async_trait]
44        impl AutomatedMarketMakerFactory for Factory {
45            fn address(&self) -> Felt{
46                match self {
47                    $(Factory::$factory_type(pool) => pool.address(),)+
48                }
49            }
50
51
52            async fn fetch_all_pools<P>(&mut self, provider: Arc<P>) -> Result<Vec<AMM>, AMMError>
53            where
54            P: Provider + Sync + Send
55            {
56                match self {
57                        $(Factory::$factory_type(pool) => pool.fetch_all_pools(provider).await,)+
58                }
59            }
60
61            fn amm_created_event_signature(&self) -> Vec<Vec<Felt>> {
62                match self {
63                    $(Factory::$factory_type(factory) => factory.amm_created_event_signature(),)+
64                }
65            }
66
67
68            async fn populate_amm_data<P>(
69                &self,
70                amms: &mut [AMM],
71                block_number: Option<u64>,
72                provider: Arc<P>,
73            ) -> Result<(), AMMError>
74            where
75                P: Provider + Send + Sync
76            {
77                match self {
78                    $(Factory::$factory_type(factory) => {
79                        factory.populate_amm_data(amms, block_number, provider).await
80                    },)+
81                }
82            }
83        }
84
85
86        impl PartialEq for Factory {
87            fn eq(&self, other: &Self) -> bool {
88                self.address() == other.address()
89            }
90        }
91
92        impl Eq for Factory {}
93    };
94}
95
96factory!(JediswapFactory, TenKFactory);
97
98impl Factory {
99    #[allow(unused)]
100    pub async fn get_all_pools_from_logs<P>(
101        &self,
102        mut from_block: u64,
103        to_block: u64,
104        step: u64,
105        provider: Arc<P>,
106    ) -> Result<Vec<AMM>, AMMError>
107    where
108        P: Provider,
109    {
110        let factory_address = self.address();
111        let amm_created_event_signature = self.amm_created_event_signature();
112        let mut futures = FuturesUnordered::new();
113
114        let mut aggregated_amms: Vec<AMM> = vec![];
115
116        while from_block < to_block {
117            let provider = provider.clone();
118            let mut target_block = from_block + step - 1;
119            if target_block > to_block {
120                target_block = to_block;
121            }
122
123            let filter = EventFilter {
124                from_block: Some(BlockId::Number(from_block)),
125                to_block: Some(BlockId::Number(to_block)),
126                address: Some(factory_address),
127                keys: Some(self.amm_created_event_signature()),
128            };
129
130            futures.push(async move { provider.get_events(filter, None, 10).await });
131
132            // from_block += step;
133        }
134
135        // while let Some(result) = futures.next().await {
136        //     let logs = result.map_err(AMMError::TransportError)?;
137        //
138        //     for log in logs {
139        //         aggregated_amms.push(self.new_empty_amm_from_log(log).unwrap());
140        //     }
141        // }
142
143        Ok(aggregated_amms)
144    }
145}