use core::marker::PhantomData;
use frame_support::traits::{
fungible::{self, NativeOrWithId},
tokens::ConversionFromAssetBalance,
};
use moonbeam_core_primitives::{AssetId, Balance};
use pallet_xcm_weight_trader::RELATIVE_PRICE_DECIMALS;
use sp_runtime::traits::MaybeEquivalence;
pub struct AssetRateConverter<T, NativeAsset>(PhantomData<(T, NativeAsset)>);
impl<
T: frame_system::Config
+ pallet_xcm_weight_trader::Config
+ pallet_moonbeam_foreign_assets::Config,
NativeAsset: fungible::Mutate<T::AccountId> + fungible::Inspect<T::AccountId>,
> ConversionFromAssetBalance<Balance, NativeOrWithId<AssetId>, Balance>
for AssetRateConverter<T, NativeAsset>
{
type Error = pallet_xcm_weight_trader::Error<T>;
fn from_asset_balance(
balance: Balance,
asset_kind: NativeOrWithId<AssetId>,
) -> Result<Balance, Self::Error> {
match asset_kind {
NativeOrWithId::Native => Ok(balance),
NativeOrWithId::WithId(asset_id) => {
let location = pallet_moonbeam_foreign_assets::Pallet::<T>::convert_back(&asset_id)
.ok_or(pallet_xcm_weight_trader::Error::<T>::AssetNotFound)?;
let relative_price =
pallet_xcm_weight_trader::Pallet::<T>::get_asset_relative_price(&location)
.ok_or(pallet_xcm_weight_trader::Error::<T>::AssetNotFound)?;
Ok(balance
.checked_mul(relative_price)
.ok_or(pallet_xcm_weight_trader::Error::<T>::PriceOverflow)?
.checked_div(10u128.pow(RELATIVE_PRICE_DECIMALS))
.ok_or(pallet_xcm_weight_trader::Error::<T>::PriceOverflow)?)
}
}
}
#[cfg(feature = "runtime-benchmarks")]
fn ensure_successful(asset_id: NativeOrWithId<AssetId>) {
use frame_support::traits::OriginTrait;
use xcm::latest::{Junction::Parachain, Location};
match asset_id {
NativeOrWithId::Native => (),
NativeOrWithId::WithId(asset_id) => {
if let None = pallet_moonbeam_foreign_assets::Pallet::<T>::convert_back(&asset_id) {
let location = Location::new(1, [Parachain(1000)]);
let root = <T as frame_system::Config>::RuntimeOrigin::root();
use sp_std::vec;
pallet_moonbeam_foreign_assets::Pallet::<T>::do_create_asset(
asset_id,
location.clone(),
12,
vec![b'M', b'T'].try_into().expect("invalid ticker"),
vec![b'M', b'y', b'T', b'o', b'k']
.try_into()
.expect("invalid name"),
None,
)
.expect("Failed to create foreign asset");
pallet_xcm_weight_trader::Pallet::<T>::add_asset(root, location.clone(), 1u128)
.expect("Could not add asset");
}
}
}
}
}