From 7beeba5fb89292816e65cdc721890c2396927174 Mon Sep 17 00:00:00 2001
From: Gavin Wood <gavin@parity.io>
Date: Tue, 21 Mar 2023 13:59:54 +0000
Subject: [PATCH] Introduce OpenGov into Polkadot (#6701)

* OpenGov for Polkadot

* Integrate OpenGov into XCM

* Formatting

* Missing files

* Remove Gov1 from Kusama

* Fixes

* Update runtime/polkadot/src/governance/origins.rs

Co-authored-by: Ankan <10196091+Ank4n@users.noreply.github.com>

* Revert scheduler origin changes

* Fixes

* Docs

* Remove todo

* Docs

* Move Fellowship to Collectives  (#6718)

* FellowshipAdmin origin over xcm

* accept Fellows origin from Collectives

* remove Fellowship

* remove unreachable arm

* define benchmarks

* correct comment for DOLLARS constant

* Add OpenGov Calls to Proxy Definitions (#6729)

* add opengov calls to proxy definitions

* fix build

* Update runtime/polkadot/src/governance/mod.rs

Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>

* Update runtime/polkadot/src/governance/tracks.rs

Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>

* Update runtime/polkadot/src/lib.rs

Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>

* Update runtime/polkadot/src/governance/origins.rs

Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>

* Update runtime/polkadot/src/governance/mod.rs

Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>

* Update old.rs

* Update old.rs

* weights with new api

* XCM tweaks for OpenGov (#6855)

* pass xcm origin, allow unpaid form Collectives and Fellows, whitelist call

* unpaid execution only for Fellows

* Apply suggestions from code review

Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>

* rename const namespace to system_parachains

* remove prod_or_fast

---------

Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>

* remove unused import

---------

Co-authored-by: Ankan <10196091+Ank4n@users.noreply.github.com>
Co-authored-by: parity-processbot <>
Co-authored-by: Muharem Ismailov <ismailov.m.h@gmail.com>
Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>
---
 polkadot/Cargo.lock                           |   4 +
 polkadot/node/service/src/chain_spec.rs       |  16 -
 .../kusama/src/governance/fellowship.rs       |  13 +-
 polkadot/runtime/kusama/src/governance/mod.rs |   3 -
 polkadot/runtime/kusama/src/lib.rs            |  58 +-
 polkadot/runtime/kusama/src/xcm_config.rs     |  66 +--
 polkadot/runtime/polkadot/Cargo.toml          |  14 +
 .../runtime/polkadot/constants/src/lib.rs     |   9 +
 .../runtime/polkadot/src/governance/mod.rs    | 100 ++++
 .../src/governance/old.rs                     |  78 +--
 .../polkadot/src/governance/origins.rs        | 151 +++++
 .../runtime/polkadot/src/governance/tracks.rs | 319 +++++++++++
 polkadot/runtime/polkadot/src/lib.rs          | 262 ++-------
 polkadot/runtime/polkadot/src/weights/mod.rs  |   3 +
 .../src/weights/pallet_conviction_voting.rs   | 172 ++++++
 .../polkadot/src/weights/pallet_referenda.rs  | 520 ++++++++++++++++++
 .../polkadot/src/weights/pallet_whitelist.rs  | 108 ++++
 polkadot/runtime/polkadot/src/xcm_config.rs   |  64 ++-
 18 files changed, 1547 insertions(+), 413 deletions(-)
 create mode 100644 polkadot/runtime/polkadot/src/governance/mod.rs
 rename polkadot/runtime/{kusama => polkadot}/src/governance/old.rs (78%)
 create mode 100644 polkadot/runtime/polkadot/src/governance/origins.rs
 create mode 100644 polkadot/runtime/polkadot/src/governance/tracks.rs
 create mode 100644 polkadot/runtime/polkadot/src/weights/pallet_conviction_voting.rs
 create mode 100644 polkadot/runtime/polkadot/src/weights/pallet_referenda.rs
 create mode 100644 polkadot/runtime/polkadot/src/weights/pallet_whitelist.rs

diff --git a/polkadot/Cargo.lock b/polkadot/Cargo.lock
index ee12ffeaf1c..11c0847f1a9 100644
--- a/polkadot/Cargo.lock
+++ b/polkadot/Cargo.lock
@@ -7437,6 +7437,7 @@ dependencies = [
  "pallet-bounties",
  "pallet-child-bounties",
  "pallet-collective",
+ "pallet-conviction-voting",
  "pallet-democracy",
  "pallet-election-provider-multi-phase",
  "pallet-election-provider-support-benchmarking",
@@ -7455,6 +7456,7 @@ dependencies = [
  "pallet-offences-benchmarking",
  "pallet-preimage",
  "pallet-proxy",
+ "pallet-referenda",
  "pallet-scheduler",
  "pallet-session",
  "pallet-session-benchmarking",
@@ -7468,6 +7470,7 @@ dependencies = [
  "pallet-treasury",
  "pallet-utility",
  "pallet-vesting",
+ "pallet-whitelist",
  "pallet-xcm",
  "parity-scale-codec",
  "polkadot-primitives",
@@ -7482,6 +7485,7 @@ dependencies = [
  "serde_json",
  "smallvec",
  "sp-api",
+ "sp-arithmetic",
  "sp-authority-discovery",
  "sp-block-builder",
  "sp-consensus-babe",
diff --git a/polkadot/node/service/src/chain_spec.rs b/polkadot/node/service/src/chain_spec.rs
index 12b65c7ba85..f867cf97ca7 100644
--- a/polkadot/node/service/src/chain_spec.rs
+++ b/polkadot/node/service/src/chain_spec.rs
@@ -743,14 +743,6 @@ fn kusama_staging_testnet_config_genesis(wasm_binary: &[u8]) -> kusama::GenesisC
 			slash_reward_fraction: Perbill::from_percent(10),
 			..Default::default()
 		},
-		phragmen_election: Default::default(),
-		democracy: Default::default(),
-		council: kusama::CouncilConfig { members: vec![], phantom: Default::default() },
-		technical_committee: kusama::TechnicalCommitteeConfig {
-			members: vec![],
-			phantom: Default::default(),
-		},
-		technical_membership: Default::default(),
 		babe: kusama::BabeConfig {
 			authorities: Default::default(),
 			epoch_config: Some(kusama::BABE_GENESIS_EPOCH_CONFIG),
@@ -1442,14 +1434,6 @@ pub fn kusama_testnet_genesis(
 			slash_reward_fraction: Perbill::from_percent(10),
 			..Default::default()
 		},
-		phragmen_election: Default::default(),
-		democracy: kusama::DemocracyConfig::default(),
-		council: kusama::CouncilConfig { members: vec![], phantom: Default::default() },
-		technical_committee: kusama::TechnicalCommitteeConfig {
-			members: vec![],
-			phantom: Default::default(),
-		},
-		technical_membership: Default::default(),
 		babe: kusama::BabeConfig {
 			authorities: Default::default(),
 			epoch_config: Some(kusama::BABE_GENESIS_EPOCH_CONFIG),
diff --git a/polkadot/runtime/kusama/src/governance/fellowship.rs b/polkadot/runtime/kusama/src/governance/fellowship.rs
index 6d01780ebc0..3e5acf0b4f5 100644
--- a/polkadot/runtime/kusama/src/governance/fellowship.rs
+++ b/polkadot/runtime/kusama/src/governance/fellowship.rs
@@ -335,18 +335,7 @@ impl pallet_ranked_collective::Config<FellowshipCollectiveInstance> for Runtime
 	// - the FellowshipAdmin origin (i.e. token holder referendum);
 	// - a vote by the rank *above* the new rank.
 	type PromoteOrigin = EitherOf<
-		EitherOf<
-			frame_system::EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
-			MapSuccess<
-				pallet_collective::EnsureProportionAtLeast<
-					Self::AccountId,
-					super::old::TechnicalCollective,
-					2,
-					3,
-				>,
-				Replace<ConstU16<6>>,
-			>,
-		>,
+		frame_system::EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
 		EitherOf<
 			MapSuccess<FellowshipAdmin, Replace<ConstU16<9>>>,
 			TryMapSuccess<origins::EnsureFellowship, CheckedReduceBy<ConstU16<1>>>,
diff --git a/polkadot/runtime/kusama/src/governance/mod.rs b/polkadot/runtime/kusama/src/governance/mod.rs
index c2db914f647..d7812e39d7a 100644
--- a/polkadot/runtime/kusama/src/governance/mod.rs
+++ b/polkadot/runtime/kusama/src/governance/mod.rs
@@ -23,9 +23,6 @@ use frame_support::{
 };
 use frame_system::EnsureRootWithSuccess;
 
-// Old governance configurations.
-pub mod old;
-
 mod origins;
 pub use origins::{
 	pallet_custom_origins, AuctionAdmin, Fellows, FellowshipAdmin, FellowshipExperts,
diff --git a/polkadot/runtime/kusama/src/lib.rs b/polkadot/runtime/kusama/src/lib.rs
index 54a3f648f39..57ab3ea654c 100644
--- a/polkadot/runtime/kusama/src/lib.rs
+++ b/polkadot/runtime/kusama/src/lib.rs
@@ -55,7 +55,7 @@ use frame_support::{
 	construct_runtime, parameter_types,
 	traits::{
 		ConstU32, Contains, EitherOf, EitherOfDiverse, InstanceFilter, KeyOwnerProofSystem,
-		LockIdentifier, PrivilegeCmp, StorageMapShim, WithdrawReasons,
+		PrivilegeCmp, StorageMapShim, WithdrawReasons,
 	},
 	weights::ConstantMultiplier,
 	PalletId, RuntimeDebug,
@@ -80,7 +80,6 @@ use sp_staking::SessionIndex;
 #[cfg(any(feature = "std", test))]
 use sp_version::NativeVersion;
 use sp_version::RuntimeVersion;
-use static_assertions::const_assert;
 
 pub use frame_system::Call as SystemCall;
 pub use pallet_balances::Call as BalancesCall;
@@ -107,8 +106,8 @@ pub mod xcm_config;
 // Governance configurations.
 pub mod governance;
 use governance::{
-	old::CouncilCollective, pallet_custom_origins, AuctionAdmin, Fellows, GeneralAdmin, LeaseAdmin,
-	StakingAdmin, Treasurer, TreasurySpender,
+	pallet_custom_origins, AuctionAdmin, Fellows, GeneralAdmin, LeaseAdmin, StakingAdmin,
+	Treasurer, TreasurySpender,
 };
 
 #[cfg(test)]
@@ -207,11 +206,6 @@ impl PrivilegeCmp<OriginCaller> for OriginPrivilegeCmp {
 		match (left, right) {
 			// Root is greater than anything.
 			(OriginCaller::system(frame_system::RawOrigin::Root), _) => Some(Ordering::Greater),
-			// Check which one has more yes votes.
-			(
-				OriginCaller::Council(pallet_collective::RawOrigin::Members(l_yes_votes, l_count)),
-				OriginCaller::Council(pallet_collective::RawOrigin::Members(r_yes_votes, r_count)),
-			) => Some((l_yes_votes * r_count).cmp(&(r_yes_votes * l_count))),
 			// For every other origin we don't care, as they are not used for `ScheduleOrigin`.
 			_ => None,
 		}
@@ -224,6 +218,8 @@ impl pallet_scheduler::Config for Runtime {
 	type PalletsOrigin = OriginCaller;
 	type RuntimeCall = RuntimeCall;
 	type MaximumWeight = MaximumSchedulerWeight;
+	// The goal of having ScheduleOrigin include AuctionAdmin is to allow the auctions track of
+	// OpenGov to schedule periodic auctions.
 	type ScheduleOrigin = EitherOf<EnsureRoot<AccountId>, AuctionAdmin>;
 	type MaxScheduledPerBlock = MaxScheduledPerBlock;
 	type WeightInfo = weights::pallet_scheduler::WeightInfo<Runtime>;
@@ -594,10 +590,7 @@ impl pallet_fast_unstake::Config for Runtime {
 	type Currency = Balances;
 	type BatchSize = frame_support::traits::ConstU32<64>;
 	type Deposit = frame_support::traits::ConstU128<{ CENTS * 100 }>;
-	type ControlOrigin = EitherOfDiverse<
-		EnsureRoot<AccountId>,
-		pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 2>,
-	>;
+	type ControlOrigin = EnsureRoot<AccountId>;
 	type Staking = Staking;
 	type MaxErasToCheckPerBlock = ConstU32<1>;
 	#[cfg(feature = "runtime-benchmarks")]
@@ -681,17 +674,6 @@ impl pallet_child_bounties::Config for Runtime {
 	type WeightInfo = weights::pallet_child_bounties::WeightInfo<Runtime>;
 }
 
-impl pallet_tips::Config for Runtime {
-	type MaximumReasonLength = MaximumReasonLength;
-	type DataDepositPerByte = DataDepositPerByte;
-	type Tippers = PhragmenElection;
-	type TipCountdown = TipCountdown;
-	type TipFindersFee = TipFindersFee;
-	type TipReportDepositBase = TipReportDepositBase;
-	type RuntimeEvent = RuntimeEvent;
-	type WeightInfo = weights::pallet_tips::WeightInfo<Runtime>;
-}
-
 impl pallet_offences::Config for Runtime {
 	type RuntimeEvent = RuntimeEvent;
 	type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
@@ -983,15 +965,9 @@ impl InstanceFilter<RuntimeCall> for ProxyType {
 				RuntimeCall::Session(..) |
 				RuntimeCall::Grandpa(..) |
 				RuntimeCall::ImOnline(..) |
-				RuntimeCall::Democracy(..) |
-				RuntimeCall::Council(..) |
-				RuntimeCall::TechnicalCommittee(..) |
-				RuntimeCall::PhragmenElection(..) |
-				RuntimeCall::TechnicalMembership(..) |
 				RuntimeCall::Treasury(..) |
 				RuntimeCall::Bounties(..) |
 				RuntimeCall::ChildBounties(..) |
-				RuntimeCall::Tips(..) |
 				RuntimeCall::ConvictionVoting(..) |
 				RuntimeCall::Referenda(..) |
 				RuntimeCall::FellowshipCollective(..) |
@@ -1028,12 +1004,9 @@ impl InstanceFilter<RuntimeCall> for ProxyType {
 			),
 			ProxyType::Governance => matches!(
 				c,
-				RuntimeCall::Democracy(..) |
-					RuntimeCall::Council(..) | RuntimeCall::TechnicalCommittee(..) |
-					RuntimeCall::PhragmenElection(..) |
-					RuntimeCall::Treasury(..) |
+				RuntimeCall::Treasury(..) |
 					RuntimeCall::Bounties(..) |
-					RuntimeCall::Tips(..) | RuntimeCall::Utility(..) |
+					RuntimeCall::Utility(..) |
 					RuntimeCall::ChildBounties(..) |
 					// OpenGov calls
 					RuntimeCall::ConvictionVoting(..) |
@@ -1361,13 +1334,7 @@ construct_runtime! {
 		AuthorityDiscovery: pallet_authority_discovery::{Pallet, Config} = 12,
 
 		// Governance stuff.
-		Democracy: pallet_democracy::{Pallet, Call, Storage, Config<T>, Event<T>} = 13,
-		Council: pallet_collective::<Instance1>::{Pallet, Call, Storage, Origin<T>, Event<T>, Config<T>} = 14,
-		TechnicalCommittee: pallet_collective::<Instance2>::{Pallet, Call, Storage, Origin<T>, Event<T>, Config<T>} = 15,
-		PhragmenElection: pallet_elections_phragmen::{Pallet, Call, Storage, Event<T>, Config<T>} = 16,
-		TechnicalMembership: pallet_membership::<Instance1>::{Pallet, Call, Storage, Event<T>, Config<T>} = 17,
 		Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event<T>} = 18,
-
 		ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event<T>} = 20,
 		Referenda: pallet_referenda::{Pallet, Call, Storage, Event<T>} = 21,
 //		pub type FellowshipCollectiveInstance = pallet_ranked_collective::Instance1;
@@ -1415,9 +1382,6 @@ construct_runtime! {
 		Bounties: pallet_bounties::{Pallet, Call, Storage, Event<T>} = 35,
 		ChildBounties: pallet_child_bounties = 40,
 
-		// Tips module.
-		Tips: pallet_tips::{Pallet, Call, Storage, Event<T>} = 36,
-
 		// Election pallet. Only works with staking, but placed here to maintain indices.
 		ElectionProviderMultiPhase: pallet_election_provider_multi_phase::{Pallet, Call, Storage, Event<T>, ValidateUnsigned} = 37,
 
@@ -1544,11 +1508,7 @@ mod benches {
 		[frame_benchmarking::baseline, Baseline::<Runtime>]
 		[pallet_bounties, Bounties]
 		[pallet_child_bounties, ChildBounties]
-		[pallet_collective, Council]
-		[pallet_collective, TechnicalCommittee]
 		[pallet_conviction_voting, ConvictionVoting]
-		[pallet_democracy, Democracy]
-		[pallet_elections_phragmen, PhragmenElection]
 		[pallet_election_provider_multi_phase, ElectionProviderMultiPhase]
 		[frame_election_provider_support, ElectionProviderBench::<Runtime>]
 		[pallet_fast_unstake, FastUnstake]
@@ -1556,7 +1516,6 @@ mod benches {
 		[pallet_identity, Identity]
 		[pallet_im_online, ImOnline]
 		[pallet_indices, Indices]
-		[pallet_membership, TechnicalMembership]
 		[pallet_multisig, Multisig]
 		[pallet_nomination_pools, NominationPoolsBench::<Runtime>]
 		[pallet_offences, OffencesBench::<Runtime>]
@@ -1571,7 +1530,6 @@ mod benches {
 		[pallet_staking, Staking]
 		[frame_system, SystemBench::<Runtime>]
 		[pallet_timestamp, Timestamp]
-		[pallet_tips, Tips]
 		[pallet_treasury, Treasury]
 		[pallet_utility, Utility]
 		[pallet_vesting, Vesting]
diff --git a/polkadot/runtime/kusama/src/xcm_config.rs b/polkadot/runtime/kusama/src/xcm_config.rs
index 33ca3a810ae..06bb829b042 100644
--- a/polkadot/runtime/kusama/src/xcm_config.rs
+++ b/polkadot/runtime/kusama/src/xcm_config.rs
@@ -17,9 +17,8 @@
 //! XCM configurations for the Kusama runtime.
 
 use super::{
-	parachains_origin, AccountId, AllPalletsWithSystem, Balances, CouncilCollective, Fellows,
-	ParaId, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, StakingAdmin, WeightToFee,
-	XcmPallet,
+	parachains_origin, AccountId, AllPalletsWithSystem, Balances, Fellows, ParaId, Runtime,
+	RuntimeCall, RuntimeEvent, RuntimeOrigin, StakingAdmin, WeightToFee, XcmPallet,
 };
 use frame_support::{
 	match_types, parameter_types,
@@ -31,8 +30,8 @@ use sp_core::ConstU32;
 use xcm::latest::prelude::*;
 use xcm_builder::{
 	AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
-	AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, BackingToPlurality,
-	ChildParachainAsNative, ChildParachainConvertsVia, ChildSystemParachainAsSuperuser,
+	AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, ChildParachainAsNative,
+	ChildParachainConvertsVia, ChildSystemParachainAsSuperuser,
 	CurrencyAdapter as XcmCurrencyAdapter, FixedWeightBounds, IsChildSystemParachain, IsConcrete,
 	MintLocation, OriginToPluralityVoice, SignedAccountId32AsNative, SignedToAccountId32,
 	SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, WeightInfoBounds,
@@ -200,49 +199,6 @@ impl Contains<RuntimeCall> for SafeCallFilter {
 			RuntimeCall::Session(pallet_session::Call::purge_keys { .. }) |
 			RuntimeCall::Grandpa(..) |
 			RuntimeCall::ImOnline(..) |
-			RuntimeCall::Democracy(
-				pallet_democracy::Call::second { .. } |
-				pallet_democracy::Call::vote { .. } |
-				pallet_democracy::Call::emergency_cancel { .. } |
-				pallet_democracy::Call::fast_track { .. } |
-				pallet_democracy::Call::veto_external { .. } |
-				pallet_democracy::Call::cancel_referendum { .. } |
-				pallet_democracy::Call::delegate { .. } |
-				pallet_democracy::Call::undelegate { .. } |
-				pallet_democracy::Call::clear_public_proposals { .. } |
-				pallet_democracy::Call::unlock { .. } |
-				pallet_democracy::Call::remove_vote { .. } |
-				pallet_democracy::Call::remove_other_vote { .. } |
-				pallet_democracy::Call::blacklist { .. } |
-				pallet_democracy::Call::cancel_proposal { .. },
-			) |
-			RuntimeCall::Council(
-				pallet_collective::Call::vote { .. } |
-				pallet_collective::Call::close_old_weight { .. } |
-				pallet_collective::Call::disapprove_proposal { .. } |
-				pallet_collective::Call::close { .. },
-			) |
-			RuntimeCall::TechnicalCommittee(
-				pallet_collective::Call::vote { .. } |
-				pallet_collective::Call::close_old_weight { .. } |
-				pallet_collective::Call::disapprove_proposal { .. } |
-				pallet_collective::Call::close { .. },
-			) |
-			RuntimeCall::PhragmenElection(
-				pallet_elections_phragmen::Call::remove_voter { .. } |
-				pallet_elections_phragmen::Call::submit_candidacy { .. } |
-				pallet_elections_phragmen::Call::renounce_candidacy { .. } |
-				pallet_elections_phragmen::Call::remove_member { .. } |
-				pallet_elections_phragmen::Call::clean_defunct_voters { .. },
-			) |
-			RuntimeCall::TechnicalMembership(
-				pallet_membership::Call::add_member { .. } |
-				pallet_membership::Call::remove_member { .. } |
-				pallet_membership::Call::swap_member { .. } |
-				pallet_membership::Call::change_key { .. } |
-				pallet_membership::Call::set_prime { .. } |
-				pallet_membership::Call::clear_prime { .. },
-			) |
 			RuntimeCall::Treasury(..) |
 			RuntimeCall::ConvictionVoting(..) |
 			RuntimeCall::Referenda(
@@ -377,7 +333,6 @@ impl xcm_executor::Config for XcmConfig {
 }
 
 parameter_types! {
-	pub const CouncilBodyId: BodyId = BodyId::Executive;
 	// StakingAdmin pluralistic body.
 	pub const StakingAdminBodyId: BodyId = BodyId::Defense;
 	// Fellows pluralistic body.
@@ -389,19 +344,9 @@ parameter_types! {
 	pub ReachableDest: Option<MultiLocation> = Some(Parachain(1000).into());
 }
 
-/// Type to convert the council origin to a Plurality `MultiLocation` value.
-pub type CouncilToPlurality = BackingToPlurality<
-	RuntimeOrigin,
-	pallet_collective::Origin<Runtime, CouncilCollective>,
-	CouncilBodyId,
->;
-
 /// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior location
 /// of this chain.
 pub type LocalOriginToLocation = (
-	// We allow an origin from the Collective pallet to be used in XCM as a corresponding Plurality of the
-	// `Unit` body.
-	CouncilToPlurality,
 	// And a usual Signed origin to be used in XCM as a corresponding AccountId32
 	SignedToAccountId32<RuntimeOrigin, AccountId, ThisNetwork>,
 );
@@ -416,9 +361,6 @@ pub type FellowsToPlurality = OriginToPluralityVoice<RuntimeOrigin, Fellows, Fel
 /// Type to convert a pallet `Origin` type value into a `MultiLocation` value which represents an interior location
 /// of this chain for a destination chain.
 pub type LocalPalletOriginToLocation = (
-	// We allow an origin from the Collective pallet to be used in XCM as a corresponding Plurality of the
-	// `Unit` body.
-	CouncilToPlurality,
 	// StakingAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value.
 	StakingAdminToPlurality,
 	// Fellows origin to be used in XCM as a corresponding Plurality `MultiLocation` value.
diff --git a/polkadot/runtime/polkadot/Cargo.toml b/polkadot/runtime/polkadot/Cargo.toml
index 691963d14e8..69bde56eae3 100644
--- a/polkadot/runtime/polkadot/Cargo.toml
+++ b/polkadot/runtime/polkadot/Cargo.toml
@@ -27,6 +27,7 @@ sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", d
 sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 sp-mmr-primitives = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
+sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 sp-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
@@ -44,6 +45,7 @@ pallet-child-bounties = { git = "https://github.com/paritytech/substrate", branc
 pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 pallet-collective = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
+pallet-conviction-voting = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 pallet-democracy = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 pallet-elections-phragmen = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 pallet-election-provider-multi-phase = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
@@ -60,6 +62,7 @@ pallet-nomination-pools-runtime-api = { git = "https://github.com/paritytech/sub
 pallet-offences = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 pallet-preimage = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 pallet-proxy = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
+pallet-referenda = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 pallet-scheduler = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 pallet-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
@@ -72,6 +75,7 @@ polkadot-runtime-constants = { package = "polkadot-runtime-constants", path = ".
 pallet-timestamp = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 pallet-tips = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 pallet-treasury = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
+pallet-whitelist = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 pallet-vesting = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 pallet-utility = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
 frame-election-provider-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
@@ -125,6 +129,7 @@ std = [
 	"tx-pool-api/std",
 	"block-builder-api/std",
 	"offchain-primitives/std",
+	"sp-arithmetic/std",
 	"sp-std/std",
 	"sp-mmr-primitives/std",
 	"frame-support/std",
@@ -135,6 +140,7 @@ std = [
 	"pallet-balances/std",
 	"pallet-bounties/std",
 	"pallet-child-bounties/std",
+	"pallet-conviction-voting/std",
 	"pallet-transaction-payment/std",
 	"pallet-transaction-payment-rpc-runtime-api/std",
 	"pallet-collective/std",
@@ -153,6 +159,7 @@ std = [
 	"pallet-offences/std",
 	"pallet-preimage/std",
 	"pallet-proxy/std",
+	"pallet-referenda/std",
 	"pallet-scheduler/std",
 	"pallet-session/std",
 	"pallet-staking/std",
@@ -162,6 +169,7 @@ std = [
 	"pallet-tips/std",
 	"pallet-babe/std",
 	"pallet-vesting/std",
+	"pallet-whitelist/std",
 	"pallet-utility/std",
 	"sp-runtime/std",
 	"sp-staking/std",
@@ -194,6 +202,7 @@ runtime-benchmarks = [
 	"pallet-bags-list/runtime-benchmarks",
 	"pallet-balances/runtime-benchmarks",
 	"pallet-collective/runtime-benchmarks",
+	"pallet-conviction-voting/runtime-benchmarks",
 	"pallet-democracy/runtime-benchmarks",
 	"pallet-elections-phragmen/runtime-benchmarks",
 	"pallet-election-provider-multi-phase/runtime-benchmarks",
@@ -209,6 +218,7 @@ runtime-benchmarks = [
 	"pallet-nomination-pools-benchmarking/runtime-benchmarks",
 	"pallet-preimage/runtime-benchmarks",
 	"pallet-proxy/runtime-benchmarks",
+	"pallet-referenda/runtime-benchmarks",
 	"pallet-scheduler/runtime-benchmarks",
 	"pallet-staking/runtime-benchmarks",
 	"pallet-timestamp/runtime-benchmarks",
@@ -218,6 +228,7 @@ runtime-benchmarks = [
 	"pallet-tips/runtime-benchmarks",
 	"pallet-utility/runtime-benchmarks",
 	"pallet-vesting/runtime-benchmarks",
+	"pallet-whitelist/runtime-benchmarks",
 	"pallet-xcm/runtime-benchmarks",
 	"pallet-offences-benchmarking/runtime-benchmarks",
 	"pallet-session-benchmarking/runtime-benchmarks",
@@ -238,6 +249,7 @@ try-runtime = [
 	"pallet-bags-list/try-runtime",
 	"pallet-bounties/try-runtime",
 	"pallet-child-bounties/try-runtime",
+	"pallet-conviction-voting/try-runtime",
 	"pallet-transaction-payment/try-runtime",
 	"pallet-collective/try-runtime",
 	"pallet-elections-phragmen/try-runtime",
@@ -254,6 +266,7 @@ try-runtime = [
 	"pallet-offences/try-runtime",
 	"pallet-preimage/try-runtime",
 	"pallet-proxy/try-runtime",
+	"pallet-referenda/try-runtime",
 	"pallet-scheduler/try-runtime",
 	"pallet-session/try-runtime",
 	"pallet-staking/try-runtime",
@@ -262,6 +275,7 @@ try-runtime = [
 	"pallet-tips/try-runtime",
 	"pallet-babe/try-runtime",
 	"pallet-vesting/try-runtime",
+	"pallet-whitelist/try-runtime",
 	"pallet-utility/try-runtime",
 	"pallet-xcm/try-runtime",
 ]
diff --git a/polkadot/runtime/polkadot/constants/src/lib.rs b/polkadot/runtime/polkadot/constants/src/lib.rs
index c205415acb6..6aec6768e88 100644
--- a/polkadot/runtime/polkadot/constants/src/lib.rs
+++ b/polkadot/runtime/polkadot/constants/src/lib.rs
@@ -29,6 +29,7 @@ pub mod currency {
 
 	pub const UNITS: Balance = 10_000_000_000;
 	pub const DOLLARS: Balance = UNITS; // 10_000_000_000
+	pub const GRAND: Balance = DOLLARS * 1_000; // 10_000_000_000_000
 	pub const CENTS: Balance = DOLLARS / 100; // 100_000_000
 	pub const MILLICENTS: Balance = CENTS / 1_000; // 100_000
 
@@ -110,6 +111,14 @@ pub mod xcm {
 	}
 }
 
+/// System Parachains.
+pub mod system_parachain {
+	/// Statemint parachain ID.
+	pub const STATEMINT_ID: u32 = 1000;
+	/// Collectives parachain ID.
+	pub const COLLECTIVES_ID: u32 = 1001;
+}
+
 #[cfg(test)]
 mod tests {
 	use super::{
diff --git a/polkadot/runtime/polkadot/src/governance/mod.rs b/polkadot/runtime/polkadot/src/governance/mod.rs
new file mode 100644
index 00000000000..a595db33203
--- /dev/null
+++ b/polkadot/runtime/polkadot/src/governance/mod.rs
@@ -0,0 +1,100 @@
+// Copyright 2023 Parity Technologies (UK) Ltd.
+// This file is part of Polkadot.
+
+// Polkadot 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.
+
+// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
+
+//! New governance configurations for the Polkadot runtime.
+
+use super::*;
+use crate::xcm_config::CollectivesLocation;
+use frame_support::{parameter_types, traits::EitherOf};
+use frame_system::EnsureRootWithSuccess;
+use pallet_xcm::{EnsureXcm, IsVoiceOfBody};
+use xcm::latest::BodyId;
+
+// Old governance configurations.
+pub mod old;
+
+mod origins;
+pub use origins::{
+	pallet_custom_origins, AuctionAdmin, FellowshipAdmin, GeneralAdmin, LeaseAdmin,
+	ReferendumCanceller, ReferendumKiller, Spender, StakingAdmin, Treasurer, WhitelistedCaller,
+};
+mod tracks;
+pub use tracks::TracksInfo;
+
+parameter_types! {
+	pub const VoteLockingPeriod: BlockNumber = 7 * DAYS;
+}
+
+impl pallet_conviction_voting::Config for Runtime {
+	type WeightInfo = weights::pallet_conviction_voting::WeightInfo<Self>;
+	type RuntimeEvent = RuntimeEvent;
+	type Currency = Balances;
+	type VoteLockingPeriod = VoteLockingPeriod;
+	type MaxVotes = ConstU32<512>;
+	type MaxTurnout =
+		frame_support::traits::tokens::currency::ActiveIssuanceOf<Balances, Self::AccountId>;
+	type Polls = Referenda;
+}
+
+parameter_types! {
+	pub const AlarmInterval: BlockNumber = 1;
+	pub const SubmissionDeposit: Balance = 1 * DOLLARS;
+	pub const UndecidingTimeout: BlockNumber = 14 * DAYS;
+}
+
+parameter_types! {
+	pub const MaxBalance: Balance = Balance::max_value();
+}
+pub type TreasurySpender = EitherOf<EnsureRootWithSuccess<AccountId, MaxBalance>, Spender>;
+
+impl origins::pallet_custom_origins::Config for Runtime {}
+
+parameter_types! {
+	// Fellows pluralistic body.
+	pub const FellowsBodyId: BodyId = BodyId::Technical;
+}
+
+impl pallet_whitelist::Config for Runtime {
+	type WeightInfo = weights::pallet_whitelist::WeightInfo<Self>;
+	type RuntimeCall = RuntimeCall;
+	type RuntimeEvent = RuntimeEvent;
+	type WhitelistOrigin = EitherOfDiverse<
+		EnsureRoot<Self::AccountId>,
+		EnsureXcm<IsVoiceOfBody<CollectivesLocation, FellowsBodyId>>,
+	>;
+	type DispatchWhitelistedOrigin = EitherOf<EnsureRoot<Self::AccountId>, WhitelistedCaller>;
+	type Preimages = Preimage;
+}
+
+impl pallet_referenda::Config for Runtime {
+	type WeightInfo = weights::pallet_referenda::WeightInfo<Self>;
+	type RuntimeCall = RuntimeCall;
+	type RuntimeEvent = RuntimeEvent;
+	type Scheduler = Scheduler;
+	type Currency = Balances;
+	type SubmitOrigin = frame_system::EnsureSigned<AccountId>;
+	type CancelOrigin = EitherOf<EnsureRoot<AccountId>, ReferendumCanceller>;
+	type KillOrigin = EitherOf<EnsureRoot<AccountId>, ReferendumKiller>;
+	type Slash = Treasury;
+	type Votes = pallet_conviction_voting::VotesOf<Runtime>;
+	type Tally = pallet_conviction_voting::TallyOf<Runtime>;
+	type SubmissionDeposit = SubmissionDeposit;
+	type MaxQueued = ConstU32<100>;
+	type UndecidingTimeout = UndecidingTimeout;
+	type AlarmInterval = AlarmInterval;
+	type Tracks = TracksInfo;
+	type Preimages = Preimage;
+}
diff --git a/polkadot/runtime/kusama/src/governance/old.rs b/polkadot/runtime/polkadot/src/governance/old.rs
similarity index 78%
rename from polkadot/runtime/kusama/src/governance/old.rs
rename to polkadot/runtime/polkadot/src/governance/old.rs
index e50c778d56f..fcded42a20d 100644
--- a/polkadot/runtime/kusama/src/governance/old.rs
+++ b/polkadot/runtime/polkadot/src/governance/old.rs
@@ -1,4 +1,4 @@
-// Copyright 2022 Parity Technologies (UK) Ltd.
+// Copyright 2023 Parity Technologies (UK) Ltd.
 // This file is part of Polkadot.
 
 // Polkadot is free software: you can redistribute it and/or modify
@@ -14,18 +14,18 @@
 // You should have received a copy of the GNU General Public License
 // along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
 
-//! Old governance configurations for the Kusama runtime.
+//! Old governance configurations for the Polkadot runtime.
 
 use crate::*;
 use frame_support::{parameter_types, traits::EitherOfDiverse};
 
 parameter_types! {
-	pub LaunchPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1, "KSM_LAUNCH_PERIOD");
-	pub VotingPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1 * MINUTES, "KSM_VOTING_PERIOD");
-	pub FastTrackVotingPeriod: BlockNumber = prod_or_fast!(3 * HOURS, 1 * MINUTES, "KSM_FAST_TRACK_VOTING_PERIOD");
-	pub const MinimumDeposit: Balance = 100 * CENTS;
-	pub EnactmentPeriod: BlockNumber = prod_or_fast!(8 * DAYS, 1, "KSM_ENACTMENT_PERIOD");
-	pub CooloffPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1 * MINUTES, "KSM_COOLOFF_PERIOD");
+	pub LaunchPeriod: BlockNumber = prod_or_fast!(28 * DAYS, 1, "DOT_LAUNCH_PERIOD");
+	pub VotingPeriod: BlockNumber = prod_or_fast!(28 * DAYS, 1 * MINUTES, "DOT_VOTING_PERIOD");
+	pub FastTrackVotingPeriod: BlockNumber = prod_or_fast!(3 * HOURS, 1 * MINUTES, "DOT_FAST_TRACK_VOTING_PERIOD");
+	pub const MinimumDeposit: Balance = 100 * DOLLARS;
+	pub EnactmentPeriod: BlockNumber = prod_or_fast!(28 * DAYS, 1, "DOT_ENACTMENT_PERIOD");
+	pub CooloffPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1, "DOT_COOLOFF_PERIOD");
 	pub const InstantAllowed: bool = true;
 	pub const MaxVotes: u32 = 100;
 	pub const MaxProposals: u32 = 100;
@@ -41,35 +41,45 @@ impl pallet_democracy::Config for Runtime {
 	type MinimumDeposit = MinimumDeposit;
 	type SubmitOrigin = frame_system::EnsureSigned<AccountId>;
 	/// A straight majority of the council can decide what their next motion is.
-	type ExternalOrigin =
-		pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 2>;
-	/// A majority can have the next scheduled referendum be a straight majority-carries vote.
-	type ExternalMajorityOrigin =
-		pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 2>;
+	type ExternalOrigin = EitherOfDiverse<
+		pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 2>,
+		frame_system::EnsureRoot<AccountId>,
+	>;
+	/// A 60% super-majority can have the next scheduled referendum be a straight majority-carries vote.
+	type ExternalMajorityOrigin = EitherOfDiverse<
+		pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 3, 5>,
+		frame_system::EnsureRoot<AccountId>,
+	>;
 	/// A unanimous council can have the next scheduled referendum be a straight default-carries
 	/// (NTB) vote.
-	type ExternalDefaultOrigin =
-		pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 1>;
+	type ExternalDefaultOrigin = EitherOfDiverse<
+		pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 1>,
+		frame_system::EnsureRoot<AccountId>,
+	>;
 	/// Two thirds of the technical committee can have an `ExternalMajority/ExternalDefault` vote
 	/// be tabled immediately and with a shorter voting/enactment period.
-	type FastTrackOrigin =
-		pallet_collective::EnsureProportionAtLeast<AccountId, TechnicalCollective, 2, 3>;
-	type InstantOrigin =
-		pallet_collective::EnsureProportionAtLeast<AccountId, TechnicalCollective, 1, 1>;
+	type FastTrackOrigin = EitherOfDiverse<
+		pallet_collective::EnsureProportionAtLeast<AccountId, TechnicalCollective, 2, 3>,
+		frame_system::EnsureRoot<AccountId>,
+	>;
+	type InstantOrigin = EitherOfDiverse<
+		pallet_collective::EnsureProportionAtLeast<AccountId, TechnicalCollective, 1, 1>,
+		frame_system::EnsureRoot<AccountId>,
+	>;
 	type InstantAllowed = InstantAllowed;
 	type FastTrackVotingPeriod = FastTrackVotingPeriod;
 	// To cancel a proposal which has been passed, 2/3 of the council must agree to it.
 	type CancellationOrigin = EitherOfDiverse<
-		EnsureRoot<AccountId>,
 		pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 2, 3>,
+		EnsureRoot<AccountId>,
 	>;
-	type BlacklistOrigin = EnsureRoot<AccountId>;
 	// To cancel a proposal before it has been passed, the technical committee must be unanimous or
 	// Root must agree.
 	type CancelProposalOrigin = EitherOfDiverse<
-		EnsureRoot<AccountId>,
 		pallet_collective::EnsureProportionAtLeast<AccountId, TechnicalCollective, 1, 1>,
+		EnsureRoot<AccountId>,
 	>;
+	type BlacklistOrigin = EnsureRoot<AccountId>;
 	// Any single technical committee member may veto a coming council proposal, however they can
 	// only do it once and it lasts only for the cooloff period.
 	type VetoOrigin = pallet_collective::EnsureMember<AccountId, TechnicalCollective>;
@@ -86,7 +96,7 @@ impl pallet_democracy::Config for Runtime {
 }
 
 parameter_types! {
-	pub CouncilMotionDuration: BlockNumber = prod_or_fast!(3 * DAYS, 2 * MINUTES, "KSM_MOTION_DURATION");
+	pub CouncilMotionDuration: BlockNumber = prod_or_fast!(7 * DAYS, 2 * MINUTES, "DOT_MOTION_DURATION");
 	pub const CouncilMaxProposals: u32 = 100;
 	pub const CouncilMaxMembers: u32 = 100;
 }
@@ -105,26 +115,27 @@ impl pallet_collective::Config<CouncilCollective> for Runtime {
 }
 
 parameter_types! {
-	pub const CandidacyBond: Balance = 100 * CENTS;
+	pub const CandidacyBond: Balance = 100 * DOLLARS;
 	// 1 storage item created, key size is 32 bytes, value size is 16+16.
 	pub const VotingBondBase: Balance = deposit(1, 64);
 	// additional data per vote is 32 bytes (account id).
 	pub const VotingBondFactor: Balance = deposit(0, 32);
-	/// Daily council elections
-	pub TermDuration: BlockNumber = prod_or_fast!(24 * HOURS, 2 * MINUTES, "KSM_TERM_DURATION");
-	pub const DesiredMembers: u32 = 19;
-	pub const DesiredRunnersUp: u32 = 19;
-	pub const MaxVotesPerVoter: u32 = 16;
+	/// Weekly council elections; scaling up to monthly eventually.
+	pub TermDuration: BlockNumber = prod_or_fast!(7 * DAYS, 2 * MINUTES, "DOT_TERM_DURATION");
+	/// 13 members initially, to be increased to 23 eventually.
+	pub const DesiredMembers: u32 = 13;
+	pub const DesiredRunnersUp: u32 = 20;
 	pub const MaxVoters: u32 = 10 * 1000;
+	pub const MaxVotesPerVoter: u32 = 16;
 	pub const MaxCandidates: u32 = 1000;
 	pub const PhragmenElectionPalletId: LockIdentifier = *b"phrelect";
 }
-
-// Make sure that there are no more than `MaxMembers` members elected via Phragmen.
+// Make sure that there are no more than `MaxMembers` members elected via phragmen.
 const_assert!(DesiredMembers::get() <= CouncilMaxMembers::get());
 
 impl pallet_elections_phragmen::Config for Runtime {
 	type RuntimeEvent = RuntimeEvent;
+	type PalletId = PhragmenElectionPalletId;
 	type Currency = Balances;
 	type ChangeMembers = Council;
 	type InitializeMembers = Council;
@@ -138,14 +149,13 @@ impl pallet_elections_phragmen::Config for Runtime {
 	type DesiredRunnersUp = DesiredRunnersUp;
 	type TermDuration = TermDuration;
 	type MaxVoters = MaxVoters;
-	type MaxCandidates = MaxCandidates;
 	type MaxVotesPerVoter = MaxVotesPerVoter;
-	type PalletId = PhragmenElectionPalletId;
+	type MaxCandidates = MaxCandidates;
 	type WeightInfo = weights::pallet_elections_phragmen::WeightInfo<Runtime>;
 }
 
 parameter_types! {
-	pub TechnicalMotionDuration: BlockNumber = prod_or_fast!(3 * DAYS, 2 * MINUTES, "KSM_MOTION_DURATION");
+	pub const TechnicalMotionDuration: BlockNumber = 7 * DAYS;
 	pub const TechnicalMaxProposals: u32 = 100;
 	pub const TechnicalMaxMembers: u32 = 100;
 }
diff --git a/polkadot/runtime/polkadot/src/governance/origins.rs b/polkadot/runtime/polkadot/src/governance/origins.rs
new file mode 100644
index 00000000000..0cf5834d1f4
--- /dev/null
+++ b/polkadot/runtime/polkadot/src/governance/origins.rs
@@ -0,0 +1,151 @@
+// Copyright 2023 Parity Technologies (UK) Ltd.
+// This file is part of Polkadot.
+
+// Polkadot 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.
+
+// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
+
+//! Custom origins for governance interventions.
+
+pub use pallet_custom_origins::*;
+
+#[frame_support::pallet]
+pub mod pallet_custom_origins {
+	use crate::{Balance, DOLLARS, GRAND};
+	use frame_support::pallet_prelude::*;
+
+	#[pallet::config]
+	pub trait Config: frame_system::Config {}
+
+	#[pallet::pallet]
+	pub struct Pallet<T>(_);
+
+	#[derive(PartialEq, Eq, Clone, MaxEncodedLen, Encode, Decode, TypeInfo, RuntimeDebug)]
+	#[pallet::origin]
+	pub enum Origin {
+		/// Origin able to cancel slashes and manage minimum commission.
+		StakingAdmin,
+		/// Origin for spending up to $10,000,000 DOT from the treasury as well as generally
+		/// administering it.
+		Treasurer,
+		/// Origin for managing the composition of the fellowship.
+		FellowshipAdmin,
+		/// Origin for managing the registrar.
+		GeneralAdmin,
+		/// Origin for starting auctions.
+		AuctionAdmin,
+		/// Origin able to force slot leases.
+		LeaseAdmin,
+		/// Origin able to cancel referenda.
+		ReferendumCanceller,
+		/// Origin able to kill referenda.
+		ReferendumKiller,
+		/// Origin able to spend around $250 from the treasury at once.
+		SmallTipper,
+		/// Origin able to spend around $1,000 from the treasury at once.
+		BigTipper,
+		/// Origin able to spend around $10,000 from the treasury at once.
+		SmallSpender,
+		/// Origin able to spend around $100,000 from the treasury at once.
+		MediumSpender,
+		/// Origin able to spend up to $1,000,000 DOT from the treasury at once.
+		BigSpender,
+		/// Origin able to dispatch a whitelisted call.
+		WhitelistedCaller,
+	}
+
+	macro_rules! decl_unit_ensures {
+		( $name:ident: $success_type:ty = $success:expr ) => {
+			pub struct $name;
+			impl<O: Into<Result<Origin, O>> + From<Origin>>
+				EnsureOrigin<O> for $name
+			{
+				type Success = $success_type;
+				fn try_origin(o: O) -> Result<Self::Success, O> {
+					o.into().and_then(|o| match o {
+						Origin::$name => Ok($success),
+						r => Err(O::from(r)),
+					})
+				}
+				#[cfg(feature = "runtime-benchmarks")]
+				fn try_successful_origin() -> Result<O, ()> {
+					Ok(O::from(Origin::$name))
+				}
+			}
+		};
+		( $name:ident ) => { decl_unit_ensures! { $name : () = () } };
+		( $name:ident: $success_type:ty = $success:expr, $( $rest:tt )* ) => {
+			decl_unit_ensures! { $name: $success_type = $success }
+			decl_unit_ensures! { $( $rest )* }
+		};
+		( $name:ident, $( $rest:tt )* ) => {
+			decl_unit_ensures! { $name }
+			decl_unit_ensures! { $( $rest )* }
+		};
+		() => {}
+	}
+	decl_unit_ensures!(
+		StakingAdmin,
+		Treasurer,
+		FellowshipAdmin,
+		GeneralAdmin,
+		AuctionAdmin,
+		LeaseAdmin,
+		ReferendumCanceller,
+		ReferendumKiller,
+		WhitelistedCaller,
+	);
+
+	macro_rules! decl_ensure {
+		(
+			$vis:vis type $name:ident: EnsureOrigin<Success = $success_type:ty> {
+				$( $item:ident = $success:expr, )*
+			}
+		) => {
+			$vis struct $name;
+			impl<O: Into<Result<Origin, O>> + From<Origin>>
+				EnsureOrigin<O> for $name
+			{
+				type Success = $success_type;
+				fn try_origin(o: O) -> Result<Self::Success, O> {
+					o.into().and_then(|o| match o {
+						$(
+							Origin::$item => Ok($success),
+						)*
+						r => Err(O::from(r)),
+					})
+				}
+				#[cfg(feature = "runtime-benchmarks")]
+				fn try_successful_origin() -> Result<O, ()> {
+					// By convention the more privileged origins go later, so for greatest chance
+					// of success, we want the last one.
+					let _result: Result<O, ()> = Err(());
+					$(
+						let _result: Result<O, ()> = Ok(O::from(Origin::$item));
+					)*
+					_result
+				}
+			}
+		}
+	}
+
+	decl_ensure! {
+		pub type Spender: EnsureOrigin<Success = Balance> {
+			SmallTipper = 250 * DOLLARS,
+			BigTipper = 1 * GRAND,
+			SmallSpender = 10 * GRAND,
+			MediumSpender = 100 * GRAND,
+			BigSpender = 1_000 * GRAND,
+			Treasurer = 10_000 * GRAND,
+		}
+	}
+}
diff --git a/polkadot/runtime/polkadot/src/governance/tracks.rs b/polkadot/runtime/polkadot/src/governance/tracks.rs
new file mode 100644
index 00000000000..862ab79c73a
--- /dev/null
+++ b/polkadot/runtime/polkadot/src/governance/tracks.rs
@@ -0,0 +1,319 @@
+// Copyright 2023 Parity Technologies (UK) Ltd.
+// This file is part of Polkadot.
+
+// Polkadot 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.
+
+// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
+
+//! Track configurations for governance.
+
+use super::*;
+
+const fn percent(x: i32) -> sp_arithmetic::FixedI64 {
+	sp_arithmetic::FixedI64::from_rational(x as u128, 100)
+}
+use pallet_referenda::Curve;
+const APP_ROOT: Curve = Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100));
+const SUP_ROOT: Curve = Curve::make_linear(28, 28, percent(0), percent(50));
+const APP_STAKING_ADMIN: Curve = Curve::make_linear(17, 28, percent(50), percent(100));
+const SUP_STAKING_ADMIN: Curve =
+	Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50));
+const APP_TREASURER: Curve = Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100));
+const SUP_TREASURER: Curve = Curve::make_linear(28, 28, percent(0), percent(50));
+const APP_FELLOWSHIP_ADMIN: Curve = Curve::make_linear(17, 28, percent(50), percent(100));
+const SUP_FELLOWSHIP_ADMIN: Curve =
+	Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50));
+const APP_GENERAL_ADMIN: Curve =
+	Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100));
+const SUP_GENERAL_ADMIN: Curve =
+	Curve::make_reciprocal(7, 28, percent(10), percent(0), percent(50));
+const APP_AUCTION_ADMIN: Curve =
+	Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100));
+const SUP_AUCTION_ADMIN: Curve =
+	Curve::make_reciprocal(7, 28, percent(10), percent(0), percent(50));
+const APP_LEASE_ADMIN: Curve = Curve::make_linear(17, 28, percent(50), percent(100));
+const SUP_LEASE_ADMIN: Curve = Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50));
+const APP_REFERENDUM_CANCELLER: Curve = Curve::make_linear(17, 28, percent(50), percent(100));
+const SUP_REFERENDUM_CANCELLER: Curve =
+	Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50));
+const APP_REFERENDUM_KILLER: Curve = Curve::make_linear(17, 28, percent(50), percent(100));
+const SUP_REFERENDUM_KILLER: Curve =
+	Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50));
+const APP_SMALL_TIPPER: Curve = Curve::make_linear(10, 28, percent(50), percent(100));
+const SUP_SMALL_TIPPER: Curve = Curve::make_reciprocal(1, 28, percent(4), percent(0), percent(50));
+const APP_BIG_TIPPER: Curve = Curve::make_linear(10, 28, percent(50), percent(100));
+const SUP_BIG_TIPPER: Curve = Curve::make_reciprocal(8, 28, percent(1), percent(0), percent(50));
+const APP_SMALL_SPENDER: Curve = Curve::make_linear(17, 28, percent(50), percent(100));
+const SUP_SMALL_SPENDER: Curve =
+	Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50));
+const APP_MEDIUM_SPENDER: Curve = Curve::make_linear(23, 28, percent(50), percent(100));
+const SUP_MEDIUM_SPENDER: Curve =
+	Curve::make_reciprocal(16, 28, percent(1), percent(0), percent(50));
+const APP_BIG_SPENDER: Curve = Curve::make_linear(28, 28, percent(50), percent(100));
+const SUP_BIG_SPENDER: Curve = Curve::make_reciprocal(20, 28, percent(1), percent(0), percent(50));
+const APP_WHITELISTED_CALLER: Curve =
+	Curve::make_reciprocal(16, 28 * 24, percent(96), percent(50), percent(100));
+const SUP_WHITELISTED_CALLER: Curve =
+	Curve::make_reciprocal(1, 28, percent(20), percent(5), percent(50));
+
+const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo<Balance, BlockNumber>); 15] = [
+	(
+		0,
+		pallet_referenda::TrackInfo {
+			name: "root",
+			max_deciding: 1,
+			decision_deposit: 100 * GRAND,
+			prepare_period: 2 * HOURS,
+			decision_period: 28 * DAYS,
+			confirm_period: 24 * HOURS,
+			min_enactment_period: 24 * HOURS,
+			min_approval: APP_ROOT,
+			min_support: SUP_ROOT,
+		},
+	),
+	(
+		1,
+		pallet_referenda::TrackInfo {
+			name: "whitelisted_caller",
+			max_deciding: 100,
+			decision_deposit: 10 * GRAND,
+			prepare_period: 30 * MINUTES,
+			decision_period: 28 * DAYS,
+			confirm_period: 10 * MINUTES,
+			min_enactment_period: 10 * MINUTES,
+			min_approval: APP_WHITELISTED_CALLER,
+			min_support: SUP_WHITELISTED_CALLER,
+		},
+	),
+	(
+		10,
+		pallet_referenda::TrackInfo {
+			name: "staking_admin",
+			max_deciding: 10,
+			decision_deposit: 5 * GRAND,
+			prepare_period: 2 * HOURS,
+			decision_period: 28 * DAYS,
+			confirm_period: 3 * HOURS,
+			min_enactment_period: 10 * MINUTES,
+			min_approval: APP_STAKING_ADMIN,
+			min_support: SUP_STAKING_ADMIN,
+		},
+	),
+	(
+		11,
+		pallet_referenda::TrackInfo {
+			name: "treasurer",
+			max_deciding: 10,
+			decision_deposit: 1 * GRAND,
+			prepare_period: 2 * HOURS,
+			decision_period: 28 * DAYS,
+			confirm_period: 3 * HOURS,
+			min_enactment_period: 24 * HOURS,
+			min_approval: APP_TREASURER,
+			min_support: SUP_TREASURER,
+		},
+	),
+	(
+		12,
+		pallet_referenda::TrackInfo {
+			name: "lease_admin",
+			max_deciding: 10,
+			decision_deposit: 5 * GRAND,
+			prepare_period: 2 * HOURS,
+			decision_period: 28 * DAYS,
+			confirm_period: 3 * HOURS,
+			min_enactment_period: 10 * MINUTES,
+			min_approval: APP_LEASE_ADMIN,
+			min_support: SUP_LEASE_ADMIN,
+		},
+	),
+	(
+		13,
+		pallet_referenda::TrackInfo {
+			name: "fellowship_admin",
+			max_deciding: 10,
+			decision_deposit: 5 * GRAND,
+			prepare_period: 2 * HOURS,
+			decision_period: 28 * DAYS,
+			confirm_period: 3 * HOURS,
+			min_enactment_period: 10 * MINUTES,
+			min_approval: APP_FELLOWSHIP_ADMIN,
+			min_support: SUP_FELLOWSHIP_ADMIN,
+		},
+	),
+	(
+		14,
+		pallet_referenda::TrackInfo {
+			name: "general_admin",
+			max_deciding: 10,
+			decision_deposit: 5 * GRAND,
+			prepare_period: 2 * HOURS,
+			decision_period: 28 * DAYS,
+			confirm_period: 3 * HOURS,
+			min_enactment_period: 10 * MINUTES,
+			min_approval: APP_GENERAL_ADMIN,
+			min_support: SUP_GENERAL_ADMIN,
+		},
+	),
+	(
+		15,
+		pallet_referenda::TrackInfo {
+			name: "auction_admin",
+			max_deciding: 10,
+			decision_deposit: 5 * GRAND,
+			prepare_period: 2 * HOURS,
+			decision_period: 28 * DAYS,
+			confirm_period: 3 * HOURS,
+			min_enactment_period: 10 * MINUTES,
+			min_approval: APP_AUCTION_ADMIN,
+			min_support: SUP_AUCTION_ADMIN,
+		},
+	),
+	(
+		20,
+		pallet_referenda::TrackInfo {
+			name: "referendum_canceller",
+			max_deciding: 1_000,
+			decision_deposit: 10 * GRAND,
+			prepare_period: 2 * HOURS,
+			decision_period: 7 * DAYS,
+			confirm_period: 3 * HOURS,
+			min_enactment_period: 10 * MINUTES,
+			min_approval: APP_REFERENDUM_CANCELLER,
+			min_support: SUP_REFERENDUM_CANCELLER,
+		},
+	),
+	(
+		21,
+		pallet_referenda::TrackInfo {
+			name: "referendum_killer",
+			max_deciding: 1_000,
+			decision_deposit: 50 * GRAND,
+			prepare_period: 2 * HOURS,
+			decision_period: 28 * DAYS,
+			confirm_period: 3 * HOURS,
+			min_enactment_period: 10 * MINUTES,
+			min_approval: APP_REFERENDUM_KILLER,
+			min_support: SUP_REFERENDUM_KILLER,
+		},
+	),
+	(
+		30,
+		pallet_referenda::TrackInfo {
+			name: "small_tipper",
+			max_deciding: 200,
+			decision_deposit: 1 * DOLLARS,
+			prepare_period: 1 * MINUTES,
+			decision_period: 7 * DAYS,
+			confirm_period: 10 * MINUTES,
+			min_enactment_period: 1 * MINUTES,
+			min_approval: APP_SMALL_TIPPER,
+			min_support: SUP_SMALL_TIPPER,
+		},
+	),
+	(
+		31,
+		pallet_referenda::TrackInfo {
+			name: "big_tipper",
+			max_deciding: 100,
+			decision_deposit: 10 * DOLLARS,
+			prepare_period: 10 * MINUTES,
+			decision_period: 7 * DAYS,
+			confirm_period: 1 * HOURS,
+			min_enactment_period: 10 * MINUTES,
+			min_approval: APP_BIG_TIPPER,
+			min_support: SUP_BIG_TIPPER,
+		},
+	),
+	(
+		32,
+		pallet_referenda::TrackInfo {
+			name: "small_spender",
+			max_deciding: 50,
+			decision_deposit: 100 * DOLLARS,
+			prepare_period: 4 * HOURS,
+			decision_period: 28 * DAYS,
+			confirm_period: 12 * HOURS,
+			min_enactment_period: 24 * HOURS,
+			min_approval: APP_SMALL_SPENDER,
+			min_support: SUP_SMALL_SPENDER,
+		},
+	),
+	(
+		33,
+		pallet_referenda::TrackInfo {
+			name: "medium_spender",
+			max_deciding: 50,
+			decision_deposit: 200 * DOLLARS,
+			prepare_period: 4 * HOURS,
+			decision_period: 28 * DAYS,
+			confirm_period: 24 * HOURS,
+			min_enactment_period: 24 * HOURS,
+			min_approval: APP_MEDIUM_SPENDER,
+			min_support: SUP_MEDIUM_SPENDER,
+		},
+	),
+	(
+		34,
+		pallet_referenda::TrackInfo {
+			name: "big_spender",
+			max_deciding: 50,
+			decision_deposit: 400 * DOLLARS,
+			prepare_period: 4 * HOURS,
+			decision_period: 28 * DAYS,
+			confirm_period: 48 * HOURS,
+			min_enactment_period: 24 * HOURS,
+			min_approval: APP_BIG_SPENDER,
+			min_support: SUP_BIG_SPENDER,
+		},
+	),
+];
+
+pub struct TracksInfo;
+impl pallet_referenda::TracksInfo<Balance, BlockNumber> for TracksInfo {
+	type Id = u16;
+	type RuntimeOrigin = <RuntimeOrigin as frame_support::traits::OriginTrait>::PalletsOrigin;
+	fn tracks() -> &'static [(Self::Id, pallet_referenda::TrackInfo<Balance, BlockNumber>)] {
+		&TRACKS_DATA[..]
+	}
+	fn track_for(id: &Self::RuntimeOrigin) -> Result<Self::Id, ()> {
+		if let Ok(system_origin) = frame_system::RawOrigin::try_from(id.clone()) {
+			match system_origin {
+				frame_system::RawOrigin::Root => Ok(0),
+				_ => Err(()),
+			}
+		} else if let Ok(custom_origin) = origins::Origin::try_from(id.clone()) {
+			match custom_origin {
+				origins::Origin::WhitelistedCaller => Ok(1),
+				// General admin
+				origins::Origin::StakingAdmin => Ok(10),
+				origins::Origin::Treasurer => Ok(11),
+				origins::Origin::LeaseAdmin => Ok(12),
+				origins::Origin::FellowshipAdmin => Ok(13),
+				origins::Origin::GeneralAdmin => Ok(14),
+				origins::Origin::AuctionAdmin => Ok(15),
+				// Referendum admins
+				origins::Origin::ReferendumCanceller => Ok(20),
+				origins::Origin::ReferendumKiller => Ok(21),
+				// Limited treasury spenders
+				origins::Origin::SmallTipper => Ok(30),
+				origins::Origin::BigTipper => Ok(31),
+				origins::Origin::SmallSpender => Ok(32),
+				origins::Origin::MediumSpender => Ok(33),
+				origins::Origin::BigSpender => Ok(34),
+			}
+		} else {
+			Err(())
+		}
+	}
+}
+pallet_referenda::impl_tracksinfo_get!(TracksInfo, Balance, BlockNumber);
diff --git a/polkadot/runtime/polkadot/src/lib.rs b/polkadot/runtime/polkadot/src/lib.rs
index 12441342f85..cf1bb606fca 100644
--- a/polkadot/runtime/polkadot/src/lib.rs
+++ b/polkadot/runtime/polkadot/src/lib.rs
@@ -47,7 +47,7 @@ use frame_support::{
 	weights::ConstantMultiplier,
 	PalletId, RuntimeDebug,
 };
-use frame_system::{EnsureRoot, EnsureWithSuccess};
+use frame_system::EnsureRoot;
 use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId};
 use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
 use pallet_session::historical as session_historical;
@@ -99,6 +99,13 @@ mod weights;
 
 mod bag_thresholds;
 
+// Governance configurations.
+pub mod governance;
+use governance::{
+	old::CouncilCollective, pallet_custom_origins, AuctionAdmin, FellowshipAdmin, GeneralAdmin,
+	LeaseAdmin, StakingAdmin, Treasurer, TreasurySpender,
+};
+
 pub mod xcm_config;
 
 impl_runtime_weights!(polkadot_runtime_constants);
@@ -137,11 +144,6 @@ pub fn native_version() -> NativeVersion {
 	NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
 }
 
-type MoreThanHalfCouncil = EitherOfDiverse<
-	EnsureRoot<AccountId>,
-	pallet_collective::EnsureProportionMoreThan<AccountId, CouncilCollective, 1, 2>,
->;
-
 parameter_types! {
 	pub const Version: RuntimeVersion = VERSION;
 	pub const SS58Prefix: u8 = 0;
@@ -181,11 +183,6 @@ parameter_types! {
 	pub const NoPreimagePostponement: Option<u32> = Some(10);
 }
 
-type ScheduleOrigin = EitherOfDiverse<
-	EnsureRoot<AccountId>,
-	pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 2>,
->;
-
 /// Used the compare the privilege of an origin inside the scheduler.
 pub struct OriginPrivilegeCmp;
 
@@ -215,7 +212,9 @@ impl pallet_scheduler::Config for Runtime {
 	type PalletsOrigin = OriginCaller;
 	type RuntimeCall = RuntimeCall;
 	type MaximumWeight = MaximumSchedulerWeight;
-	type ScheduleOrigin = ScheduleOrigin;
+	// The goal of having ScheduleOrigin include AuctionAdmin is to allow the auctions track of
+	// OpenGov to schedule periodic auctions.
+	type ScheduleOrigin = EitherOf<EnsureRoot<AccountId>, AuctionAdmin>;
 	type MaxScheduledPerBlock = MaxScheduledPerBlock;
 	type WeightInfo = weights::pallet_scheduler::WeightInfo<Runtime>;
 	type OriginPrivilegeCmp = OriginPrivilegeCmp;
@@ -481,10 +480,7 @@ impl pallet_election_provider_multi_phase::Config for Runtime {
 		(),
 	>;
 	type BenchmarkingConfig = runtime_common::elections::BenchmarkConfig;
-	type ForceOrigin = EitherOfDiverse<
-		EnsureRoot<AccountId>,
-		pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 2, 3>,
-	>;
+	type ForceOrigin = EitherOf<EnsureRoot<Self::AccountId>, StakingAdmin>;
 	type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo<Self>;
 	type MaxElectingVoters = MaxElectingVoters;
 	type MaxElectableTargets = MaxElectableTargets;
@@ -542,11 +538,6 @@ parameter_types! {
 	pub const MaxNominations: u32 = <NposCompactSolution16 as frame_election_provider_support::NposSolution>::LIMIT as u32;
 }
 
-type StakingAdminOrigin = EitherOfDiverse<
-	EnsureRoot<AccountId>,
-	pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 3, 4>,
->;
-
 pub struct EraPayout;
 impl pallet_staking::EraPayout<Balance> for EraPayout {
 	fn era_payout(
@@ -588,7 +579,7 @@ impl pallet_staking::Config for Runtime {
 	type SessionsPerEra = SessionsPerEra;
 	type BondingDuration = BondingDuration;
 	type SlashDeferDuration = SlashDeferDuration;
-	type AdminOrigin = StakingAdminOrigin;
+	type AdminOrigin = EitherOf<EnsureRoot<Self::AccountId>, StakingAdmin>;
 	type SessionInterface = Self;
 	type EraPayout = EraPayout;
 	type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
@@ -610,10 +601,7 @@ impl pallet_fast_unstake::Config for Runtime {
 	type Currency = Balances;
 	type BatchSize = frame_support::traits::ConstU32<16>;
 	type Deposit = frame_support::traits::ConstU128<{ UNITS }>;
-	type ControlOrigin = EitherOfDiverse<
-		EnsureRoot<AccountId>,
-		pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 2>,
-	>;
+	type ControlOrigin = EnsureRoot<AccountId>;
 	type Staking = Staking;
 	type MaxErasToCheckPerBlock = ConstU32<1>;
 	#[cfg(feature = "runtime-benchmarks")]
@@ -641,178 +629,11 @@ impl pallet_identity::Config for Runtime {
 	type MaxAdditionalFields = MaxAdditionalFields;
 	type MaxRegistrars = MaxRegistrars;
 	type Slashed = Treasury;
-	type ForceOrigin = MoreThanHalfCouncil;
-	type RegistrarOrigin = MoreThanHalfCouncil;
+	type ForceOrigin = EitherOf<EnsureRoot<Self::AccountId>, GeneralAdmin>;
+	type RegistrarOrigin = EitherOf<EnsureRoot<Self::AccountId>, GeneralAdmin>;
 	type WeightInfo = weights::pallet_identity::WeightInfo<Runtime>;
 }
 
-parameter_types! {
-	pub LaunchPeriod: BlockNumber = prod_or_fast!(28 * DAYS, 1, "DOT_LAUNCH_PERIOD");
-	pub VotingPeriod: BlockNumber = prod_or_fast!(28 * DAYS, 1 * MINUTES, "DOT_VOTING_PERIOD");
-	pub FastTrackVotingPeriod: BlockNumber = prod_or_fast!(3 * HOURS, 1 * MINUTES, "DOT_FAST_TRACK_VOTING_PERIOD");
-	pub const MinimumDeposit: Balance = 100 * DOLLARS;
-	pub EnactmentPeriod: BlockNumber = prod_or_fast!(28 * DAYS, 1, "DOT_ENACTMENT_PERIOD");
-	pub CooloffPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1, "DOT_COOLOFF_PERIOD");
-	pub const InstantAllowed: bool = true;
-	pub const MaxVotes: u32 = 100;
-	pub const MaxProposals: u32 = 100;
-}
-
-impl pallet_democracy::Config for Runtime {
-	type RuntimeEvent = RuntimeEvent;
-	type Currency = Balances;
-	type EnactmentPeriod = EnactmentPeriod;
-	type VoteLockingPeriod = EnactmentPeriod;
-	type LaunchPeriod = LaunchPeriod;
-	type VotingPeriod = VotingPeriod;
-	type MinimumDeposit = MinimumDeposit;
-	type SubmitOrigin = frame_system::EnsureSigned<AccountId>;
-	/// A straight majority of the council can decide what their next motion is.
-	type ExternalOrigin = EitherOfDiverse<
-		pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 2>,
-		frame_system::EnsureRoot<AccountId>,
-	>;
-	/// A 60% super-majority can have the next scheduled referendum be a straight majority-carries vote.
-	type ExternalMajorityOrigin = EitherOfDiverse<
-		pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 3, 5>,
-		frame_system::EnsureRoot<AccountId>,
-	>;
-	/// A unanimous council can have the next scheduled referendum be a straight default-carries
-	/// (NTB) vote.
-	type ExternalDefaultOrigin = EitherOfDiverse<
-		pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 1>,
-		frame_system::EnsureRoot<AccountId>,
-	>;
-	/// Two thirds of the technical committee can have an `ExternalMajority/ExternalDefault` vote
-	/// be tabled immediately and with a shorter voting/enactment period.
-	type FastTrackOrigin = EitherOfDiverse<
-		pallet_collective::EnsureProportionAtLeast<AccountId, TechnicalCollective, 2, 3>,
-		frame_system::EnsureRoot<AccountId>,
-	>;
-	type InstantOrigin = EitherOfDiverse<
-		pallet_collective::EnsureProportionAtLeast<AccountId, TechnicalCollective, 1, 1>,
-		frame_system::EnsureRoot<AccountId>,
-	>;
-	type InstantAllowed = InstantAllowed;
-	type FastTrackVotingPeriod = FastTrackVotingPeriod;
-	// To cancel a proposal which has been passed, 2/3 of the council must agree to it.
-	type CancellationOrigin = EitherOfDiverse<
-		pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 2, 3>,
-		EnsureRoot<AccountId>,
-	>;
-	// To cancel a proposal before it has been passed, the technical committee must be unanimous or
-	// Root must agree.
-	type CancelProposalOrigin = EitherOfDiverse<
-		pallet_collective::EnsureProportionAtLeast<AccountId, TechnicalCollective, 1, 1>,
-		EnsureRoot<AccountId>,
-	>;
-	type BlacklistOrigin = EnsureRoot<AccountId>;
-	// Any single technical committee member may veto a coming council proposal, however they can
-	// only do it once and it lasts only for the cooloff period.
-	type VetoOrigin = pallet_collective::EnsureMember<AccountId, TechnicalCollective>;
-	type CooloffPeriod = CooloffPeriod;
-	type Slash = Treasury;
-	type Scheduler = Scheduler;
-	type PalletsOrigin = OriginCaller;
-	type MaxVotes = MaxVotes;
-	type WeightInfo = weights::pallet_democracy::WeightInfo<Runtime>;
-	type MaxProposals = MaxProposals;
-	type Preimages = Preimage;
-	type MaxDeposits = ConstU32<100>;
-	type MaxBlacklisted = ConstU32<100>;
-}
-
-parameter_types! {
-	pub CouncilMotionDuration: BlockNumber = prod_or_fast!(7 * DAYS, 2 * MINUTES, "DOT_MOTION_DURATION");
-	pub const CouncilMaxProposals: u32 = 100;
-	pub const CouncilMaxMembers: u32 = 100;
-}
-
-pub type CouncilCollective = pallet_collective::Instance1;
-impl pallet_collective::Config<CouncilCollective> for Runtime {
-	type RuntimeOrigin = RuntimeOrigin;
-	type Proposal = RuntimeCall;
-	type RuntimeEvent = RuntimeEvent;
-	type MotionDuration = CouncilMotionDuration;
-	type MaxProposals = CouncilMaxProposals;
-	type MaxMembers = CouncilMaxMembers;
-	type DefaultVote = pallet_collective::PrimeDefaultVote;
-	type SetMembersOrigin = EnsureRoot<AccountId>;
-	type WeightInfo = weights::pallet_collective_council::WeightInfo<Runtime>;
-}
-
-parameter_types! {
-	pub const CandidacyBond: Balance = 100 * DOLLARS;
-	// 1 storage item created, key size is 32 bytes, value size is 16+16.
-	pub const VotingBondBase: Balance = deposit(1, 64);
-	// additional data per vote is 32 bytes (account id).
-	pub const VotingBondFactor: Balance = deposit(0, 32);
-	/// Weekly council elections; scaling up to monthly eventually.
-	pub TermDuration: BlockNumber = prod_or_fast!(7 * DAYS, 2 * MINUTES, "DOT_TERM_DURATION");
-	/// 13 members initially, to be increased to 23 eventually.
-	pub const DesiredMembers: u32 = 13;
-	pub const DesiredRunnersUp: u32 = 20;
-	pub const MaxVoters: u32 = 10 * 1000;
-	pub const MaxVotesPerVoter: u32 = 16;
-	pub const MaxCandidates: u32 = 1000;
-	pub const PhragmenElectionPalletId: LockIdentifier = *b"phrelect";
-}
-// Make sure that there are no more than `MaxMembers` members elected via phragmen.
-const_assert!(DesiredMembers::get() <= CouncilMaxMembers::get());
-
-impl pallet_elections_phragmen::Config for Runtime {
-	type RuntimeEvent = RuntimeEvent;
-	type PalletId = PhragmenElectionPalletId;
-	type Currency = Balances;
-	type ChangeMembers = Council;
-	type InitializeMembers = Council;
-	type CurrencyToVote = frame_support::traits::U128CurrencyToVote;
-	type CandidacyBond = CandidacyBond;
-	type VotingBondBase = VotingBondBase;
-	type VotingBondFactor = VotingBondFactor;
-	type LoserCandidate = Treasury;
-	type KickedMember = Treasury;
-	type DesiredMembers = DesiredMembers;
-	type DesiredRunnersUp = DesiredRunnersUp;
-	type TermDuration = TermDuration;
-	type MaxVoters = MaxVoters;
-	type MaxVotesPerVoter = MaxVotesPerVoter;
-	type MaxCandidates = MaxCandidates;
-	type WeightInfo = weights::pallet_elections_phragmen::WeightInfo<Runtime>;
-}
-
-parameter_types! {
-	pub const TechnicalMotionDuration: BlockNumber = 7 * DAYS;
-	pub const TechnicalMaxProposals: u32 = 100;
-	pub const TechnicalMaxMembers: u32 = 100;
-}
-
-pub type TechnicalCollective = pallet_collective::Instance2;
-impl pallet_collective::Config<TechnicalCollective> for Runtime {
-	type RuntimeOrigin = RuntimeOrigin;
-	type Proposal = RuntimeCall;
-	type RuntimeEvent = RuntimeEvent;
-	type MotionDuration = TechnicalMotionDuration;
-	type MaxProposals = TechnicalMaxProposals;
-	type MaxMembers = TechnicalMaxMembers;
-	type DefaultVote = pallet_collective::PrimeDefaultVote;
-	type SetMembersOrigin = EnsureRoot<AccountId>;
-	type WeightInfo = weights::pallet_collective_technical_committee::WeightInfo<Runtime>;
-}
-
-impl pallet_membership::Config<pallet_membership::Instance1> for Runtime {
-	type RuntimeEvent = RuntimeEvent;
-	type AddOrigin = MoreThanHalfCouncil;
-	type RemoveOrigin = MoreThanHalfCouncil;
-	type SwapOrigin = MoreThanHalfCouncil;
-	type ResetOrigin = MoreThanHalfCouncil;
-	type PrimeOrigin = MoreThanHalfCouncil;
-	type MembershipInitialized = TechnicalCommittee;
-	type MembershipChanged = TechnicalCommittee;
-	type MaxMembers = TechnicalMaxMembers;
-	type WeightInfo = weights::pallet_membership::WeightInfo<Runtime>;
-}
-
 parameter_types! {
 	pub const ProposalBond: Permill = Permill::from_percent(5);
 	pub const ProposalBondMinimum: Balance = 100 * DOLLARS;
@@ -834,16 +655,11 @@ parameter_types! {
 	pub const CouncilSpendOriginMaxAmount: Balance = Balance::MAX;
 }
 
-type ApproveOrigin = EitherOfDiverse<
-	EnsureRoot<AccountId>,
-	pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 3, 5>,
->;
-
 impl pallet_treasury::Config for Runtime {
 	type PalletId = TreasuryPalletId;
 	type Currency = Balances;
-	type ApproveOrigin = ApproveOrigin;
-	type RejectOrigin = MoreThanHalfCouncil;
+	type ApproveOrigin = EitherOfDiverse<EnsureRoot<AccountId>, Treasurer>;
+	type RejectOrigin = EitherOfDiverse<EnsureRoot<AccountId>, Treasurer>;
 	type RuntimeEvent = RuntimeEvent;
 	type OnSlash = Treasury;
 	type ProposalBond = ProposalBond;
@@ -855,14 +671,7 @@ impl pallet_treasury::Config for Runtime {
 	type SpendFunds = Bounties;
 	type MaxApprovals = MaxApprovals;
 	type WeightInfo = weights::pallet_treasury::WeightInfo<Runtime>;
-	type SpendOrigin = EitherOf<
-		frame_system::EnsureRootWithSuccess<AccountId, RootSpendOriginMaxAmount>,
-		EnsureWithSuccess<
-			pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 3, 5>,
-			AccountId,
-			CouncilSpendOriginMaxAmount,
-		>,
-	>;
+	type SpendOrigin = TreasurySpender;
 }
 
 parameter_types! {
@@ -1035,9 +844,8 @@ impl claims::Config for Runtime {
 	type RuntimeEvent = RuntimeEvent;
 	type VestingSchedule = Vesting;
 	type Prefix = Prefix;
-	/// At least 3/4 of the council must agree to a claim move before it can happen.
-	type MoveClaimOrigin =
-		pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 3, 4>;
+	/// Only Root can move a claim.
+	type MoveClaimOrigin = EnsureRoot<AccountId>;
 	type WeightInfo = weights::runtime_common_claims::WeightInfo<Runtime>;
 }
 
@@ -1182,6 +990,9 @@ impl InstanceFilter<RuntimeCall> for ProxyType {
 				RuntimeCall::Bounties(..) |
 				RuntimeCall::ChildBounties(..) |
 				RuntimeCall::Tips(..) |
+				RuntimeCall::ConvictionVoting(..) |
+				RuntimeCall::Referenda(..) |
+				RuntimeCall::Whitelist(..) |
 				RuntimeCall::Claims(..) |
 				RuntimeCall::Vesting(pallet_vesting::Call::vest{..}) |
 				RuntimeCall::Vesting(pallet_vesting::Call::vest_other{..}) |
@@ -1210,7 +1021,10 @@ impl InstanceFilter<RuntimeCall> for ProxyType {
 						RuntimeCall::Treasury(..) |
 						RuntimeCall::Bounties(..) |
 						RuntimeCall::Tips(..) | RuntimeCall::Utility(..) |
-						RuntimeCall::ChildBounties(..)
+						RuntimeCall::ChildBounties(..) |
+						RuntimeCall::ConvictionVoting(..) |
+						RuntimeCall::Referenda(..) |
+						RuntimeCall::Whitelist(..)
 				),
 			ProxyType::Staking => {
 				matches!(
@@ -1367,7 +1181,7 @@ impl slots::Config for Runtime {
 	type Registrar = Registrar;
 	type LeasePeriod = LeasePeriod;
 	type LeaseOffset = LeaseOffset;
-	type ForceOrigin = MoreThanHalfCouncil;
+	type ForceOrigin = EitherOf<EnsureRoot<Self::AccountId>, LeaseAdmin>;
 	type WeightInfo = weights::runtime_common_slots::WeightInfo<Runtime>;
 }
 
@@ -1403,11 +1217,6 @@ parameter_types! {
 	pub const SampleLength: BlockNumber = 2 * MINUTES;
 }
 
-type AuctionInitiate = EitherOfDiverse<
-	EnsureRoot<AccountId>,
-	pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 2, 3>,
->;
-
 impl auctions::Config for Runtime {
 	type RuntimeEvent = RuntimeEvent;
 	type Leaser = Slots;
@@ -1415,7 +1224,7 @@ impl auctions::Config for Runtime {
 	type EndingPeriod = EndingPeriod;
 	type SampleLength = SampleLength;
 	type Randomness = pallet_babe::RandomnessFromOneEpochAgo<Runtime>;
-	type InitiateOrigin = AuctionInitiate;
+	type InitiateOrigin = AuctionAdmin;
 	type WeightInfo = weights::runtime_common_auctions::WeightInfo<Runtime>;
 }
 
@@ -1496,7 +1305,7 @@ construct_runtime! {
 		ImOnline: pallet_im_online::{Pallet, Call, Storage, Event<T>, ValidateUnsigned, Config<T>} = 12,
 		AuthorityDiscovery: pallet_authority_discovery::{Pallet, Config} = 13,
 
-		// Governance stuff.
+		// Old governance stuff.
 		Democracy: pallet_democracy::{Pallet, Call, Storage, Config<T>, Event<T>} = 14,
 		Council: pallet_collective::<Instance1>::{Pallet, Call, Storage, Origin<T>, Event<T>, Config<T>} = 15,
 		TechnicalCommittee: pallet_collective::<Instance2>::{Pallet, Call, Storage, Origin<T>, Event<T>, Config<T>} = 16,
@@ -1504,6 +1313,11 @@ construct_runtime! {
 		TechnicalMembership: pallet_membership::<Instance1>::{Pallet, Call, Storage, Event<T>, Config<T>} = 18,
 		Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event<T>} = 19,
 
+		// OpenGov stuff.
+		ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event<T>} = 20,
+		Referenda: pallet_referenda::{Pallet, Call, Storage, Event<T>} = 21,
+		Origins: pallet_custom_origins::{Origin} = 22,
+		Whitelist: pallet_whitelist::{Pallet, Call, Storage, Event<T>} = 23,
 
 		// Claims. Usable initially.
 		Claims: claims::{Pallet, Call, Storage, Event<T>, Config<T>, ValidateUnsigned} = 24,
@@ -1675,6 +1489,9 @@ mod benches {
 		[pallet_treasury, Treasury]
 		[pallet_utility, Utility]
 		[pallet_vesting, Vesting]
+		[pallet_conviction_voting, ConvictionVoting]
+		[pallet_referenda, Referenda]
+		[pallet_whitelist, Whitelist]
 		// XCM
 		[pallet_xcm, XcmPallet]
 	);
@@ -2177,6 +1994,7 @@ sp_api::impl_runtime_apis! {
 #[cfg(test)]
 mod test_fees {
 	use super::*;
+	use crate::governance::old::*;
 	use frame_support::{dispatch::GetDispatchInfo, weights::WeightToFee as WeightToFeeT};
 	use keyring::Sr25519Keyring::{Alice, Charlie};
 	use pallet_transaction_payment::Multiplier;
diff --git a/polkadot/runtime/polkadot/src/weights/mod.rs b/polkadot/runtime/polkadot/src/weights/mod.rs
index cef8d5d00aa..f14ee2eef6f 100644
--- a/polkadot/runtime/polkadot/src/weights/mod.rs
+++ b/polkadot/runtime/polkadot/src/weights/mod.rs
@@ -23,6 +23,7 @@ pub mod pallet_bounties;
 pub mod pallet_child_bounties;
 pub mod pallet_collective_council;
 pub mod pallet_collective_technical_committee;
+pub mod pallet_conviction_voting;
 pub mod pallet_democracy;
 pub mod pallet_election_provider_multi_phase;
 pub mod pallet_elections_phragmen;
@@ -35,6 +36,7 @@ pub mod pallet_multisig;
 pub mod pallet_nomination_pools;
 pub mod pallet_preimage;
 pub mod pallet_proxy;
+pub mod pallet_referenda;
 pub mod pallet_scheduler;
 pub mod pallet_session;
 pub mod pallet_staking;
@@ -43,6 +45,7 @@ pub mod pallet_tips;
 pub mod pallet_treasury;
 pub mod pallet_utility;
 pub mod pallet_vesting;
+pub mod pallet_whitelist;
 pub mod pallet_xcm;
 pub mod runtime_common_auctions;
 pub mod runtime_common_claims;
diff --git a/polkadot/runtime/polkadot/src/weights/pallet_conviction_voting.rs b/polkadot/runtime/polkadot/src/weights/pallet_conviction_voting.rs
new file mode 100644
index 00000000000..82f6ea3acb8
--- /dev/null
+++ b/polkadot/runtime/polkadot/src/weights/pallet_conviction_voting.rs
@@ -0,0 +1,172 @@
+// Copyright 2017-2022 Parity Technologies (UK) Ltd.
+// This file is part of Polkadot.
+
+// Polkadot 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.
+
+// Polkadot 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 Polkadot.  If not, see <http://www.gnu.org/licenses/>.
+//! Autogenerated weights for `pallet_conviction_voting`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-03-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `cob`, CPU: `<UNKNOWN>`
+//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot
+// benchmark
+// pallet
+// --chain=polkadot-dev
+// --steps=2
+// --repeat=1
+// --pallet=pallet_conviction_voting
+// --extrinsic=*
+// --execution=wasm
+// --wasm-execution=compiled
+// --header=./file_header.txt
+// --output=./runtime/polkadot/src/weights/
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+
+use frame_support::{traits::Get, weights::Weight};
+use sp_std::marker::PhantomData;
+
+/// Weight functions for `pallet_conviction_voting`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> pallet_conviction_voting::WeightInfo for WeightInfo<T> {
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: ConvictionVoting VotingFor (r:1 w:1)
+	/// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen)
+	/// Storage: ConvictionVoting ClassLocksFor (r:1 w:1)
+	/// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen)
+	/// Storage: Balances Locks (r:1 w:1)
+	/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:1 w:1)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn vote_new() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `13612`
+		//  Estimated: `86075`
+		// Minimum execution time: 174_000_000 picoseconds.
+		Weight::from_parts(174_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 86075))
+			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().writes(5))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: ConvictionVoting VotingFor (r:1 w:1)
+	/// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen)
+	/// Storage: ConvictionVoting ClassLocksFor (r:1 w:1)
+	/// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen)
+	/// Storage: Balances Locks (r:1 w:1)
+	/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:2 w:2)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn vote_existing() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `14364`
+		//  Estimated: `127513`
+		// Minimum execution time: 240_000_000 picoseconds.
+		Weight::from_parts(240_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 127513))
+			.saturating_add(T::DbWeight::get().reads(6))
+			.saturating_add(T::DbWeight::get().writes(6))
+	}
+	/// Storage: ConvictionVoting VotingFor (r:1 w:1)
+	/// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen)
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:2 w:2)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn remove_vote() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `14084`
+		//  Estimated: `118973`
+		// Minimum execution time: 219_000_000 picoseconds.
+		Weight::from_parts(219_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 118973))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(4))
+	}
+	/// Storage: ConvictionVoting VotingFor (r:1 w:1)
+	/// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen)
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:0)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	fn remove_other_vote() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `13139`
+		//  Estimated: `35107`
+		// Minimum execution time: 109_000_000 picoseconds.
+		Weight::from_parts(109_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 35107))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	/// Storage: ConvictionVoting VotingFor (r:2 w:2)
+	/// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen)
+	/// Storage: Referenda ReferendumInfoFor (r:512 w:512)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:2 w:2)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	/// Storage: ConvictionVoting ClassLocksFor (r:1 w:1)
+	/// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen)
+	/// Storage: Balances Locks (r:1 w:1)
+	/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
+	/// The range of component `r` is `[0, 512]`.
+	fn delegate(_r: u32, ) -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `272 + r * (427 ±0)`
+		//  Estimated: `1900250`
+		// Minimum execution time: 86_000_000 picoseconds.
+		Weight::from_parts(27_182_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 1900250))
+			.saturating_add(T::DbWeight::get().reads(518))
+			.saturating_add(T::DbWeight::get().writes(518))
+	}
+	/// Storage: ConvictionVoting VotingFor (r:2 w:2)
+	/// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen)
+	/// Storage: Referenda ReferendumInfoFor (r:512 w:512)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:2 w:2)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	/// The range of component `r` is `[0, 512]`.
+	fn undelegate(_r: u32, ) -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `470 + r * (426 ±0)`
+		//  Estimated: `1891710`
+		// Minimum execution time: 59_000_000 picoseconds.
+		Weight::from_parts(27_242_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 1891710))
+			.saturating_add(T::DbWeight::get().reads(516))
+			.saturating_add(T::DbWeight::get().writes(516))
+	}
+	/// Storage: ConvictionVoting VotingFor (r:1 w:1)
+	/// Proof: ConvictionVoting VotingFor (max_values: None, max_size: Some(27241), added: 29716, mode: MaxEncodedLen)
+	/// Storage: ConvictionVoting ClassLocksFor (r:1 w:1)
+	/// Proof: ConvictionVoting ClassLocksFor (max_values: None, max_size: Some(311), added: 2786, mode: MaxEncodedLen)
+	/// Storage: Balances Locks (r:1 w:1)
+	/// Proof: Balances Locks (max_values: None, max_size: Some(1299), added: 3774, mode: MaxEncodedLen)
+	fn unlock() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `12385`
+		//  Estimated: `39246`
+		// Minimum execution time: 121_000_000 picoseconds.
+		Weight::from_parts(121_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 39246))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+}
diff --git a/polkadot/runtime/polkadot/src/weights/pallet_referenda.rs b/polkadot/runtime/polkadot/src/weights/pallet_referenda.rs
new file mode 100644
index 00000000000..5ebe89b6948
--- /dev/null
+++ b/polkadot/runtime/polkadot/src/weights/pallet_referenda.rs
@@ -0,0 +1,520 @@
+// Copyright 2017-2022 Parity Technologies (UK) Ltd.
+// This file is part of Polkadot.
+
+// Polkadot 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.
+
+// Polkadot 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 Polkadot.  If not, see <http://www.gnu.org/licenses/>.
+//! Autogenerated weights for `pallet_referenda`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-03-07, STEPS: `1`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `cob`, CPU: `<UNKNOWN>`
+//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot
+// benchmark
+// pallet
+// --chain=polkadot-dev
+// --steps=1
+// --repeat=1
+// --pallet=pallet_referenda
+// --extrinsic=*
+// --execution=wasm
+// --wasm-execution=compiled
+// --header=./file_header.txt
+// --output=./runtime/polkadot/src/weights/
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+
+use frame_support::{traits::Get, weights::Weight};
+use sp_std::marker::PhantomData;
+
+/// Weight functions for `pallet_referenda`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> pallet_referenda::WeightInfo for WeightInfo<T> {
+	/// Storage: Referenda ReferendumCount (r:1 w:1)
+	/// Proof: Referenda ReferendumCount (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:1 w:1)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	/// Storage: Referenda ReferendumInfoFor (r:0 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	fn submit() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `290`
+		//  Estimated: `43917`
+		// Minimum execution time: 54_000_000 picoseconds.
+		Weight::from_parts(54_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 43917))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:2 w:2)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn place_decision_deposit_preparing() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `575`
+		//  Estimated: `88267`
+		// Minimum execution time: 64_000_000 picoseconds.
+		Weight::from_parts(64_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 88267))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Referenda DecidingCount (r:1 w:0)
+	/// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen)
+	/// Storage: Referenda TrackQueue (r:1 w:1)
+	/// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen)
+	fn place_decision_deposit_queued() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `3203`
+		//  Estimated: `13357`
+		// Minimum execution time: 82_000_000 picoseconds.
+		Weight::from_parts(82_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 13357))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Referenda DecidingCount (r:1 w:0)
+	/// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen)
+	/// Storage: Referenda TrackQueue (r:1 w:1)
+	/// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen)
+	fn place_decision_deposit_not_queued() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `3223`
+		//  Estimated: `13357`
+		// Minimum execution time: 59_000_000 picoseconds.
+		Weight::from_parts(59_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 13357))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Referenda DecidingCount (r:1 w:1)
+	/// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen)
+	/// Storage: Balances InactiveIssuance (r:1 w:0)
+	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:2 w:2)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn place_decision_deposit_passing() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `575`
+		//  Estimated: `93247`
+		// Minimum execution time: 142_000_000 picoseconds.
+		Weight::from_parts(142_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 93247))
+			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().writes(4))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Referenda DecidingCount (r:1 w:1)
+	/// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen)
+	/// Storage: Balances InactiveIssuance (r:1 w:0)
+	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
+	fn place_decision_deposit_failing() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `482`
+		//  Estimated: `9381`
+		// Minimum execution time: 54_000_000 picoseconds.
+		Weight::from_parts(54_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 9381))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	fn refund_decision_deposit() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `415`
+		//  Estimated: `4401`
+		// Minimum execution time: 35_000_000 picoseconds.
+		Weight::from_parts(35_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 4401))
+			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	fn refund_submission_deposit() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `405`
+		//  Estimated: `4401`
+		// Minimum execution time: 36_000_000 picoseconds.
+		Weight::from_parts(36_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 4401))
+			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:2 w:2)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn cancel() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `451`
+		//  Estimated: `88267`
+		// Minimum execution time: 52_000_000 picoseconds.
+		Weight::from_parts(52_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 88267))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:2 w:2)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	/// Storage: Referenda MetadataOf (r:1 w:0)
+	/// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen)
+	fn kill() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `756`
+		//  Estimated: `91784`
+		// Minimum execution time: 141_000_000 picoseconds.
+		Weight::from_parts(141_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 91784))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: Referenda TrackQueue (r:1 w:0)
+	/// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen)
+	/// Storage: Referenda DecidingCount (r:1 w:1)
+	/// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen)
+	fn one_fewer_deciding_queue_empty() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `174`
+		//  Estimated: `8956`
+		// Minimum execution time: 12_000_000 picoseconds.
+		Weight::from_parts(12_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 8956))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	/// Storage: Referenda TrackQueue (r:1 w:1)
+	/// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen)
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Balances InactiveIssuance (r:1 w:0)
+	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:2 w:2)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn one_fewer_deciding_failing() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `3972`
+		//  Estimated: `95245`
+		// Minimum execution time: 139_000_000 picoseconds.
+		Weight::from_parts(139_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 95245))
+			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().writes(4))
+	}
+	/// Storage: Referenda TrackQueue (r:1 w:1)
+	/// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen)
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Balances InactiveIssuance (r:1 w:0)
+	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:2 w:2)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn one_fewer_deciding_passing() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `3972`
+		//  Estimated: `95245`
+		// Minimum execution time: 153_000_000 picoseconds.
+		Weight::from_parts(153_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 95245))
+			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().writes(4))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Referenda TrackQueue (r:1 w:1)
+	/// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:1 w:0)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn nudge_referendum_requeued_insertion() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `3990`
+		//  Estimated: `52306`
+		// Minimum execution time: 82_000_000 picoseconds.
+		Weight::from_parts(82_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 52306))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Referenda TrackQueue (r:1 w:1)
+	/// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:1 w:0)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn nudge_referendum_requeued_slide() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `3990`
+		//  Estimated: `52306`
+		// Minimum execution time: 76_000_000 picoseconds.
+		Weight::from_parts(76_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 52306))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Referenda DecidingCount (r:1 w:0)
+	/// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen)
+	/// Storage: Referenda TrackQueue (r:1 w:1)
+	/// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:1 w:0)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn nudge_referendum_queued() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `3964`
+		//  Estimated: `55785`
+		// Minimum execution time: 108_000_000 picoseconds.
+		Weight::from_parts(108_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 55785))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Referenda DecidingCount (r:1 w:0)
+	/// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen)
+	/// Storage: Referenda TrackQueue (r:1 w:1)
+	/// Proof: Referenda TrackQueue (max_values: None, max_size: Some(2012), added: 4487, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:1 w:0)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn nudge_referendum_not_queued() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `3984`
+		//  Estimated: `55785`
+		// Minimum execution time: 85_000_000 picoseconds.
+		Weight::from_parts(85_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 55785))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:1 w:1)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn nudge_referendum_no_deposit() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `403`
+		//  Estimated: `46829`
+		// Minimum execution time: 37_000_000 picoseconds.
+		Weight::from_parts(37_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 46829))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:1 w:1)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn nudge_referendum_preparing() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `451`
+		//  Estimated: `46829`
+		// Minimum execution time: 33_000_000 picoseconds.
+		Weight::from_parts(33_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 46829))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	fn nudge_referendum_timed_out() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `310`
+		//  Estimated: `4401`
+		// Minimum execution time: 22_000_000 picoseconds.
+		Weight::from_parts(22_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 4401))
+			.saturating_add(T::DbWeight::get().reads(1))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Referenda DecidingCount (r:1 w:1)
+	/// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen)
+	/// Storage: Balances InactiveIssuance (r:1 w:0)
+	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:1 w:1)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn nudge_referendum_begin_deciding_failing() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `451`
+		//  Estimated: `51809`
+		// Minimum execution time: 46_000_000 picoseconds.
+		Weight::from_parts(46_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 51809))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Referenda DecidingCount (r:1 w:1)
+	/// Proof: Referenda DecidingCount (max_values: None, max_size: Some(14), added: 2489, mode: MaxEncodedLen)
+	/// Storage: Balances InactiveIssuance (r:1 w:0)
+	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:1 w:1)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn nudge_referendum_begin_deciding_passing() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `451`
+		//  Estimated: `51809`
+		// Minimum execution time: 49_000_000 picoseconds.
+		Weight::from_parts(49_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 51809))
+			.saturating_add(T::DbWeight::get().reads(4))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Balances InactiveIssuance (r:1 w:0)
+	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:1 w:1)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn nudge_referendum_begin_confirming() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `504`
+		//  Estimated: `48330`
+		// Minimum execution time: 39_000_000 picoseconds.
+		Weight::from_parts(39_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 48330))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Balances InactiveIssuance (r:1 w:0)
+	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:1 w:1)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn nudge_referendum_end_confirming() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `487`
+		//  Estimated: `48330`
+		// Minimum execution time: 41_000_000 picoseconds.
+		Weight::from_parts(41_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 48330))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Balances InactiveIssuance (r:1 w:0)
+	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:1 w:1)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn nudge_referendum_continue_not_confirming() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `504`
+		//  Estimated: `48330`
+		// Minimum execution time: 34_000_000 picoseconds.
+		Weight::from_parts(34_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 48330))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Balances InactiveIssuance (r:1 w:0)
+	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:1 w:1)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn nudge_referendum_continue_confirming() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `508`
+		//  Estimated: `48330`
+		// Minimum execution time: 32_000_000 picoseconds.
+		Weight::from_parts(32_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 48330))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Balances InactiveIssuance (r:1 w:0)
+	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:2 w:2)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	/// Storage: Scheduler Lookup (r:1 w:1)
+	/// Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen)
+	fn nudge_referendum_approved() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `508`
+		//  Estimated: `93281`
+		// Minimum execution time: 73_000_000 picoseconds.
+		Weight::from_parts(73_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 93281))
+			.saturating_add(T::DbWeight::get().reads(5))
+			.saturating_add(T::DbWeight::get().writes(4))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:1)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Balances InactiveIssuance (r:1 w:0)
+	/// Proof: Balances InactiveIssuance (max_values: Some(1), max_size: Some(16), added: 511, mode: MaxEncodedLen)
+	/// Storage: Scheduler Agenda (r:1 w:1)
+	/// Proof: Scheduler Agenda (max_values: None, max_size: Some(38963), added: 41438, mode: MaxEncodedLen)
+	fn nudge_referendum_rejected() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `504`
+		//  Estimated: `48330`
+		// Minimum execution time: 40_000_000 picoseconds.
+		Weight::from_parts(40_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 48330))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:0)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Preimage StatusFor (r:1 w:0)
+	/// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen)
+	/// Storage: Referenda MetadataOf (r:0 w:1)
+	/// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen)
+	fn set_some_metadata() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `454`
+		//  Estimated: `7957`
+		// Minimum execution time: 25_000_000 picoseconds.
+		Weight::from_parts(25_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 7957))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+	/// Storage: Referenda ReferendumInfoFor (r:1 w:0)
+	/// Proof: Referenda ReferendumInfoFor (max_values: None, max_size: Some(936), added: 3411, mode: MaxEncodedLen)
+	/// Storage: Referenda MetadataOf (r:1 w:1)
+	/// Proof: Referenda MetadataOf (max_values: None, max_size: Some(52), added: 2527, mode: MaxEncodedLen)
+	fn clear_metadata() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `387`
+		//  Estimated: `7918`
+		// Minimum execution time: 22_000_000 picoseconds.
+		Weight::from_parts(22_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 7918))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(1))
+	}
+}
diff --git a/polkadot/runtime/polkadot/src/weights/pallet_whitelist.rs b/polkadot/runtime/polkadot/src/weights/pallet_whitelist.rs
new file mode 100644
index 00000000000..552d0df1890
--- /dev/null
+++ b/polkadot/runtime/polkadot/src/weights/pallet_whitelist.rs
@@ -0,0 +1,108 @@
+// Copyright 2017-2022 Parity Technologies (UK) Ltd.
+// This file is part of Polkadot.
+
+// Polkadot 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.
+
+// Polkadot 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 Polkadot.  If not, see <http://www.gnu.org/licenses/>.
+//! Autogenerated weights for `pallet_whitelist`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2023-03-07, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `cob`, CPU: `<UNKNOWN>`
+//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("polkadot-dev"), DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/polkadot
+// benchmark
+// pallet
+// --chain=polkadot-dev
+// --steps=2
+// --repeat=1
+// --pallet=pallet_whitelist
+// --extrinsic=*
+// --execution=wasm
+// --wasm-execution=compiled
+// --header=./file_header.txt
+// --output=./runtime/polkadot/src/weights/
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+
+use frame_support::{traits::Get, weights::Weight};
+use sp_std::marker::PhantomData;
+
+/// Weight functions for `pallet_whitelist`.
+pub struct WeightInfo<T>(PhantomData<T>);
+impl<T: frame_system::Config> pallet_whitelist::WeightInfo for WeightInfo<T> {
+	/// Storage: Whitelist WhitelistedCall (r:1 w:1)
+	/// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen)
+	/// Storage: Preimage StatusFor (r:1 w:1)
+	/// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen)
+	fn whitelist_call() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `118`
+		//  Estimated: `7061`
+		// Minimum execution time: 33_000_000 picoseconds.
+		Weight::from_parts(33_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 7061))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+	/// Storage: Whitelist WhitelistedCall (r:1 w:1)
+	/// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen)
+	/// Storage: Preimage StatusFor (r:1 w:1)
+	/// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen)
+	fn remove_whitelisted_call() -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `247`
+		//  Estimated: `7061`
+		// Minimum execution time: 24_000_000 picoseconds.
+		Weight::from_parts(24_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 7061))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+	/// Storage: Whitelist WhitelistedCall (r:1 w:1)
+	/// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen)
+	/// Storage: Preimage PreimageFor (r:1 w:1)
+	/// Proof: Preimage PreimageFor (max_values: None, max_size: Some(4194344), added: 4196819, mode: Measured)
+	/// Storage: Preimage StatusFor (r:1 w:1)
+	/// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen)
+	/// The range of component `n` is `[1, 4194294]`.
+	fn dispatch_whitelisted_call(_n: u32, ) -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `311 + n * (1 ±0)`
+		//  Estimated: `4205175`
+		// Minimum execution time: 43_000_000 picoseconds.
+		Weight::from_parts(4_138_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 4205175))
+			.saturating_add(T::DbWeight::get().reads(3))
+			.saturating_add(T::DbWeight::get().writes(3))
+	}
+	/// Storage: Whitelist WhitelistedCall (r:1 w:1)
+	/// Proof: Whitelist WhitelistedCall (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen)
+	/// Storage: Preimage StatusFor (r:1 w:1)
+	/// Proof: Preimage StatusFor (max_values: None, max_size: Some(91), added: 2566, mode: MaxEncodedLen)
+	/// The range of component `n` is `[1, 10000]`.
+	fn dispatch_whitelisted_call_with_preimage(_n: u32, ) -> Weight {
+		// Proof Size summary in bytes:
+		//  Measured:  `247`
+		//  Estimated: `7061`
+		// Minimum execution time: 32_000_000 picoseconds.
+		Weight::from_parts(45_000_000, 0)
+			.saturating_add(Weight::from_parts(0, 7061))
+			.saturating_add(T::DbWeight::get().reads(2))
+			.saturating_add(T::DbWeight::get().writes(2))
+	}
+}
diff --git a/polkadot/runtime/polkadot/src/xcm_config.rs b/polkadot/runtime/polkadot/src/xcm_config.rs
index 4f817093703..d853b27132c 100644
--- a/polkadot/runtime/polkadot/src/xcm_config.rs
+++ b/polkadot/runtime/polkadot/src/xcm_config.rs
@@ -17,23 +17,27 @@
 //! XCM configuration for Polkadot.
 
 use super::{
-	parachains_origin, AccountId, AllPalletsWithSystem, Balances, CouncilCollective, ParaId,
-	Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmPallet,
+	parachains_origin, AccountId, AllPalletsWithSystem, Balances, CouncilCollective,
+	FellowshipAdmin, ParaId, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, StakingAdmin,
+	WeightToFee, XcmPallet,
 };
 use frame_support::{
 	match_types, parameter_types,
 	traits::{Contains, Everything, Nothing},
 	weights::Weight,
 };
+use pallet_xcm::XcmPassthrough;
+use polkadot_runtime_constants::{system_parachain::*, xcm::body::FELLOWSHIP_ADMIN_INDEX};
 use runtime_common::{paras_registrar, xcm_sender, ToAuthor};
 use sp_core::ConstU32;
 use xcm::latest::prelude::*;
 use xcm_builder::{
-	AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom,
-	AllowTopLevelPaidExecutionFrom, BackingToPlurality, ChildParachainAsNative,
-	ChildParachainConvertsVia, CurrencyAdapter as XcmCurrencyAdapter, FixedWeightBounds,
-	IsConcrete, MintLocation, SignedAccountId32AsNative, SignedToAccountId32,
-	SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, WithComputedOrigin,
+	AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
+	AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, BackingToPlurality,
+	ChildParachainAsNative, ChildParachainConvertsVia, CurrencyAdapter as XcmCurrencyAdapter,
+	FixedWeightBounds, IsConcrete, MintLocation, OriginToPluralityVoice, SignedAccountId32AsNative,
+	SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, UsingComponents,
+	WithComputedOrigin,
 };
 use xcm_executor::traits::WithOriginFilter;
 
@@ -91,6 +95,8 @@ type LocalOriginConverter = (
 	// If the origin kind is `Native` and the XCM origin is the `AccountId32` location, then it can
 	// be expressed using the `Signed` origin variant.
 	SignedAccountId32AsNative<ThisNetwork, RuntimeOrigin>,
+	// Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
+	XcmPassthrough<RuntimeOrigin>,
 );
 
 parameter_types! {
@@ -110,8 +116,9 @@ pub type XcmRouter = (
 
 parameter_types! {
 	pub const Dot: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(TokenLocation::get()) });
-	pub const DotForStatemint: (MultiAssetFilter, MultiLocation) = (Dot::get(), Parachain(1000).into_location());
-	pub const DotForCollectives: (MultiAssetFilter, MultiLocation) = (Dot::get(), Parachain(1001).into_location());
+	pub const DotForStatemint: (MultiAssetFilter, MultiLocation) = (Dot::get(), Parachain(STATEMINT_ID).into_location());
+	pub const CollectivesLocation: MultiLocation = Parachain(COLLECTIVES_ID).into_location();
+	pub const DotForCollectives: (MultiAssetFilter, MultiLocation) = (Dot::get(), CollectivesLocation::get());
 	pub const MaxAssetsIntoHolding: u32 = 64;
 }
 
@@ -123,6 +130,10 @@ match_types! {
 	pub type OnlyParachains: impl Contains<MultiLocation> = {
 		MultiLocation { parents: 0, interior: X1(Parachain(_)) }
 	};
+	pub type CollectivesOrFellows: impl Contains<MultiLocation> = {
+		MultiLocation { parents: 0, interior: X1(Parachain(COLLECTIVES_ID)) } |
+		MultiLocation { parents: 0, interior: X2(Parachain(COLLECTIVES_ID), Plurality { id: BodyId::Technical, .. }) }
+	};
 }
 
 /// The barriers one of which must be passed for an XCM message to be executed.
@@ -137,6 +148,8 @@ pub type Barrier = (
 			AllowTopLevelPaidExecutionFrom<Everything>,
 			// Subscriptions for version tracking are OK.
 			AllowSubscriptionsFrom<OnlyParachains>,
+			// Collectives and Fellows plurality get free execution.
+			AllowExplicitUnpaidExecutionFrom<CollectivesOrFellows>,
 		),
 		UniversalLocation,
 		ConstU32<8>,
@@ -300,7 +313,8 @@ impl Contains<RuntimeCall> for SafeCallFilter {
 			) |
 			RuntimeCall::XcmPallet(pallet_xcm::Call::limited_reserve_transfer_assets {
 				..
-			}) => true,
+			}) |
+			RuntimeCall::Whitelist(pallet_whitelist::Call::whitelist_call { .. }) => true,
 			_ => false,
 		}
 	}
@@ -339,6 +353,10 @@ impl xcm_executor::Config for XcmConfig {
 
 parameter_types! {
 	pub const CouncilBodyId: BodyId = BodyId::Executive;
+	// StakingAdmin pluralistic body.
+	pub const StakingAdminBodyId: BodyId = BodyId::Defense;
+	// FellowshipAdmin pluralistic body.
+	pub const FellowshipAdminBodyId: BodyId = BodyId::Index(FELLOWSHIP_ADMIN_INDEX);
 }
 
 #[cfg(feature = "runtime-benchmarks")]
@@ -356,17 +374,35 @@ pub type CouncilToPlurality = BackingToPlurality<
 /// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior location
 /// of this chain.
 pub type LocalOriginToLocation = (
-	// We allow an origin from the Collective pallet to be used in XCM as a corresponding Plurality of the
-	// `Unit` body.
 	CouncilToPlurality,
 	// And a usual Signed origin to be used in XCM as a corresponding AccountId32
 	SignedToAccountId32<RuntimeOrigin, AccountId, ThisNetwork>,
 );
 
+/// Type to convert the `StakingAdmin` origin to a Plurality `MultiLocation` value.
+pub type StakingAdminToPlurality =
+	OriginToPluralityVoice<RuntimeOrigin, StakingAdmin, StakingAdminBodyId>;
+
+/// Type to convert the FellowshipAdmin origin to a Plurality `MultiLocation` value.
+pub type FellowshipAdminToPlurality =
+	OriginToPluralityVoice<RuntimeOrigin, FellowshipAdmin, FellowshipAdminBodyId>;
+
+/// Type to convert a pallet `Origin` type value into a `MultiLocation` value which represents an interior location
+/// of this chain for a destination chain.
+pub type LocalPalletOriginToLocation = (
+	// We allow an origin from the Collective pallet to be used in XCM as a corresponding Plurality of the
+	// `Unit` body.
+	CouncilToPlurality,
+	// StakingAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value.
+	StakingAdminToPlurality,
+	// FellowshipAdmin origin to be used in XCM as a corresponding Plurality `MultiLocation` value.
+	FellowshipAdminToPlurality,
+);
+
 impl pallet_xcm::Config for Runtime {
 	type RuntimeEvent = RuntimeEvent;
-	// Only allow the council to send messages.
-	type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<RuntimeOrigin, CouncilToPlurality>;
+	// We only allow the root, the council, the fellowship admin and the staking admin to send messages.
+	type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<RuntimeOrigin, LocalPalletOriginToLocation>;
 	type XcmRouter = XcmRouter;
 	// Anyone can execute XCM messages locally...
 	type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
-- 
GitLab