diff --git a/Cargo.lock b/Cargo.lock index 46107693..ec57d43d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -528,7 +528,7 @@ checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "milky_way" -version = "0.4.10" +version = "0.4.11" dependencies = [ "cosmwasm-std", "schemars", @@ -874,7 +874,7 @@ dependencies = [ [[package]] name = "staking" -version = "0.4.10" +version = "0.4.11" dependencies = [ "bech32", "bech32-no_std", diff --git a/Cargo.toml b/Cargo.toml index ceb25095..06919578 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ members = ["contracts/*", "packages/*"] [workspace.package] -version = "0.4.10" +version = "0.4.11" authors = ["Decento Labs"] edition = "2021" rust-version = "1.68.0" diff --git a/contracts/staking/src/contract.rs b/contracts/staking/src/contract.rs index 7b482bae..725939ee 100644 --- a/contracts/staking/src/contract.rs +++ b/contracts/staking/src/contract.rs @@ -96,6 +96,7 @@ pub fn instantiate( stopped: true, // we start stopped oracle_contract_address: None, // just for migration. This always needs to be set oracle_contract_address_v2: None, + oracle_address: None, }; CONFIG.save(deps.storage, &config)?; @@ -115,6 +116,7 @@ pub fn instantiate( Some(msg.treasury_address), msg.oracle_contract_address, msg.oracle_contract_address_v2, + msg.oracle_address, )?; // Init State @@ -207,6 +209,7 @@ pub fn execute( treasury_address, oracle_contract_address, oracle_contract_address_v2, + oracle_address, } => update_config( deps, env, @@ -222,6 +225,7 @@ pub fn execute( treasury_address, oracle_contract_address, oracle_contract_address_v2, + oracle_address, ), ExecuteMsg::ReceiveRewards {} => receive_rewards(deps, env, info), ExecuteMsg::ReceiveUnstakedTokens { batch_id } => { diff --git a/contracts/staking/src/execute.rs b/contracts/staking/src/execute.rs index 43bbac7b..499f7aa2 100644 --- a/contracts/staking/src/execute.rs +++ b/contracts/staking/src/execute.rs @@ -167,6 +167,21 @@ fn update_oracle_msgs(deps: Deps, env: Env, config: &Config) -> Result ContractResult { let mut config: Config = CONFIG.load(deps.storage)?; - // update oracle contract address v2 - if msg.oracle_contract_address_v2.is_some() { - let oracle_contract_address_v2 = msg.oracle_contract_address_v2.unwrap(); - let address = validate_address(&oracle_contract_address_v2, "osmo")?; - config.oracle_contract_address_v2 = Some(address); + // update oracle contract address v3 + if msg.oracle_address.is_some() { + let oracle_address = msg.oracle_address.unwrap(); + let address = validate_address(&oracle_address, "osmo")?; + config.oracle_address = Some(address); } + CONFIG.save(deps.storage, &config)?; - Ok(Response::new().add_attribute("action", "update_oracle_contract_address_v2")) + Ok(Response::new().add_attribute("action", "update_oracle_address")) } // Update the config; callable by the owner @@ -771,6 +787,7 @@ pub fn update_config( treasury_address: Option, oracle_contract_address: Option, oracle_contract_address_v2: Option, + oracle_address: Option, ) -> ContractResult { ADMIN.assert_admin(deps.as_ref(), &info.sender)?; @@ -837,6 +854,12 @@ pub fn update_config( config.oracle_contract_address_v2 = Some(address); } + if oracle_address.is_some() { + let oracle_address = oracle_address.unwrap(); + let address = validate_address(&oracle_address, "osmo")?; + config.oracle_address = Some(address); + } + CONFIG.save(deps.storage, &config)?; Ok(Response::new().add_attribute("action", "update_config")) diff --git a/contracts/staking/src/msg.rs b/contracts/staking/src/msg.rs index 5a0a7ebe..e7a518bc 100644 --- a/contracts/staking/src/msg.rs +++ b/contracts/staking/src/msg.rs @@ -35,6 +35,8 @@ pub struct InstantiateMsg { pub oracle_contract_address: Option, // The migratable redemption / purchase rate oracle address pub oracle_contract_address_v2: Option, + // The redemption / purchase rate oracle address + pub oracle_address: Option, } #[cw_serde] @@ -71,6 +73,7 @@ pub enum ExecuteMsg { treasury_address: Option, oracle_contract_address: Option, oracle_contract_address_v2: Option, + oracle_address: Option, }, ReceiveRewards {}, ReceiveUnstakedTokens { @@ -108,6 +111,7 @@ pub struct ConfigResponse { pub stopped: bool, pub oracle_contract_address: String, pub oracle_contract_address_v2: String, + pub oracle_address: String, } #[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug, Default)] @@ -198,7 +202,7 @@ pub enum QueryMsg { #[derive(Serialize, Deserialize, JsonSchema)] pub struct MigrateMsg { - pub oracle_contract_address_v2: Option + pub oracle_address: Option } #[cw_serde] diff --git a/contracts/staking/src/oracle.rs b/contracts/staking/src/oracle.rs index 0df1a21e..e5a2f76c 100644 --- a/contracts/staking/src/oracle.rs +++ b/contracts/staking/src/oracle.rs @@ -7,52 +7,21 @@ pub const ORACLE_PURCHASE_RATE_KEY: &str = "milkTIA_purchase_rate"; #[cw_serde] pub enum Oracle { - /// Uploads and stores a new metric PostMetric { - /// Key identifying the metric (e.g. `stuatom_redemption_rate`) key: String, - /// Value for the metric (e.g. `1.1`) value: String, - /// Category for the metric(e.g. `redemption_rate`) - /// Helps determine handling of additional context metric_type: MetricType, - /// Unix timestamp with which the metric was updated on the source chain update_time: u64, - /// Block height with which the metric was updated on the source chain block_height: u64, - /// Additional metric-specific attributes attributes: Option, }, + PostRates { + denom: String, + purchase_rate: String, + redemption_rate: String, + }, } -/// The RedemptionRate struct represents the redemption rate of an stToken -#[cw_serde] -pub struct RedemptionRate { - /// stToken denom as an IBC hash, as it appears on the oracle chain - pub denom: String, - /// The redemption rate of the stToken - pub redemption_rate: Decimal, - /// The unix timestamp representing when the redemption rate was last updated - pub update_time: u64, -} - -/// The PurchaseRate struct represents the purchase rate of an milkTia -#[cw_serde] -pub struct PurchaseRate { - /// stToken denom as an IBC hash, as it appears on the oracle chain - pub denom: String, - /// The purchase rate of the milkTia - pub purchase_rate: Decimal, - /// The unix timestamp representing when the purchase rate was last updated - pub update_time: u64, -} - -/// This contract represents a generic key value store -/// A "metric" is the term for a piece of information stored -/// Each metric has a higher level category that helps inform if any other, -/// metric-specific logic needs to be run -/// i.e. For redemption rates, there is an expected format for the attributes -/// field with additional metadata #[cw_serde] pub enum MetricType { RedemptionRate, @@ -60,15 +29,11 @@ pub enum MetricType { Other(String), } -/// For use in price oracles, the RedemptionRate metric requires the stToken denom -/// as it appears on the controller chain (e.g. `stuosmo`) #[cw_serde] pub struct RedemptionRateAttributes { pub sttoken_denom: String, } -/// For use in price oracles, the PurchaseRate metric requires the stToken denom -/// as it appears on the controller chain (e.g. `stuosmo`) #[cw_serde] pub struct PurchaseRateAttributes { pub sttoken_denom: String, diff --git a/contracts/staking/src/query.rs b/contracts/staking/src/query.rs index 86364ff9..cfa282b2 100644 --- a/contracts/staking/src/query.rs +++ b/contracts/staking/src/query.rs @@ -49,6 +49,10 @@ pub fn query_config(deps: Deps) -> StdResult { .oracle_contract_address_v2 .map(|v| v.to_string()) .unwrap_or_default(), + oracle_address: config + .oracle_address + .map(|v| v.to_string()) + .unwrap_or_default(), }; Ok(res) } diff --git a/contracts/staking/src/state.rs b/contracts/staking/src/state.rs index adbc270b..f21854c3 100644 --- a/contracts/staking/src/state.rs +++ b/contracts/staking/src/state.rs @@ -21,6 +21,7 @@ pub struct Config { pub stopped: bool, pub oracle_contract_address: Option, pub oracle_contract_address_v2: Option, + pub oracle_address: Option, } // TODO: PENDING - DOCS DEFINE THESE AS MAPS? // Discuss: Do we want to add or remove any state? diff --git a/contracts/staking/src/tests/ibc_transfer_tests.rs b/contracts/staking/src/tests/ibc_transfer_tests.rs index 19fc0af0..64f06451 100644 --- a/contracts/staking/src/tests/ibc_transfer_tests.rs +++ b/contracts/staking/src/tests/ibc_transfer_tests.rs @@ -48,7 +48,7 @@ mod ibc_transfer_tests { ] ); assert_eq!( - result.messages[4], + result.messages[5], SubMsg { id: ibc_sub_msg_id.clone(), msg: >::into(MsgTransfer { diff --git a/contracts/staking/src/tests/instantiate_tests.rs b/contracts/staking/src/tests/instantiate_tests.rs index ec1d489f..2956b74b 100644 --- a/contracts/staking/src/tests/instantiate_tests.rs +++ b/contracts/staking/src/tests/instantiate_tests.rs @@ -47,6 +47,7 @@ mod tests { ibc_channel_id: CHANNEL_ID.to_string(), oracle_contract_address: None, oracle_contract_address_v2: None, + oracle_address: None, } } @@ -158,6 +159,7 @@ mod tests { treasury_address: Some(OSMO3.to_string()), oracle_contract_address: None, oracle_contract_address_v2: None, + oracle_address: None, }; let res = crate::contract::execute( @@ -189,6 +191,7 @@ mod tests { treasury_address: None, oracle_contract_address: None, oracle_contract_address_v2: None, + oracle_address: None, }; let res = crate::contract::execute( deps.as_mut(), @@ -215,6 +218,7 @@ mod tests { treasury_address: None, oracle_contract_address: None, oracle_contract_address_v2: None, + oracle_address: None, }; let res = crate::contract::execute( deps.as_mut(), @@ -241,6 +245,7 @@ mod tests { treasury_address: None, oracle_contract_address: None, oracle_contract_address_v2: None, + oracle_address: None, }; let res = crate::contract::execute( deps.as_mut(), diff --git a/contracts/staking/src/tests/reward_tests.rs b/contracts/staking/src/tests/reward_tests.rs index 1e2a3b51..3195d0d4 100644 --- a/contracts/staking/src/tests/reward_tests.rs +++ b/contracts/staking/src/tests/reward_tests.rs @@ -70,10 +70,10 @@ mod reward_tests { assert!(res.is_ok()); let res = res.unwrap(); - assert_eq!(res.messages.len(), 4); // transfer message and redemption/purchase rate update - assert_eq!(res.messages[3].reply_on, ReplyOn::Always); + assert_eq!(res.messages.len(), 5); // transfer message and redemption/purchase rate update + assert_eq!(res.messages[4].reply_on, ReplyOn::Always); assert_eq!( - res.messages[3].msg, + res.messages[4].msg, CosmosMsg::from(MsgTransfer { source_channel: CHANNEL_ID.to_string(), source_port: "transfer".to_string(), diff --git a/contracts/staking/src/tests/stake_tests.rs b/contracts/staking/src/tests/stake_tests.rs index e5c46215..43313cb4 100644 --- a/contracts/staking/src/tests/stake_tests.rs +++ b/contracts/staking/src/tests/stake_tests.rs @@ -49,9 +49,9 @@ mod staking_tests { attr("mint_amount", "1000"), ] ); - assert_eq!(result.messages.len(), 5); // transfer, mint, redemption rate update + assert_eq!(result.messages.len(), 6); // transfer, mint, redemption rate update assert_eq!( - result.messages[4], + result.messages[5], SubMsg { id: ibc_sub_msg_id.clone(), msg: >::into(MsgTransfer { diff --git a/contracts/staking/src/tests/test_helper.rs b/contracts/staking/src/tests/test_helper.rs index 926f0e38..a8806ff3 100644 --- a/contracts/staking/src/tests/test_helper.rs +++ b/contracts/staking/src/tests/test_helper.rs @@ -41,6 +41,7 @@ pub fn init() -> OwnedDeps { ibc_channel_id: CHANNEL_ID.to_string(), oracle_contract_address: Some(OSMO3.to_string()), oracle_contract_address_v2: Some(OSMO4.to_string()), + oracle_address: Some(OSMO4.to_string()), }; let info = mock_info(OSMO3, &coins(1000, "uosmo")); diff --git a/contracts/staking/src/tests/unstake_tests.rs b/contracts/staking/src/tests/unstake_tests.rs index 0a2d2ca6..3f4ca11f 100644 --- a/contracts/staking/src/tests/unstake_tests.rs +++ b/contracts/staking/src/tests/unstake_tests.rs @@ -147,7 +147,7 @@ mod staking_tests { assert_eq!(attrs[3].value, "650"); let messages = resp.messages; - assert_eq!(messages.len(), 4); // batch submit and redemption/purchase rate update + assert_eq!(messages.len(), 5); // batch submit and redemption/purchase rate update assert_eq!( messages[0], SubMsg { diff --git a/contracts/staking/src/tests/withdraw_tests.rs b/contracts/staking/src/tests/withdraw_tests.rs index 02cbc920..b326a826 100644 --- a/contracts/staking/src/tests/withdraw_tests.rs +++ b/contracts/staking/src/tests/withdraw_tests.rs @@ -70,7 +70,7 @@ mod withdraw_tests { let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); assert!(res.is_ok()); let messages = res.unwrap().messages; - assert_eq!(messages.len(), 4); // withdraw and redemption/purchase rate update + assert_eq!(messages.len(), 5); // withdraw and redemption/purchase rate update let msg = QueryMsg::UnstakeRequests { user: Addr::unchecked("bob"), @@ -112,7 +112,7 @@ mod withdraw_tests { let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); assert!(res.is_ok()); let messages = res.unwrap().messages; - assert_eq!(messages.len(), 4); // withdraw and redemption/purchase rate update + assert_eq!(messages.len(), 5); // withdraw and redemption/purchase rate update let msg = QueryMsg::UnstakeRequests { user: Addr::unchecked("tom"), @@ -190,7 +190,7 @@ mod withdraw_tests { let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); assert!(res.is_ok()); let messages = res.unwrap().messages; - assert_eq!(messages.len(), 4); // withdraw and redemption rate update + assert_eq!(messages.len(), 5); // withdraw and redemption rate update let msg = QueryMsg::UnstakeRequests { user: Addr::unchecked("bob"), @@ -232,7 +232,7 @@ mod withdraw_tests { let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); assert!(res.is_ok()); let messages = res.unwrap().messages; - assert_eq!(messages.len(), 4); // withdraw and redemption/purchase rate update + assert_eq!(messages.len(), 5); // withdraw and redemption/purchase rate update let msg = QueryMsg::UnstakeRequests { user: Addr::unchecked("tom"),