Skip to content

Commit

Permalink
implemented fine-grained permissions checks for MsgUpdateParams (cron)
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrei Zavgorodnii committed Feb 2, 2024
1 parent 90100ef commit 45d6068
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 6 deletions.
1 change: 1 addition & 0 deletions contracts/dao/neutron-chain-manager/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ serde = {version = "1.0.175", default-features = false, features = ["derive"]}
thiserror = {version = "1.0"}
neutron-sdk = "0.8.0"
serde-json-wasm = "1.0.1"
prost = "0.9.0"

[dev-dependencies]
anyhow = "1.0.57"
Expand Down
31 changes: 26 additions & 5 deletions contracts/dao/neutron-chain-manager/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ use cosmwasm_std::{
};
use cw2::set_contract_version;
use neutron_sdk::bindings::msg::{AdminProposal, NeutronMsg};
use neutron_sdk::stargate::aux::make_stargate_query;
use neutron_sdk::proto_types::neutron::cron::{QueryParamsRequest};

use crate::error::ContractError;
use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, MsgUpdateParamsCron, ProposalExecuteMessageJSON, QueryMsg, Strategy};
use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, MsgUpdateParamsCron, PARAMS_QUERY_PATH_CRON, ParamsRequestCron, ParamsResponseCron, ProposalExecuteMessageJSON, QueryMsg, Strategy};
use crate::state::{STRATEGIES_ALLOW_ALL, STRATEGIES_ALLOW_ONLY};

pub(crate) const CONTRACT_NAME: &str = "crates.io:neutron-chain-manager";
Expand Down Expand Up @@ -41,15 +43,15 @@ pub fn instantiate(
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
deps: DepsMut,
env: Env,
_env: Env,
info: MessageInfo,
msg: ExecuteMsg,
) -> Result<Response<NeutronMsg>, ContractError> {
match msg {
ExecuteMsg::AddStrategy { strategy } => execute_add_strategy(deps, info, strategy),
ExecuteMsg::RemoveStrategy { address } => execute_remove_strategy(deps, info, address),
ExecuteMsg::ExecuteMessages { messages } => {
execute_execute_messages(deps, env, info, messages)
execute_execute_messages(deps, info, messages)
}
}
}
Expand Down Expand Up @@ -112,7 +114,6 @@ pub fn execute_remove_strategy(

pub fn execute_execute_messages(
deps: DepsMut,
_env: Env,
info: MessageInfo,
messages: Vec<CosmosMsg<NeutronMsg>>,
) -> Result<Response<NeutronMsg>, ContractError> {
Expand Down Expand Up @@ -159,7 +160,22 @@ pub fn execute_execute_messages(
match typed_proposal.type_field.as_str() {
"/neutron.cron.MsgUpdateParams" => {
let msg_update_params: MsgUpdateParamsCron = serde_json_wasm::from_str(proposal.message.as_str())?;
println!("{} -------- {}", msg_update_params.params.limit, msg_update_params.params.security_address)

let cron_update_param_permission = strategy.get_cron_update_param_permission()
.ok_or(ContractError::Unauthorized {})?;

let cron_params = get_cron_params(deps.as_ref(), ParamsRequestCron{})?;
if cron_params.params.limit != msg_update_params.params.limit {
if !cron_update_param_permission.limit {
return Err(ContractError::Unauthorized {});
}
}

if cron_params.params.security_address != msg_update_params.params.security_address {
if !cron_update_param_permission.security_address {
return Err(ContractError::Unauthorized {});
}
}
}
_ => {}
}
Expand All @@ -180,6 +196,11 @@ pub fn execute_execute_messages(
.add_messages(messages))
}

/// Queries the parameters of the cron module.
pub fn get_cron_params(deps: Deps, req: ParamsRequestCron) -> StdResult<ParamsResponseCron> {
make_stargate_query(deps, PARAMS_QUERY_PATH_CRON, QueryParamsRequest::from(req))
}

#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
Expand Down
31 changes: 31 additions & 0 deletions contracts/dao/neutron-chain-manager/src/msg.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::{Addr, CosmosMsg};
use neutron_sdk::bindings::msg::{NeutronMsg, ParamChange};
use neutron_sdk::proto_types::neutron::cron::QueryParamsRequest;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -81,6 +82,20 @@ impl Strategy {

false
}

pub fn get_cron_update_param_permission(&self) -> Option<CronUpdateParamsPermission> {
for permission in &self.permissions {
if let Permission::UpdateParamsPermission(update_params_permission) = permission {
return match update_params_permission {
UpdateParamsPermission::CronUpdateParamsPermission(cron_update_params) => {
Some(cron_update_params.clone())
},
}
}
}

None
}
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
Expand Down Expand Up @@ -140,3 +155,19 @@ pub struct ParamsCron {
pub security_address: String,
pub limit: u64,
}

pub const PARAMS_QUERY_PATH_CRON: &str = "/neutron.cron.Query/Params";

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct ParamsRequestCron {}

impl From<ParamsRequestCron> for QueryParamsRequest {
fn from(_: ParamsRequestCron) -> QueryParamsRequest {
QueryParamsRequest {}
}
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct ParamsResponseCron {
pub params: ParamsCron,
}
2 changes: 1 addition & 1 deletion contracts/dao/neutron-chain-manager/src/testing/tests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::contract::{execute_add_strategy, execute_remove_strategy, instantiate};
use crate::error::ContractError::{InvalidDemotion, InvalidInitialStrategy, Unauthorized};
use crate::msg::{CronPermission as CronPermissionType, MsgUpdateParamsCron, ProposalExecuteMessageJSON};
use crate::msg::{CronPermission as CronPermissionType};
use crate::msg::Permission::CronPermission;
use crate::msg::{InstantiateMsg, Strategy};
use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info};
Expand Down

0 comments on commit 45d6068

Please sign in to comment.