pub mod state {
use std::ops::Sub;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::objects::time_weighted_average::TimeWeightedAverage;
use cosmwasm_std::{Addr, Api, Decimal, StdError, StdResult, Uint128, Uint64};
use cw_asset::{AssetInfo, AssetInfoUnchecked};
use cw_storage_plus::{Item, Map};
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub enum UncheckedEmissionType {
None,
BlockShared(Decimal, AssetInfoUnchecked),
BlockPerUser(Decimal, AssetInfoUnchecked),
IncomeBased(AssetInfoUnchecked),
}
impl UncheckedEmissionType {
pub fn check(self, api: &dyn Api) -> StdResult<EmissionType> {
match self {
UncheckedEmissionType::None => Ok(EmissionType::None),
UncheckedEmissionType::BlockShared(d, a) => {
Ok(EmissionType::BlockShared(d, a.check(api, None)?))
}
UncheckedEmissionType::BlockPerUser(d, a) => {
Ok(EmissionType::BlockPerUser(d, a.check(api, None)?))
}
UncheckedEmissionType::IncomeBased(a) => {
Ok(EmissionType::IncomeBased(a.check(api, None)?))
}
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub enum EmissionType {
None,
BlockShared(Decimal, AssetInfo),
BlockPerUser(Decimal, AssetInfo),
IncomeBased(AssetInfo),
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct SubscriptionConfig {
pub version_control_address: Addr,
pub factory_address: Addr,
pub payment_asset: AssetInfo,
pub subscription_cost_per_block: Decimal,
pub subscription_per_block_emissions: EmissionType,
}
#[cosmwasm_schema::cw_serde]
pub struct SubscriptionState {
pub active_subs: u32,
}
#[cosmwasm_schema::cw_serde]
pub struct Subscriber {
pub expiration_block: u64,
pub last_emission_claim_block: u64,
pub manager_addr: Addr,
}
pub const INCOME_TWA: TimeWeightedAverage = TimeWeightedAverage::new("\u{0}{7}sub_twa");
pub const SUBSCRIPTION_CONFIG: Item<SubscriptionConfig> = Item::new("\u{0}{10}sub_config");
pub const SUBSCRIPTION_STATE: Item<SubscriptionState> = Item::new("\u{0}{9}sub_state");
pub const SUBSCRIBERS: Map<u32, Subscriber> = Map::new("subscribed");
pub const DORMANT_SUBSCRIBERS: Map<u32, Subscriber> = Map::new("un-subscribed");
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct ContributionConfig {
pub protocol_income_share: Decimal,
pub emission_user_share: Decimal,
pub max_emissions_multiple: Decimal,
pub emissions_amp_factor: Uint128,
pub emissions_offset: Uint128,
pub token_info: AssetInfo,
}
impl ContributionConfig {
pub fn verify(self) -> StdResult<Self> {
if !(decimal_is_percentage(&self.protocol_income_share)
|| decimal_is_percentage(&self.emission_user_share))
{
Err(StdError::generic_err(
"Some config fields should not be >1.",
))
} else {
Ok(self)
}
}
}
fn decimal_is_percentage(decimal: &Decimal) -> bool {
decimal <= &Decimal::one()
}
#[cosmwasm_schema::cw_serde]
pub struct ContributionState {
pub income_target: Decimal,
pub expense: Decimal,
pub total_weight: Uint128,
pub emissions: Decimal,
}
pub const CONTRIBUTORS: Map<&Addr, Compensation> = Map::new("contributors");
pub const CONTRIBUTION_CONFIG: Item<ContributionConfig> = Item::new("\u{0}{10}con_config");
pub const CACHED_CONTRIBUTION_STATE: Item<ContributionState> =
Item::new("\u{0}{15}cache_con_state");
pub const CONTRIBUTION_STATE: Item<ContributionState> = Item::new("\u{0}{9}con_state");
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, Default)]
pub struct Compensation {
pub base_per_block: Decimal,
pub weight: u32,
pub last_claim_block: Uint64,
pub expiration_block: Uint64,
}
impl Compensation {
pub fn overwrite(
mut self,
base_per_block: Option<Decimal>,
weight: Option<u32>,
expiration_block: Option<u64>,
) -> Self {
if let Some(base_per_block) = base_per_block {
self.base_per_block = base_per_block;
}
if let Some(weight) = weight {
self.weight = weight;
}
if let Some(expiration_block) = expiration_block {
self.expiration_block = expiration_block.into();
}
self
}
}
impl Sub for Compensation {
type Output = (Decimal, i32);
fn sub(self, other: Self) -> (Decimal, i32) {
(
self.base_per_block - other.base_per_block,
self.weight as i32 - other.weight as i32,
)
}
}
}
use cosmwasm_std::{Decimal, Uint128, Uint64};
use cw_asset::{Asset, AssetInfoUnchecked};
use state::{
Compensation, ContributionConfig, ContributionState, Subscriber, SubscriptionConfig,
SubscriptionState,
};
use self::state::UncheckedEmissionType;
#[cosmwasm_schema::cw_serde]
pub struct MigrateMsg {}
#[cosmwasm_schema::cw_serde]
pub struct InstantiateMsg {
pub subscription: SubscriptionInstantiateMsg,
pub contribution: Option<ContributionInstantiateMsg>,
}
#[cosmwasm_schema::cw_serde]
pub struct SubscriptionInstantiateMsg {
pub payment_asset: AssetInfoUnchecked,
pub subscription_cost_per_block: Decimal,
pub version_control_addr: String,
pub factory_addr: String,
pub subscription_per_block_emissions: UncheckedEmissionType,
}
#[cosmwasm_schema::cw_serde]
pub struct ContributionInstantiateMsg {
pub protocol_income_share: Decimal,
pub emission_user_share: Decimal,
pub max_emissions_multiple: Decimal,
pub token_info: AssetInfoUnchecked,
pub emissions_amp_factor: Uint128,
pub emissions_offset: Uint128,
pub income_averaging_period: Uint64,
}
#[cosmwasm_schema::cw_serde]
pub enum ExecuteMsg {
Pay {
os_id: u32,
},
Unsubscribe {
os_ids: Vec<u32>,
},
ClaimCompensation {
os_id: u32,
},
ClaimEmissions {
os_id: u32,
},
UpdateContributor {
contributor_os_id: u32,
base_per_block: Option<Decimal>,
weight: Option<Uint64>,
expiration_block: Option<Uint64>,
},
RemoveContributor {
os_id: u32,
},
UpdateSubscriptionConfig {
payment_asset: Option<AssetInfoUnchecked>,
version_control_address: Option<String>,
factory_address: Option<String>,
subscription_cost: Option<Decimal>,
},
UpdateContributionConfig {
protocol_income_share: Option<Decimal>,
emission_user_share: Option<Decimal>,
max_emissions_multiple: Option<Decimal>,
project_token_info: Option<AssetInfoUnchecked>,
emissions_amp_factor: Option<Uint128>,
emissions_offset: Option<Uint128>,
},
}
#[cosmwasm_schema::cw_serde]
pub enum QueryMsg {
State {},
Config {},
Fee {},
SubscriberState { os_id: u32 },
ContributorState { os_id: u32 },
}
#[cosmwasm_schema::cw_serde]
pub enum DepositHookMsg {
Pay { os_id: u32 },
}
#[cosmwasm_schema::cw_serde]
pub struct ConfigResponse {
pub contribution: ContributionConfig,
pub subscription: SubscriptionConfig,
}
#[cosmwasm_schema::cw_serde]
pub struct StateResponse {
pub contribution: ContributionState,
pub subscription: SubscriptionState,
}
#[cosmwasm_schema::cw_serde]
pub struct SubscriptionFeeResponse {
pub fee: Asset,
}
#[cosmwasm_schema::cw_serde]
pub struct SubscriberStateResponse {
pub currently_subscribed: bool,
pub subscriber_details: Subscriber,
}
#[cosmwasm_schema::cw_serde]
pub struct ContributorStateResponse {
pub compensation: Compensation,
}