1use std::collections::BTreeSet;
2
3use anchor_lang::prelude::{
4 borsh::{BorshDeserialize, BorshSerialize},
5 *,
6};
7
8pub const MAX_MARKET_CONFIG_FLAGS: usize = 128;
10
11pub const MAX_MARKET_FLAGS: usize = 8;
13
14pub const MAX_VIRTUAL_INVENTORY_FLAGS: usize = 8;
16
17#[derive(Debug, thiserror::Error)]
19pub enum MarketError {
20 #[error("not a collateral token")]
22 NotACollateralToken,
23}
24
25type MarketResult<T> = std::result::Result<T, MarketError>;
26
27#[zero_copy]
29#[derive(BorshSerialize, BorshDeserialize)]
30#[cfg_attr(feature = "debug", derive(Debug))]
31#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
32pub struct MarketMeta {
33 pub market_token_mint: Pubkey,
35 pub index_token_mint: Pubkey,
37 pub long_token_mint: Pubkey,
39 pub short_token_mint: Pubkey,
41}
42
43impl MarketMeta {
44 #[inline]
46 pub fn is_collateral_token(&self, token: &Pubkey) -> bool {
47 *token == self.long_token_mint || *token == self.short_token_mint
48 }
49
50 pub fn pnl_token(&self, is_long: bool) -> Pubkey {
52 if is_long {
53 self.long_token_mint
54 } else {
55 self.short_token_mint
56 }
57 }
58
59 pub fn to_token_side(&self, token: &Pubkey) -> MarketResult<bool> {
61 if *token == self.long_token_mint {
62 Ok(true)
63 } else if *token == self.short_token_mint {
64 Ok(false)
65 } else {
66 Err(MarketError::NotACollateralToken)
67 }
68 }
69
70 pub fn opposite_token(&self, token: &Pubkey) -> MarketResult<&Pubkey> {
72 if *token == self.long_token_mint {
73 Ok(&self.short_token_mint)
74 } else if *token == self.short_token_mint {
75 Ok(&self.long_token_mint)
76 } else {
77 Err(MarketError::NotACollateralToken)
78 }
79 }
80
81 pub fn ordered_tokens(&self) -> BTreeSet<Pubkey> {
83 BTreeSet::from([
84 self.index_token_mint,
85 self.long_token_mint,
86 self.short_token_mint,
87 ])
88 }
89}
90
91pub trait HasMarketMeta {
93 fn market_meta(&self) -> &MarketMeta;
94
95 fn is_pure(&self) -> bool {
96 let meta = self.market_meta();
97 meta.long_token_mint == meta.short_token_mint
98 }
99}
100
101impl HasMarketMeta for MarketMeta {
102 fn market_meta(&self) -> &MarketMeta {
103 self
104 }
105}
106
107pub fn ordered_tokens(from: &impl HasMarketMeta, to: &impl HasMarketMeta) -> BTreeSet<Pubkey> {
109 let mut tokens = BTreeSet::default();
110
111 let from = from.market_meta();
112 let to = to.market_meta();
113
114 for mint in [
115 &from.index_token_mint,
116 &from.long_token_mint,
117 &from.short_token_mint,
118 ]
119 .iter()
120 .chain(&[
121 &to.index_token_mint,
122 &to.long_token_mint,
123 &to.short_token_mint,
124 ]) {
125 tokens.insert(**mint);
126 }
127 tokens
128}
129
130#[derive(
132 strum::EnumString,
133 strum::Display,
134 Clone,
135 Copy,
136 PartialEq,
137 Eq,
138 PartialOrd,
139 Ord,
140 Hash,
141 num_enum::TryFromPrimitive,
142 num_enum::IntoPrimitive,
143)]
144#[strum(serialize_all = "snake_case")]
145#[cfg_attr(feature = "debug", derive(Debug))]
146#[cfg_attr(feature = "enum-iter", derive(strum::EnumIter))]
147#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
148#[cfg_attr(feature = "clap", clap(rename_all = "snake_case"))]
149#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
150#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
151#[non_exhaustive]
152#[repr(u8)]
153pub enum MarketConfigFlag {
154 SkipBorrowingFeeForSmallerSide,
156 IgnoreOpenInterestForUsageFactor,
158 }
160
161#[derive(
163 strum::EnumString,
164 strum::Display,
165 Clone,
166 Copy,
167 PartialEq,
168 Eq,
169 PartialOrd,
170 Ord,
171 Hash,
172 num_enum::TryFromPrimitive,
173 num_enum::IntoPrimitive,
174)]
175#[strum(serialize_all = "snake_case")]
176#[cfg_attr(feature = "debug", derive(Debug))]
177#[cfg_attr(feature = "enum-iter", derive(strum::EnumIter))]
178#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
179#[cfg_attr(feature = "clap", clap(rename_all = "snake_case"))]
180#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
181#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
182#[non_exhaustive]
183#[repr(u16)]
184pub enum MarketConfigKey {
185 SwapImpactExponent,
187 SwapImpactPositiveFactor,
189 SwapImpactNegativeFactor,
191 SwapFeeReceiverFactor,
193 SwapFeeFactorForPositiveImpact,
195 SwapFeeFactorForNegativeImpact,
197 MinPositionSizeUsd,
199 MinCollateralValue,
201 MinCollateralFactor,
203 MinCollateralFactorForOpenInterestMultiplierForLong,
205 MinCollateralFactorForOpenInterestMultiplierForShort,
207 MaxPositivePositionImpactFactor,
209 MaxNegativePositionImpactFactor,
211 MaxPositionImpactFactorForLiquidations,
213 PositionImpactExponent,
215 PositionImpactPositiveFactor,
217 PositionImpactNegativeFactor,
219 OrderFeeReceiverFactor,
221 OrderFeeFactorForPositiveImpact,
223 OrderFeeFactorForNegativeImpact,
225 LiquidationFeeReceiverFactor,
227 LiquidationFeeFactor,
229 PositionImpactDistributeFactor,
231 MinPositionImpactPoolAmount,
233 BorrowingFeeReceiverFactor,
235 BorrowingFeeFactorForLong,
237 BorrowingFeeFactorForShort,
239 BorrowingFeeExponentForLong,
241 BorrowingFeeExponentForShort,
243 BorrowingFeeOptimalUsageFactorForLong,
245 BorrowingFeeOptimalUsageFactorForShort,
247 BorrowingFeeBaseFactorForLong,
249 BorrowingFeeBaseFactorForShort,
251 BorrowingFeeAboveOptimalUsageFactorForLong,
253 BorrowingFeeAboveOptimalUsageFactorForShort,
255 FundingFeeExponent,
257 FundingFeeFactor,
259 FundingFeeMaxFactorPerSecond,
261 FundingFeeMinFactorPerSecond,
263 FundingFeeIncreaseFactorPerSecond,
265 FundingFeeDecreaseFactorPerSecond,
267 FundingFeeThresholdForStableFunding,
269 FundingFeeThresholdForDecreaseFunding,
271 ReserveFactor,
273 OpenInterestReserveFactor,
275 MaxPnlFactorForLongDeposit,
277 MaxPnlFactorForShortDeposit,
279 MaxPnlFactorForLongWithdrawal,
281 MaxPnlFactorForShortWithdrawal,
283 MaxPnlFactorForLongTrader,
285 MaxPnlFactorForShortTrader,
287 MaxPnlFactorForLongAdl,
289 MaxPnlFactorForShortAdl,
291 MinPnlFactorAfterLongAdl,
293 MinPnlFactorAfterShortAdl,
295 MaxPoolAmountForLongToken,
297 MaxPoolAmountForShortToken,
299 MaxPoolValueForDepositForLongToken,
301 MaxPoolValueForDepositForShortToken,
303 MaxOpenInterestForLong,
305 MaxOpenInterestForShort,
307 MinTokensForFirstDeposit,
309}
310
311#[derive(num_enum::IntoPrimitive)]
313#[repr(u8)]
314#[non_exhaustive]
315pub enum MarketFlag {
316 Enabled,
318 Pure,
320 AutoDeleveragingEnabledForLong,
322 AutoDeleveragingEnabledForShort,
324 GTEnabled,
326 }
328
329#[derive(num_enum::IntoPrimitive)]
331#[repr(u8)]
332pub enum VirtualInventoryFlag {
333 Disabled,
335 }