2727 track_storage_write ,
2828)
2929from .. import Evm
30- from ..exceptions import OutOfGasError , WriteInStaticContext
30+ from ..exceptions import WriteInStaticContext
3131from ..gas import (
3232 GAS_CALL_STIPEND ,
3333 GAS_COLD_SLOAD ,
@@ -56,25 +56,26 @@ def sload(evm: Evm) -> None:
5656 key = pop (evm .stack ).to_be_bytes32 ()
5757
5858 # GAS
59- gas_cost = (
60- GAS_WARM_ACCESS
61- if (evm .message .current_target , key ) in evm .accessed_storage_keys
62- else GAS_COLD_SLOAD
63- )
64- check_gas (evm , gas_cost )
65- if (evm .message .current_target , key ) not in evm .accessed_storage_keys :
66- evm .accessed_storage_keys .add ((evm .message .current_target , key ))
67- track_storage_read (
68- evm .state_changes ,
59+ is_cold_access = (
6960 evm .message .current_target ,
7061 key ,
71- )
62+ ) not in evm .accessed_storage_keys
63+ gas_cost = GAS_COLD_SLOAD if is_cold_access else GAS_WARM_ACCESS
64+
7265 charge_gas (evm , gas_cost )
7366
7467 # OPERATION
7568 state = evm .message .block_env .state
7669 value = get_storage (state , evm .message .current_target , key )
7770
71+ if is_cold_access :
72+ evm .accessed_storage_keys .add ((evm .message .current_target , key ))
73+ track_storage_read (
74+ evm .state_changes ,
75+ evm .message .current_target ,
76+ key ,
77+ )
78+
7879 push (evm .stack , value )
7980
8081 # PROGRAM COUNTER
@@ -94,19 +95,14 @@ def sstore(evm: Evm) -> None:
9495 # STACK
9596 key = pop (evm .stack ).to_be_bytes32 ()
9697 new_value = pop (evm .stack )
97- if evm .gas_left <= GAS_CALL_STIPEND :
98- raise OutOfGasError
9998
100- # Check static context before accessing storage
99+ # check we have at least the stipend gas
100+ check_gas (evm , GAS_CALL_STIPEND + Uint (1 ))
101+
102+ # check static context before accessing storage
101103 if evm .message .is_static :
102104 raise WriteInStaticContext
103105
104- state = evm .message .block_env .state
105- original_value = get_storage_original (
106- state , evm .message .current_target , key
107- )
108- current_value = get_storage (state , evm .message .current_target , key )
109-
110106 # GAS
111107 gas_cost = Uint (0 )
112108 is_cold_access = (
@@ -117,16 +113,15 @@ def sstore(evm: Evm) -> None:
117113 if is_cold_access :
118114 gas_cost += GAS_COLD_SLOAD
119115
120- if original_value == current_value and current_value != new_value :
121- if original_value == 0 :
122- gas_cost += GAS_STORAGE_SET
123- else :
124- gas_cost += GAS_STORAGE_UPDATE - GAS_COLD_SLOAD
125- else :
126- gas_cost += GAS_WARM_ACCESS
116+ state = evm .message .block_env .state
117+ original_value = get_storage_original (
118+ state , evm .message .current_target , key
119+ )
120+ current_value = get_storage (state , evm .message .current_target , key )
121+
122+ if is_cold_access :
123+ evm .accessed_storage_keys .add ((evm .message .current_target , key ))
127124
128- # Track storage access BEFORE checking gas (EIP-7928)
129- # Even if we run out of gas, the access attempt should be tracked
130125 capture_pre_storage (
131126 evm .message .tx_env .state_changes ,
132127 evm .message .current_target ,
@@ -138,10 +133,14 @@ def sstore(evm: Evm) -> None:
138133 evm .message .current_target ,
139134 key ,
140135 )
141- check_gas (evm , gas_cost )
142136
143- if is_cold_access :
144- evm .accessed_storage_keys .add ((evm .message .current_target , key ))
137+ if original_value == current_value and current_value != new_value :
138+ if original_value == 0 :
139+ gas_cost += GAS_STORAGE_SET
140+ else :
141+ gas_cost += GAS_STORAGE_UPDATE - GAS_COLD_SLOAD
142+ else :
143+ gas_cost += GAS_WARM_ACCESS
145144
146145 charge_gas (evm , gas_cost )
147146
0 commit comments