From ab4094907157ab9a132d51d70e335fa4d4fb103d Mon Sep 17 00:00:00 2001 From: ron Date: Tue, 8 Apr 2025 21:38:04 +0800 Subject: [PATCH 1/2] Check that the reward address matches the relayer --- .../snowbridge/pallets/outbound-queue-v2/src/lib.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/bridges/snowbridge/pallets/outbound-queue-v2/src/lib.rs b/bridges/snowbridge/pallets/outbound-queue-v2/src/lib.rs index e7b67e8ff0882..a08b8e6f65d39 100644 --- a/bridges/snowbridge/pallets/outbound-queue-v2/src/lib.rs +++ b/bridges/snowbridge/pallets/outbound-queue-v2/src/lib.rs @@ -224,6 +224,10 @@ pub mod pallet { InvalidPendingNonce, /// Reward payment failed RewardPaymentFailed, + /// Reward account invalid + InvalidRewardAccount, + /// Relayer account invalid + InvalidRelayerAccount, } /// Messages to be committed in the current block. This storage value is killed in @@ -418,12 +422,17 @@ pub mod pallet { /// Process a delivery receipt from a relayer, to allocate the relayer reward. pub fn process_delivery_receipt( - relayer: ::AccountId, + relayer: T::AccountId, receipt: DeliveryReceipt, ) -> DispatchResult { // Verify that the message was submitted from the known Gateway contract ensure!(T::GatewayAddress::get() == receipt.gateway, Error::::InvalidGateway); + // Verify the reward account is same as the account that relayed the message + let reward_account = T::AccountId::decode(&mut receipt.reward_address.as_slice()) + .map_err(|_| Error::::InvalidRewardAccount)?; + ensure!(relayer == reward_account, Error::::InvalidRelayerAccount); + let nonce = receipt.nonce; let order = >::get(nonce).ok_or(Error::::InvalidPendingNonce)?; From 66974881e2f321f5b30e0e625bec70bba1206931 Mon Sep 17 00:00:00 2001 From: ron Date: Wed, 9 Apr 2025 14:32:50 +0800 Subject: [PATCH 2/2] Credit to reward address --- .../pallets/outbound-queue-v2/src/lib.rs | 21 ++++++++----------- .../src/tests/snowbridge_v2_outbound.rs | 14 ++++++------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/bridges/snowbridge/pallets/outbound-queue-v2/src/lib.rs b/bridges/snowbridge/pallets/outbound-queue-v2/src/lib.rs index a08b8e6f65d39..5819a1555c4a1 100644 --- a/bridges/snowbridge/pallets/outbound-queue-v2/src/lib.rs +++ b/bridges/snowbridge/pallets/outbound-queue-v2/src/lib.rs @@ -224,10 +224,8 @@ pub mod pallet { InvalidPendingNonce, /// Reward payment failed RewardPaymentFailed, - /// Reward account invalid + /// Invalid Reward account InvalidRewardAccount, - /// Relayer account invalid - InvalidRelayerAccount, } /// Messages to be committed in the current block. This storage value is killed in @@ -286,7 +284,7 @@ pub mod pallet { origin: OriginFor, event: Box, ) -> DispatchResult { - let relayer = ensure_signed(origin)?; + ensure_signed(origin)?; // submit message to verifier for verification T::Verifier::verify(&event.event_log, &event.proof) @@ -295,7 +293,7 @@ pub mod pallet { let receipt = DeliveryReceipt::try_from(&event.event_log) .map_err(|_| Error::::InvalidEnvelope)?; - Self::process_delivery_receipt(relayer, receipt) + Self::process_delivery_receipt(receipt) } } @@ -421,17 +419,12 @@ pub mod pallet { } /// Process a delivery receipt from a relayer, to allocate the relayer reward. - pub fn process_delivery_receipt( - relayer: T::AccountId, - receipt: DeliveryReceipt, - ) -> DispatchResult { + pub fn process_delivery_receipt(receipt: DeliveryReceipt) -> DispatchResult { // Verify that the message was submitted from the known Gateway contract ensure!(T::GatewayAddress::get() == receipt.gateway, Error::::InvalidGateway); - // Verify the reward account is same as the account that relayed the message let reward_account = T::AccountId::decode(&mut receipt.reward_address.as_slice()) .map_err(|_| Error::::InvalidRewardAccount)?; - ensure!(relayer == reward_account, Error::::InvalidRelayerAccount); let nonce = receipt.nonce; @@ -439,7 +432,11 @@ pub mod pallet { if order.fee > 0 { // Pay relayer reward - T::RewardPayment::register_reward(&relayer, T::DefaultRewardKind::get(), order.fee); + T::RewardPayment::register_reward( + &reward_account, + T::DefaultRewardKind::get(), + order.fee, + ); } >::remove(nonce); diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/snowbridge_v2_outbound.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/snowbridge_v2_outbound.rs index e86add58f79c5..dce84ade64275 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/snowbridge_v2_outbound.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/snowbridge_v2_outbound.rs @@ -112,7 +112,7 @@ fn send_weth_from_asset_hub_to_ethereum() { }; // Submit a delivery receipt - assert_ok!(EthereumOutboundQueueV2::process_delivery_receipt(relayer, receipt)); + assert_ok!(EthereumOutboundQueueV2::process_delivery_receipt(receipt)); assert_expected_events!( BridgeHubWestend, @@ -271,7 +271,7 @@ fn transfer_relay_token_from_ah() { }; // Submit a delivery receipt - assert_ok!(EthereumOutboundQueueV2::process_delivery_receipt(relayer, receipt)); + assert_ok!(EthereumOutboundQueueV2::process_delivery_receipt(receipt)); assert_expected_events!( BridgeHubWestend, @@ -358,7 +358,7 @@ fn send_weth_and_dot_from_asset_hub_to_ethereum() { }; // Submit a delivery receipt - assert_ok!(EthereumOutboundQueueV2::process_delivery_receipt(relayer, receipt)); + assert_ok!(EthereumOutboundQueueV2::process_delivery_receipt(receipt)); assert_expected_events!( BridgeHubWestend, @@ -454,7 +454,7 @@ fn transact_with_agent_from_asset_hub() { }; // Submit a delivery receipt - assert_ok!(EthereumOutboundQueueV2::process_delivery_receipt(relayer, receipt)); + assert_ok!(EthereumOutboundQueueV2::process_delivery_receipt(receipt)); assert_expected_events!( BridgeHubWestend, @@ -538,7 +538,7 @@ fn transact_with_agent_from_asset_hub_without_any_asset_transfer() { }; // Submit a delivery receipt - assert_ok!(EthereumOutboundQueueV2::process_delivery_receipt(relayer, receipt)); + assert_ok!(EthereumOutboundQueueV2::process_delivery_receipt(receipt)); assert_expected_events!( BridgeHubWestend, @@ -655,7 +655,7 @@ fn register_token_from_penpal() { }; // Submit a delivery receipt - assert_ok!(EthereumOutboundQueueV2::process_delivery_receipt(relayer, receipt)); + assert_ok!(EthereumOutboundQueueV2::process_delivery_receipt(receipt)); assert_expected_events!( BridgeHubWestend, @@ -820,7 +820,7 @@ fn invalid_nonce_for_delivery_receipt_fails() { }; assert_err!( - EthereumOutboundQueueV2::process_delivery_receipt(relayer, receipt), + EthereumOutboundQueueV2::process_delivery_receipt(receipt), Error::::InvalidPendingNonce ); });