• Adrian Catangiu's avatar
    pallet-xcm: add new flexible `transfer_assets()` call/extrinsic (#2388) · e7651cf4
    Adrian Catangiu authored
    # Motivation (+testing)
    
    ### Enable easy `ForeignAssets` transfers using `pallet-xcm` 
    
    We had just previously added capabilities to teleport fees during
    reserve-based transfers, but what about reserve-transferring fees when
    needing to teleport some non-fee asset?
    
    This PR aligns everything under either explicit reserve-transfer,
    explicit teleport, or this new flexible `transfer_assets()` which can
    mix and match as needed with fewer artificial constraints imposed to the
    user.
    
    This will enable, for example, a (non-system) parachain to teleport
    their `ForeignAssets` assets to AssetHub while using DOT to pay fees.
    (the assets are teleported - as foreign assets should from their owner
    chain - while DOT used for fees can only be reserve-based transferred
    between said parachain and AssetHub).
    
    Added `xcm-emulator` tests for this scenario ^.
    
    # Description
    
    Reverts `(limited_)reserve_transfer_assets` to only allow reserve-based
    transfers for all `assets` including fees.
    
    Similarly `(limited_)teleport_assets` only allows teleports for all
    `assets` including fees.
        
    For complex combinations of asset transfers where assets and fees may
    have different reserves or different reserve/teleport trust
    configurations, users can use the newly added `transfer_assets()`
    extrinsic which is more flexible in allowing more complex scenarios.
    
    `assets` (excluding `fees`) must have same reserve location or otherwise
    be teleportable to `dest`.
    No limitations imposed on `fees`.
    
    - for local reserve: transfer assets to sovereign account of destination
    chain and forward a notification XCM to `dest` to mint and deposit
    reserve-based assets to `beneficiary`.
    - for destination reserve: burn local assets and forward a notification
    to `dest` chain to withdraw the reserve assets from this chain's
    sovereign account and deposit them to `beneficiary`.
    - for remote reserve: burn local assets, forward XCM to reserve chain to
    move reserves from this chain's SA to `dest` chain's SA, and forward
    another XCM to `dest` to mint and deposit reserve-based assets to
    `beneficiary`.
    - for teleports: burn local assets and forward XCM to `dest` chain to
    mint/teleport assets and deposit them to `beneficiary`.
    
    ## Review notes
    
    Only around 500 lines are prod code (see `pallet_xcm/src/lib.rs`), the
    rest of the PR is new tests and improving existing tests.
    
    ---------
    
    Co-authored-by: command-bot <>
    e7651cf4