1234567891011121314151617use frame_support::{18 {match_types, parameter_types, weights::Weight},19 pallet_prelude::Get,20 traits::{Contains, Everything},21};22use orml_traits::{location::AbsoluteReserveProvider, parameter_type_with_key};23use sp_runtime::traits::{AccountIdConversion, Convert};24use sp_std::{vec, vec::Vec};25use xcm::{26 latest::Xcm,27 v1::{BodyId, Junction::*, Junctions::*, MultiLocation, NetworkId},28};29use xcm_builder::{30 AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom,31 AllowUnpaidExecutionFrom, FixedWeightBounds, LocationInverter, TakeWeightCredit,32};33use xcm_executor::XcmExecutor;3435use up_common::types::{AccountId, Balance};36use pallet_foreing_assets::{AssetIds, CurrencyId, NativeCurrency};37use crate::{Call, Event, ParachainInfo, PolkadotXcm, Runtime};38use crate::runtime_common::config::substrate::{TreasuryModuleId, MaxLocks, MaxReserves};39use crate::runtime_common::config::pallets::TreasuryAccountId;40use crate::runtime_common::config::xcm::*;41use xcm::opaque::latest::prelude::{DepositReserveAsset, TransferReserveAsset};424344pub type Amount = i128;4546match_types! {47 pub type ParentOrParentsExecutivePlurality: impl Contains<MultiLocation> = {48 MultiLocation { parents: 1, interior: Here } |49 MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Executive, .. }) }50 };51 pub type ParentOrSiblings: impl Contains<MultiLocation> = {52 MultiLocation { parents: 1, interior: Here } |53 MultiLocation { parents: 1, interior: X1(_) }54 };55}5657pub type Barrier = DenyThenTry<58 (DenyTransact, DenyExchangeWithUnknownLocation),59 (60 TakeWeightCredit,61 AllowTopLevelPaidExecutionFrom<Everything>,62 63 AllowUnpaidExecutionFrom<ParentOrParentsExecutivePlurality>,64 65 AllowKnownQueryResponses<PolkadotXcm>,66 67 AllowSubscriptionsFrom<ParentOrSiblings>,68 ),69>;7071pub fn get_allowed_locations() -> Vec<MultiLocation> {72 vec![73 74 MultiLocation {75 parents: 0,76 interior: Here,77 },78 79 MultiLocation {80 parents: 1,81 interior: Here,82 },83 84 MultiLocation {85 parents: 1,86 interior: X1(Parachain(2000)),87 },88 89 MultiLocation {90 parents: 1,91 interior: X1(Parachain(2004)),92 },93 94 MultiLocation {95 parents: 1,96 interior: X1(Parachain(ParachainInfo::get().into())),97 },98 ]99}100101102pub struct DenyExchangeWithUnknownLocation;103impl TryPass for DenyExchangeWithUnknownLocation {104 fn try_pass<Call>(origin: &MultiLocation, message: &mut Xcm<Call>) -> Result<(), ()> {105 106 let mut allowed = get_allowed_locations().contains(origin);107108 message.0.iter().for_each(|inst| match inst {109 DepositReserveAsset { dest: dst, .. } => {110 allowed |= get_allowed_locations().contains(dst);111 }112 TransferReserveAsset { dest: dst, .. } => {113 allowed |= get_allowed_locations().contains(dst);114 }115 _ => {}116 });117118 if allowed {119 return Ok(());120 }121122 log::warn!(123 target: "xcm::barrier",124 "Unexpected deposit or transfer location"125 );126 127 Err(())128 }129}130131impl orml_tokens::Config for Runtime {132 type Event = Event;133 type Balance = Balance;134 type Amount = Amount;135 type CurrencyId = CurrencyId;136 type WeightInfo = ();137 type ExistentialDeposits = ExistentialDeposits;138 type OnDust = orml_tokens::TransferDust<Runtime, TreasuryAccountId>;139 type MaxLocks = MaxLocks;140 type MaxReserves = MaxReserves;141 142 type DustRemovalWhitelist = DustRemovalWhitelist;143 144 type ReserveIdentifier = ();145 type OnNewTokenAccount = ();146 type OnKilledTokenAccount = ();147}148149impl orml_xtokens::Config for Runtime {150 type Event = Event;151 type Balance = Balance;152 type CurrencyId = CurrencyId;153 type CurrencyIdConvert = CurrencyIdConvert;154 type AccountIdToMultiLocation = AccountIdToMultiLocation;155 type SelfLocation = SelfLocation;156 type XcmExecutor = XcmExecutor<XcmConfig<Self>>;157 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;158 type BaseXcmWeight = BaseXcmWeight;159 type LocationInverter = LocationInverter<Ancestry>;160 type MaxAssetsForTransfer = MaxAssetsForTransfer;161 type MinXcmFee = ParachainMinFee;162 type MultiLocationsFilter = Everything;163 type ReserveProvider = AbsoluteReserveProvider;164}165166parameter_type_with_key! {167 pub ExistentialDeposits: |currency_id: CurrencyId| -> Balance {168 match currency_id {169 CurrencyId::NativeAssetId(symbol) => match symbol {170 NativeCurrency::Here => 0,171 NativeCurrency::Parent=> 0,172 },173 _ => 100_000174 }175 };176}177178pub struct DustRemovalWhitelist;179impl Contains<AccountId> for DustRemovalWhitelist {180 fn contains(a: &AccountId) -> bool {181 get_all_module_accounts().contains(a)182 }183}184185pub struct CurrencyIdConvert;186impl Convert<AssetIds, Option<MultiLocation>> for CurrencyIdConvert {187 fn convert(id: AssetIds) -> Option<MultiLocation> {188 match id {189 AssetIds::NativeAssetId(NativeCurrency::Here) => Some(MultiLocation::new(190 1,191 X1(Parachain(ParachainInfo::get().into())),192 )),193 _ => None,194 }195 }196}197198parameter_types! {199 pub const BaseXcmWeight: Weight = 100_000_000; 200 pub const MaxAssetsForTransfer: usize = 2;201202 pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();203 pub SelfLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())));204}205206parameter_type_with_key! {207 pub ParachainMinFee: |_location: MultiLocation| -> Option<u128> {208 Some(100_000_000)209 };210}211212pub fn get_all_module_accounts() -> Vec<AccountId> {213 vec![TreasuryModuleId::get().into_account_truncating()]214}215216pub struct AccountIdToMultiLocation;217impl Convert<AccountId, MultiLocation> for AccountIdToMultiLocation {218 fn convert(account: AccountId) -> MultiLocation {219 X1(AccountId32 {220 network: NetworkId::Any,221 id: account.into(),222 })223 .into()224 }225}