From 743ed6bd085adf5afe1f201013ac3668c1c0b3a2 Mon Sep 17 00:00:00 2001 From: lambda-0x <0xlambda@protonmail.com> Date: Tue, 29 Aug 2023 03:59:46 +0530 Subject: [PATCH 1/4] refactor: simplify returns (#201) * refactor returns * make suggested changes in `decode_and_execute` function --- .../instructions/comparison_operations.cairo | 15 +- .../instructions/duplication_operations.cairo | 3 +- .../stop_and_arithmetic_operations.cairo | 33 ++--- crates/evm/src/interpreter.cairo | 134 +++++++++--------- 4 files changed, 84 insertions(+), 101 deletions(-) diff --git a/crates/evm/src/instructions/comparison_operations.cairo b/crates/evm/src/instructions/comparison_operations.cairo index 682bad6e6..ee0d3f59b 100644 --- a/crates/evm/src/instructions/comparison_operations.cairo +++ b/crates/evm/src/instructions/comparison_operations.cairo @@ -56,8 +56,7 @@ impl ComparisonAndBitwiseOperations of ComparisonAndBitwiseOperationsTrait { let a = *popped[0]; let b = *popped[1]; let result = a & b; - self.stack.push(result)?; - Result::Ok(()) + self.stack.push(result) } /// 0x17 - OR @@ -73,8 +72,7 @@ impl ComparisonAndBitwiseOperations of ComparisonAndBitwiseOperationsTrait { let a = *popped[0]; let b = *popped[1]; let result = a ^ b; - self.stack.push(result)?; - Result::Ok(()) + self.stack.push(result) } /// 0x19 - NOT @@ -83,8 +81,7 @@ impl ComparisonAndBitwiseOperations of ComparisonAndBitwiseOperationsTrait { fn exec_not(ref self: ExecutionContext) -> Result<(), EVMError> { let a = self.stack.pop()?; let result = ~a; - self.stack.push(result)?; - Result::Ok(()) + self.stack.push(result) } /// 0x1A - BYTE @@ -97,14 +94,12 @@ impl ComparisonAndBitwiseOperations of ComparisonAndBitwiseOperationsTrait { /// If the byte offset is out of range, we early return with 0. if i > 31 { - self.stack.push(0)?; - return Result::Ok(()); + return self.stack.push(0); } // Right shift value by offset bits and then take the least significant byte by applying modulo 256. let result = (x / 2.pow((31 - i) * 8)) % 256; - self.stack.push(result)?; - Result::Ok(()) + self.stack.push(result) } /// 0x1B - SHL diff --git a/crates/evm/src/instructions/duplication_operations.cairo b/crates/evm/src/instructions/duplication_operations.cairo index 10dba41e6..90943693f 100644 --- a/crates/evm/src/instructions/duplication_operations.cairo +++ b/crates/evm/src/instructions/duplication_operations.cairo @@ -23,8 +23,7 @@ mod internal { let i: u8 = i.into(); let item = context.stack.peek_at((i - 1).into())?; - context.stack.push(item)?; - Result::Ok(()) + context.stack.push(item) } } diff --git a/crates/evm/src/instructions/stop_and_arithmetic_operations.cairo b/crates/evm/src/instructions/stop_and_arithmetic_operations.cairo index 19a4cb238..fd9698cc6 100644 --- a/crates/evm/src/instructions/stop_and_arithmetic_operations.cairo +++ b/crates/evm/src/instructions/stop_and_arithmetic_operations.cairo @@ -37,8 +37,7 @@ impl StopAndArithmeticOperations of StopAndArithmeticOperationsTrait { // Compute the addition let (result, _) = u256_overflowing_add(*popped[0], *popped[1]); - self.stack.push(result)?; - Result::Ok(()) + self.stack.push(result) } /// 0x02 - MUL @@ -51,8 +50,7 @@ impl StopAndArithmeticOperations of StopAndArithmeticOperationsTrait { // Compute the multiplication let (result, _) = u256_overflow_mul(*popped[0], *popped[1]); - self.stack.push(result)?; - Result::Ok(()) + self.stack.push(result) } /// 0x03 - SUB @@ -65,8 +63,7 @@ impl StopAndArithmeticOperations of StopAndArithmeticOperationsTrait { // Compute the substraction let (result, _) = u256_overflow_sub(*popped[0], *popped[1]); - self.stack.push(result)?; - Result::Ok(()) + self.stack.push(result) } /// 0x04 - DIV @@ -87,8 +84,7 @@ impl StopAndArithmeticOperations of StopAndArithmeticOperationsTrait { Option::None => 0, }; - self.stack.push(result)?; - Result::Ok(()) + self.stack.push(result) } /// 0x05 - SDIV @@ -109,8 +105,7 @@ impl StopAndArithmeticOperations of StopAndArithmeticOperationsTrait { Option::None => 0, }; - self.stack.push(result)?; - Result::Ok(()) + self.stack.push(result) } /// 0x06 - MOD @@ -131,8 +126,7 @@ impl StopAndArithmeticOperations of StopAndArithmeticOperationsTrait { Option::None => 0, }; - self.stack.push(result)?; - Result::Ok(()) + self.stack.push(result) } /// 0x07 - SMOD @@ -153,8 +147,7 @@ impl StopAndArithmeticOperations of StopAndArithmeticOperationsTrait { }, Option::None => 0, }; - self.stack.push(result)?; - Result::Ok(()) + self.stack.push(result) } /// 0x08 - ADDMOD @@ -179,8 +172,7 @@ impl StopAndArithmeticOperations of StopAndArithmeticOperationsTrait { Option::None => 0, }; - self.stack.push(result)?; - Result::Ok(()) + self.stack.push(result) } /// 0x09 - MULMOD operation. @@ -205,8 +197,7 @@ impl StopAndArithmeticOperations of StopAndArithmeticOperationsTrait { Option::None => 0, }; - self.stack.push(result)?; - Result::Ok(()) + self.stack.push(result) } /// 0x0A - EXP @@ -220,8 +211,7 @@ impl StopAndArithmeticOperations of StopAndArithmeticOperationsTrait { let result = a.pow_mod(b); - self.stack.push(result)?; - Result::Ok(()) + self.stack.push(result) } /// 0x0B - SIGNEXTEND @@ -262,7 +252,6 @@ impl StopAndArithmeticOperations of StopAndArithmeticOperationsTrait { x }; - self.stack.push(result)?; - Result::Ok(()) + self.stack.push(result) } } diff --git a/crates/evm/src/interpreter.cairo b/crates/evm/src/interpreter.cairo index bb309ea97..439dc4030 100644 --- a/crates/evm/src/interpreter.cairo +++ b/crates/evm/src/interpreter.cairo @@ -91,207 +91,207 @@ impl EVMInterpreterImpl of EVMInterpreterTrait { // Call the appropriate function based on the opcode. if opcode == 0 { // STOP - context.exec_stop()?; + return context.exec_stop(); } if opcode == 1 { // ADD - context.exec_add()?; + return context.exec_add(); } if opcode == 2 { // MUL - context.exec_mul()?; + return context.exec_mul(); } if opcode == 3 { // SUB - context.exec_sub()?; + return context.exec_sub(); } if opcode == 4 { // DIV - context.exec_div()?; + return context.exec_div(); } if opcode == 5 { // SDIV - context.exec_sdiv()?; + return context.exec_sdiv(); } if opcode == 6 { // MOD - context.exec_mod()?; + return context.exec_mod(); } if opcode == 7 { // SMOD - context.exec_smod()?; + return context.exec_smod(); } if opcode == 8 { // ADDMOD - context.exec_addmod()?; + return context.exec_addmod(); } if opcode == 9 { // MULMOD - context.exec_mulmod()?; + return context.exec_mulmod(); } if opcode == 10 { // EXP - context.exec_exp()?; + return context.exec_exp(); } if opcode == 11 { // SIGNEXTEND - context.exec_signextend()?; + return context.exec_signextend(); } if opcode == 16 { // LT - context.exec_lt()?; + return context.exec_lt(); } if opcode == 17 { // GT - context.exec_gt()?; + return context.exec_gt(); } if opcode == 18 { // SLT - context.exec_slt()?; + return context.exec_slt(); } if opcode == 19 { // SGT - context.exec_sgt()?; + return context.exec_sgt(); } if opcode == 20 { // EQ - context.exec_eq()?; + return context.exec_eq(); } if opcode == 21 { // ISZERO - context.exec_iszero()?; + return context.exec_iszero(); } if opcode == 22 { // AND - context.exec_and()?; + return context.exec_and(); } if opcode == 23 { // OR - context.exec_or()?; + return context.exec_or(); } if opcode == 24 { // XOR - context.exec_xor()?; + return context.exec_xor(); } if opcode == 25 { // NOT - context.exec_not()?; + return context.exec_not(); } if opcode == 26 { // BYTE - context.exec_byte()?; + return context.exec_byte(); } if opcode == 27 { // SHL - context.exec_shl()?; + return context.exec_shl(); } if opcode == 28 { // SHR - context.exec_shr()?; + return context.exec_shr(); } if opcode == 29 { // SAR - context.exec_sar()?; + return context.exec_sar(); } if opcode == 48 { // ADDRESS - context.exec_address()?; + return context.exec_address(); } if opcode == 49 { // BALANCE - context.exec_balance()?; + return context.exec_balance(); } if opcode == 50 { // ORIGIN - context.exec_origin()?; + return context.exec_origin(); } if opcode == 51 { // CALLER - context.exec_caller()?; + return context.exec_caller(); } if opcode == 52 { // CALLVALUE - context.exec_callvalue()?; + return context.exec_callvalue(); } if opcode == 53 { // CALLDATALOAD - context.exec_calldataload()?; + return context.exec_calldataload(); } if opcode == 54 { // CALLDATASIZE - context.exec_calldatasize()?; + return context.exec_calldatasize(); } if opcode == 55 { // CALLDATACOPY - context.exec_calldatacopy()?; + return context.exec_calldatacopy(); } if opcode == 56 { // CODESIZE - context.exec_codesize()?; + return context.exec_codesize(); } if opcode == 57 { // CODECOPY - context.exec_codecopy()?; + return context.exec_codecopy(); } if opcode == 58 { // GASPRICE - context.exec_gasprice()?; + return context.exec_gasprice(); } if opcode == 59 { // EXTCODESIZE - context.exec_extcodesize()?; + return context.exec_extcodesize(); } if opcode == 60 { // EXTCODECOPY - context.exec_extcodecopy()?; + return context.exec_extcodecopy(); } if opcode == 61 { // RETURNDATASIZE - context.exec_returndatasize()?; + return context.exec_returndatasize(); } if opcode == 62 { // RETURNDATACOPY - context.exec_returndatacopy()?; + return context.exec_returndatacopy(); } if opcode == 63 { // EXTCODEHASH - context.exec_extcodehash()?; + return context.exec_extcodehash(); } if opcode == 64 { // BLOCKHASH - context.exec_blockhash()?; + return context.exec_blockhash(); } if opcode == 65 { // COINBASE - context.exec_coinbase()?; + return context.exec_coinbase(); } if opcode == 66 { // TIMESTAMP - context.exec_timestamp()?; + return context.exec_timestamp(); } if opcode == 67 { // NUMBER - context.exec_number()?; + return context.exec_number(); } if opcode == 68 { // PREVRANDAO - context.exec_prevrandao()?; + return context.exec_prevrandao(); } if opcode == 69 { // GASLIMIT - context.exec_gaslimit()?; + return context.exec_gaslimit(); } if opcode == 70 { // CHAINID - context.exec_chainid()?; + return context.exec_chainid(); } if opcode == 71 { // SELFBALANCE - context.exec_selfbalance()?; + return context.exec_selfbalance(); } if opcode == 72 { // BASEFEE - context.exec_basefee()?; + return context.exec_basefee(); } if opcode == 80 { // POP @@ -475,67 +475,67 @@ impl EVMInterpreterImpl of EVMInterpreterTrait { } if opcode == 128 { // DUP1 - context.exec_dup1()?; + return context.exec_dup1(); } if opcode == 129 { // DUP2 - context.exec_dup2()?; + return context.exec_dup2(); } if opcode == 130 { // DUP3 - context.exec_dup3()?; + return context.exec_dup3(); } if opcode == 131 { // DUP4 - context.exec_dup4()?; + return context.exec_dup4(); } if opcode == 132 { // DUP5 - context.exec_dup5()?; + return context.exec_dup5(); } if opcode == 133 { // DUP6 - context.exec_dup6()?; + return context.exec_dup6(); } if opcode == 134 { // DUP7 - context.exec_dup7()?; + return context.exec_dup7(); } if opcode == 135 { // DUP8 - context.exec_dup8()?; + return context.exec_dup8(); } if opcode == 136 { // DUP9 - context.exec_dup9()?; + return context.exec_dup9(); } if opcode == 137 { // DUP10 - context.exec_dup10()?; + return context.exec_dup10(); } if opcode == 138 { // DUP11 - context.exec_dup11()?; + return context.exec_dup11(); } if opcode == 139 { // DUP12 - context.exec_dup12()?; + return context.exec_dup12(); } if opcode == 140 { // DUP13 - context.exec_dup13()?; + return context.exec_dup13(); } if opcode == 141 { // DUP14 - context.exec_dup14()?; + return context.exec_dup14(); } if opcode == 142 { // DUP15 - context.exec_dup15()?; + return context.exec_dup15(); } if opcode == 143 { // DUP16 - context.exec_dup16()?; + return context.exec_dup16(); } if opcode == 144 { // SWAP1 From 20e93751426a44401dbf17fed6936506f60d527d Mon Sep 17 00:00:00 2001 From: TAdev <122918260+TAdev0@users.noreply.github.com> Date: Tue, 29 Aug 2023 18:33:23 +0200 Subject: [PATCH 2/4] feat: implement 0x36 - CALLDATASIZE Opcode (#200) * calldatasize * Update crates/evm/src/instructions/environmental_information.cairo Co-authored-by: lambda-0x <0xlambda@protonmail.com> * calldatasize_opcode * calldatasize * calldatasize_opcode * calldatasize_opcode --------- Co-authored-by: Tristan Co-authored-by: lambda-0x <0xlambda@protonmail.com> Co-authored-by: Tristan --- .../environmental_information.cairo | 10 +++++----- .../test_environment_information.cairo | 19 ++++++++++++++++++- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/crates/evm/src/instructions/environmental_information.cairo b/crates/evm/src/instructions/environmental_information.cairo index 1ffdbd6db..41c4022bb 100644 --- a/crates/evm/src/instructions/environmental_information.cairo +++ b/crates/evm/src/instructions/environmental_information.cairo @@ -2,10 +2,9 @@ use starknet::{EthAddressIntoFelt252}; use result::ResultTrait; use evm::stack::StackTrait; -use evm::context::ExecutionContext; -use evm::context::ExecutionContextTrait; -use evm::context::CallContextTrait; -use evm::context::BoxDynamicExecutionContextDestruct; +use evm::context::{ + ExecutionContext, ExecutionContextTrait, BoxDynamicExecutionContextDestruct, CallContextTrait +}; use evm::errors::EVMError; use utils::helpers::EthAddressIntoU256; @@ -57,7 +56,8 @@ impl EnvironmentInformationImpl of EnvironmentInformationTrait { /// Get the size of return data. /// # Specification: https://www.evm.codes/#36?fork=shanghai fn exec_calldatasize(ref self: ExecutionContext) -> Result<(), EVMError> { - Result::Ok(()) + let result: u256 = self.call_context().call_data().len().into(); + self.stack.push(result) } /// 0x37 - CALLDATACOPY operation diff --git a/crates/evm/src/tests/test_instructions/test_environment_information.cairo b/crates/evm/src/tests/test_instructions/test_environment_information.cairo index 279aad7f3..4797de9a6 100644 --- a/crates/evm/src/tests/test_instructions/test_environment_information.cairo +++ b/crates/evm/src/tests/test_instructions/test_environment_information.cairo @@ -3,7 +3,9 @@ use evm::tests::test_utils::{setup_execution_context, evm_address, callvalue}; use evm::stack::StackTrait; use option::OptionTrait; use starknet::EthAddressIntoFelt252; -use evm::context::BoxDynamicExecutionContextDestruct; +use evm::context::{ + ExecutionContext, ExecutionContextTrait, BoxDynamicExecutionContextDestruct, CallContextTrait +}; use utils::helpers::EthAddressIntoU256; #[test] @@ -41,3 +43,18 @@ fn test__exec_callvalue() { assert(ctx.stack.len() == 1, 'stack should have one element'); assert(ctx.stack.pop().unwrap() == callvalue(), 'should be `123456789'); } + +#[test] +#[available_gas(20000000)] +fn test_calldata_size() { + // Given + let mut ctx = setup_execution_context(); + let call_data: Span = ctx.call_context().call_data(); + + // When + ctx.exec_calldatasize(); + + // Then + assert(ctx.stack.len() == 1, 'stack should have one element'); + assert(ctx.stack.peek().unwrap() == call_data.len().into(), 'stack top is not calldatasize'); +} From 51e6062f930ff10ae84c81f31b2fad5dd0574def Mon Sep 17 00:00:00 2001 From: Quentash <100387965+Quentash@users.noreply.github.com> Date: Tue, 29 Aug 2023 18:38:46 +0200 Subject: [PATCH 3/4] feat: implement 0x46 - CHAINID Opcode (#205) * feat/chainidopcode * feat/chainidopcode * Update crates/evm/src/tests/test_instructions/test_block_information.cairo * docs: execution context (#176) * docs: execution context * chore: changelog * fix: typo * Update docs/general/model/execution_context.md Co-authored-by: Elias Tazartes <66871571+Eikix@users.noreply.github.com> * Update docs/general/model/execution_context.md Co-authored-by: Elias Tazartes <66871571+Eikix@users.noreply.github.com> * feat: add pc+=1 to diagram * chore: delete changelog --------- Co-authored-by: Elias Tazartes <66871571+Eikix@users.noreply.github.com> * feat(evm): add basefee opcode (#191) * feat(evm): add basefee opcode * fix(evm): change basefee to gasprice * feat(evm): add gaslimit opcode (#192) * feat(evm): add gaslimit opcode * refacto(evm): implement suggestions * chore: fmt --------- Co-authored-by: Mathieu <60658558+enitrat@users.noreply.github.com> Co-authored-by: msaug * refacto(evm): improve split word by 2x (#196) * fix: gas reports (#217) * feat(evm): add push{i} opcodes (#195) * feat(evm): add push{i} opcodes * refacto(evm): only 1 into in push * fix(evm): actually return the result of the opcode * impl suggestions * refactor: simplify returns (#201) * refactor returns * make suggested changes in `decode_and_execute` function --------- Co-authored-by: Mathieu <60658558+enitrat@users.noreply.github.com> Co-authored-by: Elias Tazartes <66871571+Eikix@users.noreply.github.com> Co-authored-by: Lucas @ StarkWare <70894690+LucasLvy@users.noreply.github.com> Co-authored-by: msaug Co-authored-by: lambda-0x <0xlambda@protonmail.com> --- .../src/instructions/block_information.cairo | 6 +++++- .../test_block_information.cairo | 19 +++++++++++++++++++ crates/utils/src/constants.cairo | 4 ++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/crates/evm/src/instructions/block_information.cairo b/crates/evm/src/instructions/block_information.cairo index eaf587a2a..982b5aed7 100644 --- a/crates/evm/src/instructions/block_information.cairo +++ b/crates/evm/src/instructions/block_information.cairo @@ -9,6 +9,7 @@ use traits::Into; use evm::context::{ExecutionContext, ExecutionContextTrait, BoxDynamicExecutionContextDestruct}; use evm::stack::StackTrait; use evm::errors::EVMError; +use utils::constants::CHAIN_ID; #[generate_trait] impl BlockInformation of BlockInformationTrait { @@ -57,7 +58,10 @@ impl BlockInformation of BlockInformationTrait { /// Get the chain ID. /// # Specification: https://www.evm.codes/#46?fork=shanghai fn exec_chainid(ref self: ExecutionContext) -> Result<(), EVMError> { - Result::Ok(()) + // CHAIN_ID = KKRT (0x4b4b5254) in ASCII + // TODO: Replace the hardcoded value by a value set in kakarot main contract constructor + // Push the chain ID to stack + self.stack.push(CHAIN_ID) } /// 0x47 - SELFBALANCE diff --git a/crates/evm/src/tests/test_instructions/test_block_information.cairo b/crates/evm/src/tests/test_instructions/test_block_information.cairo index bf8ec80f9..8ab46b8b5 100644 --- a/crates/evm/src/tests/test_instructions/test_block_information.cairo +++ b/crates/evm/src/tests/test_instructions/test_block_information.cairo @@ -3,6 +3,7 @@ use evm::context::BoxDynamicExecutionContextDestruct; use evm::stack::StackTrait; use evm::tests::test_utils::setup_execution_context; use starknet::testing::{set_block_timestamp, set_block_number}; +use utils::constants::CHAIN_ID; #[test] #[available_gas(20000000)] @@ -61,3 +62,21 @@ fn test_basefee() { assert(ctx.stack.len() == 1, 'stack should have one element'); assert(ctx.stack.peek().unwrap() == 10, 'stack top should be 0'); } + +#[test] +#[available_gas(20000000)] +fn test_chainid_should_push_chain_id_to_stack() { + // Given + let mut ctx = setup_execution_context(); + + // CHAIN_ID = KKRT (0x4b4b5254) in ASCII + // TODO: Replace the hardcoded value by a value set in kakarot main contract constructor + let chain_id: u256 = CHAIN_ID; + + // When + ctx.exec_chainid(); + + // Then + let result = ctx.stack.peek().unwrap(); + assert(result == chain_id, 'stack should have chain id'); +} diff --git a/crates/utils/src/constants.cairo b/crates/utils/src/constants.cairo index f8f47efb1..d4acadc11 100644 --- a/crates/utils/src/constants.cairo +++ b/crates/utils/src/constants.cairo @@ -1,5 +1,9 @@ // FELT PRIME const FELT252_PRIME: u256 = 0x800000000000011000000000000000000000000000000000000000000000001; +// BLOCK +// CHAIN_ID = KKRT (0x4b4b5254) in ASCII +const CHAIN_ID: u256 = 1263227476; + // STACK const STACK_MAX_DEPTH: usize = 1024; From 36c3f37fa8329705693f982e9fa84c65b1e6dc59 Mon Sep 17 00:00:00 2001 From: Daniel Bejarano <58019353+dbejarano820@users.noreply.github.com> Date: Tue, 29 Aug 2023 10:56:39 -0600 Subject: [PATCH 4/4] feat: implement 0x11 - GT opcode (#220) * feat: implement 0x11 - GT opcode * simplified return * feedback * quick fix --- .../instructions/comparison_operations.cairo | 10 +++- .../test_comparison_operations.cairo | 48 +++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/crates/evm/src/instructions/comparison_operations.cairo b/crates/evm/src/instructions/comparison_operations.cairo index ee0d3f59b..671bd2458 100644 --- a/crates/evm/src/instructions/comparison_operations.cairo +++ b/crates/evm/src/instructions/comparison_operations.cairo @@ -20,7 +20,15 @@ impl ComparisonAndBitwiseOperations of ComparisonAndBitwiseOperationsTrait { /// 0x11 - GT /// # Specification: https://www.evm.codes/#11?fork=shanghai fn exec_gt(ref self: ExecutionContext) -> Result<(), EVMError> { - Result::Ok(()) + let popped = self.stack.pop_n(2)?; + let a = *popped[0]; + let b = *popped[1]; + let result = if (a > b) { + 1 + } else { + 0 + }; + self.stack.push(result) } 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 4701cdf81..d26890bb0 100644 --- a/crates/evm/src/tests/test_instructions/test_comparison_operations.cairo +++ b/crates/evm/src/tests/test_instructions/test_comparison_operations.cairo @@ -196,3 +196,51 @@ fn test_byte_offset_out_of_range() { assert(ctx.stack.len() == 1, 'stack should have one element'); assert(ctx.stack.peek().unwrap() == 0x00, 'stack top should be 0x00'); } + +#[test] +#[available_gas(20000000)] +fn test_exec_gt_true() { + // Given + let mut ctx = setup_execution_context(); + ctx.stack.push(9_u256).unwrap(); + ctx.stack.push(10_u256).unwrap(); + + // When + ctx.exec_gt(); + + // Then + assert(ctx.stack.len() == 1, 'stack should have one element'); + assert(ctx.stack.peek().unwrap() == 1, 'stack top should be 1'); +} + +#[test] +#[available_gas(20000000)] +fn test_exec_gt_false() { + // Given + let mut ctx = setup_execution_context(); + ctx.stack.push(10_u256).unwrap(); + ctx.stack.push(9_u256).unwrap(); + + // When + ctx.exec_gt(); + + // Then + assert(ctx.stack.len() == 1, 'stack should have one element'); + assert(ctx.stack.peek().unwrap() == 0, 'stack top should be 0'); +} + +#[test] +#[available_gas(20000000)] +fn test_exec_gt_false_equal() { + // Given + let mut ctx = setup_execution_context(); + ctx.stack.push(10_u256).unwrap(); + ctx.stack.push(10_u256).unwrap(); + + // When + ctx.exec_gt(); + + // Then + assert(ctx.stack.len() == 1, 'stack should have one element'); + assert(ctx.stack.peek().unwrap() == 0, 'stack top should be 0'); +}