Skip to content
This repository has been archived by the owner on May 21, 2024. It is now read-only.

Extend pallet-xcm to pay teleport with non teleported asset #266

Merged
merged 30 commits into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
85bde1c
feat: migrate to polkadot-v1.0.0
Aug 22, 2023
35e301e
feat: add missing migrations for polkadot-v1.0.0
Aug 24, 2023
7f13ca7
Fix Benchmkaring
hbulgarini Aug 24, 2023
e484833
".git/.scripts/commands/bench-all/bench-all.sh" --runtime=trappist --…
Aug 24, 2023
900877f
Fix compilation
hbulgarini Aug 24, 2023
923b9f7
add pallet for teleport foreign assets into ah
metricaez Aug 24, 2023
74db417
clean duplicated errors
metricaez Aug 25, 2023
08a93cf
cargo fmt
metricaez Aug 25, 2023
38918dd
comments
metricaez Aug 25, 2023
ac306c0
fix typo
metricaez Aug 28, 2023
92e5940
foreign asset by reanchoring
metricaez Aug 28, 2023
fb6d26b
Burn withdrawn assets on origin
metricaez Aug 28, 2023
935f233
Merge branch 'main' into emi-proxy-teleport-pallet
metricaez Aug 28, 2023
f280b8e
add comments and remove fee_asset_item
metricaez Aug 29, 2023
575e655
import through prelude
metricaez Sep 1, 2023
fa7b919
add foreign locations for LocationToAccountId
metricaez Sep 1, 2023
42f9527
Merge branch 'main' into emi-proxy-teleport-pallet
metricaez Sep 1, 2023
3d28e3c
minor fixes and add execution check
metricaez Sep 4, 2023
ab8bfbc
add obnoxious comments to avoid misusage
metricaez Sep 4, 2023
41aea01
cargo fmt
metricaez Sep 4, 2023
69fb3fe
prelude wildcard
metricaez Sep 5, 2023
55fb0fe
cargo fmt
metricaez Sep 5, 2023
7541ba1
dismiss "proxy" wording
metricaez Sep 5, 2023
a5c8dd4
typo
metricaez Sep 6, 2023
baefbba
Withdraw derivative on origin (#275)
metricaez Sep 14, 2023
4477bb8
Merge branch 'main' into emi-proxy-teleport-pallet
metricaez Sep 14, 2023
6aca06b
add hash of foreign location
metricaez Sep 14, 2023
3aeab64
typo and remove job limit on git workflow
metricaez Sep 15, 2023
8d26c7d
use teleport fallback weight
metricaez Sep 15, 2023
d2bac9e
add jobs 1 flag to check.yml
metricaez Sep 15, 2023
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
18 changes: 18 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pallet-dex-rpc-runtime-api = { version = "0.0.1", git = "https://github.com/pari
pallet-asset-registry = { default-features = false, path = "pallets/asset-registry" }
trappist-runtime-benchmarks = { default-features = false, path = "pallets/benchmarks" }
pallet-lockdown-mode = { version = "0.1.0", default-features = false, path = "pallets/lockdown-mode" }
pallet-proxy-teleport = { version = "0.1.0", default-features = false, path = "pallets/proxy-teleport" }

# Substrate std
try-runtime-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v1.0.0" }
Expand Down
41 changes: 41 additions & 0 deletions pallets/proxy-teleport/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[package]
name = "pallet-proxy-teleport"
version = "0.1.0"
description = "Pallet for allowing to teleport funds by paying with a proxy account."
authors = { workspace = true }
license = { workspace = true }
homepage = { workspace = true }
repository = { workspace = true }
edition = { workspace = true }

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
parity-scale-codec = { workspace = true, features = [ "derive" ] }
scale-info = { workspace = true }
sp-runtime = { workspace = true }
sp-std = { workspace = true }
frame-benchmarking = { workspace = true }
frame-support = { workspace = true }
frame-system = { workspace = true }
pallet-xcm = { workspace = true }
xcm = { workspace = true }
sp-io = { workspace = true }


[dev-dependencies]
sp-core = { workspace = true }
sp-io = { workspace = true }
sp-runtime = { workspace = true }

[features]
default = ["std"]
std = [
"parity-scale-codec/std",
"frame-support/std",
"frame-system/std",
"scale-info/std",
]
runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"]
try-runtime = ["frame-support/try-runtime"]
214 changes: 214 additions & 0 deletions pallets/proxy-teleport/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
#![cfg_attr(not(feature = "std"), no_std)]

type BaseXcm<T> = pallet_xcm::Pallet<T>;
use frame_support::{
dispatch::DispatchResult,
ensure,
traits::{Contains, EnsureOrigin, Get},
weights::Weight,
};
use frame_system::pallet_prelude::OriginFor;
pub use pallet::*;
use parity_scale_codec::Encode;
use sp_std::{boxed::Box, vec};
pub use xcm::{
opaque::latest::prelude::{Junction, Junctions, MultiLocation, OriginKind},
v3::{
AssetId, ExecuteXcm, Fungibility,
Instruction::{
BurnAsset, BuyExecution, DepositAsset, DepositReserveAsset, InitiateReserveWithdraw,
ReceiveTeleportedAsset, Transact, WithdrawAsset,
},
MultiAsset, MultiAssetFilter, MultiAssets, Parent, SendXcm, WeightLimit,
WeightLimit::Unlimited,
WildMultiAsset, Xcm, XcmHash,
},
stiiifff marked this conversation as resolved.
Show resolved Hide resolved
VersionedMultiAssets, VersionedMultiLocation, VersionedResponse, VersionedXcm,
};

// #[cfg(test)]
// mod mock;

// #[cfg(test)]
// mod tests;

// #[cfg(feature = "runtime-benchmarks")]
// mod benchmarking;
// pub mod weights;
// pub use weights::*;

#[frame_support::pallet]
pub mod pallet {
use super::*;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;

#[pallet::pallet]
pub struct Pallet<T>(_);

#[pallet::config]
pub trait Config: frame_system::Config + pallet_xcm::Config {
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
}

#[pallet::error]
pub enum Error<T> {
/// An error ocured during send
SendError,
}

#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// Execution of an XCM message was attempted.
Attempted { outcome: xcm::latest::Outcome },
/// A XCM message was sent.
Sent {
origin: MultiLocation,
destination: MultiLocation,
message: Xcm<()>,
message_id: XcmHash,
},
}

/// Teleport native asset from a parachain to another.
/// This function is called by the parachain that wants to teleport native assets to another
/// parachain but needs to buy execution on the destination parachain with an asset that is not
/// being teleported. We call this asset the proxy asset.
/// The parachain that wants to teleport native assets to another parachain with this method
/// need to fund its Sovereign Account with the proxy asset on the destination parachain.
/// If multiple proxy assets are included in the message, only the first one is used to buy
/// execution. Proxy assets are trapped on the destination parachain.
/// Parameters:
/// - `origin`: The origin of the call.
/// - `dest`: The destination chain of the teleport.
/// - `beneficiary`: The beneficiary of the teleport from the perspective of the destination
/// chain.
/// - `native_asset_amount`: The amount of native asset to teleport.
/// - `proxy_asset`: The proxy asset to buy execution on the destination chain.

#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::call_index(0)]
#[pallet::weight(10_000)]
pub fn proxy_native_teleport(
origin: OriginFor<T>,
dest: Box<VersionedMultiLocation>,
beneficiary: Box<VersionedMultiLocation>,
native_asset_amount: u128,
proxy_asset: Box<VersionedMultiAssets>,
) -> DispatchResult {
Self::do_proxy_teleport_assets(
origin,
dest,
beneficiary,
native_asset_amount,
proxy_asset,
)
}
}
}

impl<T: Config> Pallet<T> {
fn do_proxy_teleport_assets(
origin: OriginFor<T>,
dest: Box<VersionedMultiLocation>,
beneficiary: Box<VersionedMultiLocation>,
native_asset_amount: u128,
proxy_asset: Box<VersionedMultiAssets>,

Choose a reason for hiding this comment

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

is this input parameter actually required?

My understanding is that it is always going to be the Relay chain/system parachain native asset hence the user would always set the same input.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hey, I see your point, I left it as a parameter as I thought that there might be an use case in which you would like to buy execution with other asset that is handeld but is not the Relay/SP native. For example buying with execution with xUSD on AH. What do you think?

Choose a reason for hiding this comment

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

good point, I agree it makes sense to leave this flexibility for the future. Only thing, it would be good to document this, particularly that the sovereign account in AH will need to have enough balance of the relevant asset for this to work (apart from it having a liquidity pool vs the native asset etc)

) -> DispatchResult {
//Unbox origin, destination and beneficiary.
let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?;
let dest: MultiLocation =
(*dest).try_into().map_err(|()| pallet_xcm::Error::<T>::BadVersion)?;
let beneficiary: MultiLocation =
(*beneficiary).try_into().map_err(|()| pallet_xcm::Error::<T>::BadVersion)?;

//Create assets

// Native from local perspective
let native_asset = MultiAsset {
id: AssetId::Concrete(MultiLocation::here()),
fun: Fungibility::Fungible(native_asset_amount),
};
let assets = MultiAssets::from(vec![native_asset.clone()]);

// Native from foreign perspective
let context = T::UniversalLocation::get();
let native_as_foreign = native_asset
.reanchored(&dest, context)
.map_err(|_| pallet_xcm::Error::<T>::CannotReanchor)?;
let foreing_assets = MultiAssets::from(vec![native_as_foreign]);

//Unbox proxy asset
let proxy_asset: MultiAssets =
(*proxy_asset).try_into().map_err(|()| pallet_xcm::Error::<T>::BadVersion)?;
Copy link

@franciscoaguirre franciscoaguirre Sep 1, 2023

Choose a reason for hiding this comment

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

You might want to unbox this earlier. You're gonna use it anyway and reanchoring is more expensive than this conversion.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done but would you care to explain further ?

Choose a reason for hiding this comment

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

You don't want to perform an expensive operation only to then find out your boxed value had a bad version

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Understood and makes sense, feel free to resolve.


//TeleportFilter check
let value = (origin_location, assets.into_inner());
ensure!(T::XcmTeleportFilter::contains(&value), pallet_xcm::Error::<T>::Filtered);
let (origin_location, assets) = value;

// Reanchor the proxy asset to the destination chain.
let fee_asset_item: usize = 0;
let fees = proxy_asset
.get(fee_asset_item as usize)
.ok_or(pallet_xcm::Error::<T>::Empty)?
.clone()
.reanchored(&dest, context)
.map_err(|_| pallet_xcm::Error::<T>::CannotReanchor)?;

// TODO: Define if Withdrawn proxy assets are deposited or trapped.
// Check if there is no vulnerability through RefundSurplus
//let max_assets = (assets.len() as u32).checked_add(1).ok_or(Error::<T>::TooManyAssets)?;

//Build the message to execute on origin.
let assets: MultiAssets = assets.into();
stiiifff marked this conversation as resolved.
Show resolved Hide resolved
let message: Xcm<<T as frame_system::Config>::RuntimeCall> = Xcm(vec![
// Withdraw drops asset so is used as burn mechanism

Choose a reason for hiding this comment

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

I was wondering, is it possible to mimic what InitiateTeleport does so that we don't leave the native asset trapped in the holding?

Choose a reason for hiding this comment

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

This way we could directly pass assets in line 172 instead of the hardcoded foreing_assets.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I like this, on it! Thanks

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Update:

  • I have implemented the reanchor , foreign_assets is no longer hardcoded.
  • I have also added a BurnAssets to mimic this part of the InitiateTeleport instruction
  • Currently trying to solve this check_out logic for this proxy call to track teleports too.

Copy link

@IkerAlus IkerAlus Aug 29, 2023

Choose a reason for hiding this comment

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

Good idea to use BurnAsssets instruction. In my opinion this is a solution close to as clean as we can get it. This way there is no trapped assets in the holding whereas the counterpart is expected to be minted in the destination chain. I think the check out logic is then secondary.

franciscoaguirre marked this conversation as resolved.
Show resolved Hide resolved
WithdrawAsset(assets.clone()),
BurnAsset(assets),
Copy link
Contributor

Choose a reason for hiding this comment

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

Indeed, shouldn't it be a InitiateTeleport instruction instead of the BurnAsset one ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Addressed here

]);

// Build the message to send.
// Set WeightLimit
// TODO: Implement weight_limit calculation with final instructions.
let weight_limit: WeightLimit = Unlimited;
let xcm_message: Xcm<()> = Xcm(vec![
franciscoaguirre marked this conversation as resolved.
Show resolved Hide resolved
WithdrawAsset(proxy_asset),
BuyExecution { fees, weight_limit },
ReceiveTeleportedAsset(foreing_assets.clone()),
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't get the need for the ReceiveTeleportedAsset instruction .. can you explain ?

Copy link
Collaborator Author

@metricaez metricaez Aug 28, 2023

Choose a reason for hiding this comment

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

Hey! Sure.

We must take in consideration that:

  • InitiateTeleport instruction imprints a ReceiveTeleportedAsset as first instruction of the xcm message that it sends.
  • The Barrier that we are targeting for in Asset Hub is AllowTopLevelPaidExecutionFrom, this Barrier to pass imposes a certain sequence of Instructions to be received in order as detailed here.
  • That is why do_teleport_assets fn from pallet-xcm sets BuyExecution as the first instruction of the xcm message that is sent as parameter to InitiateTeleport, therefore the Instruction order to be receive would be:
    -- Receive -> ClearOrigin (from InitiateTeleport)
    -- BuyExecution (from the xcm sent as parameter of InitiateTeleport)
    Leading to the Barrier compliant sequence of ReceiveTele... -> ClearOrigin -> BuyExecution

However, on Asset Hub we cannot BuyExecution with HOP or teleport ROC into it which would trigger the ReceiveTeleportedAssets progression with ROC.

There is no Instruction that allows me to prepend a Withdraw (ROC) + BuyExecution (ROC) together with the InitiateTeleport logic.

Therefore I am forced to split the logic of the call in two parts: What should be executed on Trappist and what should be sent to be executed on Asset Hub. I am trying to handcraft the logic as close as possible to the one from InitiateTeleport but adding the extra instructions that are needed for the use case. This leads to:

  • A execute_xcm for taking the assets to be teleported on origin via Withdraw + Burn
  • A send_xcm for paying execution with ROC and apply the "teleport" logic on Asset Hub. This is done by the Withdraw + BuyExecution + ReceiveTele... + DepositAsset that is sent to be executed on Asset Hub.

With these Instructions on this combination I try to approach to the do_teleport_assets logic but sneaking an execution buy with ROC on AH.

I hope this explains both this approach and the rest of the comments, please do let me know if you have any further question or if something doesn't make sense since this is just how I figured out how to work around this issue

// Intentionally trap ROC to avoid exploit

Choose a reason for hiding this comment

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

I don't see why keeping this ROC around would be a potential exploit. Care to explain?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yet to be explored but initially I was depositing All assets on beneficiary, and since at the time ROC is coming from pre funded Trappist's SovereignAccount on Asset Hub, there could be a case in which multiple calls drain the funds from the SovereignAccount into the beneficiary.

Limiting the amount of the proxy_asset, or demanding at least certain amount of the native_asset to be teleported could be a starter to avoid this. Atm, by not depositing all assets and only the foreign/native asset whose equivalent amount has been withdrawn on origin, users couldn't benefit from this exploit. However they could drain the funds by trapping all of them because some people just want to watch the world burn.

Changing origin to the from root to the sender would totally fix this as the funds of ROC (or any proxy_asset) would have been already owned by the caller.

Choose a reason for hiding this comment

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

I explained the way things work on my other comment. The funds are always coming from a user, since they pay on the sender chain (via burning). The only potential exploit there is minting more than is burnt. If the mechanism works well, Trappist's SA should never be arbitrarily drained, it will always be the result of derivative tokens being burnt.

Trappist's SA's balance in ROCs = sum(balance in derivative ROC for account in Trappist) <- If this holds then it all works fine.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Agreed that, if implemented, would solve this existing vulnerability.

DepositAsset { assets: MultiAssetFilter::Definite(foreing_assets), beneficiary },
]);

// Temporarly hardcode weight.
// TODO: Replace for Weigher.
let weight: Weight = Weight::from_parts(1_000_000_000, 100_000);
// T::Weigher::weight(&mut message).map_err(|()| Error::<T>::UnweighableMessage)?;

// Execute Withdraw for trapping assets on origin.
let hash = message.using_encoded(sp_io::hashing::blake2_256);
let outcome =
T::XcmExecutor::execute_xcm_in_credit(origin_location, message, hash, weight, weight);
Self::deposit_event(Event::Attempted { outcome });

// Use pallet-xcm send for sending message.
let root_origin = T::SendXcmOrigin::ensure_origin(frame_system::RawOrigin::Root.into())?;

Choose a reason for hiding this comment

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

The origin should be the account that has the funds it wants to teleport

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I agree that the one paying for the execution with the proxy asset on destiny chain should be the SovereignAccount (SA from now on) of the sender account and not the SA of the chain.

As a quick recap, proxy asset indicates which asset should be used to buy execution on destiny, but the funding of the account that is going to pay for that execution with said asset must be done previously to this call.

For simplicity, let's focus on the use case of: origin chain is Trappist, destiny chain is Asset Hub and the proxy asset is ROC.

Funding the SA of Trappist is simple, you can obtain the SA address with this tool and the PARA ID. Then you do a simple transfer of ROC on Asset Hub to the address of Trappist's SA. Therefore why I currently set Root as origin.

However doing so for the SA of the caller origin account from Trappist in Asset Hub, let's call it Alice, is not straightforward. Two good solutions would be:

  • Creating a tool that exposes this to obtain the address given a certain MultiLocation and send ROC to it on AH.
  • As you suggested on our related talk, another approach would be doing a XCM TransferAsset of ROC to {1, X2(Trappist,Alice)} which is the SA of Trappist's Alice on AH (or any Sibling). However, atm, AH doesn't allow executions.

Moving forward, I implemented the HashedDescription on Trappist's LocationToAccountId and was able to get the address SA of Trappist's Alice, meaning the SA of {1, X2(Trappist,Alice)} MultiLocation.

This allowed me to send ROC on AH to this address and now the call buys execution successfully if we set the origin of the call to Alice instead of Root. However, {1, X2(Trappist,Alice)} is not considered a Trusted Teleporter by AH.

Using an alias of Alice's SA to Trappist's SA which is currently a TrustedTeleported would be a increment of privileges on Alice that I do not see fit and also AH doesn't accept any Aliasers.

Choose a reason for hiding this comment

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

I don't think the name "proxy asset" is the best to describe what's going on here. The idea of this pallet, and extrinsic, is to teleport one main asset to chain B but withdraw another one on B as well.
It might be called something like withdraw_and_teleport.
It's just the name "proxy" the one that seems misused, it could be called a "fee asset" and that might be better.

Choose a reason for hiding this comment

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

Regarding using Alice as the origin of the message, in the end, it's not needed, Alice will already pay up on the sender chain, in this case Trappist, with derivative assets, in this case derivative ROCs.

It's perfectly fine to Withdraw from Trappist's sovereign account since AH doesn't care about Trappist's internal bookkeeping, it only cares that the whole of Trappist has some amount of ROCs. InitiateReserveWithdraw handles it in that way.

On another note, if you only fund Trappist's sovereign account on AH, you're basically giving up power over those assets and are unable to use them again. You should instead use DepositReserveAsset. That will fund the SA but also send a message over to Trappist to mint derivative tokens and send them to Alice over there. That will allow Alice to use this extrinsic to teleport whatever she wants, along with withdrawing the real ROCs for fees.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Agreed on the wording, as logic evolved the proxy term that I initially used became outdated, will re work.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

As for the DepositReserveAsset, will explore the suggestion as it would solve two main points:

  • Users or chain admins having to fund the SA with a transfer which requires them to obtain the address of the SA and adds an extra step of friction.
  • Most importantly, it diminishes vulnerabilities as it would take any incentive to drain the SA because users would be required to have the derivative on origin chain, and to do so they would have needed to reserve them, so basically it would be their funds.

As discussed on our following chat regarding this comment, withdrawn ROC derivatives on Trappist should also be burned and surplus of ROCs on Asset Hub could be refunded to avoid trapping unnecessary users funds.

From usability perspective, users would no longer need to fund SA through a transfer and they would need to ReserveAssetTransfer ROCs to their addresses on Trappist to be able to do this teleport.

Will implement and update on this thread.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

#275 Shows a first approach.

let interior: Junctions =
root_origin.try_into().map_err(|_| pallet_xcm::Error::<T>::InvalidOrigin)?;
//TODO: Check this Error population
let message_id = BaseXcm::<T>::send_xcm(interior, dest, xcm_message.clone())
franciscoaguirre marked this conversation as resolved.
Show resolved Hide resolved
.map_err(|_| Error::<T>::SendError)?;
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't you use execute_xcm instead of send_xcm, to initiate the teleport port operation on the local chain ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Addressed here

let e = Event::Sent {
origin: origin_location,
destination: dest,
message: xcm_message,
message_id,
};
Self::deposit_event(e);

// Finish.
Ok(())
}
}
2 changes: 2 additions & 0 deletions runtime/trappist/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ pallet-dex-rpc-runtime-api = { workspace = true }
pallet-asset-registry = { workspace = true }
trappist-runtime-benchmarks = { workspace = true }
pallet-lockdown-mode = { workspace = true }
pallet-proxy-teleport = { workspace = true }

[features]
default = ["std"]
Expand Down Expand Up @@ -148,6 +149,7 @@ std = [
"pallet-identity/std",
"pallet-lockdown-mode/std",
"pallet-preimage/std",
"pallet-proxy-teleport/std",
"pallet-multisig/std",
"pallet-insecure-randomness-collective-flip/std",
"pallet-scheduler/std",
Expand Down
5 changes: 5 additions & 0 deletions runtime/trappist/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,10 @@ impl pallet_treasury::Config for Runtime {
type SpendOrigin = frame_support::traits::NeverEnsureOrigin<Balance>;
}

impl pallet_proxy_teleport::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
}

impl pallet_lockdown_mode::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type LockdownModeOrigin = frame_system::EnsureRoot<Self::AccountId>;
Expand Down Expand Up @@ -717,6 +721,7 @@ construct_runtime!(
// Additional pallets
Dex: pallet_dex::{Pallet, Call, Storage, Event<T>} = 110,
AssetRegistry: pallet_asset_registry::{Pallet, Call, Storage, Event<T>} = 111,
ProxyTeleport: pallet_proxy_teleport = 112,
}
);

Expand Down