Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce new XCM instruction: InitiateAssetsTransfer for complex asset transfers #100

Conversation

acatangiu
Copy link
Contributor

This is a continuation of polkadot-fellows/xcm-format#63 following the migration of XCM RFCs to this repo.

Summary

This RFC proposes a new instruction that provides a way to initiate asset transfers which transfer multiple types (teleports, local-reserve, destination-reserve) of assets, on remote chains using XCM alone.

The currently existing instructions are too opinionated and force each XCM asset transfer to a single transfer type (teleport, local-reserve, destination-reserve). This results in inability to combine different types of transfers in single transfer which results in overall poor UX when trying to move assets across chains.

Example usage

    // pay remote fees with ROCs
    let remote_fees = Some(
        AssetTransferFilter::ReserveWithdraw(
            AssetFilter::Wild(AllOf { id: rocs_id.into(), fun: WildFungibility::Fungible })
        )
    );
    // XCM to be executed locally
    let xcm = Xcm::<penpal_runtime::RuntimeCall>(vec![
        // Withdraw both ROCs and PENs from origin account
        WithdrawAsset(assets.clone().into()),
        // Execute the transfers while paying remote fees with ROCs
        InitiateAssetsTransfer {
            dest: local_asset_hub,
            assets: vec![
                // ROCs are reserve-withdrawn on AHR
                ReserveWithdraw(rocs.into()),
                // PENs are teleported to AHR
                Teleport(pens.into()),
            ],
            remote_fees,
            remote_xcm: xcm_on_ahr,
        },
    ]);

I also have a proof-of-concept implementation and a proof-of-concept asset transfer test, transferring 2 different types of assets across 3 chains.

…sset transfers

This RFC proposes a new instruction that provides a way to initiate asset transfers which transfer multiple
types (teleports, local-reserve, destination-reserve) of assets, on remote chains using XCM alone.

The currently existing instructions are too opinionated and force each XCM asset transfer to a single
transfer type (teleport, local-reserve, destination-reserve). This results in inability to combine different
types of transfers in single transfer which results in overall poor UX when trying to move assets across
chains.

```rust
    // pay remote fees with ROCs
    let remote_fees = Some(
        AssetTransferFilter::ReserveWithdraw(
            AssetFilter::Wild(AllOf { id: rocs_id.into(), fun: WildFungibility::Fungible })
        )
    );
    // XCM to be executed locally
    let xcm = Xcm::<penpal_runtime::RuntimeCall>(vec![
        // Withdraw both ROCs and PENs from origin account
        WithdrawAsset(assets.clone().into()),
        // Execute the transfers while paying remote fees with ROCs
        InitiateAssetsTransfer {
            dest: local_asset_hub,
            assets: vec![
                // ROCs are reserve-withdrawn on AHR
                ReserveWithdraw(rocs.into()),
                // PENs are teleported to AHR
                Teleport(pens.into()),
            ],
            remote_fees,
            remote_xcm: xcm_on_ahr,
        },
    ]);
```

I also have a [proof-of-concept implementation](https://github.com/acatangiu/polkadot-sdk/blob/1738f8eebd33d87c9c09c7a6bcd7c42fc1a8aa9e/polkadot/xcm/xcm-executor/src/lib.rs#L717C4-L831C6) and a [proof-of-concept asset transfer test](https://github.com/acatangiu/polkadot-sdk/blob/1738f8eebd33d87c9c09c7a6bcd7c42fc1a8aa9e/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs#L484C1-L489C60), transferring 2 different types of assets across 3 chains.
@acatangiu acatangiu force-pushed the xcm-multi-type-asset-transfer branch from 55d1fe7 to 1b39952 Compare July 30, 2024 11:25
@xlc
Copy link
Contributor

xlc commented Jul 31, 2024

not sure if I missed something but what about the order of the asset deposit?
e.g. transfer from Acala to AH, of 50 DOT and 10 USDT. it will result one UMP and one HRMP at Acala. On AH, it will receive one DMP and one HRMP. how exactly is this case handled?

@acatangiu
Copy link
Contributor Author

not sure if I missed something but what about the order of the asset deposit? e.g. transfer from Acala to AH, of 50 DOT and 10 USDT. it will result one UMP and one HRMP at Acala. On AH, it will receive one DMP and one HRMP. how exactly is this case handled?

This new instruction is point-to-point (same as the rest). It can be used by higher layers that build cross chain xcm programs to move assets across multiple hops by calling it at every hop along the way. But the required/used path is outside the scope of concerns of the XCVM. It only executes this instr which explicitly specifies the dest (next hop).

Transferring assets that require different paths is still not supported within same XCM because of the async nature of cross chain messages..

I will include some of this information in the RFC for clarity.

@franciscoaguirre
Copy link
Contributor

not sure if I missed something but what about the order of the asset deposit? e.g. transfer from Acala to AH, of 50 DOT and 10 USDT. it will result one UMP and one HRMP at Acala. On AH, it will receive one DMP and one HRMP. how exactly is this case handled?

If AH is used as a reserve then this would just be one HRMP and it'd be possible, no?

Copy link

@vgeddes vgeddes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The design looks good. I've confirmed in https://hackmd.io/@vgeddes/rkeSGIAYR that InitiateAssetsTransfer unlocks new potential for Snowbridge, mainly in improving UX.

@acatangiu
Copy link
Contributor Author

/rfc propose

@paritytech-rfc-bot
Copy link
Contributor

Hey @acatangiu, here is a link you can use to create the referendum aiming to approve this RFC number 0100.

Instructions
  1. Open the link.

  2. Switch to the Submission tab.

  1. Adjust the transaction if needed (for example, the proposal Origin).

  2. Submit the Transaction


It is based on commit hash dc585343d23aa7685cce08f3d939829fb803703e.

The proposed remark text is: RFC_APPROVE(0100,86bf80319a20a97813c131ae3105074a228250077d6545f5f51812d61dbcab79).

Copy link

PR can be merged.

Write the following command to trigger the bot

/rfc process 0xfdf10d88746da6af4245b60405acbd49fbee059d109185b97c7b5fd8541b17c4

@acatangiu
Copy link
Contributor Author

/rfc process 0xfdf10d88746da6af4245b60405acbd49fbee059d109185b97c7b5fd8541b17c4

@paritytech-rfc-bot paritytech-rfc-bot bot merged commit 89a79fc into polkadot-fellows:main Aug 26, 2024
@paritytech-rfc-bot
Copy link
Contributor

The on-chain referendum has approved the RFC.

@anaelleltd anaelleltd added the Approved Has passed on-chain voting. label Sep 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Approved Has passed on-chain voting.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants