diff --git a/crates/evm/src/instructions/comparison_operations.cairo b/crates/evm/src/instructions/comparison_operations.cairo index 797025f27..6fc053c5a 100644 --- a/crates/evm/src/instructions/comparison_operations.cairo +++ b/crates/evm/src/instructions/comparison_operations.cairo @@ -116,7 +116,17 @@ impl ComparisonAndBitwiseOperations of ComparisonAndBitwiseOperationsTrait { /// 0x1B - SHL /// # Specification: https://www.evm.codes/#1b?fork=shanghai fn exec_shl(ref self: ExecutionContext) -> Result<(), EVMError> { - Result::Ok(()) + let popped = self.stack.pop_n(2)?; + let shift = *popped[0]; + let val = *popped[1]; + + // if shift is bigger than 255 return 0 + if shift > 255 { + return self.stack.push(0); + } + + let result = val.wrapping_shl(shift); + self.stack.push(result) } /// 0x1C - SHR diff --git a/crates/evm/src/tests/test_instructions/test_comparison_operations.cairo b/crates/evm/src/tests/test_instructions/test_comparison_operations.cairo index 747b8f95e..3e5037076 100644 --- a/crates/evm/src/tests/test_instructions/test_comparison_operations.cairo +++ b/crates/evm/src/tests/test_instructions/test_comparison_operations.cairo @@ -213,6 +213,50 @@ fn test_exec_gt_true() { assert(ctx.stack.peek().unwrap() == 1, 'stack top should be 1'); } +#[test] +#[available_gas(20000000)] +fn test_exec_shl() { + // Given + let mut ctx = setup_execution_context(); + ctx.stack.push(0xff00000000000000000000000000000000000000000000000000000000000000).unwrap(); + ctx.stack.push(4_u256).unwrap(); + + // When + ctx.exec_shl(); + + // Then + assert(ctx.stack.len() == 1, 'stack should have one element'); + assert( + ctx + .stack + .peek() + .unwrap() == 0xf000000000000000000000000000000000000000000000000000000000000000, + 'stack top should be 0xf00000...' + ); +} + +#[test] +#[available_gas(20000000)] +fn test_exec_shl_wrapping() { + // Given + let mut ctx = setup_execution_context(); + ctx.stack.push(0xff00000000000000000000000000000000000000000000000000000000000000).unwrap(); + ctx.stack.push(256_u256).unwrap(); + + // When + ctx.exec_shl(); + + // Then + assert(ctx.stack.len() == 1, 'stack should have one element'); + assert( + ctx + .stack + .peek() + .unwrap() == 0, + 'if shift > 255 should return 0' + ); +} + #[test] #[available_gas(20000000)] fn test_exec_gt_false() {