gmsol_programs/model/
position.rs1use std::sync::Arc;
2
3use gmsol_model::action::{decrease_position::DecreasePositionSwapType, swap::SwapReport};
4
5use crate::{constants, gmsol_store::accounts::Position};
6
7use super::MarketModel;
8
9#[derive(Debug, Clone)]
11pub struct PositionModel {
12 market: MarketModel,
13 position: Arc<Position>,
14 is_long: bool,
15 is_collateral_token_long: bool,
16}
17
18#[repr(u8)]
19enum PositionKind {
20 #[allow(dead_code)]
21 Uninitialized,
22 Long,
23 Short,
24}
25
26impl Position {
27 fn try_is_long(&self) -> gmsol_model::Result<bool> {
28 if self.kind == PositionKind::Long as u8 {
29 Ok(true)
30 } else if self.kind == PositionKind::Short as u8 {
31 Ok(false)
32 } else {
33 Err(gmsol_model::Error::InvalidPosition(
34 "uninitialized position",
35 ))
36 }
37 }
38}
39
40impl PositionModel {
41 pub fn new(market: MarketModel, position: Arc<Position>) -> gmsol_model::Result<Self> {
43 let is_long = position.try_is_long()?;
44 let is_collateral_token_long = market.meta.token_side(&position.collateral_token)?;
45 Ok(Self {
46 market,
47 position,
48 is_long,
49 is_collateral_token_long,
50 })
51 }
52
53 fn make_position_mut(&mut self) -> &mut Position {
54 Arc::make_mut(&mut self.position)
55 }
56
57 pub fn position(&self) -> &Position {
59 &self.position
60 }
61}
62
63impl gmsol_model::PositionState<{ constants::MARKET_DECIMALS }> for PositionModel {
64 type Num = u128;
65
66 type Signed = i128;
67
68 fn collateral_amount(&self) -> &Self::Num {
69 &self.position.state.collateral_amount
70 }
71
72 fn size_in_usd(&self) -> &Self::Num {
73 &self.position.state.size_in_usd
74 }
75
76 fn size_in_tokens(&self) -> &Self::Num {
77 &self.position.state.size_in_tokens
78 }
79
80 fn borrowing_factor(&self) -> &Self::Num {
81 &self.position.state.borrowing_factor
82 }
83
84 fn funding_fee_amount_per_size(&self) -> &Self::Num {
85 &self.position.state.funding_fee_amount_per_size
86 }
87
88 fn claimable_funding_fee_amount_per_size(&self, is_long_collateral: bool) -> &Self::Num {
89 if is_long_collateral {
90 &self
91 .position
92 .state
93 .long_token_claimable_funding_amount_per_size
94 } else {
95 &self
96 .position
97 .state
98 .short_token_claimable_funding_amount_per_size
99 }
100 }
101}
102
103impl gmsol_model::PositionStateMut<{ constants::MARKET_DECIMALS }> for PositionModel {
104 fn collateral_amount_mut(&mut self) -> &mut Self::Num {
105 &mut self.make_position_mut().state.collateral_amount
106 }
107
108 fn size_in_usd_mut(&mut self) -> &mut Self::Num {
109 &mut self.make_position_mut().state.size_in_usd
110 }
111
112 fn size_in_tokens_mut(&mut self) -> &mut Self::Num {
113 &mut self.make_position_mut().state.size_in_tokens
114 }
115
116 fn borrowing_factor_mut(&mut self) -> &mut Self::Num {
117 &mut self.make_position_mut().state.borrowing_factor
118 }
119
120 fn funding_fee_amount_per_size_mut(&mut self) -> &mut Self::Num {
121 &mut self.make_position_mut().state.funding_fee_amount_per_size
122 }
123
124 fn claimable_funding_fee_amount_per_size_mut(
125 &mut self,
126 is_long_collateral: bool,
127 ) -> &mut Self::Num {
128 if is_long_collateral {
129 &mut self
130 .make_position_mut()
131 .state
132 .long_token_claimable_funding_amount_per_size
133 } else {
134 &mut self
135 .make_position_mut()
136 .state
137 .short_token_claimable_funding_amount_per_size
138 }
139 }
140}
141
142impl gmsol_model::Position<{ constants::MARKET_DECIMALS }> for PositionModel {
143 type Market = MarketModel;
144
145 fn market(&self) -> &Self::Market {
146 &self.market
147 }
148
149 fn is_long(&self) -> bool {
150 self.is_long
151 }
152
153 fn is_collateral_token_long(&self) -> bool {
154 self.is_collateral_token_long
155 }
156
157 fn are_pnl_and_collateral_tokens_the_same(&self) -> bool {
158 self.is_long == self.is_collateral_token_long || self.market.is_pure()
159 }
160
161 fn on_validate(&self) -> gmsol_model::Result<()> {
162 Ok(())
163 }
164}
165
166impl gmsol_model::PositionMut<{ constants::MARKET_DECIMALS }> for PositionModel {
167 fn market_mut(&mut self) -> &mut Self::Market {
168 &mut self.market
169 }
170
171 fn on_increased(&mut self) -> gmsol_model::Result<()> {
172 Ok(())
173 }
174
175 fn on_decreased(&mut self) -> gmsol_model::Result<()> {
176 Ok(())
177 }
178
179 fn on_swapped(
180 &mut self,
181 _ty: DecreasePositionSwapType,
182 _report: &SwapReport<Self::Num, <Self::Num as gmsol_model::num::Unsigned>::Signed>,
183 ) -> gmsol_model::Result<()> {
184 Ok(())
185 }
186
187 fn on_swap_error(
188 &mut self,
189 _ty: DecreasePositionSwapType,
190 _error: gmsol_model::Error,
191 ) -> gmsol_model::Result<()> {
192 Ok(())
193 }
194}