moonbeam_runtime_common/
impl_asset_conversion.rs1use core::marker::PhantomData;
18
19use frame_support::traits::{
20 fungible::{self, NativeOrWithId},
21 tokens::ConversionFromAssetBalance,
22};
23use moonbeam_core_primitives::{AssetId, Balance};
24use pallet_xcm_weight_trader::RELATIVE_PRICE_DECIMALS;
25use sp_runtime::traits::MaybeEquivalence;
26
27pub struct AssetRateConverter<T, NativeAsset>(PhantomData<(T, NativeAsset)>);
28impl<
29 T: frame_system::Config
30 + pallet_xcm_weight_trader::Config
31 + pallet_moonbeam_foreign_assets::Config,
32 NativeAsset: fungible::Mutate<T::AccountId> + fungible::Inspect<T::AccountId>,
33 > ConversionFromAssetBalance<Balance, NativeOrWithId<AssetId>, Balance>
34 for AssetRateConverter<T, NativeAsset>
35{
36 type Error = pallet_xcm_weight_trader::Error<T>;
37
38 fn from_asset_balance(
39 balance: Balance,
40 asset_kind: NativeOrWithId<AssetId>,
41 ) -> Result<Balance, Self::Error> {
42 match asset_kind {
43 NativeOrWithId::Native => Ok(balance),
44 NativeOrWithId::WithId(asset_id) => {
45 let location = pallet_moonbeam_foreign_assets::Pallet::<T>::convert_back(&asset_id)
46 .ok_or(pallet_xcm_weight_trader::Error::<T>::AssetNotFound)?;
47 let relative_price =
48 pallet_xcm_weight_trader::Pallet::<T>::get_asset_relative_price(&location)
49 .ok_or(pallet_xcm_weight_trader::Error::<T>::AssetNotFound)?;
50 Ok(balance
51 .checked_mul(relative_price)
52 .ok_or(pallet_xcm_weight_trader::Error::<T>::PriceOverflow)?
53 .checked_div(10u128.pow(RELATIVE_PRICE_DECIMALS))
54 .ok_or(pallet_xcm_weight_trader::Error::<T>::PriceOverflow)?)
55 }
56 }
57 }
58
59 #[cfg(feature = "runtime-benchmarks")]
61 fn ensure_successful(asset_id: NativeOrWithId<AssetId>) {
62 use frame_support::traits::OriginTrait;
63 use xcm::latest::{Junction::Parachain, Location};
64 match asset_id {
65 NativeOrWithId::Native => (),
66 NativeOrWithId::WithId(asset_id) => {
67 if let None = pallet_moonbeam_foreign_assets::Pallet::<T>::convert_back(&asset_id) {
68 let location = Location::new(1, [Parachain(1000)]);
69 let root = <T as frame_system::Config>::RuntimeOrigin::root();
70
71 use sp_std::vec;
72 pallet_moonbeam_foreign_assets::Pallet::<T>::do_create_asset(
73 asset_id,
74 location.clone(),
75 12,
76 vec![b'M', b'T'].try_into().expect("invalid ticker"),
77 vec![b'M', b'y', b'T', b'o', b'k']
78 .try_into()
79 .expect("invalid name"),
80 None,
81 )
82 .expect("Failed to create foreign asset");
83
84 pallet_xcm_weight_trader::Pallet::<T>::add_asset(root, location.clone(), 1u128)
85 .expect("Could not add asset");
86 }
87 }
88 }
89 }
90}