-
Notifications
You must be signed in to change notification settings - Fork 296
Description
current, we have multi assets support, and use fee_item asset as reserve
| let (transfer_kind, dest, reserve, recipient) = Self::transfer_kind(&fee, &dest)?; |
i.e. if currencies=vec![(CurrencyId::R, 100), (CurrencyId::B, 450)], and fee_item=0, reserve=Parent, because fee asset is R, then xcm sent to Relaychain likes:
origin: MultiLocation { parents: 0, interior: X1(Parachain(1)) },
message: Xcm([
WithdrawAsset(MultiAssets([
MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: Here }), fun: Fungible(100) },
MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X2(Parachain(2), GeneralKey([66])) }), fun: Fungible(450) }])), // 🔥
ClearOrigin,
BuyExecution { fees: MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: Here }), fun: Fungible(50) }, weight_limit: Limited(40) },
DepositReserveAsset {
assets: Wild(All), max_assets: 2,
dest: MultiLocation { parents: 0, interior: X1(Parachain(2)) },
xcm: Xcm([
BuyExecution { fees: MultiAsset { id: Concrete(MultiLocation { parents: 1, interior: Here }), fun: Fungible(50) }, weight_limit: Limited(40) },
DepositAsset { assets: Wild(All), max_assets: 2, beneficiary: MultiLocation { parents: 0, interior: X1(AccountId32 { network: Any, id: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] }) } }]) }
]), weight_limit: 18446744073709551615, weight_credit: 0
this will error when execute second WithdrawAsset because relaychain doesn't have (0, Parachain(2), GeneralKey(B)) asset.
if currencies=vec![(CurrencyId::R, 100), (CurrencyId::B, 450)], and fee_item=1, reserve=(1,Parachain(2)), because fee asset is B, then xcm send to Sibling Parachain(2) likes:
origin: MultiLocation { parents: 0, interior: X1(Parachain(1)) },
message: Xcm([
WithdrawAsset(MultiAssets([
MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X1(GeneralKey([66])) }), fun: Fungible(450) }, // sibling_a_account should have enougn B token
MultiAsset { id: Concrete(MultiLocation { parents: 1, interior: Here }), fun: Fungible(100) }])), // sibling_a_account also should have enough R token
ClearOrigin,
BuyExecution {
fees: MultiAsset {
id: Concrete(MultiLocation { parents: 0, interior: X1(GeneralKey([66])) }), fun: Fungible(450) // ⬅️
}, weight_limit: Limited(40) },
DepositAsset {
assets: Wild(All), max_assets: 2,
beneficiary: MultiLocation { parents: 0, interior: X1(AccountId32 { network: Any, id: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] }) }
}
]), weight_limit: 6148914691236517205, weight_credit: 0
this can sucess if we open gate here(if not, there'll be DistinctReserveForAssetAndFee error):
open-runtime-module-library/xtokens/src/lib.rs
Lines 584 to 587 in 4a66b29
| ensure!( | |
| fee.reserve() == asset.reserve(), | |
| Error::<T>::DistinctReserveForAssetAndFee | |
| ); |
and the xcm above use (0, GeneralKey(B)) as fee, although this is what the fee_item exactly wanted.
but in some cases we want use sibling parachain as reserve chain, and also use relaychain asset as fee.
i.e. transfer RMRK from Karura to Statemine, we use KSM as fee. the xcm on recipient parachain should be like:
message: Xcm([
WithdrawAsset(MultiAssets([
MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X1(GeneralKey([66])) }), fun: Fungible(450) }, // sibling_a_account should have enougn B token
MultiAsset { id: Concrete(MultiLocation { parents: 1, interior: Here }), fun: Fungible(100) }])), // sibling_a_account also should have enough R token
ClearOrigin,
BuyExecution {
fees: MultiAsset {
id: Concrete(MultiLocation { parents: 1, interior: Here }), fun: Fungible(50) // ⬅️
}, weight_limit: Limited(40) },
DepositAsset {
assets: Wild(All), max_assets: 2,
beneficiary: MultiLocation { parents: 0, interior: X1(AccountId32 { network: Any, id: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] }) }
}
])
PS: in the case of transfer RMRK from Karura to Statemine, if we transfer only RMRK, in the Statemine side, as trader not matched, xcm executed in Statemine will failed, and throw TooExpsensive error. so we must use KSM as fee, because Statemine only support KSM as fee for now.