Skip to content

Commit

Permalink
some more fixes to pallet-token-gateway
Browse files Browse the repository at this point in the history
  • Loading branch information
seunlanlege committed Jan 10, 2025
1 parent 530d840 commit 111602e
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 52 deletions.
2 changes: 1 addition & 1 deletion modules/pallets/testsuite/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use ismp::{
};
use ismp_sync_committee::constants::sepolia::Sepolia;
use pallet_ismp::{offchain::Leaf, ModuleId};
use pallet_token_gateway::CreateAssetId;
use pallet_token_gateway::types::CreateAssetId;
use pallet_token_governor::GatewayParams;
use sp_core::{
crypto::AccountId32,
Expand Down
16 changes: 9 additions & 7 deletions modules/pallets/testsuite/src/tests/pallet_token_gateway.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@ use ismp::{
router::{PostRequest, Request, Timeout},
};
use pallet_token_gateway::{
impls::convert_to_erc20, AssetRegistration, Body, BodyWithCall, CreateAssetId,
SubstrateCalldata, TeleportParams,
impls::convert_to_erc20,
types::{
AssetRegistration, Body, BodyWithCall, CreateAssetId, SubstrateCalldata, TeleportParams,
},
};

use sp_core::{ByteArray, Get, Pair, H160, H256, U256};

use sp_runtime::{AccountId32, MultiSignature};
use token_gateway_primitives::{
token_gateway_id, token_governor_id, AssetMetadata, GatewayAssetRegistration,
AssetMetadata, GatewayAssetRegistration, PALLET_TOKEN_GATEWAY_ID, TOKEN_GOVERNOR_ID,
};
use xcm_simulator_example::ALICE;

Expand Down Expand Up @@ -165,7 +167,7 @@ fn inspector_should_intercept_illegal_request() {
source: StateMachine::Kusama(100),
dest: StateMachine::Evm(1),
nonce: 0,
from: token_gateway_id().0.to_vec(),
from: PALLET_TOKEN_GATEWAY_ID.to_vec(),
to: H160::zero().0.to_vec(),
timeout_timestamp: 1000,
body: {
Expand Down Expand Up @@ -256,7 +258,7 @@ fn inspector_should_handle_timeout_correctly() {
source: StateMachine::Kusama(100),
dest: StateMachine::Evm(1),
nonce: 0,
from: token_gateway_id().0.to_vec(),
from: PALLET_TOKEN_GATEWAY_ID.to_vec(),
to: H160::zero().0.to_vec(),
timeout_timestamp: 1000,
body: {
Expand Down Expand Up @@ -318,8 +320,8 @@ fn receiving_remote_asset_creation() {
source: StateMachine::Polkadot(3367),
dest: StateMachine::Kusama(100),
nonce: 0,
from: token_governor_id(),
to: token_gateway_id().0.to_vec(),
from: TOKEN_GOVERNOR_ID.to_vec(),
to: PALLET_TOKEN_GATEWAY_ID.to_vec(),
timeout_timestamp: 0,
body: asset_metadata.encode(),
};
Expand Down
6 changes: 3 additions & 3 deletions modules/pallets/token-gateway-inspector/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub mod pallet {
use frame_support::{pallet_prelude::*, Blake2_128Concat};

use ismp::host::StateMachine;
use pallet_token_gateway::Body;
use pallet_token_gateway::types::Body;
use pallet_token_governor::StandaloneChainAssets;

#[pallet::pallet]
Expand Down Expand Up @@ -88,7 +88,7 @@ pub mod pallet {
// As long as the initial deployment is valid
// it's impossible to send malicious requests
if source.is_evm() && dest.is_evm() {
return Ok(())
return Ok(());
}

if let Some(body) = Self::is_token_gateway_request(&body) {
Expand Down Expand Up @@ -142,7 +142,7 @@ pub mod pallet {
// As long as the initial deployment is valid
// it's impossible to send malicious requests
if source.is_evm() && dest.is_evm() {
return Ok(())
return Ok(());
}

if let Some(body) = Self::is_token_gateway_request(&body) {
Expand Down
19 changes: 7 additions & 12 deletions modules/pallets/token-gateway/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
//! This library contains types shared with token gateway and other pallets
#![cfg_attr(not(feature = "std"), no_std)]

use alloy_primitives::hex;
use ismp::host::StateMachine;
use sp_core::{ConstU32, H160, H256};
use sp_runtime::BoundedVec;
Expand All @@ -24,19 +25,13 @@ extern crate alloc;
use alloc::vec::Vec;
use codec::{Decode, Encode};

/// The token registry Id
pub const REGISTRY: [u8; 8] = *b"registry";
/// Pallet Token Governor's module ID for ISMP requests
pub const TOKEN_GOVERNOR_ID: [u8; 8] = *b"registry";

/// Token Gateway Id for substrate chains
/// Module Id is the last 20 bytes of the keccak hash of the pallet id
pub fn token_gateway_id() -> H160 {
let hash = sp_io::hashing::keccak_256(b"tokengty");
H160::from_slice(&hash[12..32])
}

pub fn token_governor_id() -> Vec<u8> {
REGISTRY.to_vec()
}
/// Pallet Token Gateway's module ID for ISMP requests
///
/// Derived from `keccak_256(b"tokengty")[12..]`
pub const PALLET_TOKEN_GATEWAY_ID: [u8; 20] = hex!("a09b1c60e8650245f92518c8a17314878c4043ed");

/// Holds metadata relevant to a multi-chain native asset
#[derive(Debug, Clone, Encode, Decode, scale_info::TypeInfo, PartialEq, Eq, Default)]
Expand Down
2 changes: 1 addition & 1 deletion modules/pallets/token-gateway/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ where
timeout: 10,
token_gateway: vec![1, 2, 3, 4, 5],
relayer_fee: 1000000002u128.into(),
call_data: None,
call_data: None,
}
}

Expand Down
6 changes: 3 additions & 3 deletions modules/pallets/token-gateway/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ use alloc::string::ToString;
use frame_support::PalletId;
use sp_core::U256;
use sp_runtime::traits::AccountIdConversion;
use token_gateway_primitives::token_gateway_id;
use token_gateway_primitives::PALLET_TOKEN_GATEWAY_ID;

use crate::{Config, Pallet};

impl<T: Config> Pallet<T> {
pub fn pallet_account() -> T::AccountId {
let mut inner = [0u8; 8];
inner.copy_from_slice(&token_gateway_id().0[0..8]);
inner.copy_from_slice(&PALLET_TOKEN_GATEWAY_ID[0..8]);
PalletId(inner).into_account_truncating()
}

pub fn is_token_gateway(id: &[u8]) -> bool {
id == &token_gateway_id().0
id == &PALLET_TOKEN_GATEWAY_ID
}
}

Expand Down
40 changes: 23 additions & 17 deletions modules/pallets/token-gateway/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@ use ismp::{
use sp_core::{Get, H160, U256};
use sp_runtime::{traits::Dispatchable, MultiSignature};
use token_gateway_primitives::{
token_gateway_id, token_governor_id, AssetMetadata, DeregisterAssets,
AssetMetadata, DeregisterAssets, PALLET_TOKEN_GATEWAY_ID, TOKEN_GOVERNOR_ID,
};
use types::{
AssetId, Body, BodyWithCall, CreateAssetId, EvmToSubstrate, RequestBody, SubstrateCalldata,
};
pub use types::*;

use alloc::{string::ToString, vec, vec::Vec};
use frame_system::RawOrigin;
Expand All @@ -65,6 +67,7 @@ pub mod pallet {
use alloc::collections::BTreeMap;
use pallet_hyperbridge::PALLET_HYPERBRIDGE;
use sp_runtime::traits::AccountIdConversion;
use types::{AssetRegistration, TeleportParams};

use super::*;
use frame_support::{
Expand Down Expand Up @@ -123,6 +126,7 @@ pub mod pallet {
type Decimals: Get<u8>;

/// A trait that converts an evm address to a substrate account
/// Used for authenticating incoming cross-chain runtime calls.
type EvmToSubstrate: EvmToSubstrate<Self>;

/// Weight information for extrinsics in this pallet
Expand Down Expand Up @@ -160,12 +164,12 @@ pub mod pallet {
pub enum Event<T: Config> {
/// An asset has been teleported
AssetTeleported {
/// Source account on the relaychain
/// Source account
from: T::AccountId,
/// beneficiary account on destination
to: H256,
/// Amount transferred
amount: <<T as Config>::NativeCurrency as Currency<T::AccountId>>::Balance,
amount: <T::NativeCurrency as Currency<T::AccountId>>::Balance,
/// Destination chain
dest: StateMachine,
/// Request commitment
Expand Down Expand Up @@ -337,7 +341,7 @@ pub mod pallet {

let dispatch_post = DispatchPost {
dest: params.destination,
from: token_gateway_id().0.to_vec(),
from: PALLET_TOKEN_GATEWAY_ID.to_vec(),
to: params.token_gateway,
timeout: params.timeout,
body,
Expand Down Expand Up @@ -411,8 +415,8 @@ pub mod pallet {
let dispatcher = <T as Config>::Dispatcher::default();
let dispatch_post = DispatchPost {
dest: T::Coprocessor::get().ok_or_else(|| Error::<T>::CoprocessorNotConfigured)?,
from: token_gateway_id().0.to_vec(),
to: token_governor_id(),
from: PALLET_TOKEN_GATEWAY_ID.to_vec(),
to: TOKEN_GOVERNOR_ID.to_vec(),
timeout: 0,
body: { RemoteERC6160AssetRegistration::CreateAsset(asset.reg).encode() },
};
Expand Down Expand Up @@ -458,8 +462,8 @@ pub mod pallet {
let dispatcher = <T as Config>::Dispatcher::default();
let dispatch_post = DispatchPost {
dest: T::Coprocessor::get().ok_or_else(|| Error::<T>::CoprocessorNotConfigured)?,
from: token_gateway_id().0.to_vec(),
to: token_governor_id(),
from: PALLET_TOKEN_GATEWAY_ID.to_vec(),
to: TOKEN_GOVERNOR_ID.to_vec(),
timeout: 0,
body: { RemoteERC6160AssetRegistration::UpdateAsset(asset).encode() },
};
Expand Down Expand Up @@ -497,7 +501,7 @@ where
) -> Result<(), anyhow::Error> {
// The only requests allowed from token governor on Hyperbridge is asset creation, updating
// and deregistering
if from == token_governor_id() && Some(source) == T::Coprocessor::get() {
if &from == &TOKEN_GOVERNOR_ID[..] && Some(source) == T::Coprocessor::get() {
if let Ok(metadata) = AssetMetadata::decode(&mut &body[..]) {
let asset_id: H256 = sp_io::hashing::keccak_256(metadata.symbol.as_ref()).into();
// If the local aset Id exists, then it must mean this is an update.
Expand Down Expand Up @@ -554,9 +558,10 @@ where
return Ok(());
}
}
let expected = TokenGatewayAddresses::<T>::get(source)
.ok_or_else(|| anyhow!("Not configured to receive assets from {source:?}"))?;
ensure!(
from == TokenGatewayAddresses::<T>::get(source).unwrap_or_default().to_vec() ||
from == token_gateway_id().0.to_vec(),
from == expected,
ismp::error::Error::ModuleDispatchError {
msg: "Token Gateway: Unknown source contract address".to_string(),
meta: Meta { source, dest, nonce },
Expand Down Expand Up @@ -634,13 +639,15 @@ where
}

if let Some(call_data) = body.data {
let substrate_data = SubstrateCalldata::decode(&mut &call_data.0[..])?;
let substrate_data = SubstrateCalldata::decode(&mut &call_data.0[..])
.map_err(|err| anyhow!("Calldata decode error: {err:?}"))?;
// Verify signature against encoded runtime call
let nonce = frame_system::Pallet::<T>::account_nonce(beneficiary.clone());
let payload = (nonce, substrate_data.runtime_call.clone()).encode();
let message = sp_io::hashing::keccak_256(&payload);

let multi_signature = MultiSignature::decode(&mut &*substrate_data.signature)?;
let multi_signature = MultiSignature::decode(&mut &*substrate_data.signature)
.map_err(|err| anyhow!("Signature decode error: {err:?}"))?;

match multi_signature {
MultiSignature::Ed25519(sig) => {
Expand Down Expand Up @@ -679,9 +686,8 @@ where
},
}

let runtime_call = <<T as frame_system::Config>::RuntimeCall as codec::Decode>::decode(
&mut &*substrate_data.runtime_call,
)?;
let runtime_call = T::RuntimeCall::decode(&mut &*substrate_data.runtime_call)
.map_err(|err| anyhow!("RuntimeCall decode error: {err:?}"))?;
runtime_call
.dispatch(RawOrigin::Signed(beneficiary.clone()).into())
.map_err(|e| anyhow!("Call dispatch executed with error {:?}", e.error))?;
Expand Down
8 changes: 4 additions & 4 deletions modules/pallets/token-governor/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use crate::{
TokenGatewayRequest, TokenRegistrarParams, UnsignedERC6160AssetRegistration, PALLET_ID,
};

use token_gateway_primitives::{token_gateway_id, AssetMetadata};
use token_gateway_primitives::{AssetMetadata, PALLET_TOKEN_GATEWAY_ID};

impl<T: Config> Pallet<T>
where
Expand Down Expand Up @@ -77,7 +77,7 @@ where

for ChainWithSupply { chain, supply } in asset.chains.clone() {
let address = if chain.is_substrate() {
token_gateway_id()
H160(PALLET_TOKEN_GATEWAY_ID)
} else {
let GatewayParams { address, .. } = TokenGatewayParams::<T>::get(&chain)
.ok_or_else(|| Error::<T>::UnknownTokenGateway)?;
Expand Down Expand Up @@ -169,7 +169,7 @@ where
}

let address = if chain.is_substrate() {
token_gateway_id()
H160(PALLET_TOKEN_GATEWAY_ID)
} else {
let GatewayParams { address, .. } = TokenGatewayParams::<T>::get(&chain)
.ok_or_else(|| Error::<T>::UnknownTokenGateway)?;
Expand Down Expand Up @@ -211,7 +211,7 @@ where
}

let address = if chain.is_substrate() {
token_gateway_id()
H160(PALLET_TOKEN_GATEWAY_ID)
} else {
let GatewayParams { address, .. } = TokenGatewayParams::<T>::get(&chain)
.ok_or_else(|| Error::<T>::UnknownTokenGateway)?;
Expand Down
8 changes: 4 additions & 4 deletions modules/pallets/token-governor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ use alloc::{format, vec};
use codec::Encode;
use ismp::module::IsmpModule;
use primitive_types::{H160, H256};
use token_gateway_primitives::{token_gateway_id, RemoteERC6160AssetRegistration};
use token_gateway_primitives::{RemoteERC6160AssetRegistration, PALLET_TOKEN_GATEWAY_ID};

pub use token_gateway_primitives::REGISTRY as PALLET_ID;
pub use token_gateway_primitives::TOKEN_GOVERNOR_ID as PALLET_ID;

// Re-export pallet items so that they can be accessed from the crate namespace.
pub use pallet::*;
Expand Down Expand Up @@ -411,7 +411,7 @@ where
PostRequest { body: data, from, source, .. }: PostRequest,
) -> Result<(), anyhow::Error> {
// Only substrate chains are allowed to fully register assets remotely
if source.is_substrate() && from == token_gateway_id().0.to_vec() {
if source.is_substrate() && &from == &PALLET_TOKEN_GATEWAY_ID[..] {
let remote_reg: RemoteERC6160AssetRegistration = codec::Decode::decode(&mut &*data)
.map_err(|_| ismp::error::Error::Custom(format!("Failed to decode data")))?;
match remote_reg {
Expand All @@ -433,7 +433,7 @@ where
},
}

return Ok(())
return Ok(());
}
let RegistrarParams { address, .. } = TokenRegistrarParams::<T>::get(&source)
.ok_or_else(|| ismp::error::Error::Custom(format!("Pallet is not initialized")))?;
Expand Down

0 comments on commit 111602e

Please sign in to comment.