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

Asset transfers can alias XCM origin on destination to original origin #122

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 148 additions & 0 deletions text/0122-alias-origin-on-asset-transfers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# RFC-0122: Asset transfers can alias XCM origin on destination to original origin

| | |
| --------------- | ------------------------------------------------------------------------------------------- |
| **Start Date** | 01 Sep 2024. |
| **Description** | Single and Multi-hop asset transfers should be able to carry over original origin |
| **Authors** | Adrian Catangiu |

## Summary

XCM programs generated by the `InitiateAssetTransfer` instruction shall have the option to carry over the original origin all the way to the final destination. They shall do so by internally making use of `AliasOrigin` or `ClearOrigin` depending on given parameters.

This allows asset transfers to retain their original origin even across multiple hops.

Ecosystem chains would have to change their trusted aliasing rules to effectively make use of this feature.

## Motivation

Currently, all XCM asset transfer instructions ultimately clear the origin in the remote XCM message by use of the `ClearOrigin` instruction. This is done for security considerations to ensure that subsequent (user-controlled) instructions cannot command the authority of the sending chain.

The problem with this approach is that it limits what can be achieved on remote chains through XCM. Most XCM operations require having an origin, and following any asset transfer the origin is lost, meaning not much can be done other than depositing the transferred assets to some local account or transferring them onward to another chain.

For example, we cannot transfer some funds for buying execution, then do a `Transact` (all in the same XCM message).

The above example is a basic, core building block for cross-chain interactions and we should support it.

Transact XCM programs today require a two step process:

<img src="https://raw.githubusercontent.com/acatangiu/RFCs/alias-origin-on-asset-transfers/text/0122-transact-today.png" alt="Transact Today">

And we want to be able to do it using a single XCM program.

## Stakeholders

Runtime Users, Runtime Devs, wallets, cross-chain dApps.

## Explanation

In the case of XCM programs going from `source-chain` directly to `dest-chain` without an intermediary hop, we can enable scenarios such as above by using the `AliasOrigin` instruction instead of the `ClearOrigin` instruction.

Instead of clearing the `source-chain` origin, the destination chain shall attempt to alias `source-chain` to "original origin" on the source chain.
Most common such origin aliasing would be `X1(Parachain(source-chain))` -> `X2(Parachain(source-chain), AccountId32(origin-account))` for the case of a single hop transfer where the initiator is a (signed/pure/proxy) account `origin-account` on `source-chain`.
acatangiu marked this conversation as resolved.
Show resolved Hide resolved

This allows an actor on chain A to `Transact` on chain B without having to prefund its SA account on chain B, instead they can simply transfer the required fees in the same XCM program as the `Transact`.

As long as the asset transfer has the same XCM route/hops as the rest of the program, this pattern of usage can be composed across multiple hops, to ultimately `Transact` on the final hop using the original origin on the source chain, effectively abstracting away any intermediary hops.

### Trust assumptions

The model described above makes some aliasing trust assumptions, the most important being how _the root location of the intermediate hop/chain has to be trusted to alias ("impersonate") other locations from the source chain_.

The origin aliasing trust relationship is highly customizeable at the runtime level, so that parachains can define coarse filters or granular pairs of (source, target) locations aliasing.

Even so, this RFC aims to also propose a standard set of aliasing rules that all Parachains can integrate for allowing the vast majority of `Transact` usecases in a "one-click" manner (single XCM), without practically lowering their security posture.
acatangiu marked this conversation as resolved.
Show resolved Hide resolved

#### Standard Aliasing Rules:

1. Any chain allows aliasing into a child location. Equivalent to DescendOrigin into an interior location.
2. Parachains allow Asset Hub root location to alias into any other origin.

Now, the second rule as defined above in its most generic form might seem "dangerous" at first, but in practical terms if Asset Hub Root gets compromised and can access arbitrary sovereign accounts on Asset Hub and/or send arbitrary XCMs, the blast radius and potential damage to other parachains are not relevantly impacted by this aliasing rule.

This second rule can also be tightened by each parachain to their own liking, for example limit Asset Hub aliasing to a stricter range of locations:
- "allow Asset Hub root to alias Ethereum locations" - which enables support for `Transact` over the Ethereum Snowbridge (but doesn't support sibling parachain to Transact through Asset Hub)

### XCM `InitiateAssetsTransfer` instruction changes

A new parameter `preserve_origin` to be added to the `InitiateAssetsTransfer` XCM instruction that specifies if the original origin should be preserved or cleared.

```diff
InitiateAssetsTransfer {
destination: Location,
assets: Vec<AssetTransferFilter>,
remote_fees: Option<AssetTransferFilter>,
+ preserve_origin: bool,
remote_xcm: Xcm<()>,
}
```

This parameter is explicitly necessary because the instruction should be usable between any two chains regardless of their origin-aliasing trust relationship. Preserving the origin requires some level of trust, while clearing it works regardless of that relationship.
Specifying `preserve_origin: false` will always work regardless of the configured alias filters of the
involved chains.

### Example scenarios

Transact within the ecosytem:
- between two chains using an asset native to either one of them for paying for Transact,
- between two chains using an Asset Hub asset (e.g. USDT) for paying for Transact,

<img src="https://raw.githubusercontent.com/acatangiu/RFCs/alias-origin-on-asset-transfers/text/0122-transact-single-xcm.png" alt="Ecosystem Transact">

Transact over Snowbridge (same for other bridges):
- user on Ethereum calls function in Parachain A on Polkadot, pays with ETH,
- user on ParaA on Polkdaot calls function on Ethereum, pays with ETH,

<img src="https://raw.githubusercontent.com/acatangiu/RFCs/alias-origin-on-asset-transfers/text/0122-transact-over-bridge.png" alt="Transact Over Bridge">

## Drawbacks

In terms of ergonomics and user experience, this support for combining an asset transfer with a subsequent action (like Transact) is a net possitive.
acatangiu marked this conversation as resolved.
Show resolved Hide resolved

In terms off performance, and privacy, this is neutral with no changes.
acatangiu marked this conversation as resolved.
Show resolved Hide resolved

In terms of security, the feature by itself is also neutral because it allows `preserve_origin: false` usage for operating with no extra trust assumptions. When wanting to support preserving origin, chains need to configure secure origin aliasing filters. The "standard" one provided in this RFC will be the right choice for the majority of chains, but for others it will not be depending on their business model and logic (e.g. chain does not plan to integrate with Asset Hub). It is up to the individual chains to configure accordingly.

## Testing, Security, and Privacy

Barriers should now allow `AliasOrigin` or `ClearOrigin`.

Normally, XCM program builders should audit their programs and eliminate assumptions of "no origin" on remote side of this instruction. In this case, the `InitiateAssetsTransfer` has not been released yet, it will be part of XCMv5, and we can make this change part of the same XCMv5 so that there isn't even the possibility of someone in the wild having built XCM programs using this instruction on those wrong assumptions.

The working assumption going forward is that the origin on the remote side can either be cleared or it can be the local origin's reanchored location. This assumption is in line with the current behavior of remote XCM programs sent over using `pallet_xcm::send`.

The existing `DepositReserveAsset`, `InitiateReserveWithdraw` and `InitiateTeleport` cross chain asset transfer instructions will not attempt to do origin aliasing and will always clear origin same as before for compatibility reasons.

## Performance, Ergonomics, and Compatibility

### Performance

No impact.

### Ergonomics

Improves ergonomics by allowing the local origin to operate on the remote chain even when the XCM program includes an asset transfer.

### Compatibility

At the executor-level this change is backwards and forwards compatible. Both types of programs can be executed on new and old versions of XCM with no changes in behavior.

New version of the `InitiateAssetsTransfer` instruction acts same as before when used with `preserve_origin: false`.

For using the new capabilities, the XCM builder has to verify that the involved chains have the required origin-aliasing filters configured and use some new version of Barriers aware of `AliasOrigin` as an allowed alternative to `ClearOrigin`.

For compatibility reasons, this RFC proposes this mechanism be added as an enhancement to the yet unreleased `InitiateAssetsTransfer` instruction, thus eliminating possibilities of XCM logic breakages in the wild.
Following the same logic, the existing `DepositReserveAsset`, `InitiateReserveWithdraw` and `InitiateTeleport` cross chain asset transfer instructions will not attempt to do origin aliasing and will always clear the origin same as before for compatibility reasons.

Any one of `DepositReserveAsset`, `InitiateReserveWithdraw` and `InitiateTeleport` instructions can be replaced with a `InitiateAssetsTransfer` instruction with or without origin aliasing, thus providing a clean and clear upgrade path for opting-in this new feature.

## Prior Art and References

- [RFC: InitiateAssetsTransfer for complex asset transfers](https://github.com/polkadot-fellows/RFCs/pull/100)
- [RFC: Descend XCM origin instead of clearing it where possible](https://github.com/polkadot-fellows/RFCs/pull/109)

## Unresolved Questions

None

## Future Directions and Related Material
Binary file added text/0122-transact-over-bridge.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added text/0122-transact-single-xcm.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added text/0122-transact-today.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.