hyperdrive_math/short/
fees.rs

1use ethers::types::U256;
2use eyre::Result;
3use fixedpointmath::{fixed, FixedPoint};
4
5use crate::State;
6
7impl State {
8    /// Calculates the curve fee paid when opening shorts with a given bond amount.
9    ///
10    /// The open short curve fee, `$\Phi_{c,os}(\Delta y)$`, is paid in base and
11    /// is given by:
12    ///
13    /// ```math
14    /// \Phi_{c,os}(\Delta y) = \phi_c \cdot (1 - p) \cdot \Delta y
15    /// ```
16    pub fn open_short_curve_fee(&self, bond_amount: FixedPoint<U256>) -> Result<FixedPoint<U256>> {
17        // NOTE: Round up to overestimate the curve fee.
18        Ok(self
19            .curve_fee()
20            .mul_up(fixed!(1e18) - self.calculate_spot_price()?)
21            .mul_up(bond_amount))
22    }
23
24    /// Calculates the governance fee paid when opening shorts with a given bond
25    /// amount.
26    ///
27    /// The open short governance fee, `$\Phi_{g,os}(\Delta y)$`, is paid in
28    /// base and is given by:
29    ///
30    /// ```math
31    /// \Phi_{g,os}(\Delta y) = \phi_g \cdot \Phi_{c,os}(\Delta y)
32    /// ```
33    pub fn open_short_governance_fee(
34        &self,
35        bond_amount: FixedPoint<U256>,
36        maybe_curve_fee: Option<FixedPoint<U256>>,
37    ) -> Result<FixedPoint<U256>> {
38        let curve_fee = match maybe_curve_fee {
39            Some(maybe_curve_fee) => maybe_curve_fee,
40            None => self.open_short_curve_fee(bond_amount)?,
41        };
42        // NOTE: Round down to underestimate the governance fee.
43        Ok(curve_fee.mul_down(self.governance_lp_fee()))
44    }
45
46    /// Calculates the curve fee paid when opening shorts with a given bond
47    /// amount.
48    ///
49    /// The close short curve fee, `$\Phi_{c,cs}(\Delta y)$`, is paid in shares
50    /// and is given by:
51    ///
52    /// ```math
53    /// \Phi_{c,cs}(\Delta y) = \frac{\phi_c \cdot (1-p) \cdot \Delta y \cdot t}{c}
54    /// ```
55    ///
56    /// where $t$ is the normalized time remaining until bond maturity.
57    pub fn close_short_curve_fee(
58        &self,
59        bond_amount: FixedPoint<U256>,
60        maturity_time: U256,
61        current_time: U256,
62    ) -> Result<FixedPoint<U256>> {
63        let normalized_time_remaining =
64            self.calculate_normalized_time_remaining(maturity_time, current_time);
65        // NOTE: Round up to overestimate the curve fee.
66        Ok(self
67            .curve_fee()
68            .mul_up(fixed!(1e18) - self.calculate_spot_price()?)
69            .mul_up(bond_amount)
70            .mul_div_up(normalized_time_remaining, self.vault_share_price()))
71    }
72
73    /// Calculate the governance fee paid when closing shorts with a given bond
74    /// amount.
75    ///
76    /// The close short governance fee, `$\Phi_{g,cs}(\Delta y)$`, is paid in
77    /// shares and is given by:
78    ///
79    /// ```math
80    /// \Phi_{g,cs}(\Delta y) = \Phi_{c,cs}(\Delta y) * \phi_g
81    /// ```
82    ///
83    /// NOTE: Round down to underestimate the governance curve fee
84    pub fn close_short_governance_fee(
85        &self,
86        bond_amount: FixedPoint<U256>,
87        maturity_time: U256,
88        current_time: U256,
89        maybe_curve_fee: Option<FixedPoint<U256>>,
90    ) -> Result<FixedPoint<U256>> {
91        let curve_fee = match maybe_curve_fee {
92            Some(maybe_curve_fee) => maybe_curve_fee,
93            None => self.close_short_curve_fee(bond_amount, maturity_time, current_time)?,
94        };
95        // NOTE: Round down to underestimate the governance fee.
96        Ok(curve_fee.mul_down(self.governance_lp_fee()))
97    }
98
99    /// Calculate the flat fee paid when closing shorts with a given bond
100    /// amount.
101    ///
102    /// The close short flat fee, `$\Phi_{f,cs}(\Delta y)$`, is paid in shares
103    /// and is given by:
104    ///
105    /// ```math
106    /// \Phi_{f,cs}(\Delta y) = \frac{\Delta y \cdot (1 - t) \cdot \phi_f}{c}
107    /// ```
108    ///
109    /// where `$t$` is the normalized time remaining until bond maturity.
110    pub fn close_short_flat_fee(
111        &self,
112        bond_amount: FixedPoint<U256>,
113        maturity_time: U256,
114        current_time: U256,
115    ) -> FixedPoint<U256> {
116        let normalized_time_remaining =
117            self.calculate_normalized_time_remaining(maturity_time, current_time);
118        // NOTE: Round up to overestimate the flat fee.
119        bond_amount
120            .mul_div_up(
121                fixed!(1e18) - normalized_time_remaining,
122                self.vault_share_price(),
123            )
124            .mul_up(self.flat_fee())
125    }
126}