Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Secretary Program #4764

Closed
Closed
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,13 @@ impl Contains<Location> for AmbassadorEntities {
}
}

pub struct SecretaryEntities;
Doordashcon marked this conversation as resolved.
Show resolved Hide resolved
impl Contains<Location> for SecretaryEntities {
fn contains(location: &Location) -> bool {
matches!(location.unpack(), (1, [Parachain(1001), PalletInstance(94)]))
}
}

pub type Barrier = TrailingSetTopicAsId<
DenyThenTry<
DenyReserveTransferToRelayChain,
Expand All @@ -296,6 +303,7 @@ pub type Barrier = TrailingSetTopicAsId<
Equals<bridging::SiblingBridgeHub>,
FellowshipEntities,
AmbassadorEntities,
SecretaryEntities,
)>,
// Subscriptions for version tracking are OK.
AllowSubscriptionsFrom<Everything>,
Expand Down Expand Up @@ -338,6 +346,7 @@ pub type WaivedLocations = (
Equals<RelayTreasuryLocation>,
FellowshipEntities,
AmbassadorEntities,
SecretaryEntities,
);

/// Cases where a remote origin is accepted as trusted Teleporter for a given asset:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ use westend_runtime_constants::time::HOURS;
use xcm::prelude::*;
use xcm_builder::{AliasesIntoAccountId32, PayOverXcm};

use crate::secretary::SecretaryCollectiveInstance;

use crate::secretary::ranks::SECRETARY;
Doordashcon marked this conversation as resolved.
Show resolved Hide resolved

#[cfg(feature = "runtime-benchmarks")]
use crate::impls::benchmarks::{OpenHrmpChannel, PayWithEnsure};
#[cfg(feature = "runtime-benchmarks")]
Expand Down Expand Up @@ -83,19 +87,22 @@ impl pallet_referenda::Config<FellowshipReferendaInstance> for Runtime {
type RuntimeEvent = RuntimeEvent;
type Scheduler = Scheduler;
type Currency = Balances;
// Fellows can submit proposals.
// Fellows & Secretary can submit proposals.
type SubmitOrigin = EitherOf<
pallet_ranked_collective::EnsureMember<Runtime, FellowshipCollectiveInstance, 3>,
MapSuccess<
TryWithMorphedArg<
RuntimeOrigin,
<RuntimeOrigin as OriginTrait>::PalletsOrigin,
ToVoice,
EnsureOfRank<Runtime, FellowshipCollectiveInstance>,
(AccountId, u16),
EitherOf<
pallet_ranked_collective::EnsureMember<Runtime, FellowshipCollectiveInstance, 3>,
MapSuccess<
TryWithMorphedArg<
RuntimeOrigin,
<RuntimeOrigin as OriginTrait>::PalletsOrigin,
ToVoice,
EnsureOfRank<Runtime, FellowshipCollectiveInstance>,
(AccountId, u16),
>,
TakeFirst,
>,
TakeFirst,
>,
pallet_ranked_collective::EnsureMember<Runtime, SecretaryCollectiveInstance, { SECRETARY }>,
>;
type CancelOrigin = Architects;
type KillOrigin = Masters;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));

pub mod secretary;
pub use secretary::pallet_secretary_origins;

pub mod ambassador;
pub mod impls;
mod weights;
Expand Down Expand Up @@ -298,6 +301,8 @@ pub enum ProxyType {
Fellowship,
/// Ambassador proxy. Allows calls related to the Ambassador Program.
Ambassador,
/// Secretary proxy. Allows calls related to the Secretary Program.
Secretary,
}
impl Default for ProxyType {
fn default() -> Self {
Expand Down Expand Up @@ -348,6 +353,15 @@ impl InstanceFilter<RuntimeCall> for ProxyType {
RuntimeCall::Utility { .. } |
RuntimeCall::Multisig { .. }
),
ProxyType::Secretary => matches!(
c,
RuntimeCall::SecretaryCollective { .. } |
RuntimeCall::SecretaryReferenda { .. } |
RuntimeCall::SecretaryCore { .. } |
RuntimeCall::SecretarySalary { .. } |
RuntimeCall::Utility { .. } |
RuntimeCall::Multisig { .. }
),
}
}
fn is_superset(&self, o: &Self) -> bool {
Expand Down Expand Up @@ -709,6 +723,13 @@ construct_runtime!(
AmbassadorContent: pallet_collective_content::<Instance1> = 75,

StateTrieMigration: pallet_state_trie_migration = 80,

// Secretary Program
SecretaryCollective: pallet_ranked_collective::<Instance3> = 90,
SecretaryReferenda: pallet_referenda::<Instance3> = 91,
SecretaryOrigins: pallet_secretary_origins = 92,
SecretaryCore: pallet_core_fellowship::<Instance3> = 93,
SecretarySalary: pallet_salary::<Instance3> = 94,
}
);

Expand Down Expand Up @@ -783,12 +804,16 @@ mod benches {
[pallet_ranked_collective, FellowshipCollective]
[pallet_core_fellowship, FellowshipCore]
[pallet_salary, FellowshipSalary]
[pallet_treasury, FellowshipTreasury]
[pallet_referenda, AmbassadorReferenda]
[pallet_ranked_collective, AmbassadorCollective]
[pallet_collective_content, AmbassadorContent]
[pallet_core_fellowship, AmbassadorCore]
[pallet_salary, AmbassadorSalary]
[pallet_treasury, FellowshipTreasury]
[pallet_referenda, SecretaryReferenda]
[pallet_ranked_collective, SecretaryCollective]
[pallet_core_fellowship, SecretaryCore]
[pallet_salary, SecretarySalary]
[pallet_asset_rate, AssetRate]
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
// Copyright (C) Parity Technologies (UK) Ltd.
// This file is part of Cumulus.

// Cumulus is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Cumulus is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.

//! The Polkadot Secretary Collective.
//!
//! The module defines the following on-chain functionality of the Secretary Program:
//!
//! - Managed set of program members, where every member is at the same rank
//! (via [SecretaryCollective](pallet_ranked_collective)).
//! - Referendum functionality for the program members to propose, vote on, and execute
//! proposals on behalf of the program (via [SecretaryReferenda](pallet_referenda)).
//! - Promotion and demotion periods, register of members' activity, and rank based salaries
//! (via [SecretaryCore](pallet_core_fellowship)).
//! - Members' salaries (via [SecretarySalary](pallet_salary), requiring a member to be
//! imported or inducted into [SecretaryCore](pallet_core_fellowship)).
Doordashcon marked this conversation as resolved.
Show resolved Hide resolved
pub mod origins;
mod tracks;

use super::*;
use crate::{
fellowship::{ranks::DAN_3, FellowshipCollectiveInstance},
xcm_config::{FellowshipAdminBodyId, LocationToAccountId, WndAssetHub},
};
use frame_support::traits::{tokens::GetSalary, EitherOf, EitherOfDiverse, MapSuccess};
use frame_system::EnsureRootWithSuccess;
pub use origins::pallet_origins as pallet_secretary_origins;
use origins::pallet_origins::Secretary;
use sp_core::ConstU128;
use sp_runtime::traits::{ConstU16, ConvertToValue, Identity, Replace, ReplaceWithDefault};
use xcm::prelude::*;
use xcm_builder::{AliasesIntoAccountId32, PayOverXcm};

/// The Secretary members' ranks.
pub mod ranks {
use pallet_ranked_collective::Rank;

#[allow(dead_code)]
pub const SECRETARY_CANDIDATE: Rank = 0;
pub const SECRETARY: Rank = 1;
}

/// Origins of:
/// - Root;
/// - FellowshipAdmin (i.e. token holder referendum);
/// - Plurarity vote from Fellows can promote, demote, remove and approve rank retention
Doordashcon marked this conversation as resolved.
Show resolved Hide resolved
/// of members of the Secretary Collective (rank `2`).
Doordashcon marked this conversation as resolved.
Show resolved Hide resolved
type ApproveOrigin = EitherOf<
EnsureRootWithSuccess<AccountId, ConstU16<65535>>,
EitherOf<
MapSuccess<
EnsureXcm<IsVoiceOfBody<GovernanceLocation, FellowshipAdminBodyId>>,
Replace<ConstU16<2>>,
>,
MapSuccess<Fellows, Replace<ConstU16<2>>>,
Comment on lines +61 to +64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not see a reason to limit with 2, and might be easily forgotten to be updated

>,
>;

/// Origins of:
/// - Root;
/// - FellowshipAdmin (i.e. token holder referendum);
/// - Secretary;
/// - Plurarity vote from Fellows can kill and cancel proposals.
/// of members of the Secretary Collective.
type OpenGovOrSecretaryOrFellow = EitherOfDiverse<
EitherOfDiverse<EnsureRoot<AccountId>, Fellows>,
EitherOfDiverse<Secretary, EnsureXcm<IsVoiceOfBody<GovernanceLocation, FellowshipAdminBodyId>>>,
>;

/// Origins of:
/// - Root;
/// - FellowshipAdmin (i.e. token holder referendum);
/// - Plurarity vote from Fellows can exchange origins and
/// - configure the parameters that govern the Collective.
type OpenGovOrFellow = EitherOfDiverse<
EnsureRoot<AccountId>,
EitherOfDiverse<Fellows, EnsureXcm<IsVoiceOfBody<GovernanceLocation, FellowshipAdminBodyId>>>,
>;

impl pallet_secretary_origins::Config for Runtime {}

pub type SecretaryReferendaInstance = pallet_referenda::Instance3;

impl pallet_referenda::Config<SecretaryReferendaInstance> for Runtime {
type WeightInfo = (); // TODO weights::pallet_referenda_secretary_referenda::WeightInfo<Runtime>;
type RuntimeCall = RuntimeCall;
type RuntimeEvent = RuntimeEvent;
type Scheduler = Scheduler;
type Currency = Balances;
// Secretary collective can submit proposals.
type SubmitOrigin = pallet_ranked_collective::EnsureMember<
Runtime,
SecretaryCollectiveInstance,
{ ranks::SECRETARY },
>;
type CancelOrigin = OpenGovOrSecretaryOrFellow;
type KillOrigin = OpenGovOrSecretaryOrFellow;
type Slash = ToParentTreasury<WestendTreasuryAccount, LocationToAccountId, Runtime>;
type Votes = pallet_ranked_collective::Votes;
type Tally = pallet_ranked_collective::TallyOf<Runtime, SecretaryCollectiveInstance>;
type SubmissionDeposit = ConstU128<0>;
type MaxQueued = ConstU32<100>;
type UndecidingTimeout = ConstU32<{ 7 * DAYS }>;
type AlarmInterval = ConstU32<1>;
type Tracks = tracks::TracksInfo;
type Preimages = Preimage;
}

pub type SecretaryCollectiveInstance = pallet_ranked_collective::Instance3;

impl pallet_ranked_collective::Config<SecretaryCollectiveInstance> for Runtime {
type WeightInfo = (); // TODO weights::pallet_ranked_collective_secretary_collective::WeightInfo<Runtime>;
type RuntimeEvent = RuntimeEvent;
type AddOrigin = MapSuccess<Self::PromoteOrigin, ReplaceWithDefault<()>>;
type RemoveOrigin = ApproveOrigin;
type PromoteOrigin = ApproveOrigin;
type DemoteOrigin = ApproveOrigin;
type ExchangeOrigin = OpenGovOrFellow;
type Polls = SecretaryReferenda;
type MinRankOfClass = Identity;
type MemberSwappedHandler = (crate::SecretaryCore, crate::SecretarySalary);
type VoteWeight = pallet_ranked_collective::Geometric;
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkSetup = (crate::SecretaryCore, crate::SecretarySalary);
}

pub type SecretaryCoreInstance = pallet_core_fellowship::Instance3;

impl pallet_core_fellowship::Config<SecretaryCoreInstance> for Runtime {
type WeightInfo = (); // TODO weights::pallet_core_fellowship_secretary_core::WeightInfo<Runtime>;
type RuntimeEvent = RuntimeEvent;
type Members = pallet_ranked_collective::Pallet<Runtime, SecretaryCollectiveInstance>;
type Balance = Balance;
type ParamsOrigin = OpenGovOrFellow;
// Induction is by any of:
// - Root;
// - FellowshipAdmin (i.e. token holder referendum);
// - A single Member of the Technical Fellowship, rank 3 and above;
// - A single member of the Secretary Collective.
type InductOrigin = EitherOfDiverse<
EitherOfDiverse<
EnsureRoot<AccountId>,
EnsureXcm<IsVoiceOfBody<GovernanceLocation, FellowshipAdminBodyId>>,
>,
EitherOfDiverse<
pallet_ranked_collective::EnsureMember<
Runtime,
FellowshipCollectiveInstance,
{ DAN_3 },
>,
pallet_ranked_collective::EnsureMember<
Runtime,
SecretaryCollectiveInstance,
{ ranks::SECRETARY },
>,
>,
>;
type ApproveOrigin = ApproveOrigin;
type PromoteOrigin = ApproveOrigin;
type EvidenceSize = ConstU32<65536>;
type MaxRank = ConstU32<1>;
}

pub type SecretarySalaryInstance = pallet_salary::Instance3;

parameter_types! {
// The interior location on AssetHub for the paying account. This is the Secretary Salary
// pallet instance. This sovereign account will need funding.
pub SecretarySalaryInteriorLocation: InteriorLocation = PalletInstance(94).into();
}

/// [`PayOverXcm`] setup to pay the Secretary salary on the AssetHub in USDT.
pub type SecretarySalaryPaymaster = PayOverXcm<
SecretarySalaryInteriorLocation,
crate::xcm_config::XcmRouter,
crate::PolkadotXcm,
ConstU32<{ 6 * HOURS }>,
AccountId,
(),
ConvertToValue<WndAssetHub>,
AliasesIntoAccountId32<(), AccountId>,
>;

pub struct SalaryForRank;
impl GetSalary<u16, AccountId, Balance> for SalaryForRank {
fn get_salary(rank: u16, _who: &AccountId) -> Balance {
if rank == 1 {
1000
Doordashcon marked this conversation as resolved.
Show resolved Hide resolved
} else {
0
}
}
}

impl pallet_salary::Config<SecretarySalaryInstance> for Runtime {
type WeightInfo = (); // TODO weights::pallet_salary_secretary_salary::WeightInfo<Runtime>;
type RuntimeEvent = RuntimeEvent;

#[cfg(not(feature = "runtime-benchmarks"))]
type Paymaster = SecretarySalaryPaymaster;
#[cfg(feature = "runtime-benchmarks")]
type Paymaster = crate::impls::benchmarks::PayWithEnsure<
SecretarySalaryPaymaster,
crate::impls::benchmarks::OpenHrmpChannel<ConstU32<1000>>,
>;
type Members = pallet_ranked_collective::Pallet<Runtime, SecretaryCollectiveInstance>;

#[cfg(not(feature = "runtime-benchmarks"))]
type Salary = SalaryForRank;
#[cfg(feature = "runtime-benchmarks")]
type Salary = frame_support::traits::tokens::ConvertRank<
crate::impls::benchmarks::RankToSalary<Balances>,
>;
// 15 days to register for a salary payment.
type RegistrationPeriod = ConstU32<{ 15 * DAYS }>;
// 15 days to claim the salary payment.
type PayoutPeriod = ConstU32<{ 15 * DAYS }>;
Doordashcon marked this conversation as resolved.
Show resolved Hide resolved
// Total monthly salary budget.
type Budget = ConstU128<{ 10_000 * DOLLARS }>;
Doordashcon marked this conversation as resolved.
Show resolved Hide resolved
}
Loading
Loading