hylo_core/
stability_mode.rs1use std::fmt::Display;
2
3use anchor_lang::prelude::*;
4use fix::prelude::*;
5
6use crate::error::CoreError::StabilityValidation;
7use crate::stability_mode::StabilityMode::{Depeg, Mode1, Mode2, Normal};
8
9#[derive(
12 Copy, Clone, Debug, AnchorSerialize, AnchorDeserialize, PartialEq, PartialOrd,
13)]
14pub enum StabilityMode {
15 Normal,
16 Mode1,
17 Mode2,
18 Depeg,
19}
20
21impl Display for StabilityMode {
22 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23 match self {
24 Normal => f.write_str("Normal"),
25 Mode1 => f.write_str("Mode1"),
26 Mode2 => f.write_str("Mode2"),
27 Depeg => f.write_str("Depeg"),
28 }
29 }
30}
31
32#[derive(Copy, Clone)]
33pub struct StabilityController {
34 pub stability_threshold_1: UFix64<N2>,
35 pub stability_threshold_2: UFix64<N2>,
36}
37
38impl StabilityController {
39 pub fn new(
41 stability_threshold_1: UFix64<N2>,
42 stability_threshold_2: UFix64<N2>,
43 ) -> Result<StabilityController> {
44 let controller = StabilityController {
45 stability_threshold_1,
46 stability_threshold_2,
47 };
48 controller.validate()?;
49 Ok(controller)
50 }
51
52 pub fn stability_mode(
55 &self,
56 collateral_ratio: UFix64<N9>,
57 ) -> Result<StabilityMode> {
58 Ok(
59 if collateral_ratio >= self.stability_threshold_1.convert() {
60 Normal
61 } else if collateral_ratio >= self.stability_threshold_2.convert() {
62 Mode1
63 } else if collateral_ratio >= UFix64::one() {
64 Mode2
65 } else {
66 Depeg
67 },
68 )
69 }
70
71 #[must_use]
74 pub fn prev_stability_threshold(
75 &self,
76 mode: StabilityMode,
77 ) -> Option<UFix64<N2>> {
78 match mode {
79 Normal => None,
80 Mode1 => Some(self.stability_threshold_1),
81 Mode2 => Some(self.stability_threshold_2),
82 Depeg => Some(UFix64::one()),
83 }
84 }
85
86 #[must_use]
90 pub fn next_stability_threshold(
91 &self,
92 mode: StabilityMode,
93 ) -> Option<UFix64<N2>> {
94 match mode {
95 Normal => Some(self.stability_threshold_1),
96 Mode1 => Some(self.stability_threshold_2),
97 Mode2 => Some(UFix64::one()),
98 Depeg => None,
99 }
100 }
101
102 #[must_use]
104 pub fn min_stability_threshold(&self) -> UFix64<N2> {
105 self.stability_threshold_2
106 }
107
108 pub fn validate(&self) -> Result<()> {
113 let t1 = self.stability_threshold_1;
114 let t2 = self.stability_threshold_2;
115 let one = UFix64::one();
116 if t1 > t2 && t1 > one && t2 > one {
117 Ok(())
118 } else {
119 Err(StabilityValidation.into())
120 }
121 }
122}
123
124#[cfg(test)]
125mod tests {
126 #[test]
127 fn stability_mode_ord() {
128 use super::StabilityMode::*;
129 assert!(Normal < Mode1);
130 assert!(Mode1 < Mode2);
131 assert!(Mode2 < Depeg);
132 }
133}