gmsol_model/market/
borrowing.rs1use num_traits::{CheckedAdd, CheckedSub, Zero};
2
3use crate::{
4 action::update_borrowing_state::UpdateBorrowingState,
5 params::fee::{BorrowingFeeKinkModelParams, BorrowingFeeParams},
6 price::Prices,
7 Balance, BalanceExt, BaseMarket, BaseMarketExt,
8};
9
10pub trait BorrowingFeeMarket<const DECIMALS: u8>: BaseMarket<DECIMALS> {
12 fn borrowing_factor_pool(&self) -> crate::Result<&Self::Pool>;
14
15 fn total_borrowing_pool(&self) -> crate::Result<&Self::Pool>;
17
18 fn borrowing_fee_params(&self) -> crate::Result<BorrowingFeeParams<Self::Num>>;
20
21 fn passed_in_seconds_for_borrowing(&self) -> crate::Result<u64>;
23
24 fn borrowing_fee_kink_model_params(
26 &self,
27 ) -> crate::Result<BorrowingFeeKinkModelParams<Self::Num>>;
28}
29
30impl<M: BorrowingFeeMarket<DECIMALS>, const DECIMALS: u8> BorrowingFeeMarket<DECIMALS> for &mut M {
31 fn borrowing_factor_pool(&self) -> crate::Result<&Self::Pool> {
32 (**self).borrowing_factor_pool()
33 }
34
35 fn total_borrowing_pool(&self) -> crate::Result<&Self::Pool> {
36 (**self).total_borrowing_pool()
37 }
38
39 fn borrowing_fee_params(&self) -> crate::Result<BorrowingFeeParams<Self::Num>> {
40 (**self).borrowing_fee_params()
41 }
42
43 fn passed_in_seconds_for_borrowing(&self) -> crate::Result<u64> {
44 (**self).passed_in_seconds_for_borrowing()
45 }
46
47 fn borrowing_fee_kink_model_params(
48 &self,
49 ) -> crate::Result<BorrowingFeeKinkModelParams<Self::Num>> {
50 (**self).borrowing_fee_kink_model_params()
51 }
52}
53
54pub trait BorrowingFeeMarketExt<const DECIMALS: u8>: BorrowingFeeMarket<DECIMALS> {
56 #[inline]
58 fn cumulative_borrowing_factor(&self, is_long: bool) -> crate::Result<Self::Num> {
59 self.borrowing_factor_pool()?.amount(is_long)
60 }
61
62 fn borrowing_factor_per_second(
64 &self,
65 is_long: bool,
66 prices: &Prices<Self::Num>,
67 ) -> crate::Result<Self::Num> {
68 use crate::utils;
69
70 let reserved_value = self.reserved_value(&prices.index_token_price, is_long)?;
71
72 if reserved_value.is_zero() {
73 return Ok(Zero::zero());
74 }
75
76 let params = self.borrowing_fee_params()?;
77
78 if params.skip_borrowing_fee_for_smaller_side() {
79 let open_interest = self.open_interest()?;
80 let long_interest = open_interest.long_amount()?;
81 let short_interest = open_interest.short_amount()?;
82 if (is_long && long_interest < short_interest)
83 || (!is_long && short_interest < long_interest)
84 {
85 return Ok(Zero::zero());
86 }
87 }
88
89 let pool_value = self.pool_value_without_pnl_for_one_side(prices, is_long, false)?;
90
91 if pool_value.is_zero() {
92 return Err(crate::Error::UnableToGetBorrowingFactorEmptyPoolValue);
93 }
94
95 if let Some(factor) = self
96 .borrowing_fee_kink_model_params()?
97 .borrowing_factor_per_second(self, is_long, &reserved_value, &pool_value)?
98 {
99 Ok(factor)
100 } else {
101 let reserved_value_after_exponent =
102 utils::apply_exponent_factor(reserved_value, params.exponent(is_long).clone())
103 .ok_or(crate::Error::Computation(
104 "calculating reserved value after exponent",
105 ))?;
106 let reserved_value_to_pool_factor =
107 utils::div_to_factor(&reserved_value_after_exponent, &pool_value, false).ok_or(
108 crate::Error::Computation("calculating reserved value to pool factor"),
109 )?;
110 utils::apply_factor(&reserved_value_to_pool_factor, params.factor(is_long)).ok_or(
111 crate::Error::Computation("calculating borrowing factor per second"),
112 )
113 }
114 }
115
116 fn next_cumulative_borrowing_factor(
118 &self,
119 is_long: bool,
120 prices: &Prices<Self::Num>,
121 duration_in_second: u64,
122 ) -> crate::Result<(Self::Num, Self::Num)> {
123 use num_traits::{CheckedMul, FromPrimitive};
124
125 let borrowing_factor_per_second = self.borrowing_factor_per_second(is_long, prices)?;
126 let current_factor = self.cumulative_borrowing_factor(is_long)?;
127
128 let duration_value =
129 Self::Num::from_u64(duration_in_second).ok_or(crate::Error::Convert)?;
130 let delta = borrowing_factor_per_second
131 .checked_mul(&duration_value)
132 .ok_or(crate::Error::Computation(
133 "calculating borrowing factor delta",
134 ))?;
135 let next_cumulative_borrowing_factor =
136 current_factor
137 .checked_add(&delta)
138 .ok_or(crate::Error::Computation(
139 "calculating next borrowing factor",
140 ))?;
141 Ok((next_cumulative_borrowing_factor, delta))
142 }
143
144 fn total_pending_borrowing_fees(
146 &self,
147 prices: &Prices<Self::Num>,
148 is_long: bool,
149 ) -> crate::Result<Self::Num> {
150 let open_interest = self.open_interest()?.amount(is_long)?;
151
152 let duration_in_second = self.passed_in_seconds_for_borrowing()?;
153 let next_cumulative_borrowing_factor = self
154 .next_cumulative_borrowing_factor(is_long, prices, duration_in_second)?
155 .0;
156 let total_borrowing = self.total_borrowing_pool()?.amount(is_long)?;
157
158 crate::utils::apply_factor(&open_interest, &next_cumulative_borrowing_factor)
159 .and_then(|total| total.checked_sub(&total_borrowing))
160 .ok_or(crate::Error::Computation(
161 "calculating total pending borrowing fees",
162 ))
163 }
164}
165
166impl<M: BorrowingFeeMarket<DECIMALS> + ?Sized, const DECIMALS: u8> BorrowingFeeMarketExt<DECIMALS>
167 for M
168{
169}
170
171pub trait BorrowingFeeMarketMut<const DECIMALS: u8>: BorrowingFeeMarket<DECIMALS> {
173 fn just_passed_in_seconds_for_borrowing(&mut self) -> crate::Result<u64>;
175
176 fn borrowing_factor_pool_mut(&mut self) -> crate::Result<&mut Self::Pool>;
180}
181
182impl<M: BorrowingFeeMarketMut<DECIMALS>, const DECIMALS: u8> BorrowingFeeMarketMut<DECIMALS>
183 for &mut M
184{
185 fn just_passed_in_seconds_for_borrowing(&mut self) -> crate::Result<u64> {
186 (**self).just_passed_in_seconds_for_borrowing()
187 }
188
189 fn borrowing_factor_pool_mut(&mut self) -> crate::Result<&mut Self::Pool> {
190 (**self).borrowing_factor_pool_mut()
191 }
192}
193
194pub trait BorrowingFeeMarketMutExt<const DECIMALS: u8>: BorrowingFeeMarketMut<DECIMALS> {
196 fn update_borrowing(
198 &mut self,
199 prices: &Prices<Self::Num>,
200 ) -> crate::Result<UpdateBorrowingState<&mut Self, DECIMALS>>
201 where
202 Self: Sized,
203 {
204 UpdateBorrowingState::try_new(self, prices)
205 }
206}
207
208impl<M: BorrowingFeeMarketMut<DECIMALS> + ?Sized, const DECIMALS: u8>
209 BorrowingFeeMarketMutExt<DECIMALS> for M
210{
211}