open-runtime-module-library icon indicating copy to clipboard operation
open-runtime-module-library copied to clipboard

How to adapt `Currencies` to `NamedReservableCurrency` / `CurrrencyAdapter` doesn't work with the native currency

Open maltekliemann opened this issue 2 years ago • 3 comments

I'm using orml_currencies to handle multiple currencies alongside a native currency, and I'm trying to call NamedReservableCurrency::slash_reserved_named on the native currency (so that I get the negative imbalance caused by the slash).

When using a non-native currency, I could use orml_tokens::CurrencyAdapter<Runtime, GetTokenId>, but using that with the native currency won't work because CurrencyAdapter delegates the calls to tokens::Pallet, rather than currencies::Pallet.

So i have a couple of questions:

  • Is there a canonical approach to doing this?
  • More specifically, can we have a CurrencyAdapter for orml_currencies?
  • And just for my own edification, why does orml_currencies gobble up the imbalances in the first place?

maltekliemann avatar Sep 29 '22 11:09 maltekliemann

We usually just pass Balances for native token but there isn't a lot of reason why we can't implement CurrencyAdapter for orml_currencies. It is just that no one requested it yet until now.

Imbalance is a useful thing but just doesn't work nicely when dealing with multiple assets so we want to avoid using it. Of course if you can find a nice way to implement it, that will be lovely.

xlc avatar Sep 29 '22 22:09 xlc

Thanks for the quick reply! I'll see if I find the time to implement CurrencyAdapter for orml_currencies some time soon.

Just one question: You say that immbalances don't work nicely when dealing with multiple assets. What do you mean exactly?

maltekliemann avatar Sep 30 '22 11:09 maltekliemann

Let's have some examples

let a: PositiveImbalance<???> = MultiCurrency::withdraw(CurrencyId:TokenA, Alice, 1000)
let b: PositiveImbalance <???> = MultiCurrency::withdraw(CurrencyId:TokenB, Alice, 1000)

a and b are imbalance for two different tokens, therefore ideally they should be different type. However they have to be the same type with above code.

So the API will need to be something like

let a: PositiveImbalance<TokenA> = MultiCurrency::<TokenA>::withdraw(Alice, 1000)
let b: PositiveImbalance<TokenB> = MultiCurrency::<TokenB>::withdraw(Alice, 1000)

But you won't be able to use to above API to implement something like

fn transfer(from: AccountId, to: AccountId, currencyId: CurrencyId) {
  let a: PositiveImbalance<???> = MultiCurrency::<???>::withdraw(Alice, 1000)
}

xlc avatar Oct 01 '22 00:10 xlc