1pub mod interest_rate_models;
2pub mod msg;
3
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6use thiserror::Error;
7
8use cosmwasm_std::{Addr, Uint128};
9
10use crate::asset::AssetType;
11use crate::error::MarsError;
12use crate::helpers::decimal_param_le_one;
13use crate::math::decimal::Decimal;
14
15use self::interest_rate_models::InterestRateModel;
16
17#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
19pub struct Config {
20 pub owner: Addr,
22 pub address_provider_address: Addr,
24 pub ma_token_code_id: u64,
26 pub close_factor: Decimal,
28}
29
30impl Config {
31 pub fn validate(&self) -> Result<(), MarsError> {
32 decimal_param_le_one(&self.close_factor, "close_factor")?;
33
34 Ok(())
35 }
36}
37
38#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
40pub struct GlobalState {
41 pub market_count: u32,
43}
44
45#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
47pub struct Market {
48 pub index: u32,
50 pub ma_token_address: Addr,
52 pub asset_type: AssetType,
54
55 pub max_loan_to_value: Decimal,
57 pub liquidation_threshold: Decimal,
59 pub liquidation_bonus: Decimal,
62 pub reserve_factor: Decimal,
64
65 pub interest_rate_model: InterestRateModel,
67
68 pub borrow_index: Decimal,
70 pub liquidity_index: Decimal,
72 pub borrow_rate: Decimal,
74 pub liquidity_rate: Decimal,
76 pub indexes_last_updated: u64,
78
79 pub debt_total_scaled: Uint128,
81
82 pub active: bool,
84 pub deposit_enabled: bool,
86 pub borrow_enabled: bool,
88}
89
90impl Market {
91 pub fn validate(&self) -> Result<(), MarketError> {
92 decimal_param_le_one(&self.max_loan_to_value, "max_loan_to_value")?;
93 decimal_param_le_one(&self.liquidation_threshold, "liquidation_threshold")?;
94 decimal_param_le_one(&self.liquidation_bonus, "liquidation_bonus")?;
95
96 if self.liquidation_threshold <= self.max_loan_to_value {
98 return Err(MarketError::InvalidLiquidationThreshold {
99 liquidation_threshold: self.liquidation_threshold,
100 max_loan_to_value: self.max_loan_to_value,
101 });
102 }
103
104 Ok(())
105 }
106}
107
108impl Default for Market {
109 fn default() -> Self {
110 let dynamic_ir_model = interest_rate_models::InterestRateModel::Dynamic {
111 params: interest_rate_models::DynamicInterestRateModelParams {
112 min_borrow_rate: Decimal::zero(),
113 max_borrow_rate: Decimal::one(),
114 kp_1: Default::default(),
115 optimal_utilization_rate: Default::default(),
116 kp_augmentation_threshold: Default::default(),
117 kp_2: Default::default(),
118
119 update_threshold_txs: 1,
120 update_threshold_seconds: 0,
121 },
122 state: interest_rate_models::DynamicInterestRateModelState {
123 txs_since_last_borrow_rate_update: 0,
124 borrow_rate_last_updated: 0,
125 },
126 };
127
128 Market {
129 index: 0,
130 ma_token_address: crate::helpers::zero_address(),
131 liquidity_index: Decimal::one(),
132 borrow_index: Decimal::one(),
133 borrow_rate: Default::default(),
134 liquidity_rate: Default::default(),
135 max_loan_to_value: Default::default(),
136 reserve_factor: Default::default(),
137 indexes_last_updated: 0,
138 debt_total_scaled: Default::default(),
139 asset_type: AssetType::Native,
140 liquidation_threshold: Decimal::one(),
141 liquidation_bonus: Decimal::zero(),
142 interest_rate_model: dynamic_ir_model,
143 active: true,
144 deposit_enabled: true,
145 borrow_enabled: true,
146 }
147 }
148}
149
150#[derive(Error, Debug, PartialEq)]
151pub enum MarketError {
152 #[error("{0}")]
153 Mars(#[from] MarsError),
154
155 #[error("liquidation_threshold should be greater than max_loan_to_value. liquidation_threshold: {liquidation_threshold:?}, max_loan_to_value: {max_loan_to_value:?}")]
156 InvalidLiquidationThreshold {
157 liquidation_threshold: Decimal,
158 max_loan_to_value: Decimal,
159 },
160}
161
162#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
164pub struct User {
165 pub borrowed_assets: Uint128,
168 pub collateral_assets: Uint128,
171}
172
173impl Default for User {
174 fn default() -> Self {
175 User {
176 borrowed_assets: Uint128::zero(),
177 collateral_assets: Uint128::zero(),
178 }
179 }
180}
181
182#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
184pub struct Debt {
185 pub amount_scaled: Uint128,
187
188 pub uncollateralized: bool,
190}
191
192#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
193#[serde(rename_all = "snake_case")]
194pub enum UserHealthStatus {
195 NotBorrowing,
196 Borrowing(Decimal),
197}
198#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
200pub struct ConfigResponse {
201 pub owner: Addr,
202 pub address_provider_address: Addr,
203 pub ma_token_code_id: u64,
204 pub market_count: u32,
205 pub close_factor: Decimal,
206}
207
208#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
209pub struct MarketsListResponse {
210 pub markets_list: Vec<MarketInfo>,
211}
212
213#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
214pub struct MarketInfo {
215 pub denom: String,
217 pub asset_label: String,
219 pub asset_reference: Vec<u8>,
221 pub asset_type: AssetType,
223 pub ma_token_address: Addr,
225}
226
227#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
228pub struct UserDebtResponse {
229 pub debts: Vec<UserAssetDebtResponse>,
230}
231
232#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
233pub struct UserAssetDebtResponse {
234 pub denom: String,
236 pub asset_label: String,
238 pub asset_reference: Vec<u8>,
240 pub asset_type: AssetType,
242 pub amount_scaled: Uint128,
244 pub amount: Uint128,
246}
247
248#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
249pub struct UserCollateralResponse {
250 pub collateral: Vec<UserAssetCollateralResponse>,
251}
252
253#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
254pub struct UserAssetCollateralResponse {
255 pub denom: String,
257 pub asset_label: String,
259 pub asset_reference: Vec<u8>,
261 pub asset_type: AssetType,
263 pub enabled: bool,
265}
266
267#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
268pub struct UserPositionResponse {
269 pub total_collateral_in_uusd: Uint128,
270 pub total_debt_in_uusd: Uint128,
271 pub total_collateralized_debt_in_uusd: Uint128,
273 pub max_debt_in_uusd: Uint128,
274 pub weighted_liquidation_threshold_in_uusd: Uint128,
275 pub health_status: UserHealthStatus,
276}