1use crate::{
2 adapters::{bribe_manager::BribeManager, connector::Connector, global_config_adapter::ConfigExt},
3 constants::{at_connector, AT_BRIBE_MANAGER},
4 error::SharedError,
5 stake_config::StakeConfig,
6};
7use cosmwasm_schema::{cw_serde, QueryResponses};
8use cosmwasm_std::{Addr, Api, Decimal, DepsMut, Uint128};
9use cw20::Cw20ReceiveMsg;
10use cw_address_like::AddressLike;
11use cw_asset::{Asset, AssetError, AssetInfo, AssetInfoBase, AssetInfoUnchecked};
12
13#[cw_serde]
14pub struct Config {
15 pub reward_info: AssetInfo,
16 pub global_config_addr: Addr,
17 pub default_yearly_take_rate: Decimal,
18 pub gauge: String,
19}
20
21impl Config {
22 pub fn get_connector(&self, deps: &DepsMut, gauge: &str) -> Result<Connector, SharedError> {
23 Ok(Connector(self.get_address(&deps.querier, &at_connector(gauge))?))
24 }
25 pub fn get_bribe_manager(&self, deps: &DepsMut) -> Result<BribeManager, SharedError> {
26 Ok(BribeManager(self.get_address(&deps.querier, AT_BRIBE_MANAGER)?))
27 }
28}
29
30#[cw_serde]
31pub struct AssetDistribution {
32 pub asset: AssetInfo,
33 pub distribution: Decimal,
34 pub total_vp: Uint128,
35}
36
37#[cw_serde]
38#[derive(Default)]
39pub struct AssetConfigRuntime {
40 pub last_taken_s: u64,
41 pub taken: Uint128,
42 pub harvested: Uint128,
43
44 pub yearly_take_rate: Decimal,
45 pub stake_config: StakeConfig<Addr>,
46}
47
48#[cw_serde]
49pub struct AssetConfig<T: AddressLike> {
50 pub yearly_take_rate: Decimal,
51 pub stake_config: StakeConfig<T>,
52}
53
54#[cw_serde]
55pub struct InstantiateMsg {
56 pub global_config_addr: String,
57 pub reward_info: AssetInfoUnchecked,
58 pub default_yearly_take_rate: Decimal,
59 pub gauge: String,
60}
61
62#[cw_serde]
63pub struct AssetInfoWithConfig<T: AddressLike> {
64 pub info: AssetInfoBase<T>,
65 pub config: Option<AssetConfig<T>>,
66}
67
68#[cw_serde]
69pub struct AssetInfoWithRuntime {
70 pub info: AssetInfo,
71 pub config: AssetConfigRuntime,
72 pub whitelisted: bool,
73}
74
75impl From<AssetInfoUnchecked> for AssetInfoWithConfig<String> {
76 fn from(val: AssetInfoUnchecked) -> Self {
77 AssetInfoWithConfig::new(val, None)
78 }
79}
80
81impl From<AssetInfo> for AssetInfoWithConfig<String> {
82 fn from(val: AssetInfo) -> Self {
83 AssetInfoWithConfig::new(val.into(), None)
84 }
85}
86
87impl AssetInfoWithConfig<String> {
88 pub fn new(info: AssetInfoUnchecked, config: Option<AssetConfig<String>>) -> Self {
89 Self {
90 info,
91 config,
92 }
93 }
94}
95
96impl AssetInfoWithConfig<String> {
97 pub fn check(self, api: &dyn Api) -> Result<AssetInfoWithConfig<Addr>, AssetError> {
98 Ok(AssetInfoWithConfig {
99 info: self.info.check(api, None)?,
100 config: self
101 .config
102 .map(|a| -> Result<AssetConfig<Addr>, AssetError> {
103 Ok(AssetConfig {
104 yearly_take_rate: a.yearly_take_rate,
105 stake_config: a.stake_config.check(api)?,
106 })
107 })
108 .transpose()?,
109 })
110 }
111}
112
113#[cw_serde]
114pub enum CallbackMsg {
115 UpdateRewards {
116 initial_balance: Asset,
117 },
118 TrackBribes {
119 for_asset: AssetInfo,
120 initial_balances: Vec<Asset>,
121 },
122 DistributeBribes {
123 assets: Option<Vec<AssetInfo>>,
124 },
125}
126
127impl From<CallbackMsg> for ExecuteMsg {
128 fn from(val: CallbackMsg) -> Self {
129 ExecuteMsg::Callback(val)
130 }
131}
132
133#[cw_serde]
134pub enum Cw20HookMsg {
135 Stake {
136 recipient: Option<String>,
137 },
138}
139
140#[cw_serde]
141pub enum ExecuteMsg {
142 Receive(Cw20ReceiveMsg),
143
144 Stake {
146 recipient: Option<String>,
147 },
148 Unstake(Asset),
149 ClaimReward(AssetInfo),
150 ClaimRewards {
151 assets: Option<Vec<AssetInfo>>,
152 },
153
154 WhitelistAssets(Vec<AssetInfoWithConfig<String>>),
156 RemoveAssets(Vec<AssetInfo>),
157 UpdateAssetConfig(AssetInfoWithConfig<String>),
159 SetAssetRewardDistribution(Vec<AssetDistribution>),
160
161 UpdateRewards {},
163 DistributeTakeRate {
164 update: Option<bool>,
165 assets: Option<Vec<AssetInfo>>,
166 },
167 DistributeBribes {
168 update: Option<bool>,
169 assets: Option<Vec<AssetInfo>>,
170 },
171 Callback(CallbackMsg),
172}
173
174#[cw_serde]
175#[derive(QueryResponses)]
176pub enum QueryMsg {
177 #[returns(Config)]
178 Config {},
179
180 #[returns(WhitelistedAssetsResponse)]
181 WhitelistedAssets {},
182
183 #[returns(WhitelistedAssetsDetailsResponse)]
184 WhitelistedAssetDetails {},
185
186 #[returns(Vec<AssetDistribution>)]
187 RewardDistribution {},
188
189 #[returns(StakedBalanceRes)]
190 StakedBalance(AssetQuery),
191
192 #[returns(PendingRewardsRes)]
193 PendingRewards(AssetQuery),
194
195 #[returns(Vec<StakedBalanceRes>)]
196 AllStakedBalances(AllStakedBalancesQuery),
197
198 #[returns(Vec<PendingRewardsRes>)]
199 AllPendingRewards(AllPendingRewardsQuery),
200
201 #[returns(Vec<PendingRewardsDetailRes>)]
202 AllPendingRewardsDetail(AllPendingRewardsQuery),
203
204 #[returns(Vec<StakedBalanceRes>)]
205 TotalStakedBalances {},
206}
207
208pub type WhitelistedAssetsResponse = Vec<AssetInfo>;
209pub type WhitelistedAssetsDetailsResponse = Vec<AssetInfoWithRuntime>;
210
211#[cw_serde]
212pub struct AssetQuery {
213 pub address: String,
214 pub asset: AssetInfo,
215}
216
217#[cw_serde]
218pub struct AllStakedBalancesQuery {
219 pub address: String,
220}
221
222#[cw_serde]
223pub struct AllPendingRewardsQuery {
224 pub address: String,
225}
226
227#[cw_serde]
228pub struct MigrateMsg {}
229
230#[cw_serde]
231pub struct StakedBalanceRes {
232 pub asset: Asset,
233 pub shares: Uint128,
234 pub config: AssetConfigRuntime,
235}
236
237#[cw_serde]
238pub struct PendingRewardsRes {
239 pub staked_asset_share: Asset,
240 pub reward_asset: Asset,
241}
242
243#[cw_serde]
244pub struct PendingRewardsDetailRes {
245 pub share: Uint128,
246 pub staked_asset: Asset,
247 pub reward_asset: Asset,
248}