Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,11 @@ OpenGuild is a builder-driven community centered around Polkadot. OpenGuild is b
- **Website:** [OpenGuild Website](https://openguild.wtf/)
- **Github:** [OpenGuild Labs](https://github.com/openguild-labs)
- **Discord**: [Openguild Discord Channel](https://discord.gg/bcjMzxqtD7)

## Participant Registration

Add your information to the below list to officially participate in the workshop challenge (This is the first mission of the whole workshop)

| Emoji | Name | Github Username | Occupations |
| ----- | --------------- | ----------------------------------------------------- | ------------------------ |
| 🦁 | Aji Guruh Prasetyo | [ajiguruhprasetyo](https://github.com/ajiguruhprasetyo) | Software Engineer |
83 changes: 75 additions & 8 deletions src/governance.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use crate::staking::StakingConfig;
use crate::system::SystemConfig;
use std::collections::HashMap;

pub trait GovernanceConfig: StakingConfig {}

pub struct Proposal {
Expand All @@ -25,17 +23,33 @@ pub struct GovernancePallet<T: GovernanceConfig> {
}

impl<T: GovernanceConfig> GovernancePallet<T> {
// Create a new instance of the governance pallet
pub fn new() -> Self {
todo!()
Self {
proposals: HashMap::new(),
votes: HashMap::new(),
next_proposal_id: 0,
}
}

// Create a new proposal
pub fn create_proposal(
&mut self,
creator: T::AccountId,
_creator: T::AccountId,
description: String,
) -> Result<u32, &'static str> {
todo!()
self.next_proposal_id += 1;

self.proposals.insert(
self.next_proposal_id,
Proposal {
description,
yes_votes: 0,
no_votes: 0,
status: ProposalStatus::Active,
},
);
Ok(self.next_proposal_id)
}

// Vote on a proposal (true = yes, false = no)
Expand All @@ -45,17 +59,70 @@ impl<T: GovernanceConfig> GovernancePallet<T> {
proposal_id: u32,
vote_type: bool,
) -> Result<(), &'static str> {
todo!()
if self.votes.contains_key(&(voter.clone(), proposal_id)) {
return Err("You can only vote once");
}

if !self.proposals.contains_key(&proposal_id) {
return Err("the proposal data doesn't exist");
}

self.votes.insert((voter, proposal_id), vote_type);
let validate_proposal = self.get_proposal(proposal_id).expect("Proposal not found");

let yes_votes = if vote_type {
validate_proposal.yes_votes + 1
} else {
validate_proposal.yes_votes
};
let no_votes = if !vote_type {
validate_proposal.no_votes + 1
} else {
validate_proposal.no_votes
};

let result_proposal = Proposal {
description: validate_proposal.description.clone(),
yes_votes,
no_votes,
status: validate_proposal.status.clone(),
};

self.proposals.insert(proposal_id, result_proposal);

Ok(())
}

// Get proposal details
pub fn get_proposal(&self, proposal_id: u32) -> Option<&Proposal> {
todo!()
self.proposals.get(&proposal_id)
}

// Finalize a proposal (changes status based on votes)
pub fn finalize_proposal(&mut self, proposal_id: u32) -> Result<ProposalStatus, &'static str> {
todo!()
let data_proposal = self
.get_proposal(proposal_id)
.expect("could not found the proposal");

let yes_votes = data_proposal.yes_votes;
let no_votes = data_proposal.no_votes;

let status = if yes_votes > no_votes {
ProposalStatus::Approved
} else {
ProposalStatus::Rejected
};

let result_proposal = Proposal {
description: data_proposal.description.clone(),
yes_votes,
no_votes,
status: status.clone(),
};

self.proposals.insert(proposal_id, result_proposal);

Ok(status)
}
}

Expand Down
44 changes: 38 additions & 6 deletions src/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,64 @@ pub struct StakingPallet<T: StakingConfig> {

impl<T: StakingConfig> StakingPallet<T> {
pub fn new() -> Self {
todo!()
Self {
free_balances: HashMap::new(),
staked_balances: HashMap::new(),
}
}

// Set free balance for an account
pub fn set_balance(&mut self, who: T::AccountId, amount: T::Balance) {
todo!()
self.free_balances.insert(who.clone(), amount);
}

// Stake tokens (move from free to staked)
pub fn stake(&mut self, who: T::AccountId, amount: T::Balance) -> Result<(), &'static str> {
todo!()
let data_free_balance = self.get_free_balance(who.clone());
let data_staked_balance = self.get_staked_balance(who.clone());

let validate_free_balance = data_free_balance
.checked_sub(&amount)
.ok_or("not enough funds")?;
let validate_staked_balance = data_staked_balance.checked_add(&amount).ok_or("overflow")?;

self.free_balances
.insert(who.clone(), validate_free_balance);
self.staked_balances
.insert(who.clone(), validate_staked_balance);

Ok(())
}

// Unstake tokens (move from staked to free)
pub fn unstake(&mut self, who: T::AccountId, amount: T::Balance) -> Result<(), &'static str> {
todo!()
let data_staked_balance = self.get_staked_balance(who.clone());
let data_free_balance = self.get_free_balance(who.clone());

let validate_staked_balance = data_staked_balance
.checked_sub(&amount)
.ok_or("not enough funds")?;
let validate_free_balance = data_free_balance.checked_add(&amount).ok_or("overvlow")?;

self.free_balances
.insert(who.clone(), validate_free_balance);
self.staked_balances
.insert(who.clone(), validate_staked_balance);

Ok(())
}

// Get free balance for an account
pub fn get_free_balance(&self, who: T::AccountId) -> T::Balance {
todo!()
*self.free_balances.get(&who).unwrap_or(&T::Balance::zero())
}

// Get staked balance for an account
pub fn get_staked_balance(&self, who: T::AccountId) -> T::Balance {
todo!()
*self
.staked_balances
.get(&who)
.unwrap_or(&T::Balance::zero())
}
}

Expand Down