From f34f7a218516c68e81d468058b7ac3ebe971b184 Mon Sep 17 00:00:00 2001 From: groundedsage Date: Thu, 13 Mar 2025 17:28:35 +0800 Subject: [PATCH 1/3] Register for OpenGuild FRAME Challenges --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c0ca209..b0ebdbc 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ git clone https://github.com/openguild-labs/frame-challenges.git Go to **Participant Registration** section and register to be the workshop participants. Add the below to the list, replace any placeholder with your personal information. ``` -| 🦄 | Name | Github username | Your current occupation | +| 🦄 | Wade | groundedsage | Software Engineer | ``` - Step 5: `Commit` your code and push to the forked Github repository From 3a3aeb340d39467ef555930abf964ded7d6cc548 Mon Sep 17 00:00:00 2001 From: groundedsage Date: Thu, 13 Mar 2025 19:01:31 +0800 Subject: [PATCH 2/3] add staking --- src/staking.rs | 50 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/src/staking.rs b/src/staking.rs index 7bd646e..4313afe 100644 --- a/src/staking.rs +++ b/src/staking.rs @@ -16,32 +16,64 @@ pub struct StakingPallet { impl StakingPallet { pub fn new() -> Self { - todo!() - } + StakingPallet { + 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, amount); } // Stake tokens (move from free to staked) pub fn stake(&mut self, who: T::AccountId, amount: T::Balance) -> Result<(), &'static str> { - todo!() + + // Subtract the amount from the free balance + let free_balance = self.free_balances.get(&who).copied().unwrap_or_else(T::Balance::zero); + let new_free_balance = free_balance.checked_sub(&amount).ok_or("Not enough free balance to stake")?; + self.free_balances.insert(who.clone(), new_free_balance); + + // Add the amount to the staked balance + let staked_balance = self.staked_balances.get(&who).copied().unwrap_or_else(T::Balance::zero); + let new_staked_balance = staked_balance.checked_add(&amount).ok_or("Overflow in staking")?; + self.staked_balances.insert(who, new_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!() - } +pub fn unstake(&mut self, who: T::AccountId, amount: T::Balance) -> Result<(), &'static str> { + + let new_staked_balance = self.staked_balances + .get(&who) + .copied() + .unwrap_or_else(T::Balance::zero) + .checked_sub(&amount) + .ok_or("Not enough staked balance to unstake")?; + + let new_free_balance = self.free_balances + .get(&who) + .copied() + .unwrap_or_else(T::Balance::zero) + .checked_add(&amount) + .ok_or("Overflow in unstaking")?; + + self.staked_balances.insert(who.clone(), new_staked_balance); + self.free_balances.insert(who, new_free_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).cloned().unwrap_or_else(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).copied().unwrap_or_else(T::Balance::zero) } } From 16614a038aa59f0deedee4b496e1768a88f4db20 Mon Sep 17 00:00:00 2001 From: groundedsage Date: Thu, 13 Mar 2025 22:43:12 +0800 Subject: [PATCH 3/3] add governance --- src/governance.rs | 58 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/src/governance.rs b/src/governance.rs index f71f10b..6764192 100644 --- a/src/governance.rs +++ b/src/governance.rs @@ -26,7 +26,11 @@ pub struct GovernancePallet { impl GovernancePallet { pub fn new() -> Self { - todo!() + Self { + proposals: HashMap::new(), + votes: HashMap::new(), + next_proposal_id: 0 + } } // Create a new proposal @@ -35,7 +39,18 @@ impl GovernancePallet { creator: T::AccountId, description: String, ) -> Result { - todo!() + let proposal_id = self.next_proposal_id; + self.next_proposal_id += 1; + + let proposal = Proposal { + description, + yes_votes: 0, + no_votes: 0, + status: ProposalStatus::Active, + }; + + self.proposals.insert(proposal_id, proposal); + Ok(proposal_id) } // Vote on a proposal (true = yes, false = no) @@ -45,17 +60,50 @@ impl GovernancePallet { proposal_id: u32, vote_type: bool, ) -> Result<(), &'static str> { - todo!() + let proposal = self.proposals.get_mut(&proposal_id).ok_or("Proposal does not exist")?; + + if !matches!(proposal.status, ProposalStatus::Active) { + return Err("Proposal is not active"); + } + + let vote_key = (voter.clone(), proposal_id); + if self.votes.contains_key(&vote_key) { + return Err("Voter has already voted on this proposal"); + } + + self.votes.insert(vote_key, vote_type); + + if vote_type { + proposal.yes_votes += 1; + } else { + proposal.no_votes += 1; + } + + 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 { - todo!() + let proposal = self.proposals.get_mut(&proposal_id).ok_or("Proposal doesn't exist")?; + + // Ensure the proposal is active before finalizing. + if !matches!(proposal.status, ProposalStatus::Active) { + return Err("Proposal already finalized") + }; + + let new_status = if proposal.yes_votes > proposal.no_votes { + ProposalStatus::Approved + } else { + ProposalStatus::Rejected + }; + + proposal.status = new_status.clone(); + Ok(new_status) } }