@@ -488,7 +488,7 @@ def str_memory(self) -> str:
488488 + "\n "
489489 )
490490
491- def push (self , v : Word ) -> None :
491+ def _push (self , v : Word ) -> None :
492492 if isinstance (v , int ):
493493 # TODO: support native types on the stack
494494 # if not (0 <= v < 2**256):
@@ -1041,6 +1041,19 @@ def context_str(self) -> str:
10411041 opcode = self .current_opcode ()
10421042 return f"addr={ hexify (self .this ())} pc={ self .pc } insn={ mnemonic (opcode )} "
10431043
1044+ def push (self , val ) -> None :
1045+ val = unbox_int (val )
1046+
1047+ if isinstance (val , int ):
1048+ if val in sha3_inv :
1049+ # restore precomputed hashes
1050+ val = self .sha3_data (con (sha3_inv [val ]))
1051+ # TODO: support more commonly used concrete keccak values
1052+ elif val == EMPTY_KECCAK :
1053+ val = self .sha3_data (b"" )
1054+
1055+ self .st ._push (val )
1056+
10441057 def halt (
10451058 self ,
10461059 data : ByteVec | None ,
@@ -1258,7 +1271,7 @@ def sha3(self) -> None:
12581271 size : int = self .int_of (self .st .pop (), "symbolic SHA3 data size" )
12591272 data = self .st .mslice (loc , size ).unwrap () if size else b""
12601273 sha3_image = self .sha3_data (data )
1261- self .st . push (sha3_image )
1274+ self .push (sha3_image )
12621275
12631276 def sha3_hash (self , data : Bytes ) -> bytes | None :
12641277 """return concrete bytes if the hash can be evaluated, otherwise None"""
@@ -2233,7 +2246,7 @@ def callback(new_ex: Exec, stack, step_id):
22332246
22342247 # set status code on the stack
22352248 subcall_success = subcall .output .error is None
2236- new_ex .st . push (1 if subcall_success else 0 )
2249+ new_ex .push (1 if subcall_success else 0 )
22372250
22382251 if not subcall_success :
22392252 # revert network states
@@ -2386,7 +2399,7 @@ def call_unknown() -> None:
23862399 f"call_exit_code_{ uid ()} _{ ex .new_call_id ():>02} " , BitVecSort256
23872400 )
23882401 ex .path .append (exit_code_var == exit_code )
2389- ex .st . push (exit_code if is_bv_value (exit_code ) else exit_code_var )
2402+ ex .push (exit_code if is_bv_value (exit_code ) else exit_code_var )
23902403
23912404 # transfer msg.value
23922405 send_callvalue (exit_code_var != ZERO )
@@ -2500,7 +2513,7 @@ def create(
25002513
25012514 if new_addr in ex .code :
25022515 # address conflicts don't revert, they push 0 on the stack and continue
2503- ex .st . push (0 )
2516+ ex .push (0 )
25042517 ex .advance_pc ()
25052518
25062519 # add a virtual subcontext to the trace for debugging purposes
@@ -2561,11 +2574,11 @@ def callback(new_ex: Exec, stack, step_id):
25612574 new_ex .set_code (new_addr , new_code )
25622575
25632576 # push new address to stack
2564- new_ex .st . push (uint256 (new_addr ))
2577+ new_ex .push (uint256 (new_addr ))
25652578
25662579 else :
25672580 # creation failed
2568- new_ex .st . push (0 )
2581+ new_ex .push (0 )
25692582
25702583 # revert network states
25712584 new_ex .code = orig_code .copy ()
@@ -2756,12 +2769,12 @@ def calldataload(
27562769
27572770 for candidate in ex .path .concretization .candidates [loaded ]:
27582771 new_ex = self .create_branch (ex , loaded == candidate , ex .pc )
2759- new_ex .st . push (candidate )
2772+ new_ex .push (candidate )
27602773 new_ex .advance_pc ()
27612774 stack .push (new_ex , step_id )
27622775 return
27632776
2764- ex .st . push (loaded )
2777+ ex .push (loaded )
27652778 ex .advance_pc ()
27662779 stack .push (ex , step_id )
27672780
@@ -2886,102 +2899,102 @@ def finalize(ex: Exec):
28862899 pass
28872900
28882901 elif EVM .ADD <= opcode <= EVM .SMOD : # ADD MUL SUB DIV SDIV MOD SMOD
2889- ex .st . push (self .arith (ex , opcode , ex .st .pop (), ex .st .pop ()))
2902+ ex .push (self .arith (ex , opcode , ex .st .pop (), ex .st .pop ()))
28902903
28912904 elif EVM .ADDMOD <= opcode <= EVM .MULMOD : # ADDMOD MULMOD
2892- ex .st . push (
2905+ ex .push (
28932906 self .arith2 (ex , opcode , ex .st .pop (), ex .st .pop (), ex .st .pop ())
28942907 )
28952908
28962909 elif opcode == EVM .EXP :
2897- ex .st . push (self .arith (ex , opcode , ex .st .pop (), ex .st .pop ()))
2910+ ex .push (self .arith (ex , opcode , ex .st .pop (), ex .st .pop ()))
28982911
28992912 elif opcode == EVM .LT :
29002913 w1 = ex .st .popi ()
29012914 w2 = ex .st .popi ()
2902- ex .st . push (ULT (w1 , w2 )) # bvult
2915+ ex .push (ULT (w1 , w2 )) # bvult
29032916
29042917 elif opcode == EVM .GT :
29052918 w1 = ex .st .popi ()
29062919 w2 = ex .st .popi ()
2907- ex .st . push (UGT (w1 , w2 )) # bvugt
2920+ ex .push (UGT (w1 , w2 )) # bvugt
29082921
29092922 elif opcode == EVM .SLT :
29102923 w1 = ex .st .popi ()
29112924 w2 = ex .st .popi ()
2912- ex .st . push (w1 < w2 ) # bvslt
2925+ ex .push (w1 < w2 ) # bvslt
29132926
29142927 elif opcode == EVM .SGT :
29152928 w1 = ex .st .popi ()
29162929 w2 = ex .st .popi ()
2917- ex .st . push (w1 > w2 ) # bvsgt
2930+ ex .push (w1 > w2 ) # bvsgt
29182931
29192932 elif opcode == EVM .EQ :
29202933 w1 = ex .st .pop ()
29212934 w2 = ex .st .pop ()
29222935
29232936 if eq (w1 .sort (), w2 .sort ()):
2924- ex .st . push (w1 == w2 )
2937+ ex .push (w1 == w2 )
29252938 else :
29262939 if is_bool (w1 ):
29272940 if not is_bv (w2 ):
29282941 raise ValueError (w2 )
2929- ex .st . push (If (w1 , ONE , ZERO ) == w2 )
2942+ ex .push (If (w1 , ONE , ZERO ) == w2 )
29302943 else :
29312944 if not is_bv (w1 ):
29322945 raise ValueError (w1 )
29332946 if not is_bool (w2 ):
29342947 raise ValueError (w2 )
2935- ex .st . push (w1 == If (w2 , ONE , ZERO ))
2948+ ex .push (w1 == If (w2 , ONE , ZERO ))
29362949
29372950 elif opcode == EVM .ISZERO :
2938- ex .st . push (is_zero (ex .st .pop ()))
2951+ ex .push (is_zero (ex .st .pop ()))
29392952
29402953 elif opcode in [EVM .AND , EVM .OR , EVM .XOR ]:
2941- ex .st . push (bitwise (opcode , ex .st .pop (), ex .st .pop ()))
2954+ ex .push (bitwise (opcode , ex .st .pop (), ex .st .pop ()))
29422955
29432956 elif opcode == EVM .NOT :
2944- ex .st . push (~ ex .st .popi ()) # bvnot
2957+ ex .push (~ ex .st .popi ()) # bvnot
29452958
29462959 elif opcode == EVM .SHL :
29472960 w1 = ex .st .popi ()
29482961 w2 = ex .st .popi ()
2949- ex .st . push (w2 << w1 ) # bvshl
2962+ ex .push (w2 << w1 ) # bvshl
29502963
29512964 elif opcode == EVM .SAR :
29522965 w1 = ex .st .popi ()
29532966 w2 = ex .st .popi ()
2954- ex .st . push (w2 >> w1 ) # bvashr
2967+ ex .push (w2 >> w1 ) # bvashr
29552968
29562969 elif opcode == EVM .SHR :
29572970 w1 = ex .st .popi ()
29582971 w2 = ex .st .popi ()
2959- ex .st . push (LShR (w2 , w1 )) # bvlshr
2972+ ex .push (LShR (w2 , w1 )) # bvlshr
29602973
29612974 elif opcode == EVM .SIGNEXTEND :
29622975 w = ex .int_of (ex .st .popi (), "symbolic SIGNEXTEND size" )
29632976 if w <= 30 : # if w == 31, result is SignExt(0, value) == value
29642977 bl = (w + 1 ) * 8
2965- ex .st . push (SignExt (256 - bl , Extract (bl - 1 , 0 , ex .st .popi ())))
2978+ ex .push (SignExt (256 - bl , Extract (bl - 1 , 0 , ex .st .popi ())))
29662979
29672980 elif opcode == EVM .CALLDATALOAD :
29682981 self .calldataload (ex , stack , step_id )
29692982 continue
29702983
29712984 elif opcode == EVM .CALLDATASIZE :
2972- ex .st . push (len (ex .calldata ()))
2985+ ex .push (len (ex .calldata ()))
29732986
29742987 elif opcode == EVM .CALLVALUE :
2975- ex .st . push (ex .callvalue ())
2988+ ex .push (ex .callvalue ())
29762989
29772990 elif opcode == EVM .CALLER :
2978- ex .st . push (uint256 (ex .caller ()))
2991+ ex .push (uint256 (ex .caller ()))
29792992
29802993 elif opcode == EVM .ORIGIN :
2981- ex .st . push (uint256 (ex .origin ()))
2994+ ex .push (uint256 (ex .origin ()))
29822995
29832996 elif opcode == EVM .ADDRESS :
2984- ex .st . push (uint256 (ex .this ()))
2997+ ex .push (uint256 (ex .this ()))
29852998
29862999 elif opcode == EVM .EXTCODESIZE :
29873000 account = uint160 (ex .st .peek ())
@@ -3003,7 +3016,7 @@ def finalize(ex: Exec):
30033016 else 0
30043017 )
30053018
3006- ex .st . push (codesize )
3019+ ex .push (codesize )
30073020
30083021 elif opcode == EVM .EXTCODECOPY :
30093022 account : Address = uint160 (ex .st .peek ())
@@ -3050,49 +3063,49 @@ def finalize(ex: Exec):
30503063 else :
30513064 codehash = 0 # vs EMPTY_KECCAK, see EIP-1052
30523065
3053- ex .st . push (codehash )
3066+ ex .push (codehash )
30543067
30553068 elif opcode == EVM .CODESIZE :
3056- ex .st . push (len (ex .pgm ))
3069+ ex .push (len (ex .pgm ))
30573070
30583071 elif opcode == EVM .GAS :
3059- ex .st . push (f_gas (con (ex .new_gas_id ())))
3072+ ex .push (f_gas (con (ex .new_gas_id ())))
30603073
30613074 elif opcode == EVM .GASPRICE :
3062- ex .st . push (f_gasprice ())
3075+ ex .push (f_gasprice ())
30633076
30643077 elif opcode == EVM .BASEFEE :
3065- ex .st . push (ex .block .basefee )
3078+ ex .push (ex .block .basefee )
30663079
30673080 elif opcode == EVM .CHAINID :
3068- ex .st . push (ex .block .chainid )
3081+ ex .push (ex .block .chainid )
30693082
30703083 elif opcode == EVM .COINBASE :
3071- ex .st . push (uint256 (ex .block .coinbase ))
3084+ ex .push (uint256 (ex .block .coinbase ))
30723085
30733086 elif opcode == EVM .DIFFICULTY :
3074- ex .st . push (ex .block .difficulty )
3087+ ex .push (ex .block .difficulty )
30753088
30763089 elif opcode == EVM .GASLIMIT :
3077- ex .st . push (ex .block .gaslimit )
3090+ ex .push (ex .block .gaslimit )
30783091
30793092 elif opcode == EVM .NUMBER :
3080- ex .st . push (ex .block .number )
3093+ ex .push (ex .block .number )
30813094
30823095 elif opcode == EVM .TIMESTAMP :
3083- ex .st . push (ex .block .timestamp )
3096+ ex .push (ex .block .timestamp )
30843097
30853098 elif opcode == EVM .PC :
3086- ex .st . push (ex .pc )
3099+ ex .push (ex .pc )
30873100
30883101 elif opcode == EVM .BLOCKHASH :
3089- ex .st . push (f_blockhash (ex .st .pop ()))
3102+ ex .push (f_blockhash (ex .st .pop ()))
30903103
30913104 elif opcode == EVM .BALANCE :
3092- ex .st . push (ex .balance_of (uint160 (ex .st .pop ())))
3105+ ex .push (ex .balance_of (uint160 (ex .st .pop ())))
30933106
30943107 elif opcode == EVM .SELFBALANCE :
3095- ex .st . push (ex .balance_of (ex .this ()))
3108+ ex .push (ex .balance_of (ex .this ()))
30963109
30973110 elif opcode in [
30983111 EVM .CALL ,
@@ -3118,7 +3131,7 @@ def finalize(ex: Exec):
31183131
31193132 elif opcode == EVM .MLOAD :
31203133 loc : int = ex .mloc (check_size = True )
3121- ex .st . push (ex .st .memory .get_word (loc ))
3134+ ex .push (ex .st .memory .get_word (loc ))
31223135
31233136 elif opcode == EVM .MSTORE :
31243137 loc : int = ex .mloc (check_size = True )
@@ -3134,19 +3147,19 @@ def finalize(ex: Exec):
31343147 size : int = len (ex .st .memory )
31353148 # round up to the next multiple of 32
31363149 size = ((size + 31 ) // 32 ) * 32
3137- ex .st . push (size )
3150+ ex .push (size )
31383151
31393152 elif opcode == EVM .SLOAD :
31403153 slot : Word = ex .st .pop ()
3141- ex .st . push (self .sload (ex , ex .this (), slot ))
3154+ ex .push (self .sload (ex , ex .this (), slot ))
31423155
31433156 elif opcode == EVM .SSTORE :
31443157 slot : Word = ex .st .pop ()
31453158 value : Word = ex .st .pop ()
31463159 self .sstore (ex , ex .this (), slot , value )
31473160
31483161 elif opcode == EVM .RETURNDATASIZE :
3149- ex .st . push (ex .returndatasize ())
3162+ ex .push (ex .returndatasize ())
31503163
31513164 elif opcode == EVM .RETURNDATACOPY :
31523165 loc : int = ex .mloc (check_size = False )
@@ -3197,9 +3210,9 @@ def finalize(ex: Exec):
31973210 if idx < 0 :
31983211 raise ValueError (idx )
31993212 if idx >= 32 :
3200- ex .st . push (0 )
3213+ ex .push (0 )
32013214 else :
3202- ex .st . push (
3215+ ex .push (
32033216 ZeroExt (
32043217 248 , Extract ((31 - idx ) * 8 + 7 , (31 - idx ) * 8 , w )
32053218 )
@@ -3209,7 +3222,7 @@ def finalize(ex: Exec):
32093222 f"Warning: the use of symbolic BYTE indexing may potentially "
32103223 f"impact the performance of symbolic reasoning: BYTE { idx } { w } "
32113224 )
3212- ex .st . push (self .sym_byte_of (idx , w ))
3225+ ex .push (self .sym_byte_of (idx , w ))
32133226
32143227 elif EVM .LOG0 <= opcode <= EVM .LOG4 :
32153228 if ex .message ().is_static :
@@ -3223,24 +3236,14 @@ def finalize(ex: Exec):
32233236 ex .emit_log (EventLog (ex .this (), topics , data ))
32243237
32253238 elif opcode == EVM .PUSH0 :
3226- ex .st . push (0 )
3239+ ex .push (0 )
32273240
32283241 elif EVM .PUSH1 <= opcode <= EVM .PUSH32 :
32293242 val = unbox_int (insn .operand )
32303243 if isinstance (val , int ):
3231- if opcode == EVM .PUSH32 :
3232- if val in sha3_inv :
3233- # restore precomputed hashes
3234- ex .st .push (ex .sha3_data (con (sha3_inv [val ])))
3235- # TODO: support more commonly used concrete keccak values
3236- elif val == EMPTY_KECCAK :
3237- ex .st .push (ex .sha3_data (b"" ))
3238- else :
3239- ex .st .push (val )
3240- else :
3241- ex .st .push (val )
3244+ ex .push (val )
32423245 else :
3243- ex .st . push (uint256 (val ) if opcode < EVM .PUSH32 else val )
3246+ ex .push (uint256 (val ) if opcode < EVM .PUSH32 else val )
32443247
32453248 elif EVM .DUP1 <= opcode <= EVM .DUP16 :
32463249 ex .st .dup (opcode - EVM .DUP1 + 1 )
0 commit comments