use crate::{Config, Error, Pezpallet};
use alloc::vec::Vec;
use hex_literal::hex;
use pezsp_core::Get;
use xcm::prelude::*;
use xcm_executor::traits::TransferType;
const PASEO_GENESIS_HASH: [u8; 32] =
hex!["77afd6190f1554ad45fd0d31aee62aacc33c6db0ea801129acb813f913e0764f"];
impl<T: Config> Pezpallet<T> {
pub(crate) fn ensure_network_asset_reserve_transfer_allowed(
assets: &Vec<Asset>,
fee_asset_id: &AssetId,
assets_transfer_type: &TransferType,
fees_transfer_type: &TransferType,
) -> Result<(), Error<T>> {
let mut remaining_assets = assets.clone();
let fee_asset_index =
assets.iter().position(|a| a.id == *fee_asset_id).ok_or(Error::<T>::Empty)?;
let fee_asset = remaining_assets.remove(fee_asset_index);
Self::ensure_one_transfer_type_allowed(&remaining_assets, &assets_transfer_type)?;
Self::ensure_one_transfer_type_allowed(&[fee_asset], &fees_transfer_type)?;
Ok(())
}
fn ensure_one_transfer_type_allowed(
assets: &[Asset],
transfer_type: &TransferType,
) -> Result<(), Error<T>> {
let is_reserve_transfer = matches!(
transfer_type,
TransferType::LocalReserve
| TransferType::DestinationReserve
| TransferType::RemoteReserve(_)
);
if !is_reserve_transfer {
return Ok(());
}
for asset in assets {
if Self::is_network_native_asset(&asset.id) {
tracing::debug!(
target: "xcm::pezpallet_xcm::transfer_assets",
asset_id = ?asset.id, ?transfer_type,
"Network native asset reserve transfer blocked in preparation for the Asset Hub Migration. Use `transfer_assets_using_type_and_then` instead and explicitly mention the reserve."
);
return Err(Error::<T>::InvalidAssetUnknownReserve);
}
}
Ok(())
}
fn is_network_native_asset(asset_id: &AssetId) -> bool {
let universal_location = T::UniversalLocation::get();
let asset_location = &asset_id.0;
match universal_location.len() {
1 => {
if let Some(Junction::GlobalConsensus(network)) = universal_location.first() {
let is_target_network = match network {
NetworkId::Pezkuwi | NetworkId::Kusama => true,
NetworkId::ByGenesis(genesis_hash) => {
*genesis_hash == xcm::v5::ZAGROS_GENESIS_HASH
|| *genesis_hash == PASEO_GENESIS_HASH
|| *genesis_hash == xcm::v5::PEZKUWICHAIN_GENESIS_HASH },
_ => false,
};
is_target_network && asset_location.is_here()
} else {
false
}
},
2 => {
if let (Some(Junction::GlobalConsensus(network)), Some(Junction::Teyrchain(_))) =
(universal_location.first(), universal_location.last())
{
let is_target_network = match network {
NetworkId::Pezkuwi | NetworkId::Kusama => true,
NetworkId::ByGenesis(genesis_hash) => {
*genesis_hash == xcm::v5::ZAGROS_GENESIS_HASH
|| *genesis_hash == PASEO_GENESIS_HASH
|| *genesis_hash == xcm::v5::PEZKUWICHAIN_GENESIS_HASH },
_ => false,
};
is_target_network && *asset_location == Location::parent()
} else {
false
}
},
_ => false,
}
}
}