mars_params/
execute.rs

1use cosmwasm_std::{Decimal, DepsMut, MessageInfo, Response};
2use mars_utils::error::ValidationError;
3
4use crate::{
5    error::{ContractError, ContractResult},
6    msg::{AssetParamsUpdate, VaultConfigUpdate},
7    state::{ASSET_PARAMS, OWNER, TARGET_HEALTH_FACTOR, VAULT_CONFIGS},
8};
9
10pub const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME");
11pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
12
13pub fn update_target_health_factor(
14    deps: DepsMut,
15    info: MessageInfo,
16    target_health_factor: Decimal,
17) -> ContractResult<Response> {
18    OWNER.assert_owner(deps.storage, &info.sender)?;
19
20    assert_thf(target_health_factor)?;
21    TARGET_HEALTH_FACTOR.save(deps.storage, &target_health_factor)?;
22
23    let response = Response::new()
24        .add_attribute("action", "update_target_health_factor")
25        .add_attribute("value", target_health_factor.to_string());
26
27    Ok(response)
28}
29
30pub fn update_asset_params(
31    deps: DepsMut,
32    info: MessageInfo,
33    update: AssetParamsUpdate,
34) -> ContractResult<Response> {
35    OWNER.assert_owner(deps.storage, &info.sender)?;
36
37    let mut response = Response::new().add_attribute("action", "update_asset_param");
38
39    match update {
40        AssetParamsUpdate::AddOrUpdate {
41            params: unchecked,
42        } => {
43            let params = unchecked.check(deps.api)?;
44
45            ASSET_PARAMS.save(deps.storage, &params.denom, &params)?;
46            response = response
47                .add_attribute("action_type", "add_or_update")
48                .add_attribute("denom", params.denom);
49        }
50    }
51
52    Ok(response)
53}
54
55pub fn update_vault_config(
56    deps: DepsMut,
57    info: MessageInfo,
58    update: VaultConfigUpdate,
59) -> ContractResult<Response> {
60    OWNER.assert_owner(deps.storage, &info.sender)?;
61
62    let mut response = Response::new().add_attribute("action", "update_vault_config");
63
64    match update {
65        VaultConfigUpdate::AddOrUpdate {
66            config,
67        } => {
68            let checked = config.check(deps.api)?;
69            VAULT_CONFIGS.save(deps.storage, &checked.addr, &checked)?;
70            response = response
71                .add_attribute("action_type", "add_or_update")
72                .add_attribute("addr", checked.addr);
73        }
74    }
75
76    Ok(response)
77}
78
79pub fn assert_thf(thf: Decimal) -> Result<(), ContractError> {
80    if thf < Decimal::one() || thf > Decimal::from_atomics(2u128, 0u32)? {
81        return Err(ValidationError::InvalidParam {
82            param_name: "target_health_factor".to_string(),
83            invalid_value: thf.to_string(),
84            predicate: "[1, 2]".to_string(),
85        }
86        .into());
87    }
88    Ok(())
89}
90
91/// liquidation_threshold should be greater than or equal to max_loan_to_value
92pub fn assert_lqt_gt_max_ltv(
93    max_ltv: Decimal,
94    liq_threshold: Decimal,
95) -> Result<(), ValidationError> {
96    if liq_threshold <= max_ltv {
97        return Err(ValidationError::InvalidParam {
98            param_name: "liquidation_threshold".to_string(),
99            invalid_value: liq_threshold.to_string(),
100            predicate: format!("> {} (max LTV)", max_ltv),
101        });
102    }
103    Ok(())
104}
105
106pub fn assert_hls_lqt_gt_max_ltv(
107    max_ltv: Decimal,
108    liq_threshold: Decimal,
109) -> Result<(), ValidationError> {
110    if liq_threshold <= max_ltv {
111        return Err(ValidationError::InvalidParam {
112            param_name: "hls_liquidation_threshold".to_string(),
113            invalid_value: liq_threshold.to_string(),
114            predicate: format!("> {} (hls max LTV)", max_ltv),
115        });
116    }
117    Ok(())
118}