diff --git a/Cargo.lock b/Cargo.lock index 1d3b8f9..1110bc7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,7 +15,7 @@ dependencies = [ [[package]] name = "alliance-hub" -version = "0.1.1" +version = "0.1.2" dependencies = [ "alliance-protocol", "cosmwasm-schema", diff --git a/contracts/alliance-hub/Cargo.toml b/contracts/alliance-hub/Cargo.toml index f577876..b74be15 100644 --- a/contracts/alliance-hub/Cargo.toml +++ b/contracts/alliance-hub/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "alliance-hub" -version = "0.1.1" +version = "0.1.2" authors = ["Terra Money "] edition = "2018" diff --git a/contracts/alliance-hub/schema/alliance-hub.json b/contracts/alliance-hub/schema/alliance-hub.json index 8638250..0c451ab 100644 --- a/contracts/alliance-hub/schema/alliance-hub.json +++ b/contracts/alliance-hub/schema/alliance-hub.json @@ -1,6 +1,6 @@ { "contract_name": "alliance-hub", - "contract_version": "0.1.0", + "contract_version": "0.1.2", "idl_version": "1.0.0", "instantiate": { "$schema": "http://json-schema.org/draft-07/schema#", @@ -10,6 +10,7 @@ "alliance_token_denom", "controller", "governance", + "operator", "oracle", "reward_denom" ], @@ -23,6 +24,9 @@ "governance": { "type": "string" }, + "operator": { + "type": "string" + }, "oracle": { "type": "string" }, @@ -220,6 +224,45 @@ } }, "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_config" + ], + "properties": { + "update_config": { + "type": "object", + "properties": { + "controller": { + "type": [ + "string", + "null" + ] + }, + "governance": { + "type": [ + "string", + "null" + ] + }, + "operator": { + "type": [ + "string", + "null" + ] + }, + "oracle": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } ], "definitions": { @@ -840,6 +883,7 @@ "controller", "governance", "last_reward_update_timestamp", + "operator", "oracle", "reward_denom" ], @@ -859,6 +903,9 @@ "last_reward_update_timestamp": { "$ref": "#/definitions/Timestamp" }, + "operator": { + "$ref": "#/definitions/Addr" + }, "oracle": { "$ref": "#/definitions/Addr" }, diff --git a/contracts/alliance-hub/schema/raw/execute.json b/contracts/alliance-hub/schema/raw/execute.json index e23ba07..0e0622e 100644 --- a/contracts/alliance-hub/schema/raw/execute.json +++ b/contracts/alliance-hub/schema/raw/execute.json @@ -186,6 +186,45 @@ } }, "additionalProperties": false + }, + { + "type": "object", + "required": [ + "update_config" + ], + "properties": { + "update_config": { + "type": "object", + "properties": { + "controller": { + "type": [ + "string", + "null" + ] + }, + "governance": { + "type": [ + "string", + "null" + ] + }, + "operator": { + "type": [ + "string", + "null" + ] + }, + "oracle": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } ], "definitions": { diff --git a/contracts/alliance-hub/schema/raw/instantiate.json b/contracts/alliance-hub/schema/raw/instantiate.json index 62db08e..69f2a42 100644 --- a/contracts/alliance-hub/schema/raw/instantiate.json +++ b/contracts/alliance-hub/schema/raw/instantiate.json @@ -6,6 +6,7 @@ "alliance_token_denom", "controller", "governance", + "operator", "oracle", "reward_denom" ], @@ -19,6 +20,9 @@ "governance": { "type": "string" }, + "operator": { + "type": "string" + }, "oracle": { "type": "string" }, diff --git a/contracts/alliance-hub/schema/raw/response_to_config.json b/contracts/alliance-hub/schema/raw/response_to_config.json index dba4984..85b5983 100644 --- a/contracts/alliance-hub/schema/raw/response_to_config.json +++ b/contracts/alliance-hub/schema/raw/response_to_config.json @@ -8,6 +8,7 @@ "controller", "governance", "last_reward_update_timestamp", + "operator", "oracle", "reward_denom" ], @@ -27,6 +28,9 @@ "last_reward_update_timestamp": { "$ref": "#/definitions/Timestamp" }, + "operator": { + "$ref": "#/definitions/Addr" + }, "oracle": { "$ref": "#/definitions/Addr" }, diff --git a/contracts/alliance-hub/src/contract.rs b/contracts/alliance-hub/src/contract.rs index 363feed..c5db057 100644 --- a/contracts/alliance-hub/src/contract.rs +++ b/contracts/alliance-hub/src/contract.rs @@ -181,6 +181,12 @@ pub fn execute( // ExecuteMsg::RebalanceEmissionsCallback {} => rebalance_emissions_callback(deps, env, info), // Allow Governance to overwrite the AssetDistributions for the reward emissions // Generic unsupported handler returns a StdError + ExecuteMsg::UpdateConfig { + governance, + controller, + oracle, + operator, + } => update_config(deps, info, governance, controller, oracle, operator), _ => Err(ContractError::Std(StdError::generic_err( "unsupported action", ))), @@ -655,6 +661,41 @@ fn update_reward_callback( Ok(Response::new().add_attributes(vec![("action", "update_rewards_callback")])) } +fn update_config( + deps: DepsMut, + info: MessageInfo, + governance: Option, + controller: Option, + oracle: Option, + operator: Option, +) -> Result { + let mut config = CONFIG.load(deps.storage)?; + ensure!( + info.sender == config.governance, + ContractError::Unauthorized {} + ); + + if let Some(governance) = governance { + config.governance = deps.api.addr_validate(&governance)?; + } + + if let Some(controller) = controller { + config.controller = deps.api.addr_validate(&controller)?; + } + + if let Some(oracle) = oracle { + config.oracle = deps.api.addr_validate(&oracle)?; + } + + if let Some(operator) = operator { + config.operator = deps.api.addr_validate(&operator)?; + } + + CONFIG.save(deps.storage, &config)?; + + Ok(Response::new().add_attributes(vec![("action", "update_config")])) +} + // fn rebalance_emissions( // deps: DepsMut, // env: Env, diff --git a/contracts/alliance-hub/src/tests/instantiate.rs b/contracts/alliance-hub/src/tests/instantiate.rs index e2779e5..fc9703b 100644 --- a/contracts/alliance-hub/src/tests/instantiate.rs +++ b/contracts/alliance-hub/src/tests/instantiate.rs @@ -1,15 +1,18 @@ -use crate::contract::reply; -use crate::query::query; -use crate::tests::helpers::setup_contract; -use crate::token_factory::{CustomExecuteMsg, DenomUnit, Metadata, TokenExecuteMsg}; -use alliance_protocol::alliance_protocol::{Config, QueryMsg}; -use cosmwasm_std::testing::{mock_dependencies, mock_env}; +use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; use cosmwasm_std::{ from_binary, Addr, Binary, CosmosMsg, Reply, Response, SubMsg, SubMsgResponse, SubMsgResult, Timestamp, Uint128, }; use terra_proto_rs::traits::MessageExt; +use alliance_protocol::alliance_protocol::ExecuteMsg::UpdateConfig; +use alliance_protocol::alliance_protocol::{Config, QueryMsg}; + +use crate::contract::{execute, reply}; +use crate::query::query; +use crate::tests::helpers::setup_contract; +use crate::token_factory::{CustomExecuteMsg, DenomUnit, Metadata, TokenExecuteMsg}; + #[test] fn test_setup_contract() { let mut deps = mock_dependencies(); @@ -18,12 +21,12 @@ fn test_setup_contract() { assert_eq!( res, Response::default() - .add_attributes(vec![("action", "instantiate"),]) + .add_attributes(vec![("action", "instantiate")]) .add_submessage(SubMsg::reply_on_success( CosmosMsg::Custom(CustomExecuteMsg::Token(TokenExecuteMsg::CreateDenom { subdenom: denom.to_string(), })), - 1 + 1, )) ); @@ -116,3 +119,83 @@ fn test_reply_create_token() { } ); } + +#[test] +fn test_update_config() { + let mut deps = mock_dependencies(); + setup_contract(deps.as_mut()); + + let query_config = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); + let Config { + governance, + controller, + oracle, + operator, + .. + } = from_binary(&query_config).unwrap(); + + assert_eq!(governance, Addr::unchecked("gov")); + assert_eq!(controller, Addr::unchecked("controller")); + assert_eq!(oracle, Addr::unchecked("oracle")); + assert_eq!(operator, Addr::unchecked("operator")); + + let msg = UpdateConfig { + governance: Some("new_gov".to_string()), + controller: Some("new_controller".to_string()), + oracle: Some("new_oracle".to_string()), + operator: Some("new_operator".to_string()), + }; + + let result = execute( + deps.as_mut(), + mock_env(), + mock_info("unauthorized", &[]), + msg.clone(), + ); + + if result.is_ok() { + panic!("should be unauthorized") + } + + let result = execute( + deps.as_mut(), + mock_env(), + mock_info("operator", &[]), + msg.clone(), + ); + + if result.is_ok() { + panic!("should be unauthorized") + } + + let result = execute( + deps.as_mut(), + mock_env(), + mock_info("controller", &[]), + msg.clone(), + ); + + if result.is_ok() { + panic!("should be unauthorized") + } + + let result = execute(deps.as_mut(), mock_env(), mock_info("gov", &[]), msg); + + if result.is_err() { + panic!("should be fine") + } + + let query_config = query(deps.as_ref(), mock_env(), QueryMsg::Config {}).unwrap(); + let Config { + governance, + controller, + oracle, + operator, + .. + } = from_binary(&query_config).unwrap(); + + assert_eq!(governance, Addr::unchecked("new_gov")); + assert_eq!(controller, Addr::unchecked("new_controller")); + assert_eq!(oracle, Addr::unchecked("new_oracle")); + assert_eq!(operator, Addr::unchecked("new_operator")); +} diff --git a/packages/alliance-protocol/src/alliance_protocol.rs b/packages/alliance-protocol/src/alliance_protocol.rs index bc68e4a..f405d2f 100644 --- a/packages/alliance-protocol/src/alliance_protocol.rs +++ b/packages/alliance-protocol/src/alliance_protocol.rs @@ -53,6 +53,12 @@ pub enum ExecuteMsg { RebalanceEmissions {}, RebalanceEmissionsCallback {}, SetAssetRewardDistribution(Vec), + UpdateConfig { + governance: Option, + controller: Option, + oracle: Option, + operator: Option, + }, } #[cw_serde]