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

Swaps for XCM delivery fees #5131

Merged
merged 24 commits into from
Sep 2, 2024
Merged

Conversation

franciscoaguirre
Copy link
Contributor

@franciscoaguirre franciscoaguirre commented Jul 24, 2024

Context

Fees can already be paid in other assets locally thanks to the Trader implementations we have.
This doesn't work when sending messages because delivery fees go through a different mechanism altogether.
The idea is to fix this leveraging the AssetExchanger config item that's able to turn the asset the user wants to pay fees in into the asset the router expects for delivery fees.

Main addition

An adapter was needed to use pallet-asset-conversion for exchanging assets in XCM.
This was created in #5130.

The XCM executor was modified to use AssetExchanger (when available) to swap assets to pay for delivery fees.

Limitations

We can only pay for delivery fees in different assets in intermediate hops. We can't pay in different assets locally. The first hop will always need the native token of the chain (or whatever is specified in the XcmRouter).
This is a byproduct of using the BuyExecution instruction to know which asset should be used for delivery fee payment.
Since this instruction is not present when executing an XCM locally, we are left with this limitation.
To illustrate this limitation, I'll show two scenarios. All chains involved have pools.

Scenario 1

Parachain A --> Parachain B

Here, parachain A can use any asset in a pool with its native asset to pay for local execution fees.
However, as of now we can't use those for local delivery fees.
This means transfers from A to B need some amount of A's native token to pay for delivery fees.

Scenario 2

Parachain A --> Parachain C --> Parachain B

Here, Parachain C's remote delivery fees can be paid with any asset in a pool with its native asset.
This allows a reserve asset transfer between A and B with C as the reserve to only need A's native token at the starting hop.
After that, it could all be pool assets.

Future work

The fact that delivery fees go through a totally different mechanism results in a lot of bugs and pain points.
Unfortunately, this is not so easy to solve in a backwards compatible manner.
Delivery fees will be integrated into the language in future XCM versions, following polkadot-fellows/xcm-format#53.

Old PR: #4375.

@franciscoaguirre franciscoaguirre requested review from a team as code owners July 24, 2024 18:13
@franciscoaguirre franciscoaguirre added the T6-XCM This PR/Issue is related to XCM. label Jul 26, 2024
@franciscoaguirre franciscoaguirre changed the base branch from master to single-asset-exchange-adapter July 26, 2024 09:47
@franciscoaguirre franciscoaguirre requested review from a team as code owners July 26, 2024 09:47
@franciscoaguirre franciscoaguirre force-pushed the swaps-for-delivery-fees branch 2 times, most recently from 70caf38 to 5939ba2 Compare July 26, 2024 09:49
@franciscoaguirre
Copy link
Contributor Author

Same tests for rococo?

github-merge-queue bot pushed a commit that referenced this pull request Aug 2, 2024
Added a new adapter to xcm-builder, the `SingleAssetExchangeAdapter`.
This adapter makes it easy to use `pallet-asset-conversion` for
configuring the `AssetExchanger` XCM config item.

I also took the liberty of adding a new function to the `AssetExchange`
trait, with the following signature:

```rust
fn quote_exchange_price(give: &Assets, want: &Assets, maximal: bool) -> Option<Assets>;
```

The signature is meant to be fairly symmetric to that of
`exchange_asset`.
The way they interact can be seen in the doc comment for it in the
`AssetExchange` trait.

This is a breaking change but is needed for
#5131.
Another idea is to create a new trait for this but that would require
setting it in the XCM config which is also breaking.

Old PR: #4375.

---------

Co-authored-by: Adrian Catangiu <adrian@parity.io>
Base automatically changed from single-asset-exchange-adapter to master August 2, 2024 13:00
@paritytech-cicd-pr
Copy link

The CI pipeline was cancelled due to failure one of the required jobs.
Job name: test-linux-stable 2/3
Logs: https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/6911046

@franciscoaguirre franciscoaguirre added this pull request to the merge queue Sep 2, 2024
Merged via the queue into master with commit 5291412 Sep 2, 2024
145 of 185 checks passed
@franciscoaguirre franciscoaguirre deleted the swaps-for-delivery-fees branch September 2, 2024 11:18
x3c41a added a commit that referenced this pull request Sep 4, 2024
# Context

Fees can already be paid in other assets locally thanks to the Trader
implementations we have.
This doesn't work when sending messages because delivery fees go through
a different mechanism altogether.
The idea is to fix this leveraging the `AssetExchanger` config item
that's able to turn the asset the user wants to pay fees in into the
asset the router expects for delivery fees.

# Main addition

An adapter was needed to use `pallet-asset-conversion` for exchanging
assets in XCM.
This was created in
#5130.

The XCM executor was modified to use `AssetExchanger` (when available)
to swap assets to pay for delivery fees.

## Limitations

We can only pay for delivery fees in different assets in intermediate
hops. We can't pay in different assets locally. The first hop will
always need the native token of the chain (or whatever is specified in
the `XcmRouter`).
This is a byproduct of using the `BuyExecution` instruction to know
which asset should be used for delivery fee payment.
Since this instruction is not present when executing an XCM locally, we
are left with this limitation.
To illustrate this limitation, I'll show two scenarios. All chains
involved have pools.

### Scenario 1

Parachain A --> Parachain B

Here, parachain A can use any asset in a pool with its native asset to
pay for local execution fees.
However, as of now we can't use those for local delivery fees.
This means transfers from A to B need some amount of A's native token to
pay for delivery fees.

### Scenario 2

Parachain A --> Parachain C --> Parachain B

Here, Parachain C's remote delivery fees can be paid with any asset in a
pool with its native asset.
This allows a reserve asset transfer between A and B with C as the
reserve to only need A's native token at the starting hop.
After that, it could all be pool assets.

## Future work

The fact that delivery fees go through a totally different mechanism
results in a lot of bugs and pain points.
Unfortunately, this is not so easy to solve in a backwards compatible
manner.
Delivery fees will be integrated into the language in future XCM
versions, following
polkadot-fellows/xcm-format#53.

Old PR: #4375.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T6-XCM This PR/Issue is related to XCM.
Projects
Status: Audited
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants