Skip to main content

ve3_shared/
stake_config.rs

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}