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

Reserve transfer assets to Ethereum with weth as fee & UnpaidExecution #135

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
9 changes: 8 additions & 1 deletion bridges/snowbridge/primitives/router/src/outbound/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ impl<'a, Call> XcmConverter<'a, Call> {
let _ = self.next();
}

// Get the fee asset item from BuyExecution or continue parsing.
// Todo: Get the fee asset item from BuyExecution and verify against remote_fee.
let fee_asset = match_expression!(self.peek(), Ok(BuyExecution { fees, .. }), fees);
if fee_asset.is_some() {
let _ = self.next();
Expand Down Expand Up @@ -259,6 +259,13 @@ impl<'a, Call> XcmConverter<'a, Call> {
// transfer amount must be greater than 0.
ensure!(amount > 0, ZeroAssetTransfer);

// Todo: Get the fee asset item from BurnAsset and verify against local_fee.
let local_assets =
match_expression!(self.peek(), Ok(BurnAsset(local_assets)), Some(local_assets));
if local_assets.is_some() {
let _ = self.next();
}

// Check if there is a SetTopic and skip over it if found.
let topic_id = match_expression!(self.next()?, SetTopic(id), id).ok_or(SetTopicExpected)?;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,6 @@ fn send_token_from_ethereum_to_penpal() {
/// - returning the token to Ethereum
#[test]
fn send_weth_asset_from_asset_hub_to_ethereum() {
use asset_hub_rococo_runtime::xcm_config::bridging::to_ethereum::DefaultBridgeHubEthereumBaseFee;
let assethub_sovereign = BridgeHubRococo::sovereign_account_id_of(Location::new(
1,
[Parachain(AssetHubRococo::para_id().into())],
Expand All @@ -397,6 +396,9 @@ fn send_weth_asset_from_asset_hub_to_ethereum() {
AssetHubRococo::fund_accounts(vec![(AssetHubRococoReceiver::get(), INITIAL_FUND)]);

const WETH_AMOUNT: u128 = 1_000_000_000;
const WETH_FEE_AMOUNT: u128 = 1_000_000_000;

const RELAY_TOKEN_FEE_AMOUNT: u128 = 1_000_000_000;

BridgeHubRococo::execute_with(|| {
type RuntimeEvent = <BridgeHubRococo as Chain>::RuntimeEvent;
Expand Down Expand Up @@ -445,7 +447,19 @@ fn send_weth_asset_from_asset_hub_to_ethereum() {
)),
fun: Fungible(WETH_AMOUNT),
}];
let multi_assets = VersionedAssets::V4(Assets::from(assets));
let fees = vec![
Asset { id: AssetId(Location::parent()), fun: Fungible(RELAY_TOKEN_FEE_AMOUNT) },
Asset {
id: AssetId(Location::new(
2,
[
GlobalConsensus(Ethereum { chain_id: CHAIN_ID }),
AccountKey20 { network: None, key: WETH },
],
)),
fun: Fungible(WETH_FEE_AMOUNT),
},
];

let destination = VersionedLocation::V4(Location::new(
2,
Expand All @@ -461,20 +475,20 @@ fn send_weth_asset_from_asset_hub_to_ethereum() {
AssetHubRococoReceiver::get(),
);
// Send the Weth back to Ethereum
<AssetHubRococo as AssetHubRococoPallet>::PolkadotXcm::reserve_transfer_assets(
<AssetHubRococo as AssetHubRococoPallet>::PolkadotXcm::reserve_transfer_ethereum_assets(
RuntimeOrigin::signed(AssetHubRococoReceiver::get()),
Box::new(destination),
Box::new(beneficiary),
Box::new(multi_assets),
0,
Box::new(VersionedAssets::V4(Assets::from(assets))),
Box::new(VersionedAssets::V4(Assets::from(fees))),
)
.unwrap();
let free_balance_after = <AssetHubRococo as AssetHubRococoPallet>::Balances::free_balance(
AssetHubRococoReceiver::get(),
);
// Assert at least DefaultBridgeHubEthereumBaseFee charged from the sender
let free_balance_diff = free_balance_before - free_balance_after;
assert!(free_balance_diff > DefaultBridgeHubEthereumBaseFee::get());
assert!(free_balance_diff > 0);
});

BridgeHubRococo::execute_with(|| {
Expand All @@ -487,25 +501,6 @@ fn send_weth_asset_from_asset_hub_to_ethereum() {
RuntimeEvent::EthereumOutboundQueue(snowbridge_pallet_outbound_queue::Event::MessageQueued {..}) => {},
]
);
let events = BridgeHubRococo::events();
// Check that the local fee was credited to the Snowbridge sovereign account
assert!(
events.iter().any(|event| matches!(
event,
RuntimeEvent::Balances(pallet_balances::Event::Minted { who, amount })
if *who == TREASURY_ACCOUNT.into() && *amount == 16903333
)),
"Snowbridge sovereign takes local fee."
);
// Check that the remote fee was credited to the AssetHub sovereign account
assert!(
events.iter().any(|event| matches!(
event,
RuntimeEvent::Balances(pallet_balances::Event::Minted { who, amount })
if *who == assethub_sovereign && *amount == 2680000000000,
)),
"AssetHub sovereign takes remote fee."
);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,9 @@ use xcm_builder::{
IsConcrete, LocalMint, NetworkExportTableItem, NoChecking, NonFungiblesAdapter,
ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
SovereignPaidRemoteExporter, SovereignSignedViaLocation, StartsWith,
StartsWithExplicitGlobalConsensus, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents,
WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, XcmFeeManagerFromComponents,
XcmFeeToAccount,
SovereignSignedViaLocation, StartsWith, StartsWithExplicitGlobalConsensus, TakeWeightCredit,
TrailingSetTopicAsId, UnpaidRemoteExporter, UsingComponents, WeightInfoBounds,
WithComputedOrigin, WithUniqueTopic, XcmFeeManagerFromComponents, XcmFeeToAccount,
};
use xcm_executor::{traits::WithOriginFilter, XcmExecutor};

Expand Down Expand Up @@ -657,7 +656,7 @@ pub type XcmRouter = WithUniqueTopic<(
ToWestendXcmRouter,
// Router which wraps and sends xcm to BridgeHub to be delivered to the Ethereum
// GlobalConsensus
SovereignPaidRemoteExporter<bridging::EthereumNetworkExportTable, XcmpQueue, UniversalLocation>,
UnpaidRemoteExporter<bridging::EthereumNetworkExportTable, XcmpQueue, UniversalLocation>,
)>;

impl pallet_xcm::Config for Runtime {
Expand Down Expand Up @@ -864,10 +863,7 @@ pub mod bridging {
EthereumNetwork::get(),
Some(sp_std::vec![Junctions::Here]),
SiblingBridgeHub::get(),
Some((
XcmBridgeHubRouterFeeAssetId::get(),
BridgeHubEthereumBaseFee::get(),
).into())
Comment on lines -867 to -870
Copy link
Author

@yrong yrong Apr 3, 2024

Choose a reason for hiding this comment

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

Remove the BridgeHubEthereumBaseFee config which is variable/unstable and hard to maintain on chain.

None,
),
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ use parachains_common::{
};
use polkadot_parachain_primitives::primitives::Sibling;
use polkadot_runtime_common::xcm_sender::ExponentialPrice;
use snowbridge_runtime_common::XcmExportFeeToSibling;
use sp_core::Get;
use sp_runtime::traits::AccountIdConversion;
use sp_std::marker::PhantomData;
Expand All @@ -61,7 +60,8 @@ use xcm_builder::{
FungibleAdapter, HandleFee, IsConcrete, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative,
SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId,
UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, XcmFeeToAccount,
UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
XcmFeeManagerFromComponents, XcmFeeToAccount,
};
use xcm_executor::{
traits::{FeeManager, FeeReason, FeeReason::Export, TransactAsset, WithOriginFilter},
Expand All @@ -79,6 +79,7 @@ parameter_types! {
pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating();
pub RelayTreasuryLocation: Location = (Parent, PalletInstance(rococo_runtime_constants::TREASURY_PALLET_ID)).into();
pub SiblingPeople: Location = (Parent, Parachain(rococo_runtime_constants::system_parachain::PEOPLE_ID)).into();
pub SiblingAssetHub: Location = (Parent, Parachain(rococo_runtime_constants::system_parachain::ASSET_HUB_ID)).into();
}

/// Type for specifying how a `Location` can be converted into an `AccountId`. This is used
Expand Down Expand Up @@ -255,6 +256,7 @@ pub type Barrier = TrailingSetTopicAsId<
ParentOrParentsPlurality,
Equals<RelayTreasuryLocation>,
Equals<SiblingPeople>,
Equals<SiblingAssetHub>,
)>,
// Subscriptions for version tracking are OK.
AllowSubscriptionsFrom<ParentRelayOrSiblingParachains>,
Expand Down Expand Up @@ -305,26 +307,9 @@ impl xcm_executor::Config for XcmConfig {
type SubscriptionService = PolkadotXcm;
type PalletInstancesInfo = AllPalletsWithSystem;
type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
type FeeManager = XcmFeeManagerFromComponentsBridgeHub<
type FeeManager = XcmFeeManagerFromComponents<
WaivedLocations,
(
XcmExportFeeToRelayerRewardAccounts<
Self::AssetTransactor,
crate::bridge_to_westend_config::WestendGlobalConsensusNetwork,
crate::bridge_to_westend_config::AssetHubWestendParaId,
crate::bridge_to_westend_config::BridgeHubWestendChainId,
crate::bridge_to_westend_config::AssetHubRococoToAssetHubWestendMessagesLane,
>,
XcmExportFeeToSibling<
bp_rococo::Balance,
AccountId,
TokenLocation,
EthereumNetwork,
Self::AssetTransactor,
crate::EthereumOutboundQueue,
>,
XcmFeeToAccount<Self::AssetTransactor, AccountId, TreasuryAccount>,
),
XcmFeeToAccount<Self::AssetTransactor, AccountId, TreasuryAccount>,
>;
type MessageExporter = (
crate::bridge_to_westend_config::ToBridgeHubWestendHaulBlobExporter,
Expand Down
Loading
Loading