astroport_emissions_controller/
instantiate.rs1use astroport::asset::validate_native_denom;
2#[cfg(not(feature = "library"))]
3use cosmwasm_std::entry_point;
4use cosmwasm_std::{
5 ensure, to_json_binary, Addr, DepsMut, Env, MessageInfo, Reply, Response, StdError, SubMsg,
6 SubMsgResponse, SubMsgResult, Uint128, WasmMsg,
7};
8use cw2::set_contract_version;
9use cw_utils::parse_instantiate_response_data;
10use neutron_sdk::bindings::msg::NeutronMsg;
11use neutron_sdk::bindings::query::NeutronQuery;
12
13use astroport_governance::emissions_controller::hub::{Config, TuneInfo};
14use astroport_governance::emissions_controller::hub::{EmissionsState, HubInstantiateMsg};
15use astroport_governance::emissions_controller::utils::query_incentives_addr;
16use astroport_governance::voting_escrow;
17
18use crate::error::ContractError;
19use crate::state::{CONFIG, POOLS_WHITELIST, TUNE_INFO};
20use crate::utils::{get_epoch_start, get_xastro_rate_and_share};
21
22pub const CONTRACT_NAME: &str = env!("CARGO_PKG_NAME");
24pub const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
26pub const INSTANTIATE_VXASTRO_REPLY_ID: u64 = 1;
28
29#[cfg_attr(not(feature = "library"), entry_point)]
31pub fn instantiate(
32 deps: DepsMut<NeutronQuery>,
33 env: Env,
34 _info: MessageInfo,
35 msg: HubInstantiateMsg,
36) -> Result<Response<NeutronMsg>, ContractError> {
37 let deps = deps.into_empty();
38
39 set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
40
41 validate_native_denom(&msg.astro_denom)?;
42
43 let factory = deps.api.addr_validate(&msg.factory)?;
44
45 let staking =
46 if msg.xastro_denom.starts_with("factory/") && msg.xastro_denom.ends_with("/xASTRO") {
47 deps.api
48 .addr_validate(msg.xastro_denom.split('/').nth(1).unwrap())
49 } else {
50 Err(StdError::generic_err(format!(
51 "Invalid xASTRO denom {}",
52 msg.xastro_denom
53 )))
54 }?;
55
56 let config = Config {
57 owner: deps.api.addr_validate(&msg.owner)?,
58 assembly: deps.api.addr_validate(&msg.assembly)?,
59 vxastro: Addr::unchecked(""),
60 incentives_addr: query_incentives_addr(deps.querier, &factory)?,
61 factory,
62 astro_denom: msg.astro_denom.to_string(),
63 pools_per_outpost: msg.pools_per_outpost,
64 whitelisting_fee: msg.whitelisting_fee,
65 fee_receiver: deps.api.addr_validate(&msg.fee_receiver)?,
66 whitelist_threshold: msg.whitelist_threshold,
67 emissions_multiple: msg.emissions_multiple,
68 max_astro: msg.max_astro,
69 staking,
70 xastro_denom: msg.xastro_denom.clone(),
71 };
72 config.validate()?;
73
74 CONFIG.save(deps.storage, &config)?;
75
76 let (xastro_rate, _) = get_xastro_rate_and_share(deps.querier, &config)?;
78
79 TUNE_INFO.save(
81 deps.storage,
82 &TuneInfo {
83 tune_ts: get_epoch_start(env.block.time.seconds()),
84 pools_grouped: Default::default(),
85 outpost_emissions_statuses: Default::default(),
86 emissions_state: EmissionsState {
87 xastro_rate,
88 collected_astro: msg.collected_astro,
89 ema: msg.ema,
90 emissions_amount: Uint128::zero(),
91 },
92 },
93 env.block.time.seconds(),
94 )?;
95
96 let init_vxastro_msg = WasmMsg::Instantiate {
98 admin: Some(msg.assembly),
99 code_id: msg.vxastro_code_id,
100 msg: to_json_binary(&voting_escrow::InstantiateMsg {
101 deposit_denom: msg.xastro_denom.to_string(),
102 emissions_controller: env.contract.address.to_string(),
103 marketing: msg.vxastro_marketing_info,
104 })?,
105 funds: vec![],
106 label: "Vote Escrowed xASTRO".to_string(),
107 };
108
109 POOLS_WHITELIST.save(deps.storage, &vec![])?;
110
111 Ok(Response::default()
112 .add_attribute("action", "instantiate_emissions_controller")
113 .add_submessage(SubMsg::reply_on_success(
114 init_vxastro_msg,
115 INSTANTIATE_VXASTRO_REPLY_ID,
116 )))
117}
118
119#[cfg_attr(not(feature = "library"), entry_point)]
120pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result<Response, ContractError> {
121 match msg {
122 Reply {
123 id: INSTANTIATE_VXASTRO_REPLY_ID,
124 result:
125 SubMsgResult::Ok(SubMsgResponse {
126 data: Some(data), ..
127 }),
128 } => {
129 let vxastro_contract = parse_instantiate_response_data(&data)?.contract_address;
130
131 CONFIG.update::<_, StdError>(deps.storage, |mut config| {
132 ensure!(
133 config.vxastro == Addr::unchecked(""),
134 StdError::generic_err("vxASTRO contract is already set")
135 );
136
137 config.vxastro = Addr::unchecked(&vxastro_contract);
138 Ok(config)
139 })?;
140
141 Ok(Response::new().add_attribute("vxastro", vxastro_contract))
142 }
143 _ => Err(ContractError::FailedToParseReply {}),
144 }
145}