use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::{Addr, Decimal, Uint128};
use cw20::Cw20ReceiveMsg;
use thiserror::Error;
use crate::asset::AssetInfo;
pub const MAX_ALLOWED_LP_TOKENS: usize = 100_000;
pub const MAX_USER_LP_TOKEN_LOCKS: usize = 100_000;
pub const MAX_INSTANT_UNBOND_FEE_BP: u64 = 1000;
#[cw_serde]
pub struct InstantiateMsg {
pub owner: Addr,
pub keeper_addr: Addr,
pub unbond_config: UnbondConfig,
}
#[cw_serde]
pub enum MigrateMsg {
V3_1FromV1 {
keeper_addr: Addr,
instant_unbond_fee_bp: u64,
instant_unbond_min_fee_bp: u64,
fee_tier_interval: u64
},
V3_1FromV2 {
keeper_addr: Addr
},
V3_1FromV2_2 {},
V3_1FromV3 {},
}
#[cw_serde]
pub struct AssetRewardState {
pub reward_index: Decimal,
pub last_distributed: u64,
}
#[cw_serde]
pub struct State {
pub next_factory_id: u64,
}
#[cw_serde]
pub struct UnclaimedReward {
pub asset: AssetInfo,
pub amount: Uint128,
}
#[cw_serde]
pub struct RewardSchedule {
pub title: String,
pub creator: Addr,
pub asset: AssetInfo,
pub amount: Uint128,
pub staking_lp_token: Addr,
pub start_block_time: u64,
pub end_block_time: u64,
}
#[cw_serde]
pub struct CreatorClaimableRewardState {
pub claimed: bool,
pub amount: Uint128,
pub last_update: u64,
}
impl Default for CreatorClaimableRewardState {
fn default() -> Self {
CreatorClaimableRewardState {
claimed: false,
amount: Uint128::zero(),
last_update: 0,
}
}
}
#[cw_serde]
pub struct UnlockFeeTier {
pub seconds_till_unlock_start: u64,
pub seconds_till_unlock_end: u64,
pub unlock_fee_bp: u64
}
#[cw_serde]
pub struct Config {
pub owner: Addr,
pub keeper: Addr,
pub allowed_lp_tokens: Vec<Addr>,
pub allowed_reward_cw20_tokens: Vec<Addr>,
pub unbond_config: UnbondConfig
}
#[cw_serde]
pub enum InstantUnbondConfig {
Disabled,
Enabled {
min_fee: u64,
max_fee: u64,
fee_tier_interval: u64,
}
}
#[cw_serde]
pub struct UnbondConfig {
pub unlock_period: u64,
pub instant_unbond_config: InstantUnbondConfig
}
#[derive(Error, Debug, PartialEq)]
pub enum UnbondConfigValidationError {
#[error("Min fee smaller than max fee is not allowed")]
InvalidMinFee { min_fee: u64, max_fee: u64 },
#[error("Max fee bigger than {MAX_INSTANT_UNBOND_FEE_BP} is not allowed")]
InvalidMaxFee { max_fee: u64 },
#[error("Invalid fee tier interval. Fee tier interval must be a non-zero value lesser than the unlock period")]
InvalidFeeTierInterval { fee_tier_interval: u64 },
}
impl UnbondConfig {
pub fn validate(&self) -> Result<(), UnbondConfigValidationError> {
match self.instant_unbond_config {
InstantUnbondConfig::Disabled => Ok(()),
InstantUnbondConfig::Enabled { min_fee, max_fee, fee_tier_interval } => {
if min_fee > max_fee {
Err(UnbondConfigValidationError::InvalidMinFee {
min_fee,
max_fee,
})
} else if max_fee > MAX_INSTANT_UNBOND_FEE_BP {
Err(UnbondConfigValidationError::InvalidMaxFee {
max_fee
})
} else if fee_tier_interval == 0 || fee_tier_interval > self.unlock_period {
Err(UnbondConfigValidationError::InvalidFeeTierInterval {
fee_tier_interval,
})
} else {
Ok(())
}
}
}
}
}
#[cw_serde]
pub struct ConfigV2_1 {
pub owner: Addr,
pub keeper: Option<Addr>,
pub allowed_lp_tokens: Vec<Addr>,
pub unlock_period: u64,
pub minimum_reward_schedule_proposal_start_delay: u64,
pub instant_unbond_fee_bp: u64,
pub fee_tier_interval: u64,
pub instant_unbond_min_fee_bp: u64,
}
#[cw_serde]
pub struct ConfigV2_2 {
pub owner: Addr,
pub keeper: Addr,
pub allowed_lp_tokens: Vec<Addr>,
pub unlock_period: u64,
pub minimum_reward_schedule_proposal_start_delay: u64,
pub instant_unbond_fee_bp: u64,
pub fee_tier_interval: u64,
pub instant_unbond_min_fee_bp: u64,
}
#[cw_serde]
pub struct ConfigV3 {
pub owner: Addr,
pub keeper: Addr,
pub allowed_lp_tokens: Vec<Addr>,
pub unlock_period: u64,
pub instant_unbond_fee_bp: u64,
pub fee_tier_interval: u64,
pub instant_unbond_min_fee_bp: u64,
}
#[cw_serde]
pub struct ConfigV1 {
pub owner: Addr,
pub allowed_lp_tokens: Vec<Addr>,
pub unlock_period: u64,
pub minimum_reward_schedule_proposal_start_delay: u64,
}
#[derive(Eq)]
#[cw_serde]
pub struct TokenLock {
pub unlock_time: u64,
pub amount: Uint128,
}
#[cw_serde]
pub struct TokenLockInfo {
pub locks: Vec<TokenLock>,
pub unlocked_amount: Uint128
}
#[cw_serde]
pub struct AssetStakerInfo {
pub asset: AssetInfo,
pub reward_index: Decimal,
pub pending_reward: Uint128,
}
#[cw_serde]
#[derive(Default)]
pub struct LpGlobalState {
pub total_bond_amount: Uint128,
pub active_reward_assets: Vec<AssetInfo>
}
#[cw_serde]
pub struct RewardScheduleResponse {
pub id: u64,
pub reward_schedule: RewardSchedule,
}
#[cw_serde]
pub struct InstantLpUnlockFee {
pub time_until_lock_expiry: u64,
pub unlock_fee_bp: u64,
pub unlock_fee: Uint128,
pub unlock_amount: Uint128,
}
#[cw_serde]
#[derive(QueryResponses)]
pub enum QueryMsg {
#[returns(Config)]
Config {},
#[returns(UnbondConfig)]
UnbondConfig {
lp_token: Option<Addr>
},
#[returns(Vec<UnclaimedReward>)]
UnclaimedRewards {
lp_token: Addr,
user: Addr,
block_time: Option<u64>,
},
#[returns(TokenLockInfo)]
TokenLocks {
lp_token: Addr,
user: Addr,
block_time: Option<u64>
},
#[returns(Vec<TokenLock>)]
RawTokenLocks {
lp_token: Addr,
user: Addr,
},
#[returns(Uint128)]
BondedLpTokens {
lp_token: Addr,
user: Addr,
},
#[returns(InstantLpUnlockFee)]
InstantUnlockFee {
user: Addr,
lp_token: Addr,
token_lock: TokenLock
},
#[returns(Vec<UnlockFeeTier>)]
InstantUnlockFeeTiers {
lp_token: Addr
},
#[returns(Vec<UnlockFeeTier>)]
DefaultInstantUnlockFeeTiers {},
#[returns(Vec<Addr>)]
AllowedLPTokensForReward {},
#[returns(Addr)]
Owner {},
#[returns(Vec<RewardScheduleResponse>)]
RewardSchedules { lp_token: Addr, asset: AssetInfo },
#[returns(AssetRewardState)]
RewardState { lp_token: Addr, asset: AssetInfo },
#[returns(AssetStakerInfo)]
StakerInfo { lp_token: Addr, asset: AssetInfo, user: Addr },
#[returns(CreatorClaimableRewardState)]
CreatorClaimableReward { reward_schedule_id: u64 }
}
#[cw_serde]
pub enum Cw20HookMsg {
Bond {
beneficiary_user: Option<Addr>
},
CreateRewardSchedule {
lp_token: Addr,
actual_creator: Option<Addr>,
title: String,
start_block_time: u64,
end_block_time: u64,
},
}
#[cw_serde]
pub enum ExecuteMsg {
UpdateConfig {
keeper_addr: Option<Addr>,
unbond_config: Option<UnbondConfig>,
},
SetCustomUnbondConfig {
lp_token: Addr,
unbond_config: UnbondConfig,
},
UnsetCustomUnbondConfig {
lp_token: Addr,
},
CreateRewardSchedule {
lp_token: Addr,
title: String,
actual_creator: Option<Addr>,
start_block_time: u64,
end_block_time: u64,
},
AllowLpToken {
lp_token: Addr,
},
RemoveLpToken {
lp_token: Addr,
},
AllowRewardCw20Token {
addr: Addr
},
RemoveRewardCw20Token {
addr: Addr,
},
Receive(Cw20ReceiveMsg),
Bond {
lp_token: Addr,
amount: Uint128,
},
Unbond {
lp_token: Addr,
amount: Option<Uint128>,
},
InstantUnbond {
lp_token: Addr,
amount: Uint128,
},
Unlock {
lp_token: Addr,
},
InstantUnlock {
lp_token: Addr,
token_locks: Vec<TokenLock>,
},
Withdraw {
lp_token: Addr,
},
ClaimUnallocatedReward {
reward_schedule_id: u64,
},
ProposeNewOwner {
owner: Addr,
expires_in: u64,
},
ClaimOwnership {},
DropOwnershipProposal {}
}