diff --git a/libethcore/EVMSchedule.h b/libethcore/EVMSchedule.h index 7f024da916e..205614b0b00 100644 --- a/libethcore/EVMSchedule.h +++ b/libethcore/EVMSchedule.h @@ -58,6 +58,7 @@ struct EVMSchedule unsigned logTopicGas = 375; unsigned createGas = 32000; unsigned callGas = 40; + unsigned precompileStaticCallGas = 700; unsigned callStipend = 2300; unsigned callValueTransferGas = 9000; unsigned callNewAccountGas = 25000; @@ -151,6 +152,7 @@ static const EVMSchedule IstanbulSchedule = [] { EVMSchedule schedule = ConstantinopleFixSchedule; schedule.accountVersion = 1; schedule.txDataNonZeroGas = 16; + schedule.precompileStaticCallGas = 40; return schedule; }(); diff --git a/libevm/LegacyVMCalls.cpp b/libevm/LegacyVMCalls.cpp index 1d418fcd037..14438b44b90 100644 --- a/libevm/LegacyVMCalls.cpp +++ b/libevm/LegacyVMCalls.cpp @@ -204,13 +204,16 @@ bool LegacyVM::caseCallSetup(CallParameters *callParams, bytesRef& o_output) assert(callParams->valueTransfer == 0); assert(callParams->apparentValue == 0); - m_runGas = toInt63(m_schedule->callGas); - callParams->staticCall = (m_OP == Instruction::STATICCALL || m_ext->staticCall); + Address const destinationAddr = asAddress(m_SP[1]); + + if (callParams->staticCall && isPrecompiledContract(destinationAddr)) + m_runGas = toInt63(m_schedule->precompileStaticCallGas); + else + m_runGas = toInt63(m_schedule->callGas); bool const haveValueArg = m_OP == Instruction::CALL || m_OP == Instruction::CALLCODE; - Address destinationAddr = asAddress(m_SP[1]); if (m_OP == Instruction::CALL && (m_SP[2] > 0 || m_schedule->zeroValueTransferChargesNewAccountGas()) && !m_ext->exists(destinationAddr)) diff --git a/libevm/VMFace.h b/libevm/VMFace.h index a0ee72301c8..af250afba57 100644 --- a/libevm/VMFace.h +++ b/libevm/VMFace.h @@ -87,5 +87,11 @@ inline u256 fromAddress(Address _a) return (u160)_a; } +// Checks whether address is in the address range for precompiles according to EIP-1352 +inline bool isPrecompiledContract(Address const& _addr) noexcept +{ + static Address const c_maxPrecompiledAddress{0xffff}; + return _addr <= c_maxPrecompiledAddress; +} } }