diff --git a/runtime/test-runtime/src/xcm_config.rs b/runtime/test-runtime/src/xcm_config.rs
index 45e7956d45ba..21ce8c877dc3 100644
--- a/runtime/test-runtime/src/xcm_config.rs
+++ b/runtime/test-runtime/src/xcm_config.rs
@@ -80,7 +80,12 @@ impl WeightTrader for DummyWeightTrader {
 		DummyWeightTrader
 	}
 
-	fn buy_weight(&mut self, _weight: Weight, _payment: Assets) -> Result<Assets, XcmError> {
+	fn buy_weight(
+		&mut self,
+		_weight: Weight,
+		_payment: Assets,
+		_context: &XcmContext,
+	) -> Result<Assets, XcmError> {
 		Ok(Assets::default())
 	}
 }
diff --git a/xcm/xcm-builder/src/tests/weight.rs b/xcm/xcm-builder/src/tests/weight.rs
index 99ef029196ff..a2fb265413f5 100644
--- a/xcm/xcm-builder/src/tests/weight.rs
+++ b/xcm/xcm-builder/src/tests/weight.rs
@@ -24,25 +24,42 @@ fn fixed_rate_of_fungible_should_work() {
 	}
 
 	let mut trader = FixedRateOfFungible::<WeightPrice, ()>::new();
+	let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None };
+
 	// supplies 100 unit of asset, 80 still remains after purchasing weight
 	assert_eq!(
-		trader
-			.buy_weight(Weight::from_parts(10, 10), fungible_multi_asset(Here.into(), 100).into()),
+		trader.buy_weight(
+			Weight::from_parts(10, 10),
+			fungible_multi_asset(Here.into(), 100).into(),
+			&ctx,
+		),
 		Ok(fungible_multi_asset(Here.into(), 80).into()),
 	);
 	// should have nothing left, as 5 + 5 = 10, and we supplied 10 units of asset.
 	assert_eq!(
-		trader.buy_weight(Weight::from_parts(5, 5), fungible_multi_asset(Here.into(), 10).into()),
+		trader.buy_weight(
+			Weight::from_parts(5, 5),
+			fungible_multi_asset(Here.into(), 10).into(),
+			&ctx,
+		),
 		Ok(vec![].into()),
 	);
 	// should have 5 left, as there are no proof size components
 	assert_eq!(
-		trader.buy_weight(Weight::from_parts(5, 0), fungible_multi_asset(Here.into(), 10).into()),
+		trader.buy_weight(
+			Weight::from_parts(5, 0),
+			fungible_multi_asset(Here.into(), 10).into(),
+			&ctx,
+		),
 		Ok(fungible_multi_asset(Here.into(), 5).into()),
 	);
 	// not enough to purchase the combined weights
 	assert_err!(
-		trader.buy_weight(Weight::from_parts(5, 5), fungible_multi_asset(Here.into(), 5).into()),
+		trader.buy_weight(
+			Weight::from_parts(5, 5),
+			fungible_multi_asset(Here.into(), 5).into(),
+			&ctx,
+		),
 		XcmError::TooExpensive,
 	);
 }
@@ -149,35 +166,41 @@ fn weight_trader_tuple_should_work() {
 	);
 
 	let mut traders = Traders::new();
+	let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None };
+
 	// trader one buys weight
 	assert_eq!(
-		traders.buy_weight(Weight::from_parts(5, 5), fungible_multi_asset(Here.into(), 10).into()),
+		traders.buy_weight(
+			Weight::from_parts(5, 5),
+			fungible_multi_asset(Here.into(), 10).into(),
+			&ctx
+		),
 		Ok(vec![].into()),
 	);
 	// trader one refunds
 	assert_eq!(
-		traders.refund_weight(Weight::from_parts(2, 2)),
+		traders.refund_weight(Weight::from_parts(2, 2), &ctx),
 		Some(fungible_multi_asset(Here.into(), 4))
 	);
 
 	let mut traders = Traders::new();
 	// trader one failed; trader two buys weight
 	assert_eq!(
-		traders.buy_weight(Weight::from_parts(5, 5), fungible_multi_asset(para_1, 10).into()),
+		traders.buy_weight(Weight::from_parts(5, 5), fungible_multi_asset(para_1, 10).into(), &ctx),
 		Ok(vec![].into()),
 	);
 	// trader two refunds
 	assert_eq!(
-		traders.refund_weight(Weight::from_parts(2, 2)),
+		traders.refund_weight(Weight::from_parts(2, 2), &ctx),
 		Some(fungible_multi_asset(para_1, 4))
 	);
 
 	let mut traders = Traders::new();
 	// all traders fails
 	assert_err!(
-		traders.buy_weight(Weight::from_parts(5, 5), fungible_multi_asset(para_2, 10).into()),
+		traders.buy_weight(Weight::from_parts(5, 5), fungible_multi_asset(para_2, 10).into(), &ctx),
 		XcmError::TooExpensive,
 	);
 	// and no refund
-	assert_eq!(traders.refund_weight(Weight::from_parts(2, 2)), None);
+	assert_eq!(traders.refund_weight(Weight::from_parts(2, 2), &ctx), None);
 }
diff --git a/xcm/xcm-builder/src/weight.rs b/xcm/xcm-builder/src/weight.rs
index 1473775eccd8..73cba6cb557b 100644
--- a/xcm/xcm-builder/src/weight.rs
+++ b/xcm/xcm-builder/src/weight.rs
@@ -140,11 +140,16 @@ impl<T: Get<(AssetId, u128, u128)>, R: TakeRevenue> WeightTrader for FixedRateOf
 		Self(Weight::zero(), 0, PhantomData)
 	}
 
-	fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {
+	fn buy_weight(
+		&mut self,
+		weight: Weight,
+		payment: Assets,
+		context: &XcmContext,
+	) -> Result<Assets, XcmError> {
 		log::trace!(
 			target: "xcm::weight",
-			"FixedRateOfFungible::buy_weight weight: {:?}, payment: {:?}",
-			weight, payment,
+			"FixedRateOfFungible::buy_weight weight: {:?}, payment: {:?}, context: {:?}",
+			weight, payment, context,
 		);
 		let (id, units_per_second, units_per_mb) = T::get();
 		let amount = (units_per_second * (weight.ref_time() as u128) /
@@ -160,8 +165,8 @@ impl<T: Get<(AssetId, u128, u128)>, R: TakeRevenue> WeightTrader for FixedRateOf
 		Ok(unused)
 	}
 
-	fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
-		log::trace!(target: "xcm::weight", "FixedRateOfFungible::refund_weight weight: {:?}", weight);
+	fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option<MultiAsset> {
+		log::trace!(target: "xcm::weight", "FixedRateOfFungible::refund_weight weight: {:?}, context: {:?}", weight, context);
 		let (id, units_per_second, units_per_mb) = T::get();
 		let weight = weight.min(self.0);
 		let amount = (units_per_second * (weight.ref_time() as u128) /
@@ -210,8 +215,13 @@ impl<
 		Self(Weight::zero(), Zero::zero(), PhantomData)
 	}
 
-	fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {
-		log::trace!(target: "xcm::weight", "UsingComponents::buy_weight weight: {:?}, payment: {:?}", weight, payment);
+	fn buy_weight(
+		&mut self,
+		weight: Weight,
+		payment: Assets,
+		context: &XcmContext,
+	) -> Result<Assets, XcmError> {
+		log::trace!(target: "xcm::weight", "UsingComponents::buy_weight weight: {:?}, payment: {:?}, context: {:?}", weight, payment, context);
 		let amount = WeightToFee::weight_to_fee(&weight);
 		let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?;
 		let required = (Concrete(AssetId::get()), u128_amount).into();
@@ -221,8 +231,8 @@ impl<
 		Ok(unused)
 	}
 
-	fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
-		log::trace!(target: "xcm::weight", "UsingComponents::refund_weight weight: {:?}", weight);
+	fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option<MultiAsset> {
+		log::trace!(target: "xcm::weight", "UsingComponents::refund_weight weight: {:?}, context: {:?}", weight, context);
 		let weight = weight.min(self.0);
 		let amount = WeightToFee::weight_to_fee(&weight);
 		self.0 -= weight;
diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs
index 050d73837085..57ddc4322923 100644
--- a/xcm/xcm-executor/src/lib.rs
+++ b/xcm/xcm-executor/src/lib.rs
@@ -457,7 +457,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
 		let current_surplus = self.total_surplus.saturating_sub(self.total_refunded);
 		if current_surplus.any_gt(Weight::zero()) {
 			self.total_refunded.saturating_accrue(current_surplus);
-			if let Some(w) = self.trader.refund_weight(current_surplus) {
+			if let Some(w) = self.trader.refund_weight(current_surplus, &self.context) {
 				self.subsume_asset(w)?;
 			}
 		}
@@ -689,7 +689,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
 					// pay for `weight` using up to `fees` of the holding register.
 					let max_fee =
 						self.holding.try_take(fees.into()).map_err(|_| XcmError::NotHoldingFees)?;
-					let unspent = self.trader.buy_weight(weight, max_fee)?;
+					let unspent = self.trader.buy_weight(weight, max_fee, &self.context)?;
 					self.subsume_assets(unspent)?;
 				}
 				Ok(())
diff --git a/xcm/xcm-executor/src/traits/weight.rs b/xcm/xcm-executor/src/traits/weight.rs
index 033614d4bf61..06e6b5f55bce 100644
--- a/xcm/xcm-executor/src/traits/weight.rs
+++ b/xcm/xcm-executor/src/traits/weight.rs
@@ -49,13 +49,18 @@ pub trait WeightTrader: Sized {
 	/// Purchase execution weight credit in return for up to a given `payment`. If less of the
 	/// payment is required then the surplus is returned. If the `payment` cannot be used to pay
 	/// for the `weight`, then an error is returned.
-	fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError>;
+	fn buy_weight(
+		&mut self,
+		weight: Weight,
+		payment: Assets,
+		context: &XcmContext,
+	) -> Result<Assets, XcmError>;
 
 	/// Attempt a refund of `weight` into some asset. The caller does not guarantee that the weight was
 	/// purchased using `buy_weight`.
 	///
 	/// Default implementation refunds nothing.
-	fn refund_weight(&mut self, _weight: Weight) -> Option<MultiAsset> {
+	fn refund_weight(&mut self, _weight: Weight, _context: &XcmContext) -> Option<MultiAsset> {
 		None
 	}
 }
@@ -66,11 +71,16 @@ impl WeightTrader for Tuple {
 		for_tuples!( ( #( Tuple::new() ),* ) )
 	}
 
-	fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {
+	fn buy_weight(
+		&mut self,
+		weight: Weight,
+		payment: Assets,
+		context: &XcmContext,
+	) -> Result<Assets, XcmError> {
 		let mut too_expensive_error_found = false;
 		let mut last_error = None;
 		for_tuples!( #(
-			match Tuple.buy_weight(weight, payment.clone()) {
+			match Tuple.buy_weight(weight, payment.clone(), context) {
 				Ok(assets) => return Ok(assets),
 				Err(e) => {
 					if let XcmError::TooExpensive = e {
@@ -92,9 +102,9 @@ impl WeightTrader for Tuple {
 		})
 	}
 
-	fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
+	fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option<MultiAsset> {
 		for_tuples!( #(
-			if let Some(asset) = Tuple.refund_weight(weight) {
+			if let Some(asset) = Tuple.refund_weight(weight, context) {
 				return Some(asset);
 			}
 		)* );