1

I would like to divide a Balance into two parts. One is 10% of value and another part is 90% of the value. BalanceOf<T> is the Balance of a pallet.

    type Balance: AtLeast32BitUnsigned
        + FullCodec
        + Copy
        + MaybeSerializeDeserialize
        + Debug
        + Default
        + scale_info::TypeInfo
        + MaxEncodedLen;
let value: BalanceOf<T> = some_balance;
let deposit: BalanceOf<T> = 0.1 * value;
let actual: BalanceOf<T> = value - deposit;

The error message is the following.

cannot multiply `{float}` by `<<T as pallet::Config>::Currencies as orml_traits::MultiCurrency<<T as frame_system::Config>::AccountId>>::Balance`
the trait `Mul<<<T as pallet::Config>::Currencies as orml_traits::MultiCurrency<<T as frame_system::Config>::AccountId>>::Balance>` is not implemented for `{float}`

Another approach is to use sp_runtime::traits::CheckedDiv

let value: BalanceOf<T> = some_balance;
let deposit = value
    .checked_div(&10u128.into())
    .ok_or(DispatchError::Other("Arithmetic error"))?;
let actual = value - deposit;

There I get this error.

the trait `From<u128>` is not implemented for `<<T as pallet::Config>::Currencies as orml_traits::MultiCurrency<<T as frame_system::Config>::AccountId>>::Balance`

What is the best possible way to approach this safely?

1 Answer 1

3

There is actually a function as part of the Imbalance trait to handle exactly this: ration.

You can see an example of its use to split transaction fees between the Treasury and block author in Polkadot.


EDIT: Update to do without an Imbalance.

There is a better pattern to use if you're not dealing with an imbalance (e.g. a transaction fee that's already been deducted from an account). It is from_percent.

This should work (including the option to make it configurable):

use sp_runtime::Percent;

pub type BalanceOf<T> = 
  <<T as Config<I>>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;

#[frame_support::pallet]
pub mod pallet {

    #[pallet::config]
    pub trait Config: frame_system::Config {

        // Only needed if you want it configurable:
        #[pallet::constant]
        type DepositFee: Get<Percent>;
    }
}

impl<T: Config> Pallet<T> {
  fn my_function(value: BalanceOf<T>) {
    // To hard code in a value, you can just use `Percent` directly:
    let deposit = Percent::from_percent(10) * value;

    // If you want it configurable, you can just `Get` the percentage from the config:
    let deposit = T::DepositFee::get() * value;

    let actual = value - deposit;

    /* do your thing... */
  }
}

Then, if configurable, you would configure your runtime like:

parameter_types! {
    pub const DepositFee: Percent = Percent::from_percent(10);
}

impl my_pallet::Config for Runtime {
    type DepositFee = DepositFee;
}
2
  • That fits my question really well. Thank you for that. How could I create an imbalance out of a balance?
    – Chralt
    May 22 at 18:08
  • Doh, read it too fast. Updated for when just dealing with balances. May 23 at 5:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.