mev_engine/amm/
pool.rs

1use std::sync::Arc;
2
3use async_trait::async_trait;
4use serde::{Deserialize, Serialize};
5use starknet::{
6    core::types::{Felt, StarknetError},
7    providers::Provider,
8};
9
10use super::jediswap::pool::JediswapPool;
11use crate::amm::tenkswap::pool::TenkSwapPool;
12
13#[async_trait]
14pub trait AutomatedMarketMaker {
15    /// Returns the address of the AMM.
16    fn address(&self) -> Felt;
17
18    /// Returns a vector of tokens in the AMM.
19    fn tokens(&self) -> Vec<Felt>;
20
21    async fn sync<P>(&mut self, provider: Arc<P>) -> Result<(), StarknetError>
22    where
23        P: Provider + Send + Sync;
24
25    /// Calculates a f64 representation of base token price in the AMM.
26    fn calculate_price(&self, base_token: Felt, quote_token: Felt) -> Result<f64, StarknetError>;
27
28    /// Locally simulates a swap in the AMM.
29    ///
30    /// Returns the amount received for `amount_in` of `token_in`.
31    async fn simulate_swap<P>(
32        &self,
33        base_token: Felt,
34        amount_in: Felt,
35        provider: Arc<P>,
36    ) -> Result<Felt, StarknetError>
37    where
38        P: Provider + Send + Sync;
39
40    /// Locally simulates a swap in the AMM.
41    /// Mutates the AMM state to the state of the AMM after swapping.
42    /// Returns the amount received for `amount_in` of `token_in`.
43    fn simulate_swap_mut(
44        &mut self,
45        base_token: Felt,
46        quote_token: Felt,
47        amount_in: Felt,
48    ) -> Result<Felt, StarknetError>;
49
50    // async fn populate_data<P>(&mut self, middleware: Arc<P>) -> Result<(), StarknetError>
51    // where
52    //     P: Provider + Sync + Send;
53}
54
55macro_rules! amm {
56    ($($pool_type:ident),+ $(,)?) => {
57        #[derive(Debug, Clone, Serialize, Deserialize)]
58        pub enum AMM {
59            $($pool_type($pool_type),)+
60        }
61
62        #[async_trait]
63        impl AutomatedMarketMaker for AMM {
64            fn address(&self) -> Felt{
65                match self {
66                    $(AMM::$pool_type(pool) => pool.address(),)+
67                }
68            }
69
70            fn tokens(&self) -> Vec<Felt> {
71                match self {
72                    $(AMM::$pool_type(pool) => pool.tokens(),)+
73                }
74            }
75
76            async fn sync<P>(&mut self, middleware: Arc<P>) -> Result<(), StarknetError>
77            where
78                P: Provider + Send + Sync,
79            {
80                match self {
81                    $(AMM::$pool_type(pool) => pool.sync(middleware).await,)+
82                }
83            }
84
85
86            async fn simulate_swap<P>(&self, base_token: Felt, amount_in: Felt, provider: Arc<P>) -> Result<Felt, StarknetError> where P: Provider + Send + Sync {
87                match self {
88                    $(AMM::$pool_type(pool) => pool.simulate_swap(base_token, amount_in, provider).await,)+
89                }
90            }
91
92            fn simulate_swap_mut(&mut self, base_token: Felt, quote_token: Felt, amount_in: Felt) -> Result<Felt, StarknetError> {
93                match self {
94                    $(AMM::$pool_type(pool) => pool.simulate_swap_mut(base_token, quote_token, amount_in),)+
95                }
96            }
97
98
99            fn calculate_price(&self, base_token: Felt, quote_token: Felt) -> Result<f64, StarknetError> {
100                match self {
101                    $(AMM::$pool_type(pool) => pool.calculate_price(base_token, quote_token),)+
102                }
103            }
104
105
106            // async fn populate_data<P>(&mut self, middleware: Arc<P>) -> Result<(), StarknetError>
107            // where
108            //     P: Provider + Send + Sync,
109            // {
110            //     match self {
111            //         $(AMM::$pool_type(pool) => pool.populate_data(middleware).await,)+
112            //     }
113            // }
114        }
115
116
117        impl PartialEq for AMM {
118            fn eq(&self, other: &Self) -> bool {
119                self.address() == other.address()
120            }
121        }
122
123        impl Eq for AMM {}
124    };
125}
126
127amm!(JediswapPool, TenkSwapPool);