Skip to content

Commit

Permalink
Merge pull request #31 from WHELP-project/pool/deploy-staking
Browse files Browse the repository at this point in the history
Pool: Implement automatic deployment of the staking contract
  • Loading branch information
ueco-jb authored Nov 20, 2023
2 parents f0e395e + eb01190 commit ac21a33
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 84 deletions.
34 changes: 26 additions & 8 deletions contracts/pool/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use coreum_wasm_sdk::{
use cosmwasm_std::{
attr, coin, ensure, entry_point, from_binary, to_binary, Addr, BankMsg, Binary, Coin,
CosmosMsg, Decimal, Decimal256, Deps, DepsMut, Env, Isqrt, MessageInfo, Reply, StdError,
StdResult, Uint128, Uint256,
StdResult, Uint128, Uint256, WasmMsg,
};

use cw2::set_contract_version;
Expand All @@ -27,7 +27,7 @@ use dex::{
get_share_in_assets, handle_reply, save_tmp_staking_config, ConfigResponse, ContractError,
CumulativePricesResponse, Cw20HookMsg, ExecuteMsg, InstantiateMsg, MigrateMsg, PairInfo,
PoolResponse, QueryMsg, ReverseSimulationResponse, SimulationResponse, DEFAULT_SLIPPAGE,
LP_TOKEN_PRECISION, MAX_ALLOWED_SLIPPAGE, TWAP_PRECISION,
INSTANTIATE_STAKE_REPLY_ID, LP_TOKEN_PRECISION, MAX_ALLOWED_SLIPPAGE, TWAP_PRECISION,
},
};

Expand All @@ -46,7 +46,7 @@ const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn instantiate(
deps: DepsMut<CoreumQueries>,
env: Env,
_info: MessageInfo,
info: MessageInfo,
msg: InstantiateMsg,
) -> Result<Response, ContractError> {
let asset_infos = check_asset_infos(deps.api, &msg.asset_infos)?;
Expand All @@ -63,10 +63,11 @@ pub fn instantiate(

let lp_token_name = format_lp_token_name(&asset_infos, &deps.querier)?;

let lp_share_denom: String = format!("u{}-{}", lp_token_name.clone(), env.contract.address);
let config = Config {
pool_info: PairInfo {
contract_addr: env.contract.address.clone(),
liquidity_token: format!("u{}-{}", lp_token_name.clone(), env.contract.address),
liquidity_token: lp_share_denom.clone(),
staking_addr: Addr::unchecked(""),
asset_infos,
pool_type: PoolType::Xyk {},
Expand All @@ -84,8 +85,8 @@ pub fn instantiate(
LP_SHARE_AMOUNT.save(deps.storage, &Uint128::zero())?;
save_tmp_staking_config(deps.storage, &msg.staking_config)?;

Ok(
Response::new().add_submessage(SubMsg::new(CoreumMsg::AssetFT(assetft::Msg::Issue {
Ok(Response::new()
.add_submessage(SubMsg::new(CoreumMsg::AssetFT(assetft::Msg::Issue {
symbol: lp_token_name.clone(),
subunit: format!("u{}", lp_token_name),
precision: LP_TOKEN_PRECISION,
Expand All @@ -94,8 +95,25 @@ pub fn instantiate(
features: Some(vec![0, 1, 2]), // 0 - minting, 1 - burning, 2 - freezing
burn_rate: Some("0".into()),
send_commission_rate: Some("0.00000".into()),
}))),
)
})))
.add_submessage(SubMsg::reply_on_success(
WasmMsg::Instantiate {
code_id: msg.staking_config.staking_code_id,
msg: to_binary(&dex::stake::InstantiateMsg {
lp_share_denom,
tokens_per_power: msg.staking_config.tokens_per_power,
min_bond: msg.staking_config.min_bond,
unbonding_periods: msg.staking_config.unbonding_periods,
max_distributions: msg.staking_config.max_distributions,
admin: Some(info.sender.to_string()),
unbonder: None, // TODO: allow specifying unbonder
})?,
funds: vec![],
admin: Some(info.sender.to_string()),
label: String::from("Dex-Stake"),
},
INSTANTIATE_STAKE_REPLY_ID,
)))
}

/// Manages the contract migration.
Expand Down
64 changes: 39 additions & 25 deletions contracts/pool/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ fn proper_initialization() {
AssetInfo::SmartToken("uusd".to_string()),
AssetInfo::Cw20Token("asset0000".to_string()),
],
token_code_id: 10u64,
init_params: None,
staking_config: default_stake_config(),
trading_starts: 0,
Expand All @@ -74,22 +73,45 @@ fn proper_initialization() {
let res = instantiate(deps.as_mut(), env, info, msg).unwrap();
assert_eq!(
res.messages,
vec![SubMsg {
msg: CoreumMsg::AssetFT(assetft::Msg::Issue {
symbol: "uusdmapplp".to_string(),
subunit: "uuusdmapplp".to_string(),
precision: LP_TOKEN_PRECISION,
initial_amount: Uint128::zero(),
description: Some("Dex LP Share token".to_string()),
features: Some(vec![0, 1, 2]),
burn_rate: Some("0".into()),
send_commission_rate: Some("0.00000".into()),
})
.into(),
id: 0,
gas_limit: None,
reply_on: ReplyOn::Never
},]
vec![
SubMsg {
msg: CoreumMsg::AssetFT(assetft::Msg::Issue {
symbol: "uusdmapplp".to_string(),
subunit: "uuusdmapplp".to_string(),
precision: LP_TOKEN_PRECISION,
initial_amount: Uint128::zero(),
description: Some("Dex LP Share token".to_string()),
features: Some(vec![0, 1, 2]),
burn_rate: Some("0".into()),
send_commission_rate: Some("0.00000".into()),
})
.into(),
id: 0,
gas_limit: None,
reply_on: ReplyOn::Never
},
SubMsg {
msg: CosmosMsg::Wasm(WasmMsg::Instantiate {
admin: Some("addr0000".to_owned()),
code_id: 11,
funds: vec![],
label: "Dex-Stake".to_owned(),
msg: to_binary(&dex::stake::InstantiateMsg {
lp_share_denom: "uuusdmapplp-cosmos2contract".to_owned(),
tokens_per_power: Uint128::new(1000),
min_bond: Uint128::new(1000),
unbonding_periods: vec![60 * 60 * 24 * 7],
max_distributions: 6,
admin: Some("addr0000".to_owned()),
unbonder: None
})
.unwrap()
}),
id: 2,
gas_limit: None,
reply_on: ReplyOn::Success
}
]
);

// It worked, let's query the state
Expand Down Expand Up @@ -137,7 +159,6 @@ fn test_freezing_a_pool_blocking_actions_then_unfreeze() {
AssetInfo::SmartToken("uusd".to_string()),
AssetInfo::Cw20Token("asset0000".to_string()),
],
token_code_id: 10u64,
// factory_addr: String::from("factory"),
init_params: None,
staking_config: default_stake_config(),
Expand Down Expand Up @@ -419,7 +440,6 @@ fn provide_liquidity() {
AssetInfo::SmartToken("uusd".to_string()),
AssetInfo::Cw20Token("asset0000".to_string()),
],
token_code_id: 10u64,
// factory_addr: String::from("factory"),
init_params: None,
staking_config: default_stake_config(),
Expand Down Expand Up @@ -869,7 +889,6 @@ fn withdraw_liquidity() {
AssetInfo::SmartToken("uusd".to_string()),
AssetInfo::Cw20Token("asset0000".to_string()),
],
token_code_id: 10u64,

// factory_addr: String::from("factory"),
init_params: None,
Expand Down Expand Up @@ -1023,7 +1042,6 @@ fn query_twap() {
// instantiate the contract
let msg = InstantiateMsg {
asset_infos: vec![uusd.clone().into(), token.clone().into()],
token_code_id: 10u64,
// factory_addr: String::from("factory"),
init_params: None,
staking_config: default_stake_config(),
Expand Down Expand Up @@ -1181,7 +1199,6 @@ fn try_native_to_token() {
AssetInfo::SmartToken("uusd".to_string()),
AssetInfo::Cw20Token("asset0000".to_string()),
],
token_code_id: 10u64,
// factory_addr: String::from("factory"),
init_params: None,
staking_config: default_stake_config(),
Expand Down Expand Up @@ -1399,7 +1416,6 @@ fn try_token_to_native() {
AssetInfo::SmartToken("uusd".to_string()),
AssetInfo::Cw20Token("asset0000".to_string()),
],
token_code_id: 10u64,
// factory_addr: String::from("factory"),
init_params: None,
staking_config: default_stake_config(),
Expand Down Expand Up @@ -1662,7 +1678,6 @@ fn test_query_pool() {
AssetInfo::SmartToken("uusd".to_string()),
AssetInfo::Cw20Token("asset0000".to_string()),
],
token_code_id: 10u64,
// factory_addr: String::from("factory"),
init_params: None,
staking_config: default_stake_config(),
Expand Down Expand Up @@ -1724,7 +1739,6 @@ fn test_query_share() {
AssetInfo::SmartToken("uusd".to_string()),
AssetInfo::Cw20Token("asset0000".to_string()),
],
token_code_id: 10u64,
// factory_addr: String::from("factory"),
init_params: None,
staking_config: default_stake_config(),
Expand Down
9 changes: 0 additions & 9 deletions contracts/pool_stable/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ fn proper_initialization() {
AssetInfo::SmartToken("uusd".to_string()),
AssetInfo::Cw20Token("asset0000".to_string()),
],
token_code_id: 10u64,
init_params: Some(
to_binary(&StablePoolParams {
amp: 100,
Expand Down Expand Up @@ -143,7 +142,6 @@ fn test_freezing_a_pool_blocking_actions_then_unfreeze() {
AssetInfo::SmartToken("uusd".to_string()),
AssetInfo::Cw20Token("asset0000".to_string()),
],
token_code_id: 10u64,
// factory_addr: String::from("factory"),
init_params: Some(
to_binary(&StablePoolParams {
Expand Down Expand Up @@ -432,7 +430,6 @@ fn test_freezing_a_pool_blocking_actions_then_unfreeze() {
// AssetInfo::SmartToken("uusd".to_string()),
// AssetInfo::Cw20Token("asset0000".to_string()),
// ],
// token_code_id: 10u64,
// // factory_addr: String::from("factory"),
// init_params: None,
// staking_config: default_stake_config(),
Expand Down Expand Up @@ -882,7 +879,6 @@ fn test_freezing_a_pool_blocking_actions_then_unfreeze() {
// AssetInfo::SmartToken("uusd".to_string()),
// AssetInfo::Cw20Token("asset0000".to_string()),
// ],
// token_code_id: 10u64,
//
// // factory_addr: String::from("factory"),
// init_params: None,
Expand Down Expand Up @@ -1036,7 +1032,6 @@ fn test_freezing_a_pool_blocking_actions_then_unfreeze() {
// // instantiate the contract
// let msg = InstantiateMsg {
// asset_infos: vec![uusd.clone().into(), token.clone().into()],
// token_code_id: 10u64,
// // factory_addr: String::from("factory"),
// init_params: None,
// staking_config: default_stake_config(),
Expand Down Expand Up @@ -1194,7 +1189,6 @@ fn test_freezing_a_pool_blocking_actions_then_unfreeze() {
// AssetInfo::SmartToken("uusd".to_string()),
// AssetInfo::Cw20Token("asset0000".to_string()),
// ],
// token_code_id: 10u64,
// // factory_addr: String::from("factory"),
// init_params: None,
// staking_config: default_stake_config(),
Expand Down Expand Up @@ -1412,7 +1406,6 @@ fn test_freezing_a_pool_blocking_actions_then_unfreeze() {
// AssetInfo::SmartToken("uusd".to_string()),
// AssetInfo::Cw20Token("asset0000".to_string()),
// ],
// token_code_id: 10u64,
// // factory_addr: String::from("factory"),
// init_params: None,
// staking_config: default_stake_config(),
Expand Down Expand Up @@ -1675,7 +1668,6 @@ fn test_freezing_a_pool_blocking_actions_then_unfreeze() {
// AssetInfo::SmartToken("uusd".to_string()),
// AssetInfo::Cw20Token("asset0000".to_string()),
// ],
// token_code_id: 10u64,
// // factory_addr: String::from("factory"),
// init_params: None,
// staking_config: default_stake_config(),
Expand Down Expand Up @@ -1737,7 +1729,6 @@ fn test_freezing_a_pool_blocking_actions_then_unfreeze() {
// AssetInfo::SmartToken("uusd".to_string()),
// AssetInfo::Cw20Token("asset0000".to_string()),
// ],
// token_code_id: 10u64,
// // factory_addr: String::from("factory"),
// init_params: None,
// staking_config: default_stake_config(),
Expand Down
2 changes: 0 additions & 2 deletions packages/dex/src/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,6 @@ impl PairInfo {
pub struct InstantiateMsg {
/// Information about assets in the pool
pub asset_infos: Vec<AssetInfo>,
/// The token contract code ID used for the tokens in the pool
pub token_code_id: u64,
/// The factory contract address
// pub factory_addr: String,
/// Optional binary serialised parameters for custom pool types
Expand Down
58 changes: 18 additions & 40 deletions packages/dex/src/pool/instantiate.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use coreum_wasm_sdk::core::{CoreumMsg, CoreumQueries};
use cosmwasm_std::{Addr, DepsMut, Reply, StdError, StdResult, Storage};
use cw_storage_plus::Item;
use cw_utils::MsgExecuteContractResponse;
use cw_utils::MsgInstantiateContractResponse;

use super::{ContractError, PairInfo, StakeConfig};

Expand All @@ -15,7 +15,7 @@ const TMP_STAKING_CONFIG: Item<StakeConfig> = Item::new("tmp_staking_config");
pub const LP_TOKEN_PRECISION: u32 = 6;

/// A `reply` call code ID used for staking contract instantiation sub-message.
const _INSTANTIATE_STAKE_REPLY_ID: u64 = 2;
pub const INSTANTIATE_STAKE_REPLY_ID: u64 = 2;

/// Saves this `stake_config` to the storage temporarily
/// until the reply for creating the lp token arrives.
Expand All @@ -28,56 +28,34 @@ pub fn save_tmp_staking_config(

/// Handles the replies from the lp token and staking contract instantiation sub-messages.
pub fn handle_reply(
_deps: &DepsMut<CoreumQueries>,
deps: &DepsMut<CoreumQueries>,
msg: Reply,
// factory: &Addr,
_pool_info: &mut PairInfo,
pool_info: &mut PairInfo,
) -> Result<Response, ContractError> {
let msg_id = msg.id;
// parse the reply
let _res = cw_utils::parse_reply_execute_data(msg).map_err(|_| {
let res = cw_utils::parse_reply_instantiate_data(msg).map_err(|_| {
StdError::parse_err("MsgInstantiateContractResponse", "failed to parse data")
})?;
Err(ContractError::UnknownReply(msg_id))
match msg_id {
INSTANTIATE_STAKE_REPLY_ID => instantiate_staking_reply(deps, res, pool_info),
_ => Err(ContractError::UnknownReply(msg_id)),
}
}

/// Sets the `pool_info`'s `liquidity_token` field to the address of the newly instantiated
/// lp token contract, reads the temporary staking config and sends a sub-message to instantiate
/// the staking contract.
pub fn instantiate_lp_token_reply(
_deps: &DepsMut<CoreumQueries>,
_res: MsgExecuteContractResponse,
_factory: &Addr,
// Sets the `pool_info`'s `staking_addr` field to the address of the newly instantiated
// staking contract, and returns a response.
pub fn instantiate_staking_reply(
deps: &DepsMut<CoreumQueries>,
res: MsgInstantiateContractResponse,
pool_info: &mut PairInfo,
) -> Result<Response, ContractError> {
if pool_info.liquidity_token != Addr::unchecked("") {
return Err(ContractError::AddrAlreadySet("liquidity_token"));
if pool_info.staking_addr != Addr::unchecked("") {
return Err(ContractError::AddrAlreadySet("staking"));
}

// pool_info.liquidity_token = deps.api.addr_validate(&res.contract_address)?;
pool_info.staking_addr = deps.api.addr_validate(&res.contract_address)?;

// now that we have the lp token, create the staking contract
// let staking_cfg = TMP_STAKING_CONFIG.load(deps.storage)?;

Ok(Response::new()
// .add_submessage(SubMsg::new(
// staking_cfg.into_init_msg(&deps.querier, res.contract_address, factory.to_string())?,
// ))
.add_attribute("liquidity_token_addr", &pool_info.liquidity_token))
Ok(Response::new().add_attribute("staking_addr", &pool_info.staking_addr))
}

// Sets the `pool_info`'s `staking_addr` field to the address of the newly instantiated
// staking contract, and returns a response.
// pub fn instantiate_staking_reply(
// deps: &DepsMut<CoreumQueries>,
// res: MsgInstantiateContractResponse,
// pool_info: &mut PairInfo,
// ) -> Result<Response, ContractError> {
// if pool_info.staking_addr != Addr::unchecked("") {
// return Err(ContractError::AddrAlreadySet("staking"));
// }
//
// pool_info.staking_addr = deps.api.addr_validate(&res.contract_address)?;
//
// Ok(Response::new().add_attribute("staking_addr", &pool_info.staking_addr))
// }

0 comments on commit ac21a33

Please sign in to comment.