diff --git a/state/runtime/evm/instructions.go b/state/runtime/evm/instructions.go index 7cd86a58e6..73b64924d6 100644 --- a/state/runtime/evm/instructions.go +++ b/state/runtime/evm/instructions.go @@ -855,6 +855,10 @@ func opCodeCopy(c *state) { dataOffset := c.pop() length := c.pop() + if length.Uint64() <= 0 { + return + } + if !c.allocateMemory(memOffset, length) { return } diff --git a/state/runtime/evm/instructions_test.go b/state/runtime/evm/instructions_test.go index 04053e2510..95bab07923 100644 --- a/state/runtime/evm/instructions_test.go +++ b/state/runtime/evm/instructions_test.go @@ -1127,6 +1127,23 @@ func TestCallDataCopy(t *testing.T) { assert.Equal(t, big.NewInt(1).FillBytes(make([]byte, 32)), s.memory) } +func TestCodeCopyLenZero(t *testing.T) { + s, cancelFn := getState(&chain.ForksInTime{}) + defer cancelFn() + + var expectedGas = s.gas + + s.push(big.NewInt(0)) //length + s.push(big.NewInt(0)) //dataOffset + s.push(big.NewInt(0)) //memOffset + + opCodeCopy(s) + + // We check that no gas was spent and there was no error + assert.Equal(t, expectedGas, s.gas) + assert.NoError(t, s.err) +} + func TestCodeCopy(t *testing.T) { s, cancelFn := getState(&chain.ForksInTime{}) defer cancelFn()