1use crate::adapters::asset_staking::AssetStaking;
2use crate::adapters::astroport::AstroportIncentives;
3use crate::error::SharedError;
4use crate::extensions::asset_infos_ext::AssetInfosEx;
5use crate::extensions::env_ext::EnvExt;
6use crate::msgs_asset_staking::CallbackMsg;
7use crate::msgs_asset_staking::ExecuteMsg;
8use cosmwasm_schema::cw_serde;
9use cosmwasm_std::Addr;
10use cosmwasm_std::Api;
11use cosmwasm_std::CosmosMsg;
12use cosmwasm_std::DepsMut;
13use cosmwasm_std::Env;
14use cw_address_like::AddressLike;
15use cw_asset::Asset;
16use cw_asset::AssetError;
17use cw_asset::AssetInfo;
18use cw_asset::AssetInfoBase;
19
20#[cw_serde]
21#[derive(Default)]
22pub enum StakeConfig<T: AddressLike> {
23 #[default]
24 Default,
25 Astroport {
26 contract: T,
27 reward_infos: Vec<AssetInfoBase<T>>,
28 },
29 Ve3 {
30 contract: T,
31 reward_infos: Vec<AssetInfoBase<T>>,
32 },
33}
34
35fn track_bribes_callback_msg(
36 deps: &DepsMut,
37 env: &Env,
38 asset: AssetInfo,
39 asset_infos: &Vec<AssetInfo>,
40) -> Result<CosmosMsg, SharedError> {
41 Ok(env.callback_msg(ExecuteMsg::Callback(CallbackMsg::TrackBribes {
42 for_asset: asset,
43 initial_balances: asset_infos.with_balance_query(&deps.querier, &env.contract.address)?,
44 }))?)
45}
46
47impl StakeConfig<String> {
48 pub fn check(self, api: &dyn Api) -> Result<StakeConfig<Addr>, AssetError> {
49 Ok(match self {
50 StakeConfig::Default => StakeConfig::Default,
51 StakeConfig::Astroport {
52 contract,
53 reward_infos,
54 } => StakeConfig::Astroport {
55 contract: api.addr_validate(&contract)?,
56 reward_infos: reward_infos
57 .into_iter()
58 .map(|a| a.check(api, None))
59 .collect::<Result<Vec<_>, AssetError>>()?,
60 },
61 StakeConfig::Ve3 {
62 contract,
63 reward_infos,
64 } => StakeConfig::Ve3 {
65 contract: api.addr_validate(&contract)?,
66 reward_infos: reward_infos
67 .into_iter()
68 .map(|a| a.check(api, None))
69 .collect::<Result<Vec<_>, AssetError>>()?,
70 },
71 })
72 }
73}
74
75impl StakeConfig<Addr> {
76 pub fn stake_check_received_msg(
77 &self,
78 deps: &DepsMut,
79 env: &Env,
80 asset: Asset,
81 ) -> Result<Vec<CosmosMsg>, SharedError> {
82 if asset.amount.is_zero() {
83 return Ok(vec![]);
84 }
85
86 Ok(match self {
87 StakeConfig::Default => vec![],
88 StakeConfig::Astroport {
89 contract,
90 reward_infos,
91 } => {
92 vec![
93 AstroportIncentives(contract.clone()).deposit(asset.clone())?,
94 track_bribes_callback_msg(deps, env, asset.info, reward_infos)?,
95 ]
96 },
97 StakeConfig::Ve3 {
98 contract,
99 reward_infos,
100 } => {
101 vec![
102 AssetStaking(contract.clone()).deposit_msg(asset.clone())?,
103 track_bribes_callback_msg(deps, env, asset.info, reward_infos)?,
104 ]
105 },
106 })
107 }
108
109 pub fn unstake_check_received_msg(
110 &self,
111 deps: &DepsMut,
112 env: &Env,
113 asset: Asset,
114 ) -> Result<Vec<CosmosMsg>, SharedError> {
115 if asset.amount.is_zero() {
116 return Ok(vec![]);
117 }
118
119 Ok(match self {
120 StakeConfig::Default => vec![],
121 StakeConfig::Astroport {
122 contract,
123 reward_infos,
124 } => {
125 vec![
126 AstroportIncentives(contract.clone()).withdraw(asset.clone())?,
127 track_bribes_callback_msg(deps, env, asset.info, reward_infos)?,
128 ]
129 },
130 StakeConfig::Ve3 {
131 contract,
132 reward_infos,
133 } => {
134 vec![
135 AssetStaking(contract.clone()).withdraw_msg(asset.clone())?,
136 track_bribes_callback_msg(deps, env, asset.info, reward_infos)?,
137 ]
138 },
139 })
140 }
141
142 pub fn claim_check_received_msg(
143 &self,
144 deps: &DepsMut,
145 env: &Env,
146 asset: AssetInfo,
147 ) -> Result<Vec<CosmosMsg>, SharedError> {
148 Ok(match self {
149 StakeConfig::Default => vec![],
150 StakeConfig::Astroport {
151 contract,
152 reward_infos,
153 } => {
154 let asset_string = match &asset {
155 cw_asset::AssetInfoBase::Native(native) => Ok(native.to_string()),
156 cw_asset::AssetInfoBase::Cw20(contract) => Ok(contract.to_string()),
157 _ => Err(SharedError::NotSupported("asset".to_string())),
158 }?;
159
160 vec![
161 AstroportIncentives(contract.clone()).claim_rewards_msg(vec![asset_string])?,
162 track_bribes_callback_msg(deps, env, asset, reward_infos)?,
163 ]
164 },
165 StakeConfig::Ve3 {
166 contract,
167 reward_infos,
168 } => {
169 vec![
170 AssetStaking(contract.clone()).claim_reward_msg(asset.clone())?,
171 track_bribes_callback_msg(deps, env, asset, reward_infos)?,
172 ]
173 },
174 })
175 }
176}