@@ -541,3 +541,75 @@ def test_clz_initcode_create(state_test: StateTestFiller, pre: Alloc, opcode: Op
541
541
}
542
542
543
543
state_test (pre = pre , post = post , tx = tx )
544
+
545
+
546
+ class CallingContext :
547
+ """Context for calling operations."""
548
+
549
+ callee_context = 1 # CALL
550
+ caller_context = 2 # DELEGATECALL
551
+ no_context = 3 # STATICCALL
552
+
553
+
554
+ @pytest .mark .valid_from ("Osaka" )
555
+ @pytest .mark .parametrize (
556
+ "opcode,context" ,
557
+ [
558
+ pytest .param (Op .CALL , CallingContext .callee_context , id = "call" ),
559
+ pytest .param (Op .DELEGATECALL , CallingContext .caller_context , id = "delegatecall" ),
560
+ pytest .param (Op .CALLCODE , CallingContext .caller_context , id = "callcode" ),
561
+ pytest .param (Op .STATICCALL , CallingContext .no_context , id = "staticcall" ),
562
+ ],
563
+ )
564
+ def test_clz_call_operation (
565
+ state_test : StateTestFiller , pre : Alloc , opcode : Op , context : CallingContext
566
+ ):
567
+ """Test CLZ opcode with call operation."""
568
+ test_cases = [0 , 64 , 255 ]
569
+
570
+ # Storage Layout
571
+ callee_storage = Storage ()
572
+ caller_storage = Storage ()
573
+
574
+ callee_code = Bytecode ()
575
+
576
+ for bits in reversed (test_cases ):
577
+ callee_code += Op .CLZ (1 << bits )
578
+
579
+ if context != CallingContext .no_context :
580
+ for bits in test_cases :
581
+ callee_code += Op .SSTORE (callee_storage .store_next (255 - bits ), Op .CLZ (1 << bits ))
582
+
583
+ for i in range (len (test_cases )):
584
+ callee_code += Op .PUSH32 (i * 0x20 ) + Op .MSTORE
585
+
586
+ callee_code += Op .RETURN (0 , len (test_cases ) * 0x20 )
587
+
588
+ callee_address = pre .deploy_contract (code = callee_code )
589
+
590
+ caller_code = opcode (
591
+ gas = 0xFFFF , address = callee_address , ret_offset = 0 , ret_size = len (test_cases ) * 0x20
592
+ )
593
+
594
+ for i , bits in enumerate (test_cases ):
595
+ caller_code += Op .SSTORE (caller_storage .store_next (255 - bits ), Op .MLOAD (i * 0x20 ))
596
+
597
+ caller_address = pre .deploy_contract (code = caller_code )
598
+
599
+ tx = Transaction (
600
+ to = caller_address ,
601
+ sender = pre .fund_eoa (),
602
+ gas_limit = 200_000 ,
603
+ )
604
+
605
+ post = {}
606
+
607
+ if context == CallingContext .caller_context :
608
+ post [caller_address ] = Account (storage = callee_storage )
609
+ elif context == CallingContext .callee_context :
610
+ post [callee_address ] = Account (storage = callee_storage )
611
+ post [caller_address ] = Account (storage = caller_storage )
612
+ elif context == CallingContext .no_context :
613
+ post [caller_address ] = Account (storage = caller_storage )
614
+
615
+ state_test (pre = pre , post = post , tx = tx )
0 commit comments