diff --git a/tests/osaka/eip7939_count_leading_zeros/test_count_leading_zeros.py b/tests/osaka/eip7939_count_leading_zeros/test_count_leading_zeros.py index 58a872ac085..cbf31af2025 100644 --- a/tests/osaka/eip7939_count_leading_zeros/test_count_leading_zeros.py +++ b/tests/osaka/eip7939_count_leading_zeros/test_count_leading_zeros.py @@ -11,6 +11,7 @@ Alloc, Block, BlockchainTestFiller, + Bytecode, CodeGasMeasure, StateTestFiller, Transaction, @@ -155,6 +156,63 @@ def test_clz_stack_underflow(state_test: StateTestFiller, pre: Alloc): state_test(pre=pre, post=post, tx=tx) +@pytest.mark.valid_from("Osaka") +def test_clz_stack_not_overflow(state_test: StateTestFiller, pre: Alloc, fork: Fork): + """Test CLZ opcode never causes stack overflow.""" + max_stack_items = fork.max_stack_height() + + code = Bytecode() + post = {} + + code += Op.PUSH0 * (max_stack_items - 2) + + for i in range(256): + code += Op.PUSH1(i) + Op.CLZ(1 << i) + Op.SWAP1 + Op.SSTORE + + code_address = pre.deploy_contract(code=code) + + post[code_address] = Account(storage={i: 255 - i for i in range(256)}) + + tx = Transaction( + to=code_address, + sender=pre.fund_eoa(), + gas_limit=6_000_000, + ) + + state_test(pre=pre, post=post, tx=tx) + + +@pytest.mark.valid_from("Osaka") +def test_clz_push_operation_same_value(state_test: StateTestFiller, pre: Alloc): + """Test CLZ opcode returns the same value via different push operations.""" + code = Bytecode() + post = {} + + for bit in range(1, 33): # PUSH value + for push_n in range(bit, 33): # PUSHn opcode + op = getattr(Op, f"PUSH{push_n}") + key = 100 * bit + push_n + code += Op.SSTORE(key, Op.CLZ(op[1 << bit])) + + code_address = pre.deploy_contract(code=code) + + tx = Transaction( + to=code_address, + sender=pre.fund_eoa(), + gas_limit=30_000_000, + ) + + post = { + code_address: Account( + storage={ + bit * 100 + push_n: 255 - bit for bit in range(1, 33) for push_n in range(bit, 33) + } + ) + } + + state_test(pre=pre, post=post, tx=tx) + + @pytest.mark.valid_at_transition_to("Osaka", subsequent_forks=True) def test_clz_fork_transition(blockchain_test: BlockchainTestFiller, pre: Alloc): """Test CLZ opcode behavior at fork transition."""