Skip to content

Commit

Permalink
Make sure that the execution fee is the token of this chain or the to…
Browse files Browse the repository at this point in the history
…ken of the recipient chain
  • Loading branch information
imstar15 committed Nov 9, 2023
1 parent f5a3d21 commit 15bc38d
Showing 1 changed file with 46 additions and 12 deletions.
58 changes: 46 additions & 12 deletions pallets/automation-time/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ use frame_support::{
weights::constants::WEIGHT_REF_TIME_PER_SECOND,
};
use frame_system::pallet_prelude::*;
use orml_traits::{FixedConversionRateProvider, MultiCurrency};
use orml_traits::{
location::{Parse, Reserve},
FixedConversionRateProvider, MultiCurrency,
};
use pallet_parachain_staking::DelegatorActions;
use pallet_timestamp::{self as timestamp};
pub use pallet_xcmp_handler::InstructionSequence;
Expand Down Expand Up @@ -197,6 +200,14 @@ pub mod pallet {
BalanceOf<Self>,
<Self as frame_system::Config>::RuntimeCall,
>;

/// The way to retreave the reserve of a MultiAsset. This can be
/// configured to accept absolute or relative paths for self tokens
type ReserveProvider: Reserve;

/// Self chain location.
#[pallet::constant]
type SelfLocation: Get<MultiLocation>;
}

const STORAGE_VERSION: StorageVersion = StorageVersion::new(2);
Expand Down Expand Up @@ -267,7 +278,10 @@ pub mod pallet {
/// The version of the `VersionedMultiLocation` value used is not able
/// to be interpreted.
BadVersion,
UnsupportedFeePayment,
CannotReanchor,
/// Invalid asset location.
InvalidAssetLocation,
}

#[pallet::event]
Expand Down Expand Up @@ -374,6 +388,8 @@ pub mod pallet {
/// * `DuplicateTask`: There can be no duplicate tasks.
/// * `TimeTooFarOut`: Execution time or frequency are past the max time horizon.
/// * `TimeSlotFull`: Time slot is full. No more tasks can be scheduled for this time.
/// * `UnsupportedFeePayment`: Unsupported fee payment.
/// * `InvalidAssetLocation` Invalid asset location.
#[pallet::call_index(2)]
#[pallet::weight(<T as Config>::WeightInfo::schedule_xcmp_task_full(schedule.number_of_executions()))]
pub fn schedule_xcmp_task(
Expand All @@ -391,10 +407,18 @@ pub mod pallet {
MultiLocation::try_from(*destination).map_err(|()| Error::<T>::BadVersion)?;
let schedule_fee =
MultiLocation::try_from(*schedule_fee).map_err(|()| Error::<T>::BadVersion)?;

let execution_fee: AssetPayment = *execution_fee;
let execution_fee_location =
MultiLocation::try_from(execution_fee.clone().asset_location)
.map_err(|()| Error::<T>::BadVersion)?;

Self::ensure_supported_execution_fee_location(&execution_fee_location, &destination)?;

let action = Action::XCMP {
destination,
schedule_fee,
execution_fee: *execution_fee,
execution_fee,
encoded_call,
encoded_call_weight,
overall_weight,
Expand Down Expand Up @@ -1354,14 +1378,11 @@ pub mod pallet {
abort_errors: Vec<Vec<u8>>,
) -> DispatchResult {
match action.clone() {
Action::XCMP { execution_fee, instruction_sequence, .. } => {
Action::XCMP { execution_fee, .. } => {
let asset_location = MultiLocation::try_from(execution_fee.asset_location)
.map_err(|()| Error::<T>::BadVersion)?;
let asset_location = asset_location
.reanchored(
&MultiLocation::new(1, X1(Parachain(T::SelfParaId::get().into()))),
T::UniversalLocation::get(),
)
let _asset_location = asset_location
.reanchored(&T::SelfLocation::get().into(), T::UniversalLocation::get())
.map_err(|_| Error::<T>::CannotReanchor)?;
},
_ => (),
Expand Down Expand Up @@ -1521,10 +1542,7 @@ pub mod pallet {

let schedule_fee_location = action.schedule_fee_location::<T>();
let schedule_fee_location = schedule_fee_location
.reanchored(
&MultiLocation::new(1, X1(Parachain(T::SelfParaId::get().into()))),
T::UniversalLocation::get(),
)
.reanchored(&T::SelfLocation::get().into(), T::UniversalLocation::get())
.map_err(|_| Error::<T>::CannotReanchor)?;

let fee = if schedule_fee_location == MultiLocation::default() {
Expand All @@ -1542,6 +1560,22 @@ pub mod pallet {

Ok(fee)
}

pub fn ensure_supported_execution_fee_location(
exeuction_fee_location: &MultiLocation,
destination: &MultiLocation,
) -> Result<(), DispatchError> {
if exeuction_fee_location.chain_part().is_none() {
return Err(Error::<T>::InvalidAssetLocation.into())
}

let self_location = T::SelfLocation::get();
if exeuction_fee_location != &self_location && exeuction_fee_location != destination {
return Err(Error::<T>::UnsupportedFeePayment.into())
}

Ok(())
}
}

impl<T: Config> pallet_valve::Shutdown for Pallet<T> {
Expand Down

0 comments on commit 15bc38d

Please sign in to comment.