diff --git a/nimbus/vm/interpreter/opcodes_impl.nim b/nimbus/vm/interpreter/opcodes_impl.nim index 4e7d33ca4..b61f1b183 100644 --- a/nimbus/vm/interpreter/opcodes_impl.nim +++ b/nimbus/vm/interpreter/opcodes_impl.nim @@ -121,10 +121,11 @@ op signExtend, inline = false, bits, value: var res: UInt256 if bits <= 31.u256: let + one = 1.u256 testBit = bits.toInt * 8 + 7 - bitPos = (1 shl testBit) - mask = u256(bitPos - 1) - if not isZero(value and bitPos.u256): + bitPos = one shl testBit + mask = bitPos - one + if not isZero(value and bitPos): res = value or (not mask) else: res = value and mask diff --git a/tests/test_op_arith.nim b/tests/test_op_arith.nim index cfafaca7f..c70c8afd3 100644 --- a/tests/test_op_arith.nim +++ b/tests/test_op_arith.nim @@ -341,3 +341,12 @@ suite "Arithmetic Opcodes": SMOD success: false stack: "0x000000000000000000000000000000000000000000000000000000000000001E" + + # real case, EVM bug, integer over flow + assembler: # SIGNEXTEND OP + title: "SIGNEXTEND_1" + code: + PUSH32 "0x000000000000000000000000000000003f9b347132d29b62d161117bca8c7307" + PUSH1 "0x0F" + SIGNEXTEND + stack: "0x000000000000000000000000000000003f9b347132d29b62d161117bca8c7307" diff --git a/tests/test_op_env.nim b/tests/test_op_env.nim index 6a1cd3571..024cfa443 100644 --- a/tests/test_op_env.nim +++ b/tests/test_op_env.nim @@ -280,8 +280,6 @@ suite "Environmental Information Opcodes": "0x5E" "0x07" - # macro_assembler automatically insert STOP instruction at the end, - # so codesize become 63, not 62 like ethereumj assembler: # CODESIZE OP title: "CODESIZE_1" code: @@ -289,7 +287,7 @@ suite "Environmental Information Opcodes": "0x602001600a5254516040016014525451606001601e5254516080016028525460" "0xa052546016604860003960166000f26000603f556103e75660005460005360200235" stack: - "0x0000000000000000000000000000000000000000000000000000000000000063" + "0x0000000000000000000000000000000000000000000000000000000000000062" success: false # 0x94 == 148 bytes