use crate::{
adapters::{
asset_staking::AssetStaking, global_config_adapter::ConfigExt, voting_escrow::VotingEscrow,
},
constants::{at_asset_staking, AT_VOTING_ESCROW},
error::SharedError,
helpers::time::{Time, Times},
msgs_asset_staking::AssetDistribution,
msgs_voting_escrow::LockInfoResponse,
};
use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::{Addr, Decimal, DepsMut, Uint128};
use cw20::Cw20ReceiveMsg;
use cw_asset::{AssetInfo, AssetInfoUnchecked};
#[cw_serde]
pub struct InstantiateMsg {
pub global_config_addr: String,
pub gauges: Vec<GaugeConfig>,
pub rebase_asset: AssetInfoUnchecked,
}
#[cw_serde]
pub struct GaugeConfig {
pub name: String,
pub min_gauge_percentage: Decimal,
}
#[cw_serde]
pub enum ExecuteMsg {
Vote {
gauge: String,
votes: Vec<(String, u16)>,
},
UpdateVote {
token_id: String,
lock_info: LockInfoResponse,
},
ClaimRebase {
token_id: Option<String>,
},
AddRebase {},
Receive(Cw20ReceiveMsg),
SetDistribution {},
UpdateConfig {
update_gauge: Option<GaugeConfig>,
remove_gauge: Option<String>,
},
}
#[cw_serde]
pub enum ReceiveMsg {
AddRebase {},
}
#[cw_serde]
#[derive(QueryResponses)]
pub enum QueryMsg {
#[returns(UserInfoExtendedResponse)]
UserInfo {
user: String,
time: Option<Time>,
},
#[returns(UserInfosResponse)]
UserInfos {
start_after: Option<String>,
limit: Option<u32>,
time: Option<Time>,
},
#[returns(Config)]
Config {},
#[returns(UserSharesResponse)]
UserShares {
user: Addr,
times: Option<Times>,
},
#[returns(UserFirstParticipationResponse)]
UserFirstParticipation {
user: Addr,
},
#[returns(VotedInfoResponse)]
GaugeInfo {
gauge: String,
key: String,
time: Option<Time>,
},
#[returns(GaugeInfosResponse)]
GaugeInfos {
gauge: String,
keys: Option<Vec<String>>,
time: Option<Time>,
},
#[returns(GaugeDistributionResponse)]
Distribution {
gauge: String,
time: Option<Time>,
},
#[returns(Vec<GaugeDistributionResponse>)]
Distributions {
time: Option<Time>,
},
#[returns(UserPendingRebaseResponse)]
UserPendingRebase {
user: Addr,
},
}
#[cw_serde]
pub struct UserPendingRebaseResponse {
pub rebase: Uint128,
}
#[cw_serde]
pub struct UserFirstParticipationResponse {
pub period: Option<u64>,
}
#[cw_serde]
pub struct UserSharesResponse {
pub shares: Vec<UserShare>,
}
#[cw_serde]
pub struct UserShare {
pub gauge: String,
pub asset: AssetInfo,
pub period: u64,
pub user_vp: Uint128,
pub total_vp: Uint128,
}
#[cw_serde]
pub struct MigrateMsg {}
#[cw_serde]
pub struct Config {
pub global_config_addr: Addr,
pub gauges: Vec<GaugeConfig>,
pub rebase_asset: AssetInfo,
}
impl Config {
pub fn assert_gauge(&self, gauge: &str) -> Result<&GaugeConfig, SharedError> {
let gauge_config = self.gauges.iter().find(|a| a.name == gauge);
gauge_config.ok_or_else(|| SharedError::NotFound(format!("gauge not found: {0}", gauge)))
}
pub fn get_asset_staking(
&self,
deps: &DepsMut,
gauge: &str,
) -> Result<AssetStaking, SharedError> {
self.global_config().get_address(&deps.querier, &at_asset_staking(gauge)).map(AssetStaking)
}
pub fn get_voting_escrow(&self, deps: &DepsMut) -> Result<VotingEscrow, SharedError> {
self.global_config().get_address(&deps.querier, AT_VOTING_ESCROW).map(VotingEscrow)
}
}
#[cw_serde]
#[derive(Default)]
pub struct VotedInfoResponse {
pub voting_power: Uint128,
pub fixed_amount: Uint128,
pub slope: Uint128,
}
#[cw_serde]
#[derive(Default)]
pub struct UserInfoExtendedResponse {
pub voting_power: Uint128,
pub fixed_amount: Uint128,
pub slope: Uint128,
pub gauge_votes: Vec<GaugeVote>,
}
#[cw_serde]
#[derive(Default)]
pub struct GaugeVote {
pub period: u64,
pub votes: Vec<(String, u16)>,
}
#[cw_serde]
pub struct GaugeDistributionResponse {
pub gauge: String,
pub period: u64,
pub total_gauge_vp: Uint128,
pub assets: Vec<AssetDistribution>,
}
pub type UserInfosResponse = Vec<(Addr, VotedInfoResponse)>;
pub type GaugeInfosResponse = Vec<(String, VotedInfoResponse)>;