From 6bead9bdc2d1409d82bcae2785c5e3122c74769d Mon Sep 17 00:00:00 2001 From: Andrei Maiboroda Date: Wed, 4 Sep 2019 12:04:08 +0200 Subject: [PATCH] EIP-2200 implementation: throw OOG for SSTORE with gas below stipend --- lib/evmone/analysis.cpp | 1 + lib/evmone/instructions.cpp | 8 ++++++++ test/unittests/evm_state_test.cpp | 20 ++++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/lib/evmone/analysis.cpp b/lib/evmone/analysis.cpp index 4b6c202aa7..40a1a3fbd3 100644 --- a/lib/evmone/analysis.cpp +++ b/lib/evmone/analysis.cpp @@ -160,6 +160,7 @@ code_analysis analyze( break; case OP_GAS: + case OP_SSTORE: instr.arg.p.number = block->gas_cost; break; diff --git a/lib/evmone/instructions.cpp b/lib/evmone/instructions.cpp index 351c713262..051d5930ec 100644 --- a/lib/evmone/instructions.cpp +++ b/lib/evmone/instructions.cpp @@ -491,6 +491,14 @@ const instr_info* op_sstore(const instr_info* instr, execution_state& state) noe if (state.msg->flags & EVMC_STATIC) return state.exit(EVMC_STATIC_MODE_VIOLATION); + if (state.rev >= EVMC_ISTANBUL) + { + const auto correction = state.current_block_cost - instr->arg.p.number; + const auto gas_left = state.gas_left + correction; + if (gas_left <= 2300) + return state.exit(EVMC_OUT_OF_GAS); + } + const auto key = intx::be::store(state.stack.pop()); const auto value = intx::be::store(state.stack.pop()); auto status = state.host.set_storage(state.msg->destination, key, value); diff --git a/test/unittests/evm_state_test.cpp b/test/unittests/evm_state_test.cpp index 8550175f18..0cfa0c2059 100644 --- a/test/unittests/evm_state_test.cpp +++ b/test/unittests/evm_state_test.cpp @@ -164,6 +164,26 @@ TEST_F(evm_state, sstore_cost) } } +TEST_F(evm_state, sstore_below_stipend) +{ + const auto code = sstore(0, 0); + + rev = EVMC_HOMESTEAD; + execute(2306, code); + EXPECT_EQ(result.status_code, EVMC_OUT_OF_GAS); + + rev = EVMC_CONSTANTINOPLE; + execute(2306, code); + EXPECT_EQ(result.status_code, EVMC_SUCCESS); + + rev = EVMC_ISTANBUL; + execute(2306, code); + EXPECT_EQ(result.status_code, EVMC_OUT_OF_GAS); + + execute(2307, code); + EXPECT_EQ(result.status_code, EVMC_SUCCESS); +} + TEST_F(evm_state, tx_context) { host.tx_context.block_timestamp = 0xdd;