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::v1::{Junction::*, MultiLocation, Junctions::*};23use xcm::latest::{24 AssetId::{Concrete},25 Fungibility::Fungible as XcmFungible,26 MultiAsset, Error as XcmError,27 Weight,28};29use xcm_builder::{CurrencyAdapter, NativeAsset};30use xcm_executor::{31 Assets,32 traits::{MatchesFungible, WeightTrader},33};34use pallet_foreign_assets::{AssetIds, NativeCurrency};35use sp_std::marker::PhantomData;36use crate::{Balances, ParachainInfo};37use super::{LocationToAccountId, RelayLocation};3839use up_common::types::{AccountId, Balance};4041pub struct OnlySelfCurrency;42impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {43 fn matches_fungible(a: &MultiAsset) -> Option<B> {44 let paraid = Parachain(ParachainInfo::parachain_id().into());45 match (&a.id, &a.fun) {46 (47 Concrete(MultiLocation {48 parents: 1,49 interior: X1(loc),50 }),51 XcmFungible(ref amount),52 ) if paraid == *loc => CheckedConversion::checked_from(*amount),53 (54 Concrete(MultiLocation {55 parents: 0,56 interior: Here,57 }),58 XcmFungible(ref amount),59 ) => CheckedConversion::checked_from(*amount),60 _ => None,61 }62 }63}646566pub type LocalAssetTransactor = CurrencyAdapter<67 68 Balances,69 70 OnlySelfCurrency,71 72 LocationToAccountId,73 74 AccountId,75 76 (),77>;7879pub type AssetTransactors = LocalAssetTransactor;8081pub type IsReserve = NativeAsset;8283pub struct UsingOnlySelfCurrencyComponents<84 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,85 AssetId: Get<MultiLocation>,86 AccountId,87 Currency: CurrencyT<AccountId>,88 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,89>(90 Weight,91 Currency::Balance,92 PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,93);94impl<95 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,96 AssetId: Get<MultiLocation>,97 AccountId,98 Currency: CurrencyT<AccountId>,99 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,100 > WeightTrader101 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>102{103 fn new() -> Self {104 Self(0, Zero::zero(), PhantomData)105 }106107 fn buy_weight(&mut self, _weight: Weight, payment: Assets) -> Result<Assets, XcmError> {108 Ok(payment)109 }110}111impl<112 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,113 AssetId: Get<MultiLocation>,114 AccountId,115 Currency: CurrencyT<AccountId>,116 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,117 > Drop118 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>119{120 fn drop(&mut self) {121 OnUnbalanced::on_unbalanced(Currency::issue(self.1));122 }123}124125pub type Trader<T> = UsingOnlySelfCurrencyComponents<126 pallet_configuration::WeightToFee<T, Balance>,127 RelayLocation,128 AccountId,129 Balances,130 (),131>;132133pub struct CurrencyIdConvert;134impl Convert<AssetIds, Option<MultiLocation>> for CurrencyIdConvert {135 fn convert(id: AssetIds) -> Option<MultiLocation> {136 match id {137 AssetIds::NativeAssetId(NativeCurrency::Here) => Some(MultiLocation::new(138 1,139 X1(Parachain(ParachainInfo::get().into())),140 )),141 _ => None,142 }143 }144}