diff --git a/src/consensus/beacon.rs b/src/consensus/beacon.rs
index fdd1ca91f4d34aa8b85b7dfe417c04877e7565ee..fcc9d6f7baf74ec36343345ef93c2ea8b8dd43e7 100644
--- a/src/consensus/beacon.rs
+++ b/src/consensus/beacon.rs
@@ -6,6 +6,7 @@ use crate::{
     TaskGuard,
 };
 use async_trait::async_trait;
+use bitvec::macros::internal::funty::Fundamental;
 use ethereum_jsonrpc::*;
 use jsonrpsee::{
     core::{server::rpc_module::Methods, RpcResult},
@@ -281,36 +282,32 @@ impl Consensus for BeaconConsensus {
 
     fn finalize(
         &self,
-        header: &crate::models::BlockHeader,
-        ommers: &[crate::models::BlockHeader],
-    ) -> anyhow::Result<Vec<super::FinalizationChange>> {
-        let block_number = header.number;
-        let block_reward = self.block_reward.for_block(block_number);
-
-        Ok(if block_reward > 0 {
-            let mut changes = Vec::with_capacity(1 + ommers.len());
-
-            let mut miner_reward = block_reward;
-            for ommer in ommers {
-                let ommer_reward =
-                    (U256::from(8 + ommer.number.0 - block_number.0) * block_reward) >> 3;
-                changes.push(FinalizationChange::Reward {
-                    address: ommer.beneficiary,
-                    amount: ommer_reward,
-                    ommer: true,
-                });
-                miner_reward += block_reward / 32;
+        block: &BlockHeaderOrSender,
+        ommers: &[BlockHeader],
+    ) -> anyhow::Result<Vec<FinalizationChange>> {
+        let mut miner_reward: U256 = U256::ZERO;
+        let mut finalization_changes = vec![];
+        match block {
+            BlockHeaderOrSender::WithSender(block) => {
+                for behaviors in &block.behaviors {
+                    miner_reward += U256::from(
+                        (behaviors.behavior.quantity.as_f32()
+                            * REWARD_PER_BEHAVIOR_QUANTITY
+                            * MINER_RATE_ON_BEHAVIOR_QUANTITY)
+                            .as_u32(),
+                    );
+                }
+                let amount_from_transaction: u32 =
+                    (block.transactions.len().as_u32() * MINER_FIXED_REWARD_PER_TRANSACTION) as u32;
+                miner_reward += U256::from(amount_from_transaction);
+                finalization_changes.push(FinalizationChange::Reward {
+                    address: block.header.beneficiary,
+                    amount: miner_reward,
+                    ommer: false,
+                })
             }
-
-            changes.push(FinalizationChange::Reward {
-                address: header.beneficiary,
-                amount: miner_reward,
-                ommer: false,
-            });
-
-            changes
-        } else {
-            vec![]
-        })
+            _ => {}
+        }
+        Ok(finalization_changes)
     }
 }
diff --git a/src/consensus/clique/mod.rs b/src/consensus/clique/mod.rs
index 44f4c79aa94aef7d064a3afee817ee7cffb46655..494e6cb55530595d18769d4cb72b9272ccf1ac5d 100644
--- a/src/consensus/clique/mod.rs
+++ b/src/consensus/clique/mod.rs
@@ -1,6 +1,8 @@
 pub mod state;
+
 pub use state::CliqueState;
 
+use crate::consensus::BlockHeaderOrSender;
 use crate::{
     consensus::{
         fork_choice_graph::ForkChoiceGraph, state::CliqueBlock, CliqueError, Consensus,
@@ -217,20 +219,24 @@ impl Consensus for Clique {
 
     fn finalize(
         &self,
-        block: &BlockHeader,
-        _ommers: &[BlockHeader],
+        block: &BlockHeaderOrSender,
+        ommers: &[BlockHeader],
     ) -> anyhow::Result<Vec<FinalizationChange>> {
-        let clique_block = CliqueBlock::from_header(block)?;
-
-        let mut state = self.state.lock();
+        match block {
+            BlockHeaderOrSender::Header(block) => {
+                let clique_block = CliqueBlock::from_header(block)?;
 
-        state
-            .validate(&clique_block, false)
-            .map_err(DuoError::Validation)?;
-        state.finalize(clique_block);
+                let mut state = self.state.lock();
 
-        state.set_block_hash(block.hash());
+                state
+                    .validate(&clique_block, false)
+                    .map_err(DuoError::Validation)?;
+                state.finalize(clique_block);
 
+                state.set_block_hash(block.hash());
+            }
+            _ => {}
+        }
         Ok(vec![])
     }
 
diff --git a/src/consensus/mod.rs b/src/consensus/mod.rs
index 2abdb7d32527fc0db2d4ebeee2f098bb85c56dd8..ece3801d215b96e2f82fb4c2e3c2546f08753aa0 100644
--- a/src/consensus/mod.rs
+++ b/src/consensus/mod.rs
@@ -64,6 +64,11 @@ pub enum ForkChoiceMode {
     Difficulty(Arc<Mutex<ForkChoiceGraph>>),
 }
 
+pub enum BlockHeaderOrSender {
+    Header(BlockHeader),
+    WithSender(BlockWithSenders),
+}
+
 pub trait Consensus: Debug + Send + Sync + 'static {
     fn fork_choice_mode(&self) -> ForkChoiceMode;
 
@@ -88,7 +93,7 @@ pub trait Consensus: Debug + Send + Sync + 'static {
     /// NOTE: For Ethash See YP Section 11.3 "Reward Application".
     fn finalize(
         &self,
-        block: &BlockHeader,
+        block: &BlockHeaderOrSender,
         ommers: &[BlockHeader],
     ) -> anyhow::Result<Vec<FinalizationChange>>;
 
@@ -123,17 +128,20 @@ pub trait Consensus: Debug + Send + Sync + 'static {
 pub enum BadTransactionError {
     SenderNoEOA {
         sender: Address,
-    }, // EIP-3607: σ[S(T)]c ≠ KEC( () )
+    },
+    // EIP-3607: σ[S(T)]c ≠ KEC( () )
     WrongNonce {
         account: Address,
         expected: u64,
         got: u64,
-    }, // Tn ≠ σ[S(T)]n
+    },
+    // Tn ≠ σ[S(T)]n
     InsufficientFunds {
         account: Address,
         available: U512,
         required: U512,
-    }, // v0 > σ[S(T)]b
+    },
+    // v0 > σ[S(T)]b
     BlockGasLimitExceeded {
         available: u64,
         required: u64,
@@ -182,11 +190,13 @@ pub enum ValidationError {
     WrongStateRoot {
         expected: H256,
         got: H256,
-    }, // wrong Hr
+    },
+    // wrong Hr
     WrongOmmersHash {
         expected: H256,
         got: H256,
-    }, // wrong Ho
+    },
+    // wrong Ho
     WrongHeaderNonce {
         expected: H64,
         got: H64,
@@ -194,11 +204,13 @@ pub enum ValidationError {
     WrongTransactionsRoot {
         expected: H256,
         got: H256,
-    }, // wrong Ht
+    },
+    // wrong Ht
     WrongReceiptsRoot {
         expected: H256,
         got: H256,
-    }, // wrong He
+    },
+    // wrong He
     WrongLogsBloom {
         expected: Bloom,
         got: Bloom,
@@ -208,46 +220,62 @@ pub enum ValidationError {
     UnknownParent {
         number: BlockNumber,
         parent_hash: H256,
-    }, // P(H) = ∅ ∨ Hi ≠ P(H)Hi + 1
-    WrongDifficulty, // Hd ≠ D(H)
+    },
+    // P(H) = ∅ ∨ Hi ≠ P(H)Hi + 1
+    WrongDifficulty,
+    // Hd ≠ D(H)
     GasAboveLimit {
         used: u64,
         limit: u64,
-    }, // Hg > Hl
-    InvalidGasLimit, // |Hl-P(H)Hl|≥P(H)Hl/1024 ∨ Hl<5000
+    },
+    // Hg > Hl
+    InvalidGasLimit,
+    // |Hl-P(H)Hl|≥P(H)Hl/1024 ∨ Hl<5000
     InvalidTimestamp {
         parent: u64,
         current: u64,
-    }, // Hs ≤ P(H)Hs
-    ExtraDataTooLong, // ‖Hx‖ > 32
-    WrongDaoExtraData, // see EIP-779
+    },
+    // Hs ≤ P(H)Hs
+    ExtraDataTooLong,
+    // ‖Hx‖ > 32
+    WrongDaoExtraData,
+    // see EIP-779
     WrongBaseFee {
         expected: Option<U256>,
         got: Option<U256>,
-    }, // see EIP-1559
-    MissingBaseFee,  // see EIP-1559
-    InvalidSeal,     // Nonce or mix_hash
+    },
+    // see EIP-1559
+    MissingBaseFee,
+    // see EIP-1559
+    InvalidSeal, // Nonce or mix_hash
 
     // See [YP] Section 6.2 "Execution", Eq (58)
-    MissingSender, // S(T) = ∅
+    MissingSender,
+    // S(T) = ∅
     BadTransaction {
         index: usize,
         error: BadTransactionError,
     },
-    IntrinsicGas,                 // g0 > Tg
-    MaxFeeLessThanBase,           // max_fee_per_gas < base_fee_per_gas (EIP-1559)
+    IntrinsicGas,
+    // g0 > Tg
+    MaxFeeLessThanBase,
+    // max_fee_per_gas < base_fee_per_gas (EIP-1559)
     MaxPriorityFeeGreaterThanMax, // max_priority_fee_per_gas > max_fee_per_gas (EIP-1559)
 
     // See [YP] Section 11.1 "Ommer Validation", Eq (157)
     OmmerUnknownParent {
         number: BlockNumber,
         parent_hash: H256,
-    }, // P(H) = ∅ ∨ Hi ≠ P(H)Hi + 1
-    TooManyOmmers, // ‖BU‖ > 2
+    },
+    // P(H) = ∅ ∨ Hi ≠ P(H)Hi + 1
+    TooManyOmmers,
+    // ‖BU‖ > 2
     InvalidOmmerHeader {
         inner: Box<ValidationError>,
-    }, // ¬V(U)
-    NotAnOmmer,    // ¬k(U, P(BH)H, 6)
+    },
+    // ¬V(U)
+    NotAnOmmer,
+    // ¬k(U, P(BH)H, 6)
     DuplicateOmmer, // not well covered by the YP actually
 
     // See [YP] Section 11.2 "Transaction Validation", Eq (160)
diff --git a/src/consensus/pob/mod.rs b/src/consensus/pob/mod.rs
index 9d3d8a82f4fd68f4bbd7c47446d2af7a3bc337e7..a3c9b08266a89b2641308b873a8d6cf5f4a60200 100644
--- a/src/consensus/pob/mod.rs
+++ b/src/consensus/pob/mod.rs
@@ -1,6 +1,7 @@
 use std::{num::NonZeroUsize, sync::Arc};
 
 use ::ethash::LightDAG;
+use bitvec::macros::internal::funty::Fundamental;
 use lru::LruCache;
 use parking_lot::Mutex;
 
@@ -24,6 +25,10 @@ pub trait Verifiable<T> {
     fn verify(&self) -> bool;
 }
 
+pub const MINER_RATE_ON_BEHAVIOR_QUANTITY: f32 = 0.1;
+pub const REWARD_PER_BEHAVIOR_QUANTITY: f32 = 1.;
+pub const MINER_FIXED_REWARD_PER_TRANSACTION: u32 = 10;
+
 type Dag = LightDAG;
 
 #[derive(Debug)]
@@ -184,36 +189,33 @@ impl Consensus for Pob {
     }
     fn finalize(
         &self,
-        header: &BlockHeader,
+        block: &BlockHeaderOrSender,
         ommers: &[BlockHeader],
     ) -> anyhow::Result<Vec<FinalizationChange>> {
-        let block_number = header.number;
-        let block_reward = self.block_reward.for_block(block_number);
-
-        Ok(if block_reward > 0 {
-            let mut changes = Vec::with_capacity(1 + ommers.len());
-            let mut miner_reward = block_reward;
-            for ommer in ommers {
-                let ommer_reward =
-                    (U256::from(8 + ommer.number.0 - block_number.0) * block_reward) >> 3;
-                changes.push(FinalizationChange::Reward {
-                    address: ommer.beneficiary,
-                    amount: ommer_reward,
-                    ommer: true,
-                });
-                miner_reward += block_reward / 32;
+        let mut miner_reward: U256 = U256::ZERO;
+        let mut finalization_changes = vec![];
+        match block {
+            BlockHeaderOrSender::WithSender(block) => {
+                for behaviors in &block.behaviors {
+                    miner_reward += U256::from(
+                        (behaviors.behavior.quantity.as_f32()
+                            * REWARD_PER_BEHAVIOR_QUANTITY
+                            * MINER_RATE_ON_BEHAVIOR_QUANTITY)
+                            .as_u32(),
+                    );
+                }
+                let amount_from_transaction: u32 =
+                    (block.transactions.len().as_u32() * MINER_FIXED_REWARD_PER_TRANSACTION) as u32;
+                miner_reward += U256::from(amount_from_transaction);
+                finalization_changes.push(FinalizationChange::Reward {
+                    address: block.header.beneficiary,
+                    amount: miner_reward,
+                    ommer: false,
+                })
             }
-
-            changes.push(FinalizationChange::Reward {
-                address: header.beneficiary,
-                amount: miner_reward,
-                ommer: false,
-            });
-
-            changes
-        } else {
-            vec![]
-        })
+            _ => {}
+        }
+        Ok(finalization_changes)
     }
 
     fn needs_parallel_validation(&self) -> bool {
diff --git a/src/execution/processor.rs b/src/execution/processor.rs
index f4e8d4ff5ae96480858fb3ffaf5b98dfd97942d3..7ffd4ed7d3d64ac5c6ef27fccab18f5efb7db47a 100644
--- a/src/execution/processor.rs
+++ b/src/execution/processor.rs
@@ -331,7 +331,10 @@ where
             receipts.push(self.execute_transaction(&txn.message, txn.sender)?);
         }
 
-        for change in self.engine.finalize(self.header, &self.block.ommers)? {
+        for change in self.engine.finalize(
+            &BlockHeaderOrSender::Header(self.header.clone()),
+            &self.block.ommers,
+        )? {
             match change {
                 FinalizationChange::Reward {
                     address, amount, ..
diff --git a/src/rpc/otterscan.rs b/src/rpc/otterscan.rs
index bade167c12d1ea63c706e64ff08c7461a085dc11..3a8192a432e54548d173a124f563751230ca3ba4 100644
--- a/src/rpc/otterscan.rs
+++ b/src/rpc/otterscan.rs
@@ -1,4 +1,5 @@
 use super::helpers;
+use crate::consensus::BlockHeaderOrSender;
 use crate::{
     accessors::chain,
     consensus::{engine_factory, FinalizationChange},
@@ -54,8 +55,8 @@ where
         let chainspec = tx
             .get(tables::Config, ())?
             .ok_or_else(|| format_err!("no chainspec found"))?;
-        let finalization_changes =
-            engine_factory(None, chainspec, None)?.finalize(&header, &ommers)?;
+        let finalization_changes = engine_factory(None, chainspec, None)?
+            .finalize(&BlockHeaderOrSender::Header(header), &ommers)?;
 
         let mut block_reward = U256::ZERO;
         let mut uncle_reward = U256::ZERO;
@@ -472,8 +473,8 @@ where
 
             Ok(vec![])
         })
-        .await
-        .unwrap_or_else(helpers::joinerror_to_result)
+            .await
+            .unwrap_or_else(helpers::joinerror_to_result)
     }
     async fn search_transactions_before(
         &self,
@@ -820,8 +821,8 @@ where
                 None
             })
         })
-        .await
-        .unwrap_or_else(helpers::joinerror_to_result)
+            .await
+            .unwrap_or_else(helpers::joinerror_to_result)
     }
     async fn get_contract_creator(&self, addr: Address) -> RpcResult<Option<ContractCreatorData>> {
         let _ = addr;
diff --git a/src/rpc/trace.rs b/src/rpc/trace.rs
index 66846297405a01c85befd21a90d6f13982c588fc..73ed5213f8e2277d1e75c5ff9cdfd390f76e932e 100644
--- a/src/rpc/trace.rs
+++ b/src/rpc/trace.rs
@@ -1,4 +1,5 @@
 use super::helpers;
+use crate::consensus::BlockHeaderOrSender;
 use crate::{
     bitmapdb,
     consensus::engine_factory,
@@ -389,7 +390,9 @@ where
 
     let mut rewards = vec![];
     if let Some(ommers) = ommers_for_finalization {
-        for change in engine_factory(None, chain_spec, None)?.finalize(&header, &ommers)? {
+        for change in engine_factory(None, chain_spec, None)?
+            .finalize(&BlockHeaderOrSender::Header(header), &ommers)?
+        {
             match change {
                 crate::consensus::FinalizationChange::Reward {
                     address,
@@ -842,9 +845,9 @@ where
                 let block_hash = crate::accessors::chain::canonical_hash::read(&txn, block_number)?
                     .ok_or_else(|| format_err!("canonical hash for block #{block_number} not found"))?;
                 let transactions = crate::accessors::chain::block_body::read_without_senders(
-                        &txn,
-                        block_number,
-                    )?.ok_or_else(|| format_err!("body not found for block #{block_number}/{block_hash}"))?
+                    &txn,
+                    block_number,
+                )?.ok_or_else(|| format_err!("body not found for block #{block_number}/{block_hash}"))?
                     .transactions;
                 let (index, signed_message) = transactions
                     .iter()
@@ -871,15 +874,15 @@ where
                         .map(|(signed_message, sender)| (sender, signed_message.message, hashset![]))
                         .take(index)
                         .chain(once((sender, message, trace_types)))
-                        .collect(),None,
+                        .collect(), None,
                 )?.0
-                .pop().unwrap());
+                    .pop().unwrap());
             }
 
             Err(RpcError::Custom("tx not found".to_string()))
         })
-        .await
-        .unwrap_or_else(helpers::joinerror_to_result)
+            .await
+            .unwrap_or_else(helpers::joinerror_to_result)
     }
 
     async fn block(