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
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ After learning about Substrate, FRAME, Runtime, and Pallets in Polkadot SDK, thi
### Project Structure

This challenge simulates three core components:

- `system.rs`: Foundation module similar to `frame_system`
- `staking.rs`: Token staking module similar to `pallet_staking`
- `governance.rs`: On-chain proposal system similar to `pallet_collective` or `pallet_democracy`
Expand Down Expand Up @@ -94,3 +95,8 @@ 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

| 🦄 | Name | Github username | Your current occupation |
| 🦄 | I Gusti Agung Ramananda Wira Dharma | [agungramananda](https://github.com/agungramananda) | Computer Science Student |
60 changes: 54 additions & 6 deletions src/governance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub struct Proposal {
status: ProposalStatus,
}

#[derive(Clone)]
#[derive(Clone,PartialEq)]
pub enum ProposalStatus {
Active,
Approved,
Expand All @@ -26,7 +26,11 @@ pub struct GovernancePallet<T: GovernanceConfig> {

impl<T: GovernanceConfig> GovernancePallet<T> {
pub fn new() -> Self {
todo!()
Self {
proposals : HashMap::new(),
votes : HashMap::new(),
next_proposal_id: 0,
}
}

// Create a new proposal
Expand All @@ -35,7 +39,18 @@ impl<T: GovernanceConfig> GovernancePallet<T> {
creator: T::AccountId,
description: String,
) -> Result<u32, &'static str> {
todo!()
let proposal_id = self.next_proposal_id;
let new_proposal = Proposal {
description,
yes_votes : 0,
no_votes : 0,
status : ProposalStatus::Active,
};

self.proposals.insert(proposal_id, new_proposal);
self.next_proposal_id += 1;

Ok(proposal_id)
}

// Vote on a proposal (true = yes, false = no)
Expand All @@ -45,17 +60,50 @@ impl<T: GovernanceConfig> GovernancePallet<T> {
proposal_id: u32,
vote_type: bool,
) -> Result<(), &'static str> {
todo!()
if !self.proposals.contains_key(&proposal_id){
return Err("Proposal not found");
}

if self.votes.contains_key(&(voter.clone(), proposal_id)){
return Err("Has already voted on this proposal");
}

let proposal = self.proposals.get_mut(&proposal_id).unwrap();

if vote_type {
proposal.yes_votes += 1;
} else {
proposal.no_votes += 1;
}

self.votes.insert((voter,proposal_id), vote_type);
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!()
if !self.proposals.contains_key(&proposal_id){
return Err("Proposal not found");
}

let proposal = self.proposals.get_mut(&proposal_id).unwrap();

if proposal.status != ProposalStatus::Active {
return Err("Proposal is not active and already finalized");
}

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

Ok(proposal.status.clone())
}
}

Expand Down
41 changes: 35 additions & 6 deletions src/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,61 @@ 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,amount);
}

// Stake tokens (move from free to staked)
pub fn stake(&mut self, who: T::AccountId, amount: T::Balance) -> Result<(), &'static str> {
todo!()
let user_free_balance = self.free_balances.get(&who).copied().unwrap_or_else(Zero::zero);
let user_stacked_balance = self.staked_balances.get(&who).copied().unwrap_or_else(Zero::zero);

if user_free_balance.checked_sub(&amount).is_none() {
return Err("Not enough free balance to stake");
}

let new_free_balance = user_free_balance - amount;
let new_stacked_balance = user_stacked_balance + amount;

self.free_balances.insert(who.clone(), new_free_balance);
self.staked_balances.insert(who, new_stacked_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 user_free_balance = self.free_balances.get(&who).copied().unwrap_or_else(Zero::zero);
let user_stacked_balance = self.staked_balances.get(&who).copied().unwrap_or_else(Zero::zero);

if user_stacked_balance.checked_sub(&amount).is_none() {
return Err("Not enough stacked balance to unstake");
}

let new_free_balance = user_free_balance + amount;
let new_stacked_balance = user_stacked_balance - amount;

self.staked_balances.insert(who.clone(), new_stacked_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).copied().unwrap_or_else(Zero::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(Zero::zero)
}
}

Expand Down