From 0cf73c2d4a8149c19037beae298159ef86e24478 Mon Sep 17 00:00:00 2001 From: Igor Papandinas <26460174+ipapandinas@users.noreply.github.com> Date: Fri, 26 Dec 2025 14:12:06 +0100 Subject: [PATCH 1/3] chore: remove lockdrop precompile --- Cargo.lock | 30 -- Cargo.toml | 1 - precompiles/dispatch-lockdrop/Cargo.toml | 60 --- .../dispatch-lockdrop/DispatchLockdrop.sol | 20 - precompiles/dispatch-lockdrop/src/lib.rs | 135 ------- precompiles/dispatch-lockdrop/src/mock.rs | 212 ---------- precompiles/dispatch-lockdrop/src/tests.rs | 372 ------------------ runtime/astar/Cargo.toml | 2 - runtime/astar/src/precompiles.rs | 42 +- runtime/local/Cargo.toml | 2 - runtime/local/src/precompiles.rs | 40 +- runtime/shibuya/Cargo.toml | 2 - runtime/shibuya/src/precompiles.rs | 40 +- runtime/shiden/Cargo.toml | 2 - runtime/shiden/src/precompiles.rs | 41 +- 15 files changed, 18 insertions(+), 983 deletions(-) delete mode 100644 precompiles/dispatch-lockdrop/Cargo.toml delete mode 100644 precompiles/dispatch-lockdrop/DispatchLockdrop.sol delete mode 100644 precompiles/dispatch-lockdrop/src/lib.rs delete mode 100644 precompiles/dispatch-lockdrop/src/mock.rs delete mode 100644 precompiles/dispatch-lockdrop/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 6e8f5dd7f9..4dff176ab8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -652,7 +652,6 @@ dependencies = [ "pallet-evm-precompile-bn128", "pallet-evm-precompile-dapp-staking", "pallet-evm-precompile-dispatch", - "pallet-evm-precompile-dispatch-lockdrop", "pallet-evm-precompile-ed25519", "pallet-evm-precompile-modexp", "pallet-evm-precompile-sha3fips", @@ -7340,7 +7339,6 @@ dependencies = [ "pallet-evm-precompile-bn128", "pallet-evm-precompile-dapp-staking", "pallet-evm-precompile-dispatch", - "pallet-evm-precompile-dispatch-lockdrop", "pallet-evm-precompile-ed25519", "pallet-evm-precompile-modexp", "pallet-evm-precompile-sha3fips", @@ -9429,32 +9427,6 @@ dependencies = [ "sp-runtime", ] -[[package]] -name = "pallet-evm-precompile-dispatch-lockdrop" -version = "0.1.0" -dependencies = [ - "astar-primitives", - "ethers", - "fp-evm", - "frame-support", - "frame-system", - "hex-literal", - "libsecp256k1", - "log", - "pallet-balances", - "pallet-evm", - "pallet-evm-precompile-dispatch", - "pallet-timestamp", - "pallet-utility", - "parity-scale-codec", - "precompile-utils", - "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", -] - [[package]] name = "pallet-evm-precompile-ed25519" version = "2.0.0-dev" @@ -15306,7 +15278,6 @@ dependencies = [ "pallet-evm-precompile-bn128", "pallet-evm-precompile-dapp-staking", "pallet-evm-precompile-dispatch", - "pallet-evm-precompile-dispatch-lockdrop", "pallet-evm-precompile-ed25519", "pallet-evm-precompile-modexp", "pallet-evm-precompile-sha3fips", @@ -15424,7 +15395,6 @@ dependencies = [ "pallet-evm-precompile-bn128", "pallet-evm-precompile-dapp-staking", "pallet-evm-precompile-dispatch", - "pallet-evm-precompile-dispatch-lockdrop", "pallet-evm-precompile-ed25519", "pallet-evm-precompile-modexp", "pallet-evm-precompile-sha3fips", diff --git a/Cargo.toml b/Cargo.toml index beef6f511a..a32b633dd4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -310,7 +310,6 @@ pallet-evm-precompile-substrate-ecdsa = { path = "./precompiles/substrate-ecdsa" pallet-evm-precompile-xcm = { path = "./precompiles/xcm", default-features = false } pallet-evm-precompile-dapp-staking = { path = "./precompiles/dapp-staking", default-features = false } pallet-evm-precompile-unified-accounts = { path = "./precompiles/unified-accounts", default-features = false } -pallet-evm-precompile-dispatch-lockdrop = { path = "./precompiles/dispatch-lockdrop", default-features = false } pallet-chain-extension-assets = { path = "./chain-extensions/pallet-assets", default-features = false } pallet-chain-extension-unified-accounts = { path = "./chain-extensions/unified-accounts", default-features = false } diff --git a/precompiles/dispatch-lockdrop/Cargo.toml b/precompiles/dispatch-lockdrop/Cargo.toml deleted file mode 100644 index f6f508c611..0000000000 --- a/precompiles/dispatch-lockdrop/Cargo.toml +++ /dev/null @@ -1,60 +0,0 @@ -[package] -name = "pallet-evm-precompile-dispatch-lockdrop" -description = "Evm Precompile to dispatch calls for lockdrop accounts" -version = "0.1.0" -authors.workspace = true -edition.workspace = true -homepage.workspace = true -repository.workspace = true - -[dependencies] -fp-evm = { workspace = true } -frame-support = { workspace = true } -frame-system = { workspace = true } -hex-literal = { workspace = true } -libsecp256k1 = { workspace = true, features = ["hmac", "static-context"] } -log = { workspace = true } -pallet-evm = { workspace = true } -pallet-evm-precompile-dispatch = { workspace = true } -parity-scale-codec = { workspace = true } -precompile-utils = { workspace = true } -sp-core = { workspace = true } -sp-io = { workspace = true } -sp-runtime = { workspace = true } -sp-std = { workspace = true } - -[dev-dependencies] -astar-primitives = { workspace = true } -ethers = { workspace = true } -frame-system = { workspace = true } -pallet-balances = { workspace = true } -pallet-timestamp = { workspace = true } -pallet-utility = { workspace = true } -precompile-utils = { workspace = true, features = ["testing"] } -scale-info = { workspace = true } -sp-core = { workspace = true } -sp-io = { workspace = true } -sp-runtime = { workspace = true } -sp-std = { workspace = true } - -[features] -default = ["std"] -std = [ - "log/std", - "libsecp256k1/std", - "parity-scale-codec/std", - "scale-info/std", - "sp-std/std", - "sp-core/std", - "sp-io/std", - "sp-runtime/std", - "frame-support/std", - "frame-system/std", - "astar-primitives/std", - "precompile-utils/std", - "pallet-evm/std", - "pallet-balances/std", - "pallet-timestamp/std", - "fp-evm/std", - "pallet-evm-precompile-dispatch/std", -] diff --git a/precompiles/dispatch-lockdrop/DispatchLockdrop.sol b/precompiles/dispatch-lockdrop/DispatchLockdrop.sol deleted file mode 100644 index f464b5c3da..0000000000 --- a/precompiles/dispatch-lockdrop/DispatchLockdrop.sol +++ /dev/null @@ -1,20 +0,0 @@ -pragma solidity ^0.8.0; - -/** - * @title Dispatch Lockdrop calls interface. - */ - -/// Interface to dispatch lockdrop calls precompiled contract -/// Pre-deployed at the address 0x0000000000000000000000000000000000005007 -interface RescueLockdrop { - /** - * @dev Dispatch lockdrop call - * @param call - SCALE-encoded call arguments - * @param pubkey - full ECDSA pubkey 64 bytes - * @return boolean confirming whether the call got successfully dispatched - */ - function dispatch_lockdrop_call( - bytes calldata call, - bytes calldata pubkey - ) external returns (bool); -} \ No newline at end of file diff --git a/precompiles/dispatch-lockdrop/src/lib.rs b/precompiles/dispatch-lockdrop/src/lib.rs deleted file mode 100644 index 26f58e1862..0000000000 --- a/precompiles/dispatch-lockdrop/src/lib.rs +++ /dev/null @@ -1,135 +0,0 @@ -// This file is part of Astar. - -// Copyright (C) Stake Technologies Pte.Ltd. -// SPDX-License-Identifier: GPL-3.0-or-later - -// Astar is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Astar is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Astar. If not, see . - -#![cfg_attr(not(feature = "std"), no_std)] - -extern crate alloc; - -use core::marker::PhantomData; -use fp_evm::PrecompileHandle; -use frame_support::pallet_prelude::IsType; -use frame_support::traits::Get; -use frame_support::weights::Weight; -use frame_support::{ - dispatch::{GetDispatchInfo, PostDispatchInfo}, - traits::ConstU32, -}; -use frame_system::Config; -use pallet_evm::GasWeightMapping; -use pallet_evm_precompile_dispatch::DispatchValidateT; -use parity_scale_codec::DecodeLimit; -use precompile_utils::prelude::{revert, BoundedBytes, RuntimeHelper}; -use precompile_utils::EvmResult; -use sp_core::{crypto::AccountId32, H160, H256}; -use sp_io::hashing::keccak_256; -use sp_runtime::traits::Dispatchable; -use sp_std::vec::Vec; - -#[cfg(test)] -mod mock; -#[cfg(test)] -mod tests; - -pub const LOG_TARGET: &str = "precompile::dispatch-lockdrop"; - -// ECDSA PublicKey -type ECDSAPublic = ConstU32<64>; - -// `DecodeLimit` specifies the max depth a call can use when decoding, as unbounded depth -// can be used to overflow the stack. -// Default value is 8, which is the same as in XCM call decoding. -pub struct DispatchLockdrop>( - PhantomData<(Runtime, DispatchValidator, DecodeLimit)>, -); - -type CallLengthLimit = ConstU32<2048>; - -#[precompile_utils::precompile] -impl - DispatchLockdrop -where - Runtime: pallet_evm::Config, - ::RuntimeOrigin: From>, - Runtime::RuntimeCall: Dispatchable + GetDispatchInfo, - ::AccountId: IsType, - ::AccountId: From<[u8; 32]>, - DispatchValidator: - DispatchValidateT<::AccountId, ::RuntimeCall>, - DecodeLimit: Get, -{ - #[precompile::public("dispatch_lockdrop_call(bytes,bytes)")] - fn dispatch_lockdrop_call( - handle: &mut impl PrecompileHandle, - call: BoundedBytes, - pubkey: BoundedBytes, - ) -> EvmResult { - log::trace!( - target: LOG_TARGET, - "raw arguments: call: {:?}, pubkey: {:?}", - call, - pubkey - ); - - let caller: H160 = handle.context().caller.into(); - let input: Vec = call.into(); - - // Record a fixed amount of weight to ensure there is no free execution - handle.record_cost(Runtime::GasWeightMapping::weight_to_gas( - Weight::from_parts(1_000_000_000u64, 0), - ))?; - - // Ensure that the caller matches the public key - if caller != Self::get_evm_address_from_pubkey(pubkey.as_bytes()) { - let message: &str = "caller does not match the public key"; - log::trace!(target: LOG_TARGET, "{}", message); - return Err(revert(message)); - } - - // Derive the account id from the public key - let origin = Self::get_account_id_from_pubkey(pubkey.as_bytes()) - .ok_or(revert("could not derive AccountId from pubkey"))?; - - // Decode the call - let call = Runtime::RuntimeCall::decode_with_depth_limit(DecodeLimit::get(), &mut &*input) - .map_err(|_| revert("could not decode call"))?; - - // Validate the call - ensure that the call is allowed in filter - DispatchValidator::validate_before_dispatch(&origin, &call) - .map_or_else(|| Ok(()), |_| Err(revert("invalid Call")))?; - - // Dispatch the call and handle the cost - RuntimeHelper::::try_dispatch::( - handle, - Some(origin).into(), - call, - 0, - )?; - - Ok(true) - } - - fn get_account_id_from_pubkey(pubkey: &[u8]) -> Option<::AccountId> { - libsecp256k1::PublicKey::parse_slice(pubkey, None) - .map(|k| sp_io::hashing::blake2_256(k.serialize_compressed().as_ref()).into()) - .ok() - } - - fn get_evm_address_from_pubkey(pubkey: &[u8]) -> H160 { - H160::from(H256::from_slice(&keccak_256(pubkey))) - } -} diff --git a/precompiles/dispatch-lockdrop/src/mock.rs b/precompiles/dispatch-lockdrop/src/mock.rs deleted file mode 100644 index 0b0681c49d..0000000000 --- a/precompiles/dispatch-lockdrop/src/mock.rs +++ /dev/null @@ -1,212 +0,0 @@ -// This file is part of Astar. - -// Copyright (C) Stake Technologies Pte.Ltd. -// SPDX-License-Identifier: GPL-3.0-or-later - -// Astar is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Astar is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Astar. If not, see . - -use super::*; -use std::marker::PhantomData; - -use fp_evm::{IsPrecompileResult, Precompile}; -use frame_support::{ - construct_runtime, derive_impl, parameter_types, traits::ConstU64, weights::Weight, -}; -pub use pallet_evm::{ - AddressMapping, EnsureAddressNever, EnsureAddressRoot, PrecompileResult, PrecompileSet, -}; -use sp_core::{keccak_256, H160}; -use sp_runtime::{ - traits::{ConstU32, IdentityLookup}, - AccountId32, -}; - -use frame_support::traits::Contains; - -use astar_primitives::precompiles::DispatchFilterValidate; -pub type AccountId = AccountId32; -pub type Balance = u128; -pub type Block = frame_system::mocking::MockBlock; -pub const PRECOMPILE_ADDRESS: H160 = H160::repeat_byte(0x7B); - -pub const ONE: u128 = 1_000_000_000_000_000_000; -pub const ALICE: AccountId32 = AccountId32::new([1u8; 32]); -pub const DUMMY: AccountId32 = AccountId32::new([2u8; 32]); - -pub fn alice_secret() -> libsecp256k1::SecretKey { - libsecp256k1::SecretKey::parse(&keccak_256(b"Alice")).unwrap() -} - -parameter_types! { - pub const BlockHashCount: u64 = 250; - pub BlockWeights: frame_system::limits::BlockWeights = - frame_system::limits::BlockWeights::simple_max(Weight::from_parts(1024, 0)); -} - -#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] -impl frame_system::Config for TestRuntime { - type Block = Block; - type AccountId = AccountId32; - type Lookup = IdentityLookup; - type AccountData = pallet_balances::AccountData; -} - -pub struct WhitelistedCalls; - -impl Contains for WhitelistedCalls { - fn contains(call: &RuntimeCall) -> bool { - match call { - RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { .. }) => true, - RuntimeCall::System(frame_system::Call::remark { .. }) => true, - RuntimeCall::Utility(_) => true, - _ => false, - } - } -} - -#[derive(Debug, Clone, Copy)] -pub struct TestPrecompileSet(PhantomData); - -impl PrecompileSet for TestPrecompileSet -where - R: pallet_evm::Config, - DispatchLockdrop>: Precompile, -{ - fn execute(&self, handle: &mut impl PrecompileHandle) -> Option { - match handle.code_address() { - a if a == PRECOMPILE_ADDRESS => Some(DispatchLockdrop::< - R, - DispatchFilterValidate, - >::execute(handle)), - _ => None, - } - } - - fn is_precompile(&self, address: H160, _gas: u64) -> IsPrecompileResult { - IsPrecompileResult::Answer { - is_precompile: address == PRECOMPILE_ADDRESS, - extra_cost: 0, - } - } -} - -parameter_types! { - pub const ExistentialDeposit: u128 = 1; -} - -#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] -impl pallet_balances::Config for TestRuntime { - type Balance = Balance; - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; -} - -parameter_types! { - pub const MinimumPeriod: u64 = 5; -} - -#[derive_impl(pallet_timestamp::config_preludes::TestDefaultConfig)] -impl pallet_timestamp::Config for TestRuntime { - type MinimumPeriod = MinimumPeriod; -} - -parameter_types! { - pub const PrecompilesValue: TestPrecompileSet = - TestPrecompileSet(PhantomData); - pub WeightPerGas: Weight = Weight::from_parts(1, 0); -} - -pub type PrecompileCall = DispatchLockdropCall< - TestRuntime, - DispatchFilterValidate<::RuntimeCall, WhitelistedCalls>, - ConstU32<8>, ->; - -pub struct AddressMapper; -impl AddressMapping for AddressMapper { - fn into_account_id(account: H160) -> astar_primitives::AccountId { - let mut account_id = [0u8; 32]; - account_id[0..20].clone_from_slice(&account.as_bytes()); - - account_id - .try_into() - .expect("H160 is 20 bytes long so it must fit into 32 bytes; QED") - } -} - -impl pallet_evm::Config for TestRuntime { - type FeeCalculator = (); - type GasWeightMapping = pallet_evm::FixedGasWeightMapping; - type WeightPerGas = WeightPerGas; - type CallOrigin = EnsureAddressRoot; - type WithdrawOrigin = EnsureAddressNever; - type AddressMapping = AddressMapper; - type Currency = Balances; - type RuntimeEvent = RuntimeEvent; - type Runner = pallet_evm::runner::stack::Runner; - type PrecompilesType = TestPrecompileSet; - type PrecompilesValue = PrecompilesValue; - type Timestamp = Timestamp; - type ChainId = ChainId; - type OnChargeTransaction = (); - type BlockGasLimit = (); - type BlockHashMapping = pallet_evm::SubstrateBlockHashMapping; - type FindAuthor = (); - type OnCreate = (); - type WeightInfo = (); - type GasLimitPovSizeRatio = ConstU64<4>; - type AccountProvider = pallet_evm::FrameSystemAccountProvider; - type GasLimitStorageGrowthRatio = ConstU64<0>; -} - -impl pallet_utility::Config for TestRuntime { - type RuntimeEvent = RuntimeEvent; - type RuntimeCall = RuntimeCall; - type PalletsOrigin = OriginCaller; - type WeightInfo = (); -} - -parameter_types! { - // 2 storage items with value size 20 and 32 - pub const AccountMappingStorageFee: u128 = 0; - pub ChainId: u64 = 1024; -} - -// Configure a mock runtime to test the pallet. -construct_runtime!( - pub enum TestRuntime - { - System: frame_system, - Evm: pallet_evm, - Balances : pallet_balances, - Timestamp: pallet_timestamp, - Utility: pallet_utility, - } -); - -#[derive(Default)] -pub(crate) struct ExtBuilder; - -impl ExtBuilder { - pub(crate) fn build(self) -> sp_io::TestExternalities { - use sp_runtime::BuildStorage; - let t = frame_system::GenesisConfig::::default() - .build_storage() - .expect("Frame system builds valid default genesis config"); - - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext - } -} diff --git a/precompiles/dispatch-lockdrop/src/tests.rs b/precompiles/dispatch-lockdrop/src/tests.rs deleted file mode 100644 index 78fb95fb64..0000000000 --- a/precompiles/dispatch-lockdrop/src/tests.rs +++ /dev/null @@ -1,372 +0,0 @@ -// This file is part of Astar. - -// Copyright (C) Stake Technologies Pte.Ltd. -// SPDX-License-Identifier: GPL-3.0-or-later - -// Astar is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Astar is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Astar. If not, see . - -use core::str::from_utf8; -use frame_support::dispatch::GetDispatchInfo; -use frame_support::traits::Currency; -use libsecp256k1::PublicKeyFormat; -use sp_core::crypto::{AccountId32, Ss58Codec}; - -use crate::mock::*; - -use astar_primitives::evm::EvmAddress; -use hex_literal::hex; -use parity_scale_codec::Encode; -use precompile_utils::testing::*; -use sp_core::{ecdsa, Pair}; - -fn precompiles() -> TestPrecompileSet { - PrecompilesValue::get() -} - -#[test] -fn dispatch_calls_on_behalf_of_lockdrop_works() { - ExtBuilder.build().execute_with(|| { - // Transfer balance to Alice - let call = RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { - dest: ALICE, - value: 15 * ONE, - }); - // Sanity check - Alice holds no Balance - assert_eq!(Balances::free_balance(ALICE), 0); - - // Get Alice EVM address based on the Public Key - let alice_eth = crate::tests::eth_address(&alice_secret()); - // Get derived AccountId from the Blake2b hash of the compressed ECDSA Public key - let account_id = account_id(&alice_secret()); - // Fund this account (fund the lockdrop account) - let _ = Balances::deposit_creating(&account_id, ONE * 20); - // Get the full 64 bytes ECDSA Public key - let pubkey = crate::tests::public_key_full(&alice_secret()); - - precompiles() - .prepare_test( - alice_eth, - PRECOMPILE_ADDRESS, - PrecompileCall::dispatch_lockdrop_call { - call: call.encode().into(), - pubkey: pubkey.into(), - }, - ) - .expect_no_logs() - .execute_returns(true); - - // Get Balance of ALICE in pallet balances - assert_eq!(Balances::free_balance(ALICE), 15 * ONE); - }); -} - -#[test] -fn proper_gas_is_charged() { - ExtBuilder.build().execute_with(|| { - let call = RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { - dest: ALICE, - value: 15 * ONE, - }); - - // Dispatch a call and ensure gas is charged properly - // Expected gas is the constant weight of 1_000_000_000 and the weight of the call - // In mock one unit of ref_time us charged 1 - let expected_gas = 1_000_000_000u64 + call.get_dispatch_info().total_weight().ref_time(); - - // Get Alice EVM address based on the Public Key - let alice_eth = crate::tests::eth_address(&alice_secret()); - // Get derived AccountId from the Blake2b hash of the compressed ECDSA Public key - let account_id = account_id(&alice_secret()); - // Fund this account (fund the lockdrop account) - let _ = Balances::deposit_creating(&account_id, ONE * 20); - // Get the full 64 bytes ECDSA Public key - let pubkey = crate::tests::public_key_full(&alice_secret()); - - precompiles() - .prepare_test( - alice_eth, - PRECOMPILE_ADDRESS, - PrecompileCall::dispatch_lockdrop_call { - call: call.encode().into(), - pubkey: pubkey.into(), - }, - ) - .expect_cost(expected_gas) - .execute_returns(true); - }); -} - -#[test] -fn pubkey_does_not_match_caller_address() { - ExtBuilder.build().execute_with(|| { - // Transfer balance to Alice - let call = RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { - dest: ALICE, - value: 15 * ONE, - }); - // Sanity check - Alice holds no Balance - assert_eq!(Balances::free_balance(ALICE), 0); - - // Get Alice EVM address based on the Public Key - let alice_eth = crate::tests::eth_address(&alice_secret()); - // Dummy AccountId to sign the EIP712 payload with - let account_id = DUMMY; - // Fund this dummy account - let _ = Balances::deposit_creating(&account_id, ONE * 20); - // Create a dummy pubkey - let pubkey = [10u8; 64]; - - precompiles() - .prepare_test( - alice_eth, - PRECOMPILE_ADDRESS, - PrecompileCall::dispatch_lockdrop_call { - call: call.encode().into(), - pubkey: pubkey.into(), - }, - ) - .expect_no_logs() - .execute_reverts(|output| output == b"caller does not match the public key"); - - // Get Balance of ALICE in pallet balances and ensure it has not received any funds - assert_eq!(Balances::free_balance(ALICE), 0); - }); -} - -#[test] -fn pubkey_derive_to_proper_ss58() { - ExtBuilder.build().execute_with(|| { - // Transfer balance to Alice - let call = RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { - dest: ALICE, - value: 15 * ONE, - }); - // Sanity check - Alice holds no Balance - assert_eq!(Balances::free_balance(ALICE), 0); - - // The seed "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" - // should resolve to the SS58 address "5EGynCAEvv8NLeHx8vDMvb8hTcEcMYUMWCDQEEncNEfNWB2W" - // If we fund this account, it will be able to dispatch the Transfer call - let pair = ecdsa::Pair::from_seed(&hex!( - "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" - )); - let pubkey = crate::tests::public_key_full_from_compressed(pair.public().as_ref()); - let alice_eth = EvmAddress::from_slice(&sp_io::hashing::keccak_256(&pubkey)[12..]); - let account_id = - AccountId::from_ss58check("5EGynCAEvv8NLeHx8vDMvb8hTcEcMYUMWCDQEEncNEfNWB2W").unwrap(); - // Fund this account - let _ = Balances::deposit_creating(&account_id, ONE * 20); - - precompiles() - .prepare_test( - alice_eth, - PRECOMPILE_ADDRESS, - PrecompileCall::dispatch_lockdrop_call { - call: call.encode().into(), - pubkey: pubkey.into(), - }, - ) - .expect_no_logs() - .execute_returns(true); - - // Assert that the call (Transfer) was successful - assert_eq!(Balances::free_balance(ALICE), 15 * ONE); - }); -} - -#[test] -fn decode_limit_too_high() { - ExtBuilder.build().execute_with(|| { - let mut nested_call = - RuntimeCall::System(frame_system::Call::remark { remark: Vec::new() }); - - // More than 8 depth - for _ in 0..9 { - nested_call = RuntimeCall::Utility(pallet_utility::Call::as_derivative { - index: 0, - call: Box::new(nested_call), - }); - } - - // Get Alice EVM address based on the Public Key - let alice_eth = crate::tests::eth_address(&alice_secret()); - // Get derived AccountId from the Blake2b hash of the compressed ECDSA Public key - let account_id = account_id(&alice_secret()); - // Fund this account (fund the lockdrop account) - let _ = Balances::deposit_creating(&account_id, ONE * 20); - // Get the full 64 bytes ECDSA Public key - let pubkey = crate::tests::public_key_full(&alice_secret()); - - precompiles() - .prepare_test( - alice_eth, - PRECOMPILE_ADDRESS, - PrecompileCall::dispatch_lockdrop_call { - call: nested_call.encode().into(), - pubkey: pubkey.into(), - }, - ) - .expect_no_logs() - .execute_reverts(|output| from_utf8(output).unwrap().contains("could not decode call")); - }); -} - -#[test] -fn decode_limit_bounded() { - ExtBuilder.build().execute_with(|| { - let calls: Vec<_> = (0..681) - .map(|_| RuntimeCall::System(frame_system::Call::remark { remark: Vec::new() })) - .collect(); - let call = RuntimeCall::Utility(pallet_utility::Call::batch_all { calls }); - let out_of_bounds_calls: Vec<_> = (0..682) - .map(|_| RuntimeCall::System(frame_system::Call::remark { remark: Vec::new() })) - .collect(); - let out_of_bounds_call = RuntimeCall::Utility(pallet_utility::Call::batch_all { - calls: out_of_bounds_calls, - }); - - // Get Alice EVM address based on the Public Key - let alice_eth = crate::tests::eth_address(&alice_secret()); - // Get derived AccountId from the Blake2b hash of the compressed ECDSA Public key - let account_id = account_id(&alice_secret()); - // Fund this account (fund the lockdrop account) - let _ = Balances::deposit_creating(&account_id, ONE * 20); - // Get the full 64 bytes ECDSA Public key - let pubkey = crate::tests::public_key_full(&alice_secret()); - - precompiles() - .prepare_test( - alice_eth, - PRECOMPILE_ADDRESS, - PrecompileCall::dispatch_lockdrop_call { - call: call.encode().into(), - pubkey: pubkey.into(), - }, - ) - .expect_no_logs() - .execute_returns(true); - - precompiles() - .prepare_test( - alice_eth, - PRECOMPILE_ADDRESS, - PrecompileCall::dispatch_lockdrop_call { - call: out_of_bounds_call.encode().into(), - pubkey: pubkey.into(), - }, - ) - .expect_no_logs() - .execute_reverts(|output| output == b"call: Value is too large for length"); - }); -} - -#[test] -fn decode_limit_ok() { - ExtBuilder.build().execute_with(|| { - let mut nested_call = - RuntimeCall::System(frame_system::Call::remark { remark: Vec::new() }); - - for _ in 0..8 { - nested_call = RuntimeCall::Utility(pallet_utility::Call::as_derivative { - index: 0, - call: Box::new(nested_call), - }); - } - - // Get Alice EVM address based on the Public Key - let alice_eth = crate::tests::eth_address(&alice_secret()); - // Get derived AccountId from the Blake2b hash of the compressed ECDSA Public key - let account_id = account_id(&alice_secret()); - // Fund this account (fund the lockdrop account) - let _ = Balances::deposit_creating(&account_id, ONE * 20); - // Get the full 64 bytes ECDSA Public key - let pubkey = crate::tests::public_key_full(&alice_secret()); - - precompiles() - .prepare_test( - alice_eth, - PRECOMPILE_ADDRESS, - PrecompileCall::dispatch_lockdrop_call { - call: nested_call.encode().into(), - pubkey: pubkey.into(), - }, - ) - .expect_no_logs() - .execute_returns(true); - }); -} - -#[test] -fn only_whitelisted_calls_can_be_dispatched() { - ExtBuilder.build().execute_with(|| { - // Transfer balance to Alice - let call = RuntimeCall::System(frame_system::Call::remark_with_event { - remark: b"Hello World".to_vec(), - }); - - // Get Alice EVM address based on the Public Key - let alice_eth = crate::tests::eth_address(&alice_secret()); - // Get derived AccountId from the Blake2b hash of the compressed ECDSA Public key - let account_id = crate::tests::account_id(&alice_secret()); - // Fund this account (fund the lockdrop account) - let _ = Balances::deposit_creating(&account_id, ONE * 20); - // Get the full 64 bytes ECDSA Public key - let pubkey = crate::tests::public_key_full(&alice_secret()); - - precompiles() - .prepare_test( - alice_eth, - PRECOMPILE_ADDRESS, - PrecompileCall::dispatch_lockdrop_call { - call: call.encode().into(), - pubkey: pubkey.into(), - }, - ) - .expect_no_logs() - .execute_reverts(|output| output == b"invalid Call"); - }); -} - -fn account_id(secret: &libsecp256k1::SecretKey) -> AccountId32 { - sp_io::hashing::blake2_256( - ecdsa::Public::from_full( - &libsecp256k1::PublicKey::from_secret_key(secret).serialize()[1..65], - ) - .unwrap() - .as_ref(), - ) - .into() -} - -fn eth_address(secret: &libsecp256k1::SecretKey) -> EvmAddress { - EvmAddress::from_slice( - &sp_io::hashing::keccak_256( - &libsecp256k1::PublicKey::from_secret_key(secret).serialize()[1..65], - )[12..], - ) -} - -fn public_key_full_from_compressed(pubkey: &[u8]) -> [u8; 64] { - libsecp256k1::PublicKey::parse_slice(pubkey, Some(PublicKeyFormat::Compressed)) - .unwrap() - .serialize()[1..65] - .try_into() - .unwrap() -} - -fn public_key_full(secret: &libsecp256k1::SecretKey) -> [u8; 64] { - libsecp256k1::PublicKey::from_secret_key(secret).serialize()[1..65] - .try_into() - .unwrap() -} diff --git a/runtime/astar/Cargo.toml b/runtime/astar/Cargo.toml index 8b4a2f89c3..554c169a53 100644 --- a/runtime/astar/Cargo.toml +++ b/runtime/astar/Cargo.toml @@ -122,7 +122,6 @@ pallet-collective-proxy = { workspace = true } pallet-dapp-staking = { workspace = true } pallet-evm-precompile-assets-erc20 = { workspace = true } pallet-evm-precompile-dapp-staking = { workspace = true } -pallet-evm-precompile-dispatch-lockdrop = { workspace = true } pallet-evm-precompile-sr25519 = { workspace = true } pallet-evm-precompile-substrate-ecdsa = { workspace = true } pallet-evm-precompile-xcm = { workspace = true } @@ -196,7 +195,6 @@ std = [ "pallet-evm-precompile-blake2/std", "pallet-evm-precompile-bn128/std", "pallet-evm-precompile-dapp-staking/std", - "pallet-evm-precompile-dispatch-lockdrop/std", "pallet-evm-precompile-dispatch/std", "pallet-evm-precompile-ed25519/std", "pallet-evm-precompile-modexp/std", diff --git a/runtime/astar/src/precompiles.rs b/runtime/astar/src/precompiles.rs index 6ee6e13912..3464ff7060 100644 --- a/runtime/astar/src/precompiles.rs +++ b/runtime/astar/src/precompiles.rs @@ -26,7 +26,6 @@ use pallet_evm_precompile_blake2::Blake2F; use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; use pallet_evm_precompile_dapp_staking::DappStakingV3Precompile; use pallet_evm_precompile_dispatch::Dispatch; -use pallet_evm_precompile_dispatch_lockdrop::DispatchLockdrop; use pallet_evm_precompile_ed25519::Ed25519Verify; use pallet_evm_precompile_modexp::Modexp; use pallet_evm_precompile_sha3fips::Sha3FIPS256; @@ -35,7 +34,6 @@ use pallet_evm_precompile_sr25519::Sr25519Precompile; use pallet_evm_precompile_substrate_ecdsa::SubstrateEcdsaPrecompile; use pallet_evm_precompile_xcm::XcmPrecompile; use precompile_utils::precompile_set::*; -use sp_core::ConstU32; use sp_std::fmt::Debug; /// The asset precompile address prefix. Addresses that match against this prefix will be routed @@ -73,27 +71,6 @@ impl Contains for WhitelistedCalls { } } -/// Filter that only allows whitelisted runtime call to pass through dispatch-lockdrop precompile -pub struct WhitelistedLockdropCalls; - -impl Contains for WhitelistedLockdropCalls { - fn contains(t: &RuntimeCall) -> bool { - match t { - RuntimeCall::Utility(pallet_utility::Call::batch { calls }) - | RuntimeCall::Utility(pallet_utility::Call::batch_all { calls }) => calls - .iter() - .all(|call| WhitelistedLockdropCalls::contains(call)), - RuntimeCall::DappStaking(pallet_dapp_staking::Call::unbond_and_unstake { .. }) => true, - RuntimeCall::DappStaking(pallet_dapp_staking::Call::withdraw_unbonded { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_all { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { .. }) => true, - RuntimeCall::Assets(pallet_assets::Call::transfer { .. }) => true, - _ => false, - } - } -} - /// The PrecompileSet installed in the Astar runtime. #[precompile_utils::precompile_name_from_address] pub type AstarPrecompilesSetAt = ( @@ -144,18 +121,9 @@ pub type AstarPrecompilesSetAt = ( CallableByPrecompile, ), >, - // Skipping 20485 and 20486 to make sure all network have consistent - // precompiles address - PrecompileAt< - AddressU64<20487>, - DispatchLockdrop< - R, - DispatchFilterValidate, - ConstU32<8>, - >, - // Not callable from smart contract nor precompiled, only EOA accounts - (), - >, + // Skipping 20485 - prev. XVM precompile + // Skipping 20486 to make sure all network have consistent precompiles address + // Skipping 20487 - prev. Lockdrop precompile ); pub type AstarPrecompiles = PrecompileSetBuilder< @@ -163,8 +131,8 @@ pub type AstarPrecompiles = PrecompileSetBuilder< ( // Skip precompiles if out of range. PrecompilesInRangeInclusive< - // We take range as last precompile index, UPDATE this once new prcompile is added - (AddressU64<1>, AddressU64<20487>), + // We take range as last precompile index, UPDATE this once new precompile is added/removed + (AddressU64<1>, AddressU64<20484>), AstarPrecompilesSetAt, >, // Prefixed precompile sets (XC20) diff --git a/runtime/local/Cargo.toml b/runtime/local/Cargo.toml index 171ba21a15..092971d583 100644 --- a/runtime/local/Cargo.toml +++ b/runtime/local/Cargo.toml @@ -79,7 +79,6 @@ pallet-dapp-staking = { workspace = true } pallet-dynamic-evm-base-fee = { workspace = true } pallet-evm-precompile-assets-erc20 = { workspace = true } pallet-evm-precompile-dapp-staking = { workspace = true } -pallet-evm-precompile-dispatch-lockdrop = { workspace = true } pallet-evm-precompile-sr25519 = { workspace = true } pallet-evm-precompile-substrate-ecdsa = { workspace = true } pallet-evm-precompile-unified-accounts = { workspace = true } @@ -148,7 +147,6 @@ std = [ "pallet-evm-precompile-sr25519/std", "pallet-evm-precompile-substrate-ecdsa/std", "pallet-evm-precompile-unified-accounts/std", - "pallet-evm-precompile-dispatch-lockdrop/std", "pallet-grandpa/std", "pallet-insecure-randomness-collective-flip/std", "pallet-preimage/std", diff --git a/runtime/local/src/precompiles.rs b/runtime/local/src/precompiles.rs index 8a29d1ab7e..3903f82ace 100644 --- a/runtime/local/src/precompiles.rs +++ b/runtime/local/src/precompiles.rs @@ -20,14 +20,12 @@ use crate::{RuntimeCall, UnifiedAccounts}; use astar_primitives::precompiles::DispatchFilterValidate; -use frame_support::traits::ConstU32; use frame_support::{parameter_types, traits::Contains}; use pallet_evm_precompile_assets_erc20::Erc20AssetsPrecompileSet; use pallet_evm_precompile_blake2::Blake2F; use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; use pallet_evm_precompile_dapp_staking::DappStakingV3Precompile; use pallet_evm_precompile_dispatch::Dispatch; -use pallet_evm_precompile_dispatch_lockdrop::DispatchLockdrop; use pallet_evm_precompile_ed25519::Ed25519Verify; use pallet_evm_precompile_modexp::Modexp; use pallet_evm_precompile_sha3fips::Sha3FIPS256; @@ -70,27 +68,6 @@ impl Contains for WhitelistedCalls { } } -/// Filter that only allows whitelisted runtime call to pass through dispatch-lockdrop precompile -pub struct WhitelistedLockdropCalls; - -impl Contains for WhitelistedLockdropCalls { - fn contains(t: &RuntimeCall) -> bool { - match t { - RuntimeCall::Utility(pallet_utility::Call::batch { calls }) - | RuntimeCall::Utility(pallet_utility::Call::batch_all { calls }) => calls - .iter() - .all(|call| WhitelistedLockdropCalls::contains(call)), - RuntimeCall::DappStaking(pallet_dapp_staking::Call::unbond_and_unstake { .. }) => true, - RuntimeCall::DappStaking(pallet_dapp_staking::Call::withdraw_unbonded { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_all { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { .. }) => true, - RuntimeCall::Assets(pallet_assets::Call::transfer { .. }) => true, - _ => false, - } - } -} - /// The PrecompileSet installed in the Local runtime. #[precompile_utils::precompile_name_from_address] pub type LocalPrecompilesSetAt = ( @@ -132,22 +109,13 @@ pub type LocalPrecompilesSetAt = ( (CallableByContract, CallableByPrecompile), >, // skip 20484 for xcm precompile - // Skipping 20485 to make sure all network have consistent precompiles address + // Skipping 20485 - prev. XVM precompile PrecompileAt< AddressU64<20486>, UnifiedAccountsPrecompile, (CallableByContract, CallableByPrecompile), >, - PrecompileAt< - AddressU64<20487>, - DispatchLockdrop< - R, - DispatchFilterValidate, - ConstU32<8>, - >, - // Not callable from smart contract nor precompiled, only EOA accounts - (), - >, + // Skipping 20487 - prev. Lockdrop precompile ); pub type LocalPrecompiles = PrecompileSetBuilder< @@ -155,8 +123,8 @@ pub type LocalPrecompiles = PrecompileSetBuilder< ( // Skip precompiles if out of range. PrecompilesInRangeInclusive< - // We take range as last precompile index, UPDATE this once new precompile is added - (AddressU64<1>, AddressU64<20487>), + // We take range as last precompile index, UPDATE this once new precompile is added/removed + (AddressU64<1>, AddressU64<20486>), LocalPrecompilesSetAt, >, // Prefixed precompile sets (XC20) diff --git a/runtime/shibuya/Cargo.toml b/runtime/shibuya/Cargo.toml index 73de4d8f08..e2092c873e 100644 --- a/runtime/shibuya/Cargo.toml +++ b/runtime/shibuya/Cargo.toml @@ -117,7 +117,6 @@ pallet-dynamic-evm-base-fee = { workspace = true } pallet-ethereum-checked = { workspace = true } pallet-evm-precompile-assets-erc20 = { workspace = true } pallet-evm-precompile-dapp-staking = { workspace = true } -pallet-evm-precompile-dispatch-lockdrop = { workspace = true } pallet-evm-precompile-sr25519 = { workspace = true } pallet-evm-precompile-substrate-ecdsa = { workspace = true } pallet-evm-precompile-unified-accounts = { workspace = true } @@ -204,7 +203,6 @@ std = [ "pallet-evm-precompile-blake2/std", "pallet-evm-precompile-bn128/std", "pallet-evm-precompile-dapp-staking/std", - "pallet-evm-precompile-dispatch-lockdrop/std", "pallet-evm-precompile-dispatch/std", "pallet-evm-precompile-ed25519/std", "pallet-evm-precompile-modexp/std", diff --git a/runtime/shibuya/src/precompiles.rs b/runtime/shibuya/src/precompiles.rs index 19a4133219..6366ac7667 100644 --- a/runtime/shibuya/src/precompiles.rs +++ b/runtime/shibuya/src/precompiles.rs @@ -20,14 +20,12 @@ use crate::{RuntimeCall, UnifiedAccounts}; use astar_primitives::precompiles::DispatchFilterValidate; -use frame_support::traits::ConstU32; use frame_support::{parameter_types, traits::Contains}; use pallet_evm_precompile_assets_erc20::Erc20AssetsPrecompileSet; use pallet_evm_precompile_blake2::Blake2F; use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; use pallet_evm_precompile_dapp_staking::DappStakingV3Precompile; use pallet_evm_precompile_dispatch::Dispatch; -use pallet_evm_precompile_dispatch_lockdrop::DispatchLockdrop; use pallet_evm_precompile_ed25519::Ed25519Verify; use pallet_evm_precompile_modexp::Modexp; use pallet_evm_precompile_sha3fips::Sha3FIPS256; @@ -74,27 +72,6 @@ impl Contains for WhitelistedCalls { } } -/// Filter that only allows whitelisted runtime call to pass through dispatch-lockdrop precompile -pub struct WhitelistedLockdropCalls; - -impl Contains for WhitelistedLockdropCalls { - fn contains(t: &RuntimeCall) -> bool { - match t { - RuntimeCall::Utility(pallet_utility::Call::batch { calls }) - | RuntimeCall::Utility(pallet_utility::Call::batch_all { calls }) => calls - .iter() - .all(|call| WhitelistedLockdropCalls::contains(call)), - RuntimeCall::DappStaking(pallet_dapp_staking::Call::unbond_and_unstake { .. }) => true, - RuntimeCall::DappStaking(pallet_dapp_staking::Call::withdraw_unbonded { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_all { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { .. }) => true, - RuntimeCall::Assets(pallet_assets::Call::transfer { .. }) => true, - _ => false, - } - } -} - /// The PrecompileSet installed in the Shibuya runtime. #[precompile_utils::precompile_name_from_address] pub type ShibuyaPrecompilesSetAt = ( @@ -144,22 +121,13 @@ pub type ShibuyaPrecompilesSetAt = ( CallableByPrecompile, ), >, - // Skipping 20485 to make sure all network have consistent precompiles address + // Skipping 20485 - prev. XVM precompile PrecompileAt< AddressU64<20486>, UnifiedAccountsPrecompile, (CallableByContract, CallableByPrecompile), >, - PrecompileAt< - AddressU64<20487>, - DispatchLockdrop< - R, - DispatchFilterValidate, - ConstU32<8>, - >, - // Not callable from smart contract nor precompiled, only EOA accounts - (), - >, + // Skipping 20487 - prev. Lockdrop precompile ); pub type ShibuyaPrecompiles = PrecompileSetBuilder< @@ -167,8 +135,8 @@ pub type ShibuyaPrecompiles = PrecompileSetBuilder< ( // Skip precompiles if out of range. PrecompilesInRangeInclusive< - // TODO: what is the range for precompiles sets 1 - ? - (AddressU64<1>, AddressU64<40951>), + // We take range as last precompile index, UPDATE this once new precompile is added/removed + (AddressU64<1>, AddressU64<20486>), ShibuyaPrecompilesSetAt, >, // Prefixed precompile sets (XC20) diff --git a/runtime/shiden/Cargo.toml b/runtime/shiden/Cargo.toml index bb36231d48..c8b2c84e5a 100644 --- a/runtime/shiden/Cargo.toml +++ b/runtime/shiden/Cargo.toml @@ -116,7 +116,6 @@ pallet-collator-selection = { workspace = true } pallet-dapp-staking = { workspace = true } pallet-evm-precompile-assets-erc20 = { workspace = true } pallet-evm-precompile-dapp-staking = { workspace = true } -pallet-evm-precompile-dispatch-lockdrop = { workspace = true } pallet-evm-precompile-sr25519 = { workspace = true } pallet-evm-precompile-substrate-ecdsa = { workspace = true } pallet-evm-precompile-xcm = { workspace = true } @@ -179,7 +178,6 @@ std = [ "pallet-evm-precompile-bn128/std", "sp-genesis-builder/std", "pallet-evm-precompile-dispatch/std", - "pallet-evm-precompile-dispatch-lockdrop/std", "pallet-evm-precompile-ed25519/std", "pallet-evm-precompile-modexp/std", "xcm-runtime-apis/std", diff --git a/runtime/shiden/src/precompiles.rs b/runtime/shiden/src/precompiles.rs index d5821340eb..194dde9d3a 100644 --- a/runtime/shiden/src/precompiles.rs +++ b/runtime/shiden/src/precompiles.rs @@ -20,14 +20,12 @@ use crate::RuntimeCall; use astar_primitives::precompiles::DispatchFilterValidate; -use frame_support::pallet_prelude::ConstU32; use frame_support::{parameter_types, traits::Contains}; use pallet_evm_precompile_assets_erc20::Erc20AssetsPrecompileSet; use pallet_evm_precompile_blake2::Blake2F; use pallet_evm_precompile_bn128::{Bn128Add, Bn128Mul, Bn128Pairing}; use pallet_evm_precompile_dapp_staking::DappStakingV3Precompile; use pallet_evm_precompile_dispatch::Dispatch; -use pallet_evm_precompile_dispatch_lockdrop::DispatchLockdrop; use pallet_evm_precompile_ed25519::Ed25519Verify; use pallet_evm_precompile_modexp::Modexp; use pallet_evm_precompile_sha3fips::Sha3FIPS256; @@ -67,26 +65,6 @@ impl Contains for WhitelistedCalls { } } } -/// Filter that only allows whitelisted runtime call to pass through dispatch-lockdrop precompile -pub struct WhitelistedLockdropCalls; - -impl Contains for WhitelistedLockdropCalls { - fn contains(t: &RuntimeCall) -> bool { - match t { - RuntimeCall::Utility(pallet_utility::Call::batch { calls }) - | RuntimeCall::Utility(pallet_utility::Call::batch_all { calls }) => calls - .iter() - .all(|call| WhitelistedLockdropCalls::contains(call)), - RuntimeCall::DappStaking(pallet_dapp_staking::Call::unbond_and_unstake { .. }) => true, - RuntimeCall::DappStaking(pallet_dapp_staking::Call::withdraw_unbonded { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_all { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { .. }) => true, - RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { .. }) => true, - RuntimeCall::Assets(pallet_assets::Call::transfer { .. }) => true, - _ => false, - } - } -} /// The PrecompileSet installed in the Shiden runtime. #[precompile_utils::precompile_name_from_address] @@ -137,18 +115,9 @@ pub type ShidenPrecompilesSetAt = ( CallableByPrecompile, ), >, - // Skipping 20485 and 20486 to make sure all network have consistent - // precompiles address - PrecompileAt< - AddressU64<20487>, - DispatchLockdrop< - R, - DispatchFilterValidate, - ConstU32<8>, - >, - // Not callable from smart contract nor precompiled, only EOA accounts - (), - >, + // Skipping 20485 - prev. XVM precompile + // Skipping 20486 to make sure all network have consistent precompiles address + // Skipping 20487 - prev. Lockdrop precompile ); pub type ShidenPrecompiles = PrecompileSetBuilder< @@ -156,8 +125,8 @@ pub type ShidenPrecompiles = PrecompileSetBuilder< ( // Skip precompiles if out of range. PrecompilesInRangeInclusive< - // We take range as last precompile index, UPDATE this once new prcompile is added - (AddressU64<1>, AddressU64<20487>), + // We take range as last precompile index, UPDATE this once new precompile is added/removed + (AddressU64<1>, AddressU64<20484>), ShidenPrecompilesSetAt, >, // Prefixed precompile sets (XC20) From 86dc62818e1de7c8080ffe9c6dc4fe51e3f28d14 Mon Sep 17 00:00:00 2001 From: Igor Papandinas <26460174+ipapandinas@users.noreply.github.com> Date: Mon, 29 Dec 2025 17:20:00 +0100 Subject: [PATCH 2/3] use revert for disabled precompiles --- Cargo.lock | 1 + primitives/Cargo.toml | 1 + primitives/src/precompiles.rs | 13 ++++++++++++- runtime/astar/src/precompiles.rs | 19 ++++++++++++++++--- runtime/local/src/precompiles.rs | 19 ++++++++++++++++--- runtime/shibuya/src/precompiles.rs | 19 ++++++++++++++++--- runtime/shiden/src/precompiles.rs | 19 ++++++++++++++++--- 7 files changed, 78 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3108027911..953ae15633 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -969,6 +969,7 @@ dependencies = [ "pallet-treasury 37.0.0", "pallet-xc-asset-config", "parity-scale-codec", + "precompile-utils", "scale-info", "sp-arithmetic", "sp-core", diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 2735d38435..cd201fc949 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -20,6 +20,7 @@ scale-info = { workspace = true } ethereum = { workspace = true, features = ["with-scale"] } ethereum-types = { workspace = true } fp-evm = { workspace = true } +precompile-utils = { workspace = true, default-features = false } # Substrate dependencies frame-support = { workspace = true } diff --git a/primitives/src/precompiles.rs b/primitives/src/precompiles.rs index 84184399a9..0259f630d0 100644 --- a/primitives/src/precompiles.rs +++ b/primitives/src/precompiles.rs @@ -18,11 +18,12 @@ use core::marker::PhantomData; -use fp_evm::{ExitError, PrecompileFailure}; +use fp_evm::{ExitError, Precompile, PrecompileFailure, PrecompileHandle, PrecompileResult}; use frame_support::{ dispatch::{DispatchClass, GetDispatchInfo, Pays}, traits::Contains, }; +use precompile_utils::prelude::*; use pallet_evm_precompile_dispatch::DispatchValidateT; /// Struct that allows only calls based on `Filter` to pass through. @@ -53,3 +54,13 @@ impl> } } } + + +/// A minimal precompile that always reverts +pub struct DisabledPrecompile(PhantomData); + +impl Precompile for DisabledPrecompile { + fn execute(_handle: &mut impl PrecompileHandle) -> PrecompileResult { + Err(revert("This precompile has been disabled")) + } +} \ No newline at end of file diff --git a/runtime/astar/src/precompiles.rs b/runtime/astar/src/precompiles.rs index 806928872a..fcba9cf19e 100644 --- a/runtime/astar/src/precompiles.rs +++ b/runtime/astar/src/precompiles.rs @@ -19,7 +19,7 @@ //! The Astar Network EVM precompiles. This can be compiled with ``#[no_std]`, ready for Wasm. use crate::{Runtime, RuntimeCall}; -use astar_primitives::precompiles::DispatchFilterValidate; +use astar_primitives::precompiles::{DisabledPrecompile, DispatchFilterValidate}; use frame_support::{parameter_types, traits::Contains}; use pallet_evm_precompile_assets_erc20::Erc20AssetsPrecompileSet; use pallet_evm_precompile_blake2::Blake2F; @@ -71,6 +71,11 @@ impl Contains for WhitelistedCalls { } } +// Type aliases to avoid name collision in the precompile_name_from_address macro +// when the same deprecated precompile is used at multiple addresses +type DisabledXvmPrecompile = DisabledPrecompile; +type DisabledLockdropPrecompile = DisabledPrecompile; + /// The PrecompileSet installed in the Astar runtime. #[precompile_utils::precompile_name_from_address] pub type AstarPrecompilesSetAt = ( @@ -125,9 +130,17 @@ pub type AstarPrecompilesSetAt = ( CallableByPrecompile, ), >, - // Skipping 20485 - prev. XVM precompile + PrecompileAt< + AddressU64<20485>, + DisabledXvmPrecompile, + (), + >, // Skipping 20486 to make sure all network have consistent precompiles address - // Skipping 20487 - prev. Lockdrop precompile + PrecompileAt< + AddressU64<20487>, + DisabledLockdropPrecompile, + (), + >, ); pub type AstarPrecompiles = PrecompileSetBuilder< diff --git a/runtime/local/src/precompiles.rs b/runtime/local/src/precompiles.rs index a9cb7920e4..1809c07ea0 100644 --- a/runtime/local/src/precompiles.rs +++ b/runtime/local/src/precompiles.rs @@ -19,7 +19,7 @@ //! The Local Network EVM precompiles. This can be compiled with ``#[no_std]`, ready for Wasm. use crate::{Runtime, RuntimeCall, UnifiedAccounts}; -use astar_primitives::precompiles::DispatchFilterValidate; +use astar_primitives::precompiles::{DisabledPrecompile, DispatchFilterValidate}; use frame_support::{parameter_types, traits::Contains}; use pallet_evm_precompile_assets_erc20::Erc20AssetsPrecompileSet; use pallet_evm_precompile_blake2::Blake2F; @@ -68,6 +68,11 @@ impl Contains for WhitelistedCalls { } } +// Type aliases to avoid name collision in the precompile_name_from_address macro +// when the same deprecated precompile is used at multiple addresses +type DisabledXvmPrecompile = DisabledPrecompile; +type DisabledLockdropPrecompile = DisabledPrecompile; + /// The PrecompileSet installed in the Local runtime. #[precompile_utils::precompile_name_from_address] pub type LocalPrecompilesSetAt = ( @@ -113,13 +118,21 @@ pub type LocalPrecompilesSetAt = ( (CallableByContract, CallableByPrecompile), >, // skip 20484 for xcm precompile - // Skipping 20485 - prev. XVM precompile + PrecompileAt< + AddressU64<20485>, + DisabledXvmPrecompile, + (), + >, PrecompileAt< AddressU64<20486>, UnifiedAccountsPrecompile, (CallableByContract, CallableByPrecompile), >, - // Skipping 20487 - prev. Lockdrop precompile + PrecompileAt< + AddressU64<20487>, + DisabledLockdropPrecompile, + (), + >, ); pub type LocalPrecompiles = PrecompileSetBuilder< diff --git a/runtime/shibuya/src/precompiles.rs b/runtime/shibuya/src/precompiles.rs index 6041e3dc12..f3d1129acc 100644 --- a/runtime/shibuya/src/precompiles.rs +++ b/runtime/shibuya/src/precompiles.rs @@ -19,7 +19,7 @@ //! The Astar Network EVM precompiles. This can be compiled with ``#[no_std]`, ready for Wasm. use crate::{Runtime, RuntimeCall, UnifiedAccounts}; -use astar_primitives::precompiles::DispatchFilterValidate; +use astar_primitives::precompiles::{DisabledPrecompile, DispatchFilterValidate}; use frame_support::{parameter_types, traits::Contains}; use pallet_evm_precompile_assets_erc20::Erc20AssetsPrecompileSet; use pallet_evm_precompile_blake2::Blake2F; @@ -72,6 +72,11 @@ impl Contains for WhitelistedCalls { } } +// Type aliases to avoid name collision in the precompile_name_from_address macro +// when the same deprecated precompile is used at multiple addresses +type DisabledXvmPrecompile = DisabledPrecompile; +type DisabledLockdropPrecompile = DisabledPrecompile; + /// The PrecompileSet installed in the Shibuya runtime. #[precompile_utils::precompile_name_from_address] pub type ShibuyaPrecompilesSetAt = ( @@ -125,13 +130,21 @@ pub type ShibuyaPrecompilesSetAt = ( CallableByPrecompile, ), >, - // Skipping 20485 - prev. XVM precompile + PrecompileAt< + AddressU64<20485>, + DisabledXvmPrecompile, + (), + >, PrecompileAt< AddressU64<20486>, UnifiedAccountsPrecompile, (CallableByContract, CallableByPrecompile), >, - // Skipping 20487 - prev. Lockdrop precompile + PrecompileAt< + AddressU64<20487>, + DisabledLockdropPrecompile, + (), + >, ); pub type ShibuyaPrecompiles = PrecompileSetBuilder< diff --git a/runtime/shiden/src/precompiles.rs b/runtime/shiden/src/precompiles.rs index 87af4ffe9a..5a98809e94 100644 --- a/runtime/shiden/src/precompiles.rs +++ b/runtime/shiden/src/precompiles.rs @@ -19,7 +19,7 @@ //! The Shiden Network EVM precompiles. This can be compiled with ``#[no_std]`, ready for Wasm. use crate::{Runtime, RuntimeCall}; -use astar_primitives::precompiles::DispatchFilterValidate; +use astar_primitives::precompiles::{DisabledPrecompile, DispatchFilterValidate}; use frame_support::{parameter_types, traits::Contains}; use pallet_evm_precompile_assets_erc20::Erc20AssetsPrecompileSet; use pallet_evm_precompile_blake2::Blake2F; @@ -66,6 +66,11 @@ impl Contains for WhitelistedCalls { } } +// Type aliases to avoid name collision in the precompile_name_from_address macro +// when the same deprecated precompile is used at multiple addresses +type DisabledXvmPrecompile = DisabledPrecompile; +type DisabledLockdropPrecompile = DisabledPrecompile; + /// The PrecompileSet installed in the Shiden runtime. #[precompile_utils::precompile_name_from_address] pub type ShidenPrecompilesSetAt = ( @@ -119,9 +124,17 @@ pub type ShidenPrecompilesSetAt = ( CallableByPrecompile, ), >, - // Skipping 20485 - prev. XVM precompile + PrecompileAt< + AddressU64<20485>, + DisabledXvmPrecompile, + (), + >, // Skipping 20486 to make sure all network have consistent precompiles address - // Skipping 20487 - prev. Lockdrop precompile + PrecompileAt< + AddressU64<20487>, + DisabledLockdropPrecompile, + (), + >, ); pub type ShidenPrecompiles = PrecompileSetBuilder< From b2f040af9a0272bf71064458040c48dea7484f8f Mon Sep 17 00:00:00 2001 From: Igor Papandinas <26460174+ipapandinas@users.noreply.github.com> Date: Mon, 29 Dec 2025 17:33:30 +0100 Subject: [PATCH 3/3] make CI happy --- primitives/Cargo.toml | 1 + primitives/src/precompiles.rs | 5 ++--- runtime/astar/src/precompiles.rs | 12 ++---------- runtime/local/src/precompiles.rs | 12 ++---------- runtime/shibuya/src/precompiles.rs | 12 ++---------- runtime/shiden/src/precompiles.rs | 12 ++---------- 6 files changed, 11 insertions(+), 43 deletions(-) diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index cd201fc949..7f0808cca4 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -71,6 +71,7 @@ std = [ "frame-system/std", "pallet-membership/std", "pallet-collective/std", + "precompile-utils/std", "sp-std/std", "sp-runtime/std", "sp-core/std", diff --git a/primitives/src/precompiles.rs b/primitives/src/precompiles.rs index 0259f630d0..04a45242e5 100644 --- a/primitives/src/precompiles.rs +++ b/primitives/src/precompiles.rs @@ -23,8 +23,8 @@ use frame_support::{ dispatch::{DispatchClass, GetDispatchInfo, Pays}, traits::Contains, }; -use precompile_utils::prelude::*; use pallet_evm_precompile_dispatch::DispatchValidateT; +use precompile_utils::prelude::*; /// Struct that allows only calls based on `Filter` to pass through. pub struct DispatchFilterValidate>( @@ -55,7 +55,6 @@ impl> } } - /// A minimal precompile that always reverts pub struct DisabledPrecompile(PhantomData); @@ -63,4 +62,4 @@ impl Precompile for DisabledPrecompile { fn execute(_handle: &mut impl PrecompileHandle) -> PrecompileResult { Err(revert("This precompile has been disabled")) } -} \ No newline at end of file +} diff --git a/runtime/astar/src/precompiles.rs b/runtime/astar/src/precompiles.rs index fcba9cf19e..c9e988ff0d 100644 --- a/runtime/astar/src/precompiles.rs +++ b/runtime/astar/src/precompiles.rs @@ -130,17 +130,9 @@ pub type AstarPrecompilesSetAt = ( CallableByPrecompile, ), >, - PrecompileAt< - AddressU64<20485>, - DisabledXvmPrecompile, - (), - >, + PrecompileAt, DisabledXvmPrecompile, ()>, // Skipping 20486 to make sure all network have consistent precompiles address - PrecompileAt< - AddressU64<20487>, - DisabledLockdropPrecompile, - (), - >, + PrecompileAt, DisabledLockdropPrecompile, ()>, ); pub type AstarPrecompiles = PrecompileSetBuilder< diff --git a/runtime/local/src/precompiles.rs b/runtime/local/src/precompiles.rs index 1809c07ea0..68cbd14937 100644 --- a/runtime/local/src/precompiles.rs +++ b/runtime/local/src/precompiles.rs @@ -118,21 +118,13 @@ pub type LocalPrecompilesSetAt = ( (CallableByContract, CallableByPrecompile), >, // skip 20484 for xcm precompile - PrecompileAt< - AddressU64<20485>, - DisabledXvmPrecompile, - (), - >, + PrecompileAt, DisabledXvmPrecompile, ()>, PrecompileAt< AddressU64<20486>, UnifiedAccountsPrecompile, (CallableByContract, CallableByPrecompile), >, - PrecompileAt< - AddressU64<20487>, - DisabledLockdropPrecompile, - (), - >, + PrecompileAt, DisabledLockdropPrecompile, ()>, ); pub type LocalPrecompiles = PrecompileSetBuilder< diff --git a/runtime/shibuya/src/precompiles.rs b/runtime/shibuya/src/precompiles.rs index f3d1129acc..eafc04b7d2 100644 --- a/runtime/shibuya/src/precompiles.rs +++ b/runtime/shibuya/src/precompiles.rs @@ -130,21 +130,13 @@ pub type ShibuyaPrecompilesSetAt = ( CallableByPrecompile, ), >, - PrecompileAt< - AddressU64<20485>, - DisabledXvmPrecompile, - (), - >, + PrecompileAt, DisabledXvmPrecompile, ()>, PrecompileAt< AddressU64<20486>, UnifiedAccountsPrecompile, (CallableByContract, CallableByPrecompile), >, - PrecompileAt< - AddressU64<20487>, - DisabledLockdropPrecompile, - (), - >, + PrecompileAt, DisabledLockdropPrecompile, ()>, ); pub type ShibuyaPrecompiles = PrecompileSetBuilder< diff --git a/runtime/shiden/src/precompiles.rs b/runtime/shiden/src/precompiles.rs index 5a98809e94..dcbbc33227 100644 --- a/runtime/shiden/src/precompiles.rs +++ b/runtime/shiden/src/precompiles.rs @@ -124,17 +124,9 @@ pub type ShidenPrecompilesSetAt = ( CallableByPrecompile, ), >, - PrecompileAt< - AddressU64<20485>, - DisabledXvmPrecompile, - (), - >, + PrecompileAt, DisabledXvmPrecompile, ()>, // Skipping 20486 to make sure all network have consistent precompiles address - PrecompileAt< - AddressU64<20487>, - DisabledLockdropPrecompile, - (), - >, + PrecompileAt, DisabledLockdropPrecompile, ()>, ); pub type ShidenPrecompiles = PrecompileSetBuilder<