diff --git a/frame/evm/src/lib.rs b/frame/evm/src/lib.rs index 5edb5d6acd..034e62dcc0 100644 --- a/frame/evm/src/lib.rs +++ b/frame/evm/src/lib.rs @@ -74,7 +74,8 @@ use codec::{Decode, Encode}; use evm::Config as EvmConfig; use frame_support::dispatch::DispatchResultWithPostInfo; use frame_support::traits::{ - Currency, ExistenceRequirement, FindAuthor, Get, Imbalance, OnUnbalanced, WithdrawReasons, + tokens::fungible::Inspect, Currency, ExistenceRequirement, FindAuthor, Get, Imbalance, + OnUnbalanced, WithdrawReasons, }; use frame_support::weights::{Pays, PostDispatchInfo, Weight}; use frame_system::RawOrigin; @@ -118,7 +119,7 @@ pub mod pallet { /// Mapping from address to account id. type AddressMapping: AddressMapping; /// Currency type for withdraw and balance storage. - type Currency: Currency; + type Currency: Currency + Inspect; /// The overarching event type. type Event: From> + IsType<::Event>; @@ -621,7 +622,8 @@ impl Pallet { let account_id = T::AddressMapping::into_account_id(*address); let nonce = frame_system::Pallet::::account_nonce(&account_id); - let balance = T::Currency::free_balance(&account_id); + // keepalive `true` takes into account ExistentialDeposit as part of what's considered liquid balance. + let balance = T::Currency::reducible_balance(&account_id, true); Account { nonce: U256::from(UniqueSaturatedInto::::unique_saturated_into(nonce)), diff --git a/frame/evm/src/tests.rs b/frame/evm/src/tests.rs index 35d3911f10..6330dd7bde 100644 --- a/frame/evm/src/tests.rs +++ b/frame/evm/src/tests.rs @@ -21,7 +21,7 @@ use super::*; use crate::mock::*; use frame_support::assert_ok; -use frame_support::traits::GenesisBuild; +use frame_support::traits::{GenesisBuild, LockIdentifier, LockableCurrency, WithdrawReasons}; use std::{collections::BTreeMap, str::FromStr}; type Balances = pallet_balances::Pallet; @@ -121,3 +121,24 @@ fn find_author() { ); }); } + +#[test] +fn reducible_balance() { + new_test_ext().execute_with(|| { + let evm_addr = H160::from_str("1000000000000000000000000000000000000001").unwrap(); + let account_id = ::AddressMapping::into_account_id(evm_addr); + let existential = ExistentialDeposit::get(); + + // Genesis Balance. + let genesis_balance = EVM::account_basic(&evm_addr).balance; + + // Lock identifier. + let lock_id: LockIdentifier = *b"te/stlok"; + // Reserve some funds. + let to_lock = 1000; + Balances::set_lock(lock_id, &account_id, to_lock, WithdrawReasons::RESERVE); + // Reducible is, as currently configured in `account_basic`, (balance - lock + existential). + let reducible_balance = EVM::account_basic(&evm_addr).balance; + assert_eq!(reducible_balance, (genesis_balance - to_lock + existential)); + }); +} diff --git a/ts-tests/tests/test-balance.ts b/ts-tests/tests/test-balance.ts index 758c217aaf..24a2bf33a7 100644 --- a/ts-tests/tests/test-balance.ts +++ b/ts-tests/tests/test-balance.ts @@ -5,7 +5,7 @@ import { createAndFinalizeBlock, describeWithFrontier, customRequest } from "./u describeWithFrontier("Frontier RPC (Balance)", (context) => { const GENESIS_ACCOUNT = "0x6be02d1d3665660d22ff9624b7be0551ee1ac91b"; - const GENESIS_ACCOUNT_BALANCE = "340282366920938463463374607431768211455"; + const GENESIS_ACCOUNT_BALANCE = "340282366920938463463374607431768210955"; const GENESIS_ACCOUNT_PRIVATE_KEY = "0x99B3C12287537E38C90A9219D4CB074A89A16E9CDB20BF85728EBD97C343E342"; const TEST_ACCOUNT = "0x1111111111111111111111111111111111111111"; @@ -25,7 +25,7 @@ describeWithFrontier("Frontier RPC (Balance)", (context) => { }, GENESIS_ACCOUNT_PRIVATE_KEY); await customRequest(context.web3, "eth_sendRawTransaction", [tx.rawTransaction]); await createAndFinalizeBlock(context.web3); - expect(await context.web3.eth.getBalance(GENESIS_ACCOUNT)).to.equal("340282366920938463463374607431768189943"); - expect(await context.web3.eth.getBalance(TEST_ACCOUNT)).to.equal("512"); + expect(await context.web3.eth.getBalance(GENESIS_ACCOUNT)).to.equal("340282366920938463463374607431768189443"); + expect(await context.web3.eth.getBalance(TEST_ACCOUNT)).to.equal("12"); }); });