open-runtime-module-library
open-runtime-module-library copied to clipboard
How to adapt `Currencies` to `NamedReservableCurrency` / `CurrrencyAdapter` doesn't work with the native currency
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
fororml_currencies
? - And just for my own edification, why does
orml_currencies
gobble up the imbalances in the first place?
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.
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?
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)
}