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

xcm: multi-hop mixed asset transfers not working because of missing transport fee #4832

Closed
acatangiu opened this issue Jun 19, 2024 · 1 comment · Fixed by #4834
Closed
Assignees
Labels
T6-XCM This PR/Issue is related to XCM.

Comments

@acatangiu
Copy link
Contributor

Description

Sending XCM messages to other chains requires paying a "transport fee". This can be paid either:

  • from origin local account if jit_withdraw = true,
  • taken from Holding register otherwise.

This currently works for following hops/scenarios:

  1. On destination no transport fee needed (only sending costs, not receiving),
  2. Local/originating chain: just set JIT=true and fee will be paid from signed account,
  3. Intermediary hops - only if intermediary is acting as reserve between two untrusted chains (aka only for DepositReserveAsset instruction) - this was fixed in xcm-executor: DepositReserveAsset charges delivery fees from inner assets #3142

But now we're seeing more complex asset transfers that are mixing reserve transfers with teleports depending on the involved chains.
E.g. transferring DOT between Relay and parachain, but through AH (using AH instead of the Relay chain as parachain's DOT reserve).

In the Parachain --1--> AssetHub --2--> Relay scenario, DOT has to be reserve-withdrawn in leg 1, then teleported in leg 2.
On the intermediary hop (AssetHub), InitiateTeleport fails to send onward message because of missing transport fees. We also can't rely on jit_withdraw because the original origin is lost on the way, and even if it weren't we can't rely on the user having funded accounts on each hop along the way.

Solution

Charge the transport fee in the executor from the transferred assets (if available).

@acatangiu acatangiu added the T6-XCM This PR/Issue is related to XCM. label Jun 19, 2024
@acatangiu acatangiu self-assigned this Jun 19, 2024
@acatangiu acatangiu moved this to In Progress in Bridges + XCM Jun 19, 2024
@xlc
Copy link
Contributor

xlc commented Jun 19, 2024

we need to do this polkadot-fellows/xcm-format#53

acatangiu added a commit to acatangiu/polkadot-sdk that referenced this issue Dec 2, 2024
This can be paid either:
- from `origin` local account if `jit_withdraw = true`,
- taken from Holding register otherwise.

This currently works for following hops/scenarios:
1. On destination no transport fee needed (only sending costs, not receiving),
2. Local/originating chain: just set JIT=true and fee will be paid from signed account,
3. Intermediary hops - only if intermediary is acting as reserve between two untrusted
chains (aka only for `DepositReserveAsset` instruction) - this was fixed in
paritytech#3142

But now we're seeing more complex asset transfers that are mixing reserve transfers
with teleports depending on the involved chains.

E.g. transferring DOT between Relay and parachain, but through AH (using AH instead
of the Relay chain as parachain's DOT reserve).

In the `Parachain --1--> AssetHub --2--> Relay` scenario, DOT has to be reserve-withdrawn
in leg `1`, then teleported in leg `2`.
On the intermediary hop (AssetHub), `InitiateTeleport` fails to send onward message because
of missing transport fees. We also can't rely on `jit_withdraw` because the original origin
is lost on the way, and even if it weren't we can't rely on the user having funded accounts
on each hop along the way.

- Charge the transport fee in the executor from the transferred assets (if available),
- Only charge from transferred assets if JIT_WITHDRAW was not set,
- Only charge from transferred assets if Holding doesn't already contain enough (other)
assets to pay for the transport fee.

Added regression tests in emulated transfers.

Fixes paritytech#4832

Signed-off-by: Adrian Catangiu <adrian@parity.io>
acatangiu added a commit to acatangiu/polkadot-sdk that referenced this issue Dec 2, 2024
This can be paid either:
- from `origin` local account if `jit_withdraw = true`,
- taken from Holding register otherwise.

This currently works for following hops/scenarios:
1. On destination no transport fee needed (only sending costs, not receiving),
2. Local/originating chain: just set JIT=true and fee will be paid from signed account,
3. Intermediary hops - only if intermediary is acting as reserve between two untrusted
chains (aka only for `DepositReserveAsset` instruction) - this was fixed in
paritytech#3142

But now we're seeing more complex asset transfers that are mixing reserve transfers
with teleports depending on the involved chains.

E.g. transferring DOT between Relay and parachain, but through AH (using AH instead
of the Relay chain as parachain's DOT reserve).

In the `Parachain --1--> AssetHub --2--> Relay` scenario, DOT has to be reserve-withdrawn
in leg `1`, then teleported in leg `2`.
On the intermediary hop (AssetHub), `InitiateTeleport` fails to send onward message because
of missing transport fees. We also can't rely on `jit_withdraw` because the original origin
is lost on the way, and even if it weren't we can't rely on the user having funded accounts
on each hop along the way.

- Charge the transport fee in the executor from the transferred assets (if available),
- Only charge from transferred assets if JIT_WITHDRAW was not set,
- Only charge from transferred assets if Holding doesn't already contain enough (other)
assets to pay for the transport fee.

Added regression tests in emulated transfers.

Fixes paritytech#4832

Signed-off-by: Adrian Catangiu <adrian@parity.io>
github-merge-queue bot pushed a commit that referenced this issue Dec 9, 2024
…#4834)

# Description

Sending XCM messages to other chains requires paying a "transport fee".
This can be paid either:
- from `origin` local account if `jit_withdraw = true`,
- taken from Holding register otherwise.

This currently works for following hops/scenarios:
1. On destination no transport fee needed (only sending costs, not
receiving),
2. Local/originating chain: just set JIT=true and fee will be paid from
signed account,
3. Intermediary hops - only if intermediary is acting as reserve between
two untrusted chains (aka only for `DepositReserveAsset` instruction) -
this was fixed in #3142

But now we're seeing more complex asset transfers that are mixing
reserve transfers with teleports depending on the involved chains.

# Example

E.g. transferring DOT between Relay and parachain, but through AH (using
AH instead of the Relay chain as parachain's DOT reserve).

In the `Parachain --1--> AssetHub --2--> Relay` scenario, DOT has to be
reserve-withdrawn in leg `1`, then teleported in leg `2`.
On the intermediary hop (AssetHub), `InitiateTeleport` fails to send
onward message because of missing transport fees. We also can't rely on
`jit_withdraw` because the original origin is lost on the way, and even
if it weren't we can't rely on the user having funded accounts on each
hop along the way.

# Solution/Changes

- Charge the transport fee in the executor from the transferred assets
(if available),
- Only charge from transferred assets if JIT_WITHDRAW was not set,
- Only charge from transferred assets if unless using XCMv5 `PayFees`
where we do not have this problem.

# Testing

Added regression tests in emulated transfers.

Fixes #4832
Fixes #6637

---------

Signed-off-by: Adrian Catangiu <adrian@parity.io>
Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com>
@github-project-automation github-project-automation bot moved this from In Progress to Done in Bridges + XCM Dec 9, 2024
github-actions bot pushed a commit that referenced this issue Dec 9, 2024
…#4834)

# Description

Sending XCM messages to other chains requires paying a "transport fee".
This can be paid either:
- from `origin` local account if `jit_withdraw = true`,
- taken from Holding register otherwise.

This currently works for following hops/scenarios:
1. On destination no transport fee needed (only sending costs, not
receiving),
2. Local/originating chain: just set JIT=true and fee will be paid from
signed account,
3. Intermediary hops - only if intermediary is acting as reserve between
two untrusted chains (aka only for `DepositReserveAsset` instruction) -
this was fixed in #3142

But now we're seeing more complex asset transfers that are mixing
reserve transfers with teleports depending on the involved chains.

# Example

E.g. transferring DOT between Relay and parachain, but through AH (using
AH instead of the Relay chain as parachain's DOT reserve).

In the `Parachain --1--> AssetHub --2--> Relay` scenario, DOT has to be
reserve-withdrawn in leg `1`, then teleported in leg `2`.
On the intermediary hop (AssetHub), `InitiateTeleport` fails to send
onward message because of missing transport fees. We also can't rely on
`jit_withdraw` because the original origin is lost on the way, and even
if it weren't we can't rely on the user having funded accounts on each
hop along the way.

# Solution/Changes

- Charge the transport fee in the executor from the transferred assets
(if available),
- Only charge from transferred assets if JIT_WITHDRAW was not set,
- Only charge from transferred assets if unless using XCMv5 `PayFees`
where we do not have this problem.

# Testing

Added regression tests in emulated transfers.

Fixes #4832
Fixes #6637

---------

Signed-off-by: Adrian Catangiu <adrian@parity.io>
Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com>
(cherry picked from commit e79fd2b)
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: Done
Development

Successfully merging a pull request may close this issue.

2 participants