From 761009a84e674b0430997ca2f9ab0e334972a49c Mon Sep 17 00:00:00 2001 From: open-junius Date: Mon, 2 Jun 2025 21:11:57 +0800 Subject: [PATCH 1/8] pre fund contract --- frame/evm/precompile/dispatch/src/lib.rs | 4 +- frame/evm/src/lib.rs | 59 +++++++++++++++++++++++- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/frame/evm/precompile/dispatch/src/lib.rs b/frame/evm/precompile/dispatch/src/lib.rs index b7be946b93..31c8aa8c2f 100644 --- a/frame/evm/precompile/dispatch/src/lib.rs +++ b/frame/evm/precompile/dispatch/src/lib.rs @@ -38,8 +38,8 @@ use frame_support::{ use sp_runtime::traits::Dispatchable; // Frontier use fp_evm::{ - ExitError, ExitSucceed, Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput, - PrecompileResult, + ExitError, ExitSucceed, LinearCostPrecompile, Precompile, PrecompileFailure, PrecompileHandle, + PrecompileOutput, PrecompileResult, }; use pallet_evm::{AddressMapping, GasWeightMapping}; diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index f8fa9913a2..254f76e57e 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -79,6 +79,7 @@ use scale_info::TypeInfo; // Substrate use frame_support::{ dispatch::{DispatchResultWithPostInfo, Pays, PostDispatchInfo}, + ensure, storage::{child::KillStorageResult, KeyPrefixIterator}, traits::{ fungible::{Balanced, Credit, Debt}, @@ -308,8 +309,33 @@ pub mod pallet { nonce: Option, access_list: Vec<(H160, Vec)>, ) -> DispatchResultWithPostInfo { + // let who = ensure_signed(origin.clone())?; T::CallOrigin::ensure_address_origin(&source, origin)?; + // let mini_balance = >::minimum_balance(); + Self::ensure_balance_for_contract_creation(&source)?; + // let balance = Self::account_basic(&source); + + // // if balance.0.balance; + // let mini_balance = ::AccountId, + // >>::minimum_balance(); + + // let mini_balance_origin = mini_balance; + + // let mini_balance = SubstrateBalance::from( + // UniqueSaturatedInto::::unique_saturated_into(mini_balance), + // ); + + // // let mini_balance_u64: u64 = mini_balance.into_u64_saturating(); + + // let mini_balance = T::BalanceConverter::into_evm_balance(mini_balance) + // .unwrap_or(EvmBalance::from(0u64)); + + // if balance.0.balance < mini_balance.0 { + // return Err(Error::::BalanceLow.into()); + // } + let whitelist = >::get(); let whitelist_disabled = >::get(); let is_transactional = true; @@ -349,6 +375,15 @@ pub mod pallet { value: create_address, .. } => { + let mini_balance = ::AccountId, + >>::minimum_balance(); + T::Currency::transfer( + &T::AddressMapping::into_account_id(source), + &T::AddressMapping::into_account_id(create_address), + mini_balance, + ExistenceRequirement::AllowDeath, + )?; Pallet::::deposit_event(Event::::Created { address: create_address, }); @@ -400,6 +435,7 @@ pub mod pallet { access_list: Vec<(H160, Vec)>, ) -> DispatchResultWithPostInfo { T::CallOrigin::ensure_address_origin(&source, origin)?; + Self::ensure_balance_for_contract_creation(&source)?; let whitelist = >::get(); let whitelist_disabled = >::get(); @@ -441,6 +477,15 @@ pub mod pallet { value: create_address, .. } => { + let mini_balance = ::AccountId, + >>::minimum_balance(); + T::Currency::transfer( + &T::AddressMapping::into_account_id(source), + &T::AddressMapping::into_account_id(create_address), + mini_balance, + ExistenceRequirement::AllowDeath, + )?; Pallet::::deposit_event(Event::::Created { address: create_address, }); @@ -952,7 +997,7 @@ impl Pallet { T::Currency::reducible_balance(&account_id, Preservation::Preserve, Fortitude::Polite); let balance_sub = SubstrateBalance::from(UniqueSaturatedInto::::unique_saturated_into(balance)); - let balance_eth = + let balance_eth: EvmBalance = T::BalanceConverter::into_evm_balance(balance_sub).unwrap_or(EvmBalance::from(0u64)); ( @@ -971,6 +1016,18 @@ impl Pallet { T::FindAuthor::find_author(pre_runtime_digests).unwrap_or_default() } + + /// Ensure balance to pre fund contract creation. + pub fn ensure_balance_for_contract_creation(source: &H160) -> DispatchResultWithPostInfo { + let account_id = T::AddressMapping::into_account_id(*source); + let balance = + T::Currency::reducible_balance(&account_id, Preservation::Preserve, Fortitude::Polite); + + let mini_balance = >::minimum_balance(); + + ensure!(balance >= mini_balance, Error::::BalanceLow); + Ok(().into()) + } } /// Handle withdrawing, refunding and depositing of transaction fees. From 4888f8b3fbd3702a8859df99f2fd6497b298acf6 Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 3 Jun 2025 08:09:03 +0800 Subject: [PATCH 2/8] compile is ok --- frame/evm/precompile/dispatch/src/lib.rs | 4 +- frame/evm/src/lib.rs | 76 ++++++++++-------------- 2 files changed, 32 insertions(+), 48 deletions(-) diff --git a/frame/evm/precompile/dispatch/src/lib.rs b/frame/evm/precompile/dispatch/src/lib.rs index 02ec42ad34..7f169e612f 100644 --- a/frame/evm/precompile/dispatch/src/lib.rs +++ b/frame/evm/precompile/dispatch/src/lib.rs @@ -38,8 +38,8 @@ use frame_support::{ use sp_runtime::traits::Dispatchable; // Frontier use fp_evm::{ - ExitError, ExitSucceed, LinearCostPrecompile, Precompile, PrecompileFailure, PrecompileHandle, - PrecompileOutput, PrecompileResult, + ExitError, ExitSucceed, Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput, + PrecompileResult, }; use pallet_evm::{AddressMapping, GasWeightMapping}; diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index 79587fc138..f651dd8b7b 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -79,6 +79,7 @@ use scale_info::TypeInfo; // Substrate use frame_support::{ dispatch::{DispatchResultWithPostInfo, Pays, PostDispatchInfo}, + ensure, storage::KeyPrefixIterator, traits::{ fungible::{Balanced, Credit, Debt}, @@ -103,9 +104,8 @@ use fp_account::AccountId20; use fp_evm::GenesisAccount; pub use fp_evm::{ Account, AccountProvider, CallInfo, CreateInfo, ExecutionInfoV2 as ExecutionInfo, - FeeCalculator, IsPrecompileResult, LinearCostPrecompile, Log, Precompile, PrecompileFailure, - PrecompileHandle, PrecompileOutput, PrecompileResult, PrecompileSet, - TransactionValidationError, Vicinity, + FeeCalculator, IsPrecompileResult, Log, Precompile, PrecompileFailure, PrecompileHandle, + PrecompileOutput, PrecompileResult, PrecompileSet, TransactionValidationError, Vicinity, }; pub use self::{ @@ -404,30 +404,7 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { // let who = ensure_signed(origin.clone())?; T::CallOrigin::ensure_address_origin(&source, origin)?; - - // let mini_balance = >::minimum_balance(); Self::ensure_balance_for_contract_creation(&source)?; - // let balance = Self::account_basic(&source); - - // // if balance.0.balance; - // let mini_balance = ::AccountId, - // >>::minimum_balance(); - - // let mini_balance_origin = mini_balance; - - // let mini_balance = SubstrateBalance::from( - // UniqueSaturatedInto::::unique_saturated_into(mini_balance), - // ); - - // // let mini_balance_u64: u64 = mini_balance.into_u64_saturating(); - - // let mini_balance = T::BalanceConverter::into_evm_balance(mini_balance) - // .unwrap_or(EvmBalance::from(0u64)); - - // if balance.0.balance < mini_balance.0 { - // return Err(Error::::BalanceLow.into()); - // } let whitelist = >::get(); let whitelist_disabled = >::get(); @@ -468,14 +445,15 @@ pub mod pallet { value: create_address, .. } => { - // T::Currency::minimum_balance(); - - // T::Currency::transfer( - // &T::AddressMapping::into_account_id(source), - // &T::AddressMapping::into_account_id(create_address), - // mini_balance, - // ExistenceRequirement::AllowDeath, - // )?; + let mini_balance = <::Currency as Currency< + <::AccountProvider as AccountProvider>::AccountId, + >>::minimum_balance(); + T::Currency::transfer( + &T::AddressMapping::into_account_id(source), + &T::AddressMapping::into_account_id(create_address), + mini_balance, + ExistenceRequirement::AllowDeath, + )?; Pallet::::deposit_event(Event::::Created { address: create_address, }); @@ -527,7 +505,7 @@ pub mod pallet { access_list: Vec<(H160, Vec)>, ) -> DispatchResultWithPostInfo { T::CallOrigin::ensure_address_origin(&source, origin)?; - // Self::ensure_balance_for_contract_creation(&source)?; + Self::ensure_balance_for_contract_creation(&source)?; let whitelist = >::get(); let whitelist_disabled = >::get(); @@ -569,15 +547,15 @@ pub mod pallet { value: create_address, .. } => { - // let mini_balance = ::AccountId, - // >>::minimum_balance(); - // T::Currency::transfer( - // &T::AddressMapping::into_account_id(source), - // &T::AddressMapping::into_account_id(create_address), - // mini_balance, - // ExistenceRequirement::AllowDeath, - // )?; + let mini_balance = <::Currency as Currency< + <::AccountProvider as AccountProvider>::AccountId, + >>::minimum_balance(); + T::Currency::transfer( + &T::AddressMapping::into_account_id(source), + &T::AddressMapping::into_account_id(create_address), + mini_balance, + ExistenceRequirement::AllowDeath, + )?; Pallet::::deposit_event(Event::::Created { address: create_address, }); @@ -1097,9 +1075,15 @@ impl Pallet { let balance = T::Currency::reducible_balance(&account_id, Preservation::Preserve, Fortitude::Polite); - // let mini_balance = >::minimum_balance(); + let balance = UniqueSaturatedInto::::unique_saturated_into(balance); + + let mini_balance = <::Currency as Currency< + <::AccountProvider as AccountProvider>::AccountId, + >>::minimum_balance(); + + let mini_balance = UniqueSaturatedInto::::unique_saturated_into(mini_balance); - // ensure!(balance >= mini_balance, Error::::BalanceLow); + ensure!(balance >= mini_balance, Error::::BalanceLow); Ok(().into()) } } From 254f185a0d35b03d02bdfd17254557de624da39c Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 6 Jun 2025 21:29:04 +0800 Subject: [PATCH 3/8] impl done --- frame/evm/src/lib.rs | 32 ++++++++++++++++++++++-- frame/evm/src/runner/stack.rs | 46 ++++++++++++++++++++++++++++++++--- 2 files changed, 72 insertions(+), 6 deletions(-) diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index f651dd8b7b..d5d29131d9 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -654,6 +654,10 @@ pub mod pallet { Undefined, /// Origin is not allowed to perform the operation. NotAllowed, + /// Not enough balance to pay existential deposit + BalanceLowForExistentialDeposit, + /// Token transfer to new contract failed + TransferToNewContractFailed, } impl From for Error { @@ -1070,7 +1074,10 @@ impl Pallet { } /// Ensure balance to pre fund contract creation. - pub fn ensure_balance_for_contract_creation(source: &H160) -> DispatchResultWithPostInfo { + pub fn ensure_balance_for_contract_creation( + source: &H160, + // ) -> Result<(), sp_runtime::DispatchError> { + ) -> Result<(), Error> { let account_id = T::AddressMapping::into_account_id(*source); let balance = T::Currency::reducible_balance(&account_id, Preservation::Preserve, Fortitude::Polite); @@ -1083,9 +1090,30 @@ impl Pallet { let mini_balance = UniqueSaturatedInto::::unique_saturated_into(mini_balance); - ensure!(balance >= mini_balance, Error::::BalanceLow); + ensure!( + balance >= mini_balance, + Error::::BalanceLowForExistentialDeposit + ); Ok(().into()) } + + /// transfer existential deposit to new contract + pub fn transfer_minimal_to_new_contract( + source: &H160, + create_address: &H160, + ) -> Result<(), Error> { + let mini_balance = <::Currency as Currency< + <::AccountProvider as AccountProvider>::AccountId, + >>::minimum_balance(); + T::Currency::transfer( + &T::AddressMapping::into_account_id(*source), + &T::AddressMapping::into_account_id(*create_address), + mini_balance, + ExistenceRequirement::AllowDeath, + ) + .map_err(|_| Error::::TransferToNewContractFailed)?; + Ok(()) + } } /// Handle withdrawing, refunding and depositing of transaction fees. diff --git a/frame/evm/src/runner/stack.rs b/frame/evm/src/runner/stack.rs index cc713017eb..6cd5acec4c 100644 --- a/frame/evm/src/runner/stack.rs +++ b/frame/evm/src/runner/stack.rs @@ -526,6 +526,10 @@ where proof_size_base_cost: Option, config: &evm::Config, ) -> Result> { + Pallet::::ensure_balance_for_contract_creation(&source).map_err(|_| RunnerError { + error: Error::::BalanceLow, + weight: Weight::default(), + })?; if validate { if !disable_whitelist_check && !whitelist.contains(&source) { return Err(RunnerError { @@ -551,7 +555,7 @@ where )?; } let precompiles = T::PrecompilesValue::get(); - Self::execute( + let result = Self::execute( source, value, gas_limit, @@ -569,7 +573,22 @@ where executor.transact_create(source, value, init, gas_limit, access_list); (reason, address) }, - ) + ); + if let Ok(create_info) = &result { + match create_info { + CreateInfo { + exit_reason: ExitReason::Succeed(_), + value: create_address, + .. + } => Pallet::::transfer_minimal_to_new_contract(&source, &create_address) + .map_err(|_| RunnerError { + error: Error::::BalanceLow, + weight: Weight::default(), + })?, + _ => {} + } + } + result } fn create2( @@ -590,6 +609,10 @@ where proof_size_base_cost: Option, config: &evm::Config, ) -> Result> { + Pallet::::ensure_balance_for_contract_creation(&source).map_err(|_| RunnerError { + error: Error::::BalanceLow, + weight: Weight::default(), + })?; if validate { if !disable_whitelist_check && !whitelist.contains(&source) { return Err(RunnerError { @@ -616,7 +639,7 @@ where } let precompiles = T::PrecompilesValue::get(); let code_hash = H256::from(sp_io::hashing::keccak_256(&init)); - Self::execute( + let result = Self::execute( source, value, gas_limit, @@ -638,7 +661,22 @@ where executor.transact_create2(source, value, init, salt, gas_limit, access_list); (reason, address) }, - ) + ); + if let Ok(create_info) = &result { + match create_info { + CreateInfo { + exit_reason: ExitReason::Succeed(_), + value: create_address, + .. + } => Pallet::::transfer_minimal_to_new_contract(&source, &create_address) + .map_err(|_| RunnerError { + error: Error::::BalanceLow, + weight: Weight::default(), + })?, + _ => {} + } + } + result } } From 46612e6222f1acdcd0fdacd82012292495e67413 Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 6 Jun 2025 21:51:40 +0800 Subject: [PATCH 4/8] fix lint --- frame/evm/src/lib.rs | 2 +- frame/evm/src/runner/stack.rs | 38 ++++++++++++++++++----------------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index d5d29131d9..9da34f9660 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -1094,7 +1094,7 @@ impl Pallet { balance >= mini_balance, Error::::BalanceLowForExistentialDeposit ); - Ok(().into()) + Ok(()) } /// transfer existential deposit to new contract diff --git a/frame/evm/src/runner/stack.rs b/frame/evm/src/runner/stack.rs index 6cd5acec4c..e8f9676007 100644 --- a/frame/evm/src/runner/stack.rs +++ b/frame/evm/src/runner/stack.rs @@ -575,17 +575,18 @@ where }, ); if let Ok(create_info) = &result { - match create_info { - CreateInfo { - exit_reason: ExitReason::Succeed(_), - value: create_address, - .. - } => Pallet::::transfer_minimal_to_new_contract(&source, &create_address) - .map_err(|_| RunnerError { + if let CreateInfo { + exit_reason: ExitReason::Succeed(_), + value: create_address, + .. + } = create_info + { + Pallet::::transfer_minimal_to_new_contract(&source, create_address).map_err( + |_| RunnerError { error: Error::::BalanceLow, weight: Weight::default(), - })?, - _ => {} + }, + )?; } } result @@ -663,17 +664,18 @@ where }, ); if let Ok(create_info) = &result { - match create_info { - CreateInfo { - exit_reason: ExitReason::Succeed(_), - value: create_address, - .. - } => Pallet::::transfer_minimal_to_new_contract(&source, &create_address) - .map_err(|_| RunnerError { + if let CreateInfo { + exit_reason: ExitReason::Succeed(_), + value: create_address, + .. + } = create_info + { + Pallet::::transfer_minimal_to_new_contract(&source, create_address).map_err( + |_| RunnerError { error: Error::::BalanceLow, weight: Weight::default(), - })?, - _ => {} + }, + )?; } } result From daadb004d6515c48f28c4bd4fa9672755e80789d Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 6 Jun 2025 21:55:17 +0800 Subject: [PATCH 5/8] fix all clippy --- frame/evm/src/runner/stack.rs | 52 ++++++++++++++++------------------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/frame/evm/src/runner/stack.rs b/frame/evm/src/runner/stack.rs index e8f9676007..e6d0e256d7 100644 --- a/frame/evm/src/runner/stack.rs +++ b/frame/evm/src/runner/stack.rs @@ -574,20 +574,18 @@ where (reason, address) }, ); - if let Ok(create_info) = &result { - if let CreateInfo { - exit_reason: ExitReason::Succeed(_), - value: create_address, - .. - } = create_info - { - Pallet::::transfer_minimal_to_new_contract(&source, create_address).map_err( - |_| RunnerError { - error: Error::::BalanceLow, - weight: Weight::default(), - }, - )?; - } + if let Ok(CreateInfo { + exit_reason: ExitReason::Succeed(_), + value: create_address, + .. + }) = &result + { + Pallet::::transfer_minimal_to_new_contract(&source, create_address).map_err( + |_| RunnerError { + error: Error::::BalanceLow, + weight: Weight::default(), + }, + )?; } result } @@ -663,20 +661,18 @@ where (reason, address) }, ); - if let Ok(create_info) = &result { - if let CreateInfo { - exit_reason: ExitReason::Succeed(_), - value: create_address, - .. - } = create_info - { - Pallet::::transfer_minimal_to_new_contract(&source, create_address).map_err( - |_| RunnerError { - error: Error::::BalanceLow, - weight: Weight::default(), - }, - )?; - } + if let Ok(CreateInfo { + exit_reason: ExitReason::Succeed(_), + value: create_address, + .. + }) = &result + { + Pallet::::transfer_minimal_to_new_contract(&source, create_address).map_err( + |_| RunnerError { + error: Error::::BalanceLow, + weight: Weight::default(), + }, + )?; } result } From 02c154a779ac8990df821050935c9dc107d63048 Mon Sep 17 00:00:00 2001 From: open-junius Date: Wed, 11 Jun 2025 15:55:31 +0800 Subject: [PATCH 6/8] remove commented code --- frame/evm/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index 9da34f9660..e2ef7e60f8 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -402,7 +402,6 @@ pub mod pallet { nonce: Option, access_list: Vec<(H160, Vec)>, ) -> DispatchResultWithPostInfo { - // let who = ensure_signed(origin.clone())?; T::CallOrigin::ensure_address_origin(&source, origin)?; Self::ensure_balance_for_contract_creation(&source)?; From 4c30303fd69e7f564f0cd37352c119af9fbc5e20 Mon Sep 17 00:00:00 2001 From: open-junius Date: Wed, 11 Jun 2025 15:57:02 +0800 Subject: [PATCH 7/8] remove commented code --- frame/evm/src/lib.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index e2ef7e60f8..e4d0dd1b87 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -1052,7 +1052,7 @@ impl Pallet { T::Currency::reducible_balance(&account_id, Preservation::Preserve, Fortitude::Polite); let balance_sub = SubstrateBalance::from(UniqueSaturatedInto::::unique_saturated_into(balance)); - let balance_eth: EvmBalance = + let balance_eth = T::BalanceConverter::into_evm_balance(balance_sub).unwrap_or(EvmBalance::from(0u64)); ( @@ -1073,10 +1073,7 @@ impl Pallet { } /// Ensure balance to pre fund contract creation. - pub fn ensure_balance_for_contract_creation( - source: &H160, - // ) -> Result<(), sp_runtime::DispatchError> { - ) -> Result<(), Error> { + pub fn ensure_balance_for_contract_creation(source: &H160) -> Result<(), Error> { let account_id = T::AddressMapping::into_account_id(*source); let balance = T::Currency::reducible_balance(&account_id, Preservation::Preserve, Fortitude::Polite); From 3c3dee6dc216c4c082038ceb2a9282a753b32e4f Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 27 Jun 2025 16:23:55 +0800 Subject: [PATCH 8/8] fix unit test --- frame/evm/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index 3b229fced9..89282e0579 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -663,12 +663,12 @@ pub mod pallet { Undefined, /// Origin is not allowed to perform the operation. NotAllowed, + /// Address not allowed to deploy contracts either via CREATE or CALL(CREATE). + CreateOriginNotAllowed, /// Not enough balance to pay existential deposit BalanceLowForExistentialDeposit, /// Token transfer to new contract failed TransferToNewContractFailed, - /// Address not allowed to deploy contracts either via CREATE or CALL(CREATE). - CreateOriginNotAllowed, } impl From for Error {