Skip to content

Commit 58ed35d

Browse files
committed
Rewrite balance transfer precompile with precompile utils
1 parent 9958450 commit 58ed35d

File tree

4 files changed

+68
-28
lines changed

4 files changed

+68
-28
lines changed

Cargo.lock

Lines changed: 45 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

runtime/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ pallet-commitments = { default-features = false, path = "../pallets/commitments"
100100
fp-evm = { workspace = true }
101101
fp-rpc = { workspace = true }
102102
fp-self-contained = { workspace = true }
103+
precompile-utils = { workspace = true }
103104

104105
# Frontier FRAME
105106
pallet-base-fee = { workspace = true }
@@ -164,6 +165,7 @@ std = [
164165
"pallet-scheduler/std",
165166
"pallet-preimage/std",
166167
"pallet-commitments/std",
168+
"precompile-utils/std",
167169
"sp-api/std",
168170
"sp-block-builder/std",
169171
"sp-consensus-aura/std",
Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1+
use core::marker::PhantomData;
2+
13
use pallet_evm::{
2-
BalanceConverter, ExitError, ExitSucceed, PrecompileHandle, PrecompileOutput, PrecompileResult,
4+
BalanceConverter, ExitError, ExitSucceed, PrecompileFailure, PrecompileHandle,
5+
PrecompileOutput, PrecompileResult,
36
};
7+
use precompile_utils::EvmResult;
8+
use sp_core::H256;
49
use sp_runtime::traits::UniqueSaturatedInto;
5-
use sp_std::vec;
10+
use sp_runtime::AccountId32;
11+
use sp_std::vec::Vec;
612

713
use crate::precompiles::{
814
contract_to_origin, get_method_id, get_pubkey, get_slice, try_dispatch_runtime_call,
@@ -19,20 +25,11 @@ const CONTRACT_ADDRESS_SS58: [u8; 32] = [
1925

2026
pub struct BalanceTransferPrecompile;
2127

28+
#[precompile_utils::precompile]
2229
impl BalanceTransferPrecompile {
23-
pub fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult {
24-
let txdata = handle.input();
25-
26-
// Match method ID: keccak256("transfer(bytes32)")
27-
let method = get_slice(txdata, 0, 4)?;
28-
if get_method_id("transfer(bytes32)") != method {
29-
return Ok(PrecompileOutput {
30-
exit_status: ExitSucceed::Returned,
31-
output: vec![],
32-
});
33-
}
34-
35-
// Forward all received value to the destination address
30+
#[precompile::public("transfer(bytes32)")]
31+
#[precompile::payable]
32+
fn transfer(handle: &mut impl PrecompileHandle, address: H256) -> EvmResult<()> {
3633
let amount = handle.context().apparent_value;
3734

3835
// Use BalanceConverter to convert EVM amount to Substrate balance
@@ -41,20 +38,18 @@ impl BalanceTransferPrecompile {
4138
.ok_or(ExitError::OutOfFund)?;
4239

4340
if amount_sub.is_zero() {
44-
return Ok(PrecompileOutput {
45-
exit_status: ExitSucceed::Returned,
46-
output: vec![],
47-
});
41+
return Ok(());
4842
}
4943

50-
let address_bytes_dst = get_slice(txdata, 4, 36)?;
51-
let (account_id_dst, _) = get_pubkey(address_bytes_dst)?;
44+
let dest = get_pubkey(address.as_bytes())?.0.into();
5245

5346
let call = pallet_balances::Call::<Runtime>::transfer_allow_death {
54-
dest: account_id_dst.into(),
47+
dest,
5548
value: amount_sub.unique_saturated_into(),
5649
};
5750

58-
try_dispatch_runtime_call(handle, call, contract_to_origin(&CONTRACT_ADDRESS_SS58)?)
51+
try_dispatch_runtime_call(handle, call, contract_to_origin(&CONTRACT_ADDRESS_SS58)?)?;
52+
53+
Ok(())
5954
}
6055
}

runtime/src/precompiles/mod.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use alloc::format;
44
use core::marker::PhantomData;
55

66
use frame_support::dispatch::{GetDispatchInfo, Pays};
7-
7+
use frame_system::RawOrigin;
88
use pallet_evm::{
99
ExitError, ExitSucceed, GasWeightMapping, IsPrecompileResult, Precompile, PrecompileFailure,
1010
PrecompileHandle, PrecompileOutput, PrecompileResult, PrecompileSet,
@@ -14,13 +14,10 @@ use pallet_evm_precompile_sha3fips::Sha3FIPS256;
1414
use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256};
1515
use sp_core::{hashing::keccak_256, H160};
1616
use sp_runtime::{traits::Dispatchable, AccountId32};
17+
use sp_std::vec;
1718

1819
use crate::{Runtime, RuntimeCall};
1920

20-
use frame_system::RawOrigin;
21-
22-
use sp_std::vec;
23-
2421
// Include custom precompiles
2522
mod balance_transfer;
2623
mod ed25519;
@@ -35,6 +32,7 @@ use metagraph::*;
3532
use neuron::*;
3633
use staking::*;
3734
use subnet::*;
35+
3836
pub struct FrontierPrecompiles<R>(PhantomData<R>);
3937
impl<R> Default for FrontierPrecompiles<R>
4038
where

0 commit comments

Comments
 (0)