From aef3f5d0c28fd39d3b8988a0bd4ada7c2e3cf8d5 Mon Sep 17 00:00:00 2001 From: Thomas Butler <58192340+trbutler4@users.noreply.github.com> Date: Mon, 4 Sep 2023 04:36:21 -0500 Subject: [PATCH] feat: 0x1B - SHL opcode (#241) * passing test * tweaks * seperated tests * fixed conflict resolution mistake * moved both assertions back to wrapping shl test, added test case for shift > 255 * Update crates/evm/src/tests/test_instructions/test_comparison_operations.cairo * Update crates/evm/src/tests/test_instructions/test_comparison_operations.cairo --------- Co-authored-by: Mathieu <60658558+enitrat@users.noreply.github.com> --- .../instructions/comparison_operations.cairo | 12 ++++- .../test_comparison_operations.cairo | 44 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) 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() {