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 AssetTransactor = 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 106 Self(Weight::from_parts(0, 0), Zero::zero(), PhantomData)107 }108109 fn buy_weight(&mut self, _weight: Weight, payment: Assets) -> Result<Assets, XcmError> {110 Ok(payment)111 }112}113impl<114 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,115 AssetId: Get<MultiLocation>,116 AccountId,117 Currency: CurrencyT<AccountId>,118 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,119 > Drop120 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>121{122 fn drop(&mut self) {123 OnUnbalanced::on_unbalanced(Currency::issue(self.1));124 }125}126127pub type Trader<T> = UsingOnlySelfCurrencyComponents<128 pallet_configuration::WeightToFee<T, Balance>,129 RelayLocation,130 AccountId,131 Balances,132 (),133>;134135pub struct CurrencyIdConvert;136impl Convert<AssetIds, Option<MultiLocation>> for CurrencyIdConvert {137 fn convert(id: AssetIds) -> Option<MultiLocation> {138 match id {139 AssetIds::NativeAssetId(NativeCurrency::Here) => Some(MultiLocation::new(140 1,141 X1(Parachain(ParachainInfo::get().into())),142 )),143 _ => None,144 }145 }146}