1234567891011121314151617use frame_support::{18 traits::{tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Get},19 weights::WeightToFeePolynomial,20};21use sp_runtime::traits::{CheckedConversion, Zero, Convert};22use xcm::latest::{23 AssetId::{Concrete},24 Fungibility::Fungible as XcmFungible,25 MultiAsset, Error as XcmError, Weight,26 Junction::*,27 MultiLocation,28 Junctions::*,29};30use xcm_builder::{CurrencyAdapter, NativeAsset};31use xcm_executor::{32 Assets,33 traits::{MatchesFungible, WeightTrader},34};35use pallet_foreign_assets::{AssetIds, NativeCurrency};36use sp_std::marker::PhantomData;37use crate::{Balances, ParachainInfo};38use super::{LocationToAccountId, RelayLocation};3940use up_common::types::{AccountId, Balance};4142pub struct OnlySelfCurrency;43impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {44 fn matches_fungible(a: &MultiAsset) -> Option<B> {45 let paraid = Parachain(ParachainInfo::parachain_id().into());46 match (&a.id, &a.fun) {47 (48 Concrete(MultiLocation {49 parents: 1,50 interior: X1(loc),51 }),52 XcmFungible(ref amount),53 ) if paraid == *loc => CheckedConversion::checked_from(*amount),54 (55 Concrete(MultiLocation {56 parents: 0,57 interior: Here,58 }),59 XcmFungible(ref amount),60 ) => CheckedConversion::checked_from(*amount),61 _ => None,62 }63 }64}656667pub type LocalAssetTransactor = CurrencyAdapter<68 69 Balances,70 71 OnlySelfCurrency,72 73 LocationToAccountId,74 75 AccountId,76 77 (),78>;7980pub type AssetTransactors = LocalAssetTransactor;8182pub type IsReserve = NativeAsset;8384pub struct UsingOnlySelfCurrencyComponents<85 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,86 AssetId: Get<MultiLocation>,87 AccountId,88 Currency: CurrencyT<AccountId>,89 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,90>(91 Weight,92 Currency::Balance,93 PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,94);95impl<96 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,97 AssetId: Get<MultiLocation>,98 AccountId,99 Currency: CurrencyT<AccountId>,100 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,101 > WeightTrader102 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>103{104 fn new() -> Self {105 Self(0, Zero::zero(), PhantomData)106 }107108 fn buy_weight(&mut self, _weight: Weight, payment: Assets) -> Result<Assets, XcmError> {109 Ok(payment)110 }111}112impl<113 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,114 AssetId: Get<MultiLocation>,115 AccountId,116 Currency: CurrencyT<AccountId>,117 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,118 > Drop119 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>120{121 fn drop(&mut self) {122 OnUnbalanced::on_unbalanced(Currency::issue(self.1));123 }124}125126pub type Trader<T> = UsingOnlySelfCurrencyComponents<127 pallet_configuration::WeightToFee<T, Balance>,128 RelayLocation,129 AccountId,130 Balances,131 (),132>;133134pub struct CurrencyIdConvert;135impl Convert<AssetIds, Option<MultiLocation>> for CurrencyIdConvert {136 fn convert(id: AssetIds) -> Option<MultiLocation> {137 match id {138 AssetIds::NativeAssetId(NativeCurrency::Here) => Some(MultiLocation::new(139 1,140 X1(Parachain(ParachainInfo::get().into())),141 )),142 _ => None,143 }144 }145}