gmsol_model/market/
borrowing.rs

1use 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
10/// A market with borrowing fees.
11pub trait BorrowingFeeMarket<const DECIMALS: u8>: BaseMarket<DECIMALS> {
12    /// Get borrowing factor pool.
13    fn borrowing_factor_pool(&self) -> crate::Result<&Self::Pool>;
14
15    /// Get total borrowing pool.
16    fn total_borrowing_pool(&self) -> crate::Result<&Self::Pool>;
17
18    /// Get borrowing fee params.
19    fn borrowing_fee_params(&self) -> crate::Result<BorrowingFeeParams<Self::Num>>;
20
21    /// Get the passed time in seconds for the given kind of clock.
22    fn passed_in_seconds_for_borrowing(&self) -> crate::Result<u64>;
23
24    /// Get borrowing fee kink model params.
25    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
54/// Extension trait for [`BorrowingFeeMarket`].
55pub trait BorrowingFeeMarketExt<const DECIMALS: u8>: BorrowingFeeMarket<DECIMALS> {
56    /// Get current borrowing factor.
57    #[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    /// Get borrowing factor per second.
63    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    /// Get next cumulative borrowing factor of the given side.
117    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    /// Get total pending borrowing fees.
145    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
171/// A market that can update the borrowing fees.
172pub trait BorrowingFeeMarketMut<const DECIMALS: u8>: BorrowingFeeMarket<DECIMALS> {
173    /// Get the just passed time in seconds for the given kind of clock.
174    fn just_passed_in_seconds_for_borrowing(&mut self) -> crate::Result<u64>;
175
176    /// Get borrowing factor pool mutably.
177    /// # Requirements
178    /// - This method must return `Ok` if [`BorrowingFeeMarket::borrowing_factor_pool`] does.
179    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
194/// Extension trait for [`BorrowingFeeMarketMut`].
195pub trait BorrowingFeeMarketMutExt<const DECIMALS: u8>: BorrowingFeeMarketMut<DECIMALS> {
196    /// Create a [`UpdateBorrowingState`] action.
197    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}