mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 21:01:02 +00:00
implement ConversionToAssetBalance in asset-rate (#2903)
Implements the `ConversionToAssetBalance` trait to asset-rate by doing `1/rate*(balance)`.
This commit is contained in:
@@ -0,0 +1,15 @@
|
|||||||
|
# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
|
||||||
|
# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
|
||||||
|
|
||||||
|
title: "Implement `ConversionToAssetBalance` in asset-rate"
|
||||||
|
|
||||||
|
doc:
|
||||||
|
- audience: Runtime Dev
|
||||||
|
description: |
|
||||||
|
Implements the `ConversionToAssetBalance` trait to the asset-rate pallet.
|
||||||
|
|
||||||
|
Previously only the `ConversionFromAssetBalance` trait was implemented, which would allow to convert an asset balance into the corresponding native balance.
|
||||||
|
|
||||||
|
The `ConversionToAssetBalance` allows to use pallet-asset-rate, e.g., as a mechanism to charge XCM fees in an asset that is not the native.
|
||||||
|
crates: [ ]
|
||||||
|
|
||||||
@@ -59,8 +59,14 @@
|
|||||||
|
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
use frame_support::traits::{fungible::Inspect, tokens::ConversionFromAssetBalance};
|
use frame_support::traits::{
|
||||||
use sp_runtime::{traits::Zero, FixedPointNumber, FixedU128};
|
fungible::Inspect,
|
||||||
|
tokens::{ConversionFromAssetBalance, ConversionToAssetBalance},
|
||||||
|
};
|
||||||
|
use sp_runtime::{
|
||||||
|
traits::{CheckedDiv, Zero},
|
||||||
|
FixedPointNumber, FixedU128,
|
||||||
|
};
|
||||||
use sp_std::boxed::Box;
|
use sp_std::boxed::Box;
|
||||||
|
|
||||||
pub use pallet::*;
|
pub use pallet::*;
|
||||||
@@ -144,6 +150,8 @@ pub mod pallet {
|
|||||||
UnknownAssetKind,
|
UnknownAssetKind,
|
||||||
/// The given asset ID already has an assigned conversion rate and cannot be re-created.
|
/// The given asset ID already has an assigned conversion rate and cannot be re-created.
|
||||||
AlreadyExists,
|
AlreadyExists,
|
||||||
|
/// Overflow ocurred when calculating the inverse rate.
|
||||||
|
Overflow,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pallet::call]
|
#[pallet::call]
|
||||||
@@ -246,3 +254,25 @@ where
|
|||||||
pallet::ConversionRateToNative::<T>::set(asset_id.clone(), Some(1.into()));
|
pallet::ConversionRateToNative::<T>::set(asset_id.clone(), Some(1.into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Exposes conversion of a native balance to an asset balance.
|
||||||
|
impl<T> ConversionToAssetBalance<BalanceOf<T>, AssetKindOf<T>, BalanceOf<T>> for Pallet<T>
|
||||||
|
where
|
||||||
|
T: Config,
|
||||||
|
{
|
||||||
|
type Error = pallet::Error<T>;
|
||||||
|
|
||||||
|
fn to_asset_balance(
|
||||||
|
balance: BalanceOf<T>,
|
||||||
|
asset_kind: AssetKindOf<T>,
|
||||||
|
) -> Result<BalanceOf<T>, pallet::Error<T>> {
|
||||||
|
let rate = pallet::ConversionRateToNative::<T>::get(asset_kind)
|
||||||
|
.ok_or(pallet::Error::<T>::UnknownAssetKind.into())?;
|
||||||
|
|
||||||
|
// We cannot use `saturating_div` here so we use `checked_div`.
|
||||||
|
Ok(FixedU128::from_u32(1)
|
||||||
|
.checked_div(&rate)
|
||||||
|
.ok_or(pallet::Error::<T>::Overflow.into())?
|
||||||
|
.saturating_mul_int(balance))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -131,12 +131,19 @@ fn convert_works() {
|
|||||||
FixedU128::from_float(2.51)
|
FixedU128::from_float(2.51)
|
||||||
));
|
));
|
||||||
|
|
||||||
let conversion = <AssetRate as ConversionFromAssetBalance<
|
let conversion_from_asset = <AssetRate as ConversionFromAssetBalance<
|
||||||
BalanceOf<Test>,
|
BalanceOf<Test>,
|
||||||
<Test as pallet_asset_rate::Config>::AssetKind,
|
<Test as pallet_asset_rate::Config>::AssetKind,
|
||||||
BalanceOf<Test>,
|
BalanceOf<Test>,
|
||||||
>>::from_asset_balance(10, ASSET_ID);
|
>>::from_asset_balance(10, ASSET_ID);
|
||||||
assert_eq!(conversion.expect("Conversion rate exists for asset"), 25);
|
assert_eq!(conversion_from_asset.expect("Conversion rate exists for asset"), 25);
|
||||||
|
|
||||||
|
let conversion_to_asset = <AssetRate as ConversionToAssetBalance<
|
||||||
|
BalanceOf<Test>,
|
||||||
|
<Test as pallet_asset_rate::Config>::AssetKind,
|
||||||
|
BalanceOf<Test>,
|
||||||
|
>>::to_asset_balance(25, ASSET_ID);
|
||||||
|
assert_eq!(conversion_to_asset.expect("Conversion rate exists for asset"), 9);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,3 +158,21 @@ fn convert_unknown_throws() {
|
|||||||
assert!(conversion.is_err());
|
assert!(conversion.is_err());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn convert_overflow_throws() {
|
||||||
|
new_test_ext().execute_with(|| {
|
||||||
|
assert_ok!(AssetRate::create(
|
||||||
|
RuntimeOrigin::root(),
|
||||||
|
Box::new(ASSET_ID),
|
||||||
|
FixedU128::from_u32(0)
|
||||||
|
));
|
||||||
|
|
||||||
|
let conversion = <AssetRate as ConversionToAssetBalance<
|
||||||
|
BalanceOf<Test>,
|
||||||
|
<Test as pallet_asset_rate::Config>::AssetKind,
|
||||||
|
BalanceOf<Test>,
|
||||||
|
>>::to_asset_balance(10, ASSET_ID);
|
||||||
|
assert!(conversion.is_err());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user