mars_core/
vesting.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4use cosmwasm_std::{Addr, Api, StdResult, Uint128};
5use cw20::Cw20ReceiveMsg;
6
7#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema, Copy)]
8pub struct Schedule {
9    /// Time when vesting/unlocking starts
10    pub start_time: u64,
11    /// Time before with no token is to be vested/unlocked
12    pub cliff: u64,
13    /// Duration of the vesting/unlocking process. At time `start_time + duration`, the tokens are
14    /// vested/unlocked in full
15    pub duration: u64,
16}
17
18#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
19pub struct Config<T> {
20    /// Address provider address
21    /// T is to be `String` for the unchecked type, or `cosmwasm_std::Addr` for the checked type
22    pub address_provider_address: T,
23    /// Schedule for token unlocking; this schedule is the same for all users
24    pub unlock_schedule: Schedule,
25}
26
27impl From<Config<Addr>> for Config<String> {
28    fn from(config: Config<Addr>) -> Self {
29        Config {
30            address_provider_address: config.address_provider_address.to_string(),
31            unlock_schedule: config.unlock_schedule,
32        }
33    }
34}
35
36impl Config<String> {
37    pub fn check(&self, api: &dyn Api) -> StdResult<Config<Addr>> {
38        Ok(Config {
39            address_provider_address: api.addr_validate(&self.address_provider_address)?,
40            unlock_schedule: self.unlock_schedule,
41        })
42    }
43}
44
45#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
46pub struct Allocation {
47    /// Total amount of MARS allocated
48    pub allocated_amount: Uint128,
49    /// Amount of MARS already withdrawn
50    pub withdrawn_amount: Uint128,
51    /// The user's vesting schedule
52    pub vest_schedule: Schedule,
53}
54
55pub mod msg {
56    use super::*;
57
58    pub type InstantiateMsg = Config<String>;
59
60    #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
61    #[serde(rename_all = "snake_case")]
62    pub enum ExecuteMsg {
63        /// Implementation of cw20 receive msg
64        Receive(Cw20ReceiveMsg),
65        /// Withdraw unlocked MARS token
66        Withdraw {},
67    }
68
69    #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
70    #[serde(rename_all = "snake_case")]
71    pub enum ReceiveMsg {
72        /// Create a new allocation for a recipeint
73        CreateAllocation {
74            user_address: String,
75            vest_schedule: Schedule,
76        },
77    }
78
79    #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
80    #[serde(rename_all = "snake_case")]
81    pub enum QueryMsg {
82        /// Config of this contract. Returns `Config<String>`
83        Config {},
84        /// Status of an allocation. Returns `Allocation`
85        Allocation { user_address: String },
86        /// A user's locked voting power at a certain height, which equals the user's total allocated
87        /// Mars token amount minus the amount they have already withdrawn up to that height.
88        /// Returns `Uint128`
89        VotingPowerAt { user_address: String, block: u64 },
90        /// Total locked voting power owned by the vesting contract at a certain height. Used by
91        /// Martian Council to calculate a governance proposal's quorum. Returns `Uint128`
92        TotalVotingPowerAt { block: u64 },
93    }
94}