1use std::{borrow::Cow, fmt::Display, sync::Arc};
17
18use serde::{Deserialize, Serialize};
19
20use crate::{
21 defi::{amm::Pool, chain::Chain},
22 identifiers::{InstrumentId, Symbol, Venue},
23 instruments::{Instrument, any::InstrumentAny, currency_pair::CurrencyPair},
24 types::{currency::Currency, fixed::FIXED_PRECISION, price::Price, quantity::Quantity},
25};
26
27#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
29#[non_exhaustive]
30pub enum AmmType {
31 CPAMM,
33 CLAMM,
35 CLAMEnhanced,
37 StableSwap,
39 WeightedPool,
41 ComposablePool,
43}
44
45#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
47pub struct Dex {
48 pub chain: Chain,
50 pub name: Cow<'static, str>,
52 pub factory: Cow<'static, str>,
54 pub pool_created_event: Cow<'static, str>,
56 pub swap_created_event: Cow<'static, str>,
58 pub mint_created_event: Cow<'static, str>,
60 pub burn_created_event: Cow<'static, str>,
62 pub amm_type: AmmType,
64 #[allow(dead_code)] pairs: Vec<Pool>,
67}
68
69pub type SharedDex = Arc<Dex>;
71
72impl Dex {
73 #[must_use]
75 #[allow(clippy::too_many_arguments)]
76 pub fn new(
77 chain: Chain,
78 name: impl Into<Cow<'static, str>>,
79 factory: impl Into<Cow<'static, str>>,
80 amm_type: AmmType,
81 pool_created_event: impl Into<Cow<'static, str>>,
82 swap_created_event: impl Into<Cow<'static, str>>,
83 mint_created_event: impl Into<Cow<'static, str>>,
84 burn_created_event: impl Into<Cow<'static, str>>,
85 ) -> Self {
86 Self {
87 chain,
88 name: name.into(),
89 factory: factory.into(),
90 pool_created_event: pool_created_event.into(),
91 swap_created_event: swap_created_event.into(),
92 mint_created_event: mint_created_event.into(),
93 burn_created_event: burn_created_event.into(),
94 amm_type,
95 pairs: vec![],
96 }
97 }
98
99 pub fn id(&self) -> String {
101 format!(
102 "{}:{}",
103 self.chain.name,
104 self.name.to_lowercase().replace(' ', "_")
105 )
106 }
107}
108
109impl Display for Dex {
110 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111 write!(f, "Dex(chain={}, name={})", self.chain, self.name)
112 }
113}
114
115impl From<Pool> for CurrencyPair {
116 fn from(p: Pool) -> Self {
117 let symbol = Symbol::from(format!("{}/{}", p.token0.symbol, p.token1.symbol));
118 let id = InstrumentId::new(symbol, Venue::from(p.dex.id()));
119
120 let size_precision = p.token0.decimals.min(FIXED_PRECISION);
121 let price_precision = p.token1.decimals.min(FIXED_PRECISION);
122
123 let price_increment = Price::new(10f64.powi(-(price_precision as i32)), price_precision);
124 let size_increment = Quantity::new(10f64.powi(-(size_precision as i32)), size_precision);
125
126 CurrencyPair::new(
127 id,
128 symbol,
129 Currency::from(p.token0.symbol.as_str()),
130 Currency::from(p.token1.symbol.as_str()),
131 price_precision,
132 size_precision,
133 price_increment,
134 size_increment,
135 None,
136 None,
137 None,
138 None,
139 None,
140 None,
141 None,
142 None,
143 None,
144 None,
145 None,
146 0.into(),
147 0.into(),
148 )
149 }
150}
151
152impl From<Pool> for InstrumentAny {
153 fn from(p: Pool) -> Self {
154 CurrencyPair::from(p).into_any()
155 }
156}