1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{Addr, Coin, Decimal, Uint128};
use mars_red_bank_types::red_bank::InterestRateModel;
use mars_utils::{
    error::ValidationError,
    helpers::{decimal_param_le_one, decimal_param_lt_one},
};

use crate::execute::assert_lqt_gte_max_ltv;

#[cw_serde]
pub struct RoverPermissions {
    pub whitelisted: bool,
}

#[cw_serde]
pub struct RedBankSettings {
    pub deposit_enabled: bool,
    pub borrow_enabled: bool,
    pub deposit_cap: Uint128,
}

#[cw_serde]
pub struct AssetPermissions {
    pub rover: RoverPermissions,
    pub red_bank: RedBankSettings,
}

#[cw_serde]
pub struct AssetParams {
    pub permissions: AssetPermissions,
    pub max_loan_to_value: Decimal,
    pub liquidation_threshold: Decimal,
    pub liquidation_bonus: Decimal,
    pub interest_rate_model: InterestRateModel,
    pub reserve_factor: Decimal,
}

impl AssetParams {
    pub fn validate(&self) -> Result<(), ValidationError> {
        decimal_param_lt_one(self.reserve_factor, "reserve_factor")?;
        decimal_param_le_one(self.max_loan_to_value, "max_loan_to_value")?;
        decimal_param_le_one(self.liquidation_threshold, "liquidation_threshold")?;
        decimal_param_le_one(self.liquidation_bonus, "liquidation_bonus")?;

        assert_lqt_gte_max_ltv(self.max_loan_to_value, self.liquidation_threshold)?;

        self.interest_rate_model.validate()?;

        Ok(())
    }
}

#[cw_serde]
pub struct AssetParamsResponse {
    pub denom: String,
    pub params: AssetParams,
}

#[cw_serde]
pub struct VaultConfigResponse {
    pub addr: Addr,
    pub config: VaultConfig,
}

#[cw_serde]
pub struct VaultConfig {
    pub deposit_cap: Coin,
    pub max_loan_to_value: Decimal,
    pub liquidation_threshold: Decimal,
    pub whitelisted: bool,
}

impl VaultConfig {
    pub fn validate(&self) -> Result<(), ValidationError> {
        decimal_param_le_one(self.max_loan_to_value, "max_loan_to_value")?;
        decimal_param_le_one(self.liquidation_threshold, "liquidation_threshold")?;
        assert_lqt_gte_max_ltv(self.max_loan_to_value, self.liquidation_threshold)?;
        Ok(())
    }
}

#[cw_serde]
pub enum AssetParamsUpdate {
    AddOrUpdate {
        denom: String,
        params: AssetParams,
    },
}

#[cw_serde]
pub enum VaultConfigUpdate {
    AddOrUpdate {
        addr: String,
        config: VaultConfig,
    },
    Remove {
        addr: String,
    },
}

#[cw_serde]
pub enum RoverEmergencyUpdate {
    SetZeroMaxLtvOnVault(String),
    SetZeroDepositCapOnVault(String),
    DisallowCoin(String),
}

#[cw_serde]
pub enum RedBankEmergencyUpdate {
    DisableBorrowing(String),
}

#[cw_serde]
pub enum EmergencyUpdate {
    Rover(RoverEmergencyUpdate),
    RedBank(RedBankEmergencyUpdate),
}