use crate::market::client::MarketAdminClient;
use crate::market::error::MarketError;
use crate::tx_builder::TxBuilder;
use cosmrs::cosmwasm::MsgExecuteContract;
use cosmrs::tx::Msg;
use cosmrs::AccountId;
use cosmwasm_std::{Addr, Decimal256, Uint128};
use serde::Serialize;
use super::Allowance;
impl MarketAdminClient {
pub fn append_update_config_msg(
&self,
tx_builder: &mut TxBuilder,
market_address: AccountId,
config: UpdateConfig,
) -> Result<(), MarketError> {
let msg = ExecuteMsg {
update_config: UpdateConfigMsg {
price_oracle_contract: config.price_oracle_contract,
protocol_fee_recipient: config.protocol_fee_recipient,
protocol_fee: config.protocol_fee,
lp_fee: config.lp_fee,
allowance: config.allowance,
min_base_out: config.min_base_out,
},
};
let contract_msg = serde_json::to_vec(&msg).map_err(MarketError::SerdeJsonError)?;
let msg = MsgExecuteContract {
sender: tx_builder.account_id.clone(),
contract: market_address.clone(),
msg: contract_msg,
funds: vec![],
};
let msg = msg.to_any().map_err(MarketError::EyreError)?;
tx_builder.add_msg(msg);
Ok(())
}
}
#[derive(Serialize)]
struct UpdateConfigMsg {
pub price_oracle_contract: Option<Addr>,
pub protocol_fee_recipient: Option<Addr>,
pub protocol_fee: Option<Decimal256>,
pub lp_fee: Option<Decimal256>,
pub allowance: Option<Allowance>,
pub min_base_out: Option<Uint128>,
}
#[derive(Serialize)]
struct ExecuteMsg {
pub update_config: UpdateConfigMsg,
}
pub struct UpdateConfig {
pub price_oracle_contract: Option<Addr>,
pub protocol_fee_recipient: Option<Addr>,
pub protocol_fee: Option<Decimal256>,
pub lp_fee: Option<Decimal256>,
pub allowance: Option<Allowance>,
pub min_base_out: Option<Uint128>,
}
#[cfg(test)]
mod tests {
use crate::market::client::MarketAdminClient;
use crate::market::update_config::UpdateConfig;
use crate::market::Allowance;
use crate::oracle::client::OracleAdminClient;
use crate::test_utils::helpers::{
assert_event_attribute, TEST_ASSET_ARCH_SYMBOL, TEST_ASSET_USDT_SYMBOL,
};
use crate::test_utils::test_scenario::TestScenario;
use crate::tx_builder::TxBuilder;
use cosmrs::tendermint::abci::Code;
use cosmwasm_std::{Addr, Decimal256, Uint128};
use serial_test::serial;
use std::ops::Add;
use std::str::FromStr;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
#[tokio::test]
#[serial]
async fn test_append_update_config_msg() {
let mut test_scenario = TestScenario::new_from_config("config.json".to_string()).await;
let price_threshold_ratio = Decimal256::from_str("0.1").unwrap();
let price_expire_millis = Some(1000);
let oracle_contract_address = test_scenario
.instantiate_oracle_contract(price_threshold_ratio, price_expire_millis)
.await;
let client = OracleAdminClient::from_scenario(&test_scenario, &oracle_contract_address)
.expect("Failed to create oracle admin client");
test_scenario.set_default_assets(&client).await;
let price_expiry_time = SystemTime::now().add(Duration::from_secs(7200)); let price_expiry_timestamp = price_expiry_time
.duration_since(UNIX_EPOCH)
.expect("Converting to timestamp failed");
test_scenario
.set_default_prices(&client, price_expiry_timestamp, "50000")
.await;
let protocol_fee_recipient = test_scenario.admin_address.clone();
let protocol_fee = Decimal256::percent(10);
let lp_fee = Decimal256::percent(10);
let min_base_out = Uint128::from(1000u64);
let market_contract_addr = test_scenario
.instantiate_settlement_contract(
oracle_contract_address,
protocol_fee_recipient,
protocol_fee,
lp_fee,
TEST_ASSET_ARCH_SYMBOL.to_owned(),
vec![TEST_ASSET_USDT_SYMBOL.to_owned()],
min_base_out,
)
.await;
let market_contract_account_id = market_contract_addr.to_string().parse().unwrap();
let new_oracle_contract_address = Addr::unchecked(
test_scenario
.instantiate_oracle_contract(price_threshold_ratio, price_expire_millis)
.await,
);
let client =
OracleAdminClient::from_scenario(&test_scenario, new_oracle_contract_address.as_str())
.expect("Failed to create oracle admin client");
test_scenario.set_default_assets(&client).await;
test_scenario
.set_default_prices(&client, price_expiry_timestamp, "50000")
.await;
let market_client = MarketAdminClient::from_scenario(&test_scenario)
.expect("Failed to create market admin client");
let account = market_client
.account(test_scenario.admin_address.clone())
.await
.expect("Failed to get account info");
let mut tx_builder = TxBuilder::new(
test_scenario.admin_mnemonic.clone(),
test_scenario.chain_prefix.clone(),
test_scenario.chain_id.clone(),
test_scenario.derivation_path,
account.sequence,
account.account_number,
)
.expect("Failed to create tx builder");
let new_protocol_fee = Decimal256::from_str("0.4").unwrap();
let new_lp_fee = Decimal256::from_str("0.3").unwrap();
let new_min_base_out = Uint128::from(2000u64);
let config = UpdateConfig {
price_oracle_contract: Some(Addr::unchecked(new_oracle_contract_address.clone())),
protocol_fee_recipient: Some(Addr::unchecked(new_oracle_contract_address.clone())),
protocol_fee: Some(new_protocol_fee),
lp_fee: Some(new_lp_fee),
allowance: Some(Allowance::BannedLps(vec![test_scenario
.admin_address
.clone()])),
min_base_out: Some(new_min_base_out),
};
market_client
.append_update_config_msg(&mut tx_builder, market_contract_account_id, config)
.expect("Failed to append update config msg");
tx_builder.set_memo("From test_append_update_config_msg".to_string());
let gas = 400_000u64;
let amount = 70_000_000_000_000_000u128;
tx_builder.set_fee(amount, &test_scenario.chain_denom, gas);
let signed_bytes = tx_builder
.get_signed_bytes()
.expect("Failed to get signed bytes");
let response = market_client
.broadcast_tx(signed_bytes)
.await
.expect("Failed to broadcast tx");
match response.tx_result.code {
Code::Ok => {
println!("Transaction successful: {:?}", response.hash);
println!("Transaction response: {:?}", response);
let update_config_event = response
.tx_result
.events
.iter()
.find(|ev| ev.kind == "wasm-update_config")
.expect("Failed to find update config event");
assert_event_attribute(
update_config_event,
"price_oracle_contract",
new_oracle_contract_address.as_str(),
);
assert_event_attribute(
update_config_event,
"protocol_fee_recipient",
new_oracle_contract_address.as_str(),
);
assert_event_attribute(update_config_event, "protocol_fee", "0.4");
assert_event_attribute(update_config_event, "lp_fee", "0.3");
assert_event_attribute(update_config_event, "lps_default_allowed", "false");
assert_event_attribute(
update_config_event,
"lps_disallowed",
&test_scenario.admin_address,
);
assert_event_attribute(
update_config_event,
"min_base_out",
new_min_base_out.to_string().as_str(),
);
}
Code::Err(code) => {
panic!(
"Transaction failed with code: {:?} response: {:?}",
code, response
);
}
}
}
}