Skip to content

Commit

Permalink
dao-proposal-condorcet refractored
Browse files Browse the repository at this point in the history
  • Loading branch information
Abhishek-1857 committed Feb 21, 2024
1 parent f012bad commit 9f59145
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 63 deletions.
11 changes: 7 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 7 additions & 4 deletions contracts/proposal/dao-proposal-condorcet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,20 @@ library = []
[dependencies]
cosmwasm-std = { workspace = true }
cosmwasm-schema = { workspace = true }
cw-storage-plus = { workspace = true }
cw2 = { workspace = true }
cw-utils = { workspace = true }
secret-storage-plus = { workspace = true }
secret-cw2 = { workspace = true }
secret-utils = { workspace = true }
dao-voting = { workspace = true }
dao-dao-macros = { workspace = true }
dao-interface = { workspace = true }
thiserror = { workspace = true }
serde ={ workspace = true }
schemars ={ workspace = true }
secret-toolkit ={ workspace = true }

[dev-dependencies]
cosmwasm-schema = { workspace = true }
cw-multi-test = { workspace = true }
secret-multi-test = { workspace = true }
dao-dao-core = { workspace = true, features = ["library"] }
dao-testing = { workspace = true }
dao-voting-cw4 = { workspace = true }
Expand Down
5 changes: 4 additions & 1 deletion contracts/proposal/dao-proposal-condorcet/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use cosmwasm_schema::cw_serde;
use cw_utils::Duration;
use secret_utils::Duration;
use dao_voting::{
threshold::{validate_quorum, PercentageThreshold},
voting::validate_voting_period,
Expand All @@ -13,6 +13,7 @@ pub struct UncheckedConfig {
pub voting_period: Duration,
pub min_voting_period: Option<Duration>,
pub close_proposals_on_execution_failure: bool,
pub dao_code_hash: String,
}

#[cw_serde]
Expand All @@ -21,6 +22,7 @@ pub(crate) struct Config {
pub voting_period: Duration,
pub min_voting_period: Option<Duration>,
pub close_proposals_on_execution_failure: bool,
pub dao_code_hash: String,
}

impl UncheckedConfig {
Expand All @@ -33,6 +35,7 @@ impl UncheckedConfig {
close_proposals_on_execution_failure: self.close_proposals_on_execution_failure,
voting_period,
min_voting_period,
dao_code_hash: self.dao_code_hash
})
}
}
81 changes: 41 additions & 40 deletions contracts/proposal/dao-proposal-condorcet/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{
to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdResult,
to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdResult,
};

use cw2::set_contract_version;
use secret_cw2::set_contract_version;
use dao_voting::reply::TaggedReplyId;
use dao_voting::voting::{get_total_power, get_voting_power};

Expand Down Expand Up @@ -104,15 +104,14 @@ fn execute_propose(
choices: Vec<Choice>,
) -> Result<Response, ContractError> {
let dao = DAO.load(deps.storage)?;
let sender_voting_power = get_voting_power(deps.as_ref(), info.sender.clone(), &dao, None)?;
let config = CONFIG.load(deps.storage)?;
let sender_voting_power = get_voting_power(deps.as_ref(), config.dao_code_hash.clone(),info.sender.clone(), &dao, None)?;
if sender_voting_power.is_zero() {
return Err(ContractError::ZeroVotingPower {});
}

let config = CONFIG.load(deps.storage)?;

let id = next_proposal_id(deps.storage)?;
let total_power = get_total_power(deps.as_ref(), &dao, None)?;
let total_power = get_total_power(deps.as_ref(), config.dao_code_hash.clone(),&dao, None)?;

if choices.is_empty() {
return Err(ContractError::ZeroChoices {});
Expand All @@ -128,11 +127,11 @@ fn execute_propose(
env.block.height,
config.voting_period.after(&env.block),
);
TALLY.save(deps.storage, id, &tally)?;
TALLY.insert(deps.storage, &id, &tally)?;

let mut proposal = Proposal::new(&env.block, &config, info.sender, id, choices, total_power);
proposal.update_status(&env.block, &tally);
PROPOSAL.save(deps.storage, id, &proposal)?;
PROPOSAL.insert(deps.storage, &id, &proposal)?;

Ok(Response::default()
.add_attribute("method", "propose")
Expand All @@ -147,26 +146,27 @@ fn execute_vote(
proposal_id: u32,
vote: Vec<u32>,
) -> Result<Response, ContractError> {
let tally = TALLY.load(deps.storage, proposal_id)?;
let tally = TALLY.get(deps.storage, &proposal_id);
let sender_power = get_voting_power(
deps.as_ref(),
CONFIG.load(deps.storage)?.dao_code_hash.clone(),
info.sender.clone(),
&DAO.load(deps.storage)?,
Some(tally.start_height),
Some(tally.clone().unwrap().start_height),
)?;
if sender_power.is_zero() {
Err(ContractError::ZeroVotingPower {})
} else if VOTE.has(deps.storage, (proposal_id, info.sender.clone())) {
} else if VOTE.contains(deps.storage, &(proposal_id, info.sender.clone())) {
Err(ContractError::Voted {})
} else if tally.expired(&env.block) {
} else if tally.clone().unwrap().expired(&env.block) {
Err(ContractError::Expired {})
} else {
let vote = Vote::new(vote, tally.candidates())?;
VOTE.save(deps.storage, (proposal_id, info.sender.clone()), &vote)?;
let vote = Vote::new(vote, tally.clone().unwrap().candidates())?;
VOTE.insert(deps.storage, &(proposal_id, info.sender.clone()), &vote)?;

let mut tally = tally;
tally.add_vote(vote, sender_power);
TALLY.save(deps.storage, proposal_id, &tally)?;
let tally = tally;
tally.clone().unwrap().add_vote(vote, sender_power);
TALLY.insert(deps.storage, &proposal_id, &tally.clone().unwrap())?;

Ok(Response::default()
.add_attribute("method", "vote")
Expand All @@ -182,22 +182,23 @@ fn execute_execute(
info: MessageInfo,
proposal_id: u32,
) -> Result<Response, ContractError> {
let tally = TALLY.load(deps.storage, proposal_id)?;
let tally = TALLY.get(deps.storage, &proposal_id);
let dao = DAO.load(deps.storage)?;
let sender_power = get_voting_power(
deps.as_ref(),
CONFIG.load(deps.storage)?.dao_code_hash.clone(),
info.sender.clone(),
&dao,
Some(tally.start_height),
Some(tally.clone().unwrap().start_height),
)?;
if sender_power.is_zero() {
return Err(ContractError::ZeroVotingPower {});
}

let mut proposal = PROPOSAL.load(deps.storage, proposal_id)?;
if let Status::Passed { winner } = proposal.update_status(&env.block, &tally) {
let msgs = proposal.set_executed(dao, winner)?;
PROPOSAL.save(deps.storage, proposal_id, &proposal)?;
let proposal = PROPOSAL.get(deps.storage, &proposal_id);
if let Status::Passed { winner } = proposal.clone().unwrap().update_status(&env.block, &tally.clone().unwrap()) {
let msgs = proposal.clone().unwrap().set_executed(dao, CONFIG.load(deps.storage)?.dao_code_hash.clone(),winner)?;
PROPOSAL.insert(deps.storage,&proposal_id, &proposal.clone().unwrap())?;

Ok(Response::default()
.add_attribute("method", "execute")
Expand All @@ -215,11 +216,11 @@ fn execute_close(
info: MessageInfo,
proposal_id: u32,
) -> Result<Response, ContractError> {
let tally = TALLY.load(deps.storage, proposal_id)?;
let mut proposal = PROPOSAL.load(deps.storage, proposal_id)?;
if let Status::Rejected = proposal.update_status(&env.block, &tally) {
proposal.set_closed();
PROPOSAL.save(deps.storage, proposal_id, &proposal)?;
let tally = TALLY.get(deps.storage, &proposal_id);
let proposal = PROPOSAL.get(deps.storage, &proposal_id);
if let Status::Rejected = proposal.clone().unwrap().update_status(&env.block, &tally.unwrap()) {
proposal.clone().unwrap().set_closed();
PROPOSAL.insert(deps.storage, &proposal_id, &proposal.clone().unwrap())?;

Ok(Response::default()
.add_attribute("method", "close")
Expand Down Expand Up @@ -249,16 +250,16 @@ fn execute_set_config(
pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
match msg {
QueryMsg::Proposal { id } => {
let mut proposal = PROPOSAL.load(deps.storage, id)?;
let tally = TALLY.load(deps.storage, id)?;
proposal.update_status(&env.block, &tally);
to_json_binary(&ProposalResponse { proposal, tally })
let proposal = PROPOSAL.get(deps.storage, &id);
let tally = TALLY.get(deps.storage, &id);
proposal.clone().unwrap().update_status(&env.block, &tally.clone().unwrap());
to_binary(&ProposalResponse { proposal:proposal.unwrap(), tally:tally.unwrap() })
}
QueryMsg::Config {} => to_json_binary(&CONFIG.load(deps.storage)?),
QueryMsg::NextProposalId {} => to_json_binary(&next_proposal_id(deps.storage)?),
QueryMsg::Dao {} => to_json_binary(&DAO.load(deps.storage)?),
QueryMsg::Info {} => to_json_binary(&dao_interface::voting::InfoResponse {
info: cw2::get_contract_version(deps.storage)?,
QueryMsg::Config {} => to_binary(&CONFIG.load(deps.storage)?),
QueryMsg::NextProposalId {} => to_binary(&next_proposal_id(deps.storage)?),
QueryMsg::Dao {} => to_binary(&DAO.load(deps.storage)?),
QueryMsg::Info {} => to_binary(&dao_interface::voting::InfoResponse {
info: secret_cw2::get_contract_version(deps.storage)?,
}),
}
}
Expand All @@ -268,9 +269,9 @@ pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result<Response, ContractE
let repl = TaggedReplyId::new(msg.id)?;
match repl {
TaggedReplyId::FailedProposalExecution(proposal_id) => {
let mut proposal = PROPOSAL.load(deps.storage, proposal_id as u32)?;
proposal.set_execution_failed();
PROPOSAL.save(deps.storage, proposal_id as u32, &proposal)?;
let proposal = PROPOSAL.get(deps.storage, &(proposal_id as u32));
proposal.clone().unwrap().set_execution_failed();
PROPOSAL.insert(deps.storage, &(proposal_id as u32), &proposal.clone().unwrap())?;

Ok(Response::default()
.add_attribute("proposal_execution_failed", proposal_id.to_string())
Expand Down
4 changes: 2 additions & 2 deletions contracts/proposal/dao-proposal-condorcet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ pub mod proposal;
pub mod state;
pub mod tally;

#[cfg(test)]
mod testing;
// #[cfg(test)]
// mod testing;

pub mod vote;

Expand Down
9 changes: 5 additions & 4 deletions contracts/proposal/dao-proposal-condorcet/src/proposal.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{to_json_binary, Addr, BlockInfo, StdResult, SubMsg, Uint128, WasmMsg};
use cw_utils::Expiration;
use cosmwasm_std::{to_binary, Addr, BlockInfo, StdResult, SubMsg, Uint128, WasmMsg};
use secret_utils::Expiration;
use dao_voting::{
reply::mask_proposal_execution_proposal_id, threshold::PercentageThreshold,
voting::does_vote_count_pass,
Expand Down Expand Up @@ -153,15 +153,16 @@ impl Proposal {

/// Sets the proposal's status to executed and returns a
/// submessage to be executed.
pub(crate) fn set_executed(&mut self, dao: Addr, winner: u32) -> StdResult<SubMsg> {
pub(crate) fn set_executed(&mut self, dao: Addr,dao_code_hash: String, winner: u32) -> StdResult<SubMsg> {
debug_assert_eq!(self.last_status, Status::Passed { winner });

self.last_status = Status::Executed;

let msgs = self.choices[winner as usize].msgs.clone();
let core_exec = WasmMsg::Execute {
code_hash:dao_code_hash,
contract_addr: dao.into_string(),
msg: to_json_binary(&dao_interface::msg::ExecuteMsg::ExecuteProposalHook { msgs })?,
msg: to_binary(&dao_interface::msg::ExecuteMsg::ExecuteProposalHook { msgs })?,
funds: vec![],
};
Ok(if self.close_on_execution_failure {
Expand Down
12 changes: 6 additions & 6 deletions contracts/proposal/dao-proposal-condorcet/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
use cosmwasm_std::{Addr, StdResult, Storage};
use cw_storage_plus::{Item, Map};
use secret_storage_plus::Item;
use secret_toolkit::{serialization::Json, storage::Keymap};

use crate::{config::Config, proposal::Proposal, tally::Tally, vote::Vote};

pub(crate) const DAO: Item<Addr> = Item::new("dao");
pub(crate) const CONFIG: Item<Config> = Item::new("config");

pub(crate) const TALLY: Map<u32, Tally> = Map::new("tallys");
pub(crate) const PROPOSAL: Map<u32, Proposal> = Map::new("proposals");
pub(crate) const VOTE: Map<(u32, Addr), Vote> = Map::new("votes");
pub(crate) const TALLY: Keymap<u32, Tally,Json> = Keymap::new(b"tallys");
pub(crate) const PROPOSAL: Keymap<u32, Proposal,Json> = Keymap::new(b"proposals");
pub(crate) const VOTE: Keymap<(u32, Addr), Vote,Json> = Keymap::new(b"votes");

pub(crate) fn next_proposal_id(storage: &dyn Storage) -> StdResult<u32> {
PROPOSAL
.keys(storage, None, None, cosmwasm_std::Order::Descending)
PROPOSAL.iter_keys(storage)?
.next()
.transpose()
.map(|id| id.unwrap_or(0) + 1)
Expand Down
2 changes: 1 addition & 1 deletion contracts/proposal/dao-proposal-condorcet/src/tally.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{BlockInfo, Uint128};
use cw_utils::Expiration;
use secret_utils::Expiration;

use crate::{
m::{Stats, M},
Expand Down
2 changes: 1 addition & 1 deletion contracts/proposal/dao-proposal-multiple/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub struct InstantiateMsg {
pub veto: Option<VetoConfig>,

// dao code hash
pub code_hash: String
pub code_hash: String
}

#[cw_serde]
Expand Down

0 comments on commit 9f59145

Please sign in to comment.