mars_core/
staking.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4use crate::math::decimal::Decimal;
5use cosmwasm_std::{Addr, Decimal as StdDecimal, Uint128};
6
7/// Protocol configuration
8#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
9pub struct Config {
10    /// Contract owner
11    pub owner: Addr,
12
13    /// Address provider address
14    pub address_provider_address: Addr,
15
16    /// Astroport factory contract address
17    pub astroport_factory_address: Addr,
18    /// Astroport max spread
19    pub astroport_max_spread: StdDecimal,
20
21    /// Cooldown duration in seconds
22    pub cooldown_duration: u64,
23}
24
25/// Global State
26#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
27pub struct GlobalState {
28    /// Total amount of Mars belonging to open claims
29    pub total_mars_for_claimers: Uint128,
30}
31
32/// Unstaking cooldown data
33#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
34pub struct Claim {
35    /// Block when the claim was created (Used to apply slash events when claiming)
36    pub created_at_block: u64,
37    /// Timestamp (in seconds) after which the claim is unlocked
38    pub cooldown_end_timestamp: u64,
39    /// Amount of Mars that the user is allowed to claim
40    pub amount: Uint128,
41}
42
43/// Event where funds are taken from the Mars pool to cover a shortfall. The loss is covered
44/// proportionally by all owners of the Mars pool (xMars holders and users with an open claim)
45#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
46pub struct SlashEvent {
47    /// Percentage of total Mars slashed
48    pub slash_percentage: Decimal,
49}
50
51/// Response to Claim query
52#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
53pub struct ClaimResponse {
54    /// Existing claim for a given address. Will return None if it doesn't exist
55    pub claim: Option<Claim>,
56}
57
58pub mod msg {
59    use cosmwasm_std::{Decimal as StdDecimal, Uint128};
60
61    use cw20::Cw20ReceiveMsg;
62    use schemars::JsonSchema;
63    use serde::{Deserialize, Serialize};
64
65    #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
66    pub struct InstantiateMsg {
67        pub config: CreateOrUpdateConfig,
68    }
69
70    #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
71    pub struct CreateOrUpdateConfig {
72        pub owner: Option<String>,
73        pub address_provider_address: Option<String>,
74        pub astroport_factory_address: Option<String>,
75        pub astroport_max_spread: Option<StdDecimal>,
76        pub cooldown_duration: Option<u64>,
77    }
78
79    #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
80    #[serde(rename_all = "snake_case")]
81    pub enum ExecuteMsg {
82        /// Update staking config
83        UpdateConfig { config: CreateOrUpdateConfig },
84
85        /// Implementation for cw20 receive msg
86        Receive(Cw20ReceiveMsg),
87
88        /// Close claim sending the claimable Mars to the specified address (sender is the default)
89        Claim { recipient: Option<String> },
90
91        /// Transfer Mars, deducting it proportionally from both xMars holders and addresses
92        /// with an open claim
93        TransferMars { amount: Uint128, recipient: String },
94
95        /// Swap uusd on the contract to Mars. Meant for received protocol rewards in order
96        /// for them to belong to xMars holders as underlying Mars.
97        SwapUusdToMars { amount: Option<Uint128> },
98    }
99
100    #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
101    #[serde(rename_all = "snake_case")]
102    pub enum ReceiveMsg {
103        /// Stake Mars and mint xMars in return
104        Stake {
105            /// Address to receive the xMars tokens. Set to sender if not specified
106            recipient: Option<String>,
107        },
108
109        /// Burn xMars and initiate a cooldown period on which the underlying Mars
110        /// will be claimable. Only one open claim per address is allowed.
111        Unstake {
112            /// Address to claim the Mars tokens after cooldown. Set to sender is not specified
113            recipient: Option<String>,
114        },
115    }
116
117    #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
118    #[serde(rename_all = "snake_case")]
119    pub enum QueryMsg {
120        /// Get contract config
121        Config {},
122        /// Get contract global state
123        GlobalState {},
124        /// Compute the amount of xMars token to be minted by staking 1 unit of Mars token.
125        /// The ratio may be undefined, in which case we return `Ok(None)`
126        XMarsPerMars {},
127        /// Compute the amount of Mars token to be claimed by burning 1 unit of xMars token.
128        /// The ratio may be undefined, in which case we return `Ok(None)`
129        MarsPerXMars {},
130        /// Get open claim for given user. If claim exists, slash events are applied to the amount
131        /// so actual amount of Mars received is given.
132        Claim { user_address: String },
133    }
134}