diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 958cf9dedc..baf6df8117 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -518,6 +518,9 @@ func opSload(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) { } func opSstore(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) { + if evm.readOnly { + return nil, ErrWriteProtection + } loc := scope.Stack.pop() val := scope.Stack.pop() evm.StateDB.SetState(scope.Contract.Address(), loc.Bytes32(), val.Bytes32()) @@ -740,6 +743,9 @@ func opCall(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) { // Get the arguments from the memory. args := scope.Memory.GetPtr(inOffset.Uint64(), inSize.Uint64()) + if evm.readOnly && !value.IsZero() { + return nil, ErrWriteProtection + } if !value.IsZero() { gas += params.CallStipend } @@ -876,13 +882,15 @@ func opStop(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) { } func opSelfdestruct(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) { + if evm.readOnly { + return nil, ErrWriteProtection + } var ( this = scope.Contract.Address() balance = evm.StateDB.GetBalance(this) top = scope.Stack.pop() beneficiary = common.Address(top.Bytes20()) ) - // The funds are burned immediately if the beneficiary is the caller itself, // in this case, the beneficiary's balance is not increased. if this != beneficiary { @@ -904,15 +912,16 @@ func opSelfdestruct(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) { } func opSelfdestruct6780(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) { + if evm.readOnly { + return nil, ErrWriteProtection + } var ( this = scope.Contract.Address() balance = evm.StateDB.GetBalance(this) top = scope.Stack.pop() beneficiary = common.Address(top.Bytes20()) - newContract = evm.StateDB.IsNewContract(this) ) - // Contract is new and will actually be deleted. if newContract { if this != beneficiary { // Skip no-op transfer when self-destructing to self. diff --git a/core/vm/operations_acl.go b/core/vm/operations_acl.go index 4b7b87503d..ce394d9384 100644 --- a/core/vm/operations_acl.go +++ b/core/vm/operations_acl.go @@ -237,8 +237,10 @@ func makeSelfdestructGasFn(refundsEnabled bool) gasFunc { evm.StateDB.AddAddressToAccessList(address) gas = params.ColdAccountAccessCostEIP2929 + // Terminate the gas measurement if the leftover gas is not sufficient, + // it can effectively prevent accessing the states in the following steps if contract.Gas < gas { - return gas, nil + return 0, ErrOutOfGas } } // if empty and transfers value