diff --git a/src/components/abciapp/src/abci/server/callback/mod.rs b/src/components/abciapp/src/abci/server/callback/mod.rs
index d0ae04da8..1067897d2 100644
--- a/src/components/abciapp/src/abci/server/callback/mod.rs
+++ b/src/components/abciapp/src/abci/server/callback/mod.rs
@@ -2,13 +2,6 @@
 //! # Impl function of tendermint ABCI
 //!
 
-use globutils::wallet;
-use ledger::{
-    data_model::ASSET_TYPE_FRA,
-    staking::{FF_ADDR_EXTRA_120_0000, FF_ADDR_LIST},
-};
-use zei::xfr::asset_record::AssetRecordType;
-
 mod utils;
 
 use {
@@ -28,15 +21,19 @@ use {
     config::abci::global_cfg::CFG,
     cryptohash::sha256,
     enterprise_web3::{
-        Setter, BALANCE_MAP, BLOCK, CODE_MAP, NONCE_MAP, RECEIPTS, REDIS_CLIENT,
-        STATE_UPDATE_LIST, TXS, WEB3_SERVICE_START_HEIGHT,
+        Setter, ALLOWANCES, BALANCE_MAP, BLOCK, CODE_MAP, NONCE_MAP, RECEIPTS,
+        REDIS_CLIENT, STATE_UPDATE_LIST, TOTAL_ISSUANCE, TXS, WEB3_SERVICE_START_HEIGHT,
     },
     fp_storage::hash::{Sha256, StorageHasher},
+    globutils::wallet,
     lazy_static::lazy_static,
     ledger::{
         converter::is_convert_account,
-        data_model::Operation,
-        staking::{evm::EVM_STAKING, KEEP_HIST, VALIDATOR_UPDATE_BLOCK_ITV},
+        data_model::{Operation, ASSET_TYPE_FRA},
+        staking::{
+            evm::EVM_STAKING, FF_ADDR_EXTRA_120_0000, FF_ADDR_LIST, KEEP_HIST,
+            VALIDATOR_UPDATE_BLOCK_ITV,
+        },
         store::{
             api_cache,
             fbnc::{new_mapx, Mapx},
@@ -55,7 +52,8 @@ use {
             Arc,
         },
     },
-    tracing::{error, info},
+    tracing::info,
+    zei::xfr::asset_record::AssetRecordType,
 };
 
 pub(crate) static TENDERMINT_BLOCK_HEIGHT: AtomicI64 = AtomicI64::new(0);
@@ -651,6 +649,27 @@ pub fn commit(s: &mut ABCISubmissionServer, req: &RequestCommit) -> ResponseComm
             Default::default()
         };
 
+        let total_issuance = if let Ok(mut receipts) = TOTAL_ISSUANCE.lock() {
+            take(&mut *receipts)
+        } else {
+            Default::default()
+        };
+        let allowances = if let Ok(mut receipts) = ALLOWANCES.lock() {
+            take(&mut *receipts)
+        } else {
+            Default::default()
+        };
+        if let Some(v) = total_issuance {
+            pnk!(setter
+                .set_total_issuance(height, v)
+                .map_err(|e| eg!("set redis error: {:?}", e)));
+        }
+        for ((owner, spender), amount) in allowances.iter() {
+            pnk!(setter
+                .set_allowances(height, *owner, *spender, *amount)
+                .map_err(|e| eg!("set redis error: {:?}", e)));
+        }
+
         if !code_map.is_empty()
             || !nonce_map.is_empty()
             || !balance_map.is_empty()
@@ -659,45 +678,39 @@ pub fn commit(s: &mut ABCISubmissionServer, req: &RequestCommit) -> ResponseComm
             || !receipts.is_empty()
             || block.is_some()
         {
-            setter
-                .set_height(height)
-                .map_err(|e| error!("{:?}", e))
-                .unwrap_or(());
-
             for (addr, code) in code_map.iter() {
-                setter
+                pnk!(setter
                     .set_byte_code(height, *addr, code.clone())
-                    .map_err(|e| error!("{:?}", e))
-                    .unwrap_or(());
+                    .map_err(|e| eg!("set redis error: {:?}", e)));
             }
 
             for (addr, nonce) in nonce_map.iter() {
-                setter
+                pnk!(setter
                     .set_nonce(height, *addr, *nonce)
-                    .map_err(|e| error!("{:?}", e))
-                    .unwrap_or(());
+                    .map_err(|e| eg!("set redis error: {:?}", e)));
             }
 
             for (addr, balance) in balance_map.iter() {
-                setter
+                pnk!(setter
                     .set_balance(height, *addr, *balance)
-                    .map_err(|e| error!("{:?}", e))
-                    .unwrap_or(());
+                    .map_err(|e| eg!("set redis error: {:?}", e)));
             }
 
             for state in state_list.iter() {
-                setter
+                pnk!(setter
                     .set_state(height, state.address, state.index, state.value)
-                    .map_err(|e| error!("{:?}", e))
-                    .unwrap_or(());
+                    .map_err(|e| eg!("set redis error: {:?}", e)));
             }
 
             if let Some(block) = block {
-                setter
+                pnk!(setter
                     .set_block_info(block, receipts, txs)
-                    .map_err(|e| error!("{:?}", e))
-                    .unwrap_or(());
+                    .map_err(|e| eg!("set redis error: {:?}", e)));
             }
+
+            pnk!(setter
+                .set_height(height)
+                .map_err(|e| eg!("set redis error: {:?}", e)));
         }
     }
 
diff --git a/src/components/contracts/modules/account/src/impls.rs b/src/components/contracts/modules/account/src/impls.rs
index 94352bd80..e7e24d978 100644
--- a/src/components/contracts/modules/account/src/impls.rs
+++ b/src/components/contracts/modules/account/src/impls.rs
@@ -1,18 +1,18 @@
 use crate::{storage::*, App, Config};
 use config::abci::global_cfg::CFG;
-use enterprise_web3::{BALANCE_MAP, WEB3_SERVICE_START_HEIGHT};
+use enterprise_web3::{
+    ALLOWANCES, BALANCE_MAP, TOTAL_ISSUANCE, WEB3_SERVICE_START_HEIGHT,
+};
 use fp_core::{account::SmartAccount, context::Context};
 use fp_storage::BorrowMut;
 use fp_traits::account::AccountAsset;
 use fp_types::crypto::Address;
 use primitive_types::{H160, U256};
 use ruc::*;
-
 impl<C: Config> AccountAsset<Address> for App<C> {
     fn total_issuance(ctx: &Context) -> U256 {
         TotalIssuance::get(&ctx.state.read()).unwrap_or_default()
     }
-
     fn account_of(
         ctx: &Context,
         who: &Address,
@@ -111,8 +111,8 @@ impl<C: Config> AccountAsset<Address> for App<C> {
             let mut balance_map = BALANCE_MAP.lock().c(d!())?;
             let target_slice: &[u8] = target.as_ref();
             let target_h160 = H160::from_slice(&target_slice[4..24]);
-
             balance_map.insert(target_h160, target_account.balance);
+            set_total_issuance(issuance)?;
         }
 
         Ok(())
@@ -143,8 +143,8 @@ impl<C: Config> AccountAsset<Address> for App<C> {
             let mut balance_map = BALANCE_MAP.lock().c(d!())?;
             let target_slice: &[u8] = target.as_ref();
             let target_h160 = H160::from_slice(&target_slice[4..24]);
-
             balance_map.insert(target_h160, target_account.balance);
+            set_total_issuance(issuance)?;
         }
 
         Ok(())
@@ -205,17 +205,31 @@ impl<C: Config> AccountAsset<Address> for App<C> {
 
         Ok(())
     }
-
     fn allowance(ctx: &Context, owner: &Address, spender: &Address) -> U256 {
         Allowances::get(&ctx.state.read(), owner, spender).unwrap_or_default()
     }
-
     fn approve(
         ctx: &Context,
         owner: &Address,
+        owner_addr: H160,
         spender: &Address,
+        spender_addr: H160,
         amount: U256,
     ) -> Result<()> {
-        Allowances::insert(ctx.state.write().borrow_mut(), owner, spender, &amount)
+        Allowances::insert(ctx.state.write().borrow_mut(), owner, spender, &amount)?;
+        if CFG.enable_enterprise_web3
+            && ctx.header.height as u64 > *WEB3_SERVICE_START_HEIGHT
+        {
+            let mut allowances = ALLOWANCES.lock().c(d!())?;
+
+            allowances.push(((owner_addr, spender_addr), amount));
+        }
+        Ok(())
     }
 }
+
+fn set_total_issuance(issuance: U256) -> Result<()> {
+    let mut total_issuance = TOTAL_ISSUANCE.lock().c(d!())?;
+    *total_issuance = Some(issuance);
+    Ok(())
+}
diff --git a/src/components/contracts/modules/evm/precompile/frc20/src/lib.rs b/src/components/contracts/modules/evm/precompile/frc20/src/lib.rs
index 7b0159fcc..5ac82c0e5 100644
--- a/src/components/contracts/modules/evm/precompile/frc20/src/lib.rs
+++ b/src/components/contracts/modules/evm/precompile/frc20/src/lib.rs
@@ -302,18 +302,18 @@ impl<C: Config> FRC20<C> {
         input.expect_arguments(2)?;
 
         let caller = C::AddressMapping::convert_to_account_id(context.caller);
-        let spender: H160 = input.read::<Address>()?.into();
-        if spender == H160::zero() {
+        let s: H160 = input.read::<Address>()?.into();
+        if s == H160::zero() {
             return Err(error("FRC20: approve to the zero address"));
         }
-        let spender_id = C::AddressMapping::convert_to_account_id(spender);
+        let spender_id = C::AddressMapping::convert_to_account_id(s);
         let amount: U256 = input.read()?;
         debug!(target: "evm",
             "FRC20#approve: sender: {:?}, spender: {:?}, amount: {:?}",
-            context.caller, spender, amount
+            context.caller, s, amount
         );
 
-        C::AccountAsset::approve(state, &caller, &spender_id, amount)
+        C::AccountAsset::approve(state, &caller, context.caller, &spender_id, s, amount)
             .map_err(|e| error(format!("{e:?}")))?;
 
         Ok(PrecompileOutput {
@@ -324,7 +324,7 @@ impl<C: Config> FRC20<C> {
                 .log3(
                     APPROVAL_EVENT_SELECTOR,
                     context.caller,
-                    spender,
+                    s,
                     EvmDataWriter::new().write(amount).build(),
                 )
                 .build(),
@@ -420,7 +420,9 @@ impl<C: Config> FRC20<C> {
         C::AccountAsset::approve(
             state,
             &from_id,
+            from,
             &caller,
+            context.caller,
             allowance.saturating_sub(amount),
         )
         .map_err(|e| error(format!("{e:?}")))?;
diff --git a/src/components/contracts/primitives/enterprise-web3/Cargo.toml b/src/components/contracts/primitives/enterprise-web3/Cargo.toml
index 2d9d4113d..466b0801e 100644
--- a/src/components/contracts/primitives/enterprise-web3/Cargo.toml
+++ b/src/components/contracts/primitives/enterprise-web3/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2021"
 
 [dependencies]
 lazy_static = "1.4.0"
-evm-exporter = { package = "evm-exporter", git = "https://github.com/FindoraNetwork/enterprise-web3.git", tag = "1.0.0"}
+evm-exporter = { package = "evm-exporter", git = "https://github.com/FindoraNetwork/enterprise-web3.git", tag = "1.2.1"}
 ethereum = { version = "0.12.0", default-features = false, features = ["with-serde"] }
 primitive-types = "0.11.1"
 redis = { version = "0.21", default-features = false, features = [ "tls", "r2d2" ] }
diff --git a/src/components/contracts/primitives/enterprise-web3/src/lib.rs b/src/components/contracts/primitives/enterprise-web3/src/lib.rs
index 14ca0eb2a..b01c6d889 100644
--- a/src/components/contracts/primitives/enterprise-web3/src/lib.rs
+++ b/src/components/contracts/primitives/enterprise-web3/src/lib.rs
@@ -39,6 +39,9 @@ lazy_static! {
         Arc::new(Mutex::new(vec![]));
     pub static ref REMOVE_PENDING_STATE_UPDATE_LIST: Arc<Mutex<Vec<(H160, H256)>>> =
         Arc::new(Mutex::new(vec![]));
+    pub static ref TOTAL_ISSUANCE: Arc<Mutex<Option<U256>>> = Arc::new(Mutex::new(None));
+    pub static ref ALLOWANCES: Arc<Mutex<Vec<((H160, H160), U256)>>> =
+        Arc::new(Mutex::new(vec![]));
 }
 
 fn gen_redis_client() -> r2d2::Pool<Client> {
diff --git a/src/components/contracts/primitives/traits/src/account.rs b/src/components/contracts/primitives/traits/src/account.rs
index 65bb14fd1..0d295d191 100644
--- a/src/components/contracts/primitives/traits/src/account.rs
+++ b/src/components/contracts/primitives/traits/src/account.rs
@@ -1,5 +1,5 @@
 use fp_core::{account::SmartAccount, context::Context};
-use primitive_types::U256;
+use primitive_types::{H160, U256};
 use ruc::Result;
 
 pub trait AccountAsset<Address> {
@@ -53,7 +53,9 @@ pub trait AccountAsset<Address> {
     fn approve(
         ctx: &Context,
         owner: &Address,
+        owner_addr: H160,
         spender: &Address,
+        spender_addr: H160,
         amount: U256,
     ) -> Result<()>;
 }