diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index 218824e1f..94912eda1 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -398,9 +398,10 @@ func (v *VM) execute(ctx *Context, op Instruction) { v.estack.PushVal(v.estack.Len()) case NIP: - elem := v.estack.Pop() - _ = v.estack.Pop() - v.estack.Push(elem) + elem := v.estack.RemoveAt(1) + if elem == nil { + panic("no second element found") + } case OVER: b := v.estack.Pop() diff --git a/pkg/vm/vm_test.go b/pkg/vm/vm_test.go index 4f2b1b231..b85f4bc0c 100644 --- a/pkg/vm/vm_test.go +++ b/pkg/vm/vm_test.go @@ -803,6 +803,25 @@ func TestOVERgood(t *testing.T) { assert.Equal(t, 3, vm.estack.Len()) } +func TestNIPBadNoItem(t *testing.T) { + prog := makeProgram(NIP) + vm := load(prog) + vm.estack.PushVal(1) + vm.Run() + assert.Equal(t, true, vm.state.HasFlag(faultState)) +} + +func TestNIPGood(t *testing.T) { + prog := makeProgram(NIP) + vm := load(prog) + vm.estack.PushVal(1) + vm.estack.PushVal(2) + vm.Run() + assert.Equal(t, false, vm.state.HasFlag(faultState)) + assert.Equal(t, 1, vm.estack.Len()) + assert.Equal(t, makeStackItem(2), vm.estack.Pop().value) +} + func TestDROPBadNoItem(t *testing.T) { prog := makeProgram(DROP) vm := load(prog)