1234567891011121314151617use cumulus_pallet_xcm;18use frame_support::{19 {match_types, parameter_types, weights::Weight},20 pallet_prelude::Get,21 traits::{Contains, Everything, fungibles},22};23use frame_system::EnsureRoot;24use orml_traits::{location::AbsoluteReserveProvider, parameter_type_with_key};25use pallet_xcm::XcmPassthrough;26use polkadot_parachain::primitives::Sibling;27use sp_runtime::traits::{AccountIdConversion, CheckedConversion, Convert, Zero};28use sp_std::{borrow::Borrow, marker::PhantomData, vec, vec::Vec};29use xcm::{30 latest::{MultiAsset, Xcm},31 prelude::{Concrete, Fungible as XcmFungible},32 v1::{BodyId, Junction::*, Junctions::*, MultiLocation, NetworkId},33};34use xcm_builder::{35 AllowKnownQueryResponses, AllowSubscriptionsFrom,36 AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom,37 EnsureXcmOrigin, FixedWeightBounds, FungiblesAdapter, LocationInverter, ParentAsSuperuser,38 ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,39 SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,40 ConvertedConcreteAssetId,41};42use xcm_executor::{43 {Config, XcmExecutor},44 traits::{Convert as ConvertXcm, FilterAssetLocation, JustTry, MatchesFungible, ShouldExecute},45};4647use up_common::{48 constants::{MAXIMUM_BLOCK_WEIGHT, UNIQUE},49 types::{AccountId, Balance},50};51use pallet_foreing_assets::{52 AssetIds, AssetIdMapping, XcmForeignAssetIdMapping, CurrencyId, NativeCurrency,53 FreeForAll, TryAsForeing, ForeignAssetId,54};55use crate::{56 Balances, Call, DmpQueue, Event, Origin, ParachainInfo,57 ParachainSystem, PolkadotXcm, Runtime, XcmpQueue,58};59use crate::runtime_common::config::substrate::{TreasuryModuleId, MaxLocks, MaxReserves};60use crate::runtime_common::config::pallets::TreasuryAccountId;61use crate::runtime_common::config::xcm::*;62use crate::*;63use xcm::opaque::latest::prelude::{ DepositReserveAsset, DepositAsset, TransferAsset, TransferReserveAsset };646566pub type Amount = i128;676869pub type Barrier = DenyThenTry<70 DenyExchangeWithUnknownLocation,71 (72 TakeWeightCredit,73 AllowTopLevelPaidExecutionFrom<Everything>,74 75 AllowUnpaidExecutionFrom<ParentOrParentsExecutivePlurality>,76 77 AllowKnownQueryResponses<PolkadotXcm>,78 79 AllowSubscriptionsFrom<ParentOrSiblings>,80 ),81>;8283pub fn get_allowed_locations() -> Vec<MultiLocation> {84 vec![85 86 MultiLocation { parents: 0, interior: Here },87 88 MultiLocation { parents: 1, interior: Here },89 90 MultiLocation { parents: 1, interior: X1(Parachain(2000)) },91 92 MultiLocation { parents: 1, interior: X1(Parachain(2004)) },93 94 MultiLocation { parents: 1, interior: X1(Parachain(ParachainInfo::get().into())) },95 ]96}9798pub struct DenyThenTry<Deny, Allow>(PhantomData<Deny>, PhantomData<Allow>)99 where100 Deny: ShouldExecute,101 Allow: ShouldExecute;102103impl<Deny, Allow> ShouldExecute for DenyThenTry<Deny, Allow>104 where105 Deny: ShouldExecute,106 Allow: ShouldExecute,107{108 fn should_execute<Call>(109 origin: &MultiLocation,110 message: &mut Xcm<Call>,111 max_weight: Weight,112 weight_credit: &mut Weight,113 ) -> Result<(), ()> {114 Deny::should_execute(origin, message, max_weight, weight_credit)?;115 Allow::should_execute(origin, message, max_weight, weight_credit)116 }117}118119120pub struct DenyExchangeWithUnknownLocation;121impl ShouldExecute for DenyExchangeWithUnknownLocation {122 fn should_execute<Call>(123 origin: &MultiLocation,124 message: &mut Xcm<Call>,125 _max_weight: Weight,126 _weight_credit: &mut Weight,127 ) -> Result<(), ()> {128129 130 let mut allowed = get_allowed_locations().contains(origin);131132 message.0.iter().for_each(|inst| {133 match inst {134 DepositReserveAsset { dest: dst, .. } => { allowed |= get_allowed_locations().contains(dst); }135 TransferReserveAsset { dest: dst, .. } => { allowed |= get_allowed_locations().contains(dst); }136 _ => {}137 }138 });139140 if allowed {141 return Ok(());142 }143144 log::warn!(145 target: "xcm::barrier",146 "Unexpected deposit or transfer location"147 );148 149 Err(())150 }151}152153154match_types! {155 pub type ParentOrParentsExecutivePlurality: impl Contains<MultiLocation> = {156 MultiLocation { parents: 1, interior: Here } |157 MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Executive, .. }) }158 };159 pub type ParentOrSiblings: impl Contains<MultiLocation> = {160 MultiLocation { parents: 1, interior: Here } |161 MultiLocation { parents: 1, interior: X1(_) }162 };163}164165pub fn get_all_module_accounts() -> Vec<AccountId> {166 vec![TreasuryModuleId::get().into_account_truncating()]167}168169pub struct DustRemovalWhitelist;170impl Contains<AccountId> for DustRemovalWhitelist {171 fn contains(a: &AccountId) -> bool {172 get_all_module_accounts().contains(a)173 }174}175176parameter_type_with_key! {177 pub ExistentialDeposits: |currency_id: CurrencyId| -> Balance {178 match currency_id {179 CurrencyId::NativeAssetId(symbol) => match symbol {180 NativeCurrency::Here => 0,181 NativeCurrency::Parent=> 0,182 },183 _ => 100_000184 }185 };186}187188impl orml_tokens::Config for Runtime {189 type Event = Event;190 type Balance = Balance;191 type Amount = Amount;192 type CurrencyId = CurrencyId;193 type WeightInfo = ();194 type ExistentialDeposits = ExistentialDeposits;195 type OnDust = orml_tokens::TransferDust<Runtime, TreasuryAccountId>;196 type MaxLocks = MaxLocks;197 type MaxReserves = MaxReserves;198 199 type DustRemovalWhitelist = DustRemovalWhitelist;200 201 type ReserveIdentifier = ();202 type OnNewTokenAccount = ();203 type OnKilledTokenAccount = ();204}205206impl orml_xtokens::Config for Runtime {207 type Event = Event;208 type Balance = Balance;209 type CurrencyId = CurrencyId;210 type CurrencyIdConvert = CurrencyIdConvert;211 type AccountIdToMultiLocation = AccountIdToMultiLocation;212 type SelfLocation = SelfLocation;213 type XcmExecutor = XcmExecutor<XcmConfig<Self>>;214 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;215 type BaseXcmWeight = BaseXcmWeight;216 type LocationInverter = LocationInverter<Ancestry>;217 type MaxAssetsForTransfer = MaxAssetsForTransfer;218 type MinXcmFee = ParachainMinFee;219 type MultiLocationsFilter = Everything;220 type ReserveProvider = AbsoluteReserveProvider;221}222223pub struct CurrencyIdConvert;224impl Convert<AssetIds, Option<MultiLocation>> for CurrencyIdConvert {225 fn convert(id: AssetIds) -> Option<MultiLocation> {226 match id {227 AssetIds::NativeAssetId(NativeCurrency::Here) => Some(MultiLocation::new(228 1,229 X1(Parachain(ParachainInfo::get().into())),230 )),231 _ => None,232 }233 }234}235236parameter_types! {237 pub const BaseXcmWeight: Weight = 100_000_000; 238 pub const MaxAssetsForTransfer: usize = 2;239240 pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();241 pub SelfLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())));242}243244parameter_type_with_key! {245 pub ParachainMinFee: |_location: MultiLocation| -> Option<u128> {246 Some(100_000_000)247 };248}249250251pub struct AccountIdToMultiLocation;252impl Convert<AccountId, MultiLocation> for AccountIdToMultiLocation {253 fn convert(account: AccountId) -> MultiLocation {254 X1(AccountId32 {255 network: NetworkId::Any,256 id: account.into(),257 })258 .into()259 }260}