0

I have currency configuration as follows

use frame_support::traits::{Currency};

and in frame config

type Currency: Currency<Self::AccountId>;

Then in an extrincis function, I am trying to do a transfer

<T as Config>::Currency::transfer(
                &who,
                &validators_account,
                transaction_fee,
                ExistenceRequirement::KeepAlive
)?;

This throws an error

     --> /home/dev/Desktop/projects/GIANT/pallets/provider/src/lib.rs:281:5
      |
  278 |             <T as Config>::Currency::transfer(
      |             --------------------------------- arguments to this function are incorrect
  ...
  281 |                 transaction_fee,
      |                 ^^^^^^^^^^^^^^^ expected associated type, found `u128`
      |
      = note: expected associated type `<<T as pallet::Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance`
                            found type `u128`

But when I explore tests for transfer function in the substrate it uses integer values

                assert_noop!(
                    <Balances as Currency<_>>::transfer(&1, &2, 3, AllowDeath),
                    Error::<$test, _>::LiquidityRestrictions
                );

This throws an error as well

            <T as Config>::Currency::transfer(
                &who,
                &validators_account,
                100,
                ExistenceRequirement::KeepAlive
            )?;

Error

            <T as Config>::Currency::transfer(
      |             --------------------------------- arguments to this function are incorrect
  ...
  281 |                 100,
      |                 ^^^ expected associated type, found integer
      |

How to fix this issue?

1 Answer 1

1

As the error is noting, the it expects an associated type Balance, not a concrete type.

While your runtime may use the u128 type, your pallet does not know that, and instead uses a generic type which you must take into account.

The easiest thing would be to use sp_runtime::traits::UniqueSaturatedInto;, then add .unique_saturated_into() to your value.

/// Just like `From` except that if the source value is too big to fit into the destination type
/// then it'll saturate the destination.
pub trait UniqueSaturatedFrom<T: Sized>: Sized {
    /// Convert from a value of `T` into an equivalent instance of `Self`.
    fn unique_saturated_from(t: T) -> Self;
}

So something like this compiles:

use sp_runtime::traits::UniqueSaturatedInto;
let source = T::Lookup::lookup(source)?;
let dest = T::Lookup::lookup(dest)?;
<Self as Currency<_>>::transfer(
    &source,
    &dest,
    100u128.unique_saturated_into(),
    ExistenceRequirement::AllowDeath,
)?;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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