diff --git a/crates/vm/levm/src/opcode_handlers/keccak.rs b/crates/vm/levm/src/opcode_handlers/keccak.rs index 77a11c4df..29cd2872a 100644 --- a/crates/vm/levm/src/opcode_handlers/keccak.rs +++ b/crates/vm/levm/src/opcode_handlers/keccak.rs @@ -31,14 +31,17 @@ impl VM { self.increase_consumed_gas(current_call_frame, gas_cost)?; - let value_bytes = current_call_frame.memory.load_range(offset, size)?; + let value_bytes = if size == 0 { + vec![] + } else { + current_call_frame.memory.load_range(offset, size)? + }; let mut hasher = Keccak256::new(); hasher.update(value_bytes); - let result = hasher.finalize(); current_call_frame .stack - .push(U256::from_big_endian(&result))?; + .push(U256::from_big_endian(&hasher.finalize()))?; Ok(OpcodeSuccess::Continue) } diff --git a/crates/vm/levm/tests/edge_case_tests.rs b/crates/vm/levm/tests/edge_case_tests.rs index 33845f3bd..13e8bd867 100644 --- a/crates/vm/levm/tests/edge_case_tests.rs +++ b/crates/vm/levm/tests/edge_case_tests.rs @@ -1,3 +1,5 @@ +use std::str::FromStr; + use bytes::Bytes; use ethrex_core::U256; use ethrex_levm::{ @@ -103,6 +105,22 @@ fn test_is_negative() { vm.execute(&mut current_call_frame); } +#[test] +fn test_non_compliance_keccak256() { + let mut vm = new_vm_with_bytecode(Bytes::copy_from_slice(&[88, 88, 32, 89])).unwrap(); + let mut current_call_frame = vm.call_frames.pop().unwrap(); + vm.execute(&mut current_call_frame); + assert_eq!( + *current_call_frame.stack.stack.first().unwrap(), + U256::from_str("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470") + .unwrap() + ); + assert_eq!( + *current_call_frame.stack.stack.get(1).unwrap(), + U256::zero() + ); +} + #[test] fn test_sdiv_zero_dividend_and_negative_divisor() { let mut vm = new_vm_with_bytecode(Bytes::copy_from_slice(&[