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;6768match_types! {69 pub type ParentOrParentsExecutivePlurality: impl Contains<MultiLocation> = {70 MultiLocation { parents: 1, interior: Here } |71 MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Executive, .. }) }72 };73 pub type ParentOrSiblings: impl Contains<MultiLocation> = {74 MultiLocation { parents: 1, interior: Here } |75 MultiLocation { parents: 1, interior: X1(_) }76 };77}78798081pub struct DenyThenTry<Deny, Allow>(PhantomData<Deny>, PhantomData<Allow>)82 where83 Deny: ShouldExecute,84 Allow: ShouldExecute;8586impl<Deny, Allow> ShouldExecute for DenyThenTry<Deny, Allow>87 where88 Deny: ShouldExecute,89 Allow: ShouldExecute,90{91 fn should_execute<Call>(92 origin: &MultiLocation,93 message: &mut Xcm<Call>,94 max_weight: Weight,95 weight_credit: &mut Weight,96 ) -> Result<(), ()> {97 Deny::should_execute(origin, message, max_weight, weight_credit)?;98 Allow::should_execute(origin, message, max_weight, weight_credit)99 }100}101102pub fn get_allowed_locations() -> Vec<MultiLocation> {103 vec![104 105 MultiLocation { parents: 0, interior: Here },106 107 MultiLocation { parents: 1, interior: Here },108 109 MultiLocation { parents: 1, interior: X1(Parachain(2000)) },110 111 MultiLocation { parents: 1, interior: X1(Parachain(2023)) },112 113 MultiLocation { parents: 1, interior: X1(Parachain(ParachainInfo::get().into())) },114 ]115}116117118pub struct DenyExchangeWithUnknownLocation;119impl ShouldExecute for DenyExchangeWithUnknownLocation {120 fn should_execute<Call>(121 origin: &MultiLocation,122 message: &mut Xcm<Call>,123 _max_weight: Weight,124 _weight_credit: &mut Weight,125 ) -> Result<(), ()> {126127 128 let mut allowed = get_allowed_locations().contains(origin);129130 message.0.iter().for_each(|inst| {131 match inst {132 DepositReserveAsset { dest: dst, .. } => { allowed |= get_allowed_locations().contains(dst); }133 TransferReserveAsset { dest: dst, .. } => { allowed |= get_allowed_locations().contains(dst); }134 _ => {}135 }136 });137138 if allowed {139 return Ok(());140 }141142 log::warn!(143 target: "xcm::barrier",144 "Unexpected deposit or transfer location"145 );146 147 Err(())148 }149}150151pub type Barrier = DenyThenTry<152 DenyExchangeWithUnknownLocation,153 (154 TakeWeightCredit,155 AllowTopLevelPaidExecutionFrom<Everything>,156 157 AllowUnpaidExecutionFrom<ParentOrParentsExecutivePlurality>,158 159 AllowKnownQueryResponses<PolkadotXcm>,160 161 AllowSubscriptionsFrom<ParentOrSiblings>,162 ),163>;164165impl orml_tokens::Config for Runtime {166 type Event = Event;167 type Balance = Balance;168 type Amount = Amount;169 type CurrencyId = CurrencyId;170 type WeightInfo = ();171 type ExistentialDeposits = ExistentialDeposits;172 type OnDust = orml_tokens::TransferDust<Runtime, TreasuryAccountId>;173 type MaxLocks = MaxLocks;174 type MaxReserves = MaxReserves;175 176 type DustRemovalWhitelist = DustRemovalWhitelist;177 178 type ReserveIdentifier = ();179 type OnNewTokenAccount = ();180 type OnKilledTokenAccount = ();181}182183184185186187188189190191192193194195196197198199200201202parameter_type_with_key! {203 pub ExistentialDeposits: |currency_id: CurrencyId| -> Balance {204 match currency_id {205 CurrencyId::NativeAssetId(symbol) => match symbol {206 NativeCurrency::Here => 0,207 NativeCurrency::Parent=> 0,208 },209 _ => 100_000210 }211 };212}213214pub struct DustRemovalWhitelist;215impl Contains<AccountId> for DustRemovalWhitelist {216 fn contains(a: &AccountId) -> bool {217 get_all_module_accounts().contains(a)218 }219}220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262parameter_types! {263 pub const BaseXcmWeight: Weight = 100_000_000; 264 pub const MaxAssetsForTransfer: usize = 2;265}266267parameter_types! {268 pub const RelayLocation: MultiLocation = MultiLocation::parent();269 pub const RelayNetwork: NetworkId = NetworkId::Polkadot;270 pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();271 pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();272 pub SelfLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())));273}274275parameter_type_with_key! {276 pub ParachainMinFee: |_location: MultiLocation| -> Option<u128> {277 Some(100_000_000)278 };279}280281pub fn get_all_module_accounts() -> Vec<AccountId> {282 vec![TreasuryModuleId::get().into_account_truncating()]283}284285pub struct AccountIdToMultiLocation;286impl Convert<AccountId, MultiLocation> for AccountIdToMultiLocation {287 fn convert(account: AccountId) -> MultiLocation {288 X1(AccountId32 {289 network: NetworkId::Any,290 id: account.into(),291 })292 .into()293 }294}