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 fn address(&self) -> Felt;
17
18 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 fn calculate_price(&self, base_token: Felt, quote_token: Felt) -> Result<f64, StarknetError>;
27
28 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 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 }
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 }
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);