git.delta.rocks / unique-network / refs/commits / 568279d1cd8f

difftreelog

refactor move common xcm parts to common

Daniel Shiposha2022-09-06parent: #25b276d.patch.diff
in: master

7 files changed

modifiedruntime/common/config/orml.rsdiffbeforeafterboth
--- a/runtime/common/config/orml.rs
+++ b/runtime/common/config/orml.rs
@@ -14,19 +14,87 @@
 // You should have received a copy of the GNU General Public License
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
-use frame_support::parameter_types;
+use frame_support::{
+	parameter_types,
+	traits::{Contains, Everything},
+	weights::Weight,
+};
 use frame_system::EnsureSigned;
-use crate::{Runtime, Event, RelayChainBlockNumberProvider};
+use orml_traits::{location::AbsoluteReserveProvider, parameter_type_with_key};
+use sp_runtime::traits::Convert;
+use xcm::v1::{Junction::*, Junctions::*, MultiLocation, NetworkId};
+use xcm_builder::LocationInverter;
+use xcm_executor::XcmExecutor;
+use sp_std::{vec, vec::Vec};
+use pallet_foreing_assets::{CurrencyId, NativeCurrency};
+use crate::{
+	Runtime, Event, RelayChainBlockNumberProvider,
+	runtime_common::config::{
+		xcm::{
+			SelfLocation, Weigher, XcmConfig, Ancestry,
+			xcm_assets::{CurrencyIdConvert},
+		},
+		pallets::TreasuryAccountId,
+		substrate::{MaxLocks, MaxReserves},
+	},
+};
+
 use up_common::{
 	types::{AccountId, Balance},
 	constants::*,
 };
 
+// Signed version of balance
+pub type Amount = i128;
+
 parameter_types! {
 	pub const MinVestedTransfer: Balance = 10 * UNIQUE;
 	pub const MaxVestingSchedules: u32 = 28;
+
+	pub const BaseXcmWeight: Weight = 100_000_000; // TODO: recheck this
+	pub const MaxAssetsForTransfer: usize = 2;
+}
+
+parameter_type_with_key! {
+	pub ParachainMinFee: |_location: MultiLocation| -> Option<u128> {
+		Some(100_000_000_000)
+	};
+}
+
+parameter_type_with_key! {
+	pub ExistentialDeposits: |currency_id: CurrencyId| -> Balance {
+		match currency_id {
+			CurrencyId::NativeAssetId(symbol) => match symbol {
+				NativeCurrency::Here => 0,
+				NativeCurrency::Parent=> 0,
+			},
+			_ => 100_000
+		}
+	};
+}
+
+pub fn get_all_module_accounts() -> Vec<AccountId> {
+	vec![TreasuryAccountId::get()]
 }
 
+pub struct DustRemovalWhitelist;
+impl Contains<AccountId> for DustRemovalWhitelist {
+	fn contains(a: &AccountId) -> bool {
+		get_all_module_accounts().contains(a)
+	}
+}
+
+pub struct AccountIdToMultiLocation;
+impl Convert<AccountId, MultiLocation> for AccountIdToMultiLocation {
+	fn convert(account: AccountId) -> MultiLocation {
+		X1(AccountId32 {
+			network: NetworkId::Any,
+			id: account.into(),
+		})
+		.into()
+	}
+}
+
 impl orml_vesting::Config for Runtime {
 	type Event = Event;
 	type Currency = pallet_balances::Pallet<Runtime>;
@@ -36,3 +104,38 @@
 	type MaxVestingSchedules = MaxVestingSchedules;
 	type BlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;
 }
+
+impl orml_tokens::Config for Runtime {
+	type Event = Event;
+	type Balance = Balance;
+	type Amount = Amount;
+	type CurrencyId = CurrencyId;
+	type WeightInfo = ();
+	type ExistentialDeposits = ExistentialDeposits;
+	type OnDust = orml_tokens::TransferDust<Runtime, TreasuryAccountId>;
+	type MaxLocks = MaxLocks;
+	type MaxReserves = MaxReserves;
+	// TODO: Add all module accounts
+	type DustRemovalWhitelist = DustRemovalWhitelist;
+	/// The id type for named reserves.
+	type ReserveIdentifier = ();
+	type OnNewTokenAccount = ();
+	type OnKilledTokenAccount = ();
+}
+
+impl orml_xtokens::Config for Runtime {
+	type Event = Event;
+	type Balance = Balance;
+	type CurrencyId = CurrencyId;
+	type CurrencyIdConvert = CurrencyIdConvert;
+	type AccountIdToMultiLocation = AccountIdToMultiLocation;
+	type SelfLocation = SelfLocation;
+	type XcmExecutor = XcmExecutor<XcmConfig<Self>>;
+	type Weigher = Weigher;
+	type BaseXcmWeight = BaseXcmWeight;
+	type LocationInverter = LocationInverter<Ancestry>;
+	type MaxAssetsForTransfer = MaxAssetsForTransfer;
+	type MinXcmFee = ParachainMinFee;
+	type MultiLocationsFilter = Everything;
+	type ReserveProvider = AbsoluteReserveProvider;
+}
modifiedruntime/common/config/xcm/foreignassets.rsdiffbeforeafterboth
before · runtime/common/config/xcm/foreignassets.rs
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617use frame_support::{18	traits::{Contains, Get, fungibles},19	parameter_types,20};21use sp_runtime::traits::Zero;22use xcm::v1::{Junction::*, MultiLocation, Junctions::*};23use xcm::latest::MultiAsset;24use xcm_builder::{FungiblesAdapter, ConvertedConcreteAssetId};25use xcm_executor::traits::{Convert as ConvertXcm, JustTry, FilterAssetLocation};26use pallet_foreing_assets::{27	AssetIds, AssetIdMapping, XcmForeignAssetIdMapping, NativeCurrency, FreeForAll, TryAsForeing,28	ForeignAssetId,29};30use sp_std::{borrow::Borrow, marker::PhantomData};31use crate::{Runtime, Balances, ParachainInfo, PolkadotXcm, ForeingAssets};3233use super::{LocationToAccountId, RelayLocation};3435use up_common::types::{AccountId, Balance};3637parameter_types! {38	pub CheckingAccount: AccountId = PolkadotXcm::check_account();39}4041/// Allow checking in assets that have issuance > 0.42pub struct NonZeroIssuance<AccountId, ForeingAssets>(PhantomData<(AccountId, ForeingAssets)>);4344impl<AccountId, ForeingAssets> Contains<<ForeingAssets as fungibles::Inspect<AccountId>>::AssetId>45	for NonZeroIssuance<AccountId, ForeingAssets>46where47	ForeingAssets: fungibles::Inspect<AccountId>,48{49	fn contains(id: &<ForeingAssets as fungibles::Inspect<AccountId>>::AssetId) -> bool {50		!ForeingAssets::total_issuance(*id).is_zero()51	}52}5354pub struct AsInnerId<AssetId, ConvertAssetId>(PhantomData<(AssetId, ConvertAssetId)>);55impl<AssetId: Clone + PartialEq, ConvertAssetId: ConvertXcm<AssetId, AssetId>>56	ConvertXcm<MultiLocation, AssetId> for AsInnerId<AssetId, ConvertAssetId>57where58	AssetId: Borrow<AssetId>,59	AssetId: TryAsForeing<AssetId, ForeignAssetId>,60	AssetIds: Borrow<AssetId>,61{62	fn convert_ref(id: impl Borrow<MultiLocation>) -> Result<AssetId, ()> {63		let id = id.borrow();6465		log::trace!(66			target: "xcm::AsInnerId::Convert",67			"AsInnerId {:?}",68			id69		);7071		let parent = MultiLocation::parent();72		let here = MultiLocation::here();73		let self_location = MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())));7475		if *id == parent {76			return ConvertAssetId::convert_ref(AssetIds::NativeAssetId(NativeCurrency::Parent));77		}7879		if *id == here || *id == self_location {80			return ConvertAssetId::convert_ref(AssetIds::NativeAssetId(NativeCurrency::Here));81		}8283		match XcmForeignAssetIdMapping::<Runtime>::get_currency_id(id.clone()) {84			Some(AssetIds::ForeignAssetId(foreign_asset_id)) => {85				ConvertAssetId::convert_ref(AssetIds::ForeignAssetId(foreign_asset_id))86			}87			_ => ConvertAssetId::convert_ref(AssetIds::ForeignAssetId(0)),88		}89	}9091	fn reverse_ref(what: impl Borrow<AssetId>) -> Result<MultiLocation, ()> {92		log::trace!(93			target: "xcm::AsInnerId::Reverse",94			"AsInnerId",95		);9697		let asset_id = what.borrow();9899		let parent_id =100			ConvertAssetId::convert_ref(AssetIds::NativeAssetId(NativeCurrency::Parent)).unwrap();101		let here_id =102			ConvertAssetId::convert_ref(AssetIds::NativeAssetId(NativeCurrency::Here)).unwrap();103104		if asset_id.clone() == parent_id {105			return Ok(MultiLocation::parent());106		}107108		if asset_id.clone() == here_id {109			return Ok(MultiLocation::new(110				1,111				X1(Parachain(ParachainInfo::get().into())),112			));113		}114115		match <AssetId as TryAsForeing<AssetId, ForeignAssetId>>::try_as_foreing(asset_id.clone()) {116			Some(fid) => match XcmForeignAssetIdMapping::<Runtime>::get_multi_location(fid) {117				Some(location) => Ok(location),118				None => Err(()),119			},120			None => Err(()),121		}122	}123}124125/// Means for transacting assets besides the native currency on this chain.126pub type FungiblesTransactor = FungiblesAdapter<127	// Use this fungibles implementation:128	ForeingAssets,129	// Use this currency when it is a fungible asset matching the given location or name:130	ConvertedConcreteAssetId<AssetIds, Balance, AsInnerId<AssetIds, JustTry>, JustTry>,131	// Convert an XCM MultiLocation into a local account id:132	LocationToAccountId,133	// Our chain's account ID type (we can't get away without mentioning it explicitly):134	AccountId,135	// We only want to allow teleports of known assets. We use non-zero issuance as an indication136	// that this asset is known.137	NonZeroIssuance<AccountId, ForeingAssets>,138	// The account to use for tracking teleports.139	CheckingAccount,140>;141142/// Means for transacting assets on this chain.143pub type AssetTransactors = FungiblesTransactor;144145pub struct AllAsset;146impl FilterAssetLocation for AllAsset {147	fn filter_asset_location(_asset: &MultiAsset, _origin: &MultiLocation) -> bool {148		true149	}150}151152pub type IsReserve = AllAsset;153154pub type Trader<T> = FreeForAll<155	pallet_configuration::WeightToFee<T, Balance>,156	RelayLocation,157	AccountId,158	Balances,159	(),160>;
after · runtime/common/config/xcm/foreignassets.rs
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617use frame_support::{18	traits::{Contains, Get, fungibles},19	parameter_types,20};21use sp_runtime::traits::{Zero, Convert};22use xcm::v1::{Junction::*, MultiLocation, Junctions::*};23use xcm::latest::MultiAsset;24use xcm_builder::{FungiblesAdapter, ConvertedConcreteAssetId};25use xcm_executor::traits::{Convert as ConvertXcm, JustTry, FilterAssetLocation};26use pallet_foreing_assets::{27	AssetIds, AssetIdMapping, XcmForeignAssetIdMapping, NativeCurrency, FreeForAll, TryAsForeing,28	ForeignAssetId, CurrencyId,29};30use sp_std::{borrow::Borrow, marker::PhantomData};31use crate::{Runtime, Balances, ParachainInfo, PolkadotXcm, ForeingAssets};3233use super::{LocationToAccountId, RelayLocation};3435use up_common::types::{AccountId, Balance};3637parameter_types! {38	pub CheckingAccount: AccountId = PolkadotXcm::check_account();39}4041/// Allow checking in assets that have issuance > 0.42pub struct NonZeroIssuance<AccountId, ForeingAssets>(PhantomData<(AccountId, ForeingAssets)>);4344impl<AccountId, ForeingAssets> Contains<<ForeingAssets as fungibles::Inspect<AccountId>>::AssetId>45	for NonZeroIssuance<AccountId, ForeingAssets>46where47	ForeingAssets: fungibles::Inspect<AccountId>,48{49	fn contains(id: &<ForeingAssets as fungibles::Inspect<AccountId>>::AssetId) -> bool {50		!ForeingAssets::total_issuance(*id).is_zero()51	}52}5354pub struct AsInnerId<AssetId, ConvertAssetId>(PhantomData<(AssetId, ConvertAssetId)>);55impl<AssetId: Clone + PartialEq, ConvertAssetId: ConvertXcm<AssetId, AssetId>>56	ConvertXcm<MultiLocation, AssetId> for AsInnerId<AssetId, ConvertAssetId>57where58	AssetId: Borrow<AssetId>,59	AssetId: TryAsForeing<AssetId, ForeignAssetId>,60	AssetIds: Borrow<AssetId>,61{62	fn convert_ref(id: impl Borrow<MultiLocation>) -> Result<AssetId, ()> {63		let id = id.borrow();6465		log::trace!(66			target: "xcm::AsInnerId::Convert",67			"AsInnerId {:?}",68			id69		);7071		let parent = MultiLocation::parent();72		let here = MultiLocation::here();73		let self_location = MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())));7475		if *id == parent {76			return ConvertAssetId::convert_ref(AssetIds::NativeAssetId(NativeCurrency::Parent));77		}7879		if *id == here || *id == self_location {80			return ConvertAssetId::convert_ref(AssetIds::NativeAssetId(NativeCurrency::Here));81		}8283		match XcmForeignAssetIdMapping::<Runtime>::get_currency_id(id.clone()) {84			Some(AssetIds::ForeignAssetId(foreign_asset_id)) => {85				ConvertAssetId::convert_ref(AssetIds::ForeignAssetId(foreign_asset_id))86			}87			_ => ConvertAssetId::convert_ref(AssetIds::ForeignAssetId(0)),88		}89	}9091	fn reverse_ref(what: impl Borrow<AssetId>) -> Result<MultiLocation, ()> {92		log::trace!(93			target: "xcm::AsInnerId::Reverse",94			"AsInnerId",95		);9697		let asset_id = what.borrow();9899		let parent_id =100			ConvertAssetId::convert_ref(AssetIds::NativeAssetId(NativeCurrency::Parent)).unwrap();101		let here_id =102			ConvertAssetId::convert_ref(AssetIds::NativeAssetId(NativeCurrency::Here)).unwrap();103104		if asset_id.clone() == parent_id {105			return Ok(MultiLocation::parent());106		}107108		if asset_id.clone() == here_id {109			return Ok(MultiLocation::new(110				1,111				X1(Parachain(ParachainInfo::get().into())),112			));113		}114115		match <AssetId as TryAsForeing<AssetId, ForeignAssetId>>::try_as_foreing(asset_id.clone()) {116			Some(fid) => match XcmForeignAssetIdMapping::<Runtime>::get_multi_location(fid) {117				Some(location) => Ok(location),118				None => Err(()),119			},120			None => Err(()),121		}122	}123}124125/// Means for transacting assets besides the native currency on this chain.126pub type FungiblesTransactor = FungiblesAdapter<127	// Use this fungibles implementation:128	ForeingAssets,129	// Use this currency when it is a fungible asset matching the given location or name:130	ConvertedConcreteAssetId<AssetIds, Balance, AsInnerId<AssetIds, JustTry>, JustTry>,131	// Convert an XCM MultiLocation into a local account id:132	LocationToAccountId,133	// Our chain's account ID type (we can't get away without mentioning it explicitly):134	AccountId,135	// We only want to allow teleports of known assets. We use non-zero issuance as an indication136	// that this asset is known.137	NonZeroIssuance<AccountId, ForeingAssets>,138	// The account to use for tracking teleports.139	CheckingAccount,140>;141142/// Means for transacting assets on this chain.143pub type AssetTransactors = FungiblesTransactor;144145pub struct AllAsset;146impl FilterAssetLocation for AllAsset {147	fn filter_asset_location(_asset: &MultiAsset, _origin: &MultiLocation) -> bool {148		true149	}150}151152pub type IsReserve = AllAsset;153154pub type Trader<T> = FreeForAll<155	pallet_configuration::WeightToFee<T, Balance>,156	RelayLocation,157	AccountId,158	Balances,159	(),160>;161162pub struct CurrencyIdConvert;163impl Convert<AssetIds, Option<MultiLocation>> for CurrencyIdConvert {164	fn convert(id: AssetIds) -> Option<MultiLocation> {165		match id {166			AssetIds::NativeAssetId(NativeCurrency::Here) => Some(MultiLocation::new(167				1,168				X1(Parachain(ParachainInfo::get().into())),169			)),170			AssetIds::NativeAssetId(NativeCurrency::Parent) => Some(MultiLocation::parent()),171			AssetIds::ForeignAssetId(foreign_asset_id) => {172				XcmForeignAssetIdMapping::<Runtime>::get_multi_location(foreign_asset_id)173			}174		}175	}176}177178impl Convert<MultiLocation, Option<CurrencyId>> for CurrencyIdConvert {179	fn convert(location: MultiLocation) -> Option<CurrencyId> {180		if location == MultiLocation::here()181			|| location == MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())))182		{183			return Some(AssetIds::NativeAssetId(NativeCurrency::Here));184		}185186		if location == MultiLocation::parent() {187			return Some(AssetIds::NativeAssetId(NativeCurrency::Parent));188		}189190		if let Some(currency_id) =191			XcmForeignAssetIdMapping::<Runtime>::get_currency_id(location.clone())192		{193			return Some(currency_id);194		}195196		None197	}198}
modifiedruntime/common/config/xcm/mod.rsdiffbeforeafterboth
--- a/runtime/common/config/xcm/mod.rs
+++ b/runtime/common/config/xcm/mod.rs
@@ -14,19 +14,23 @@
 // You should have received a copy of the GNU General Public License
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
-use frame_support::{traits::Everything, weights::Weight, parameter_types};
+use frame_support::{
+	traits::{Everything, Get},
+	weights::Weight,
+	parameter_types,
+};
 use frame_system::EnsureRoot;
 use pallet_xcm::XcmPassthrough;
 use polkadot_parachain::primitives::Sibling;
 use xcm::v1::{Junction::*, MultiLocation, NetworkId};
-use xcm::latest::{Instruction, Xcm};
+use xcm::latest::prelude::*;
 use xcm_builder::{
 	AccountId32Aliases, EnsureXcmOrigin, FixedWeightBounds, LocationInverter, ParentAsSuperuser,
 	RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
 	SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, ParentIsPreset,
 };
 use xcm_executor::{Config, XcmExecutor, traits::ShouldExecute};
-use sp_std::marker::PhantomData;
+use sp_std::{marker::PhantomData, vec::Vec};
 use crate::{
 	Runtime, Call, Event, Origin, ParachainInfo, ParachainSystem, PolkadotXcm, XcmpQueue,
 	xcm_config::Barrier,
@@ -35,16 +39,16 @@
 use up_common::types::AccountId;
 
 #[cfg(feature = "foreign-assets")]
-mod foreignassets;
+pub mod foreignassets;
 
 #[cfg(not(feature = "foreign-assets"))]
-mod nativeassets;
+pub mod nativeassets;
 
 #[cfg(feature = "foreign-assets")]
-use foreignassets as xcm_assets;
+pub use foreignassets as xcm_assets;
 
 #[cfg(not(feature = "foreign-assets"))]
-use nativeassets as xcm_assets;
+pub use nativeassets as xcm_assets;
 
 use xcm_assets::{AssetTransactors, IsReserve, Trader};
 
@@ -53,6 +57,11 @@
 	pub const RelayNetwork: NetworkId = NetworkId::Polkadot;
 	pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();
 	pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();
+	pub SelfLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())));
+
+	// One XCM operation is 1_000_000 weight - almost certainly a conservative estimate.
+	pub UnitWeightCost: Weight = 1_000_000;
+	pub const MaxInstructions: u32 = 100;
 }
 
 /// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
@@ -102,12 +111,6 @@
 	// Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
 	XcmPassthrough<Origin>,
 );
-
-parameter_types! {
-	// One XCM operation is 1_000_000 weight - almost certainly a conservative estimate.
-	pub UnitWeightCost: Weight = 1_000_000;
-	pub const MaxInstructions: u32 = 100;
-}
 
 pub trait TryPass {
 	fn try_pass<Call>(origin: &MultiLocation, message: &mut Xcm<Call>) -> Result<(), ()>;
@@ -169,6 +172,40 @@
 	}
 }
 
+// Allow xcm exchange only with locations in list
+pub struct DenyExchangeWithUnknownLocation<T>(PhantomData<T>);
+impl<T: Get<Vec<MultiLocation>>> TryPass for DenyExchangeWithUnknownLocation<T> {
+	fn try_pass<Call>(origin: &MultiLocation, message: &mut Xcm<Call>) -> Result<(), ()> {
+		let allowed_locations = T::get();
+
+		// Check if deposit or transfer belongs to allowed parachains
+		let mut allowed = allowed_locations.contains(origin);
+
+		message.0.iter().for_each(|inst| match inst {
+			DepositReserveAsset { dest: dst, .. } => {
+				allowed |= allowed_locations.contains(dst);
+			}
+			TransferReserveAsset { dest: dst, .. } => {
+				allowed |= allowed_locations.contains(dst);
+			}
+			_ => {}
+		});
+
+		if allowed {
+			return Ok(());
+		}
+
+		log::warn!(
+			target: "xcm::barrier",
+			"Unexpected deposit or transfer location"
+		);
+		// Deny
+		Err(())
+	}
+}
+
+pub type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
+
 pub struct XcmConfig<T>(PhantomData<T>);
 impl<T> Config for XcmConfig<T>
 where
@@ -183,7 +220,7 @@
 	type IsTeleporter = (); // Teleportation is disabled
 	type LocationInverter = LocationInverter<Ancestry>;
 	type Barrier = Barrier;
-	type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
+	type Weigher = Weigher;
 	type Trader = Trader<T>;
 	type ResponseHandler = (); // Don't handle responses for now.
 	type SubscriptionService = PolkadotXcm;
modifiedruntime/common/config/xcm/nativeassets.rsdiffbeforeafterboth
--- a/runtime/common/config/xcm/nativeassets.rs
+++ b/runtime/common/config/xcm/nativeassets.rs
@@ -18,7 +18,7 @@
 	traits::{tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Get},
 	weights::{Weight, WeightToFeePolynomial},
 };
-use sp_runtime::traits::{CheckedConversion, Zero};
+use sp_runtime::traits::{CheckedConversion, Zero, Convert};
 use xcm::v1::{Junction::*, MultiLocation, Junctions::*};
 use xcm::latest::{
 	AssetId::{Concrete},
@@ -30,6 +30,7 @@
 	Assets,
 	traits::{MatchesFungible, WeightTrader},
 };
+use pallet_foreing_assets::{AssetIds, NativeCurrency};
 use sp_std::marker::PhantomData;
 use crate::{Balances, ParachainInfo};
 use super::{LocationToAccountId, RelayLocation};
@@ -127,3 +128,16 @@
 	Balances,
 	(),
 >;
+
+pub struct CurrencyIdConvert;
+impl Convert<AssetIds, Option<MultiLocation>> for CurrencyIdConvert {
+	fn convert(id: AssetIds) -> Option<MultiLocation> {
+		match id {
+			AssetIds::NativeAssetId(NativeCurrency::Here) => Some(MultiLocation::new(
+				1,
+				X1(Parachain(ParachainInfo::get().into())),
+			)),
+			_ => None,
+		}
+	}
+}
modifiedruntime/opal/src/xcm_config.rsdiffbeforeafterboth
--- a/runtime/opal/src/xcm_config.rs
+++ b/runtime/opal/src/xcm_config.rs
@@ -15,39 +15,17 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 use frame_support::{
-	{match_types, parameter_types, weights::Weight},
-	pallet_prelude::Get,
-	traits::{Contains, Everything},
+	{match_types, weights::Weight},
+	traits::Everything,
 };
-use orml_traits::{location::AbsoluteReserveProvider, parameter_type_with_key};
-use sp_runtime::traits::{AccountIdConversion, Convert};
-use sp_std::{vec, vec::Vec};
 use xcm::{
 	latest::Xcm,
-	v1::{BodyId, Junction::*, Junctions::*, MultiLocation, NetworkId},
-};
-use xcm_builder::{
-	AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, FixedWeightBounds, LocationInverter,
-	TakeWeightCredit,
-};
-use xcm_executor::{XcmExecutor, traits::ShouldExecute};
-
-use up_common::types::{AccountId, Balance};
-use crate::{
-	Call, Event, ParachainInfo, Runtime,
-	runtime_common::config::{
-		substrate::{TreasuryModuleId, MaxLocks, MaxReserves},
-		pallets::TreasuryAccountId,
-		xcm::*,
-	},
+	v1::{BodyId, Junction::*, Junctions::*, MultiLocation},
 };
-
-use pallet_foreing_assets::{
-	AssetIds, AssetIdMapping, XcmForeignAssetIdMapping, CurrencyId, NativeCurrency,
-};
+use xcm_builder::{AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, TakeWeightCredit};
+use xcm_executor::traits::ShouldExecute;
 
-// Signed version of balance
-pub type Amount = i128;
+use crate::runtime_common::config::xcm::{DenyThenTry, DenyTransact};
 
 match_types! {
 	pub type ParentOrParentsUnitPlurality: impl Contains<MultiLocation> = {
@@ -83,123 +61,3 @@
 		AllowAllDebug,
 	),
 >;
-
-impl Convert<MultiLocation, Option<CurrencyId>> for CurrencyIdConvert {
-	fn convert(location: MultiLocation) -> Option<CurrencyId> {
-		if location == MultiLocation::here()
-			|| location == MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())))
-		{
-			return Some(AssetIds::NativeAssetId(NativeCurrency::Here));
-		}
-
-		if location == MultiLocation::parent() {
-			return Some(AssetIds::NativeAssetId(NativeCurrency::Parent));
-		}
-
-		if let Some(currency_id) =
-			XcmForeignAssetIdMapping::<Runtime>::get_currency_id(location.clone())
-		{
-			return Some(currency_id);
-		}
-
-		None
-	}
-}
-
-impl orml_tokens::Config for Runtime {
-	type Event = Event;
-	type Balance = Balance;
-	type Amount = Amount;
-	type CurrencyId = CurrencyId;
-	type WeightInfo = ();
-	type ExistentialDeposits = ExistentialDeposits;
-	type OnDust = orml_tokens::TransferDust<Runtime, TreasuryAccountId>;
-	type MaxLocks = MaxLocks;
-	type MaxReserves = MaxReserves;
-	// TODO: Add all module accounts
-	type DustRemovalWhitelist = DustRemovalWhitelist;
-	/// The id type for named reserves.
-	type ReserveIdentifier = ();
-	type OnNewTokenAccount = ();
-	type OnKilledTokenAccount = ();
-}
-
-impl orml_xtokens::Config for Runtime {
-	type Event = Event;
-	type Balance = Balance;
-	type CurrencyId = CurrencyId;
-	type CurrencyIdConvert = CurrencyIdConvert;
-	type AccountIdToMultiLocation = AccountIdToMultiLocation;
-	type SelfLocation = SelfLocation;
-	type XcmExecutor = XcmExecutor<XcmConfig<Self>>;
-	type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
-	type BaseXcmWeight = BaseXcmWeight;
-	type LocationInverter = LocationInverter<Ancestry>;
-	type MaxAssetsForTransfer = MaxAssetsForTransfer;
-	type MinXcmFee = ParachainMinFee;
-	type MultiLocationsFilter = Everything;
-	type ReserveProvider = AbsoluteReserveProvider;
-}
-
-parameter_type_with_key! {
-	pub ExistentialDeposits: |currency_id: CurrencyId| -> Balance {
-		match currency_id {
-			CurrencyId::NativeAssetId(symbol) => match symbol {
-				NativeCurrency::Here => 0,
-				NativeCurrency::Parent=> 0,
-			},
-			_ => 100_000
-		}
-	};
-}
-
-pub struct DustRemovalWhitelist;
-impl Contains<AccountId> for DustRemovalWhitelist {
-	fn contains(a: &AccountId) -> bool {
-		get_all_module_accounts().contains(a)
-	}
-}
-
-pub struct CurrencyIdConvert;
-impl Convert<AssetIds, Option<MultiLocation>> for CurrencyIdConvert {
-	fn convert(id: AssetIds) -> Option<MultiLocation> {
-		match id {
-			AssetIds::NativeAssetId(NativeCurrency::Here) => Some(MultiLocation::new(
-				1,
-				X1(Parachain(ParachainInfo::get().into())),
-			)),
-			AssetIds::NativeAssetId(NativeCurrency::Parent) => Some(MultiLocation::parent()),
-			AssetIds::ForeignAssetId(foreign_asset_id) => {
-				XcmForeignAssetIdMapping::<Runtime>::get_multi_location(foreign_asset_id)
-			}
-		}
-	}
-}
-
-parameter_types! {
-	pub const BaseXcmWeight: Weight = 100_000_000; // TODO: recheck this
-	pub const MaxAssetsForTransfer: usize = 2;
-
-	pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();
-	pub SelfLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())));
-}
-
-parameter_type_with_key! {
-	pub ParachainMinFee: |_location: MultiLocation| -> Option<u128> {
-		Some(100_000_000_000)
-	};
-}
-
-pub fn get_all_module_accounts() -> Vec<AccountId> {
-	vec![TreasuryModuleId::get().into_account_truncating()]
-}
-pub struct AccountIdToMultiLocation;
-impl Convert<AccountId, MultiLocation> for AccountIdToMultiLocation {
-	fn convert(account: AccountId) -> MultiLocation {
-		X1(AccountId32 {
-			network: NetworkId::Any,
-			id: account.into(),
-		})
-		.into()
-	}
-}
modifiedruntime/quartz/src/xcm_config.rsdiffbeforeafterboth
--- a/runtime/quartz/src/xcm_config.rs
+++ b/runtime/quartz/src/xcm_config.rs
@@ -15,33 +15,20 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 use frame_support::{
-	{match_types, parameter_types, weights::Weight},
-	pallet_prelude::Get,
-	traits::{Contains, Everything},
+	match_types, parameter_types,
+	traits::{Everything, Get},
 };
-use orml_traits::{location::AbsoluteReserveProvider, parameter_type_with_key};
-use sp_runtime::traits::{AccountIdConversion, Convert};
 use sp_std::{vec, vec::Vec};
-use xcm::{
-	latest::Xcm,
-	v1::{BodyId, Junction::*, Junctions::*, MultiLocation, NetworkId},
-};
+use xcm::v1::{BodyId, Junction::*, Junctions::*, MultiLocation};
 use xcm_builder::{
 	AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom,
-	AllowUnpaidExecutionFrom, FixedWeightBounds, LocationInverter, TakeWeightCredit,
+	AllowUnpaidExecutionFrom, TakeWeightCredit,
 };
-use xcm_executor::XcmExecutor;
 
-use up_common::types::{AccountId, Balance};
-use pallet_foreing_assets::{AssetIds, CurrencyId, NativeCurrency};
-use crate::{Call, Event, ParachainInfo, PolkadotXcm, Runtime};
-use crate::runtime_common::config::substrate::{TreasuryModuleId, MaxLocks, MaxReserves};
-use crate::runtime_common::config::pallets::TreasuryAccountId;
-use crate::runtime_common::config::xcm::*;
-use xcm::opaque::latest::prelude::{DepositReserveAsset, TransferReserveAsset};
-
-// Signed version of balance
-pub type Amount = i128;
+use crate::{
+	ParachainInfo, PolkadotXcm,
+	runtime_common::config::xcm::{DenyThenTry, DenyTransact, DenyExchangeWithUnknownLocation},
+};
 
 match_types! {
 	pub type ParentOrParentsExecutivePlurality: impl Contains<MultiLocation> = {
@@ -54,22 +41,8 @@
 	};
 }
 
-pub type Barrier = DenyThenTry<
-	(DenyTransact, DenyExchangeWithUnknownLocation),
-	(
-		TakeWeightCredit,
-		AllowTopLevelPaidExecutionFrom<Everything>,
-		// Parent and its exec plurality get free execution
-		AllowUnpaidExecutionFrom<ParentOrParentsExecutivePlurality>,
-		// Expected responses are OK.
-		AllowKnownQueryResponses<PolkadotXcm>,
-		// Subscriptions for version tracking are OK.
-		AllowSubscriptionsFrom<ParentOrSiblings>,
-	),
->;
-
-pub fn get_allowed_locations() -> Vec<MultiLocation> {
-	vec![
+parameter_types! {
+	pub QuartzAllowedLocations: Vec<MultiLocation> = vec![
 		// Self location
 		MultiLocation {
 			parents: 0,
@@ -95,131 +68,22 @@
 			parents: 1,
 			interior: X1(Parachain(ParachainInfo::get().into())),
 		},
-	]
-}
-
-// Allow xcm exchange only with locations in list
-pub struct DenyExchangeWithUnknownLocation;
-impl TryPass for DenyExchangeWithUnknownLocation {
-	fn try_pass<Call>(origin: &MultiLocation, message: &mut Xcm<Call>) -> Result<(), ()> {
-		// Check if deposit or transfer belongs to allowed parachains
-		let mut allowed = get_allowed_locations().contains(origin);
-
-		message.0.iter().for_each(|inst| match inst {
-			DepositReserveAsset { dest: dst, .. } => {
-				allowed |= get_allowed_locations().contains(dst);
-			}
-			TransferReserveAsset { dest: dst, .. } => {
-				allowed |= get_allowed_locations().contains(dst);
-			}
-			_ => {}
-		});
-
-		if allowed {
-			return Ok(());
-		}
-
-		log::warn!(
-			target: "xcm::barrier",
-			"Unexpected deposit or transfer location"
-		);
-		// Deny
-		Err(())
-	}
+	];
 }
 
-impl orml_tokens::Config for Runtime {
-	type Event = Event;
-	type Balance = Balance;
-	type Amount = Amount;
-	type CurrencyId = CurrencyId;
-	type WeightInfo = ();
-	type ExistentialDeposits = ExistentialDeposits;
-	type OnDust = orml_tokens::TransferDust<Runtime, TreasuryAccountId>;
-	type MaxLocks = MaxLocks;
-	type MaxReserves = MaxReserves;
-	// TODO: Add all module accounts
-	type DustRemovalWhitelist = DustRemovalWhitelist;
-	/// The id type for named reserves.
-	type ReserveIdentifier = ();
-	type OnNewTokenAccount = ();
-	type OnKilledTokenAccount = ();
-}
-
-impl orml_xtokens::Config for Runtime {
-	type Event = Event;
-	type Balance = Balance;
-	type CurrencyId = CurrencyId;
-	type CurrencyIdConvert = CurrencyIdConvert;
-	type AccountIdToMultiLocation = AccountIdToMultiLocation;
-	type SelfLocation = SelfLocation;
-	type XcmExecutor = XcmExecutor<XcmConfig<Self>>;
-	type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
-	type BaseXcmWeight = BaseXcmWeight;
-	type LocationInverter = LocationInverter<Ancestry>;
-	type MaxAssetsForTransfer = MaxAssetsForTransfer;
-	type MinXcmFee = ParachainMinFee;
-	type MultiLocationsFilter = Everything;
-	type ReserveProvider = AbsoluteReserveProvider;
-}
-
-parameter_type_with_key! {
-	pub ExistentialDeposits: |currency_id: CurrencyId| -> Balance {
-		match currency_id {
-			CurrencyId::NativeAssetId(symbol) => match symbol {
-				NativeCurrency::Here => 0,
-				NativeCurrency::Parent=> 0,
-			},
-			_ => 100_000
-		}
-	};
-}
-
-pub struct DustRemovalWhitelist;
-impl Contains<AccountId> for DustRemovalWhitelist {
-	fn contains(a: &AccountId) -> bool {
-		get_all_module_accounts().contains(a)
-	}
-}
-
-pub struct CurrencyIdConvert;
-impl Convert<AssetIds, Option<MultiLocation>> for CurrencyIdConvert {
-	fn convert(id: AssetIds) -> Option<MultiLocation> {
-		match id {
-			AssetIds::NativeAssetId(NativeCurrency::Here) => Some(MultiLocation::new(
-				1,
-				X1(Parachain(ParachainInfo::get().into())),
-			)),
-			_ => None,
-		}
-	}
-}
-
-parameter_types! {
-	pub const BaseXcmWeight: Weight = 100_000_000; // TODO: recheck this
-	pub const MaxAssetsForTransfer: usize = 2;
-
-	pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();
-	pub SelfLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())));
-}
-
-parameter_type_with_key! {
-	pub ParachainMinFee: |_location: MultiLocation| -> Option<u128> {
-		Some(100_000_000)
-	};
-}
-
-pub fn get_all_module_accounts() -> Vec<AccountId> {
-	vec![TreasuryModuleId::get().into_account_truncating()]
-}
-
-pub struct AccountIdToMultiLocation;
-impl Convert<AccountId, MultiLocation> for AccountIdToMultiLocation {
-	fn convert(account: AccountId) -> MultiLocation {
-		X1(AccountId32 {
-			network: NetworkId::Any,
-			id: account.into(),
-		})
-		.into()
-	}
-}
+pub type Barrier = DenyThenTry<
+	(
+		DenyTransact,
+		DenyExchangeWithUnknownLocation<QuartzAllowedLocations>,
+	),
+	(
+		TakeWeightCredit,
+		AllowTopLevelPaidExecutionFrom<Everything>,
+		// Parent and its exec plurality get free execution
+		AllowUnpaidExecutionFrom<ParentOrParentsExecutivePlurality>,
+		// Expected responses are OK.
+		AllowKnownQueryResponses<PolkadotXcm>,
+		// Subscriptions for version tracking are OK.
+		AllowSubscriptionsFrom<ParentOrSiblings>,
+	),
+>;
modifiedruntime/unique/src/xcm_config.rsdiffbeforeafterboth
--- a/runtime/unique/src/xcm_config.rs
+++ b/runtime/unique/src/xcm_config.rs
@@ -15,33 +15,20 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 use frame_support::{
-	{match_types, parameter_types, weights::Weight},
-	pallet_prelude::Get,
-	traits::{Contains, Everything},
+	match_types, parameter_types,
+	traits::{Everything, Get},
 };
-use orml_traits::{location::AbsoluteReserveProvider, parameter_type_with_key};
-use sp_runtime::traits::{AccountIdConversion, Convert};
 use sp_std::{vec, vec::Vec};
-use xcm::{
-	latest::Xcm,
-	v1::{BodyId, Junction::*, Junctions::*, MultiLocation, NetworkId},
-};
+use xcm::v1::{BodyId, Junction::*, Junctions::*, MultiLocation};
 use xcm_builder::{
 	AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom,
-	AllowUnpaidExecutionFrom, FixedWeightBounds, LocationInverter, TakeWeightCredit,
+	AllowUnpaidExecutionFrom, TakeWeightCredit,
 };
-use xcm_executor::XcmExecutor;
 
-use up_common::types::{AccountId, Balance};
-use pallet_foreing_assets::{AssetIds, CurrencyId, NativeCurrency};
-use crate::{Call, Event, ParachainInfo, PolkadotXcm, Runtime};
-use crate::runtime_common::config::substrate::{TreasuryModuleId, MaxLocks, MaxReserves};
-use crate::runtime_common::config::pallets::TreasuryAccountId;
-use crate::runtime_common::config::xcm::*;
-use xcm::opaque::latest::prelude::{DepositReserveAsset, TransferReserveAsset};
-
-// Signed version of balance
-pub type Amount = i128;
+use crate::{
+	ParachainInfo, PolkadotXcm,
+	runtime_common::config::xcm::{DenyThenTry, DenyTransact, DenyExchangeWithUnknownLocation},
+};
 
 match_types! {
 	pub type ParentOrParentsExecutivePlurality: impl Contains<MultiLocation> = {
@@ -54,22 +41,8 @@
 	};
 }
 
-pub type Barrier = DenyThenTry<
-	(DenyTransact, DenyExchangeWithUnknownLocation),
-	(
-		TakeWeightCredit,
-		AllowTopLevelPaidExecutionFrom<Everything>,
-		// Parent and its exec plurality get free execution
-		AllowUnpaidExecutionFrom<ParentOrParentsExecutivePlurality>,
-		// Expected responses are OK.
-		AllowKnownQueryResponses<PolkadotXcm>,
-		// Subscriptions for version tracking are OK.
-		AllowSubscriptionsFrom<ParentOrSiblings>,
-	),
->;
-
-pub fn get_allowed_locations() -> Vec<MultiLocation> {
-	vec![
+parameter_types! {
+	pub UniqueAllowedLocations: Vec<MultiLocation> = vec![
 		// Self location
 		MultiLocation {
 			parents: 0,
@@ -95,131 +68,22 @@
 			parents: 1,
 			interior: X1(Parachain(ParachainInfo::get().into())),
 		},
-	]
-}
-
-// Allow xcm exchange only with locations in list
-pub struct DenyExchangeWithUnknownLocation;
-impl TryPass for DenyExchangeWithUnknownLocation {
-	fn try_pass<Call>(origin: &MultiLocation, message: &mut Xcm<Call>) -> Result<(), ()> {
-		// Check if deposit or transfer belongs to allowed parachains
-		let mut allowed = get_allowed_locations().contains(origin);
-
-		message.0.iter().for_each(|inst| match inst {
-			DepositReserveAsset { dest: dst, .. } => {
-				allowed |= get_allowed_locations().contains(dst);
-			}
-			TransferReserveAsset { dest: dst, .. } => {
-				allowed |= get_allowed_locations().contains(dst);
-			}
-			_ => {}
-		});
-
-		if allowed {
-			return Ok(());
-		}
-
-		log::warn!(
-			target: "xcm::barrier",
-			"Unexpected deposit or transfer location"
-		);
-		// Deny
-		Err(())
-	}
+	];
 }
 
-impl orml_tokens::Config for Runtime {
-	type Event = Event;
-	type Balance = Balance;
-	type Amount = Amount;
-	type CurrencyId = CurrencyId;
-	type WeightInfo = ();
-	type ExistentialDeposits = ExistentialDeposits;
-	type OnDust = orml_tokens::TransferDust<Runtime, TreasuryAccountId>;
-	type MaxLocks = MaxLocks;
-	type MaxReserves = MaxReserves;
-	// TODO: Add all module accounts
-	type DustRemovalWhitelist = DustRemovalWhitelist;
-	/// The id type for named reserves.
-	type ReserveIdentifier = ();
-	type OnNewTokenAccount = ();
-	type OnKilledTokenAccount = ();
-}
-
-impl orml_xtokens::Config for Runtime {
-	type Event = Event;
-	type Balance = Balance;
-	type CurrencyId = CurrencyId;
-	type CurrencyIdConvert = CurrencyIdConvert;
-	type AccountIdToMultiLocation = AccountIdToMultiLocation;
-	type SelfLocation = SelfLocation;
-	type XcmExecutor = XcmExecutor<XcmConfig<Self>>;
-	type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
-	type BaseXcmWeight = BaseXcmWeight;
-	type LocationInverter = LocationInverter<Ancestry>;
-	type MaxAssetsForTransfer = MaxAssetsForTransfer;
-	type MinXcmFee = ParachainMinFee;
-	type MultiLocationsFilter = Everything;
-	type ReserveProvider = AbsoluteReserveProvider;
-}
-
-parameter_type_with_key! {
-	pub ExistentialDeposits: |currency_id: CurrencyId| -> Balance {
-		match currency_id {
-			CurrencyId::NativeAssetId(symbol) => match symbol {
-				NativeCurrency::Here => 0,
-				NativeCurrency::Parent=> 0,
-			},
-			_ => 100_000
-		}
-	};
-}
-
-pub struct DustRemovalWhitelist;
-impl Contains<AccountId> for DustRemovalWhitelist {
-	fn contains(a: &AccountId) -> bool {
-		get_all_module_accounts().contains(a)
-	}
-}
-
-pub struct CurrencyIdConvert;
-impl Convert<AssetIds, Option<MultiLocation>> for CurrencyIdConvert {
-	fn convert(id: AssetIds) -> Option<MultiLocation> {
-		match id {
-			AssetIds::NativeAssetId(NativeCurrency::Here) => Some(MultiLocation::new(
-				1,
-				X1(Parachain(ParachainInfo::get().into())),
-			)),
-			_ => None,
-		}
-	}
-}
-
-parameter_types! {
-	pub const BaseXcmWeight: Weight = 100_000_000; // TODO: recheck this
-	pub const MaxAssetsForTransfer: usize = 2;
-
-	pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();
-	pub SelfLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())));
-}
-
-parameter_type_with_key! {
-	pub ParachainMinFee: |_location: MultiLocation| -> Option<u128> {
-		Some(100_000_000)
-	};
-}
-
-pub fn get_all_module_accounts() -> Vec<AccountId> {
-	vec![TreasuryModuleId::get().into_account_truncating()]
-}
-
-pub struct AccountIdToMultiLocation;
-impl Convert<AccountId, MultiLocation> for AccountIdToMultiLocation {
-	fn convert(account: AccountId) -> MultiLocation {
-		X1(AccountId32 {
-			network: NetworkId::Any,
-			id: account.into(),
-		})
-		.into()
-	}
-}
+pub type Barrier = DenyThenTry<
+	(
+		DenyTransact,
+		DenyExchangeWithUnknownLocation<UniqueAllowedLocations>,
+	),
+	(
+		TakeWeightCredit,
+		AllowTopLevelPaidExecutionFrom<Everything>,
+		// Parent and its exec plurality get free execution
+		AllowUnpaidExecutionFrom<ParentOrParentsExecutivePlurality>,
+		// Expected responses are OK.
+		AllowKnownQueryResponses<PolkadotXcm>,
+		// Subscriptions for version tracking are OK.
+		AllowSubscriptionsFrom<ParentOrSiblings>,
+	),
+>;