mars_core/
protocol_rewards_collector.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3use thiserror::Error;
4
5use cosmwasm_std::{Addr, Decimal as StdDecimal};
6
7use crate::error::MarsError;
8use crate::helpers::decimal_param_le_one;
9use crate::math::decimal::Decimal;
10
11/// Global configuration
12#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
13pub struct Config {
14    /// Contract owner
15    pub owner: Addr,
16    /// Address provider returns addresses for all protocol contracts
17    pub address_provider_address: Addr,
18    /// Percentage of fees that are sent to the safety fund
19    pub safety_fund_fee_share: Decimal,
20    /// Percentage of fees that are sent to the treasury
21    pub treasury_fee_share: Decimal,
22    /// Astroport factory contract address
23    pub astroport_factory_address: Addr,
24    /// Astroport max spread
25    pub astroport_max_spread: StdDecimal,
26}
27
28impl Config {
29    pub fn validate(&self) -> Result<(), ConfigError> {
30        decimal_param_le_one(&self.safety_fund_fee_share, "safety_fund_fee_share")?;
31        decimal_param_le_one(&self.treasury_fee_share, "treasury_fee_share")?;
32
33        let combined_fee_share = self.safety_fund_fee_share + self.treasury_fee_share;
34        // Combined fee shares cannot exceed one
35        if combined_fee_share > Decimal::one() {
36            return Err(ConfigError::InvalidFeeShareAmounts {});
37        }
38
39        Ok(())
40    }
41}
42
43#[derive(Error, Debug, PartialEq)]
44pub enum ConfigError {
45    #[error("{0}")]
46    Mars(#[from] MarsError),
47
48    #[error("Invalid fee share amounts. Sum of safety and treasury fee shares exceeds one")]
49    InvalidFeeShareAmounts {},
50}
51
52#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
53pub struct AssetConfig {
54    pub enabled_for_distribution: bool,
55}
56
57#[allow(clippy::derivable_impls)]
58impl Default for AssetConfig {
59    fn default() -> Self {
60        AssetConfig {
61            enabled_for_distribution: false,
62        }
63    }
64}
65
66pub mod msg {
67    use schemars::JsonSchema;
68    use serde::{Deserialize, Serialize};
69
70    use cosmwasm_std::{CosmosMsg, Decimal as StdDecimal, Uint128};
71
72    use astroport::asset::AssetInfo;
73
74    use crate::asset::Asset;
75    use crate::math::decimal::Decimal;
76
77    #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
78    pub struct InstantiateMsg {
79        pub config: CreateOrUpdateConfig,
80    }
81
82    #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
83    pub struct CreateOrUpdateConfig {
84        pub owner: Option<String>,
85        pub address_provider_address: Option<String>,
86        pub safety_fund_fee_share: Option<Decimal>,
87        pub treasury_fee_share: Option<Decimal>,
88        pub astroport_factory_address: Option<String>,
89        pub astroport_max_spread: Option<StdDecimal>,
90    }
91
92    #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
93    #[serde(rename_all = "snake_case")]
94    pub enum ExecuteMsg {
95        /// Update contract config
96        UpdateConfig { config: CreateOrUpdateConfig },
97
98        /// Update asset config
99        UpdateAssetConfig { asset: Asset, enabled: bool },
100
101        /// Withdraw maTokens from the red bank
102        WithdrawFromRedBank {
103            asset: Asset,
104            amount: Option<Uint128>,
105        },
106
107        /// Distribute the accrued protocol income to the safety fund, treasury and staking contracts,
108        /// according to the split set in config.
109        /// Callable by any address.
110        DistributeProtocolRewards {
111            /// Asset market fees to distribute
112            asset: Asset,
113            /// Amount to distribute to protocol contracts, defaults to contract balance if not specified
114            amount: Option<Uint128>,
115        },
116
117        /// Swap any asset on the contract to uusd
118        SwapAssetToUusd {
119            offer_asset_info: AssetInfo,
120            amount: Option<Uint128>,
121        },
122
123        /// Execute Cosmos msg (only callable by owner)
124        ExecuteCosmosMsg(CosmosMsg),
125    }
126
127    #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
128    #[serde(rename_all = "snake_case")]
129    pub enum QueryMsg {
130        /// Get config parameters
131        Config {},
132        /// Get asset config parameters
133        AssetConfig { asset: Asset },
134    }
135}