Skip to content
Merged
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
17 changes: 14 additions & 3 deletions integration-tests/src/tests/governance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ use frame_support::{
fungible::InspectFreeze, tokens::Precision, Imbalance, LockableCurrency, ReservableCurrency, StorePreimage,
},
};
use pallet_democracy::{AccountVote, Conviction, ReferendumInfo, Vote};
use pallet_democracy::{AccountVote, Conviction, ReferendumInfo, Vote, GetElectorate};
use pallet_vesting::VestingInfo;
use polimec_base_runtime::{
Balances, Council, Democracy, Elections, ParachainStaking, Preimage, RuntimeOrigin, TechnicalCommittee, Treasury,
Vesting,
Balances, Council, Democracy, Elections, ParachainStaking, PayMaster, Preimage, RuntimeOrigin, TechnicalCommittee, Treasury, Vesting
};
use tests::defaults::*;
use xcm_emulator::get_account_id_from_seed;
Expand Down Expand Up @@ -178,6 +177,18 @@ fn democracy_works() {
});
}

// Test that electorate configuration calculates correctly.
// Electorate is the total issuance minus the sum of the Growth + Operational treasury.
#[test]
fn electorate_calculates_correctly() {
PolimecBase::execute_with(|| {
let total_issuance = Balances::total_issuance();
assert_ok!(Balances::write_balance(&Treasury::account_id(), 1000 * PLMC));
assert_ok!(Balances::write_balance(&<polimec_base_runtime::Runtime as pallet_parachain_staking::Config>::PayMaster::get(), 1000 * PLMC));
assert_eq!(<polimec_base_runtime::Runtime as pallet_democracy::Config>::Electorate::get_electorate(), total_issuance - 2000 * PLMC);
})
}

/// Test that a user with staked balance can vote on a democracy proposal.
#[test]
fn user_can_vote_with_staked_balance() {
Expand Down
7 changes: 6 additions & 1 deletion pallets/democracy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ use sp_std::prelude::*;

mod conviction;
mod types;
mod traits;
mod vote;
mod vote_threshold;
pub mod weights;
Expand All @@ -177,6 +178,7 @@ pub use pallet::*;
pub use types::{
Delegations, MetadataOwner, PropIndex, ReferendumIndex, ReferendumInfo, ReferendumStatus, Tally, UnvoteScope,
};
pub use traits::GetElectorate;
pub use vote::{AccountVote, Vote, Voting};
pub use vote_threshold::{Approved, VoteThreshold};
pub use weights::WeightInfo;
Expand Down Expand Up @@ -343,6 +345,9 @@ pub mod pallet {

/// Handler for the unbalanced reduction when slashing a preimage deposit.
type Slash: OnUnbalanced<CreditOf<Self>>;

/// Type returning the total electorate.
type Electorate: GetElectorate<BalanceOf<Self>>;
}

/// The number of (public) proposals that have been made so far.
Expand Down Expand Up @@ -1516,7 +1521,7 @@ impl<T: Config> Pallet<T> {
index: ReferendumIndex,
status: ReferendumStatus<BlockNumberFor<T>, BoundedCallOf<T>, BalanceOf<T>>,
) -> bool {
let total_issuance = T::Fungible::total_issuance();
let total_issuance = T::Electorate::get_electorate();
let approved = status.threshold.approved(status.tally, total_issuance);

if approved {
Expand Down
8 changes: 8 additions & 0 deletions pallets/democracy/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,19 @@ impl SortedMembers<u64> for OneToFive {
fn add(_m: &u64) {}
}

pub struct Electorate;
impl GetElectorate<BalanceOf<Test>> for Electorate {
fn get_electorate() -> BalanceOf<Test> {
Balances::total_issuance()
}
}

impl Config for Test {
type BlacklistOrigin = EnsureRoot<u64>;
type CancelProposalOrigin = EnsureRoot<u64>;
type CancellationOrigin = EnsureSignedBy<Four, u64>;
type CooloffPeriod = ConstU64<2>;
type Electorate = Electorate;
type EnactmentPeriod = ConstU64<2>;
type ExternalDefaultOrigin = EnsureSignedBy<One, u64>;
type ExternalMajorityOrigin = EnsureSignedBy<Three, u64>;
Expand Down
18 changes: 18 additions & 0 deletions pallets/democracy/src/traits.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (C) Parity Technologies (UK) Ltd.

// Polimec Blockchain – https://www.polimec.org/
// Copyright (C) Polimec 2022. All rights reserved.

// This library includes code from Substrate, which is licensed
// under both the GNU General Public License version 3 (GPLv3) and the
// Apache License 2.0. You may choose to redistribute and/or modify this
// code under either the terms of the GPLv3 or the Apache 2.0 License,
// whichever suits your needs.

pub trait GetElectorate<Balance> {
/// Calculate the total size of the electorate (tokens in circulation that might be used
/// for voting) in terms of total Balance.
/// Used for the referendum approval threshold calculation.
/// Example: Total number of tokens in the system - total number of tokens in the treasury.
fn get_electorate() -> Balance;
}
14 changes: 13 additions & 1 deletion runtimes/base/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ extern crate frame_benchmarking;
use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases;
use frame_support::{
construct_runtime, parameter_types,
traits::{fungible::Credit, tokens, ConstU32, Contains, EitherOfDiverse, InstanceFilter, PrivilegeCmp},
traits::{fungible::{Credit, Inspect}, tokens, ConstU32, Contains, EitherOfDiverse, InstanceFilter, PrivilegeCmp},
weights::{ConstantMultiplier, Weight},
};
use frame_system::{EnsureRoot, EnsureSigned};
use pallet_democracy::GetElectorate;
use pallet_oracle_ocw::types::AssetName;
use parachains_common::AssetIdForTrustBackedAssets as AssetId;
use parity_scale_codec::Encode;
Expand Down Expand Up @@ -484,6 +485,16 @@ impl pallet_elections_phragmen::Config for Runtime {
type WeightInfo = pallet_elections_phragmen::weights::SubstrateWeight<Runtime>;
}

pub struct Electorate;
impl GetElectorate<Balance> for Electorate {
fn get_electorate() -> Balance {
let total_issuance = Balances::total_issuance();
let growth_treasury_balance = Balances::balance(&Treasury::account_id());
let protocol_treasury_balance = Balances::balance(&PayMaster::get());
total_issuance.saturating_sub(growth_treasury_balance).saturating_sub(protocol_treasury_balance)
}
}

impl pallet_democracy::Config for Runtime {
type BlacklistOrigin = EnsureRoot<AccountId>;
// To cancel a proposal before it has been passed, the technical committee must be unanimous or
Expand All @@ -495,6 +506,7 @@ impl pallet_democracy::Config for Runtime {
// To cancel a proposal which has been passed, 2/3 of the council must agree to it.
type CancellationOrigin = pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 2, 3>;
type CooloffPeriod = CooloffPeriod;
type Electorate = Electorate;
type EnactmentPeriod = EnactmentPeriod;
/// A unanimous council can have the next scheduled referendum be a straight default-carries
/// (NTB) vote.
Expand Down
14 changes: 13 additions & 1 deletion runtimes/testnet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases;
use frame_support::{
construct_runtime, ord_parameter_types, parameter_types,
traits::{
fungible::Credit, tokens, AsEnsureOriginWithArg, ConstU32, Currency, EitherOfDiverse, Everything, PrivilegeCmp,
fungible::{Credit, Inspect}, tokens, AsEnsureOriginWithArg, ConstU32, Currency, EitherOfDiverse, Everything, PrivilegeCmp,
WithdrawReasons,
},
weights::{ConstantMultiplier, Weight},
Expand Down Expand Up @@ -55,6 +55,7 @@ use sp_runtime::{
};

use pallet_oracle_ocw::types::AssetName;
use pallet_democracy::GetElectorate;
use sp_std::{cmp::Ordering, prelude::*};
#[cfg(feature = "std")]
use sp_version::NativeVersion;
Expand Down Expand Up @@ -433,6 +434,16 @@ impl pallet_elections_phragmen::Config for Runtime {
type WeightInfo = pallet_elections_phragmen::weights::SubstrateWeight<Runtime>;
}

pub struct Electorate;
impl GetElectorate<Balance> for Electorate {
fn get_electorate() -> Balance {
let total_issuance = Balances::total_issuance();
let growth_treasury_balance = Balances::balance(&Treasury::account_id());
let protocol_treasury_balance = Balances::balance(&PayMaster::get());
total_issuance.saturating_sub(growth_treasury_balance).saturating_sub(protocol_treasury_balance)
}
}

impl pallet_democracy::Config for Runtime {
type BlacklistOrigin = EnsureRoot<AccountId>;
// To cancel a proposal before it has been passed, the technical committee must be unanimous or
Expand All @@ -444,6 +455,7 @@ impl pallet_democracy::Config for Runtime {
// To cancel a proposal which has been passed, 2/3 of the council must agree to it.
type CancellationOrigin = pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 2, 3>;
type CooloffPeriod = CooloffPeriod;
type Electorate = Electorate;
type EnactmentPeriod = EnactmentPeriod;
/// A unanimous council can have the next scheduled referendum be a straight default-carries
/// (NTB) vote.
Expand Down