Skip to content

DOT transfers using pallet-xcm's transfer_assets after AHM #9054

@mrshiposha

Description

@mrshiposha

While looking at the AHM migration guide and the corresponding tests, I didn't find a test for the case of DOT transfer between two non-reserve chains using pallet-xcm's transfer_assets extrinsic (which should deduce the reserve location automatically).

I see that the tests directly execute XCM programs. However, programs are usually created by extrinsics, such as transfer_assets.

From the current code, I conclude that after AHM, when transferring DOT from Parachain A to Parachain B using polkadotXcm.transferAssets, Parachain A won't be able to deduce the reserve location:

let transfer_type =
T::XcmExecutor::determine_for(&asset, dest).map_err(Error::<T>::from)?;

pub trait XcmAssetTransfers {
/// Combinations of (Asset, Location) pairs which we trust as reserves. Meaning
/// reserve-based-transfers are to be used for assets matching this filter.
type IsReserve: ContainsPair<Asset, Location>;
/// Combinations of (Asset, Location) pairs which we trust as teleporters. Meaning teleports are
/// to be used for assets matching this filter.
type IsTeleporter: ContainsPair<Asset, Location>;
/// How to withdraw and deposit an asset.
type AssetTransactor: TransactAsset;
/// Determine transfer type to be used for transferring `asset` from local chain to `dest`.
fn determine_for(asset: &Asset, dest: &Location) -> Result<TransferType, Error> {
if Self::IsTeleporter::contains(asset, dest) {
// we trust destination for teleporting asset
return Ok(TransferType::Teleport)
} else if Self::IsReserve::contains(asset, dest) {
// we trust destination as asset reserve location
return Ok(TransferType::DestinationReserve)
}
// try to determine reserve location based on asset id/location
let asset_location = asset.id.0.chain_location();
if asset_location == Location::here() ||
Self::IsTeleporter::contains(asset, &asset_location)
{
// if the asset is local, then it's a local reserve
// it's also a local reserve if the asset's location is not `here` but it's a location
// where it can be teleported to `here` => local reserve
Ok(TransferType::LocalReserve)
} else if Self::IsReserve::contains(asset, &asset_location) {
// remote location that is recognized as reserve location for asset
Ok(TransferType::RemoteReserve(asset_location.into()))
} else {
// remote location that is not configured either as teleporter or reserve => cannot
// determine asset reserve
Err(Error::UnknownReserve)
}
}
}

Do we have a test for that?

If the problem does exist, a possible solution would be to have a ReserveProvider associated type in the XcmAssetTransfers trait, similar to the ORML pallet-xtokens:
https://github.com/open-web3-stack/open-runtime-module-library/blob/2fd6442fc9b03717e491e82b9d8754a863e41c9a/xtokens/src/lib.rs#L130-L132

CC @acatangiu @franciscoaguirre @xlc

Metadata

Metadata

Assignees

No one assigned

    Labels

    T6-XCMThis PR/Issue is related to XCM.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions