diff --git a/eth/vm/logic/arithmetic.py b/eth/vm/logic/arithmetic.py index f52aa628bd..3809d77d11 100644 --- a/eth/vm/logic/arithmetic.py +++ b/eth/vm/logic/arithmetic.py @@ -147,7 +147,9 @@ def exp(computation, gas_per_byte): bit_size = exponent.bit_length() byte_size = ceil8(bit_size) // 8 - if base == 0: + if exponent == 0: + result = 1 + elif base == 0: result = 0 else: result = pow(base, exponent, constants.UINT_256_CEILING) diff --git a/tests/core/opcodes/test_opcodes.py b/tests/core/opcodes/test_opcodes.py index 6e9ca5ba18..39d3793bb5 100644 --- a/tests/core/opcodes/test_opcodes.py +++ b/tests/core/opcodes/test_opcodes.py @@ -123,6 +123,32 @@ def test_mul(vm_class, val1, val2, expected): assert result == expected +@pytest.mark.parametrize( + 'vm_class, base, exponent, expected', + ( + (ByzantiumVM, 0, 1, 0,), + (ByzantiumVM, 0, 0, 1,), + (SpuriousDragonVM, 0, 1, 0,), + (SpuriousDragonVM, 0, 0, 1,), + (TangerineWhistleVM, 0, 1, 0,), + (TangerineWhistleVM, 0, 0, 1,), + (HomesteadVM, 0, 1, 0,), + (HomesteadVM, 0, 0, 1,), + (FrontierVM, 0, 1, 0,), + (FrontierVM, 0, 0, 1,), + ) +) +def test_exp(vm_class, base, exponent, expected): + computation = prepare_computation(vm_class) + computation.stack_push(exponent) + computation.stack_push(base) + computation.opcodes[opcode_values.EXP](computation) + + result = computation.stack_pop(type_hint=constants.UINT256) + + assert result == expected + + @pytest.mark.parametrize( # Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shl-shift-left 'vm_class, val1, val2, expected',