diff --git a/cmd/ef_tests/levm/deserialize.rs b/cmd/ef_tests/levm/deserialize.rs
index 89b4f51e97..a733797ff8 100644
--- a/cmd/ef_tests/levm/deserialize.rs
+++ b/cmd/ef_tests/levm/deserialize.rs
@@ -1,11 +1,77 @@
-use crate::types::EFTest;
+use crate::types::{EFTest, TransactionExpectedException};
 use bytes::Bytes;
 use ethrex_core::{H256, U256};
-use serde::Deserialize;
+use serde::{Deserialize, Deserializer};
 use std::{collections::HashMap, str::FromStr};
 
 use crate::types::{EFTestRawTransaction, EFTestTransaction};
 
+pub fn deserialize_transaction_expected_exception<'de, D>(
+    deserializer: D,
+) -> Result<Option<Vec<TransactionExpectedException>>, D::Error>
+where
+    D: Deserializer<'de>,
+{
+    let option: Option<String> = Option::deserialize(deserializer)?;
+
+    if let Some(value) = option {
+        let exceptions = value
+            .split('|')
+            .map(|s| match s.trim() {
+                "TransactionException.INITCODE_SIZE_EXCEEDED" => {
+                    TransactionExpectedException::InitcodeSizeExceeded
+                }
+                "TransactionException.NONCE_IS_MAX" => TransactionExpectedException::NonceIsMax,
+                "TransactionException.TYPE_3_TX_BLOB_COUNT_EXCEEDED" => {
+                    TransactionExpectedException::Type3TxBlobCountExceeded
+                }
+                "TransactionException.TYPE_3_TX_ZERO_BLOBS" => {
+                    TransactionExpectedException::Type3TxZeroBlobs
+                }
+                "TransactionException.TYPE_3_TX_CONTRACT_CREATION" => {
+                    TransactionExpectedException::Type3TxContractCreation
+                }
+                "TransactionException.TYPE_3_TX_INVALID_BLOB_VERSIONED_HASH" => {
+                    TransactionExpectedException::Type3TxInvalidBlobVersionedHash
+                }
+                "TransactionException.INTRINSIC_GAS_TOO_LOW" => {
+                    TransactionExpectedException::IntrinsicGasTooLow
+                }
+                "TransactionException.INSUFFICIENT_ACCOUNT_FUNDS" => {
+                    TransactionExpectedException::InsufficientAccountFunds
+                }
+                "TransactionException.SENDER_NOT_EOA" => TransactionExpectedException::SenderNotEoa,
+                "TransactionException.PRIORITY_GREATER_THAN_MAX_FEE_PER_GAS" => {
+                    TransactionExpectedException::PriorityGreaterThanMaxFeePerGas
+                }
+                "TransactionException.GAS_ALLOWANCE_EXCEEDED" => {
+                    TransactionExpectedException::GasAllowanceExceeded
+                }
+                "TransactionException.INSUFFICIENT_MAX_FEE_PER_GAS" => {
+                    TransactionExpectedException::InsufficientMaxFeePerGas
+                }
+                "TransactionException.RLP_INVALID_VALUE" => {
+                    TransactionExpectedException::RlpInvalidValue
+                }
+                "TransactionException.GASLIMIT_PRICE_PRODUCT_OVERFLOW" => {
+                    TransactionExpectedException::GasLimitPriceProductOverflow
+                }
+                "TransactionException.TYPE_3_TX_PRE_FORK" => {
+                    TransactionExpectedException::Type3TxPreFork
+                }
+                "TransactionException.INSUFFICIENT_MAX_FEE_PER_BLOB_GAS" => {
+                    TransactionExpectedException::InsufficientMaxFeePerBlobGas
+                }
+                other => panic!("Unexpected error type: {}", other), // Should not fail, TODO is to return an error
+            })
+            .collect();
+
+        Ok(Some(exceptions))
+    } else {
+        Ok(None)
+    }
+}
+
 pub fn deserialize_ef_post_value_indexes<'de, D>(
     deserializer: D,
 ) -> Result<HashMap<String, U256>, D::Error>
diff --git a/cmd/ef_tests/levm/runner.rs b/cmd/ef_tests/levm/runner.rs
index 49afa45b08..c777637cbb 100644
--- a/cmd/ef_tests/levm/runner.rs
+++ b/cmd/ef_tests/levm/runner.rs
@@ -1,6 +1,6 @@
 use crate::{
     report::EFTestsReport,
-    types::{EFTest, EFTestPostValue},
+    types::{EFTest, EFTestPostValue, TransactionExpectedException},
     utils,
 };
 use ethrex_core::{
@@ -76,12 +76,12 @@ pub fn run_ef_test_tx(
     let mut evm = prepare_vm_for_tx(tx_id, test)?;
     ensure_pre_state(&evm, test)?;
     let execution_result = evm.transact();
-    // ensure_post_state(execution_result, test, report, tx_id)?;
+    ensure_post_state(execution_result, test, report, tx_id)?;
     Ok(())
 }
 
 pub fn run_ef_test(test: EFTest, report: &mut EFTestsReport) -> Result<(), Box<dyn Error>> {
-    println!("Running test: {}", &test.name);
+    //println!("Running test: {}", &test.name);
     let mut failed = false;
     for (tx_id, (tx_indexes, _tx)) in test.transactions.iter().enumerate() {
         // Code for debugging a specific case.
@@ -242,6 +242,61 @@ fn get_post_value(test: &EFTest, tx_id: usize) -> Option<EFTestPostValue> {
     }
 }
 
+// Exceptions not covered: RlpInvalidValue and Type3TxPreFork
+fn exception_is_expected(
+    expected_exceptions: Vec<TransactionExpectedException>,
+    returned_error: VMError,
+) -> bool {
+    expected_exceptions.iter().any(|exception| {
+        matches!(
+            (exception, &returned_error),
+            (
+                TransactionExpectedException::IntrinsicGasTooLow,
+                VMError::IntrinsicGasTooLow
+            ) | (
+                TransactionExpectedException::InsufficientAccountFunds,
+                VMError::InsufficientAccountFunds
+            ) | (
+                TransactionExpectedException::PriorityGreaterThanMaxFeePerGas,
+                VMError::PriorityGreaterThanMaxFeePerGas
+            ) | (
+                TransactionExpectedException::GasLimitPriceProductOverflow,
+                VMError::GasLimitPriceProductOverflow
+            ) | (
+                TransactionExpectedException::SenderNotEoa,
+                VMError::SenderNotEOA
+            ) | (
+                TransactionExpectedException::InsufficientMaxFeePerGas,
+                VMError::InsufficientMaxFeePerGas
+            ) | (
+                TransactionExpectedException::NonceIsMax,
+                VMError::NonceIsMax
+            ) | (
+                TransactionExpectedException::GasAllowanceExceeded,
+                VMError::GasAllowanceExceeded
+            ) | (
+                TransactionExpectedException::Type3TxBlobCountExceeded,
+                VMError::Type3TxBlobCountExceeded
+            ) | (
+                TransactionExpectedException::Type3TxZeroBlobs,
+                VMError::Type3TxZeroBlobs
+            ) | (
+                TransactionExpectedException::Type3TxContractCreation,
+                VMError::Type3TxContractCreation
+            ) | (
+                TransactionExpectedException::Type3TxInvalidBlobVersionedHash,
+                VMError::Type3TxInvalidBlobVersionedHash
+            ) | (
+                TransactionExpectedException::InsufficientMaxFeePerBlobGas,
+                VMError::InsufficientMaxFeePerBlobGas
+            ) | (
+                TransactionExpectedException::InitcodeSizeExceeded,
+                VMError::InitcodeSizeExceeded
+            )
+        )
+    })
+}
+
 pub fn ensure_post_state(
     execution_result: Result<TransactionReport, VMError>,
     test: &EFTest,
@@ -253,12 +308,26 @@ pub fn ensure_post_state(
         Ok(execution_report) => {
             match post_value.clone().map(|v| v.clone().expect_exception) {
                 // Execution result was successful but an exception was expected.
-                Some(Some(expected_exception)) => {
-                    let error_reason = format!("Expected exception: {expected_exception}");
+                Some(Some(expected_exceptions)) => {
+                    let error_reason = match expected_exceptions.get(1) {
+                        Some(second_exception) => {
+                            format!(
+                                "Expected exception: {:?} or {:?}",
+                                expected_exceptions.first().unwrap(),
+                                second_exception
+                            )
+                        }
+                        None => {
+                            format!(
+                                "Expected exception: {:?}",
+                                expected_exceptions.first().unwrap()
+                            )
+                        }
+                    };
+
                     return Err(format!("Post-state condition failed: {error_reason}").into());
                 }
                 // Execution result was successful and no exception was expected.
-                // TODO: Check that the post-state matches the expected post-state.
                 None | Some(None) => {
                     let pos_state_root = post_state_root(execution_report, test);
                     if let Some(expected_post_state_root_hash) = post_value {
@@ -281,8 +350,29 @@ pub fn ensure_post_state(
         Err(err) => {
             match post_value.map(|v| v.clone().expect_exception) {
                 // Execution result was unsuccessful and an exception was expected.
-                // TODO: Check that the exception matches the expected exception.
-                Some(Some(_expected_exception)) => {}
+                Some(Some(expected_exceptions)) => {
+                    // Instead of cloning could use references
+                    if !exception_is_expected(expected_exceptions.clone(), err.clone()) {
+                        let error_reason = match expected_exceptions.get(1) {
+                            Some(second_exception) => {
+                                format!(
+                                    "Returned exception is not the expected: Returned {:?} but expected {:?} or {:?}",
+                                    err,
+                                    expected_exceptions.first().unwrap(),
+                                    second_exception
+                                )
+                            }
+                            None => {
+                                format!(
+                                    "Returned exception is not the expected: Returned {:?} but expected {:?}",
+                                    err,
+                                    expected_exceptions.first().unwrap()
+                                )
+                            }
+                        };
+                        return Err(format!("Post-state condition failed: {error_reason}").into());
+                    }
+                }
                 // Execution result was unsuccessful but no exception was expected.
                 None | Some(None) => {
                     let error_reason = format!("Unexpected exception: {err:?}");
diff --git a/cmd/ef_tests/levm/types.rs b/cmd/ef_tests/levm/types.rs
index 6ee27eac44..378a870d48 100644
--- a/cmd/ef_tests/levm/types.rs
+++ b/cmd/ef_tests/levm/types.rs
@@ -1,7 +1,8 @@
 use crate::deserialize::{
     deserialize_ef_post_value_indexes, deserialize_h256_vec_optional_safe, deserialize_hex_bytes,
-    deserialize_hex_bytes_vec, deserialize_u256_optional_safe, deserialize_u256_safe,
-    deserialize_u256_valued_hashmap_safe, deserialize_u256_vec_safe,
+    deserialize_hex_bytes_vec, deserialize_transaction_expected_exception,
+    deserialize_u256_optional_safe, deserialize_u256_safe, deserialize_u256_valued_hashmap_safe,
+    deserialize_u256_vec_safe,
 };
 use bytes::Bytes;
 use ethrex_core::{
@@ -99,10 +100,34 @@ impl EFTestPost {
     }
 }
 
+#[derive(Debug, Deserialize, Clone)]
+pub enum TransactionExpectedException {
+    InitcodeSizeExceeded,
+    NonceIsMax,
+    Type3TxBlobCountExceeded,
+    Type3TxZeroBlobs,
+    Type3TxContractCreation,
+    Type3TxInvalidBlobVersionedHash,
+    IntrinsicGasTooLow,
+    InsufficientAccountFunds,
+    SenderNotEoa,
+    PriorityGreaterThanMaxFeePerGas,
+    GasAllowanceExceeded,
+    InsufficientMaxFeePerGas,
+    RlpInvalidValue,
+    GasLimitPriceProductOverflow,
+    Type3TxPreFork,
+    InsufficientMaxFeePerBlobGas,
+}
+
 #[derive(Debug, Deserialize, Clone)]
 pub struct EFTestPostValue {
-    #[serde(rename = "expectException")]
-    pub expect_exception: Option<String>,
+    #[serde(
+        rename = "expectException",
+        default,
+        deserialize_with = "deserialize_transaction_expected_exception"
+    )]
+    pub expect_exception: Option<Vec<TransactionExpectedException>>,
     pub hash: H256,
     #[serde(deserialize_with = "deserialize_ef_post_value_indexes")]
     pub indexes: HashMap<String, U256>,
diff --git a/crates/vm/levm/src/vm.rs b/crates/vm/levm/src/vm.rs
index fc5a6c6bdb..6105953865 100644
--- a/crates/vm/levm/src/vm.rs
+++ b/crates/vm/levm/src/vm.rs
@@ -695,7 +695,8 @@ impl VM {
         // Access List Cost
         // TODO: Implement access list cost.
 
-        self.increase_consumed_gas(initial_call_frame, intrinsic_gas)?;
+        self.increase_consumed_gas(initial_call_frame, intrinsic_gas)
+            .map_err(|_| VMError::IntrinsicGasTooLow)?;
 
         Ok(())
     }