From 2a219e96b76096f396d0a4113c95b65ddbe427de Mon Sep 17 00:00:00 2001 From: Noah Saso Date: Fri, 17 Nov 2023 15:40:52 -0800 Subject: [PATCH] Added message to reset approver back to DAO. --- .../schema/dao-pre-propose-approver.json | 21 +++++++-- .../dao-pre-propose-approver/src/contract.rs | 45 ++++++++++++++++++- .../dao-pre-propose-approver/src/msg.rs | 9 +++- 3 files changed, 68 insertions(+), 7 deletions(-) diff --git a/contracts/pre-propose/dao-pre-propose-approver/schema/dao-pre-propose-approver.json b/contracts/pre-propose/dao-pre-propose-approver/schema/dao-pre-propose-approver.json index ca05753e2..47d39b0f3 100644 --- a/contracts/pre-propose/dao-pre-propose-approver/schema/dao-pre-propose-approver.json +++ b/contracts/pre-propose/dao-pre-propose-approver/schema/dao-pre-propose-approver.json @@ -115,7 +115,7 @@ ], "properties": { "msg": { - "$ref": "#/definitions/Empty" + "$ref": "#/definitions/ExecuteExt" } }, "additionalProperties": false @@ -298,9 +298,22 @@ } ] }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" + "ExecuteExt": { + "oneOf": [ + { + "type": "object", + "required": [ + "reset_approver" + ], + "properties": { + "reset_approver": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] }, "Status": { "oneOf": [ diff --git a/contracts/pre-propose/dao-pre-propose-approver/src/contract.rs b/contracts/pre-propose/dao-pre-propose-approver/src/contract.rs index cc59550c1..05c2a4a38 100644 --- a/contracts/pre-propose/dao-pre-propose-approver/src/contract.rs +++ b/contracts/pre-propose/dao-pre-propose-approver/src/contract.rs @@ -14,14 +14,15 @@ use dao_pre_propose_base::{error::PreProposeError, state::PreProposeContract}; use dao_voting::status::Status; use crate::msg::{ - BaseInstantiateMsg, ExecuteMsg, InstantiateMsg, ProposeMessageInternal, QueryExt, QueryMsg, + BaseInstantiateMsg, ExecuteExt, ExecuteMsg, InstantiateMsg, ProposeMessageInternal, QueryExt, + QueryMsg, }; use crate::state::{PRE_PROPOSE_APPROVAL_CONTRACT, PROPOSAL_ID_TO_PRE_PROPOSE_ID}; pub(crate) const CONTRACT_NAME: &str = "crates.io:dao-pre-propose-approver"; pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); -type PrePropose = PreProposeContract; +type PrePropose = PreProposeContract; #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( @@ -86,6 +87,9 @@ pub fn execute( proposal_id, new_status, } => execute_proposal_completed(deps, info, proposal_id, new_status), + ExecuteMsg::Extension { msg } => match msg { + ExecuteExt::ResetApprover {} => execute_reset_approver(deps, env, info), + }, _ => PrePropose::default().execute(deps, env, info, msg), } } @@ -181,6 +185,43 @@ pub fn execute_proposal_completed( } } +pub fn execute_reset_approver( + deps: DepsMut, + env: Env, + info: MessageInfo, +) -> Result { + // Check that this is coming from the DAO. + let dao = PrePropose::default().dao.load(deps.storage)?; + if info.sender != dao { + return Err(PreProposeError::Unauthorized {}); + } + + let pre_propose_approval_contract = PRE_PROPOSE_APPROVAL_CONTRACT.load(deps.storage)?; + + let reset_messages = vec![ + // Set pre-propose-approval approver to the DAO. + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: pre_propose_approval_contract.to_string(), + msg: to_binary(&PreProposeApprovalExecuteMsg::Extension { + msg: ApprovalExt::UpdateApprover { + address: dao.to_string(), + }, + })?, + funds: vec![], + }), + // Remove the proposal submitted hook. + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: pre_propose_approval_contract.to_string(), + msg: to_binary(&PreProposeApprovalExecuteMsg::RemoveProposalSubmittedHook { + address: env.contract.address.to_string(), + })?, + funds: vec![], + }), + ]; + + Ok(Response::default().add_messages(reset_messages)) +} + #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { match msg { diff --git a/contracts/pre-propose/dao-pre-propose-approver/src/msg.rs b/contracts/pre-propose/dao-pre-propose-approver/src/msg.rs index dd9f72e51..b61d9a6fe 100644 --- a/contracts/pre-propose/dao-pre-propose-approver/src/msg.rs +++ b/contracts/pre-propose/dao-pre-propose-approver/src/msg.rs @@ -10,6 +10,13 @@ pub struct InstantiateMsg { pub pre_propose_approval_contract: String, } +#[cw_serde] +pub enum ExecuteExt { + // Reset approver back to DAO that set up this approver contract. Only + // callable by the DAO. + ResetApprover {}, +} + #[cw_serde] #[derive(QueryResponses)] pub enum QueryExt { @@ -20,7 +27,7 @@ pub enum QueryExt { } pub type BaseInstantiateMsg = InstantiateBase; -pub type ExecuteMsg = ExecuteBase; +pub type ExecuteMsg = ExecuteBase; pub type QueryMsg = QueryBase; /// Internal version of the propose message that includes the