Skip to content

Commit

Permalink
Allow admin to pause/unpause subdao
Browse files Browse the repository at this point in the history
Also fixed some typos and removed unused msg.rs from dao-dao-core
  • Loading branch information
ismellike committed Sep 7, 2023
1 parent bf3ef9c commit 996328f
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 247 deletions.
35 changes: 30 additions & 5 deletions contracts/dao-dao-core/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,16 @@ pub fn execute(
msg: ExecuteMsg,
) -> Result<Response, ContractError> {
// No actions can be performed while the DAO is paused.
if let Some(expiration) = PAUSED.may_load(deps.storage)? {
if !expiration.is_expired(&env.block) {
return Err(ContractError::Paused {});
match &msg {
&ExecuteMsg::Unpause {} => {
// Allow the unpause action to pass through
}
_ => {
if let Some(expiration) = PAUSED.may_load(deps.storage)? {
if !expiration.is_expired(&env.block) {
return Err(ContractError::Paused {});
}
}
}
}

Expand All @@ -121,6 +128,7 @@ pub fn execute(
execute_proposal_hook(deps.as_ref(), info.sender, msgs)
}
ExecuteMsg::Pause { duration } => execute_pause(deps, env, info.sender, duration),
ExecuteMsg::Unpause {} => execute_unpause(deps, env, info.sender),
ExecuteMsg::Receive(_) => execute_receive_cw20(deps, info.sender),
ExecuteMsg::ReceiveNft(_) => execute_receive_cw721(deps, info.sender),
ExecuteMsg::RemoveItem { key } => execute_remove_item(deps, env, info.sender, key),
Expand Down Expand Up @@ -159,8 +167,10 @@ pub fn execute_pause(
sender: Addr,
pause_duration: Duration,
) -> Result<Response, ContractError> {
// Only the core contract may call this method.
if sender != env.contract.address {
let admin = ADMIN.load(deps.storage)?;

// Only the core contract or admin may call this method.
if sender != env.contract.address && sender != admin {
return Err(ContractError::Unauthorized {});
}

Expand All @@ -174,6 +184,21 @@ pub fn execute_pause(
.add_attribute("until", until.to_string()))
}

pub fn execute_unpause(deps: DepsMut, env: Env, sender: Addr) -> Result<Response, ContractError> {
let admin = ADMIN.load(deps.storage)?;

// Only the admin may call this method excluding the core contract.
if sender != admin || sender == env.contract.address {
return Err(ContractError::Unauthorized {});
}

PAUSED.remove(deps.storage);

Ok(Response::new()
.add_attribute("action", "execute_unpause")
.add_attribute("sender", sender))
}

pub fn execute_admin_msgs(
deps: Deps,
sender: Addr,
Expand Down
240 changes: 0 additions & 240 deletions contracts/dao-dao-core/src/msg.rs

This file was deleted.

50 changes: 48 additions & 2 deletions contracts/dao-dao-core/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1044,7 +1044,7 @@ fn test_admin_permissions() {
);
res.unwrap_err();

// Proposal mdoule can't call ExecuteAdminMsgs
// Proposal module can't call ExecuteAdminMsgs
let res = app.execute_contract(
proposal_module.address.clone(),
core_addr.clone(),
Expand Down Expand Up @@ -1117,7 +1117,7 @@ fn test_admin_permissions() {
);
res.unwrap_err();

// Admin can call ExecuteAdminMsgs, here an admin pasues the DAO
// Admin can call ExecuteAdminMsgs, here an admin pauses the DAO
let res = app.execute_contract(
Addr::unchecked("admin"),
core_with_admin_addr.clone(),
Expand Down Expand Up @@ -1150,6 +1150,52 @@ fn test_admin_permissions() {
// DAO unpauses after 10 blocks
app.update_block(|block| block.height += 11);

// Admin can directly pause the DAO
let res = app.execute_contract(
Addr::unchecked("admin"),
core_with_admin_addr.clone(),
&ExecuteMsg::Pause {
duration: Duration::Height(10),
},
&[],
);
res.unwrap();

let paused: PauseInfoResponse = app
.wrap()
.query_wasm_smart(core_with_admin_addr.clone(), &QueryMsg::PauseInfo {})
.unwrap();
assert_eq!(
paused,
PauseInfoResponse::Paused {
expiration: Expiration::AtHeight(start_height + 21)
}
);

// Admin can unpause the DAO
let res = app.execute_contract(
Addr::unchecked("admin"),
core_with_admin_addr.clone(),
&ExecuteMsg::Unpause {},
&[],
);
res.unwrap();

let paused: PauseInfoResponse = app
.wrap()
.query_wasm_smart(core_with_admin_addr.clone(), &QueryMsg::PauseInfo {})
.unwrap();
assert_eq!(paused, PauseInfoResponse::Unpaused {});

// DAO cannot unpause itself
let res = app.execute_contract(
core_with_admin_addr.clone(),
core_with_admin_addr.clone(),
&ExecuteMsg::Unpause {},
&[],
);
assert!(res.is_err());

// Admin can nominate a new admin.
let res = app.execute_contract(
Addr::unchecked("admin"),
Expand Down
2 changes: 2 additions & 0 deletions packages/dao-interface/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ pub enum ExecuteMsg {
/// Pauses the DAO for a set duration.
/// When paused the DAO is unable to execute proposals
Pause { duration: Duration },
/// Unpauses the DAO
Unpause {},
/// Executed when the contract receives a cw20 token. Depending on
/// the contract's configuration the contract will automatically
/// add the token to its treasury.
Expand Down

0 comments on commit 996328f

Please sign in to comment.