Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -1192,11 +1192,11 @@ func opDupN(pc *uint64, evm *CVM, scope *ScopeContext) ([]byte, error) {
code := scope.Contract.Code
i := *pc + 1

// Ensure an immediate byte exists after DUPN
if i >= uint64(len(code)) {
return nil, &ErrInvalidOpCode{opcode: INVALID}
// If the immediate byte is missing, treat as 0x00 (same convention as PUSHn).
var x byte
if i < uint64(len(code)) {
x = code[i]
}
x := code[i]

// This range is excluded to preserve compatibility with existing opcodes.
if x > 90 && x < 128 {
Expand All @@ -1219,11 +1219,11 @@ func opSwapN(pc *uint64, evm *CVM, scope *ScopeContext) ([]byte, error) {
code := scope.Contract.Code
i := *pc + 1

// Ensure an immediate byte exists after SWAPN
if i >= uint64(len(code)) {
return nil, &ErrInvalidOpCode{opcode: INVALID}
// If the immediate byte is missing, treat as 0x00 (same convention as PUSHn).
var x byte
if i < uint64(len(code)) {
x = code[i]
}
x := code[i]

// This range is excluded to preserve compatibility with existing opcodes.
if x > 90 && x < 128 {
Expand All @@ -1248,11 +1248,11 @@ func opExchange(pc *uint64, evm *CVM, scope *ScopeContext) ([]byte, error) {
code := scope.Contract.Code
i := *pc + 1

// Ensure an immediate byte exists after EXCHANGE
if i >= uint64(len(code)) {
return nil, &ErrInvalidOpCode{opcode: INVALID}
// If the immediate byte is missing, treat as 0x00 (same convention as PUSHn).
var x byte
if i < uint64(len(code)) {
x = code[i]
}
x := code[i]

// This range is excluded both to preserve compatibility with existing opcodes
// and to keep decode_pair’s 16-aligned arithmetic mapping valid (0–79, 128–255).
Expand Down
62 changes: 37 additions & 25 deletions core/vm/instructions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,15 @@ func TestEIP8024_Execution(t *testing.T) {
1,
},
},
{
name: "DUPN_MISSING_IMMEDIATE",
codeHex: "60016000808080808080808080808080808080e6",
wantVals: []uint64{
1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1,
},
},
{
name: "SWAPN",
codeHex: "600160008080808080808080808080808080806002e700",
Expand All @@ -786,11 +795,29 @@ func TestEIP8024_Execution(t *testing.T) {
2,
},
},
{
name: "SWAPN_MISSING_IMMEDIATE",
codeHex: "600160008080808080808080808080808080806002e7",
wantVals: []uint64{
1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2,
},
},
{
name: "EXCHANGE",
codeHex: "600060016002e801",
wantVals: []uint64{2, 0, 1},
},
{
name: "EXCHANGE_MISSING_IMMEDIATE",
codeHex: "600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060006000600060016002e8",
wantVals: []uint64{
2,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1,
},
},
{
name: "INVALID_SWAPN_LOW",
codeHex: "e75b",
Expand Down Expand Up @@ -842,21 +869,6 @@ func TestEIP8024_Execution(t *testing.T) {
codeHex: "60016002e801", // (n,m)=(1,2), need 3 items, have 2
wantErr: true,
},
{
name: "MISSING_IMMEDIATE_DUPN",
codeHex: "e6", // no operand
wantErr: true,
},
{
name: "MISSING_IMMEDIATE_SWAPN",
codeHex: "e7", // no operand
wantErr: true,
},
{
name: "MISSING_IMMEDIATE_EXCHANGE",
codeHex: "e8", // no operand
wantErr: true,
},
{
name: "PC_INCREMENT",
codeHex: "600060006000e80115",
Expand All @@ -873,25 +885,25 @@ func TestEIP8024_Execution(t *testing.T) {
var err error
for pc < uint64(len(code)) && err == nil {
op := code[pc]
switch op {
case 0x00:
switch OpCode(op) {
case STOP:
return
case 0x60:
case PUSH1:
_, err = opPush1(&pc, evm, scope)
case 0x80:
case DUP1:
dup1 := makeDup(1)
_, err = dup1(&pc, evm, scope)
case 0x56:
case JUMP:
_, err = opJump(&pc, evm, scope)
case 0x5b:
case JUMPDEST:
_, err = opJumpdest(&pc, evm, scope)
case 0x15:
case ISZERO:
_, err = opIszero(&pc, evm, scope)
case 0xe6:
case DUPN:
_, err = opDupN(&pc, evm, scope)
case 0xe7:
case SWAPN:
_, err = opSwapN(&pc, evm, scope)
case 0xe8:
case EXCHANGE:
_, err = opExchange(&pc, evm, scope)
default:
err = &ErrInvalidOpCode{opcode: OpCode(op)}
Expand Down
23 changes: 23 additions & 0 deletions core/vm/opcodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,29 @@ const (
LOG4
)

// 0xd0 range - eof operations.
const (
DATALOAD OpCode = 0xd0
DATALOADN OpCode = 0xd1
DATASIZE OpCode = 0xd2
DATACOPY OpCode = 0xd3
)

// 0xe0 range - eof operations.
const (
RJUMP OpCode = 0xe0
RJUMPI OpCode = 0xe1
RJUMPV OpCode = 0xe2
CALLF OpCode = 0xe3
RETF OpCode = 0xe4
JUMPF OpCode = 0xe5
DUPN OpCode = 0xe6
SWAPN OpCode = 0xe7
EXCHANGE OpCode = 0xe8
EOFCREATE OpCode = 0xec
RETURNCONTRACT OpCode = 0xee
)

// 0xf0 range - closures.
const (
CREATE OpCode = 0xf0 + iota
Expand Down
Loading