// Copyright (C) Parity Technologies (UK) Ltd. // This file is part of Pezcumulus. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //! The Zagros Technical Fellowship. mod origins; mod tracks; use crate::{ weights, xcm_config::{FellowshipAdminBodyId, LocationToAccountId, TreasurerBodyId, UsdtAssetHub}, AccountId, AssetRate, Balance, Balances, FellowshipReferenda, GovernanceLocation, Preimage, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Scheduler, TeyrchainInfo, ZagrosTreasuryAccount, DAYS, }; use cumulus_primitives_core::ParaId; use pezframe_support::{ parameter_types, traits::{ tokens::UnityOrOuterConversion, EitherOf, EitherOfDiverse, FromContains, MapSuccess, OriginTrait, TryWithMorphedArg, }, PalletId, }; use pezframe_system::{EnsureRoot, EnsureRootWithSuccess}; pub use origins::{ pezpallet_origins as pezpallet_fellowship_origins, Architects, EnsureCanPromoteTo, EnsureCanRetainAt, EnsureFellowship, Fellows, Masters, Members, ToVoice, }; use pezpallet_ranked_collective::EnsureOfRank; use pezpallet_xcm::{EnsureXcm, IsVoiceOfBody}; use pezkuwi_runtime_common::impls::{ ContainsParts, LocatableAssetConverter, VersionedLocatableAsset, VersionedLocationConverter, }; use pezsp_arithmetic::Permill; use pezsp_core::{ConstU128, ConstU32, ConstU8}; use pezsp_runtime::traits::{ConstU16, ConvertToValue, IdentityLookup, Replace, TakeFirst}; use testnet_teyrchains_constants::zagros::{account, currency::GRAND}; use teyrchains_common::impls::ToParentTreasury; use xcm::prelude::*; use xcm_builder::{AliasesIntoAccountId32, PayOverXcm}; use zagros_runtime_constants::time::HOURS; #[cfg(feature = "runtime-benchmarks")] use crate::impls::benchmarks::{OpenHrmpChannel, PayWithEnsure}; /// The Fellowship members' ranks. pub mod ranks { use pezpallet_ranked_collective::Rank; pub const DAN_1: Rank = 1; // aka Members. pub const DAN_2: Rank = 2; pub const DAN_3: Rank = 3; // aka Fellows. pub const DAN_4: Rank = 4; // aka Architects. pub const DAN_5: Rank = 5; pub const DAN_6: Rank = 6; pub const DAN_7: Rank = 7; // aka Masters. pub const DAN_8: Rank = 8; pub const DAN_9: Rank = 9; } impl pezpallet_fellowship_origins::Config for Runtime {} pub type FellowshipReferendaInstance = pezpallet_referenda::Instance1; impl pezpallet_referenda::Config for Runtime { type WeightInfo = weights::pezpallet_referenda_fellowship_referenda::WeightInfo; type RuntimeCall = RuntimeCall; type RuntimeEvent = RuntimeEvent; type Scheduler = Scheduler; type Currency = Balances; // Fellows can submit proposals. type SubmitOrigin = EitherOf< pezpallet_ranked_collective::EnsureMember, MapSuccess< TryWithMorphedArg< RuntimeOrigin, ::PalletsOrigin, ToVoice, EnsureOfRank, (AccountId, u16), >, TakeFirst, >, >; type CancelOrigin = Architects; type KillOrigin = Masters; type Slash = ToParentTreasury; type Votes = pezpallet_ranked_collective::Votes; type Tally = pezpallet_ranked_collective::TallyOf; type SubmissionDeposit = ConstU128<0>; type MaxQueued = ConstU32<100>; type UndecidingTimeout = ConstU32<{ 7 * DAYS }>; type AlarmInterval = ConstU32<1>; type Tracks = tracks::TracksInfo; type Preimages = Preimage; type BlockNumberProvider = crate::System; } pub type FellowshipCollectiveInstance = pezpallet_ranked_collective::Instance1; impl pezpallet_ranked_collective::Config for Runtime { type WeightInfo = weights::pezpallet_ranked_collective_fellowship_collective::WeightInfo; type RuntimeEvent = RuntimeEvent; // Promotions and the induction of new members are serviced by `FellowshipCore` pallet instance. #[cfg(not(feature = "runtime-benchmarks"))] type AddOrigin = pezframe_system::EnsureNever<()>; #[cfg(feature = "runtime-benchmarks")] type AddOrigin = pezframe_system::EnsureRoot; // The maximum value of `u16` set as a success value for the root to ensure the benchmarks will // pass. #[cfg(not(feature = "runtime-benchmarks"))] type PromoteOrigin = pezframe_system::EnsureNever; #[cfg(feature = "runtime-benchmarks")] type PromoteOrigin = EnsureRootWithSuccess>; // Demotion is by any of: // - Root can demote arbitrarily. // - the FellowshipAdmin origin (i.e. token holder referendum); // // The maximum value of `u16` set as a success value for the root to ensure the benchmarks will // pass. type RemoveOrigin = Self::DemoteOrigin; type DemoteOrigin = EitherOf< EnsureRootWithSuccess>, MapSuccess< EnsureXcm>, Replace>, >, >; // Exchange is by any of: // - Root can exchange arbitrarily. // - the Fellows origin type ExchangeOrigin = EitherOf>, Fellows>; type Polls = FellowshipReferenda; type MinRankOfClass = tracks::MinRankOfClass; type MemberSwappedHandler = (crate::FellowshipCore, crate::FellowshipSalary); type VoteWeight = pezpallet_ranked_collective::Geometric; type MaxMemberCount = (); #[cfg(feature = "runtime-benchmarks")] type BenchmarkSetup = (crate::FellowshipCore, crate::FellowshipSalary); } pub type FellowshipCoreInstance = pezpallet_core_fellowship::Instance1; impl pezpallet_core_fellowship::Config for Runtime { type WeightInfo = weights::pezpallet_core_fellowship_fellowship_core::WeightInfo; type RuntimeEvent = RuntimeEvent; type Members = pezpallet_ranked_collective::Pallet; type Balance = Balance; // Parameters are set by any of: // - Root; // - the FellowshipAdmin origin (i.e. token holder referendum); // - a vote among all Fellows. type ParamsOrigin = EitherOfDiverse< EnsureXcm>, Fellows, >; // Induction (creating a candidate) is by any of: // - Root; // - the FellowshipAdmin origin (i.e. token holder referendum); // - a single Fellow; // - a vote among all Members. type InductOrigin = EitherOfDiverse< EnsureXcm>, EitherOfDiverse< pezpallet_ranked_collective::EnsureMember< Runtime, FellowshipCollectiveInstance, { ranks::DAN_3 }, >, Members, >, >; // Approval (rank-retention) of a Member's current rank is by any of: // - Root; // - the FellowshipAdmin origin (i.e. token holder referendum); // - a vote by the rank two above the current rank for all retention up to the Master rank. type ApproveOrigin = EitherOf< MapSuccess< EnsureXcm>, Replace>, >, EnsureCanRetainAt, >; // Promotion is by any of: // - Root can promote arbitrarily. // - the FellowshipAdmin origin (i.e. token holder referendum); // - a vote by the rank two above the new rank for all promotions up to the Master rank. type PromoteOrigin = EitherOf< MapSuccess< EnsureXcm>, Replace>, >, EnsureCanPromoteTo, >; type FastPromoteOrigin = Self::PromoteOrigin; type EvidenceSize = ConstU32<65536>; type MaxRank = ConstU16<9>; } pub type FellowshipSalaryInstance = pezpallet_salary::Instance1; parameter_types! { // The interior location on AssetHub for the paying account. This is the Fellowship Salary // pallet instance (which sits at index 64). This sovereign account will need funding. pub Interior: InteriorLocation = PalletInstance(64).into(); } const USDT_UNITS: u128 = 1_000_000; /// [`PayOverXcm`] setup to pay the Fellowship salary on the AssetHub in USDT. pub type FellowshipSalaryPaymaster = PayOverXcm< Interior, crate::xcm_config::XcmRouter, crate::PezkuwiXcm, ConstU32<{ 6 * HOURS }>, AccountId, (), ConvertToValue, AliasesIntoAccountId32<(), AccountId>, >; impl pezpallet_salary::Config for Runtime { type WeightInfo = weights::pezpallet_salary_fellowship_salary::WeightInfo; type RuntimeEvent = RuntimeEvent; #[cfg(not(feature = "runtime-benchmarks"))] type Paymaster = FellowshipSalaryPaymaster; #[cfg(feature = "runtime-benchmarks")] type Paymaster = PayWithEnsure>>; type Members = pezpallet_ranked_collective::Pallet; #[cfg(not(feature = "runtime-benchmarks"))] type Salary = pezpallet_core_fellowship::Pallet; #[cfg(feature = "runtime-benchmarks")] type Salary = pezframe_support::traits::tokens::ConvertRank< crate::impls::benchmarks::RankToSalary, >; // 15 days to register for a salary payment. type RegistrationPeriod = ConstU32<{ 15 * DAYS }>; // 15 days to claim the salary payment. type PayoutPeriod = ConstU32<{ 15 * DAYS }>; // Total monthly salary budget. type Budget = ConstU128<{ 100_000 * USDT_UNITS }>; } parameter_types! { pub const FellowshipTreasuryPalletId: PalletId = account::FELLOWSHIP_TREASURY_PALLET_ID; pub const HundredPercent: Permill = Permill::from_percent(100); pub const Burn: Permill = Permill::from_percent(0); pub const MaxBalance: Balance = Balance::max_value(); // The asset's interior location for the paying account. This is the Fellowship Treasury // pallet instance (which sits at index 65). pub FellowshipTreasuryInteriorLocation: InteriorLocation = PalletInstance(65).into(); pub SelfParaId: ParaId = TeyrchainInfo::teyrchain_id(); } /// [`PayOverXcm`] setup to pay the Fellowship Treasury. pub type FellowshipTreasuryPaymaster = PayOverXcm< FellowshipTreasuryInteriorLocation, crate::xcm_config::XcmRouter, crate::PezkuwiXcm, ConstU32<{ 6 * HOURS }>, VersionedLocation, VersionedLocatableAsset, LocatableAssetConverter, VersionedLocationConverter, >; pub type FellowshipTreasuryInstance = pezpallet_treasury::Instance1; impl pezpallet_treasury::Config for Runtime { type WeightInfo = weights::pezpallet_treasury::WeightInfo; type PalletId = FellowshipTreasuryPalletId; type Currency = Balances; type RejectOrigin = EitherOfDiverse< EnsureRoot, EitherOfDiverse>, Fellows>, >; type RuntimeEvent = RuntimeEvent; type SpendPeriod = ConstU32<{ 7 * DAYS }>; type Burn = Burn; type BurnDestination = (); type SpendFunds = (); type MaxApprovals = ConstU32<100>; type SpendOrigin = EitherOf< EitherOf< EnsureRootWithSuccess, MapSuccess< EnsureXcm>, Replace>, >, >, EitherOf< MapSuccess>>, MapSuccess>>, >, >; type AssetKind = VersionedLocatableAsset; type Beneficiary = VersionedLocation; type BeneficiaryLookup = IdentityLookup; #[cfg(not(feature = "runtime-benchmarks"))] type Paymaster = FellowshipTreasuryPaymaster; #[cfg(feature = "runtime-benchmarks")] type Paymaster = PayWithEnsure>>; type BalanceConverter = UnityOrOuterConversion< ContainsParts< FromContains< xcm_builder::IsSiblingSystemTeyrchain, xcm_builder::IsParentsOnly>, >, >, AssetRate, >; type PayoutPeriod = ConstU32<{ 30 * DAYS }>; #[cfg(feature = "runtime-benchmarks")] type BenchmarkHelper = pezkuwi_runtime_common::impls::benchmarks::TreasuryArguments< pezsp_core::ConstU8<1>, ConstU32<1000>, >; type BlockNumberProvider = crate::System; }