Skip to content

Commit

Permalink
implement ConversionToAssetBalance in asset-rate (paritytech#2903)
Browse files Browse the repository at this point in the history
Implements the `ConversionToAssetBalance` trait to asset-rate by doing
`1/rate*(balance)`.
  • Loading branch information
girazoki authored Feb 20, 2024
1 parent 5987222 commit d65c8c4
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 4 deletions.
34 changes: 32 additions & 2 deletions substrate/frame/asset-rate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,14 @@
#![cfg_attr(not(feature = "std"), no_std)]

use frame_support::traits::{fungible::Inspect, tokens::ConversionFromAssetBalance};
use sp_runtime::{traits::Zero, FixedPointNumber, FixedU128};
use frame_support::traits::{
fungible::Inspect,
tokens::{ConversionFromAssetBalance, ConversionToAssetBalance},
};
use sp_runtime::{
traits::{CheckedDiv, Zero},
FixedPointNumber, FixedU128,
};
use sp_std::boxed::Box;

pub use pallet::*;
Expand Down Expand Up @@ -144,6 +150,8 @@ pub mod pallet {
UnknownAssetKind,
/// The given asset ID already has an assigned conversion rate and cannot be re-created.
AlreadyExists,
/// Overflow ocurred when calculating the inverse rate.
Overflow,
}

#[pallet::call]
Expand Down Expand Up @@ -246,3 +254,25 @@ where
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))
}
}
29 changes: 27 additions & 2 deletions substrate/frame/asset-rate/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,19 @@ fn convert_works() {
FixedU128::from_float(2.51)
));

let conversion = <AssetRate as ConversionFromAssetBalance<
let conversion_from_asset = <AssetRate as ConversionFromAssetBalance<
BalanceOf<Test>,
<Test as pallet_asset_rate::Config>::AssetKind,
BalanceOf<Test>,
>>::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);
});
}

Expand All @@ -151,3 +158,21 @@ fn convert_unknown_throws() {
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());
});
}

0 comments on commit d65c8c4

Please sign in to comment.