Skip to content

Commit

Permalink
Add implementation for create_proposal and vote
Browse files Browse the repository at this point in the history
  • Loading branch information
tupui committed Nov 23, 2024
1 parent 0b87885 commit 78b8e2c
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 7 deletions.
77 changes: 73 additions & 4 deletions contracts/versioning/src/contract_dao.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use soroban_sdk::{contractimpl, panic_with_error, Address, Bytes, Env, String};
use soroban_sdk::{contractimpl, panic_with_error, vec, Address, Bytes, Env, String, Vec};

use crate::{errors, types, DaoTrait, Tansu, TansuClient};

Expand All @@ -12,10 +12,79 @@ impl DaoTrait for Tansu {
ipfs: String,
voting_ends_at: u64,
) -> u32 {
1
let key_ = types::ProjectKey::Key(project_key.clone());
if let Some(project) = env
.storage()
.persistent()
.get::<types::ProjectKey, types::Project>(&key_)
{
crate::auth_maintainers(&env, &proposer, &project.maintainers);

let proposal_id = env
.storage()
.persistent()
.get(&types::ProjectKey::DaoTotalProposals(project_key.clone()))
.unwrap_or(0);

let voters_abstain = vec![&env, proposer];
let proposal = types::Proposal {
id: proposal_id,
title,
ipfs,
voting_ends_at,
voters_approve: Vec::new(&env),
voters_reject: Vec::new(&env),
voters_abstain,
nqg: 0,
status: types::ProposalStatus::Active,
};

let next_id = proposal_id + 1;
env.storage().persistent().set(
&types::ProjectKey::DaoTotalProposals(project_key.clone()),
&next_id,
);

let page = proposal_id.div_ceil(10);
let mut dao_page = <Tansu as DaoTrait>::get_dao(env.clone(), project_key.clone(), page);
let mut proposals = dao_page.proposals.unwrap_or(Vec::new(&env));
proposals.push_back(proposal);

dao_page.proposals = Some(proposals);

env.storage().persistent().set(
&types::ProjectKey::Dao(project_key.clone(), page),
&dao_page,
);

proposal_id
} else {
panic_with_error!(&env, &errors::ContractErrors::InvalidKey);
}
}

fn vote(env: Env, voter: Address, project_key: Bytes, proposal_id: u32, vote: bool) {}
fn vote(env: Env, voter: Address, project_key: Bytes, proposal_id: u32, vote: types::Vote) {
voter.require_auth();
let mut proposal =
<Tansu as DaoTrait>::get_proposal(env.clone(), project_key.clone(), proposal_id);
// only allow to vote once per voter
if proposal.voters_approve.contains(&voter)
| proposal.voters_reject.contains(&voter)
| proposal.voters_abstain.contains(&voter)
{
panic_with_error!(&env, &errors::ContractErrors::AlreadyVoted);
} else {
match vote {
types::Vote::Approve => proposal.voters_approve.push_back(voter),
types::Vote::Reject => proposal.voters_reject.push_back(voter),
types::Vote::Abstain => proposal.voters_abstain.push_back(voter),
}
let page = proposal_id.div_ceil(10); // round up
env.storage()
.persistent()
.set(&types::ProjectKey::Dao(project_key, page), &proposal)
}
}

fn get_dao(env: Env, project_key: Bytes, page: u32) -> types::Dao {
let key_ = types::ProjectKey::Key(project_key.clone());
Expand All @@ -37,7 +106,7 @@ impl DaoTrait for Tansu {
}

fn get_proposal(env: Env, project_key: Bytes, proposal_id: u32) -> types::Proposal {
let page = proposal_id / 10; // round down
let page = proposal_id.div_ceil(10); // round up
let sub_id = proposal_id % 10;
let dao_page = <Tansu as DaoTrait>::get_dao(env.clone(), project_key, page);
let proposals = dao_page.proposals.unwrap_or_else(|| {
Expand Down
1 change: 1 addition & 0 deletions contracts/versioning/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ pub enum ContractErrors {
MaintainerNotDomainOwner = 6,
// DAO
NoProposalorPageFound = 7,
AlreadyVoted = 8,
}
16 changes: 13 additions & 3 deletions contracts/versioning/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,28 @@ pub enum DataKey {
#[contracttype]
pub enum ProposalStatus {
Active,
Accepted,
Approved,
Rejected,
Cancelled,
}

#[contracttype]
pub enum Vote {
Approve,
Reject,
Abstain,
}

#[contracttype]
pub struct Proposal {
pub id: u32,
pub title: String,
pub ipfs: String,
pub voting_ends_at: u64,
pub votes_for: Vec<Address>,
pub votes_against: Vec<Address>,
pub voters_approve: Vec<Address>,
pub voters_reject: Vec<Address>,
pub voters_abstain: Vec<Address>,
pub nqg: u32,
pub status: ProposalStatus,
}

Expand All @@ -34,6 +43,7 @@ pub enum ProjectKey {
Key(Bytes), // UUID of the project from keccak256(name)
LastHash(Bytes), // last hash of the project
Dao(Bytes, u32), // Decentralized organization, pagination
DaoTotalProposals(Bytes),
}

#[contracttype]
Expand Down

0 comments on commit 78b8e2c

Please sign in to comment.