diff --git a/docs/testing-contracts-ethtester.rst b/docs/testing-contracts-ethtester.rst index 992cdc312a..1b7e9e3263 100644 --- a/docs/testing-contracts-ethtester.rst +++ b/docs/testing-contracts-ethtester.rst @@ -55,9 +55,9 @@ To test events and failed transactions we expand our simple storage contract to Next, we take a look at the two fixtures that will allow us to read the event logs and to check for failed transactions. -.. literalinclude:: ../tests/base_conftest.py +.. literalinclude:: ../tests/conftest.py :language: python - :pyobject: assert_tx_failed + :pyobject: tx_failed The fixture to assert failed transactions defaults to check for a ``TransactionFailed`` exception, but can be used to check for different exceptions too, as shown below. Also note that the chain gets reverted to the state before the failed transaction. diff --git a/tests/conftest.py b/tests/conftest.py index 925a025a4a..51b4b4459a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,6 @@ import json import logging +from contextlib import contextmanager from functools import wraps import hypothesis @@ -411,23 +412,6 @@ def assert_compile_failed(function_to_test, exception=Exception): return assert_compile_failed -# TODO this should not be a fixture -@pytest.fixture -def search_for_sublist(): - def search_for_sublist(ir, sublist): - _list = ir.to_list() if hasattr(ir, "to_list") else ir - if _list == sublist: - return True - if isinstance(_list, list): - for i in _list: - ret = search_for_sublist(i, sublist) - if ret is True: - return ret - return False - - return search_for_sublist - - @pytest.fixture def create2_address_of(keccak): def _f(_addr, _salt, _initcode): @@ -484,16 +468,16 @@ def get_logs(tx_hash, c, event_name): return get_logs -# TODO replace me with function like `with anchor_state()` @pytest.fixture(scope="module") -def assert_tx_failed(tester): - def assert_tx_failed(function_to_test, exception=TransactionFailed, exc_text=None): +def tx_failed(tester): + @contextmanager + def fn(exception=TransactionFailed, exc_text=None): snapshot_id = tester.take_snapshot() with pytest.raises(exception) as excinfo: - function_to_test() + yield excinfo tester.revert_to_snapshot(snapshot_id) if exc_text: # TODO test equality assert exc_text in str(excinfo.value), (exc_text, excinfo.value) - return assert_tx_failed + return fn diff --git a/tests/functional/builtins/codegen/test_abi_decode.py b/tests/functional/builtins/codegen/test_abi_decode.py index 242841e1cf..69bfef63ea 100644 --- a/tests/functional/builtins/codegen/test_abi_decode.py +++ b/tests/functional/builtins/codegen/test_abi_decode.py @@ -331,7 +331,7 @@ def abi_decode(x: Bytes[32]) -> uint256: b"\x01" * 96, # Length of byte array is beyond size bound of output type ], ) -def test_clamper(get_contract, assert_tx_failed, input_): +def test_clamper(get_contract, tx_failed, input_): contract = """ @external def abi_decode(x: Bytes[96]) -> (uint256, uint256): @@ -341,10 +341,11 @@ def abi_decode(x: Bytes[96]) -> (uint256, uint256): return a, b """ c = get_contract(contract) - assert_tx_failed(lambda: c.abi_decode(input_)) + with tx_failed(): + c.abi_decode(input_) -def test_clamper_nested_uint8(get_contract, assert_tx_failed): +def test_clamper_nested_uint8(get_contract, tx_failed): # check that _abi_decode clamps on word-types even when it is in a nested expression # decode -> validate uint8 -> revert if input >= 256 -> cast back to uint256 contract = """ @@ -355,10 +356,11 @@ def abi_decode(x: uint256) -> uint256: """ c = get_contract(contract) assert c.abi_decode(255) == 255 - assert_tx_failed(lambda: c.abi_decode(256)) + with tx_failed(): + c.abi_decode(256) -def test_clamper_nested_bytes(get_contract, assert_tx_failed): +def test_clamper_nested_bytes(get_contract, tx_failed): # check that _abi_decode clamps dynamic even when it is in a nested expression # decode -> validate Bytes[20] -> revert if len(input) > 20 -> convert back to -> add 1 contract = """ @@ -369,7 +371,8 @@ def abi_decode(x: Bytes[96]) -> Bytes[21]: """ c = get_contract(contract) assert c.abi_decode(abi.encode("(bytes)", (b"bc",))) == b"abc" - assert_tx_failed(lambda: c.abi_decode(abi.encode("(bytes)", (b"a" * 22,)))) + with tx_failed(): + c.abi_decode(abi.encode("(bytes)", (b"a" * 22,))) @pytest.mark.parametrize( @@ -381,7 +384,7 @@ def abi_decode(x: Bytes[96]) -> Bytes[21]: ("Bytes[5]", b"\x01" * 192), ], ) -def test_clamper_dynamic(get_contract, assert_tx_failed, output_typ, input_): +def test_clamper_dynamic(get_contract, tx_failed, output_typ, input_): contract = f""" @external def abi_decode(x: Bytes[192]) -> {output_typ}: @@ -390,7 +393,8 @@ def abi_decode(x: Bytes[192]) -> {output_typ}: return a """ c = get_contract(contract) - assert_tx_failed(lambda: c.abi_decode(input_)) + with tx_failed(): + c.abi_decode(input_) @pytest.mark.parametrize( @@ -422,7 +426,7 @@ def abi_decode(x: Bytes[160]) -> uint256: ("Bytes[5]", "address", b"\x01" * 128), ], ) -def test_clamper_dynamic_tuple(get_contract, assert_tx_failed, output_typ1, output_typ2, input_): +def test_clamper_dynamic_tuple(get_contract, tx_failed, output_typ1, output_typ2, input_): contract = f""" @external def abi_decode(x: Bytes[224]) -> ({output_typ1}, {output_typ2}): @@ -432,7 +436,8 @@ def abi_decode(x: Bytes[224]) -> ({output_typ1}, {output_typ2}): return a, b """ c = get_contract(contract) - assert_tx_failed(lambda: c.abi_decode(input_)) + with tx_failed(): + c.abi_decode(input_) FAIL_LIST = [ diff --git a/tests/functional/builtins/codegen/test_addmod.py b/tests/functional/builtins/codegen/test_addmod.py index b3135660bb..00745c0cdb 100644 --- a/tests/functional/builtins/codegen/test_addmod.py +++ b/tests/functional/builtins/codegen/test_addmod.py @@ -1,4 +1,4 @@ -def test_uint256_addmod(assert_tx_failed, get_contract_with_gas_estimation): +def test_uint256_addmod(tx_failed, get_contract_with_gas_estimation): uint256_code = """ @external def _uint256_addmod(x: uint256, y: uint256, z: uint256) -> uint256: @@ -11,7 +11,8 @@ def _uint256_addmod(x: uint256, y: uint256, z: uint256) -> uint256: assert c._uint256_addmod(32, 2, 32) == 2 assert c._uint256_addmod((2**256) - 1, 0, 2) == 1 assert c._uint256_addmod(2**255, 2**255, 6) == 4 - assert_tx_failed(lambda: c._uint256_addmod(1, 2, 0)) + with tx_failed(): + c._uint256_addmod(1, 2, 0) def test_uint256_addmod_ext_call( diff --git a/tests/functional/builtins/codegen/test_as_wei_value.py b/tests/functional/builtins/codegen/test_as_wei_value.py index cc27507e7c..522684fa05 100644 --- a/tests/functional/builtins/codegen/test_as_wei_value.py +++ b/tests/functional/builtins/codegen/test_as_wei_value.py @@ -23,7 +23,7 @@ @pytest.mark.parametrize("denom,multiplier", wei_denoms.items()) -def test_wei_uint256(get_contract, assert_tx_failed, denom, multiplier): +def test_wei_uint256(get_contract, tx_failed, denom, multiplier): code = f""" @external def foo(a: uint256) -> uint256: @@ -36,11 +36,12 @@ def foo(a: uint256) -> uint256: assert c.foo(value) == value * (10**multiplier) value = (2**256 - 1) // (10 ** (multiplier - 1)) - assert_tx_failed(lambda: c.foo(value)) + with tx_failed(): + c.foo(value) @pytest.mark.parametrize("denom,multiplier", wei_denoms.items()) -def test_wei_int128(get_contract, assert_tx_failed, denom, multiplier): +def test_wei_int128(get_contract, tx_failed, denom, multiplier): code = f""" @external def foo(a: int128) -> uint256: @@ -54,7 +55,7 @@ def foo(a: int128) -> uint256: @pytest.mark.parametrize("denom,multiplier", wei_denoms.items()) -def test_wei_decimal(get_contract, assert_tx_failed, denom, multiplier): +def test_wei_decimal(get_contract, tx_failed, denom, multiplier): code = f""" @external def foo(a: decimal) -> uint256: @@ -69,7 +70,7 @@ def foo(a: decimal) -> uint256: @pytest.mark.parametrize("value", (-1, -(2**127))) @pytest.mark.parametrize("data_type", ["decimal", "int128"]) -def test_negative_value_reverts(get_contract, assert_tx_failed, value, data_type): +def test_negative_value_reverts(get_contract, tx_failed, value, data_type): code = f""" @external def foo(a: {data_type}) -> uint256: @@ -77,12 +78,13 @@ def foo(a: {data_type}) -> uint256: """ c = get_contract(code) - assert_tx_failed(lambda: c.foo(value)) + with tx_failed(): + c.foo(value) @pytest.mark.parametrize("denom,multiplier", wei_denoms.items()) @pytest.mark.parametrize("data_type", ["decimal", "int128", "uint256"]) -def test_zero_value(get_contract, assert_tx_failed, denom, multiplier, data_type): +def test_zero_value(get_contract, tx_failed, denom, multiplier, data_type): code = f""" @external def foo(a: {data_type}) -> uint256: diff --git a/tests/functional/builtins/codegen/test_convert.py b/tests/functional/builtins/codegen/test_convert.py index 99dae4a932..559e1448ef 100644 --- a/tests/functional/builtins/codegen/test_convert.py +++ b/tests/functional/builtins/codegen/test_convert.py @@ -511,7 +511,7 @@ def bar(a: uint256) -> Roles: @pytest.mark.parametrize("typ", ["uint8", "int128", "int256", "uint256"]) @pytest.mark.parametrize("val", [1, 2, 3, 4, 2**128, 2**256 - 1, 2**256 - 2]) def test_flag_conversion_2( - get_contract_with_gas_estimation, assert_compile_failed, assert_tx_failed, val, typ + get_contract_with_gas_estimation, assert_compile_failed, tx_failed, val, typ ): contract = f""" flag Status: @@ -529,7 +529,8 @@ def foo(a: {typ}) -> Status: if lo <= val <= hi: assert c.foo(val) == val else: - assert_tx_failed(lambda: c.foo(val)) + with tx_failed(): + c.foo(val) else: assert_compile_failed(lambda: get_contract_with_gas_estimation(contract), TypeMismatch) @@ -608,7 +609,7 @@ def foo() -> {t_bytes}: @pytest.mark.parametrize("i_typ,o_typ,val", generate_reverting_cases()) @pytest.mark.fuzzing def test_conversion_failures( - get_contract_with_gas_estimation, assert_compile_failed, assert_tx_failed, i_typ, o_typ, val + get_contract_with_gas_estimation, assert_compile_failed, tx_failed, i_typ, o_typ, val ): """ Test multiple contracts and check for a specific exception. @@ -650,7 +651,8 @@ def foo(): """ c2 = get_contract_with_gas_estimation(contract_2) - assert_tx_failed(lambda: c2.foo()) + with tx_failed(): + c2.foo() contract_3 = f""" @external @@ -659,4 +661,5 @@ def foo(bar: {i_typ}) -> {o_typ}: """ c3 = get_contract_with_gas_estimation(contract_3) - assert_tx_failed(lambda: c3.foo(val)) + with tx_failed(): + c3.foo(val) diff --git a/tests/functional/builtins/codegen/test_create_functions.py b/tests/functional/builtins/codegen/test_create_functions.py index fa7729d98e..afa729ac8a 100644 --- a/tests/functional/builtins/codegen/test_create_functions.py +++ b/tests/functional/builtins/codegen/test_create_functions.py @@ -77,7 +77,7 @@ def test2() -> Bytes[100]: assert c.test2() == b"hello world!" -def test_minimal_proxy_exception(w3, get_contract, assert_tx_failed): +def test_minimal_proxy_exception(w3, get_contract, tx_failed): code = """ interface SubContract: @@ -111,7 +111,8 @@ def test2(a: uint256) -> Bytes[100]: c.test(transact={}) assert c.test2(1) == b"hello world!" - assert_tx_failed(lambda: c.test2(0)) + with tx_failed(): + c.test2(0) GAS_SENT = 30000 tx_hash = c.test2(0, transact={"gas": GAS_SENT}) @@ -122,9 +123,7 @@ def test2(a: uint256) -> Bytes[100]: assert receipt["gasUsed"] < GAS_SENT -def test_create_minimal_proxy_to_create2( - get_contract, create2_address_of, keccak, assert_tx_failed -): +def test_create_minimal_proxy_to_create2(get_contract, create2_address_of, keccak, tx_failed): code = """ main: address @@ -143,20 +142,15 @@ def test(_salt: bytes32) -> address: c.test(salt, transact={}) # revert on collision - assert_tx_failed(lambda: c.test(salt, transact={})) + with tx_failed(): + c.test(salt, transact={}) # test blueprints with various prefixes - 0xfe would block calls to the blueprint # contract, and 0xfe7100 is ERC5202 magic @pytest.mark.parametrize("blueprint_prefix", [b"", b"\xfe", b"\xfe\71\x00"]) def test_create_from_blueprint( - get_contract, - deploy_blueprint_for, - w3, - keccak, - create2_address_of, - assert_tx_failed, - blueprint_prefix, + get_contract, deploy_blueprint_for, w3, keccak, create2_address_of, tx_failed, blueprint_prefix ): code = """ @external @@ -193,7 +187,8 @@ def test2(target: address, salt: bytes32): # extcodesize check zero_address = "0x" + "00" * 20 - assert_tx_failed(lambda: d.test(zero_address)) + with tx_failed(): + d.test(zero_address) # now same thing but with create2 salt = keccak(b"vyper") @@ -209,11 +204,12 @@ def test2(target: address, salt: bytes32): assert HexBytes(test.address) == create2_address_of(d.address, salt, initcode) # can't collide addresses - assert_tx_failed(lambda: d.test2(f.address, salt)) + with tx_failed(): + d.test2(f.address, salt) def test_create_from_blueprint_bad_code_offset( - get_contract, get_contract_from_ir, deploy_blueprint_for, w3, assert_tx_failed + get_contract, get_contract_from_ir, deploy_blueprint_for, w3, tx_failed ): deployer_code = """ BLUEPRINT: immutable(address) @@ -254,15 +250,17 @@ def test(code_ofst: uint256) -> address: d.test(initcode_len - 1) # code_offset=len(blueprint) NOT fine! would EXTCODECOPY empty initcode - assert_tx_failed(lambda: d.test(initcode_len)) + with tx_failed(): + d.test(initcode_len) # code_offset=EIP_170_LIMIT definitely not fine! - assert_tx_failed(lambda: d.test(EIP_170_LIMIT)) + with tx_failed(): + d.test(EIP_170_LIMIT) # test create_from_blueprint with args def test_create_from_blueprint_args( - get_contract, deploy_blueprint_for, w3, keccak, create2_address_of, assert_tx_failed + get_contract, deploy_blueprint_for, w3, keccak, create2_address_of, tx_failed ): code = """ struct Bar: @@ -332,7 +330,8 @@ def should_fail(target: address, arg1: String[129], arg2: Bar): assert test.bar() == BAR # extcodesize check - assert_tx_failed(lambda: d.test("0x" + "00" * 20, FOO, BAR)) + with tx_failed(): + d.test("0x" + "00" * 20, FOO, BAR) # now same thing but with create2 salt = keccak(b"vyper") @@ -359,9 +358,11 @@ def should_fail(target: address, arg1: String[129], arg2: Bar): assert test.bar() == BAR # can't collide addresses - assert_tx_failed(lambda: d.test2(f.address, FOO, BAR, salt)) + with tx_failed(): + d.test2(f.address, FOO, BAR, salt) # ditto - with raw_args - assert_tx_failed(lambda: d.test4(f.address, encoded_args, salt)) + with tx_failed(): + d.test4(f.address, encoded_args, salt) # but creating a contract with different args is ok FOO = "bar" @@ -375,10 +376,11 @@ def should_fail(target: address, arg1: String[129], arg2: Bar): BAR = ("",) sig = keccak("should_fail(address,string,(string))".encode()).hex()[:10] encoded = abi.encode("(address,string,(string))", (f.address, FOO, BAR)).hex() - assert_tx_failed(lambda: w3.eth.send_transaction({"to": d.address, "data": f"{sig}{encoded}"})) + with tx_failed(): + w3.eth.send_transaction({"to": d.address, "data": f"{sig}{encoded}"}) -def test_create_copy_of(get_contract, w3, keccak, create2_address_of, assert_tx_failed): +def test_create_copy_of(get_contract, w3, keccak, create2_address_of, tx_failed): code = """ created_address: public(address) @internal @@ -412,7 +414,8 @@ def test2(target: address, salt: bytes32) -> address: assert w3.eth.get_code(test1) == bytecode # extcodesize check - assert_tx_failed(lambda: c.test("0x" + "00" * 20)) + with tx_failed(): + c.test("0x" + "00" * 20) # test1 = c.test(b"\x01") # assert w3.eth.get_code(test1) == b"\x01" @@ -425,12 +428,14 @@ def test2(target: address, salt: bytes32) -> address: assert HexBytes(test2) == create2_address_of(c.address, salt, vyper_initcode(bytecode)) # can't create2 where contract already exists - assert_tx_failed(lambda: c.test2(c.address, salt, transact={})) + with tx_failed(): + c.test2(c.address, salt, transact={}) # test single byte contract # test2 = c.test2(b"\x01", salt) # assert HexBytes(test2) == create2_address_of(c.address, salt, vyper_initcode(b"\x01")) - # assert_tx_failed(lambda: c.test2(bytecode, salt)) + # with tx_failed(): + # c.test2(bytecode, salt) # XXX: these various tests to check the msize allocator for diff --git a/tests/functional/builtins/codegen/test_extract32.py b/tests/functional/builtins/codegen/test_extract32.py index 6e4ee09abc..a95b57b5ab 100644 --- a/tests/functional/builtins/codegen/test_extract32.py +++ b/tests/functional/builtins/codegen/test_extract32.py @@ -1,4 +1,4 @@ -def test_extract32_extraction(assert_tx_failed, get_contract_with_gas_estimation): +def test_extract32_extraction(tx_failed, get_contract_with_gas_estimation): extract32_code = """ y: Bytes[100] @external @@ -34,18 +34,19 @@ def extrakt32_storage(index: uint256, inp: Bytes[100]) -> bytes32: ) for S, i in test_cases: - expected_result = S[i : i + 32] if 0 <= i <= len(S) - 32 else None - if expected_result is None: - assert_tx_failed(lambda p=(S, i): c.extrakt32(*p)) - else: + if 0 <= i <= len(S) - 32: + expected_result = S[i : i + 32] assert c.extrakt32(S, i) == expected_result assert c.extrakt32_mem(S, i) == expected_result assert c.extrakt32_storage(i, S) == expected_result + else: + with tx_failed(): + c.extrakt32(S, i) print("Passed bytes32 extraction test") -def test_extract32_code(assert_tx_failed, get_contract_with_gas_estimation): +def test_extract32_code(tx_failed, get_contract_with_gas_estimation): extract32_code = """ @external def foo(inp: Bytes[32]) -> int128: @@ -72,7 +73,8 @@ def foq(inp: Bytes[32]) -> address: assert c.foo(b"\x00" * 30 + b"\x01\x01") == 257 assert c.bar(b"\x00" * 30 + b"\x01\x01") == 257 - assert_tx_failed(lambda: c.foo(b"\x80" + b"\x00" * 30)) + with tx_failed(): + c.foo(b"\x80" + b"\x00" * 30) assert c.bar(b"\x80" + b"\x00" * 31) == 2**255 @@ -80,6 +82,7 @@ def foq(inp: Bytes[32]) -> address: assert c.fop(b"crow" * 8) == b"crow" * 8 assert c.foq(b"\x00" * 12 + b"3" * 20) == "0x" + "3" * 40 - assert_tx_failed(lambda: c.foq(b"crow" * 8)) + with tx_failed(): + c.foq(b"crow" * 8) print("Passed extract32 test") diff --git a/tests/functional/builtins/codegen/test_minmax.py b/tests/functional/builtins/codegen/test_minmax.py index da939d605a..f86504522f 100644 --- a/tests/functional/builtins/codegen/test_minmax.py +++ b/tests/functional/builtins/codegen/test_minmax.py @@ -198,7 +198,7 @@ def foo() -> uint256: def test_minmax_var_uint256_negative_int128( - get_contract_with_gas_estimation, assert_tx_failed, assert_compile_failed + get_contract_with_gas_estimation, tx_failed, assert_compile_failed ): from vyper.exceptions import TypeMismatch diff --git a/tests/functional/builtins/codegen/test_mulmod.py b/tests/functional/builtins/codegen/test_mulmod.py index 96477897b9..ba82ebd5b8 100644 --- a/tests/functional/builtins/codegen/test_mulmod.py +++ b/tests/functional/builtins/codegen/test_mulmod.py @@ -1,4 +1,4 @@ -def test_uint256_mulmod(assert_tx_failed, get_contract_with_gas_estimation): +def test_uint256_mulmod(tx_failed, get_contract_with_gas_estimation): uint256_code = """ @external def _uint256_mulmod(x: uint256, y: uint256, z: uint256) -> uint256: @@ -11,7 +11,8 @@ def _uint256_mulmod(x: uint256, y: uint256, z: uint256) -> uint256: assert c._uint256_mulmod(200, 3, 601) == 600 assert c._uint256_mulmod(2**255, 1, 3) == 2 assert c._uint256_mulmod(2**255, 2, 6) == 4 - assert_tx_failed(lambda: c._uint256_mulmod(2, 2, 0)) + with tx_failed(): + c._uint256_mulmod(2, 2, 0) def test_uint256_mulmod_complex(get_contract_with_gas_estimation): diff --git a/tests/functional/builtins/codegen/test_raw_call.py b/tests/functional/builtins/codegen/test_raw_call.py index 5bb23447e4..4d37176cf8 100644 --- a/tests/functional/builtins/codegen/test_raw_call.py +++ b/tests/functional/builtins/codegen/test_raw_call.py @@ -91,7 +91,7 @@ def create_and_return_proxy(inp: address) -> address: # print(f'Gas consumed: {(chain.head_state.receipts[-1].gas_used - chain.head_state.receipts[-2].gas_used - chain.last_tx.intrinsic_gas_used)}') # noqa: E501 -def test_multiple_levels2(assert_tx_failed, get_contract_with_gas_estimation): +def test_multiple_levels2(tx_failed, get_contract_with_gas_estimation): inner_code = """ @external def returnten() -> int128: @@ -114,7 +114,8 @@ def create_and_return_proxy(inp: address) -> address: c2 = get_contract_with_gas_estimation(outer_code) - assert_tx_failed(lambda: c2.create_and_call_returnten(c.address)) + with tx_failed(): + c2.create_and_call_returnten(c.address) print("Passed minimal proxy exception test") @@ -171,7 +172,7 @@ def set(i: int128, owner: address): assert outer_contract.owners(1) == a1 -def test_gas(get_contract, assert_tx_failed): +def test_gas(get_contract, tx_failed): inner_code = """ bar: bytes32 @@ -202,7 +203,8 @@ def foo_call(_addr: address): # manually specifying an insufficient amount should fail outer_contract = get_contract(outer_code.format(", gas=15000")) - assert_tx_failed(lambda: outer_contract.foo_call(inner_contract.address)) + with tx_failed(): + outer_contract.foo_call(inner_contract.address) def test_static_call(get_contract): @@ -323,7 +325,7 @@ def foo(_addr: address) -> bool: assert caller.foo(target.address) is True -def test_static_call_fails_nonpayable(get_contract, assert_tx_failed): +def test_static_call_fails_nonpayable(get_contract, tx_failed): target_source = """ baz: int128 @@ -349,10 +351,11 @@ def foo(_addr: address) -> int128: target = get_contract(target_source) caller = get_contract(caller_source) - assert_tx_failed(lambda: caller.foo(target.address)) + with tx_failed(): + caller.foo(target.address) -def test_checkable_raw_call(get_contract, assert_tx_failed): +def test_checkable_raw_call(get_contract, tx_failed): target_source = """ baz: int128 @external diff --git a/tests/functional/builtins/codegen/test_send.py b/tests/functional/builtins/codegen/test_send.py index 199f708cb4..36f8979556 100644 --- a/tests/functional/builtins/codegen/test_send.py +++ b/tests/functional/builtins/codegen/test_send.py @@ -1,4 +1,4 @@ -def test_send(assert_tx_failed, get_contract): +def test_send(tx_failed, get_contract): send_test = """ @external def foo(): @@ -9,9 +9,11 @@ def fop(): send(msg.sender, 10) """ c = get_contract(send_test, value=10) - assert_tx_failed(lambda: c.foo(transact={})) + with tx_failed(): + c.foo(transact={}) c.fop(transact={}) - assert_tx_failed(lambda: c.fop(transact={})) + with tx_failed(): + c.fop(transact={}) def test_default_gas(get_contract, w3): diff --git a/tests/functional/builtins/codegen/test_slice.py b/tests/functional/builtins/codegen/test_slice.py index 53e092019f..a15a3eeb35 100644 --- a/tests/functional/builtins/codegen/test_slice.py +++ b/tests/functional/builtins/codegen/test_slice.py @@ -41,7 +41,7 @@ def slice_tower_test(inp1: Bytes[50]) -> Bytes[50]: def test_slice_immutable( get_contract, assert_compile_failed, - assert_tx_failed, + tx_failed, opt_level, bytesdata, start, @@ -79,7 +79,8 @@ def _get_contract(): assert_compile_failed(lambda: _get_contract(), ArgumentException) elif start + length > len(bytesdata) or (len(bytesdata) > length_bound): # deploy fail - assert_tx_failed(lambda: _get_contract()) + with tx_failed(): + _get_contract() else: c = _get_contract() assert c.do_splice() == bytesdata[start : start + length] @@ -95,7 +96,7 @@ def _get_contract(): def test_slice_bytes_fuzz( get_contract, assert_compile_failed, - assert_tx_failed, + tx_failed, opt_level, location, bytesdata, @@ -175,10 +176,12 @@ def _get_contract(): assert_compile_failed(lambda: _get_contract(), (ArgumentException, TypeMismatch)) elif location == "code" and len(bytesdata) > length_bound: # deploy fail - assert_tx_failed(lambda: _get_contract()) + with tx_failed(): + _get_contract() elif end > len(bytesdata) or len(bytesdata) > length_bound: c = _get_contract() - assert_tx_failed(lambda: c.do_slice(bytesdata, start, length)) + with tx_failed(): + c.do_slice(bytesdata, start, length) else: c = _get_contract() assert c.do_slice(bytesdata, start, length) == bytesdata[start:end], code diff --git a/tests/functional/builtins/codegen/test_unary.py b/tests/functional/builtins/codegen/test_unary.py index da3823edfe..33f79be233 100644 --- a/tests/functional/builtins/codegen/test_unary.py +++ b/tests/functional/builtins/codegen/test_unary.py @@ -13,14 +13,15 @@ def negate(a: uint256) -> uint256: assert_compile_failed(lambda: get_contract(code), exception=InvalidOperation) -def test_unary_sub_int128_fail(get_contract, assert_tx_failed): +def test_unary_sub_int128_fail(get_contract, tx_failed): code = """@external def negate(a: int128) -> int128: return -(a) """ c = get_contract(code) # This test should revert on overflow condition - assert_tx_failed(lambda: c.negate(-(2**127))) + with tx_failed(): + c.negate(-(2**127)) @pytest.mark.parametrize("val", [-(2**127) + 1, 0, 2**127 - 1]) diff --git a/tests/functional/builtins/folding/test_abs.py b/tests/functional/builtins/folding/test_abs.py index 1c919d7826..a91a4f1ad3 100644 --- a/tests/functional/builtins/folding/test_abs.py +++ b/tests/functional/builtins/folding/test_abs.py @@ -39,7 +39,7 @@ def foo(a: int256) -> int256: get_contract(source) -def test_abs_lower_bound(get_contract, assert_tx_failed): +def test_abs_lower_bound(get_contract, tx_failed): source = """ @external def foo(a: int256) -> int256: @@ -47,10 +47,11 @@ def foo(a: int256) -> int256: """ contract = get_contract(source) - assert_tx_failed(lambda: contract.foo(-(2**255))) + with tx_failed(): + contract.foo(-(2**255)) -def test_abs_lower_bound_folded(get_contract, assert_tx_failed): +def test_abs_lower_bound_folded(get_contract, tx_failed): source = """ @external def foo() -> int256: diff --git a/tests/functional/codegen/calling_convention/test_default_function.py b/tests/functional/codegen/calling_convention/test_default_function.py index f7eef21af7..cf55607877 100644 --- a/tests/functional/codegen/calling_convention/test_default_function.py +++ b/tests/functional/codegen/calling_convention/test_default_function.py @@ -1,4 +1,4 @@ -def test_throw_on_sending(w3, assert_tx_failed, get_contract_with_gas_estimation): +def test_throw_on_sending(w3, tx_failed, get_contract_with_gas_estimation): code = """ x: public(int128) @@ -10,9 +10,8 @@ def __init__(): assert c.x() == 123 assert w3.eth.get_balance(c.address) == 0 - assert_tx_failed( - lambda: w3.eth.send_transaction({"to": c.address, "value": w3.to_wei(0.1, "ether")}) - ) + with tx_failed(): + w3.eth.send_transaction({"to": c.address, "value": w3.to_wei(0.1, "ether")}) assert w3.eth.get_balance(c.address) == 0 @@ -56,7 +55,7 @@ def __default__(): assert w3.eth.get_balance(c.address) == w3.to_wei(0.1, "ether") -def test_basic_default_not_payable(w3, assert_tx_failed, get_contract_with_gas_estimation): +def test_basic_default_not_payable(w3, tx_failed, get_contract_with_gas_estimation): code = """ event Sent: sender: indexed(address) @@ -67,7 +66,8 @@ def __default__(): """ c = get_contract_with_gas_estimation(code) - assert_tx_failed(lambda: w3.eth.send_transaction({"to": c.address, "value": 10**17})) + with tx_failed(): + w3.eth.send_transaction({"to": c.address, "value": 10**17}) def test_multi_arg_default(assert_compile_failed, get_contract_with_gas_estimation): @@ -100,7 +100,7 @@ def __default__(): assert_compile_failed(lambda: get_contract_with_gas_estimation(code)) -def test_zero_method_id(w3, get_logs, get_contract, assert_tx_failed): +def test_zero_method_id(w3, get_logs, get_contract, tx_failed): # test a method with 0x00000000 selector, # expects at least 36 bytes of calldata. code = """ @@ -143,10 +143,11 @@ def _call_with_bytes(hexstr): for i in range(4, 36): # match the full 4 selector bytes, but revert due to malformed (short) calldata - assert_tx_failed(lambda p="0x" + "00" * i: _call_with_bytes(p)) + with tx_failed(): + _call_with_bytes(f"0x{'00' * i}") -def test_another_zero_method_id(w3, get_logs, get_contract, assert_tx_failed): +def test_another_zero_method_id(w3, get_logs, get_contract, tx_failed): # test another zero method id but which only expects 4 bytes of calldata code = """ event Sent: diff --git a/tests/functional/codegen/calling_convention/test_default_parameters.py b/tests/functional/codegen/calling_convention/test_default_parameters.py index a90f5e6624..03f5d9fca2 100644 --- a/tests/functional/codegen/calling_convention/test_default_parameters.py +++ b/tests/functional/codegen/calling_convention/test_default_parameters.py @@ -150,7 +150,7 @@ def foo(a: int128[3] = [1, 2, 3]) -> int128[3]: assert c.foo() == [1, 2, 3] -def test_default_param_clamp(get_contract, monkeypatch, assert_tx_failed): +def test_default_param_clamp(get_contract, monkeypatch, tx_failed): code = """ @external def bar(a: int128, b: int128 = -1) -> (int128, int128): # noqa: E501 @@ -168,7 +168,8 @@ def validate_value(cls, value): monkeypatch.setattr("eth_abi.encoding.NumberEncoder.validate_value", validate_value) assert c.bar(200, 2**127 - 1) == [200, 2**127 - 1] - assert_tx_failed(lambda: c.bar(200, 2**127)) + with tx_failed(): + c.bar(200, 2**127) def test_default_param_private(get_contract): diff --git a/tests/functional/codegen/calling_convention/test_erc20_abi.py b/tests/functional/codegen/calling_convention/test_erc20_abi.py index 4a09ce68fa..b9dc5c663f 100644 --- a/tests/functional/codegen/calling_convention/test_erc20_abi.py +++ b/tests/functional/codegen/calling_convention/test_erc20_abi.py @@ -81,7 +81,7 @@ def test_initial_state(w3, erc20_caller): assert erc20_caller.decimals() == TOKEN_DECIMALS -def test_call_transfer(w3, erc20, erc20_caller, assert_tx_failed): +def test_call_transfer(w3, erc20, erc20_caller, tx_failed): # Basic transfer. erc20.transfer(erc20_caller.address, 10, transact={}) assert erc20.balanceOf(erc20_caller.address) == 10 @@ -90,13 +90,12 @@ def test_call_transfer(w3, erc20, erc20_caller, assert_tx_failed): assert erc20.balanceOf(w3.eth.accounts[1]) == 10 # more than allowed - assert_tx_failed(lambda: erc20_caller.transfer(w3.eth.accounts[1], TOKEN_TOTAL_SUPPLY)) + with tx_failed(): + erc20_caller.transfer(w3.eth.accounts[1], TOKEN_TOTAL_SUPPLY) # Negative transfer value. - assert_tx_failed( - function_to_test=lambda: erc20_caller.transfer(w3.eth.accounts[1], -1), - exception=ValidationError, - ) + with tx_failed(ValidationError): + erc20_caller.transfer(w3.eth.accounts[1], -1) def test_caller_approve_allowance(w3, erc20, erc20_caller): @@ -105,11 +104,10 @@ def test_caller_approve_allowance(w3, erc20, erc20_caller): assert erc20_caller.allowance(w3.eth.accounts[0], erc20_caller.address) == 10 -def test_caller_tranfer_from(w3, erc20, erc20_caller, assert_tx_failed): +def test_caller_tranfer_from(w3, erc20, erc20_caller, tx_failed): # Cannot transfer tokens that are unavailable - assert_tx_failed( - lambda: erc20_caller.transferFrom(w3.eth.accounts[0], erc20_caller.address, 10) - ) + with tx_failed(): + erc20_caller.transferFrom(w3.eth.accounts[0], erc20_caller.address, 10) assert erc20.balanceOf(erc20_caller.address) == 0 assert erc20.approve(erc20_caller.address, 10, transact={}) erc20_caller.transferFrom(w3.eth.accounts[0], erc20_caller.address, 5, transact={}) diff --git a/tests/functional/codegen/calling_convention/test_external_contract_calls.py b/tests/functional/codegen/calling_convention/test_external_contract_calls.py index 12fcde2f4f..0360396f03 100644 --- a/tests/functional/codegen/calling_convention/test_external_contract_calls.py +++ b/tests/functional/codegen/calling_convention/test_external_contract_calls.py @@ -3,6 +3,7 @@ import pytest from eth.codecs import abi +from vyper import compile_code from vyper.exceptions import ( ArgumentException, InvalidType, @@ -94,7 +95,7 @@ def get_array(arg1: address) -> Bytes[3]: assert c2.get_array(c.address) == b"dog" -def test_bytes_too_long(get_contract, assert_tx_failed): +def test_bytes_too_long(get_contract, tx_failed): contract_1 = """ @external def array() -> Bytes[4]: @@ -113,13 +114,14 @@ def get_array(arg1: address) -> Bytes[3]: """ c2 = get_contract(contract_2) - assert_tx_failed(lambda: c2.get_array(c.address)) + with tx_failed(): + c2.get_array(c.address) @pytest.mark.parametrize( "revert_string", ["Mayday, mayday!", "A very long revert string" + "." * 512] ) -def test_revert_propagation(get_contract, assert_tx_failed, revert_string): +def test_revert_propagation(get_contract, tx_failed, revert_string): raiser = f""" @external def run(): @@ -135,7 +137,8 @@ def run(raiser: address): """ c1 = get_contract(raiser) c2 = get_contract(caller) - assert_tx_failed(lambda: c2.run(c1.address), exc_text=revert_string) + with tx_failed(exc_text=revert_string): + c2.run(c1.address) @pytest.mark.parametrize("a,b", [(3, 3), (4, 3), (3, 4), (32, 32), (33, 33), (64, 64)]) @@ -169,7 +172,7 @@ def get_array(arg1: address) -> (Bytes[{a}], int128, Bytes[{b}]): @pytest.mark.parametrize("a,b", [(18, 7), (18, 18), (19, 6), (64, 6), (7, 19)]) @pytest.mark.parametrize("c,d", [(19, 7), (64, 64)]) -def test_tuple_with_bytes_too_long(get_contract, assert_tx_failed, a, c, b, d): +def test_tuple_with_bytes_too_long(get_contract, tx_failed, a, c, b, d): contract_1 = f""" @external def array() -> (Bytes[{c}], int128, Bytes[{d}]): @@ -193,10 +196,11 @@ def get_array(arg1: address) -> (Bytes[{a}], int128, Bytes[{b}]): c2 = get_contract(contract_2) assert c.array() == [b"nineteen characters", 255, b"seven!!"] - assert_tx_failed(lambda: c2.get_array(c.address)) + with tx_failed(): + c2.get_array(c.address) -def test_tuple_with_bytes_too_long_two(get_contract, assert_tx_failed): +def test_tuple_with_bytes_too_long_two(get_contract, tx_failed): contract_1 = """ @external def array() -> (Bytes[30], int128, Bytes[30]): @@ -220,7 +224,8 @@ def get_array(arg1: address) -> (Bytes[30], int128, Bytes[3]): c2 = get_contract(contract_2) assert c.array() == [b"nineteen characters", 255, b"seven!!"] - assert_tx_failed(lambda: c2.get_array(c.address)) + with tx_failed(): + c2.get_array(c.address) @pytest.mark.parametrize("length", [8, 256]) @@ -246,7 +251,7 @@ def bar(arg1: address) -> uint8: assert c2.bar(c.address) == 255 -def test_uint8_too_long(get_contract, assert_tx_failed): +def test_uint8_too_long(get_contract, tx_failed): contract_1 = """ @external def foo() -> uint256: @@ -265,7 +270,8 @@ def bar(arg1: address) -> uint8: """ c2 = get_contract(contract_2) - assert_tx_failed(lambda: c2.bar(c.address)) + with tx_failed(): + c2.bar(c.address) @pytest.mark.parametrize("a,b", [(8, 8), (8, 256), (256, 8), (256, 256)]) @@ -298,7 +304,7 @@ def bar(arg1: address) -> (uint{a}, Bytes[3], uint{b}): @pytest.mark.parametrize("a,b", [(8, 256), (256, 8), (256, 256)]) -def test_tuple_with_uint8_too_long(get_contract, assert_tx_failed, a, b): +def test_tuple_with_uint8_too_long(get_contract, tx_failed, a, b): contract_1 = f""" @external def foo() -> (uint{a}, Bytes[3], uint{b}): @@ -322,11 +328,12 @@ def bar(arg1: address) -> (uint8, Bytes[3], uint8): c2 = get_contract(contract_2) assert c.foo() == [int(f"{(2**a)-1}"), b"dog", int(f"{(2**b)-1}")] - assert_tx_failed(lambda: c2.bar(c.address)) + with tx_failed(): + c2.bar(c.address) @pytest.mark.parametrize("a,b", [(8, 256), (256, 8)]) -def test_tuple_with_uint8_too_long_two(get_contract, assert_tx_failed, a, b): +def test_tuple_with_uint8_too_long_two(get_contract, tx_failed, a, b): contract_1 = f""" @external def foo() -> (uint{b}, Bytes[3], uint{a}): @@ -350,7 +357,8 @@ def bar(arg1: address) -> (uint{a}, Bytes[3], uint{b}): c2 = get_contract(contract_2) assert c.foo() == [int(f"{(2**b)-1}"), b"dog", int(f"{(2**a)-1}")] - assert_tx_failed(lambda: c2.bar(c.address)) + with tx_failed(): + c2.bar(c.address) @pytest.mark.parametrize("length", [128, 256]) @@ -376,7 +384,7 @@ def bar(arg1: address) -> int128: assert c2.bar(c.address) == 1 -def test_int128_too_long(get_contract, assert_tx_failed): +def test_int128_too_long(get_contract, tx_failed): contract_1 = """ @external def foo() -> int256: @@ -395,7 +403,8 @@ def bar(arg1: address) -> int128: """ c2 = get_contract(contract_2) - assert_tx_failed(lambda: c2.bar(c.address)) + with tx_failed(): + c2.bar(c.address) @pytest.mark.parametrize("a,b", [(128, 128), (128, 256), (256, 128), (256, 256)]) @@ -428,7 +437,7 @@ def bar(arg1: address) -> (int{a}, Bytes[3], int{b}): @pytest.mark.parametrize("a,b", [(128, 256), (256, 128), (256, 256)]) -def test_tuple_with_int128_too_long(get_contract, assert_tx_failed, a, b): +def test_tuple_with_int128_too_long(get_contract, tx_failed, a, b): contract_1 = f""" @external def foo() -> (int{a}, Bytes[3], int{b}): @@ -452,11 +461,12 @@ def bar(arg1: address) -> (int128, Bytes[3], int128): c2 = get_contract(contract_2) assert c.foo() == [int(f"{(2**(a-1))-1}"), b"dog", int(f"{(2**(b-1))-1}")] - assert_tx_failed(lambda: c2.bar(c.address)) + with tx_failed(): + c2.bar(c.address) @pytest.mark.parametrize("a,b", [(128, 256), (256, 128)]) -def test_tuple_with_int128_too_long_two(get_contract, assert_tx_failed, a, b): +def test_tuple_with_int128_too_long_two(get_contract, tx_failed, a, b): contract_1 = f""" @external def foo() -> (int{b}, Bytes[3], int{a}): @@ -480,7 +490,8 @@ def bar(arg1: address) -> (int{a}, Bytes[3], int{b}): c2 = get_contract(contract_2) assert c.foo() == [int(f"{(2**(b-1))-1}"), b"dog", int(f"{(2**(a-1))-1}")] - assert_tx_failed(lambda: c2.bar(c.address)) + with tx_failed(): + c2.bar(c.address) @pytest.mark.parametrize("type", ["uint8", "uint256", "int128", "int256"]) @@ -506,7 +517,7 @@ def bar(arg1: address) -> decimal: assert c2.bar(c.address) == Decimal("1e-10") -def test_decimal_too_long(get_contract, assert_tx_failed): +def test_decimal_too_long(get_contract, tx_failed): contract_1 = """ @external def foo() -> uint256: @@ -525,7 +536,8 @@ def bar(arg1: address) -> decimal: """ c2 = get_contract(contract_2) - assert_tx_failed(lambda: c2.bar(c.address)) + with tx_failed(): + c2.bar(c.address) @pytest.mark.parametrize("a", ["uint8", "uint256", "int128", "int256"]) @@ -559,7 +571,7 @@ def bar(arg1: address) -> (decimal, Bytes[3], decimal): @pytest.mark.parametrize("a,b", [(8, 256), (256, 8), (256, 256)]) -def test_tuple_with_decimal_too_long(get_contract, assert_tx_failed, a, b): +def test_tuple_with_decimal_too_long(get_contract, tx_failed, a, b): contract_1 = f""" @external def foo() -> (uint{a}, Bytes[3], uint{b}): @@ -583,7 +595,8 @@ def bar(arg1: address) -> (decimal, Bytes[3], decimal): c2 = get_contract(contract_2) assert c.foo() == [2 ** (a - 1), b"dog", 2 ** (b - 1)] - assert_tx_failed(lambda: c2.bar(c.address)) + with tx_failed(): + c2.bar(c.address) @pytest.mark.parametrize("type", ["uint8", "uint256", "int128", "int256"]) @@ -609,7 +622,7 @@ def bar(arg1: address) -> bool: assert c2.bar(c.address) is True -def test_bool_too_long(get_contract, assert_tx_failed): +def test_bool_too_long(get_contract, tx_failed): contract_1 = """ @external def foo() -> uint256: @@ -628,7 +641,8 @@ def bar(arg1: address) -> bool: """ c2 = get_contract(contract_2) - assert_tx_failed(lambda: c2.bar(c.address)) + with tx_failed(): + c2.bar(c.address) @pytest.mark.parametrize("a", ["uint8", "uint256", "int128", "int256"]) @@ -662,7 +676,7 @@ def bar(arg1: address) -> (bool, Bytes[3], bool): @pytest.mark.parametrize("a", ["uint8", "uint256", "int128", "int256"]) @pytest.mark.parametrize("b", ["uint8", "uint256", "int128", "int256"]) -def test_tuple_with_bool_too_long(get_contract, assert_tx_failed, a, b): +def test_tuple_with_bool_too_long(get_contract, tx_failed, a, b): contract_1 = f""" @external def foo() -> ({a}, Bytes[3], {b}): @@ -686,7 +700,8 @@ def bar(arg1: address) -> (bool, Bytes[3], bool): c2 = get_contract(contract_2) assert c.foo() == [1, b"dog", 2] - assert_tx_failed(lambda: c2.bar(c.address)) + with tx_failed(): + c2.bar(c.address) @pytest.mark.parametrize("type", ["uint8", "int128", "uint256", "int256"]) @@ -736,7 +751,7 @@ def bar(arg1: address) -> address: @pytest.mark.parametrize("type", ["uint256", "int256"]) -def test_address_too_long(get_contract, assert_tx_failed, type): +def test_address_too_long(get_contract, tx_failed, type): contract_1 = f""" @external def foo() -> {type}: @@ -755,7 +770,8 @@ def bar(arg1: address) -> address: """ c2 = get_contract(contract_2) - assert_tx_failed(lambda: c2.bar(c.address)) + with tx_failed(): + c2.bar(c.address) @pytest.mark.parametrize("a", ["uint8", "int128", "uint256", "int256"]) @@ -826,7 +842,7 @@ def bar(arg1: address) -> (address, Bytes[3], address): @pytest.mark.parametrize("a", ["uint256", "int256"]) @pytest.mark.parametrize("b", ["uint256", "int256"]) -def test_tuple_with_address_too_long(get_contract, assert_tx_failed, a, b): +def test_tuple_with_address_too_long(get_contract, tx_failed, a, b): contract_1 = f""" @external def foo() -> ({a}, Bytes[3], {b}): @@ -850,7 +866,8 @@ def bar(arg1: address) -> (address, Bytes[3], address): c2 = get_contract(contract_2) assert c.foo() == [(2**160) - 1, b"dog", 2**160] - assert_tx_failed(lambda: c2.bar(c.address)) + with tx_failed(): + c2.bar(c.address) def test_external_contract_call_state_change(get_contract): @@ -1095,7 +1112,7 @@ def _expr(x: address) -> int128: assert c2._expr(c2.address) == 1 -def test_invalid_nonexistent_contract_call(w3, assert_tx_failed, get_contract): +def test_invalid_nonexistent_contract_call(w3, tx_failed, get_contract): contract_1 = """ @external def bar() -> int128: @@ -1115,11 +1132,13 @@ def foo(x: address) -> int128: c2 = get_contract(contract_2) assert c2.foo(c1.address) == 1 - assert_tx_failed(lambda: c2.foo(w3.eth.accounts[0])) - assert_tx_failed(lambda: c2.foo(w3.eth.accounts[3])) + with tx_failed(): + c2.foo(w3.eth.accounts[0]) + with tx_failed(): + c2.foo(w3.eth.accounts[3]) -def test_invalid_contract_reference_declaration(assert_tx_failed, get_contract): +def test_invalid_contract_reference_declaration(tx_failed, get_contract): contract = """ interface Bar: get_magic_number: 1 @@ -1130,19 +1149,21 @@ def test_invalid_contract_reference_declaration(assert_tx_failed, get_contract): def __init__(): pass """ - assert_tx_failed(lambda: get_contract(contract), exception=StructureException) + with tx_failed(exception=StructureException): + get_contract(contract) -def test_invalid_contract_reference_call(assert_tx_failed, get_contract): +def test_invalid_contract_reference_call(tx_failed, get_contract): contract = """ @external def bar(arg1: address, arg2: int128) -> int128: return Foo(arg1).foo(arg2) """ - assert_tx_failed(lambda: get_contract(contract), exception=UndeclaredDefinition) + with pytest.raises(UndeclaredDefinition): + compile_code(contract) -def test_invalid_contract_reference_return_type(assert_tx_failed, get_contract): +def test_invalid_contract_reference_return_type(tx_failed, get_contract): contract = """ interface Foo: def foo(arg2: int128) -> invalid: view @@ -1151,7 +1172,8 @@ def foo(arg2: int128) -> invalid: view def bar(arg1: address, arg2: int128) -> int128: return Foo(arg1).foo(arg2) """ - assert_tx_failed(lambda: get_contract(contract), exception=UnknownType) + with pytest.raises(UnknownType): + compile_code(contract) def test_external_contract_call_declaration_expr(get_contract): @@ -1378,7 +1400,7 @@ def get_lucky(amount_to_send: uint256) -> int128: assert w3.eth.get_balance(c2.address) == 250 -def test_external_call_with_gas(assert_tx_failed, get_contract_with_gas_estimation): +def test_external_call_with_gas(tx_failed, get_contract_with_gas_estimation): contract_1 = """ @external def get_lucky() -> int128: @@ -1406,7 +1428,8 @@ def get_lucky(gas_amount: uint256) -> int128: c2.set_contract(c1.address, transact={}) assert c2.get_lucky(1000) == 656598 - assert_tx_failed(lambda: c2.get_lucky(50)) # too little gas. + with tx_failed(): + c2.get_lucky(50) # too little gas. def test_skip_contract_check(get_contract_with_gas_estimation): @@ -2240,7 +2263,7 @@ def get_array(arg1: address) -> int128[3]: assert c2.get_array(c.address) == [0, 0, 0] -def test_returndatasize_too_short(get_contract, assert_tx_failed): +def test_returndatasize_too_short(get_contract, tx_failed): contract_1 = """ @external def bar(a: int128) -> int128: @@ -2256,10 +2279,11 @@ def foo(_addr: address): """ c1 = get_contract(contract_1) c2 = get_contract(contract_2) - assert_tx_failed(lambda: c2.foo(c1.address)) + with tx_failed(): + c2.foo(c1.address) -def test_returndatasize_empty(get_contract, assert_tx_failed): +def test_returndatasize_empty(get_contract, tx_failed): contract_1 = """ @external def bar(a: int128): @@ -2275,7 +2299,8 @@ def foo(_addr: address) -> int128: """ c1 = get_contract(contract_1) c2 = get_contract(contract_2) - assert_tx_failed(lambda: c2.foo(c1.address)) + with tx_failed(): + c2.foo(c1.address) def test_returndatasize_too_long(get_contract): @@ -2299,7 +2324,7 @@ def foo(_addr: address) -> int128: assert c2.foo(c1.address) == 456 -def test_no_returndata(get_contract, assert_tx_failed): +def test_no_returndata(get_contract, tx_failed): contract_1 = """ @external def bar(a: int128) -> int128: @@ -2321,10 +2346,11 @@ def foo(_addr: address, _addr2: address) -> int128: c2 = get_contract(contract_2) assert c2.foo(c1.address, c1.address) == 123 - assert_tx_failed(lambda: c2.foo(c1.address, "0x1234567890123456789012345678901234567890")) + with tx_failed(): + c2.foo(c1.address, "0x1234567890123456789012345678901234567890") -def test_default_override(get_contract, assert_tx_failed): +def test_default_override(get_contract, tx_failed): bad_erc20_code = """ @external def transfer(receiver: address, amount: uint256): @@ -2358,17 +2384,20 @@ def transferBorked(erc20: ERC20, receiver: address, amount: uint256): c = get_contract(code) # demonstrate transfer failing - assert_tx_failed(lambda: c.transferBorked(bad_erc20.address, c.address, 0)) + with tx_failed(): + c.transferBorked(bad_erc20.address, c.address, 0) # would fail without default_return_value assert c.safeTransfer(bad_erc20.address, c.address, 0) == 7 # check that `default_return_value` does not stomp valid returndata. negative_contract = get_contract(negative_transfer_code) - assert_tx_failed(lambda: c.safeTransfer(negative_contract.address, c.address, 0)) + with tx_failed(): + c.safeTransfer(negative_contract.address, c.address, 0) # default_return_value should fail on EOAs (addresses with no code) random_address = "0x0000000000000000000000000000000000001234" - assert_tx_failed(lambda: c.safeTransfer(random_address, c.address, 1)) + with tx_failed(): + c.safeTransfer(random_address, c.address, 1) # in this case, the extcodesize check runs after the token contract # selfdestructs. however, extcodesize still returns nonzero until @@ -2378,7 +2407,7 @@ def transferBorked(erc20: ERC20, receiver: address, amount: uint256): assert c.safeTransfer(self_destructing_contract.address, c.address, 0) == 7 -def test_default_override2(get_contract, assert_tx_failed): +def test_default_override2(get_contract, tx_failed): bad_code_1 = """ @external def return_64_bytes() -> bool: @@ -2407,7 +2436,8 @@ def bar(foo: Foo): c = get_contract(code) # fails due to returndatasize being nonzero but also lt 64 - assert_tx_failed(lambda: c.bar(bad_1.address)) + with tx_failed(): + c.bar(bad_1.address) c.bar(bad_2.address) @@ -2456,7 +2486,7 @@ def do_stuff(f: Foo) -> uint256: @pytest.mark.parametrize("typ,val", [("address", TEST_ADDR)]) -def test_calldata_clamp(w3, get_contract, assert_tx_failed, keccak, typ, val): +def test_calldata_clamp(w3, get_contract, tx_failed, keccak, typ, val): code = f""" @external def foo(a: {typ}): @@ -2469,7 +2499,8 @@ def foo(a: {typ}): # Static size is short by 1 byte malformed = data[:-2] - assert_tx_failed(lambda: w3.eth.send_transaction({"to": c1.address, "data": malformed})) + with tx_failed(): + w3.eth.send_transaction({"to": c1.address, "data": malformed}) # Static size is exact w3.eth.send_transaction({"to": c1.address, "data": data}) @@ -2479,7 +2510,7 @@ def foo(a: {typ}): @pytest.mark.parametrize("typ,val", [("address", ([TEST_ADDR] * 3, "vyper"))]) -def test_dynamic_calldata_clamp(w3, get_contract, assert_tx_failed, keccak, typ, val): +def test_dynamic_calldata_clamp(w3, get_contract, tx_failed, keccak, typ, val): code = f""" @external def foo(a: DynArray[{typ}, 3], b: String[5]): @@ -2493,7 +2524,8 @@ def foo(a: DynArray[{typ}, 3], b: String[5]): # Dynamic size is short by 1 byte malformed = data[:264] - assert_tx_failed(lambda: w3.eth.send_transaction({"to": c1.address, "data": malformed})) + with tx_failed(): + w3.eth.send_transaction({"to": c1.address, "data": malformed}) # Dynamic size is at least minimum (132 bytes * 2 + 2 (for 0x) = 266) valid = data[:266] diff --git a/tests/functional/codegen/calling_convention/test_modifiable_external_contract_calls.py b/tests/functional/codegen/calling_convention/test_modifiable_external_contract_calls.py index 4c321442f4..e6b2402016 100644 --- a/tests/functional/codegen/calling_convention/test_modifiable_external_contract_calls.py +++ b/tests/functional/codegen/calling_convention/test_modifiable_external_contract_calls.py @@ -1,7 +1,7 @@ from vyper.exceptions import StructureException, SyntaxException, UnknownType -def test_external_contract_call_declaration_expr(get_contract, assert_tx_failed): +def test_external_contract_call_declaration_expr(get_contract, tx_failed): contract_1 = """ lucky: public(int128) @@ -39,11 +39,12 @@ def static_set_lucky(_lucky: int128): c2.modifiable_set_lucky(7, transact={}) assert c1.lucky() == 7 # Fails attempting a state change after a call to a static address - assert_tx_failed(lambda: c2.static_set_lucky(5, transact={})) + with tx_failed(): + c2.static_set_lucky(5, transact={}) assert c1.lucky() == 7 -def test_external_contract_call_declaration_stmt(get_contract, assert_tx_failed): +def test_external_contract_call_declaration_stmt(get_contract, tx_failed): contract_1 = """ lucky: public(int128) @@ -83,11 +84,12 @@ def static_set_lucky(_lucky: int128): c2.modifiable_set_lucky(7, transact={}) assert c1.lucky() == 7 # Fails attempting a state change after a call to a static address - assert_tx_failed(lambda: c2.static_set_lucky(5, transact={})) + with tx_failed(): + c2.static_set_lucky(5, transact={}) assert c1.lucky() == 7 -def test_multiple_contract_state_changes(get_contract, assert_tx_failed): +def test_multiple_contract_state_changes(get_contract, tx_failed): contract_1 = """ lucky: public(int128) @@ -161,9 +163,12 @@ def static_modifiable_set_lucky(_lucky: int128): assert c1.lucky() == 0 c3.modifiable_modifiable_set_lucky(7, transact={}) assert c1.lucky() == 7 - assert_tx_failed(lambda: c3.modifiable_static_set_lucky(6, transact={})) - assert_tx_failed(lambda: c3.static_modifiable_set_lucky(6, transact={})) - assert_tx_failed(lambda: c3.static_static_set_lucky(6, transact={})) + with tx_failed(): + c3.modifiable_static_set_lucky(6, transact={}) + with tx_failed(): + c3.static_modifiable_set_lucky(6, transact={}) + with tx_failed(): + c3.static_static_set_lucky(6, transact={}) assert c1.lucky() == 7 diff --git a/tests/functional/codegen/calling_convention/test_return_tuple.py b/tests/functional/codegen/calling_convention/test_return_tuple.py index b375839147..266555ead6 100644 --- a/tests/functional/codegen/calling_convention/test_return_tuple.py +++ b/tests/functional/codegen/calling_convention/test_return_tuple.py @@ -1,5 +1,6 @@ import pytest +from vyper import compile_code from vyper.exceptions import TypeMismatch pytestmark = pytest.mark.usefixtures("memory_mocker") @@ -152,11 +153,11 @@ def test3() -> (address, int128): assert c.test3() == [c.out_literals()[2], 1] -def test_tuple_return_typecheck(assert_tx_failed, get_contract_with_gas_estimation): +def test_tuple_return_typecheck(tx_failed, get_contract_with_gas_estimation): code = """ @external def getTimeAndBalance() -> (bool, address): return block.timestamp, self.balance """ - - assert_tx_failed(lambda: get_contract_with_gas_estimation(code), TypeMismatch) + with pytest.raises(TypeMismatch): + compile_code(code) diff --git a/tests/functional/codegen/environment_variables/test_blockhash.py b/tests/functional/codegen/environment_variables/test_blockhash.py index b92c17a561..68db053b12 100644 --- a/tests/functional/codegen/environment_variables/test_blockhash.py +++ b/tests/functional/codegen/environment_variables/test_blockhash.py @@ -23,7 +23,7 @@ def foo() -> bytes32: assert_compile_failed(lambda: get_contract_with_gas_estimation(code)) -def test_too_old_blockhash(assert_tx_failed, get_contract_with_gas_estimation, w3): +def test_too_old_blockhash(tx_failed, get_contract_with_gas_estimation, w3): w3.testing.mine(257) code = """ @external @@ -31,14 +31,16 @@ def get_50_blockhash() -> bytes32: return blockhash(block.number - 257) """ c = get_contract_with_gas_estimation(code) - assert_tx_failed(lambda: c.get_50_blockhash()) + with tx_failed(): + c.get_50_blockhash() -def test_non_existing_blockhash(assert_tx_failed, get_contract_with_gas_estimation): +def test_non_existing_blockhash(tx_failed, get_contract_with_gas_estimation): code = """ @external def get_future_blockhash() -> bytes32: return blockhash(block.number + 1) """ c = get_contract_with_gas_estimation(code) - assert_tx_failed(lambda: c.get_future_blockhash()) + with tx_failed(): + c.get_future_blockhash() diff --git a/tests/functional/codegen/features/decorators/test_nonreentrant.py b/tests/functional/codegen/features/decorators/test_nonreentrant.py index 9e74019250..9329605678 100644 --- a/tests/functional/codegen/features/decorators/test_nonreentrant.py +++ b/tests/functional/codegen/features/decorators/test_nonreentrant.py @@ -5,7 +5,7 @@ # TODO test functions in this module across all evm versions # once we have cancun support. -def test_nonreentrant_decorator(get_contract, assert_tx_failed): +def test_nonreentrant_decorator(get_contract, tx_failed): calling_contract_code = """ interface SpecialContract: def unprotected_function(val: String[100], do_callback: bool): nonpayable @@ -98,20 +98,23 @@ def unprotected_function(val: String[100], do_callback: bool): assert reentrant_contract.special_value() == "some value" assert reentrant_contract.protected_view_fn() == "some value" - assert_tx_failed(lambda: reentrant_contract.protected_function("zzz value", True, transact={})) + with tx_failed(): + reentrant_contract.protected_function("zzz value", True, transact={}) reentrant_contract.protected_function2("another value", False, transact={}) assert reentrant_contract.special_value() == "another value" - assert_tx_failed(lambda: reentrant_contract.protected_function2("zzz value", True, transact={})) + with tx_failed(): + reentrant_contract.protected_function2("zzz value", True, transact={}) reentrant_contract.protected_function3("another value", False, transact={}) assert reentrant_contract.special_value() == "another value" - assert_tx_failed(lambda: reentrant_contract.protected_function3("zzz value", True, transact={})) + with tx_failed(): + reentrant_contract.protected_function3("zzz value", True, transact={}) -def test_nonreentrant_decorator_for_default(w3, get_contract, assert_tx_failed): +def test_nonreentrant_decorator_for_default(w3, get_contract, tx_failed): calling_contract_code = """ @external def send_funds(_amount: uint256): @@ -196,9 +199,8 @@ def __default__(): assert w3.eth.get_balance(calling_contract.address) == 2000 # Test protected function with callback to default. - assert_tx_failed( - lambda: reentrant_contract.protected_function("zzz value", True, transact={"value": 1000}) - ) + with tx_failed(): + reentrant_contract.protected_function("zzz value", True, transact={"value": 1000}) def test_disallow_on_init_function(get_contract): diff --git a/tests/functional/codegen/features/decorators/test_payable.py b/tests/functional/codegen/features/decorators/test_payable.py index 4858a7df0d..ced58e1af0 100644 --- a/tests/functional/codegen/features/decorators/test_payable.py +++ b/tests/functional/codegen/features/decorators/test_payable.py @@ -177,14 +177,13 @@ def baz() -> bool: @pytest.mark.parametrize("code", nonpayable_code) -def test_nonpayable_runtime_assertion(w3, keccak, assert_tx_failed, get_contract, code): +def test_nonpayable_runtime_assertion(w3, keccak, tx_failed, get_contract, code): c = get_contract(code) c.foo(transact={"value": 0}) sig = keccak("foo()".encode()).hex()[:10] - assert_tx_failed( - lambda: w3.eth.send_transaction({"to": c.address, "data": sig, "value": 10**18}) - ) + with tx_failed(): + w3.eth.send_transaction({"to": c.address, "data": sig, "value": 10**18}) payable_code = [ @@ -355,7 +354,7 @@ def __default__(): w3.eth.send_transaction({"to": c.address, "value": 100, "data": "0x12345678"}) -def test_nonpayable_default_func_invalid_calldata(get_contract, w3, assert_tx_failed): +def test_nonpayable_default_func_invalid_calldata(get_contract, w3, tx_failed): code = """ @external @payable @@ -369,12 +368,11 @@ def __default__(): c = get_contract(code) w3.eth.send_transaction({"to": c.address, "value": 0, "data": "0x12345678"}) - assert_tx_failed( - lambda: w3.eth.send_transaction({"to": c.address, "value": 100, "data": "0x12345678"}) - ) + with tx_failed(): + w3.eth.send_transaction({"to": c.address, "value": 100, "data": "0x12345678"}) -def test_batch_nonpayable(get_contract, w3, assert_tx_failed): +def test_batch_nonpayable(get_contract, w3, tx_failed): code = """ @external def foo() -> bool: @@ -390,8 +388,5 @@ def __default__(): data = bytes([1, 2, 3, 4]) for i in range(5): calldata = "0x" + data[:i].hex() - assert_tx_failed( - lambda data=calldata: w3.eth.send_transaction( - {"to": c.address, "value": 100, "data": data} - ) - ) + with tx_failed(): + w3.eth.send_transaction({"to": c.address, "value": 100, "data": calldata}) diff --git a/tests/functional/codegen/features/decorators/test_private.py b/tests/functional/codegen/features/decorators/test_private.py index 51e6d90ee1..39ea1bb9ae 100644 --- a/tests/functional/codegen/features/decorators/test_private.py +++ b/tests/functional/codegen/features/decorators/test_private.py @@ -449,7 +449,7 @@ def whoami() -> address: assert logged_addr == addr, "oh no" -def test_nested_static_params_only(get_contract, assert_tx_failed): +def test_nested_static_params_only(get_contract, tx_failed): code1 = """ @internal @view diff --git a/tests/functional/codegen/features/iteration/test_for_range.py b/tests/functional/codegen/features/iteration/test_for_range.py index ed6235d992..96b83ae691 100644 --- a/tests/functional/codegen/features/iteration/test_for_range.py +++ b/tests/functional/codegen/features/iteration/test_for_range.py @@ -14,7 +14,7 @@ def repeat(z: int128) -> int128: assert c.repeat(9) == 54 -def test_range_bound(get_contract, assert_tx_failed): +def test_range_bound(get_contract, tx_failed): code = """ @external def repeat(n: uint256) -> uint256: @@ -28,7 +28,8 @@ def repeat(n: uint256) -> uint256: assert c.repeat(n) == sum(i + 1 for i in range(n)) # check codegen inserts assertion for n greater than bound - assert_tx_failed(lambda: c.repeat(7)) + with tx_failed(): + c.repeat(7) def test_digit_reverser(get_contract_with_gas_estimation): @@ -172,7 +173,7 @@ def test(): @pytest.mark.parametrize("typ", ["uint8", "int128", "uint256"]) -def test_for_range_oob_check(get_contract, assert_tx_failed, typ): +def test_for_range_oob_check(get_contract, tx_failed, typ): code = f""" @external def test(): @@ -181,7 +182,8 @@ def test(): pass """ c = get_contract(code) - assert_tx_failed(lambda: c.test()) + with tx_failed(): + c.test() @pytest.mark.parametrize("typ", ["int128", "uint256"]) diff --git a/tests/functional/codegen/features/iteration/test_range_in.py b/tests/functional/codegen/features/iteration/test_range_in.py index 062cd389a0..7540049778 100644 --- a/tests/functional/codegen/features/iteration/test_range_in.py +++ b/tests/functional/codegen/features/iteration/test_range_in.py @@ -110,7 +110,7 @@ def testin() -> bool: assert_compile_failed(lambda: get_contract_with_gas_estimation(code), TypeMismatch) -def test_ownership(w3, assert_tx_failed, get_contract_with_gas_estimation): +def test_ownership(w3, tx_failed, get_contract_with_gas_estimation): code = """ owners: address[2] @@ -135,7 +135,8 @@ def is_owner() -> bool: assert c.is_owner(call={"from": a1}) is False # no one else is. # only an owner may set another owner. - assert_tx_failed(lambda: c.set_owner(1, a1, call={"from": a1})) + with tx_failed(): + c.set_owner(1, a1, call={"from": a1}) c.set_owner(1, a1, transact={}) assert c.is_owner(call={"from": a1}) is True @@ -145,7 +146,7 @@ def is_owner() -> bool: assert c.is_owner() is False -def test_in_fails_when_types_dont_match(get_contract_with_gas_estimation, assert_tx_failed): +def test_in_fails_when_types_dont_match(get_contract_with_gas_estimation, tx_failed): code = """ @external def testin(x: address) -> bool: @@ -154,4 +155,5 @@ def testin(x: address) -> bool: return True return False """ - assert_tx_failed(lambda: get_contract_with_gas_estimation(code), TypeMismatch) + with tx_failed(TypeMismatch): + get_contract_with_gas_estimation(code) diff --git a/tests/functional/codegen/features/test_assert.py b/tests/functional/codegen/features/test_assert.py index 842b32d815..af189e6dca 100644 --- a/tests/functional/codegen/features/test_assert.py +++ b/tests/functional/codegen/features/test_assert.py @@ -3,12 +3,12 @@ # web3 returns f"execution reverted: {err_str}" -# TODO move exception string parsing logic into assert_tx_failed +# TODO move exception string parsing logic into tx_failed def _fixup_err_str(s): return s.replace("execution reverted: ", "") -def test_assert_refund(w3, get_contract_with_gas_estimation, assert_tx_failed): +def test_assert_refund(w3, get_contract_with_gas_estimation, tx_failed): code = """ @external def foo(): @@ -26,7 +26,7 @@ def foo(): assert tx_receipt["gasUsed"] < gas_sent -def test_assert_reason(w3, get_contract_with_gas_estimation, assert_tx_failed, memory_mocker): +def test_assert_reason(w3, get_contract_with_gas_estimation, tx_failed, memory_mocker): code = """ @external def test(a: int128) -> int128: @@ -132,7 +132,7 @@ def test_valid_assertions(get_contract, code): get_contract(code) -def test_assert_staticcall(get_contract, assert_tx_failed, memory_mocker): +def test_assert_staticcall(get_contract, tx_failed, memory_mocker): foreign_code = """ state: uint256 @external @@ -151,10 +151,11 @@ def test(): c1 = get_contract(foreign_code) c2 = get_contract(code, *[c1.address]) # static call prohibits state change - assert_tx_failed(lambda: c2.test()) + with tx_failed(): + c2.test() -def test_assert_in_for_loop(get_contract, assert_tx_failed, memory_mocker): +def test_assert_in_for_loop(get_contract, tx_failed, memory_mocker): code = """ @external def test(x: uint256[3]) -> bool: @@ -166,12 +167,15 @@ def test(x: uint256[3]) -> bool: c = get_contract(code) c.test([1, 2, 3]) - assert_tx_failed(lambda: c.test([5, 1, 3])) - assert_tx_failed(lambda: c.test([1, 5, 3])) - assert_tx_failed(lambda: c.test([1, 3, 5])) + with tx_failed(): + c.test([5, 1, 3]) + with tx_failed(): + c.test([1, 5, 3]) + with tx_failed(): + c.test([1, 3, 5]) -def test_assert_with_reason_in_for_loop(get_contract, assert_tx_failed, memory_mocker): +def test_assert_with_reason_in_for_loop(get_contract, tx_failed, memory_mocker): code = """ @external def test(x: uint256[3]) -> bool: @@ -183,12 +187,15 @@ def test(x: uint256[3]) -> bool: c = get_contract(code) c.test([1, 2, 3]) - assert_tx_failed(lambda: c.test([5, 1, 3])) - assert_tx_failed(lambda: c.test([1, 5, 3])) - assert_tx_failed(lambda: c.test([1, 3, 5])) + with tx_failed(): + c.test([5, 1, 3]) + with tx_failed(): + c.test([1, 5, 3]) + with tx_failed(): + c.test([1, 3, 5]) -def test_assert_reason_revert_length(w3, get_contract, assert_tx_failed, memory_mocker): +def test_assert_reason_revert_length(w3, get_contract, tx_failed, memory_mocker): code = """ @external def test() -> int128: @@ -196,4 +203,5 @@ def test() -> int128: return 1 """ c = get_contract(code) - assert_tx_failed(lambda: c.test(), exc_text="oops") + with tx_failed(exc_text="oops"): + c.test() diff --git a/tests/functional/codegen/features/test_assert_unreachable.py b/tests/functional/codegen/features/test_assert_unreachable.py index 90ed31a22e..4db00bce7c 100644 --- a/tests/functional/codegen/features/test_assert_unreachable.py +++ b/tests/functional/codegen/features/test_assert_unreachable.py @@ -15,7 +15,7 @@ def foo(): assert tx_receipt["gasUsed"] == gas_sent # Drains all gains sent -def test_basic_unreachable(w3, get_contract, assert_tx_failed): +def test_basic_unreachable(w3, get_contract, tx_failed): code = """ @external def foo(val: int128) -> bool: @@ -28,12 +28,15 @@ def foo(val: int128) -> bool: assert c.foo(2) is True - assert_tx_failed(lambda: c.foo(1), exc_text="Invalid opcode 0xfe") - assert_tx_failed(lambda: c.foo(-1), exc_text="Invalid opcode 0xfe") - assert_tx_failed(lambda: c.foo(-2), exc_text="Invalid opcode 0xfe") + with tx_failed(exc_text="Invalid opcode 0xfe"): + c.foo(1) + with tx_failed(exc_text="Invalid opcode 0xfe"): + c.foo(-1) + with tx_failed(exc_text="Invalid opcode 0xfe"): + c.foo(-2) -def test_basic_call_unreachable(w3, get_contract, assert_tx_failed): +def test_basic_call_unreachable(w3, get_contract, tx_failed): code = """ @view @@ -51,11 +54,13 @@ def foo(val: int128) -> int128: assert c.foo(33) == -123 - assert_tx_failed(lambda: c.foo(1), exc_text="Invalid opcode 0xfe") - assert_tx_failed(lambda: c.foo(-1), exc_text="Invalid opcode 0xfe") + with tx_failed(exc_text="Invalid opcode 0xfe"): + c.foo(1) + with tx_failed(exc_text="Invalid opcode 0xfe"): + c.foo(-1) -def test_raise_unreachable(w3, get_contract, assert_tx_failed): +def test_raise_unreachable(w3, get_contract, tx_failed): code = """ @external def foo(): @@ -64,4 +69,5 @@ def foo(): c = get_contract(code) - assert_tx_failed(lambda: c.foo(), exc_text="Invalid opcode 0xfe") + with tx_failed(exc_text="Invalid opcode 0xfe"): + c.foo() diff --git a/tests/functional/codegen/features/test_clampers.py b/tests/functional/codegen/features/test_clampers.py index 263f10a89c..6db8570fc7 100644 --- a/tests/functional/codegen/features/test_clampers.py +++ b/tests/functional/codegen/features/test_clampers.py @@ -33,7 +33,7 @@ def _make_invalid_dynarray_tx(w3, address, signature, data): w3.eth.send_transaction({"to": address, "data": f"0x{sig}{data}"}) -def test_bytes_clamper(assert_tx_failed, get_contract_with_gas_estimation): +def test_bytes_clamper(tx_failed, get_contract_with_gas_estimation): clamper_test_code = """ @external def foo(s: Bytes[3]) -> Bytes[3]: @@ -43,10 +43,11 @@ def foo(s: Bytes[3]) -> Bytes[3]: c = get_contract_with_gas_estimation(clamper_test_code) assert c.foo(b"ca") == b"ca" assert c.foo(b"cat") == b"cat" - assert_tx_failed(lambda: c.foo(b"cate")) + with tx_failed(): + c.foo(b"cate") -def test_bytes_clamper_multiple_slots(assert_tx_failed, get_contract_with_gas_estimation): +def test_bytes_clamper_multiple_slots(tx_failed, get_contract_with_gas_estimation): clamper_test_code = """ @external def foo(s: Bytes[40]) -> Bytes[40]: @@ -58,10 +59,11 @@ def foo(s: Bytes[40]) -> Bytes[40]: assert c.foo(data[:30]) == data[:30] assert c.foo(data) == data - assert_tx_failed(lambda: c.foo(data + b"!")) + with tx_failed(): + c.foo(data + b"!") -def test_bytes_clamper_on_init(assert_tx_failed, get_contract_with_gas_estimation): +def test_bytes_clamper_on_init(tx_failed, get_contract_with_gas_estimation): clamper_test_code = """ foo: Bytes[3] @@ -77,7 +79,8 @@ def get_foo() -> Bytes[3]: c = get_contract_with_gas_estimation(clamper_test_code, *[b"cat"]) assert c.get_foo() == b"cat" - assert_tx_failed(lambda: get_contract_with_gas_estimation(clamper_test_code, *[b"cats"])) + with tx_failed(): + get_contract_with_gas_estimation(clamper_test_code, *[b"cats"]) @pytest.mark.parametrize("evm_version", list(EVM_VERSIONS)) @@ -99,7 +102,7 @@ def foo(s: bytes{n}) -> bytes{n}: @pytest.mark.parametrize("evm_version", list(EVM_VERSIONS)) @pytest.mark.parametrize("n", list(range(1, 32))) # bytes32 always passes -def test_bytes_m_clamper_failing(w3, get_contract, assert_tx_failed, n, evm_version): +def test_bytes_m_clamper_failing(w3, get_contract, tx_failed, n, evm_version): values = [] values.append(b"\x00" * n + b"\x80") # just one bit set values.append(b"\xff" * n + b"\x80") # n*8 + 1 bits set @@ -118,11 +121,9 @@ def foo(s: bytes{n}) -> bytes{n}: c = get_contract(code, evm_version=evm_version) for v in values: # munge for `_make_tx` - assert_tx_failed( - lambda val=int.from_bytes(v, byteorder="big"): _make_tx( - w3, c.address, f"foo(bytes{n})", [val] - ) - ) + with tx_failed(): + int_value = int.from_bytes(v, byteorder="big") + _make_tx(w3, c.address, f"foo(bytes{n})", [int_value]) @pytest.mark.parametrize("evm_version", list(EVM_VERSIONS)) @@ -144,7 +145,7 @@ def foo(s: int{bits}) -> int{bits}: @pytest.mark.parametrize("evm_version", list(EVM_VERSIONS)) @pytest.mark.parametrize("n", list(range(31))) # int256 does not clamp -def test_sint_clamper_failing(w3, assert_tx_failed, get_contract, n, evm_version): +def test_sint_clamper_failing(w3, tx_failed, get_contract, n, evm_version): bits = 8 * (n + 1) lo, hi = int_bounds(True, bits) values = [-(2**255), 2**255 - 1, lo - 1, hi + 1] @@ -156,7 +157,8 @@ def foo(s: int{bits}) -> int{bits}: c = get_contract(code, evm_version=evm_version) for v in values: - assert_tx_failed(lambda val=v: _make_tx(w3, c.address, f"foo(int{bits})", [val])) + with tx_failed(): + _make_tx(w3, c.address, f"foo(int{bits})", [v]) @pytest.mark.parametrize("evm_version", list(EVM_VERSIONS)) @@ -174,7 +176,7 @@ def foo(s: bool) -> bool: @pytest.mark.parametrize("evm_version", list(EVM_VERSIONS)) @pytest.mark.parametrize("value", [2, 3, 4, 8, 16, 2**256 - 1]) -def test_bool_clamper_failing(w3, assert_tx_failed, get_contract, value, evm_version): +def test_bool_clamper_failing(w3, tx_failed, get_contract, value, evm_version): code = """ @external def foo(s: bool) -> bool: @@ -182,7 +184,8 @@ def foo(s: bool) -> bool: """ c = get_contract(code, evm_version=evm_version) - assert_tx_failed(lambda: _make_tx(w3, c.address, "foo(bool)", [value])) + with tx_failed(): + _make_tx(w3, c.address, "foo(bool)", [value]) @pytest.mark.parametrize("evm_version", list(EVM_VERSIONS)) @@ -207,7 +210,7 @@ def foo(s: Roles) -> Roles: @pytest.mark.parametrize("evm_version", list(EVM_VERSIONS)) @pytest.mark.parametrize("value", [2**i for i in range(5, 256)]) -def test_flag_clamper_failing(w3, assert_tx_failed, get_contract, value, evm_version): +def test_flag_clamper_failing(w3, tx_failed, get_contract, value, evm_version): code = """ flag Roles: USER @@ -222,7 +225,8 @@ def foo(s: Roles) -> Roles: """ c = get_contract(code, evm_version=evm_version) - assert_tx_failed(lambda: _make_tx(w3, c.address, "foo(uint256)", [value])) + with tx_failed(): + _make_tx(w3, c.address, "foo(uint256)", [value]) @pytest.mark.parametrize("evm_version", list(EVM_VERSIONS)) @@ -243,7 +247,7 @@ def foo(s: uint{bits}) -> uint{bits}: @pytest.mark.parametrize("evm_version", list(EVM_VERSIONS)) @pytest.mark.parametrize("n", list(range(31))) # uint256 has no failing cases -def test_uint_clamper_failing(w3, assert_tx_failed, get_contract, evm_version, n): +def test_uint_clamper_failing(w3, tx_failed, get_contract, evm_version, n): bits = 8 * (n + 1) values = [-1, -(2**255), 2**bits] code = f""" @@ -253,7 +257,8 @@ def foo(s: uint{bits}) -> uint{bits}: """ c = get_contract(code, evm_version=evm_version) for v in values: - assert_tx_failed(lambda val=v: _make_tx(w3, c.address, f"foo(uint{bits})", [val])) + with tx_failed(): + _make_tx(w3, c.address, f"foo(uint{bits})", [v]) @pytest.mark.parametrize("evm_version", list(EVM_VERSIONS)) @@ -284,7 +289,7 @@ def foo(s: address) -> address: @pytest.mark.parametrize("evm_version", list(EVM_VERSIONS)) @pytest.mark.parametrize("value", [2**160, 2**256 - 1]) -def test_address_clamper_failing(w3, assert_tx_failed, get_contract, value, evm_version): +def test_address_clamper_failing(w3, tx_failed, get_contract, value, evm_version): code = """ @external def foo(s: address) -> address: @@ -292,7 +297,8 @@ def foo(s: address) -> address: """ c = get_contract(code, evm_version=evm_version) - assert_tx_failed(lambda: _make_tx(w3, c.address, "foo(address)", [value])) + with tx_failed(): + _make_tx(w3, c.address, "foo(address)", [value]) @pytest.mark.parametrize("evm_version", list(EVM_VERSIONS)) @@ -337,7 +343,7 @@ def foo(s: decimal) -> decimal: -187072209578355573530071658587684226515959365500929, # - (2 ** 127 - 1e-10) ], ) -def test_decimal_clamper_failing(w3, assert_tx_failed, get_contract, value, evm_version): +def test_decimal_clamper_failing(w3, tx_failed, get_contract, value, evm_version): code = """ @external def foo(s: decimal) -> decimal: @@ -346,7 +352,8 @@ def foo(s: decimal) -> decimal: c = get_contract(code, evm_version=evm_version) - assert_tx_failed(lambda: _make_tx(w3, c.address, "foo(fixed168x10)", [value])) + with tx_failed(): + _make_tx(w3, c.address, "foo(fixed168x10)", [value]) @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) @@ -366,7 +373,7 @@ def foo(a: uint256, b: int128[5], c: uint256) -> int128[5]: @pytest.mark.parametrize("bad_value", [2**127, -(2**127) - 1, 2**255 - 1, -(2**255)]) @pytest.mark.parametrize("idx", range(5)) -def test_int128_array_clamper_failing(w3, assert_tx_failed, get_contract, bad_value, idx): +def test_int128_array_clamper_failing(w3, tx_failed, get_contract, bad_value, idx): # ensure the invalid value is detected at all locations in the array code = """ @external @@ -378,7 +385,8 @@ def foo(b: int128[5]) -> int128[5]: values[idx] = bad_value c = get_contract(code) - assert_tx_failed(lambda: _make_tx(w3, c.address, "foo(int128[5])", values)) + with tx_failed(): + _make_tx(w3, c.address, "foo(int128[5])", values) @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) @@ -397,7 +405,7 @@ def foo(a: uint256, b: int128[10], c: uint256) -> int128[10]: @pytest.mark.parametrize("bad_value", [2**127, -(2**127) - 1, 2**255 - 1, -(2**255)]) @pytest.mark.parametrize("idx", range(10)) -def test_int128_array_looped_clamper_failing(w3, assert_tx_failed, get_contract, bad_value, idx): +def test_int128_array_looped_clamper_failing(w3, tx_failed, get_contract, bad_value, idx): code = """ @external def foo(b: int128[10]) -> int128[10]: @@ -408,7 +416,8 @@ def foo(b: int128[10]) -> int128[10]: values[idx] = bad_value c = get_contract(code) - assert_tx_failed(lambda: _make_tx(w3, c.address, "foo(int128[10])", values)) + with tx_failed(): + _make_tx(w3, c.address, "foo(int128[10])", values) @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) @@ -427,7 +436,7 @@ def foo(a: uint256, b: int128[6][3][1][8], c: uint256) -> int128[6][3][1][8]: @pytest.mark.parametrize("bad_value", [2**127, -(2**127) - 1, 2**255 - 1, -(2**255)]) @pytest.mark.parametrize("idx", range(12)) -def test_multidimension_array_clamper_failing(w3, assert_tx_failed, get_contract, bad_value, idx): +def test_multidimension_array_clamper_failing(w3, tx_failed, get_contract, bad_value, idx): code = """ @external def foo(b: int128[6][1][2]) -> int128[6][1][2]: @@ -438,7 +447,8 @@ def foo(b: int128[6][1][2]) -> int128[6][1][2]: values[idx] = bad_value c = get_contract(code) - assert_tx_failed(lambda: _make_tx(w3, c.address, "foo(int128[6][1][2]])", values)) + with tx_failed(): + _make_tx(w3, c.address, "foo(int128[6][1][2]])", values) @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) @@ -458,7 +468,7 @@ def foo(a: uint256, b: DynArray[int128, 5], c: uint256) -> DynArray[int128, 5]: @pytest.mark.parametrize("bad_value", [2**127, -(2**127) - 1, 2**255 - 1, -(2**255)]) @pytest.mark.parametrize("idx", range(5)) -def test_int128_dynarray_clamper_failing(w3, assert_tx_failed, get_contract, bad_value, idx): +def test_int128_dynarray_clamper_failing(w3, tx_failed, get_contract, bad_value, idx): # ensure the invalid value is detected at all locations in the array code = """ @external @@ -473,7 +483,8 @@ def foo(b: int128[5]) -> int128[5]: c = get_contract(code) data = _make_dynarray_data(32, 5, values) - assert_tx_failed(lambda: _make_invalid_dynarray_tx(w3, c.address, signature, data)) + with tx_failed(): + _make_invalid_dynarray_tx(w3, c.address, signature, data) @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) @@ -491,7 +502,7 @@ def foo(a: uint256, b: DynArray[int128, 10], c: uint256) -> DynArray[int128, 10] @pytest.mark.parametrize("bad_value", [2**127, -(2**127) - 1, 2**255 - 1, -(2**255)]) @pytest.mark.parametrize("idx", range(10)) -def test_int128_dynarray_looped_clamper_failing(w3, assert_tx_failed, get_contract, bad_value, idx): +def test_int128_dynarray_looped_clamper_failing(w3, tx_failed, get_contract, bad_value, idx): code = """ @external def foo(b: DynArray[int128, 10]) -> DynArray[int128, 10]: @@ -505,7 +516,8 @@ def foo(b: DynArray[int128, 10]) -> DynArray[int128, 10]: data = _make_dynarray_data(32, 10, values) signature = "foo(int128[])" - assert_tx_failed(lambda: _make_invalid_dynarray_tx(w3, c.address, signature, data)) + with tx_failed(): + _make_invalid_dynarray_tx(w3, c.address, signature, data) @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) @@ -527,9 +539,7 @@ def foo( @pytest.mark.parametrize("bad_value", [2**127, -(2**127) - 1, 2**255 - 1, -(2**255)]) @pytest.mark.parametrize("idx", range(4)) -def test_multidimension_dynarray_clamper_failing( - w3, assert_tx_failed, get_contract, bad_value, idx -): +def test_multidimension_dynarray_clamper_failing(w3, tx_failed, get_contract, bad_value, idx): code = """ @external def foo(b: DynArray[DynArray[int128, 2], 2]) -> DynArray[DynArray[int128, 2], 2]: @@ -549,7 +559,8 @@ def foo(b: DynArray[DynArray[int128, 2], 2]) -> DynArray[DynArray[int128, 2], 2] signature = "foo(int128[][])" c = get_contract(code) - assert_tx_failed(lambda: _make_invalid_dynarray_tx(w3, c.address, signature, data)) + with tx_failed(): + _make_invalid_dynarray_tx(w3, c.address, signature, data) @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) @@ -570,7 +581,7 @@ def foo( @pytest.mark.parametrize("bad_value", [2**127, -(2**127) - 1, 2**255 - 1, -(2**255)]) @pytest.mark.parametrize("idx", range(10)) -def test_dynarray_list_clamper_failing(w3, assert_tx_failed, get_contract, bad_value, idx): +def test_dynarray_list_clamper_failing(w3, tx_failed, get_contract, bad_value, idx): # ensure the invalid value is detected at all locations in the array code = """ @external @@ -588,4 +599,5 @@ def foo(b: DynArray[int128[5], 2]) -> DynArray[int128[5], 2]: c = get_contract(code) signature = "foo(int128[5][])" - assert_tx_failed(lambda: _make_invalid_dynarray_tx(w3, c.address, signature, data)) + with tx_failed(): + _make_invalid_dynarray_tx(w3, c.address, signature, data) diff --git a/tests/functional/codegen/features/test_init.py b/tests/functional/codegen/features/test_init.py index 29a466e869..fc765f8ab3 100644 --- a/tests/functional/codegen/features/test_init.py +++ b/tests/functional/codegen/features/test_init.py @@ -24,7 +24,7 @@ def __init__(a: uint256): assert "CALLDATALOAD" not in assembly[:ir_return_idx_start] + assembly[ir_return_idx_end:] -def test_init_calls_internal(get_contract, assert_compile_failed, assert_tx_failed): +def test_init_calls_internal(get_contract, assert_compile_failed, tx_failed): code = """ foo: public(uint8) @internal @@ -46,7 +46,8 @@ def baz() -> uint8: n = 6 c = get_contract(code, n) assert c.foo() == n * 7 - assert_tx_failed(lambda: c.baz()) + with tx_failed(): + c.baz() n = 255 assert_compile_failed(lambda: get_contract(code, n)) diff --git a/tests/functional/codegen/features/test_logging.py b/tests/functional/codegen/features/test_logging.py index 84311c41f5..ba09be1991 100644 --- a/tests/functional/codegen/features/test_logging.py +++ b/tests/functional/codegen/features/test_logging.py @@ -3,6 +3,7 @@ import pytest from eth.codecs import abi +from vyper import compile_code from vyper.exceptions import ( ArgumentException, EventDeclarationException, @@ -193,7 +194,7 @@ def bar(): def test_event_logging_cannot_have_more_than_three_topics( - assert_tx_failed, get_contract_with_gas_estimation + tx_failed, get_contract_with_gas_estimation ): loggy_code = """ event MyLog: @@ -203,9 +204,8 @@ def test_event_logging_cannot_have_more_than_three_topics( arg4: indexed(int128) """ - assert_tx_failed( - lambda: get_contract_with_gas_estimation(loggy_code), EventDeclarationException - ) + with pytest.raises(EventDeclarationException): + compile_code(loggy_code) def test_event_logging_with_data(w3, tester, keccak, get_logs, get_contract_with_gas_estimation): @@ -555,7 +555,7 @@ def foo(): assert args.arg2 == {"x": 1, "y": b"abc", "z": {"t": "house", "w": Decimal("13.5")}} -def test_fails_when_input_is_the_wrong_type(assert_tx_failed, get_contract_with_gas_estimation): +def test_fails_when_input_is_the_wrong_type(tx_failed, get_contract_with_gas_estimation): loggy_code = """ event MyLog: arg1: indexed(int128) @@ -565,10 +565,11 @@ def foo_(): log MyLog(b'yo') """ - assert_tx_failed(lambda: get_contract_with_gas_estimation(loggy_code), InvalidType) + with tx_failed(InvalidType): + get_contract_with_gas_estimation(loggy_code) -def test_fails_when_topic_is_the_wrong_size(assert_tx_failed, get_contract_with_gas_estimation): +def test_fails_when_topic_is_the_wrong_size(tx_failed, get_contract_with_gas_estimation): loggy_code = """ event MyLog: arg1: indexed(Bytes[3]) @@ -579,12 +580,11 @@ def foo(): log MyLog(b'bars') """ - assert_tx_failed(lambda: get_contract_with_gas_estimation(loggy_code), InvalidType) + with tx_failed(InvalidType): + get_contract_with_gas_estimation(loggy_code) -def test_fails_when_input_topic_is_the_wrong_size( - assert_tx_failed, get_contract_with_gas_estimation -): +def test_fails_when_input_topic_is_the_wrong_size(tx_failed, get_contract_with_gas_estimation): loggy_code = """ event MyLog: arg1: indexed(Bytes[3]) @@ -594,10 +594,11 @@ def foo(arg1: Bytes[4]): log MyLog(arg1) """ - assert_tx_failed(lambda: get_contract_with_gas_estimation(loggy_code), TypeMismatch) + with tx_failed(TypeMismatch): + get_contract_with_gas_estimation(loggy_code) -def test_fails_when_data_is_the_wrong_size(assert_tx_failed, get_contract_with_gas_estimation): +def test_fails_when_data_is_the_wrong_size(tx_failed, get_contract_with_gas_estimation): loggy_code = """ event MyLog: arg1: Bytes[3] @@ -607,12 +608,11 @@ def foo(): log MyLog(b'bars') """ - assert_tx_failed(lambda: get_contract_with_gas_estimation(loggy_code), InvalidType) + with tx_failed(InvalidType): + get_contract_with_gas_estimation(loggy_code) -def test_fails_when_input_data_is_the_wrong_size( - assert_tx_failed, get_contract_with_gas_estimation -): +def test_fails_when_input_data_is_the_wrong_size(tx_failed, get_contract_with_gas_estimation): loggy_code = """ event MyLog: arg1: Bytes[3] @@ -622,7 +622,8 @@ def foo(arg1: Bytes[4]): log MyLog(arg1) """ - assert_tx_failed(lambda: get_contract_with_gas_estimation(loggy_code), TypeMismatch) + with tx_failed(TypeMismatch): + get_contract_with_gas_estimation(loggy_code) def test_topic_over_32_bytes(get_contract_with_gas_estimation): @@ -637,7 +638,7 @@ def foo(): get_contract_with_gas_estimation(loggy_code) -def test_logging_fails_with_over_three_topics(assert_tx_failed, get_contract_with_gas_estimation): +def test_logging_fails_with_over_three_topics(tx_failed, get_contract_with_gas_estimation): loggy_code = """ event MyLog: arg1: indexed(int128) @@ -650,12 +651,11 @@ def __init__(): log MyLog(1, 2, 3, 4) """ - assert_tx_failed( - lambda: get_contract_with_gas_estimation(loggy_code), EventDeclarationException - ) + with tx_failed(EventDeclarationException): + get_contract_with_gas_estimation(loggy_code) -def test_logging_fails_with_duplicate_log_names(assert_tx_failed, get_contract_with_gas_estimation): +def test_logging_fails_with_duplicate_log_names(tx_failed, get_contract_with_gas_estimation): loggy_code = """ event MyLog: pass event MyLog: pass @@ -665,12 +665,11 @@ def foo(): log MyLog() """ - assert_tx_failed(lambda: get_contract_with_gas_estimation(loggy_code), NamespaceCollision) + with tx_failed(NamespaceCollision): + get_contract_with_gas_estimation(loggy_code) -def test_logging_fails_with_when_log_is_undeclared( - assert_tx_failed, get_contract_with_gas_estimation -): +def test_logging_fails_with_when_log_is_undeclared(tx_failed, get_contract_with_gas_estimation): loggy_code = """ @external @@ -678,10 +677,11 @@ def foo(): log MyLog() """ - assert_tx_failed(lambda: get_contract_with_gas_estimation(loggy_code), UndeclaredDefinition) + with tx_failed(UndeclaredDefinition): + get_contract_with_gas_estimation(loggy_code) -def test_logging_fails_with_topic_type_mismatch(assert_tx_failed, get_contract_with_gas_estimation): +def test_logging_fails_with_topic_type_mismatch(tx_failed, get_contract_with_gas_estimation): loggy_code = """ event MyLog: arg1: indexed(int128) @@ -691,10 +691,11 @@ def foo(): log MyLog(self) """ - assert_tx_failed(lambda: get_contract_with_gas_estimation(loggy_code), TypeMismatch) + with tx_failed(TypeMismatch): + get_contract_with_gas_estimation(loggy_code) -def test_logging_fails_with_data_type_mismatch(assert_tx_failed, get_contract_with_gas_estimation): +def test_logging_fails_with_data_type_mismatch(tx_failed, get_contract_with_gas_estimation): loggy_code = """ event MyLog: arg1: Bytes[3] @@ -704,11 +705,12 @@ def foo(): log MyLog(self) """ - assert_tx_failed(lambda: get_contract_with_gas_estimation(loggy_code), TypeMismatch) + with tx_failed(TypeMismatch): + get_contract_with_gas_estimation(loggy_code) def test_logging_fails_when_number_of_arguments_is_greater_than_declaration( - assert_tx_failed, get_contract_with_gas_estimation + tx_failed, get_contract_with_gas_estimation ): loggy_code = """ event MyLog: @@ -718,11 +720,12 @@ def test_logging_fails_when_number_of_arguments_is_greater_than_declaration( def foo(): log MyLog(1, 2) """ - assert_tx_failed(lambda: get_contract_with_gas_estimation(loggy_code), ArgumentException) + with tx_failed(ArgumentException): + get_contract_with_gas_estimation(loggy_code) def test_logging_fails_when_number_of_arguments_is_less_than_declaration( - assert_tx_failed, get_contract_with_gas_estimation + tx_failed, get_contract_with_gas_estimation ): loggy_code = """ event MyLog: @@ -733,7 +736,8 @@ def test_logging_fails_when_number_of_arguments_is_less_than_declaration( def foo(): log MyLog(1) """ - assert_tx_failed(lambda: get_contract_with_gas_estimation(loggy_code), ArgumentException) + with tx_failed(ArgumentException): + get_contract_with_gas_estimation(loggy_code) def test_loggy_code(w3, tester, get_contract_with_gas_estimation): @@ -962,7 +966,7 @@ def set_list(): ] -def test_logging_fails_when_input_is_too_big(assert_tx_failed, get_contract_with_gas_estimation): +def test_logging_fails_when_input_is_too_big(tx_failed, get_contract_with_gas_estimation): code = """ event Bar: _value: indexed(Bytes[32]) @@ -971,7 +975,8 @@ def test_logging_fails_when_input_is_too_big(assert_tx_failed, get_contract_with def foo(inp: Bytes[33]): log Bar(inp) """ - assert_tx_failed(lambda: get_contract_with_gas_estimation(code), TypeMismatch) + with tx_failed(TypeMismatch): + get_contract_with_gas_estimation(code) def test_2nd_var_list_packing(get_logs, get_contract_with_gas_estimation): diff --git a/tests/functional/codegen/features/test_reverting.py b/tests/functional/codegen/features/test_reverting.py index 2cdc727015..f24886ce96 100644 --- a/tests/functional/codegen/features/test_reverting.py +++ b/tests/functional/codegen/features/test_reverting.py @@ -7,7 +7,7 @@ pytestmark = pytest.mark.usefixtures("memory_mocker") -def test_revert_reason(w3, assert_tx_failed, get_contract_with_gas_estimation): +def test_revert_reason(w3, tx_failed, get_contract_with_gas_estimation): reverty_code = """ @external def foo(): @@ -17,14 +17,11 @@ def foo(): revert_bytes = method_id("NoFives()") - assert_tx_failed( - lambda: get_contract_with_gas_estimation(reverty_code).foo(transact={}), - TransactionFailed, - exc_text=f"execution reverted: {revert_bytes}", - ) + with tx_failed(TransactionFailed, exc_text=f"execution reverted: {revert_bytes}"): + get_contract_with_gas_estimation(reverty_code).foo(transact={}) -def test_revert_reason_typed(w3, assert_tx_failed, get_contract_with_gas_estimation): +def test_revert_reason_typed(w3, tx_failed, get_contract_with_gas_estimation): reverty_code = """ @external def foo(): @@ -35,14 +32,11 @@ def foo(): revert_bytes = method_id("NoFives(uint256)") + abi.encode("(uint256)", (5,)) - assert_tx_failed( - lambda: get_contract_with_gas_estimation(reverty_code).foo(transact={}), - TransactionFailed, - exc_text=f"execution reverted: {revert_bytes}", - ) + with tx_failed(TransactionFailed, exc_text=f"execution reverted: {revert_bytes}"): + get_contract_with_gas_estimation(reverty_code).foo(transact={}) -def test_revert_reason_typed_no_variable(w3, assert_tx_failed, get_contract_with_gas_estimation): +def test_revert_reason_typed_no_variable(w3, tx_failed, get_contract_with_gas_estimation): reverty_code = """ @external def foo(): @@ -52,8 +46,5 @@ def foo(): revert_bytes = method_id("NoFives(uint256)") + abi.encode("(uint256)", (5,)) - assert_tx_failed( - lambda: get_contract_with_gas_estimation(reverty_code).foo(transact={}), - TransactionFailed, - exc_text=f"execution reverted: {revert_bytes}", - ) + with tx_failed(TransactionFailed, exc_text=f"execution reverted: {revert_bytes}"): + get_contract_with_gas_estimation(reverty_code).foo(transact={}) diff --git a/tests/functional/codegen/integration/test_escrow.py b/tests/functional/codegen/integration/test_escrow.py index 1578f5a418..70e7cb4594 100644 --- a/tests/functional/codegen/integration/test_escrow.py +++ b/tests/functional/codegen/integration/test_escrow.py @@ -1,7 +1,7 @@ # from ethereum.tools import tester -def test_arbitration_code(w3, get_contract_with_gas_estimation, assert_tx_failed): +def test_arbitration_code(w3, get_contract_with_gas_estimation, tx_failed): arbitration_code = """ buyer: address seller: address @@ -28,13 +28,14 @@ def refund(): a0, a1, a2 = w3.eth.accounts[:3] c = get_contract_with_gas_estimation(arbitration_code, value=1) c.setup(a1, a2, transact={}) - assert_tx_failed(lambda: c.finalize(transact={"from": a1})) + with tx_failed(): + c.finalize(transact={"from": a1}) c.finalize(transact={}) print("Passed escrow test") -def test_arbitration_code_with_init(w3, assert_tx_failed, get_contract_with_gas_estimation): +def test_arbitration_code_with_init(w3, tx_failed, get_contract_with_gas_estimation): arbitration_code_with_init = """ buyer: address seller: address @@ -60,7 +61,8 @@ def refund(): """ a0, a1, a2 = w3.eth.accounts[:3] c = get_contract_with_gas_estimation(arbitration_code_with_init, *[a1, a2], value=1) - assert_tx_failed(lambda: c.finalize(transact={"from": a1})) + with tx_failed(): + c.finalize(transact={"from": a1}) c.finalize(transact={"from": a0}) print("Passed escrow test with initializer") diff --git a/tests/functional/codegen/test_interfaces.py b/tests/functional/codegen/test_interfaces.py index 3544f4a965..65d2df9038 100644 --- a/tests/functional/codegen/test_interfaces.py +++ b/tests/functional/codegen/test_interfaces.py @@ -427,7 +427,7 @@ def test(addr: address): # test data returned from external interface gets clamped @pytest.mark.parametrize("typ", ("int128", "uint8")) -def test_external_interface_int_clampers(get_contract, assert_tx_failed, typ): +def test_external_interface_int_clampers(get_contract, tx_failed, typ): external_contract = f""" @external def ok() -> {typ}: @@ -474,13 +474,16 @@ def test_fail3() -> int256: assert bad_c.should_fail() == -(2**255) assert c.test_ok() == 1 - assert_tx_failed(lambda: c.test_fail()) - assert_tx_failed(lambda: c.test_fail2()) - assert_tx_failed(lambda: c.test_fail3()) + with tx_failed(): + c.test_fail() + with tx_failed(): + c.test_fail2() + with tx_failed(): + c.test_fail3() # test data returned from external interface gets clamped -def test_external_interface_bytes_clampers(get_contract, assert_tx_failed): +def test_external_interface_bytes_clampers(get_contract, tx_failed): external_contract = """ @external def ok() -> Bytes[2]: @@ -522,14 +525,14 @@ def test_fail2() -> Bytes[3]: assert bad_c.should_fail() == b"123" assert c.test_ok() == b"12" - assert_tx_failed(lambda: c.test_fail1()) - assert_tx_failed(lambda: c.test_fail2()) + with tx_failed(): + c.test_fail1() + with tx_failed(): + c.test_fail2() # test data returned from external interface gets clamped -def test_json_abi_bytes_clampers( - get_contract, assert_tx_failed, assert_compile_failed, make_input_bundle -): +def test_json_abi_bytes_clampers(get_contract, tx_failed, assert_compile_failed, make_input_bundle): external_contract = """ @external def returns_Bytes3() -> Bytes[3]: @@ -584,9 +587,12 @@ def test_fail3() -> Bytes[3]: c = get_contract(code, bad_c.address, input_bundle=input_bundle) assert bad_c.returns_Bytes3() == b"123" - assert_tx_failed(lambda: c.test_fail1()) - assert_tx_failed(lambda: c.test_fail2()) - assert_tx_failed(lambda: c.test_fail3()) + with tx_failed(): + c.test_fail1() + with tx_failed(): + c.test_fail2() + with tx_failed(): + c.test_fail3() def test_units_interface(w3, get_contract, make_input_bundle): diff --git a/tests/functional/codegen/test_selector_table.py b/tests/functional/codegen/test_selector_table.py index abea81ced4..94233977c9 100644 --- a/tests/functional/codegen/test_selector_table.py +++ b/tests/functional/codegen/test_selector_table.py @@ -512,9 +512,7 @@ def generate_methods(draw, max_calldata_bytes): # dense selector table packing boundaries at 256 and 65336 @pytest.mark.parametrize("max_calldata_bytes", [255, 256, 65336]) @pytest.mark.fuzzing -def test_selector_table_fuzz( - max_calldata_bytes, opt_level, w3, get_contract, assert_tx_failed, get_logs -): +def test_selector_table_fuzz(max_calldata_bytes, opt_level, w3, get_contract, tx_failed, get_logs): def abi_sig(func_id, calldata_words, n_default_args): params = [] if not calldata_words else [f"uint256[{calldata_words}]"] params.extend(["uint256"] * n_default_args) @@ -600,7 +598,8 @@ def __default__(): else: hexstr = (method_id + argsdata).hex() txdata = {"to": c.address, "data": hexstr, "value": 1} - assert_tx_failed(lambda d=txdata: w3.eth.send_transaction(d)) + with tx_failed(): + w3.eth.send_transaction(txdata) # now do calldatasize check # strip some bytes @@ -610,7 +609,8 @@ def __default__(): if n_calldata_words == 0 and j == 0: # no args, hit default function if default_fn_mutability == "": - assert_tx_failed(lambda p=tx_params: w3.eth.send_transaction(p)) + with tx_failed(): + w3.eth.send_transaction(tx_params) elif default_fn_mutability == "@payable": # we should be able to send eth to it tx_params["value"] = 1 @@ -628,8 +628,10 @@ def __default__(): # check default function reverts tx_params["value"] = 1 - assert_tx_failed(lambda p=tx_params: w3.eth.send_transaction(p)) + with tx_failed(): + w3.eth.send_transaction(tx_params) else: - assert_tx_failed(lambda p=tx_params: w3.eth.send_transaction(p)) + with tx_failed(): + w3.eth.send_transaction(tx_params) _test() diff --git a/tests/functional/codegen/test_stateless_modules.py b/tests/functional/codegen/test_stateless_modules.py index 8e634e5868..2abc164689 100644 --- a/tests/functional/codegen/test_stateless_modules.py +++ b/tests/functional/codegen/test_stateless_modules.py @@ -186,7 +186,7 @@ def qux() -> library.SomeStruct: # test calls to library functions in statement position -def test_library_statement_calls(get_contract, make_input_bundle, assert_tx_failed): +def test_library_statement_calls(get_contract, make_input_bundle, tx_failed): library_source = """ from vyper.interfaces import ERC20 @internal @@ -211,7 +211,8 @@ def foo(x: uint256): assert c.counter() == 7 - assert_tx_failed(lambda: c.foo(8)) + with tx_failed(): + c.foo(8) def test_library_is_typechecked(make_input_bundle): diff --git a/tests/functional/codegen/types/numbers/test_constants.py b/tests/functional/codegen/types/numbers/test_constants.py index 25617651ec..8244bc5487 100644 --- a/tests/functional/codegen/types/numbers/test_constants.py +++ b/tests/functional/codegen/types/numbers/test_constants.py @@ -8,6 +8,13 @@ from vyper.utils import MemoryPositions +def search_for_sublist(ir, sublist): + _list = ir.to_list() if hasattr(ir, "to_list") else ir + if _list == sublist: + return True + return isinstance(_list, list) and any(search_for_sublist(i, sublist) for i in _list) + + def test_builtin_constants(get_contract_with_gas_estimation): code = """ @external @@ -192,7 +199,7 @@ def test() -> Bytes[100]: assert c.test() == test_str -def test_constant_folds(search_for_sublist): +def test_constant_folds(): some_prime = 10013677 code = f""" SOME_CONSTANT: constant(uint256) = 11 + 1 @@ -205,11 +212,9 @@ def test() -> uint256: ret: uint256 = 2**SOME_CONSTANT * SOME_PRIME return ret """ - ir = compile_code(code, output_formats=["ir"])["ir"] - assert search_for_sublist( - ir, ["mstore", [MemoryPositions.RESERVED_MEMORY], [2**12 * some_prime]] - ) + search = ["mstore", [MemoryPositions.RESERVED_MEMORY], [2**12 * some_prime]] + assert search_for_sublist(ir, search) def test_constant_lists(get_contract): diff --git a/tests/functional/codegen/types/numbers/test_decimals.py b/tests/functional/codegen/types/numbers/test_decimals.py index 1418eab063..25dc1f1a1e 100644 --- a/tests/functional/codegen/types/numbers/test_decimals.py +++ b/tests/functional/codegen/types/numbers/test_decimals.py @@ -156,7 +156,7 @@ def iarg() -> uint256: print("Passed fractional multiplication test") -def test_mul_overflow(assert_tx_failed, get_contract_with_gas_estimation): +def test_mul_overflow(tx_failed, get_contract_with_gas_estimation): mul_code = """ @external @@ -170,12 +170,14 @@ def _num_mul(x: decimal, y: decimal) -> decimal: x = Decimal("85070591730234615865843651857942052864") y = Decimal("136112946768375385385349842973") - assert_tx_failed(lambda: c._num_mul(x, y)) + with tx_failed(): + c._num_mul(x, y) x = SizeLimits.MAX_AST_DECIMAL y = 1 + DECIMAL_EPSILON - assert_tx_failed(lambda: c._num_mul(x, y)) + with tx_failed(): + c._num_mul(x, y) assert c._num_mul(x, Decimal(1)) == x @@ -186,7 +188,7 @@ def _num_mul(x: decimal, y: decimal) -> decimal: # division failure modes(!) -def test_div_overflow(get_contract, assert_tx_failed): +def test_div_overflow(get_contract, tx_failed): code = """ @external def foo(x: decimal, y: decimal) -> decimal: @@ -198,32 +200,39 @@ def foo(x: decimal, y: decimal) -> decimal: x = SizeLimits.MIN_AST_DECIMAL y = -DECIMAL_EPSILON - assert_tx_failed(lambda: c.foo(x, y)) - assert_tx_failed(lambda: c.foo(x, Decimal(0))) - assert_tx_failed(lambda: c.foo(y, Decimal(0))) + with tx_failed(): + c.foo(x, y) + with tx_failed(): + c.foo(x, Decimal(0)) + with tx_failed(): + c.foo(y, Decimal(0)) y = Decimal(1) - DECIMAL_EPSILON # 0.999999999 - assert_tx_failed(lambda: c.foo(x, y)) + with tx_failed(): + c.foo(x, y) y = Decimal(-1) - assert_tx_failed(lambda: c.foo(x, y)) + with tx_failed(): + c.foo(x, y) assert c.foo(x, Decimal(1)) == x assert c.foo(x, 1 + DECIMAL_EPSILON) == quantize(x / (1 + DECIMAL_EPSILON)) x = SizeLimits.MAX_AST_DECIMAL - assert_tx_failed(lambda: c.foo(x, DECIMAL_EPSILON)) + with tx_failed(): + c.foo(x, DECIMAL_EPSILON) y = Decimal(1) - DECIMAL_EPSILON - assert_tx_failed(lambda: c.foo(x, y)) + with tx_failed(): + c.foo(x, y) assert c.foo(x, Decimal(1)) == x assert c.foo(x, 1 + DECIMAL_EPSILON) == quantize(x / (1 + DECIMAL_EPSILON)) -def test_decimal_min_max_literals(assert_tx_failed, get_contract_with_gas_estimation): +def test_decimal_min_max_literals(tx_failed, get_contract_with_gas_estimation): code = """ @external def maximum(): diff --git a/tests/functional/codegen/types/numbers/test_exponents.py b/tests/functional/codegen/types/numbers/test_exponents.py index 5726e4c1ca..e958436efb 100644 --- a/tests/functional/codegen/types/numbers/test_exponents.py +++ b/tests/functional/codegen/types/numbers/test_exponents.py @@ -7,7 +7,7 @@ @pytest.mark.fuzzing @pytest.mark.parametrize("power", range(2, 255)) -def test_exp_uint256(get_contract, assert_tx_failed, power): +def test_exp_uint256(get_contract, tx_failed, power): code = f""" @external def foo(a: uint256) -> uint256: @@ -20,12 +20,13 @@ def foo(a: uint256) -> uint256: c = get_contract(code) c.foo(max_base) - assert_tx_failed(lambda: c.foo(max_base + 1)) + with tx_failed(): + c.foo(max_base + 1) @pytest.mark.fuzzing @pytest.mark.parametrize("power", range(2, 127)) -def test_exp_int128(get_contract, assert_tx_failed, power): +def test_exp_int128(get_contract, tx_failed, power): code = f""" @external def foo(a: int128) -> int128: @@ -44,13 +45,15 @@ def foo(a: int128) -> int128: c.foo(max_base) c.foo(min_base) - assert_tx_failed(lambda: c.foo(max_base + 1)) - assert_tx_failed(lambda: c.foo(min_base - 1)) + with tx_failed(): + c.foo(max_base + 1) + with tx_failed(): + c.foo(min_base - 1) @pytest.mark.fuzzing @pytest.mark.parametrize("power", range(2, 15)) -def test_exp_int16(get_contract, assert_tx_failed, power): +def test_exp_int16(get_contract, tx_failed, power): code = f""" @external def foo(a: int16) -> int16: @@ -69,8 +72,10 @@ def foo(a: int16) -> int16: c.foo(max_base) c.foo(min_base) - assert_tx_failed(lambda: c.foo(max_base + 1)) - assert_tx_failed(lambda: c.foo(min_base - 1)) + with tx_failed(): + c.foo(max_base + 1) + with tx_failed(): + c.foo(min_base - 1) @pytest.mark.fuzzing @@ -93,7 +98,7 @@ def foo(a: int16) -> int16: # 256 bits @example(a=2**256 - 1) @settings(max_examples=200) -def test_max_exp(get_contract, assert_tx_failed, a): +def test_max_exp(get_contract, tx_failed, a): code = f""" @external def foo(b: uint256) -> uint256: @@ -108,7 +113,8 @@ def foo(b: uint256) -> uint256: assert a ** (max_power + 1) >= 2**256 c.foo(max_power) - assert_tx_failed(lambda: c.foo(max_power + 1)) + with tx_failed(): + c.foo(max_power + 1) @pytest.mark.fuzzing @@ -128,7 +134,7 @@ def foo(b: uint256) -> uint256: # 128 bits @example(a=2**127 - 1) @settings(max_examples=200) -def test_max_exp_int128(get_contract, assert_tx_failed, a): +def test_max_exp_int128(get_contract, tx_failed, a): code = f""" @external def foo(b: int128) -> int128: @@ -143,4 +149,5 @@ def foo(b: int128) -> int128: assert not -(2**127) <= a ** (max_power + 1) < 2**127 c.foo(max_power) - assert_tx_failed(lambda: c.foo(max_power + 1)) + with tx_failed(): + c.foo(max_power + 1) diff --git a/tests/functional/codegen/types/numbers/test_modulo.py b/tests/functional/codegen/types/numbers/test_modulo.py index 018a406baa..465426cd1d 100644 --- a/tests/functional/codegen/types/numbers/test_modulo.py +++ b/tests/functional/codegen/types/numbers/test_modulo.py @@ -31,14 +31,15 @@ def num_modulo_decimal() -> decimal: assert c.num_modulo_decimal() == Decimal(".5") -def test_modulo_with_input_of_zero(assert_tx_failed, get_contract_with_gas_estimation): +def test_modulo_with_input_of_zero(tx_failed, get_contract_with_gas_estimation): code = """ @external def foo(a: decimal, b: decimal) -> decimal: return a % b """ c = get_contract_with_gas_estimation(code) - assert_tx_failed(lambda: c.foo(Decimal("1"), Decimal("0"))) + with tx_failed(): + c.foo(Decimal("1"), Decimal("0")) def test_literals_vs_evm(get_contract): diff --git a/tests/functional/codegen/types/numbers/test_signed_ints.py b/tests/functional/codegen/types/numbers/test_signed_ints.py index 3e44beb826..52de5b649f 100644 --- a/tests/functional/codegen/types/numbers/test_signed_ints.py +++ b/tests/functional/codegen/types/numbers/test_signed_ints.py @@ -12,7 +12,7 @@ @pytest.mark.parametrize("typ", types) -def test_exponent_base_zero(get_contract, assert_tx_failed, typ): +def test_exponent_base_zero(get_contract, tx_failed, typ): code = f""" @external def foo(x: {typ}) -> {typ}: @@ -25,12 +25,14 @@ def foo(x: {typ}) -> {typ}: assert c.foo(1) == 0 assert c.foo(hi) == 0 - assert_tx_failed(lambda: c.foo(-1)) - assert_tx_failed(lambda: c.foo(lo)) # note: lo < 0 + with tx_failed(): + c.foo(-1) + with tx_failed(): + c.foo(lo) # note: lo < 0 @pytest.mark.parametrize("typ", types) -def test_exponent_base_one(get_contract, assert_tx_failed, typ): +def test_exponent_base_one(get_contract, tx_failed, typ): code = f""" @external def foo(x: {typ}) -> {typ}: @@ -43,8 +45,10 @@ def foo(x: {typ}) -> {typ}: assert c.foo(1) == 1 assert c.foo(hi) == 1 - assert_tx_failed(lambda: c.foo(-1)) - assert_tx_failed(lambda: c.foo(lo)) + with tx_failed(): + c.foo(-1) + with tx_failed(): + c.foo(lo) def test_exponent_base_minus_one(get_contract): @@ -63,7 +67,7 @@ def foo(x: int256) -> int256: # TODO: make this test pass @pytest.mark.parametrize("base", (0, 1)) -def test_exponent_negative_power(get_contract, assert_tx_failed, base): +def test_exponent_negative_power(get_contract, tx_failed, base): # #2985 code = f""" @external @@ -73,7 +77,8 @@ def bar() -> int16: """ c = get_contract(code) # known bug: 2985 - assert_tx_failed(lambda: c.bar()) + with tx_failed(): + c.bar() def test_exponent_min_int16(get_contract): @@ -103,7 +108,7 @@ def foo() -> int256: @pytest.mark.parametrize("typ", types) -def test_exponent(get_contract, assert_tx_failed, typ): +def test_exponent(get_contract, tx_failed, typ): code = f""" @external def foo(x: {typ}) -> {typ}: @@ -116,7 +121,8 @@ def foo(x: {typ}) -> {typ}: test_cases = [0, 1, 3, 4, 126, 127, -1, lo, hi] for x in test_cases: if x * 2 >= typ.bits or x < 0: # out of bounds - assert_tx_failed(lambda p=x: c.foo(p)) + with tx_failed(): + c.foo(x) else: assert c.foo(x) == 4**x @@ -145,7 +151,7 @@ def negative_four() -> {typ}: @pytest.mark.parametrize("typ", types) -def test_num_bound(assert_tx_failed, get_contract_with_gas_estimation, typ): +def test_num_bound(tx_failed, get_contract_with_gas_estimation, typ): lo, hi = typ.ast_bounds num_bound_code = f""" @@ -180,16 +186,22 @@ def _num_min() -> {typ}: assert c._num_sub(lo, 0) == lo assert c._num_add(hi - 1, 1) == hi assert c._num_sub(lo + 1, 1) == lo - assert_tx_failed(lambda: c._num_add(hi, 1)) - assert_tx_failed(lambda: c._num_sub(lo, 1)) - assert_tx_failed(lambda: c._num_add(hi - 1, 2)) - assert_tx_failed(lambda: c._num_sub(lo + 1, 2)) + with tx_failed(): + c._num_add(hi, 1) + with tx_failed(): + c._num_sub(lo, 1) + with tx_failed(): + c._num_add(hi - 1, 2) + with tx_failed(): + c._num_sub(lo + 1, 2) assert c._num_max() == hi assert c._num_min() == lo - assert_tx_failed(lambda: c._num_add3(hi, 1, -1)) + with tx_failed(): + c._num_add3(hi, 1, -1) assert c._num_add3(hi, -1, 1) == hi - 1 + 1 - assert_tx_failed(lambda: c._num_add3(lo, -1, 1)) + with tx_failed(): + c._num_add3(lo, -1, 1) assert c._num_add3(lo, 1, -1) == lo + 1 - 1 @@ -219,7 +231,7 @@ def num_sub() -> {typ}: @pytest.mark.parametrize("op", sorted(ARITHMETIC_OPS.keys())) @pytest.mark.parametrize("typ", types) @pytest.mark.fuzzing -def test_arithmetic_thorough(get_contract, assert_tx_failed, assert_compile_failed, op, typ): +def test_arithmetic_thorough(get_contract, tx_failed, assert_compile_failed, op, typ): # both variables code_1 = f""" @external @@ -304,14 +316,19 @@ def foo() -> {typ}: assert get_contract(code_3).foo(y) == expected assert get_contract(code_4).foo() == expected elif div_by_zero: - assert_tx_failed(lambda p=(x, y): c.foo(*p)) + with tx_failed(): + c.foo(x, y) assert_compile_failed(lambda code=code_2: get_contract(code), ZeroDivisionException) - assert_tx_failed(lambda p=y, code=code_3: get_contract(code).foo(p)) + with tx_failed(): + get_contract(code_3).foo(y) assert_compile_failed(lambda code=code_4: get_contract(code), ZeroDivisionException) else: - assert_tx_failed(lambda p=(x, y): c.foo(*p)) - assert_tx_failed(lambda p=x, code=code_2: get_contract(code).foo(p)) - assert_tx_failed(lambda p=y, code=code_3: get_contract(code).foo(p)) + with tx_failed(): + c.foo(x, y) + with tx_failed(): + get_contract(code_2).foo(x) + with tx_failed(): + get_contract(code_3).foo(y) assert_compile_failed( lambda code=code_4: get_contract(code), (InvalidType, OverflowException) ) @@ -372,7 +389,7 @@ def foo(x: {typ}, y: {typ}) -> bool: @pytest.mark.parametrize("typ", types) -def test_negation(get_contract, assert_tx_failed, typ): +def test_negation(get_contract, tx_failed, typ): code = f""" @external def foo(a: {typ}) -> {typ}: @@ -390,7 +407,8 @@ def foo(a: {typ}) -> {typ}: assert c.foo(2) == -2 assert c.foo(-2) == 2 - assert_tx_failed(lambda: c.foo(lo)) + with tx_failed(): + c.foo(lo) @pytest.mark.parametrize("typ", types) diff --git a/tests/functional/codegen/types/numbers/test_unsigned_ints.py b/tests/functional/codegen/types/numbers/test_unsigned_ints.py index 6c8d114f29..8982065b5d 100644 --- a/tests/functional/codegen/types/numbers/test_unsigned_ints.py +++ b/tests/functional/codegen/types/numbers/test_unsigned_ints.py @@ -85,7 +85,7 @@ def foo(x: {typ}) -> {typ}: @pytest.mark.parametrize("op", sorted(ARITHMETIC_OPS.keys())) @pytest.mark.parametrize("typ", types) @pytest.mark.fuzzing -def test_arithmetic_thorough(get_contract, assert_tx_failed, assert_compile_failed, op, typ): +def test_arithmetic_thorough(get_contract, tx_failed, assert_compile_failed, op, typ): # both variables code_1 = f""" @external @@ -148,17 +148,23 @@ def foo() -> {typ}: assert get_contract(code_3).foo(y) == expected assert get_contract(code_4).foo() == expected elif div_by_zero: - assert_tx_failed(lambda p=(x, y): c.foo(*p)) - assert_compile_failed(lambda code=code_2: get_contract(code), ZeroDivisionException) - assert_tx_failed(lambda p=y, code=code_3: get_contract(code).foo(p)) - assert_compile_failed(lambda code=code_4: get_contract(code), ZeroDivisionException) + with tx_failed(): + c.foo(x, y) + with pytest.raises(ZeroDivisionException): + get_contract(code_2) + with tx_failed(): + get_contract(code_3).foo(y) + with pytest.raises(ZeroDivisionException): + get_contract(code_4) else: - assert_tx_failed(lambda p=(x, y): c.foo(*p)) - assert_tx_failed(lambda code=code_2, p=x: get_contract(code).foo(p)) - assert_tx_failed(lambda p=y, code=code_3: get_contract(code).foo(p)) - assert_compile_failed( - lambda code=code_4: get_contract(code), (InvalidType, OverflowException) - ) + with tx_failed(): + c.foo(x, y) + with tx_failed(): + get_contract(code_2).foo(x) + with tx_failed(): + get_contract(code_3).foo(y) + with pytest.raises((InvalidType, OverflowException)): + get_contract(code_4) COMPARISON_OPS = { diff --git a/tests/functional/codegen/types/test_bytes.py b/tests/functional/codegen/types/test_bytes.py index 01ec75d5c1..1ee9b8d835 100644 --- a/tests/functional/codegen/types/test_bytes.py +++ b/tests/functional/codegen/types/test_bytes.py @@ -3,7 +3,7 @@ from vyper.exceptions import InvalidType, TypeMismatch -def test_test_bytes(get_contract_with_gas_estimation, assert_tx_failed): +def test_test_bytes(get_contract_with_gas_estimation, tx_failed): test_bytes = """ @external def foo(x: Bytes[100]) -> Bytes[100]: @@ -21,7 +21,8 @@ def foo(x: Bytes[100]) -> Bytes[100]: print("Passed max-length bytes test") # test for greater than 100 bytes, should raise exception - assert_tx_failed(lambda: c.foo(b"\x35" * 101)) + with tx_failed(): + c.foo(b"\x35" * 101) print("Passed input-too-long test") diff --git a/tests/functional/codegen/types/test_dynamic_array.py b/tests/functional/codegen/types/test_dynamic_array.py index d793a56d6e..4ef6874ae9 100644 --- a/tests/functional/codegen/types/test_dynamic_array.py +++ b/tests/functional/codegen/types/test_dynamic_array.py @@ -759,27 +759,30 @@ def test_multi4_2() -> DynArray[DynArray[DynArray[DynArray[uint256, 2], 2], 2], assert c.test_multi4_2() == nest4 -def test_uint256_accessor(get_contract_with_gas_estimation, assert_tx_failed): +def test_uint256_accessor(get_contract_with_gas_estimation, tx_failed): code = """ @external def bounds_check_uint256(xs: DynArray[uint256, 3], ix: uint256) -> uint256: return xs[ix] """ c = get_contract_with_gas_estimation(code) - assert_tx_failed(lambda: c.bounds_check_uint256([], 0)) + with tx_failed(): + c.bounds_check_uint256([], 0) assert c.bounds_check_uint256([1], 0) == 1 - assert_tx_failed(lambda: c.bounds_check_uint256([1], 1)) + with tx_failed(): + c.bounds_check_uint256([1], 1) assert c.bounds_check_uint256([1, 2, 3], 0) == 1 assert c.bounds_check_uint256([1, 2, 3], 2) == 3 - assert_tx_failed(lambda: c.bounds_check_uint256([1, 2, 3], 3)) + with tx_failed(): + c.bounds_check_uint256([1, 2, 3], 3) # TODO do bounds checks for nested darrays @pytest.mark.parametrize("list_", ([], [11], [11, 12], [11, 12, 13])) -def test_dynarray_len(get_contract_with_gas_estimation, assert_tx_failed, list_): +def test_dynarray_len(get_contract_with_gas_estimation, tx_failed, list_): code = """ @external def darray_len(xs: DynArray[uint256, 3]) -> uint256: @@ -790,7 +793,7 @@ def darray_len(xs: DynArray[uint256, 3]) -> uint256: assert c.darray_len(list_) == len(list_) -def test_dynarray_too_large(get_contract_with_gas_estimation, assert_tx_failed): +def test_dynarray_too_large(get_contract_with_gas_estimation, tx_failed): code = """ @external def darray_len(xs: DynArray[uint256, 3]) -> uint256: @@ -798,10 +801,11 @@ def darray_len(xs: DynArray[uint256, 3]) -> uint256: """ c = get_contract_with_gas_estimation(code) - assert_tx_failed(lambda: c.darray_len([1, 2, 3, 4])) + with tx_failed(): + c.darray_len([1, 2, 3, 4]) -def test_int128_accessor(get_contract_with_gas_estimation, assert_tx_failed): +def test_int128_accessor(get_contract_with_gas_estimation, tx_failed): code = """ @external def bounds_check_int128(ix: int128) -> uint256: @@ -811,8 +815,10 @@ def bounds_check_int128(ix: int128) -> uint256: c = get_contract_with_gas_estimation(code) assert c.bounds_check_int128(0) == 1 assert c.bounds_check_int128(2) == 3 - assert_tx_failed(lambda: c.bounds_check_int128(3)) - assert_tx_failed(lambda: c.bounds_check_int128(-1)) + with tx_failed(): + c.bounds_check_int128(3) + with tx_failed(): + c.bounds_check_int128(-1) def test_index_exception(get_contract_with_gas_estimation, assert_compile_failed): @@ -1164,12 +1170,13 @@ def test_invalid_append_pop(get_contract, assert_compile_failed, code, exception @pytest.mark.parametrize("code,check_result", append_pop_tests) # TODO change this to fuzz random data @pytest.mark.parametrize("test_data", [[1, 2, 3, 4, 5][:i] for i in range(6)]) -def test_append_pop(get_contract, assert_tx_failed, code, check_result, test_data): +def test_append_pop(get_contract, tx_failed, code, check_result, test_data): c = get_contract(code) expected_result = check_result(test_data) if expected_result is None: # None is sentinel to indicate txn should revert - assert_tx_failed(lambda: c.foo(test_data)) + with tx_failed(): + c.foo(test_data) else: assert c.foo(test_data) == expected_result @@ -1234,7 +1241,7 @@ def foo(x: {typ}) -> {typ}: ["uint256[3]", "DynArray[uint256,3]", "DynArray[uint8, 4]", "Foo", "DynArray[Foobar, 3]"], ) # TODO change this to fuzz random data -def test_append_pop_complex(get_contract, assert_tx_failed, code_template, check_result, subtype): +def test_append_pop_complex(get_contract, tx_failed, code_template, check_result, subtype): code = code_template.format(typ=subtype) test_data = [1, 2, 3] if subtype == "Foo": @@ -1260,7 +1267,8 @@ def test_append_pop_complex(get_contract, assert_tx_failed, code_template, check expected_result = check_result(test_data) if expected_result is None: # None is sentinel to indicate txn should revert - assert_tx_failed(lambda: c.foo(test_data)) + with tx_failed(): + c.foo(test_data) else: assert c.foo(test_data) == expected_result @@ -1330,7 +1338,7 @@ def bar(_baz: DynArray[Foo, 3]) -> String[96]: assert c.bar(c_input) == "Hello world!!!!" -def test_list_of_structs_lists_with_nested_lists(get_contract, assert_tx_failed): +def test_list_of_structs_lists_with_nested_lists(get_contract, tx_failed): code = """ struct Bar: a: DynArray[uint8[2], 2] @@ -1351,7 +1359,8 @@ def foo(x: uint8) -> uint8: """ c = get_contract(code) assert c.foo(17) == 98 - assert_tx_failed(lambda: c.foo(241)) + with tx_failed(): + c.foo(241) def test_list_of_nested_struct_arrays(get_contract): @@ -1622,7 +1631,7 @@ def bar() -> uint256: assert c.bar() == 58 -def test_constant_list(get_contract, assert_tx_failed): +def test_constant_list(get_contract, tx_failed): some_good_primes = [5.0, 11.0, 17.0, 29.0, 37.0, 41.0] code = f""" MY_LIST: constant(DynArray[decimal, 6]) = {some_good_primes} @@ -1634,7 +1643,8 @@ def ix(i: uint256) -> decimal: for i, p in enumerate(some_good_primes): assert c.ix(i) == p # assert oob - assert_tx_failed(lambda: c.ix(len(some_good_primes) + 1)) + with tx_failed(): + c.ix(len(some_good_primes) + 1) def test_public_dynarray(get_contract): @@ -1831,7 +1841,8 @@ def should_revert() -> DynArray[String[65], 2]: @pytest.mark.parametrize("code", dynarray_length_no_clobber_cases) -def test_dynarray_length_no_clobber(get_contract, assert_tx_failed, code): +def test_dynarray_length_no_clobber(get_contract, tx_failed, code): # check that length is not clobbered before dynarray data copy happens c = get_contract(code) - assert_tx_failed(lambda: c.should_revert()) + with tx_failed(): + c.should_revert() diff --git a/tests/functional/codegen/types/test_flag.py b/tests/functional/codegen/types/test_flag.py index 03c22134ed..5da6d57558 100644 --- a/tests/functional/codegen/types/test_flag.py +++ b/tests/functional/codegen/types/test_flag.py @@ -74,7 +74,7 @@ def is_not_boss(a: Roles) -> bool: assert c.is_not_boss(2**4) is False -def test_bitwise(get_contract, assert_tx_failed): +def test_bitwise(get_contract, tx_failed): code = """ flag Roles: USER @@ -134,18 +134,25 @@ def binv_arg(a: Roles) -> Roles: assert c.binv_arg(0b00000) == 0b11111 # LHS is out of bound - assert_tx_failed(lambda: c.bor_arg(32, 3)) - assert_tx_failed(lambda: c.band_arg(32, 3)) - assert_tx_failed(lambda: c.bxor_arg(32, 3)) - assert_tx_failed(lambda: c.binv_arg(32)) + with tx_failed(): + c.bor_arg(32, 3) + with tx_failed(): + c.band_arg(32, 3) + with tx_failed(): + c.bxor_arg(32, 3) + with tx_failed(): + c.binv_arg(32) # RHS - assert_tx_failed(lambda: c.bor_arg(3, 32)) - assert_tx_failed(lambda: c.band_arg(3, 32)) - assert_tx_failed(lambda: c.bxor_arg(3, 32)) + with tx_failed(): + c.bor_arg(3, 32) + with tx_failed(): + c.band_arg(3, 32) + with tx_failed(): + c.bxor_arg(3, 32) -def test_augassign_storage(get_contract, w3, assert_tx_failed): +def test_augassign_storage(get_contract, w3, tx_failed): code = """ flag Roles: ADMIN @@ -190,7 +197,8 @@ def checkMinter(minter: address): assert c.roles(minter_address) == 0b10 # admin is not a minter - assert_tx_failed(lambda: c.checkMinter(admin_address)) + with tx_failed(): + c.checkMinter(admin_address) c.addMinter(admin_address, transact={}) @@ -201,7 +209,8 @@ def checkMinter(minter: address): # revoke minter c.revokeMinter(admin_address, transact={}) assert c.roles(admin_address) == 0b01 - assert_tx_failed(lambda: c.checkMinter(admin_address)) + with tx_failed(): + c.checkMinter(admin_address) # flip minter c.flipMinter(admin_address, transact={}) @@ -211,7 +220,8 @@ def checkMinter(minter: address): # flip minter c.flipMinter(admin_address, transact={}) assert c.roles(admin_address) == 0b01 - assert_tx_failed(lambda: c.checkMinter(admin_address)) + with tx_failed(): + c.checkMinter(admin_address) def test_in_flag(get_contract_with_gas_estimation): diff --git a/tests/functional/codegen/types/test_lists.py b/tests/functional/codegen/types/test_lists.py index 832b679e5e..657c4ba0b8 100644 --- a/tests/functional/codegen/types/test_lists.py +++ b/tests/functional/codegen/types/test_lists.py @@ -353,7 +353,7 @@ def test_multi4() -> uint256[2][2][2][2]: @pytest.mark.parametrize("type_", ["uint8", "uint256"]) -def test_unsigned_accessors(get_contract_with_gas_estimation, assert_tx_failed, type_): +def test_unsigned_accessors(get_contract_with_gas_estimation, tx_failed, type_): code = f""" @external def bounds_check(ix: {type_}) -> uint256: @@ -363,11 +363,12 @@ def bounds_check(ix: {type_}) -> uint256: c = get_contract_with_gas_estimation(code) assert c.bounds_check(0) == 1 assert c.bounds_check(2) == 3 - assert_tx_failed(lambda: c.bounds_check(3)) + with tx_failed(): + c.bounds_check(3) @pytest.mark.parametrize("type_", ["int128", "int256"]) -def test_signed_accessors(get_contract_with_gas_estimation, assert_tx_failed, type_): +def test_signed_accessors(get_contract_with_gas_estimation, tx_failed, type_): code = f""" @external def bounds_check(ix: {type_}) -> uint256: @@ -377,8 +378,10 @@ def bounds_check(ix: {type_}) -> uint256: c = get_contract_with_gas_estimation(code) assert c.bounds_check(0) == 1 assert c.bounds_check(2) == 3 - assert_tx_failed(lambda: c.bounds_check(3)) - assert_tx_failed(lambda: c.bounds_check(-1)) + with tx_failed(): + c.bounds_check(3) + with tx_failed(): + c.bounds_check(-1) def test_list_check_heterogeneous_types(get_contract_with_gas_estimation, assert_compile_failed): @@ -662,7 +665,7 @@ def foo(x: Bar[2][2][2]) -> uint256: ("bool", [True, False, True, False, True, False]), ], ) -def test_constant_list(get_contract, assert_tx_failed, type, value): +def test_constant_list(get_contract, tx_failed, type, value): code = f""" MY_LIST: constant({type}[{len(value)}]) = {value} @external @@ -673,7 +676,8 @@ def ix(i: uint256) -> {type}: for i, p in enumerate(value): assert c.ix(i) == p # assert oob - assert_tx_failed(lambda: c.ix(len(value) + 1)) + with tx_failed(): + c.ix(len(value) + 1) def test_nested_constant_list_accessor(get_contract): @@ -728,7 +732,7 @@ def foo(i: uint256) -> {return_type}: assert_compile_failed(lambda: get_contract(code), TypeMismatch) -def test_constant_list_address(get_contract, assert_tx_failed): +def test_constant_list_address(get_contract, tx_failed): some_good_address = [ "0x0000000000000000000000000000000000012345", "0x0000000000000000000000000000000000023456", @@ -754,10 +758,11 @@ def ix(i: uint256) -> address: for i, p in enumerate(some_good_address): assert c.ix(i) == p # assert oob - assert_tx_failed(lambda: c.ix(len(some_good_address) + 1)) + with tx_failed(): + c.ix(len(some_good_address) + 1) -def test_list_index_complex_expr(get_contract, assert_tx_failed): +def test_list_index_complex_expr(get_contract, tx_failed): # test subscripts where the index is not a literal code = """ @external @@ -771,7 +776,8 @@ def foo(xs: uint256[257], i: uint8) -> uint256: assert c.foo(xs, ix) == xs[ix + 1] # safemath should fail for uint8: 255 + 1. - assert_tx_failed(lambda: c.foo(xs, 255)) + with tx_failed(): + c.foo(xs, 255) @pytest.mark.parametrize( @@ -793,7 +799,7 @@ def foo(xs: uint256[257], i: uint8) -> uint256: ("bool", [[True, False], [True, False], [True, False]]), ], ) -def test_constant_nested_list(get_contract, assert_tx_failed, type, value): +def test_constant_nested_list(get_contract, tx_failed, type, value): code = f""" MY_LIST: constant({type}[{len(value[0])}][{len(value)}]) = {value} @external @@ -805,7 +811,8 @@ def ix(i: uint256, j: uint256) -> {type}: for j, q in enumerate(p): assert c.ix(i, j) == q # assert oob - assert_tx_failed(lambda: c.ix(len(value) + 1, len(value[0]) + 1)) + with tx_failed(): + c.ix(len(value) + 1, len(value[0]) + 1) @pytest.mark.parametrize("storage_type,return_type", itertools.permutations(integer_types, 2)) diff --git a/tests/functional/codegen/types/test_string.py b/tests/functional/codegen/types/test_string.py index 7f1fa71329..9d50f8df38 100644 --- a/tests/functional/codegen/types/test_string.py +++ b/tests/functional/codegen/types/test_string.py @@ -61,7 +61,7 @@ def get(k: String[34]) -> int128: assert c.get("a" * 34) == 6789 -def test_string_slice(get_contract_with_gas_estimation, assert_tx_failed): +def test_string_slice(get_contract_with_gas_estimation, tx_failed): test_slice4 = """ @external def foo(inp: String[10], start: uint256, _len: uint256) -> String[10]: @@ -76,10 +76,14 @@ def foo(inp: String[10], start: uint256, _len: uint256) -> String[10]: assert c.foo("badminton", 1, 0) == "" assert c.foo("badminton", 9, 0) == "" - assert_tx_failed(lambda: c.foo("badminton", 0, 10)) - assert_tx_failed(lambda: c.foo("badminton", 1, 9)) - assert_tx_failed(lambda: c.foo("badminton", 9, 1)) - assert_tx_failed(lambda: c.foo("badminton", 10, 0)) + with tx_failed(): + c.foo("badminton", 0, 10) + with tx_failed(): + c.foo("badminton", 1, 9) + with tx_failed(): + c.foo("badminton", 9, 1) + with tx_failed(): + c.foo("badminton", 10, 0) def test_private_string(get_contract_with_gas_estimation): diff --git a/tests/functional/examples/auctions/test_blind_auction.py b/tests/functional/examples/auctions/test_blind_auction.py index d814ab0cad..dcd4e0bf8b 100644 --- a/tests/functional/examples/auctions/test_blind_auction.py +++ b/tests/functional/examples/auctions/test_blind_auction.py @@ -33,15 +33,15 @@ def test_initial_state(w3, tester, auction_contract): assert auction_contract.highestBidder() is None -def test_late_bid(w3, auction_contract, assert_tx_failed): +def test_late_bid(w3, auction_contract, tx_failed): k1 = w3.eth.accounts[1] # Move time forward past bidding end w3.testing.mine(BIDDING_TIME + TEST_INCREMENT) # Try to bid after bidding has ended - assert_tx_failed( - lambda: auction_contract.bid( + with tx_failed(): + auction_contract.bid( w3.keccak( b"".join( [ @@ -53,10 +53,9 @@ def test_late_bid(w3, auction_contract, assert_tx_failed): ), transact={"value": 200, "from": k1}, ) - ) -def test_too_many_bids(w3, auction_contract, assert_tx_failed): +def test_too_many_bids(w3, auction_contract, tx_failed): k1 = w3.eth.accounts[1] # First 128 bids should be able to be placed successfully @@ -75,8 +74,8 @@ def test_too_many_bids(w3, auction_contract, assert_tx_failed): ) # 129th bid should fail - assert_tx_failed( - lambda: auction_contract.bid( + with tx_failed(): + auction_contract.bid( w3.keccak( b"".join( [ @@ -88,10 +87,9 @@ def test_too_many_bids(w3, auction_contract, assert_tx_failed): ), transact={"value": 128, "from": k1}, ) - ) -def test_early_reval(w3, auction_contract, assert_tx_failed): +def test_early_reval(w3, auction_contract, tx_failed): k1 = w3.eth.accounts[1] # k1 places 1 real bid @@ -119,11 +117,10 @@ def test_early_reval(w3, auction_contract, assert_tx_failed): _values[0] = 100 _fakes[0] = False _secrets[0] = (8675309).to_bytes(32, byteorder="big") - assert_tx_failed( - lambda: auction_contract.reveal( + with tx_failed(): + auction_contract.reveal( _numBids, _values, _fakes, _secrets, transact={"value": 0, "from": k1} ) - ) # Check highest bidder is still empty assert auction_contract.highestBidder() is None @@ -131,7 +128,7 @@ def test_early_reval(w3, auction_contract, assert_tx_failed): assert auction_contract.highestBid() == 0 -def test_late_reveal(w3, auction_contract, assert_tx_failed): +def test_late_reveal(w3, auction_contract, tx_failed): k1 = w3.eth.accounts[1] # k1 places 1 real bid @@ -159,11 +156,10 @@ def test_late_reveal(w3, auction_contract, assert_tx_failed): _values[0] = 100 _fakes[0] = False _secrets[0] = (8675309).to_bytes(32, byteorder="big") - assert_tx_failed( - lambda: auction_contract.reveal( + with tx_failed(): + auction_contract.reveal( _numBids, _values, _fakes, _secrets, transact={"value": 0, "from": k1} ) - ) # Check highest bidder is still empty assert auction_contract.highestBidder() is None @@ -171,14 +167,15 @@ def test_late_reveal(w3, auction_contract, assert_tx_failed): assert auction_contract.highestBid() == 0 -def test_early_end(w3, auction_contract, assert_tx_failed): +def test_early_end(w3, auction_contract, tx_failed): k0 = w3.eth.accounts[0] # Should not be able to end auction before reveal time has ended - assert_tx_failed(lambda: auction_contract.auctionEnd(transact={"value": 0, "from": k0})) + with tx_failed(): + auction_contract.auctionEnd(transact={"value": 0, "from": k0}) -def test_double_end(w3, auction_contract, assert_tx_failed): +def test_double_end(w3, auction_contract, tx_failed): k0 = w3.eth.accounts[0] # Move time forward past bidding and reveal end @@ -188,7 +185,8 @@ def test_double_end(w3, auction_contract, assert_tx_failed): auction_contract.auctionEnd(transact={"value": 0, "from": k0}) # Should not be able to end auction twice - assert_tx_failed(lambda: auction_contract.auctionEnd(transact={"value": 0, "from": k0})) + with tx_failed(): + auction_contract.auctionEnd(transact={"value": 0, "from": k0}) def test_blind_auction(w3, auction_contract): diff --git a/tests/functional/examples/auctions/test_simple_open_auction.py b/tests/functional/examples/auctions/test_simple_open_auction.py index cf0bb8cc20..c80b44d976 100644 --- a/tests/functional/examples/auctions/test_simple_open_auction.py +++ b/tests/functional/examples/auctions/test_simple_open_auction.py @@ -33,17 +33,19 @@ def test_initial_state(w3, tester, auction_contract, auction_start): assert auction_contract.auctionEnd() >= tester.get_block_by_number("latest")["timestamp"] -def test_bid(w3, tester, auction_contract, assert_tx_failed): +def test_bid(w3, tester, auction_contract, tx_failed): k1, k2, k3, k4, k5 = w3.eth.accounts[:5] # Bidder cannot bid 0 - assert_tx_failed(lambda: auction_contract.bid(transact={"value": 0, "from": k1})) + with tx_failed(): + auction_contract.bid(transact={"value": 0, "from": k1}) # Bidder can bid auction_contract.bid(transact={"value": 1, "from": k1}) # Check that highest bidder and highest bid have changed accordingly assert auction_contract.highestBidder() == k1 assert auction_contract.highestBid() == 1 # Bidder bid cannot equal current highest bid - assert_tx_failed(lambda: auction_contract.bid(transact={"value": 1, "from": k1})) + with tx_failed(): + auction_contract.bid(transact={"value": 1, "from": k1}) # Higher bid can replace current highest bid auction_contract.bid(transact={"value": 2, "from": k2}) # Check that highest bidder and highest bid have changed accordingly @@ -72,10 +74,11 @@ def test_bid(w3, tester, auction_contract, assert_tx_failed): assert auction_contract.pendingReturns(k1) == 0 -def test_end_auction(w3, tester, auction_contract, assert_tx_failed): +def test_end_auction(w3, tester, auction_contract, tx_failed): k1, k2, k3, k4, k5 = w3.eth.accounts[:5] # Fails if auction end time has not been reached - assert_tx_failed(lambda: auction_contract.endAuction()) + with tx_failed(): + auction_contract.endAuction() auction_contract.bid(transact={"value": 1 * 10**10, "from": k2}) # Move block timestamp foreward to reach auction end time # tester.time_travel(tester.get_block_by_number('latest')['timestamp'] + EXPIRY) @@ -86,6 +89,8 @@ def test_end_auction(w3, tester, auction_contract, assert_tx_failed): # Beneficiary receives the highest bid assert balance_after_end == balance_before_end + 1 * 10**10 # Bidder cannot bid after auction end time has been reached - assert_tx_failed(lambda: auction_contract.bid(transact={"value": 10, "from": k1})) + with tx_failed(): + auction_contract.bid(transact={"value": 10, "from": k1}) # Auction cannot be ended twice - assert_tx_failed(lambda: auction_contract.endAuction()) + with tx_failed(): + auction_contract.endAuction() diff --git a/tests/functional/examples/company/test_company.py b/tests/functional/examples/company/test_company.py index 71141b8bb5..5933a14e86 100644 --- a/tests/functional/examples/company/test_company.py +++ b/tests/functional/examples/company/test_company.py @@ -9,7 +9,7 @@ def c(w3, get_contract): return contract -def test_overbuy(w3, c, assert_tx_failed): +def test_overbuy(w3, c, tx_failed): # If all the stock has been bought, no one can buy more a1, a2 = w3.eth.accounts[1:3] test_shares = int(c.totalShares() / 2) @@ -19,15 +19,19 @@ def test_overbuy(w3, c, assert_tx_failed): assert c.stockAvailable() == 0 assert c.getHolding(a1) == (test_shares * 2) one_stock = c.price() - assert_tx_failed(lambda: c.buyStock(transact={"from": a1, "value": one_stock})) - assert_tx_failed(lambda: c.buyStock(transact={"from": a2, "value": one_stock})) + with tx_failed(): + c.buyStock(transact={"from": a1, "value": one_stock}) + with tx_failed(): + c.buyStock(transact={"from": a2, "value": one_stock}) -def test_sell_without_stock(w3, c, assert_tx_failed): +def test_sell_without_stock(w3, c, tx_failed): a1, a2 = w3.eth.accounts[1:3] # If you don't have any stock, you can't sell - assert_tx_failed(lambda: c.sellStock(1, transact={"from": a1})) - assert_tx_failed(lambda: c.sellStock(1, transact={"from": a2})) + with tx_failed(): + c.sellStock(1, transact={"from": a1}) + with tx_failed(): + c.sellStock(1, transact={"from": a2}) # But if you do, you can! test_shares = int(c.totalShares()) test_value = int(test_shares * c.price()) @@ -35,48 +39,57 @@ def test_sell_without_stock(w3, c, assert_tx_failed): assert c.getHolding(a1) == test_shares c.sellStock(test_shares, transact={"from": a1}) # But only until you run out - assert_tx_failed(lambda: c.sellStock(1, transact={"from": a1})) + with tx_failed(): + c.sellStock(1, transact={"from": a1}) -def test_oversell(w3, c, assert_tx_failed): +def test_oversell(w3, c, tx_failed): a0, a1, a2 = w3.eth.accounts[:3] # You can't sell more than you own test_shares = int(c.totalShares()) test_value = int(test_shares * c.price()) c.buyStock(transact={"from": a1, "value": test_value}) - assert_tx_failed(lambda: c.sellStock(test_shares + 1, transact={"from": a1})) + with tx_failed(): + c.sellStock(test_shares + 1, transact={"from": a1}) -def test_transfer(w3, c, assert_tx_failed): +def test_transfer(w3, c, tx_failed): # If you don't have any stock, you can't transfer a1, a2 = w3.eth.accounts[1:3] - assert_tx_failed(lambda: c.transferStock(a2, 1, transact={"from": a1})) - assert_tx_failed(lambda: c.transferStock(a1, 1, transact={"from": a2})) + with tx_failed(): + c.transferStock(a2, 1, transact={"from": a1}) + with tx_failed(): + c.transferStock(a1, 1, transact={"from": a2}) # If you transfer, you don't have the stock anymore test_shares = int(c.totalShares()) test_value = int(test_shares * c.price()) c.buyStock(transact={"from": a1, "value": test_value}) assert c.getHolding(a1) == test_shares c.transferStock(a2, test_shares, transact={"from": a1}) - assert_tx_failed(lambda: c.sellStock(1, transact={"from": a1})) + with tx_failed(): + c.sellStock(1, transact={"from": a1}) # But the other person does c.sellStock(test_shares, transact={"from": a2}) -def test_paybill(w3, c, assert_tx_failed): +def test_paybill(w3, c, tx_failed): a0, a1, a2, a3 = w3.eth.accounts[:4] # Only the company can authorize payments - assert_tx_failed(lambda: c.payBill(a2, 1, transact={"from": a1})) + with tx_failed(): + c.payBill(a2, 1, transact={"from": a1}) # A company can only pay someone if it has the money - assert_tx_failed(lambda: c.payBill(a2, 1, transact={"from": a0})) + with tx_failed(): + c.payBill(a2, 1, transact={"from": a0}) # If it has the money, it can pay someone test_value = int(c.totalShares() * c.price()) c.buyStock(transact={"from": a1, "value": test_value}) c.payBill(a2, test_value, transact={"from": a0}) # Until it runs out of money - assert_tx_failed(lambda: c.payBill(a3, 1, transact={"from": a0})) + with tx_failed(): + c.payBill(a3, 1, transact={"from": a0}) # Then no stockholders can sell their stock either - assert_tx_failed(lambda: c.sellStock(1, transact={"from": a1})) + with tx_failed(): + c.sellStock(1, transact={"from": a1}) def test_valuation(w3, c): diff --git a/tests/functional/examples/crowdfund/test_crowdfund_example.py b/tests/functional/examples/crowdfund/test_crowdfund_example.py index 9a08d9241c..e75a88bf48 100644 --- a/tests/functional/examples/crowdfund/test_crowdfund_example.py +++ b/tests/functional/examples/crowdfund/test_crowdfund_example.py @@ -27,7 +27,7 @@ def test_crowdfund_example(c, w3): assert post_bal - pre_bal == 54 -def test_crowdfund_example2(c, w3, assert_tx_failed): +def test_crowdfund_example2(c, w3, tx_failed): a0, a1, a2, a3, a4, a5, a6 = w3.eth.accounts[:7] c.participate(transact={"value": 1, "from": a3}) c.participate(transact={"value": 2, "from": a4}) @@ -39,9 +39,11 @@ def test_crowdfund_example2(c, w3, assert_tx_failed): # assert c.expired() # assert not c.reached() pre_bals = [w3.eth.get_balance(x) for x in [a3, a4, a5, a6]] - assert_tx_failed(lambda: c.refund(transact={"from": a0})) + with tx_failed(): + c.refund(transact={"from": a0}) c.refund(transact={"from": a3}) - assert_tx_failed(lambda: c.refund(transact={"from": a3})) + with tx_failed(): + c.refund(transact={"from": a3}) c.refund(transact={"from": a4}) c.refund(transact={"from": a5}) c.refund(transact={"from": a6}) diff --git a/tests/functional/examples/market_maker/test_on_chain_market_maker.py b/tests/functional/examples/market_maker/test_on_chain_market_maker.py index db9700da3b..235a0ea66f 100644 --- a/tests/functional/examples/market_maker/test_on_chain_market_maker.py +++ b/tests/functional/examples/market_maker/test_on_chain_market_maker.py @@ -31,25 +31,21 @@ def test_initial_state(market_maker): assert market_maker.owner() is None -def test_initiate(w3, market_maker, erc20, assert_tx_failed): +def test_initiate(w3, market_maker, erc20, tx_failed): a0 = w3.eth.accounts[0] - erc20.approve(market_maker.address, w3.to_wei(2, "ether"), transact={}) - market_maker.initiate( - erc20.address, w3.to_wei(1, "ether"), transact={"value": w3.to_wei(2, "ether")} - ) - assert market_maker.totalEthQty() == w3.to_wei(2, "ether") - assert market_maker.totalTokenQty() == w3.to_wei(1, "ether") + ether, ethers = w3.to_wei(1, "ether"), w3.to_wei(2, "ether") + erc20.approve(market_maker.address, ethers, transact={}) + market_maker.initiate(erc20.address, ether, transact={"value": ethers}) + assert market_maker.totalEthQty() == ethers + assert market_maker.totalTokenQty() == ether assert market_maker.invariant() == 2 * 10**36 assert market_maker.owner() == a0 assert erc20.name() == TOKEN_NAME assert erc20.decimals() == TOKEN_DECIMALS # Initiate cannot be called twice - assert_tx_failed( - lambda: market_maker.initiate( - erc20.address, w3.to_wei(1, "ether"), transact={"value": w3.to_wei(2, "ether")} - ) - ) # noqa: E501 + with tx_failed(): + market_maker.initiate(erc20.address, ether, transact={"value": ethers}) def test_eth_to_tokens(w3, market_maker, erc20): @@ -95,7 +91,7 @@ def test_tokens_to_eth(w3, market_maker, erc20): assert market_maker.totalEthQty() == w3.to_wei(1, "ether") -def test_owner_withdraw(w3, market_maker, erc20, assert_tx_failed): +def test_owner_withdraw(w3, market_maker, erc20, tx_failed): a0, a1 = w3.eth.accounts[:2] a0_balance_before = w3.eth.get_balance(a0) # Approve 2 eth transfers. @@ -110,7 +106,8 @@ def test_owner_withdraw(w3, market_maker, erc20, assert_tx_failed): assert erc20.balanceOf(a0) == TOKEN_TOTAL_SUPPLY - w3.to_wei(1, "ether") # Only owner can call ownerWithdraw - assert_tx_failed(lambda: market_maker.ownerWithdraw(transact={"from": a1})) + with tx_failed(): + market_maker.ownerWithdraw(transact={"from": a1}) market_maker.ownerWithdraw(transact={}) assert w3.eth.get_balance(a0) == a0_balance_before # Eth balance restored. assert erc20.balanceOf(a0) == TOKEN_TOTAL_SUPPLY # Tokens returned to a0. diff --git a/tests/functional/examples/name_registry/test_name_registry.py b/tests/functional/examples/name_registry/test_name_registry.py index 26f5844484..a2e92a7c52 100644 --- a/tests/functional/examples/name_registry/test_name_registry.py +++ b/tests/functional/examples/name_registry/test_name_registry.py @@ -1,8 +1,9 @@ -def test_name_registry(w3, get_contract, assert_tx_failed): +def test_name_registry(w3, get_contract, tx_failed): a0, a1 = w3.eth.accounts[:2] with open("examples/name_registry/name_registry.vy") as f: code = f.read() c = get_contract(code) c.register(b"jacques", a0, transact={}) assert c.lookup(b"jacques") == a0 - assert_tx_failed(lambda: c.register(b"jacques", a1)) + with tx_failed(): + c.register(b"jacques", a1) diff --git a/tests/functional/examples/safe_remote_purchase/test_safe_remote_purchase.py b/tests/functional/examples/safe_remote_purchase/test_safe_remote_purchase.py index 9a806ed885..2cc5dd8d4a 100644 --- a/tests/functional/examples/safe_remote_purchase/test_safe_remote_purchase.py +++ b/tests/functional/examples/safe_remote_purchase/test_safe_remote_purchase.py @@ -31,9 +31,10 @@ def get_balance(): return get_balance -def test_initial_state(w3, assert_tx_failed, get_contract, get_balance, contract_code): +def test_initial_state(w3, tx_failed, get_contract, get_balance, contract_code): # Inital deposit has to be divisible by two - assert_tx_failed(lambda: get_contract(contract_code, value=13)) + with tx_failed(): + get_contract(contract_code, value=13) # Seller puts item up for sale a0_pre_bal, a1_pre_bal = get_balance() c = get_contract(contract_code, value_in_eth=2) @@ -47,30 +48,34 @@ def test_initial_state(w3, assert_tx_failed, get_contract, get_balance, contract assert get_balance() == ((a0_pre_bal - w3.to_wei(2, "ether")), a1_pre_bal) -def test_abort(w3, assert_tx_failed, get_balance, get_contract, contract_code): +def test_abort(w3, tx_failed, get_balance, get_contract, contract_code): a0, a1, a2 = w3.eth.accounts[:3] a0_pre_bal, a1_pre_bal = get_balance() c = get_contract(contract_code, value=w3.to_wei(2, "ether")) assert c.value() == w3.to_wei(1, "ether") # Only sender can trigger refund - assert_tx_failed(lambda: c.abort(transact={"from": a2})) + with tx_failed(): + c.abort(transact={"from": a2}) # Refund works correctly c.abort(transact={"from": a0}) assert get_balance() == (a0_pre_bal, a1_pre_bal) # Purchase in process, no refund possible c = get_contract(contract_code, value=2) c.purchase(transact={"value": 2, "from": a1}) - assert_tx_failed(lambda: c.abort(transact={"from": a0})) + with tx_failed(): + c.abort(transact={"from": a0}) -def test_purchase(w3, get_contract, assert_tx_failed, get_balance, contract_code): +def test_purchase(w3, get_contract, tx_failed, get_balance, contract_code): a0, a1, a2, a3 = w3.eth.accounts[:4] init_bal_a0, init_bal_a1 = get_balance() c = get_contract(contract_code, value=2) # Purchase for too low/high price - assert_tx_failed(lambda: c.purchase(transact={"value": 1, "from": a1})) - assert_tx_failed(lambda: c.purchase(transact={"value": 3, "from": a1})) + with tx_failed(): + c.purchase(transact={"value": 1, "from": a1}) + with tx_failed(): + c.purchase(transact={"value": 3, "from": a1}) # Purchase for the correct price c.purchase(transact={"value": 2, "from": a1}) # Check if buyer is set correctly @@ -80,26 +85,29 @@ def test_purchase(w3, get_contract, assert_tx_failed, get_balance, contract_code # Check balances, both deposits should have been deducted assert get_balance() == (init_bal_a0 - 2, init_bal_a1 - 2) # Allow nobody else to purchase - assert_tx_failed(lambda: c.purchase(transact={"value": 2, "from": a3})) + with tx_failed(): + c.purchase(transact={"value": 2, "from": a3}) -def test_received(w3, get_contract, assert_tx_failed, get_balance, contract_code): +def test_received(w3, get_contract, tx_failed, get_balance, contract_code): a0, a1 = w3.eth.accounts[:2] init_bal_a0, init_bal_a1 = get_balance() c = get_contract(contract_code, value=2) # Can only be called after purchase - assert_tx_failed(lambda: c.received(transact={"from": a1})) + with tx_failed(): + c.received(transact={"from": a1}) # Purchase completed c.purchase(transact={"value": 2, "from": a1}) # Check that e.g. sender cannot trigger received - assert_tx_failed(lambda: c.received(transact={"from": a0})) + with tx_failed(): + c.received(transact={"from": a0}) # Check if buyer can call receive c.received(transact={"from": a1}) # Final check if everything worked. 1 value has been transferred assert get_balance() == (init_bal_a0 + 1, init_bal_a1 - 1) -def test_received_reentrancy(w3, get_contract, assert_tx_failed, get_balance, contract_code): +def test_received_reentrancy(w3, get_contract, tx_failed, get_balance, contract_code): buyer_contract_code = """ interface PurchaseContract: diff --git a/tests/functional/examples/storage/test_advanced_storage.py b/tests/functional/examples/storage/test_advanced_storage.py index 13ffce4f82..313d1a7e5c 100644 --- a/tests/functional/examples/storage/test_advanced_storage.py +++ b/tests/functional/examples/storage/test_advanced_storage.py @@ -18,32 +18,30 @@ def test_initial_state(adv_storage_contract): assert adv_storage_contract.storedData() == INITIAL_VALUE -def test_failed_transactions(w3, adv_storage_contract, assert_tx_failed): +def test_failed_transactions(w3, adv_storage_contract, tx_failed): k1 = w3.eth.accounts[1] # Try to set the storage to a negative amount - assert_tx_failed(lambda: adv_storage_contract.set(-10, transact={"from": k1})) + with tx_failed(): + adv_storage_contract.set(-10, transact={"from": k1}) # Lock the contract by storing more than 100. Then try to change the value adv_storage_contract.set(150, transact={"from": k1}) - assert_tx_failed(lambda: adv_storage_contract.set(10, transact={"from": k1})) + with tx_failed(): + adv_storage_contract.set(10, transact={"from": k1}) # Reset the contract and try to change the value adv_storage_contract.reset(transact={"from": k1}) adv_storage_contract.set(10, transact={"from": k1}) assert adv_storage_contract.storedData() == 10 - # Assert a different exception (ValidationError for non matching argument type) - assert_tx_failed( - lambda: adv_storage_contract.set("foo", transact={"from": k1}), ValidationError - ) + # Assert a different exception (ValidationError for non-matching argument type) + with tx_failed(ValidationError): + adv_storage_contract.set("foo", transact={"from": k1}) # Assert a different exception that contains specific text - assert_tx_failed( - lambda: adv_storage_contract.set(1, 2, transact={"from": k1}), - ValidationError, - "invocation failed due to improper number of arguments", - ) + with tx_failed(ValidationError, "invocation failed due to improper number of arguments"): + adv_storage_contract.set(1, 2, transact={"from": k1}) def test_events(w3, adv_storage_contract, get_logs): diff --git a/tests/functional/examples/tokens/test_erc1155.py b/tests/functional/examples/tokens/test_erc1155.py index abebd024b6..5dc314c037 100644 --- a/tests/functional/examples/tokens/test_erc1155.py +++ b/tests/functional/examples/tokens/test_erc1155.py @@ -29,7 +29,7 @@ @pytest.fixture -def erc1155(get_contract, w3, assert_tx_failed): +def erc1155(get_contract, w3, tx_failed): owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] with open("examples/tokens/ERC1155ownable.vy") as f: code = f.read() @@ -41,18 +41,20 @@ def erc1155(get_contract, w3, assert_tx_failed): assert c.balanceOf(a1, 1) == 1 assert c.balanceOf(a1, 2) == 1 assert c.balanceOf(a1, 3) == 1 - assert_tx_failed( - lambda: c.mintBatch(ZERO_ADDRESS, mintBatch, minBatchSetOf10, transact={"from": owner}) - ) - assert_tx_failed(lambda: c.mintBatch(a1, [1, 2, 3], [1, 1], transact={"from": owner})) + with tx_failed(): + c.mintBatch(ZERO_ADDRESS, mintBatch, minBatchSetOf10, transact={"from": owner}) + with tx_failed(): + c.mintBatch(a1, [1, 2, 3], [1, 1], transact={"from": owner}) c.mint(a1, 21, 1, transact={"from": owner}) c.mint(a1, 22, 1, transact={"from": owner}) c.mint(a1, 23, 1, transact={"from": owner}) c.mint(a1, 24, 1, transact={"from": owner}) - assert_tx_failed(lambda: c.mint(a1, 24, 1, transact={"from": a3})) - assert_tx_failed(lambda: c.mint(ZERO_ADDRESS, 24, 1, transact={"from": owner})) + with tx_failed(): + c.mint(a1, 24, 1, transact={"from": a3}) + with tx_failed(): + c.mint(ZERO_ADDRESS, 24, 1, transact={"from": owner}) assert c.balanceOf(a1, 21) == 1 assert c.balanceOf(a1, 22) == 1 @@ -80,69 +82,76 @@ def test_initial_state(erc1155): assert erc1155.supportsInterface(ERC1155_INTERFACE_ID_METADATA) -def test_pause(erc1155, w3, assert_tx_failed): +def test_pause(erc1155, w3, tx_failed): owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] # check the pause status, pause, check, unpause, check, with owner and non-owner w3.eth.accounts # this test will check all the function that should not work when paused. assert not erc1155.paused() # try to pause the contract from a non owner account - assert_tx_failed(lambda: erc1155.pause(transact={"from": a1})) + with tx_failed(): + erc1155.pause(transact={"from": a1}) # now pause the contract and check status erc1155.pause(transact={"from": owner}) assert erc1155.paused() # try pausing a paused contract - assert_tx_failed(lambda: erc1155.pause()) + with tx_failed(): + erc1155.pause() # try functions that should not work when paused - assert_tx_failed(lambda: erc1155.setURI(NEW_CONTRACT_URI)) + with tx_failed(): + erc1155.setURI(NEW_CONTRACT_URI) # test burn and burnbatch - assert_tx_failed(lambda: erc1155.burn(21, 1)) - assert_tx_failed(lambda: erc1155.burnBatch([21, 22], [1, 1])) + with tx_failed(): + erc1155.burn(21, 1) + with tx_failed(): + erc1155.burnBatch([21, 22], [1, 1]) # check mint and mintbatch - assert_tx_failed(lambda: erc1155.mint(a1, 21, 1, transact={"from": owner})) - assert_tx_failed( - lambda: erc1155.mintBatch(a1, mintBatch, minBatchSetOf10, transact={"from": owner}) - ) + with tx_failed(): + erc1155.mint(a1, 21, 1, transact={"from": owner}) + with tx_failed(): + erc1155.mintBatch(a1, mintBatch, minBatchSetOf10, transact={"from": owner}) # check safetransferfrom and safebatchtransferfrom - assert_tx_failed( - lambda: erc1155.safeTransferFrom(a1, a2, 21, 1, DUMMY_BYTES32_DATA, transact={"from": a1}) - ) - assert_tx_failed( - lambda: erc1155.safeBatchTransferFrom( + with tx_failed(): + erc1155.safeTransferFrom(a1, a2, 21, 1, DUMMY_BYTES32_DATA, transact={"from": a1}) + with tx_failed(): + erc1155.safeBatchTransferFrom( a1, a2, [21, 22, 23], [1, 1, 1], DUMMY_BYTES32_DATA, transact={"from": a1} ) - ) # check ownership functions - assert_tx_failed(lambda: erc1155.transferOwnership(a1)) - assert_tx_failed(lambda: erc1155.renounceOwnership()) + with tx_failed(): + erc1155.transferOwnership(a1) + with tx_failed(): + erc1155.renounceOwnership() # check approval functions - assert_tx_failed(lambda: erc1155.setApprovalForAll(owner, a5, True)) + with tx_failed(): + erc1155.setApprovalForAll(owner, a5, True) # try and unpause as non-owner - assert_tx_failed(lambda: erc1155.unpause(transact={"from": a1})) + with tx_failed(): + erc1155.unpause(transact={"from": a1}) erc1155.unpause(transact={"from": owner}) assert not erc1155.paused() # try un pausing an unpaused contract - assert_tx_failed(lambda: erc1155.unpause()) + with tx_failed(): + erc1155.unpause() -def test_contractURI(erc1155, w3, assert_tx_failed): +def test_contractURI(erc1155, w3, tx_failed): owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] # change contract URI and restore. assert erc1155.contractURI() == CONTRACT_METADATA_URI - assert_tx_failed( - lambda: erc1155.setContractURI(NEW_CONTRACT_METADATA_URI, transact={"from": a1}) - ) + with tx_failed(): + erc1155.setContractURI(NEW_CONTRACT_METADATA_URI, transact={"from": a1}) erc1155.setContractURI(NEW_CONTRACT_METADATA_URI, transact={"from": owner}) assert erc1155.contractURI() == NEW_CONTRACT_METADATA_URI assert erc1155.contractURI() != CONTRACT_METADATA_URI @@ -150,10 +159,11 @@ def test_contractURI(erc1155, w3, assert_tx_failed): assert erc1155.contractURI() != NEW_CONTRACT_METADATA_URI assert erc1155.contractURI() == CONTRACT_METADATA_URI - assert_tx_failed(lambda: erc1155.setContractURI(CONTRACT_METADATA_URI)) + with tx_failed(): + erc1155.setContractURI(CONTRACT_METADATA_URI) -def test_URI(erc1155, w3, assert_tx_failed): +def test_URI(erc1155, w3, tx_failed): owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] # change contract URI and restore. assert erc1155.uri(0) == CONTRACT_URI @@ -164,7 +174,8 @@ def test_URI(erc1155, w3, assert_tx_failed): assert erc1155.uri(0) != NEW_CONTRACT_URI assert erc1155.uri(0) == CONTRACT_URI - assert_tx_failed(lambda: erc1155.setURI(CONTRACT_URI)) + with tx_failed(): + erc1155.setURI(CONTRACT_URI) # set contract to dynamic URI erc1155.toggleDynUri(True, transact={"from": owner}) @@ -172,49 +183,41 @@ def test_URI(erc1155, w3, assert_tx_failed): assert erc1155.uri(0) == CONTRACT_DYNURI + str(0) + ".json" -def test_safeTransferFrom_balanceOf_single(erc1155, w3, assert_tx_failed): +def test_safeTransferFrom_balanceOf_single(erc1155, w3, tx_failed): owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] assert erc1155.balanceOf(a1, 24) == 1 # transfer by non-owner - assert_tx_failed( - lambda: erc1155.safeTransferFrom(a1, a2, 24, 1, DUMMY_BYTES32_DATA, transact={"from": a2}) - ) + with tx_failed(): + erc1155.safeTransferFrom(a1, a2, 24, 1, DUMMY_BYTES32_DATA, transact={"from": a2}) # transfer to zero address - assert_tx_failed( - lambda: erc1155.safeTransferFrom( - a1, ZERO_ADDRESS, 24, 1, DUMMY_BYTES32_DATA, transact={"from": a1} - ) - ) + with tx_failed(): + erc1155.safeTransferFrom(a1, ZERO_ADDRESS, 24, 1, DUMMY_BYTES32_DATA, transact={"from": a1}) # transfer to self - assert_tx_failed( - lambda: erc1155.safeTransferFrom(a1, a1, 24, 1, DUMMY_BYTES32_DATA, transact={"from": a1}) - ) + with tx_failed(): + erc1155.safeTransferFrom(a1, a1, 24, 1, DUMMY_BYTES32_DATA, transact={"from": a1}) # transfer more than owned - assert_tx_failed( - lambda: erc1155.safeTransferFrom(a1, a2, 24, 500, DUMMY_BYTES32_DATA, transact={"from": a1}) - ) + with tx_failed(): + erc1155.safeTransferFrom(a1, a2, 24, 500, DUMMY_BYTES32_DATA, transact={"from": a1}) # transfer item not owned / not existing - assert_tx_failed( - lambda: erc1155.safeTransferFrom(a1, a2, 500, 1, DUMMY_BYTES32_DATA, transact={"from": a1}) - ) + with tx_failed(): + erc1155.safeTransferFrom(a1, a2, 500, 1, DUMMY_BYTES32_DATA, transact={"from": a1}) erc1155.safeTransferFrom(a1, a2, 21, 1, DUMMY_BYTES32_DATA, transact={"from": a1}) assert erc1155.balanceOf(a2, 21) == 1 # try to transfer item again - assert_tx_failed( - lambda: erc1155.safeTransferFrom(a1, a2, 21, 1, DUMMY_BYTES32_DATA, transact={"from": a1}) - ) + with tx_failed(): + erc1155.safeTransferFrom(a1, a2, 21, 1, DUMMY_BYTES32_DATA, transact={"from": a1}) assert erc1155.balanceOf(a1, 21) == 0 # TODO: mint 20 NFTs [1:20] and check the balance for each -def test_mintBatch_balanceOf(erc1155, w3, assert_tx_failed): # test_mint_batch +def test_mintBatch_balanceOf(erc1155, w3, tx_failed): # test_mint_batch owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] # Use the mint three fixture to mint the tokens. # this test checks the balances of this test @@ -222,7 +225,7 @@ def test_mintBatch_balanceOf(erc1155, w3, assert_tx_failed): # test_mint_batch assert erc1155.balanceOf(a1, i) == 1 -def test_safeBatchTransferFrom_balanceOf_batch(erc1155, w3, assert_tx_failed): # test_mint_batch +def test_safeBatchTransferFrom_balanceOf_batch(erc1155, w3, tx_failed): # test_mint_batch owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] # check a1 balances for NFTs 21-24 @@ -231,67 +234,58 @@ def test_safeBatchTransferFrom_balanceOf_batch(erc1155, w3, assert_tx_failed): assert erc1155.balanceOf(a1, 23) == 1 assert erc1155.balanceOf(a1, 23) == 1 - # try to transfer item from non item owner account - assert_tx_failed( - lambda: erc1155.safeBatchTransferFrom( + # try to transfer item from non-item owner account + with tx_failed(): + erc1155.safeBatchTransferFrom( a1, a2, [21, 22, 23], [1, 1, 1], DUMMY_BYTES32_DATA, transact={"from": a2} ) - ) # try to transfer item to zero address - assert_tx_failed( - lambda: erc1155.safeBatchTransferFrom( + with tx_failed(): + erc1155.safeBatchTransferFrom( a1, ZERO_ADDRESS, [21, 22, 23], [1, 1, 1], DUMMY_BYTES32_DATA, transact={"from": a1} ) - ) # try to transfer item to self - assert_tx_failed( - lambda: erc1155.safeBatchTransferFrom( + with tx_failed(): + erc1155.safeBatchTransferFrom( a1, a1, [21, 22, 23], [1, 1, 1], DUMMY_BYTES32_DATA, transact={"from": a1} ) - ) # try to transfer more items than we own - assert_tx_failed( - lambda: erc1155.safeBatchTransferFrom( + with tx_failed(): + erc1155.safeBatchTransferFrom( a1, a2, [21, 22, 23], [1, 125, 1], DUMMY_BYTES32_DATA, transact={"from": a1} ) - ) # mismatched item and amounts - assert_tx_failed( - lambda: erc1155.safeBatchTransferFrom( + with tx_failed(): + erc1155.safeBatchTransferFrom( a1, a2, [21, 22, 23], [1, 1], DUMMY_BYTES32_DATA, transact={"from": a1} ) - ) # try to transfer nonexisting item - assert_tx_failed( - lambda: erc1155.safeBatchTransferFrom( + with tx_failed(): + erc1155.safeBatchTransferFrom( a1, a2, [21, 22, 500], [1, 1, 1], DUMMY_BYTES32_DATA, transact={"from": a1} ) - ) assert erc1155.safeBatchTransferFrom( a1, a2, [21, 22, 23], [1, 1, 1], DUMMY_BYTES32_DATA, transact={"from": a1} ) # try to transfer again, our balances are zero now, should fail - assert_tx_failed( - lambda: erc1155.safeBatchTransferFrom( + with tx_failed(): + erc1155.safeBatchTransferFrom( a1, a2, [21, 22, 23], [1, 1, 1], DUMMY_BYTES32_DATA, transact={"from": a1} ) - ) - assert_tx_failed( - lambda: erc1155.balanceOfBatch([a2, a2, a2], [21, 22], transact={"from": owner}) - == [1, 1, 1] - ) + with tx_failed(): + erc1155.balanceOfBatch([a2, a2, a2], [21, 22], transact={"from": owner}) assert erc1155.balanceOfBatch([a2, a2, a2], [21, 22, 23]) == [1, 1, 1] assert erc1155.balanceOf(a1, 21) == 0 -def test_mint_one_burn_one(erc1155, w3, assert_tx_failed): +def test_mint_one_burn_one(erc1155, w3, tx_failed): owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] # check the balance from an owner and non-owner account @@ -301,20 +295,23 @@ def test_mint_one_burn_one(erc1155, w3, assert_tx_failed): assert erc1155.balanceOf(owner, 25) == 1 # try and burn an item we don't control - assert_tx_failed(lambda: erc1155.burn(25, 1, transact={"from": a3})) + with tx_failed(): + erc1155.burn(25, 1, transact={"from": a3}) # burn an item that contains something we don't own - assert_tx_failed(lambda: erc1155.burn(595, 1, transact={"from": a1})) + with tx_failed(): + erc1155.burn(595, 1, transact={"from": a1}) # burn ah item passing a higher amount than we own - assert_tx_failed(lambda: erc1155.burn(25, 500, transact={"from": a1})) + with tx_failed(): + erc1155.burn(25, 500, transact={"from": a1}) erc1155.burn(25, 1, transact={"from": owner}) assert erc1155.balanceOf(owner, 25) == 0 -def test_mint_batch_burn_batch(erc1155, w3, assert_tx_failed): +def test_mint_batch_burn_batch(erc1155, w3, tx_failed): owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] # mint NFTs 11-20 @@ -322,16 +319,20 @@ def test_mint_batch_burn_batch(erc1155, w3, assert_tx_failed): assert erc1155.balanceOfBatch([a3, a3, a3], [11, 12, 13]) == [1, 1, 1] # try and burn a batch we don't control - assert_tx_failed(lambda: erc1155.burnBatch([11, 12], [1, 1])) + with tx_failed(): + erc1155.burnBatch([11, 12], [1, 1]) # ids and amounts array length not matching - assert_tx_failed(lambda: erc1155.burnBatch([1, 2, 3], [1, 1], transact={"from": a1})) + with tx_failed(): + erc1155.burnBatch([1, 2, 3], [1, 1], transact={"from": a1}) # burn a batch that contains something we don't own - assert_tx_failed(lambda: erc1155.burnBatch([2, 3, 595], [1, 1, 1], transact={"from": a1})) + with tx_failed(): + erc1155.burnBatch([2, 3, 595], [1, 1, 1], transact={"from": a1}) # burn a batch passing a higher amount than we own - assert_tx_failed(lambda: erc1155.burnBatch([1, 2, 3], [1, 500, 1], transact={"from": a1})) + with tx_failed(): + erc1155.burnBatch([1, 2, 3], [1, 500, 1], transact={"from": a1}) # burn existing erc1155.burnBatch([11, 12], [1, 1], transact={"from": a3}) @@ -339,18 +340,21 @@ def test_mint_batch_burn_batch(erc1155, w3, assert_tx_failed): assert erc1155.balanceOfBatch([a3, a3, a3], [11, 12, 13]) == [0, 0, 1] # burn again, should revert - assert_tx_failed(lambda: erc1155.burnBatch([11, 12], [1, 1], transact={"from": a3})) + with tx_failed(): + erc1155.burnBatch([11, 12], [1, 1], transact={"from": a3}) - assert lambda: erc1155.balanceOfBatch([a3, a3, a3], [1, 2, 3]) == [0, 0, 1] + assert erc1155.balanceOfBatch([a3, a3, a3], [1, 2, 3]) == [0, 0, 0] -def test_approval_functions(erc1155, w3, assert_tx_failed): # test_mint_batch +def test_approval_functions(erc1155, w3, tx_failed): # test_mint_batch owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] # self-approval by the owner - assert_tx_failed(lambda: erc1155.setApprovalForAll(a5, a5, True, transact={"from": a5})) + with tx_failed(): + erc1155.setApprovalForAll(a5, a5, True, transact={"from": a5}) # let's approve and operator for somebody else's account - assert_tx_failed(lambda: erc1155.setApprovalForAll(owner, a5, True, transact={"from": a3})) + with tx_failed(): + erc1155.setApprovalForAll(owner, a5, True, transact={"from": a3}) # set approval correctly erc1155.setApprovalForAll(owner, a5, True) @@ -362,7 +366,7 @@ def test_approval_functions(erc1155, w3, assert_tx_failed): # test_mint_batch erc1155.setApprovalForAll(owner, a5, False) -def test_max_batch_size_violation(erc1155, w3, assert_tx_failed): +def test_max_batch_size_violation(erc1155, w3, tx_failed): owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] TOTAL_BAD_BATCH = 200 ids = [] @@ -371,27 +375,29 @@ def test_max_batch_size_violation(erc1155, w3, assert_tx_failed): ids.append(i) amounts.append(1) - assert_tx_failed(lambda: erc1155.mintBatch(a1, ids, amounts, transact={"from": owner})) + with tx_failed(): + erc1155.mintBatch(a1, ids, amounts, transact={"from": owner}) # Transferring back and forth -def test_ownership_functions(erc1155, w3, assert_tx_failed, tester): +def test_ownership_functions(erc1155, w3, tx_failed, tester): owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] print(owner, a1, a2) print("___owner___", erc1155.owner()) # change owner from account 0 to account 1 and back assert erc1155.owner() == owner - assert_tx_failed(lambda: erc1155.transferOwnership(a1, transact={"from": a2})) + with tx_failed(): + erc1155.transferOwnership(a1, transact={"from": a2}) # try to transfer ownership to current owner - assert_tx_failed(lambda: erc1155.transferOwnership(owner)) + with tx_failed(): + erc1155.transferOwnership(owner) # try to transfer ownership to ZERO ADDRESS - assert_tx_failed( - lambda: erc1155.transferOwnership("0x0000000000000000000000000000000000000000") - ) + with tx_failed(): + erc1155.transferOwnership("0x0000000000000000000000000000000000000000") # Transfer ownership to account 1 erc1155.transferOwnership(a1, transact={"from": owner}) @@ -399,11 +405,12 @@ def test_ownership_functions(erc1155, w3, assert_tx_failed, tester): assert erc1155.owner() == a1 -def test_renounce_ownership(erc1155, w3, assert_tx_failed): +def test_renounce_ownership(erc1155, w3, tx_failed): owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] assert erc1155.owner() == owner # try to transfer ownership from non-owner account - assert_tx_failed(lambda: erc1155.renounceOwnership(transact={"from": a2})) + with tx_failed(): + erc1155.renounceOwnership(transact={"from": a2}) erc1155.renounceOwnership(transact={"from": owner}) diff --git a/tests/functional/examples/tokens/test_erc20.py b/tests/functional/examples/tokens/test_erc20.py index cba7769bae..ce507f75f8 100644 --- a/tests/functional/examples/tokens/test_erc20.py +++ b/tests/functional/examples/tokens/test_erc20.py @@ -61,7 +61,7 @@ def test_initial_state(c, w3): assert c.allowance(a2, a3) == 0 -def test_mint_and_burn(c, w3, assert_tx_failed): +def test_mint_and_burn(c, w3, tx_failed): minter, a1, a2 = w3.eth.accounts[0:3] # Test scenario were mints 2 to a1, burns twice (check balance consistency) @@ -70,23 +70,30 @@ def test_mint_and_burn(c, w3, assert_tx_failed): assert c.balanceOf(a1) == 2 c.burn(2, transact={"from": a1}) assert c.balanceOf(a1) == 0 - assert_tx_failed(lambda: c.burn(2, transact={"from": a1})) + with tx_failed(): + c.burn(2, transact={"from": a1}) assert c.balanceOf(a1) == 0 # Test scenario were mintes 0 to a2, burns (check balance consistency, false burn) c.mint(a2, 0, transact={"from": minter}) assert c.balanceOf(a2) == 0 - assert_tx_failed(lambda: c.burn(2, transact={"from": a2})) + with tx_failed(): + c.burn(2, transact={"from": a2}) # Check that a1 cannot burn after depleting their balance - assert_tx_failed(lambda: c.burn(1, transact={"from": a1})) + with tx_failed(): + c.burn(1, transact={"from": a1}) # Check that a1, a2 cannot mint - assert_tx_failed(lambda: c.mint(a1, 1, transact={"from": a1})) - assert_tx_failed(lambda: c.mint(a2, 1, transact={"from": a2})) + with tx_failed(): + c.mint(a1, 1, transact={"from": a1}) + with tx_failed(): + c.mint(a2, 1, transact={"from": a2}) # Check that mint to ZERO_ADDRESS failed - assert_tx_failed(lambda: c.mint(ZERO_ADDRESS, 1, transact={"from": a1})) - assert_tx_failed(lambda: c.mint(ZERO_ADDRESS, 1, transact={"from": minter})) + with tx_failed(): + c.mint(ZERO_ADDRESS, 1, transact={"from": a1}) + with tx_failed(): + c.mint(ZERO_ADDRESS, 1, transact={"from": minter}) -def test_totalSupply(c, w3, assert_tx_failed): +def test_totalSupply(c, w3, tx_failed): # Test total supply initially, after mint, between two burns, and after failed burn minter, a1 = w3.eth.accounts[0:2] assert c.totalSupply() == 0 @@ -96,40 +103,49 @@ def test_totalSupply(c, w3, assert_tx_failed): assert c.totalSupply() == 1 c.burn(1, transact={"from": a1}) assert c.totalSupply() == 0 - assert_tx_failed(lambda: c.burn(1, transact={"from": a1})) + with tx_failed(): + c.burn(1, transact={"from": a1}) assert c.totalSupply() == 0 # Test that 0-valued mint can't affect supply c.mint(a1, 0, transact={"from": minter}) assert c.totalSupply() == 0 -def test_transfer(c, w3, assert_tx_failed): +def test_transfer(c, w3, tx_failed): minter, a1, a2 = w3.eth.accounts[0:3] - assert_tx_failed(lambda: c.burn(1, transact={"from": a2})) + with tx_failed(): + c.burn(1, transact={"from": a2}) c.mint(a1, 2, transact={"from": minter}) c.burn(1, transact={"from": a1}) c.transfer(a2, 1, transact={"from": a1}) - assert_tx_failed(lambda: c.burn(1, transact={"from": a1})) + with tx_failed(): + c.burn(1, transact={"from": a1}) c.burn(1, transact={"from": a2}) - assert_tx_failed(lambda: c.burn(1, transact={"from": a2})) + with tx_failed(): + c.burn(1, transact={"from": a2}) # Ensure transfer fails with insufficient balance - assert_tx_failed(lambda: c.transfer(a1, 1, transact={"from": a2})) + with tx_failed(): + c.transfer(a1, 1, transact={"from": a2}) # Ensure 0-transfer always succeeds c.transfer(a1, 0, transact={"from": a2}) -def test_maxInts(c, w3, assert_tx_failed): +def test_maxInts(c, w3, tx_failed): minter, a1, a2 = w3.eth.accounts[0:3] c.mint(a1, MAX_UINT256, transact={"from": minter}) assert c.balanceOf(a1) == MAX_UINT256 - assert_tx_failed(lambda: c.mint(a1, 1, transact={"from": a1})) - assert_tx_failed(lambda: c.mint(a1, MAX_UINT256, transact={"from": a1})) + with tx_failed(): + c.mint(a1, 1, transact={"from": a1}) + with tx_failed(): + c.mint(a1, MAX_UINT256, transact={"from": a1}) # Check that totalSupply cannot overflow, even when mint to other account - assert_tx_failed(lambda: c.mint(a2, 1, transact={"from": minter})) + with tx_failed(): + c.mint(a2, 1, transact={"from": minter}) # Check that corresponding mint is allowed after burn c.burn(1, transact={"from": a1}) c.mint(a2, 1, transact={"from": minter}) - assert_tx_failed(lambda: c.mint(a2, 1, transact={"from": minter})) + with tx_failed(): + c.mint(a2, 1, transact={"from": minter}) c.transfer(a1, 1, transact={"from": a2}) # Assert that after obtaining max number of tokens, a1 can transfer those but no more assert c.balanceOf(a1) == MAX_UINT256 @@ -150,21 +166,24 @@ def test_maxInts(c, w3, assert_tx_failed): assert c.balanceOf(a1) == 0 -def test_transferFrom_and_Allowance(c, w3, assert_tx_failed): +def test_transferFrom_and_Allowance(c, w3, tx_failed): minter, a1, a2, a3 = w3.eth.accounts[0:4] - assert_tx_failed(lambda: c.burn(1, transact={"from": a2})) + with tx_failed(): + c.burn(1, transact={"from": a2}) c.mint(a1, 1, transact={"from": minter}) c.mint(a2, 1, transact={"from": minter}) c.burn(1, transact={"from": a1}) # This should fail; no allowance or balance (0 always succeeds) - assert_tx_failed(lambda: c.transferFrom(a1, a3, 1, transact={"from": a2})) + with tx_failed(): + c.transferFrom(a1, a3, 1, transact={"from": a2}) c.transferFrom(a1, a3, 0, transact={"from": a2}) # Correct call to approval should update allowance (but not for reverse pair) c.approve(a2, 1, transact={"from": a1}) assert c.allowance(a1, a2) == 1 assert c.allowance(a2, a1) == 0 # transferFrom should succeed when allowed, fail with wrong sender - assert_tx_failed(lambda: c.transferFrom(a1, a3, 1, transact={"from": a3})) + with tx_failed(): + c.transferFrom(a1, a3, 1, transact={"from": a3}) assert c.balanceOf(a2) == 1 c.approve(a1, 1, transact={"from": a2}) c.transferFrom(a2, a3, 1, transact={"from": a1}) @@ -173,7 +192,8 @@ def test_transferFrom_and_Allowance(c, w3, assert_tx_failed): # transferFrom with no funds should fail despite approval c.approve(a1, 1, transact={"from": a2}) assert c.allowance(a2, a1) == 1 - assert_tx_failed(lambda: c.transferFrom(a2, a3, 1, transact={"from": a1})) + with tx_failed(): + c.transferFrom(a2, a3, 1, transact={"from": a1}) # 0-approve should not change balance or allow transferFrom to change balance c.mint(a2, 1, transact={"from": minter}) assert c.allowance(a2, a1) == 1 @@ -181,7 +201,8 @@ def test_transferFrom_and_Allowance(c, w3, assert_tx_failed): assert c.allowance(a2, a1) == 0 c.approve(a1, 0, transact={"from": a2}) assert c.allowance(a2, a1) == 0 - assert_tx_failed(lambda: c.transferFrom(a2, a3, 1, transact={"from": a1})) + with tx_failed(): + c.transferFrom(a2, a3, 1, transact={"from": a1}) # Test that if non-zero approval exists, 0-approval is NOT required to proceed # a non-conformant implementation is described in countermeasures at # https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/edit#heading=h.m9fhqynw2xvt @@ -198,21 +219,24 @@ def test_transferFrom_and_Allowance(c, w3, assert_tx_failed): assert c.allowance(a2, a1) == 5 -def test_burnFrom_and_Allowance(c, w3, assert_tx_failed): +def test_burnFrom_and_Allowance(c, w3, tx_failed): minter, a1, a2, a3 = w3.eth.accounts[0:4] - assert_tx_failed(lambda: c.burn(1, transact={"from": a2})) + with tx_failed(): + c.burn(1, transact={"from": a2}) c.mint(a1, 1, transact={"from": minter}) c.mint(a2, 1, transact={"from": minter}) c.burn(1, transact={"from": a1}) # This should fail; no allowance or balance (0 always succeeds) - assert_tx_failed(lambda: c.burnFrom(a1, 1, transact={"from": a2})) + with tx_failed(): + c.burnFrom(a1, 1, transact={"from": a2}) c.burnFrom(a1, 0, transact={"from": a2}) # Correct call to approval should update allowance (but not for reverse pair) c.approve(a2, 1, transact={"from": a1}) assert c.allowance(a1, a2) == 1 assert c.allowance(a2, a1) == 0 # transferFrom should succeed when allowed, fail with wrong sender - assert_tx_failed(lambda: c.burnFrom(a2, 1, transact={"from": a3})) + with tx_failed(): + c.burnFrom(a2, 1, transact={"from": a3}) assert c.balanceOf(a2) == 1 c.approve(a1, 1, transact={"from": a2}) c.burnFrom(a2, 1, transact={"from": a1}) @@ -221,7 +245,8 @@ def test_burnFrom_and_Allowance(c, w3, assert_tx_failed): # transferFrom with no funds should fail despite approval c.approve(a1, 1, transact={"from": a2}) assert c.allowance(a2, a1) == 1 - assert_tx_failed(lambda: c.burnFrom(a2, 1, transact={"from": a1})) + with tx_failed(): + c.burnFrom(a2, 1, transact={"from": a1}) # 0-approve should not change balance or allow transferFrom to change balance c.mint(a2, 1, transact={"from": minter}) assert c.allowance(a2, a1) == 1 @@ -229,7 +254,8 @@ def test_burnFrom_and_Allowance(c, w3, assert_tx_failed): assert c.allowance(a2, a1) == 0 c.approve(a1, 0, transact={"from": a2}) assert c.allowance(a2, a1) == 0 - assert_tx_failed(lambda: c.burnFrom(a2, 1, transact={"from": a1})) + with tx_failed(): + c.burnFrom(a2, 1, transact={"from": a1}) # Test that if non-zero approval exists, 0-approval is NOT required to proceed # a non-conformant implementation is described in countermeasures at # https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/edit#heading=h.m9fhqynw2xvt @@ -245,7 +271,8 @@ def test_burnFrom_and_Allowance(c, w3, assert_tx_failed): c.approve(a1, 5, transact={"from": a2}) assert c.allowance(a2, a1) == 5 # Check that burnFrom to ZERO_ADDRESS failed - assert_tx_failed(lambda: c.burnFrom(ZERO_ADDRESS, 0, transact={"from": a1})) + with tx_failed(): + c.burnFrom(ZERO_ADDRESS, 0, transact={"from": a1}) def test_raw_logs(c, w3, get_log_args): @@ -307,33 +334,36 @@ def test_raw_logs(c, w3, get_log_args): assert args.value == 0 -def test_bad_transfer(c_bad, w3, assert_tx_failed): +def test_bad_transfer(c_bad, w3, tx_failed): # Ensure transfer fails if it would otherwise overflow balance when totalSupply is corrupted minter, a1, a2 = w3.eth.accounts[0:3] c_bad.mint(a1, MAX_UINT256, transact={"from": minter}) c_bad.mint(a2, 1, transact={"from": minter}) - assert_tx_failed(lambda: c_bad.transfer(a1, 1, transact={"from": a2})) + with tx_failed(): + c_bad.transfer(a1, 1, transact={"from": a2}) c_bad.transfer(a2, MAX_UINT256 - 1, transact={"from": a1}) assert c_bad.balanceOf(a1) == 1 assert c_bad.balanceOf(a2) == MAX_UINT256 -def test_bad_burn(c_bad, w3, assert_tx_failed): +def test_bad_burn(c_bad, w3, tx_failed): # Ensure burn fails if it would otherwise underflow balance when totalSupply is corrupted minter, a1 = w3.eth.accounts[0:2] assert c_bad.balanceOf(a1) == 0 c_bad.mint(a1, 2, transact={"from": minter}) assert c_bad.balanceOf(a1) == 2 - assert_tx_failed(lambda: c_bad.burn(3, transact={"from": a1})) + with tx_failed(): + c_bad.burn(3, transact={"from": a1}) -def test_bad_transferFrom(c_bad, w3, assert_tx_failed): +def test_bad_transferFrom(c_bad, w3, tx_failed): # Ensure transferFrom fails if it would otherwise overflow balance when totalSupply is corrupted minter, a1, a2 = w3.eth.accounts[0:3] c_bad.mint(a1, MAX_UINT256, transact={"from": minter}) c_bad.mint(a2, 1, transact={"from": minter}) c_bad.approve(a1, 1, transact={"from": a2}) - assert_tx_failed(lambda: c_bad.transferFrom(a2, a1, 1, transact={"from": a1})) + with tx_failed(): + c_bad.transferFrom(a2, a1, 1, transact={"from": a1}) c_bad.approve(a2, MAX_UINT256 - 1, transact={"from": a1}) assert c_bad.allowance(a1, a2) == MAX_UINT256 - 1 c_bad.transferFrom(a1, a2, MAX_UINT256 - 1, transact={"from": a2}) diff --git a/tests/functional/examples/tokens/test_erc721.py b/tests/functional/examples/tokens/test_erc721.py index ab3c6368c5..c881149baa 100644 --- a/tests/functional/examples/tokens/test_erc721.py +++ b/tests/functional/examples/tokens/test_erc721.py @@ -40,16 +40,18 @@ def test_erc165(w3, c): assert c.supportsInterface(ERC721_SIG) -def test_balanceOf(c, w3, assert_tx_failed): +def test_balanceOf(c, w3, tx_failed): someone = w3.eth.accounts[1] assert c.balanceOf(someone) == 3 - assert_tx_failed(lambda: c.balanceOf(ZERO_ADDRESS)) + with tx_failed(): + c.balanceOf(ZERO_ADDRESS) -def test_ownerOf(c, w3, assert_tx_failed): +def test_ownerOf(c, w3, tx_failed): someone = w3.eth.accounts[1] assert c.ownerOf(SOMEONE_TOKEN_IDS[0]) == someone - assert_tx_failed(lambda: c.ownerOf(INVALID_TOKEN_ID)) + with tx_failed(): + c.ownerOf(INVALID_TOKEN_ID) def test_getApproved(c, w3): @@ -72,32 +74,24 @@ def test_isApprovedForAll(c, w3): assert c.isApprovedForAll(someone, operator) == 1 -def test_transferFrom_by_owner(c, w3, assert_tx_failed, get_logs): +def test_transferFrom_by_owner(c, w3, tx_failed, get_logs): someone, operator = w3.eth.accounts[1:3] # transfer from zero address - assert_tx_failed( - lambda: c.transferFrom( - ZERO_ADDRESS, operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone} - ) - ) + with tx_failed(): + c.transferFrom(ZERO_ADDRESS, operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) # transfer to zero address - assert_tx_failed( - lambda: c.transferFrom( - someone, ZERO_ADDRESS, SOMEONE_TOKEN_IDS[0], transact={"from": someone} - ) - ) + with tx_failed(): + c.transferFrom(someone, ZERO_ADDRESS, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) # transfer token without ownership - assert_tx_failed( - lambda: c.transferFrom(someone, operator, OPERATOR_TOKEN_ID, transact={"from": someone}) - ) + with tx_failed(): + c.transferFrom(someone, operator, OPERATOR_TOKEN_ID, transact={"from": someone}) # transfer invalid token - assert_tx_failed( - lambda: c.transferFrom(someone, operator, INVALID_TOKEN_ID, transact={"from": someone}) - ) + with tx_failed(): + c.transferFrom(someone, operator, INVALID_TOKEN_ID, transact={"from": someone}) # transfer by owner tx_hash = c.transferFrom(someone, operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) @@ -152,32 +146,24 @@ def test_transferFrom_by_operator(c, w3, get_logs): assert c.balanceOf(operator) == 2 -def test_safeTransferFrom_by_owner(c, w3, assert_tx_failed, get_logs): +def test_safeTransferFrom_by_owner(c, w3, tx_failed, get_logs): someone, operator = w3.eth.accounts[1:3] # transfer from zero address - assert_tx_failed( - lambda: c.safeTransferFrom( - ZERO_ADDRESS, operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone} - ) - ) + with tx_failed(): + c.safeTransferFrom(ZERO_ADDRESS, operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) # transfer to zero address - assert_tx_failed( - lambda: c.safeTransferFrom( - someone, ZERO_ADDRESS, SOMEONE_TOKEN_IDS[0], transact={"from": someone} - ) - ) + with tx_failed(): + c.safeTransferFrom(someone, ZERO_ADDRESS, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) # transfer token without ownership - assert_tx_failed( - lambda: c.safeTransferFrom(someone, operator, OPERATOR_TOKEN_ID, transact={"from": someone}) - ) + with tx_failed(): + c.safeTransferFrom(someone, operator, OPERATOR_TOKEN_ID, transact={"from": someone}) # transfer invalid token - assert_tx_failed( - lambda: c.safeTransferFrom(someone, operator, INVALID_TOKEN_ID, transact={"from": someone}) - ) + with tx_failed(): + c.safeTransferFrom(someone, operator, INVALID_TOKEN_ID, transact={"from": someone}) # transfer by owner tx_hash = c.safeTransferFrom( @@ -238,15 +224,12 @@ def test_safeTransferFrom_by_operator(c, w3, get_logs): assert c.balanceOf(operator) == 2 -def test_safeTransferFrom_to_contract(c, w3, assert_tx_failed, get_logs, get_contract): +def test_safeTransferFrom_to_contract(c, w3, tx_failed, get_logs, get_contract): someone = w3.eth.accounts[1] # Can't transfer to a contract that doesn't implement the receiver code - assert_tx_failed( - lambda: c.safeTransferFrom( - someone, c.address, SOMEONE_TOKEN_IDS[0], transact={"from": someone} - ) - ) # noqa: E501 + with tx_failed(): + c.safeTransferFrom(someone, c.address, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) # Only to an address that implements that function receiver = get_contract( @@ -277,17 +260,20 @@ def onERC721Received( assert c.balanceOf(receiver.address) == 1 -def test_approve(c, w3, assert_tx_failed, get_logs): +def test_approve(c, w3, tx_failed, get_logs): someone, operator = w3.eth.accounts[1:3] # approve myself - assert_tx_failed(lambda: c.approve(someone, SOMEONE_TOKEN_IDS[0], transact={"from": someone})) + with tx_failed(): + c.approve(someone, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) # approve token without ownership - assert_tx_failed(lambda: c.approve(operator, OPERATOR_TOKEN_ID, transact={"from": someone})) + with tx_failed(): + c.approve(operator, OPERATOR_TOKEN_ID, transact={"from": someone}) # approve invalid token - assert_tx_failed(lambda: c.approve(operator, INVALID_TOKEN_ID, transact={"from": someone})) + with tx_failed(): + c.approve(operator, INVALID_TOKEN_ID, transact={"from": someone}) tx_hash = c.approve(operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) logs = get_logs(tx_hash, c, "Approval") @@ -299,12 +285,13 @@ def test_approve(c, w3, assert_tx_failed, get_logs): assert args.tokenId == SOMEONE_TOKEN_IDS[0] -def test_setApprovalForAll(c, w3, assert_tx_failed, get_logs): +def test_setApprovalForAll(c, w3, tx_failed, get_logs): someone, operator = w3.eth.accounts[1:3] approved = True # setApprovalForAll myself - assert_tx_failed(lambda: c.setApprovalForAll(someone, approved, transact={"from": someone})) + with tx_failed(): + c.setApprovalForAll(someone, approved, transact={"from": someone}) tx_hash = c.setApprovalForAll(operator, approved, transact={"from": someone}) logs = get_logs(tx_hash, c, "ApprovalForAll") @@ -316,14 +303,16 @@ def test_setApprovalForAll(c, w3, assert_tx_failed, get_logs): assert args.approved == approved -def test_mint(c, w3, assert_tx_failed, get_logs): +def test_mint(c, w3, tx_failed, get_logs): minter, someone = w3.eth.accounts[:2] # mint by non-minter - assert_tx_failed(lambda: c.mint(someone, SOMEONE_TOKEN_IDS[0], transact={"from": someone})) + with tx_failed(): + c.mint(someone, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) # mint to zero address - assert_tx_failed(lambda: c.mint(ZERO_ADDRESS, SOMEONE_TOKEN_IDS[0], transact={"from": minter})) + with tx_failed(): + c.mint(ZERO_ADDRESS, SOMEONE_TOKEN_IDS[0], transact={"from": minter}) # mint by minter tx_hash = c.mint(someone, NEW_TOKEN_ID, transact={"from": minter}) @@ -338,11 +327,12 @@ def test_mint(c, w3, assert_tx_failed, get_logs): assert c.balanceOf(someone) == 4 -def test_burn(c, w3, assert_tx_failed, get_logs): +def test_burn(c, w3, tx_failed, get_logs): someone, operator = w3.eth.accounts[1:3] # burn token without ownership - assert_tx_failed(lambda: c.burn(SOMEONE_TOKEN_IDS[0], transact={"from": operator})) + with tx_failed(): + c.burn(SOMEONE_TOKEN_IDS[0], transact={"from": operator}) # burn token by owner tx_hash = c.burn(SOMEONE_TOKEN_IDS[0], transact={"from": someone}) @@ -353,5 +343,6 @@ def test_burn(c, w3, assert_tx_failed, get_logs): assert args.sender == someone assert args.receiver == ZERO_ADDRESS assert args.tokenId == SOMEONE_TOKEN_IDS[0] - assert_tx_failed(lambda: c.ownerOf(SOMEONE_TOKEN_IDS[0])) + with tx_failed(): + c.ownerOf(SOMEONE_TOKEN_IDS[0]) assert c.balanceOf(someone) == 2 diff --git a/tests/functional/examples/voting/test_ballot.py b/tests/functional/examples/voting/test_ballot.py index 4207fe6e4e..9c3a09fc83 100644 --- a/tests/functional/examples/voting/test_ballot.py +++ b/tests/functional/examples/voting/test_ballot.py @@ -33,7 +33,7 @@ def test_initial_state(w3, c): assert c.voters(z0)[0] == 0 # Voter.weight -def test_give_the_right_to_vote(w3, c, assert_tx_failed): +def test_give_the_right_to_vote(w3, c, tx_failed): a0, a1, a2, a3, a4, a5 = w3.eth.accounts[:6] c.giveRightToVote(a1, transact={}) # Check voter given right has weight of 1 @@ -56,7 +56,8 @@ def test_give_the_right_to_vote(w3, c, assert_tx_failed): # Check voter_acount is now 6 assert c.voterCount() == 6 # Check chairperson cannot give the right to vote twice to the same voter - assert_tx_failed(lambda: c.giveRightToVote(a5, transact={})) + with tx_failed(): + c.giveRightToVote(a5, transact={}) # Check voters weight didn't change assert c.voters(a5)[0] == 1 # Voter.weight @@ -127,7 +128,7 @@ def test_forward_weight(w3, c): assert c.voters(a9)[0] == 10 # Voter.weight -def test_block_short_cycle(w3, c, assert_tx_failed): +def test_block_short_cycle(w3, c, tx_failed): a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = w3.eth.accounts[:10] c.giveRightToVote(a0, transact={}) c.giveRightToVote(a1, transact={}) @@ -141,7 +142,8 @@ def test_block_short_cycle(w3, c, assert_tx_failed): c.delegate(a3, transact={"from": a2}) c.delegate(a4, transact={"from": a3}) # would create a length 5 cycle: - assert_tx_failed(lambda: c.delegate(a0, transact={"from": a4})) + with tx_failed(): + c.delegate(a0, transact={"from": a4}) c.delegate(a5, transact={"from": a4}) # can't detect length 6 cycle, so this works: @@ -150,7 +152,7 @@ def test_block_short_cycle(w3, c, assert_tx_failed): # but this is something the frontend should prevent for user friendliness -def test_delegate(w3, c, assert_tx_failed): +def test_delegate(w3, c, tx_failed): a0, a1, a2, a3, a4, a5, a6 = w3.eth.accounts[:7] c.giveRightToVote(a0, transact={}) c.giveRightToVote(a1, transact={}) @@ -167,9 +169,11 @@ def test_delegate(w3, c, assert_tx_failed): # Delegate's weight is 2 assert c.voters(a0)[0] == 2 # Voter.weight # Voter cannot delegate twice - assert_tx_failed(lambda: c.delegate(a2, transact={"from": a1})) + with tx_failed(): + c.delegate(a2, transact={"from": a1}) # Voter cannot delegate to themselves - assert_tx_failed(lambda: c.delegate(a2, transact={"from": a2})) + with tx_failed(): + c.delegate(a2, transact={"from": a2}) # Voter CAN delegate to someone who hasn't been granted right to vote # Exercise: prevent that c.delegate(a6, transact={"from": a2}) @@ -180,7 +184,7 @@ def test_delegate(w3, c, assert_tx_failed): assert c.voters(a0)[0] == 3 # Voter.weight -def test_vote(w3, c, assert_tx_failed): +def test_vote(w3, c, tx_failed): a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = w3.eth.accounts[:10] c.giveRightToVote(a0, transact={}) c.giveRightToVote(a1, transact={}) @@ -197,9 +201,11 @@ def test_vote(w3, c, assert_tx_failed): # Vote count changes based on voters weight assert c.proposals(0)[1] == 3 # Proposal.voteCount # Voter cannot vote twice - assert_tx_failed(lambda: c.vote(0)) + with tx_failed(): + c.vote(0) # Voter cannot vote if they've delegated - assert_tx_failed(lambda: c.vote(0, transact={"from": a1})) + with tx_failed(): + c.vote(0, transact={"from": a1}) # Several voters can vote c.vote(1, transact={"from": a4}) c.vote(1, transact={"from": a2}) @@ -207,7 +213,8 @@ def test_vote(w3, c, assert_tx_failed): c.vote(1, transact={"from": a6}) assert c.proposals(1)[1] == 4 # Proposal.voteCount # Can't vote on a non-proposal - assert_tx_failed(lambda: c.vote(2, transact={"from": a7})) + with tx_failed(): + c.vote(2, transact={"from": a7}) def test_winning_proposal(w3, c): diff --git a/tests/functional/examples/wallet/test_wallet.py b/tests/functional/examples/wallet/test_wallet.py index 71f1e5f331..b9db5acee3 100644 --- a/tests/functional/examples/wallet/test_wallet.py +++ b/tests/functional/examples/wallet/test_wallet.py @@ -29,7 +29,7 @@ def _sign(seq, to, value, data, key): return _sign -def test_approve(w3, c, tester, assert_tx_failed, sign): +def test_approve(w3, c, tester, tx_failed, sign): a0, a1, a2, a3, a4, a5, a6 = w3.eth.accounts[:7] k0, k1, k2, k3, k4, k5, k6, k7 = tester.backend.account_keys[:8] @@ -45,24 +45,20 @@ def pack_and_sign(seq, *args): c.approve(0, "0x" + to.hex(), value, data, sigs, transact={"value": value, "from": a1}) # Approve fails if only 2 signatures are given sigs = pack_and_sign(1, k1, 0, k3, 0, 0) - assert_tx_failed( - lambda: c.approve(1, to_address, value, data, sigs, transact={"value": value, "from": a1}) - ) # noqa: E501 + with tx_failed(): + c.approve(1, to_address, value, data, sigs, transact={"value": value, "from": a1}) # Approve fails if an invalid signature is given sigs = pack_and_sign(1, k1, 0, k7, 0, k5) - assert_tx_failed( - lambda: c.approve(1, to_address, value, data, sigs, transact={"value": value, "from": a1}) - ) # noqa: E501 + with tx_failed(): + c.approve(1, to_address, value, data, sigs, transact={"value": value, "from": a1}) # Approve fails if transaction number is incorrect (the first argument should be 1) sigs = pack_and_sign(0, k1, 0, k3, 0, k5) - assert_tx_failed( - lambda: c.approve(0, to_address, value, data, sigs, transact={"value": value, "from": a1}) - ) # noqa: E501 + with tx_failed(): + c.approve(0, to_address, value, data, sigs, transact={"value": value, "from": a1}) # Approve fails if not enough value is sent sigs = pack_and_sign(1, k1, 0, k3, 0, k5) - assert_tx_failed( - lambda: c.approve(1, to_address, value, data, sigs, transact={"value": 0, "from": a1}) - ) # noqa: E501 + with tx_failed(): + c.approve(1, to_address, value, data, sigs, transact={"value": 0, "from": a1}) sigs = pack_and_sign(1, k1, 0, k3, 0, k5) # this call should succeed diff --git a/tests/unit/ast/nodes/test_evaluate_binop_decimal.py b/tests/unit/ast/nodes/test_evaluate_binop_decimal.py index 5c9956caba..44b82e321d 100644 --- a/tests/unit/ast/nodes/test_evaluate_binop_decimal.py +++ b/tests/unit/ast/nodes/test_evaluate_binop_decimal.py @@ -20,7 +20,7 @@ @example(left=Decimal("0.9999999999"), right=Decimal("0.9999999999")) @example(left=Decimal("0.0000000001"), right=Decimal("0.0000000001")) @pytest.mark.parametrize("op", "+-*/%") -def test_binop_decimal(get_contract, assert_tx_failed, op, left, right): +def test_binop_decimal(get_contract, tx_failed, op, left, right): source = f""" @external def foo(a: decimal, b: decimal) -> decimal: @@ -39,7 +39,8 @@ def foo(a: decimal, b: decimal) -> decimal: if is_valid: assert contract.foo(left, right) == new_node.value else: - assert_tx_failed(lambda: contract.foo(left, right)) + with tx_failed(): + contract.foo(left, right) def test_binop_pow(): @@ -57,7 +58,7 @@ def test_binop_pow(): values=st.lists(st_decimals, min_size=2, max_size=10), ops=st.lists(st.sampled_from("+-*/%"), min_size=11, max_size=11), ) -def test_nested(get_contract, assert_tx_failed, values, ops): +def test_nested(get_contract, tx_failed, values, ops): variables = "abcdefghij" input_value = ",".join(f"{i}: decimal" for i in variables[: len(values)]) return_value = " ".join(f"{a} {b}" for a, b in zip(variables[: len(values)], ops)) @@ -83,4 +84,5 @@ def foo({input_value}) -> decimal: if is_valid: assert contract.foo(*values) == expected else: - assert_tx_failed(lambda: contract.foo(*values)) + with tx_failed(): + contract.foo(*values) diff --git a/tests/unit/ast/nodes/test_evaluate_binop_int.py b/tests/unit/ast/nodes/test_evaluate_binop_int.py index 80c9381c0f..405d557f7d 100644 --- a/tests/unit/ast/nodes/test_evaluate_binop_int.py +++ b/tests/unit/ast/nodes/test_evaluate_binop_int.py @@ -16,7 +16,7 @@ @example(left=-1, right=1) @example(left=-1, right=-1) @pytest.mark.parametrize("op", "+-*/%") -def test_binop_int128(get_contract, assert_tx_failed, op, left, right): +def test_binop_int128(get_contract, tx_failed, op, left, right): source = f""" @external def foo(a: int128, b: int128) -> int128: @@ -35,7 +35,8 @@ def foo(a: int128, b: int128) -> int128: if is_valid: assert contract.foo(left, right) == new_node.value else: - assert_tx_failed(lambda: contract.foo(left, right)) + with tx_failed(): + contract.foo(left, right) st_uint64 = st.integers(min_value=0, max_value=2**64) @@ -45,7 +46,7 @@ def foo(a: int128, b: int128) -> int128: @settings(max_examples=50) @given(left=st_uint64, right=st_uint64) @pytest.mark.parametrize("op", "+-*/%") -def test_binop_uint256(get_contract, assert_tx_failed, op, left, right): +def test_binop_uint256(get_contract, tx_failed, op, left, right): source = f""" @external def foo(a: uint256, b: uint256) -> uint256: @@ -64,7 +65,8 @@ def foo(a: uint256, b: uint256) -> uint256: if is_valid: assert contract.foo(left, right) == new_node.value else: - assert_tx_failed(lambda: contract.foo(left, right)) + with tx_failed(): + contract.foo(left, right) @pytest.mark.xfail(reason="need to implement safe exponentiation logic") @@ -94,7 +96,7 @@ def foo(a: uint256, b: uint256) -> uint256: values=st.lists(st.integers(min_value=-256, max_value=256), min_size=2, max_size=10), ops=st.lists(st.sampled_from("+-*/%"), min_size=11, max_size=11), ) -def test_binop_nested(get_contract, assert_tx_failed, values, ops): +def test_binop_nested(get_contract, tx_failed, values, ops): variables = "abcdefghij" input_value = ",".join(f"{i}: int128" for i in variables[: len(values)]) return_value = " ".join(f"{a} {b}" for a, b in zip(variables[: len(values)], ops)) @@ -122,4 +124,5 @@ def foo({input_value}) -> int128: if is_valid: assert contract.foo(*values) == expected else: - assert_tx_failed(lambda: contract.foo(*values)) + with tx_failed(): + contract.foo(*values)