diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 06560cd3cf..33bda5ebd3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -71,6 +71,7 @@ jobs: evm-version: [shanghai] experimental-codegen: [false] memorymock: [false] + evm-backend: [revm] # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#expanding-or-adding-matrix-configurations include: @@ -79,6 +80,7 @@ jobs: debug: false opt-mode: gas evm-version: london + - python-version: ["3.11", "311"] debug: false opt-mode: gas @@ -95,6 +97,19 @@ jobs: opt-mode: gas evm-version: cancun + # py-evm rules + - python-version: ["3.11", "311"] + debug: false + opt-mode: codesize + evm-version: london + evm-backend: py-evm + + - python-version: ["3.11", "311"] + debug: false + opt-mode: gas + evm-version: cancun + evm-backend: py-evm + # test experimental pipeline - python-version: ["3.11", "311"] opt-mode: gas @@ -123,8 +138,13 @@ jobs: debug: false evm-version: shanghai - - name: py${{ matrix.python-version[1] }}-opt-${{ matrix.opt-mode }}${{ matrix.debug && '-debug' || '' }}${{ matrix.memorymock && '-memorymock' || '' }}${{ matrix.experimental-codegen && '-experimental' || '' }}-${{ matrix.evm-version }} + name: "py${{ matrix.python-version[1] }}\ + -opt-${{ matrix.opt-mode }}\ + ${{ matrix.debug && '-debug' || '' }}\ + ${{ matrix.memorymock && '-memorymock' || '' }}\ + ${{ matrix.experimental-codegen && '-experimental' || '' }}\ + -${{ matrix.evm-version }}\ + ${{ matrix.evm-backend && format('-{0}', matrix.evm-backend) || '' }}" steps: - uses: actions/checkout@v4 @@ -150,6 +170,7 @@ jobs: -m "not fuzzing" \ --optimize ${{ matrix.opt-mode }} \ --evm-version ${{ matrix.evm-version }} \ + ${{ matrix.evm-backend && format('--evm-backend {0}', matrix.evm-backend) || '' }} \ ${{ matrix.debug && '--enable-compiler-debug-mode' || '' }} \ ${{ matrix.memorymock && '--memorymock' || '' }} \ ${{ matrix.experimental-codegen && '--experimental-codegen' || '' }} \ diff --git a/setup.py b/setup.py index 6b02790ad0..6e48129cba 100644 --- a/setup.py +++ b/setup.py @@ -13,15 +13,15 @@ "pytest-instafail>=0.4,<1.0", "pytest-xdist>=3.0,<3.4", "pytest-split>=0.7.0,<1.0", - "eth-tester[py-evm]>=0.11.0b1,<0.12", "eth_abi>=5.0.0,<6.0.0", "py-evm>=0.10.1b1,<0.11", - "web3>=7.0.0b4,<8.0", "lark==1.1.9", "hypothesis[lark]>=6.0,<7.0", "eth-stdlib==0.2.7", + "eth-account==0.12.2", "setuptools", "hexbytes>=1.2", + "pyrevm>=0.3.2", ], "lint": [ "black==23.12.0", diff --git a/tests/conftest.py b/tests/conftest.py index 824fa795ab..2b645fc50d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,37 +1,24 @@ -import json -import logging from contextlib import contextmanager -from functools import wraps +from random import Random +from typing import Generator import hypothesis import pytest -import web3.exceptions -from eth_tester import EthereumTester, PyEVMBackend -from eth_tester.exceptions import TransactionFailed -from eth_utils import setup_DEBUG2_logging -from eth_utils.toolz import compose +from eth_keys.datatypes import PrivateKey from hexbytes import HexBytes -from web3 import Web3 -from web3.contract import Contract -from web3.providers.eth_tester import EthereumTesterProvider -import vyper.compiler.settings as compiler_settings -import vyper.evm.opcodes as evm +import vyper.evm.opcodes as evm_opcodes +from tests.evm_backends.base_env import BaseEnv, EvmError +from tests.evm_backends.pyevm_env import PyEvmEnv +from tests.evm_backends.revm_env import RevmEnv from tests.utils import working_directory from vyper import compiler -from vyper.ast.grammar import parse_vyper_source from vyper.codegen.ir_node import IRnode from vyper.compiler.input_bundle import FilesystemInputBundle, InputBundle -from vyper.compiler.settings import ( - OptimizationLevel, - Settings, - get_global_settings, - set_global_settings, -) -from vyper.evm.opcodes import EVM_VERSIONS, version_check +from vyper.compiler.settings import OptimizationLevel, Settings, set_global_settings from vyper.exceptions import EvmVersionException from vyper.ir import compile_ir, optimizer -from vyper.utils import ERC5202_PREFIX, keccak256 +from vyper.utils import keccak256 # Import the base fixtures pytest_plugins = ["tests.fixtures.memorymock"] @@ -46,19 +33,6 @@ hypothesis.settings.load_profile("ci") -def set_evm_verbose_logging(): - logger = logging.getLogger("eth.vm.computation.BaseComputation") - setup_DEBUG2_logging() - logger.setLevel("DEBUG2") - - -# Useful options to comment out whilst working: -# set_evm_verbose_logging() -# -# from vdb import vdb -# vdb.set_evm_opcode_debugger() - - def pytest_addoption(parser): parser.addoption( "--optimize", @@ -68,14 +42,19 @@ def pytest_addoption(parser): ) parser.addoption("--enable-compiler-debug-mode", action="store_true") parser.addoption("--experimental-codegen", action="store_true") + parser.addoption("--tracing", action="store_true") parser.addoption( "--evm-version", - choices=list(EVM_VERSIONS.keys()), + choices=list(evm_opcodes.EVM_VERSIONS.keys()), default="shanghai", help="set evm version", ) + parser.addoption( + "--evm-backend", choices=["py-evm", "revm"], default="revm", help="set evm backend" + ) + @pytest.fixture(scope="module") def output_formats(): @@ -107,29 +86,6 @@ def experimental_codegen(pytestconfig): return ret -@pytest.fixture(scope="session") -def evm_version(pytestconfig): - # note: we configure the evm version that we emit code for, - # but eth-tester is only configured with the latest mainnet - # version. luckily, evms are backwards compatible. - evm_version_str = pytestconfig.getoption("evm_version") - assert isinstance(evm_version_str, str) - return evm_version_str - - -@pytest.fixture(scope="session", autouse=True) -def global_settings(evm_version, experimental_codegen, optimize, debug): - evm.DEFAULT_EVM_VERSION = evm_version - compiler_settings.DEFAULT_ENABLE_DECIMALS = True - settings = Settings( - optimize=optimize, - evm_version=evm_version, - experimental_codegen=experimental_codegen, - debug=debug, - ) - set_global_settings(settings) - - @pytest.fixture(autouse=True) def check_venom_xfail(request, experimental_codegen): if not experimental_codegen: @@ -153,6 +109,24 @@ def _xfail(*args, **kwargs): return _xfail +@pytest.fixture(scope="session") +def evm_version(pytestconfig): + # note: configure the evm version that we emit code for. + # The env will read this fixture and apply the evm version there. + return pytestconfig.getoption("evm_version") + + +@pytest.fixture(scope="session") +def evm_backend(pytestconfig): + backend_str = pytestconfig.getoption("evm_backend") + return {"py-evm": PyEvmEnv, "revm": RevmEnv}[backend_str] + + +@pytest.fixture(scope="session") +def tracing(pytestconfig): + return pytestconfig.getoption("tracing") + + @pytest.fixture def chdir_tmp_path(tmp_path): # this is useful for when you want imports to have relpaths @@ -200,331 +174,91 @@ def dummy_input_bundle(): return InputBundle([]) -# TODO: remove me, this is just string.encode("utf-8").ljust() -# only used in test_logging.py. -@pytest.fixture -def bytes_helper(): - def bytes_helper(str, length): - return bytes(str, "utf-8") + bytearray(length - len(str)) - - return bytes_helper - - -def _none_addr(datatype, data): - if datatype == "address" and int(data, base=16) == 0: - return (datatype, None) - else: - return (datatype, data) - - -CONCISE_NORMALIZERS = (_none_addr,) - - @pytest.fixture(scope="module") -def tester(): +def gas_limit(): # set absurdly high gas limit so that london basefee never adjusts - # (note: 2**63 - 1 is max that evm allows) - custom_genesis = PyEVMBackend._generate_genesis_params(overrides={"gas_limit": 10**10}) - custom_genesis["base_fee_per_gas"] = 0 - backend = PyEVMBackend(genesis_parameters=custom_genesis) - return EthereumTester(backend=backend) - - -def zero_gas_price_strategy(web3, transaction_params=None): - return 0 # zero gas price makes testing simpler. + # (note: 2**63 - 1 is max that py-evm allows) + return 10**10 @pytest.fixture(scope="module") -def w3(tester): - w3 = Web3(EthereumTesterProvider(tester)) - w3.eth.set_gas_price_strategy(zero_gas_price_strategy) - return w3 - - -def get_compiler_gas_estimate(code, func): - sigs = compiler.phases.CompilerData(code).function_signatures - if func: - return compiler.utils.build_gas_estimates(sigs)[func] + 22000 - else: - return sum(compiler.utils.build_gas_estimates(sigs).values()) + 22000 - - -def check_gas_on_chain(w3, tester, code, func=None, res=None): - gas_estimate = get_compiler_gas_estimate(code, func) - gas_actual = tester.get_block_by_number("latest")["gas_used"] - # Computed upper bound on the gas consumption should - # be greater than or equal to the amount of gas used - if gas_estimate < gas_actual: - raise Exception(f"Gas upper bound fail: bound {gas_estimate} actual {gas_actual}") - - print(f"Function name: {func} - Gas estimate {gas_estimate}, Actual: {gas_actual}") - - -def gas_estimation_decorator(w3, tester, fn, source_code, func): - def decorator(*args, **kwargs): - @wraps(fn) - def decorated_function(*args, **kwargs): - result = fn(*args, **kwargs) - if "transact" in kwargs: - check_gas_on_chain(w3, tester, source_code, func, res=result) - return result - - return decorated_function(*args, **kwargs) +def account_keys(): + random = Random(b"vyper") + return [PrivateKey(random.randbytes(32)) for _ in range(10)] - return decorator - -def set_decorator_to_contract_function(w3, tester, contract, source_code, func): - func_definition = getattr(contract, func) - func_with_decorator = gas_estimation_decorator(w3, tester, func_definition, source_code, func) - setattr(contract, func, func_with_decorator) - - -class VyperMethod: - ALLOWED_MODIFIERS = {"call", "estimateGas", "transact", "buildTransaction"} - - def __init__(self, function, normalizers=None): - self._function = function - self._function._return_data_normalizers = normalizers - - def __call__(self, *args, **kwargs): - return self.__prepared_function(*args, **kwargs) - - def __prepared_function(self, *args, **kwargs): - if not kwargs: - modifier, modifier_dict = "call", {} - fn_abi = [ - x - for x in self._function.contract_abi - if x.get("name") == self._function.function_identifier - ].pop() - # To make tests faster just supply some high gas value. - modifier_dict.update({"gas": fn_abi.get("gas", 0) + 500000}) - elif len(kwargs) == 1: - modifier, modifier_dict = kwargs.popitem() - if modifier not in self.ALLOWED_MODIFIERS: - raise TypeError(f"The only allowed keyword arguments are: {self.ALLOWED_MODIFIERS}") - else: - raise TypeError(f"Use up to one keyword argument, one of: {self.ALLOWED_MODIFIERS}") - return getattr(self._function(*args), modifier)(modifier_dict) - - -class VyperContract: - """ - An alternative Contract Factory which invokes all methods as `call()`, - unless you add a keyword argument. The keyword argument assigns the prep method. - This call - > contract.withdraw(amount, transact={'from': eth.accounts[1], 'gas': 100000, ...}) - is equivalent to this call in the classic contract: - > contract.functions.withdraw(amount).transact({'from': eth.accounts[1], 'gas': 100000, ...}) - """ - - def __init__(self, classic_contract, method_class=VyperMethod): - classic_contract._return_data_normalizers += CONCISE_NORMALIZERS - self._classic_contract = classic_contract - self.address = self._classic_contract.address - protected_fn_names = [fn for fn in dir(self) if not fn.endswith("__")] - - try: - fn_names = [fn["name"] for fn in self._classic_contract.functions._functions] - except web3.exceptions.NoABIFunctionsFound: - fn_names = [] - - for fn_name in fn_names: - # Override namespace collisions - if fn_name in protected_fn_names: - raise AttributeError(f"{fn_name} is protected!") - else: - _classic_method = getattr(self._classic_contract.functions, fn_name) - _concise_method = method_class( - _classic_method, self._classic_contract._return_data_normalizers - ) - setattr(self, fn_name, _concise_method) - - @classmethod - def factory(cls, *args, **kwargs): - return compose(cls, Contract.factory(*args, **kwargs)) +@pytest.fixture(scope="module") +def env(gas_limit, evm_version, evm_backend, tracing, account_keys) -> BaseEnv: + return evm_backend( + gas_limit=gas_limit, + tracing=tracing, + block_number=1, + evm_version=evm_version, + account_keys=account_keys, + ) @pytest.fixture -def get_contract_from_ir(w3, optimize): +def get_contract_from_ir(env, optimize): def ir_compiler(ir, *args, **kwargs): ir = IRnode.from_list(ir) - if optimize != OptimizationLevel.NONE: + if kwargs.pop("optimize", optimize) != OptimizationLevel.NONE: ir = optimizer.optimize(ir) - bytecode, _ = compile_ir.assembly_to_evm( - compile_ir.compile_to_assembly(ir, optimize=optimize) - ) + assembly = compile_ir.compile_to_assembly(ir, optimize=optimize) + bytecode, _ = compile_ir.assembly_to_evm(assembly) - abi = kwargs.get("abi") or [] - c = w3.eth.contract(abi=abi, bytecode=bytecode) - deploy_transaction = c.constructor() - tx_hash = deploy_transaction.transact() - address = w3.eth.get_transaction_receipt(tx_hash)["contractAddress"] - contract = w3.eth.contract( - address, abi=abi, bytecode=bytecode, ContractFactoryClass=VyperContract - ) - return contract + abi = kwargs.pop("abi", []) + return env.deploy(abi, bytecode, *args, **kwargs) return ir_compiler -def _get_contract( - w3, - source_code, - optimize, - experimental_codegen, - output_formats, - *args, - override_opt_level=None, - input_bundle=None, - **kwargs, -): - settings = get_global_settings() - settings.optimize = override_opt_level or optimize - settings.experimental_codegen = experimental_codegen - out = compiler.compile_code( - source_code, - # test that all output formats can get generated - output_formats=output_formats, - settings=settings, - input_bundle=input_bundle, - show_gas_estimates=True, # Enable gas estimates for testing +@pytest.fixture(scope="module", autouse=True) +def compiler_settings(optimize, experimental_codegen, evm_version, debug): + compiler.settings.DEFAULT_ENABLE_DECIMALS = True + settings = Settings( + optimize=optimize, + evm_version=evm_version, + experimental_codegen=experimental_codegen, + debug=debug, ) - parse_vyper_source(source_code) # Test grammar. - json.dumps(out["metadata"]) # test metadata is json serializable - abi = out["abi"] - bytecode = out["bytecode"] - value = kwargs.pop("value_in_eth", 0) * 10**18 # Handle deploying with an eth value. - c = w3.eth.contract(abi=abi, bytecode=bytecode) - deploy_transaction = c.constructor(*args) - tx_info = {"from": w3.eth.accounts[0], "value": value, "gasPrice": 0} - tx_info.update(kwargs) - tx_hash = deploy_transaction.transact(tx_info) - address = w3.eth.get_transaction_receipt(tx_hash)["contractAddress"] - return w3.eth.contract(address, abi=abi, bytecode=bytecode, ContractFactoryClass=VyperContract) + set_global_settings(settings) + return settings @pytest.fixture(scope="module") -def get_contract(w3, optimize, experimental_codegen, output_formats): +def get_contract(env, optimize, output_formats, compiler_settings): def fn(source_code, *args, **kwargs): - return _get_contract( - w3, source_code, optimize, experimental_codegen, output_formats, *args, **kwargs - ) + if "override_opt_level" in kwargs: + kwargs["compiler_settings"] = Settings( + **dict(compiler_settings.__dict__, optimize=kwargs.pop("override_opt_level")) + ) + return env.deploy_source(source_code, output_formats, *args, **kwargs) return fn -@pytest.fixture -def get_contract_with_gas_estimation(tester, w3, optimize, experimental_codegen, output_formats): - def get_contract_with_gas_estimation(source_code, *args, **kwargs): - contract = _get_contract( - w3, source_code, optimize, experimental_codegen, output_formats, *args, **kwargs - ) - for abi_ in contract._classic_contract.functions.abi: - if abi_["type"] == "function": - set_decorator_to_contract_function(w3, tester, contract, source_code, abi_["name"]) - return contract - - return get_contract_with_gas_estimation - - -@pytest.fixture -def get_contract_with_gas_estimation_for_constants( - w3, optimize, experimental_codegen, output_formats -): - def get_contract_with_gas_estimation_for_constants(source_code, *args, **kwargs): - return _get_contract( - w3, source_code, optimize, experimental_codegen, output_formats, *args, **kwargs - ) - - return get_contract_with_gas_estimation_for_constants - - @pytest.fixture(scope="module") -def get_contract_module(optimize, experimental_codegen, output_formats): - """ - This fixture is used for Hypothesis tests to ensure that - the same contract is called over multiple runs of the test. - """ - custom_genesis = PyEVMBackend._generate_genesis_params(overrides={"gas_limit": 4500000}) - custom_genesis["base_fee_per_gas"] = 0 - backend = PyEVMBackend(genesis_parameters=custom_genesis) - tester = EthereumTester(backend=backend) - w3 = Web3(EthereumTesterProvider(tester)) - w3.eth.set_gas_price_strategy(zero_gas_price_strategy) - - def get_contract_module(source_code, *args, **kwargs): - return _get_contract( - w3, source_code, optimize, experimental_codegen, output_formats, *args, **kwargs - ) - - return get_contract_module - - -def _deploy_blueprint_for( - w3, - source_code, - optimize, - experimental_codegen, - output_formats, - initcode_prefix=ERC5202_PREFIX, - **kwargs, -): - settings = Settings() - settings.optimize = optimize - settings.experimental_codegen = experimental_codegen - out = compiler.compile_code( - source_code, - output_formats=output_formats, - settings=settings, - show_gas_estimates=True, # Enable gas estimates for testing - ) - parse_vyper_source(source_code) # Test grammar. - abi = out["abi"] - bytecode = HexBytes(initcode_prefix) + HexBytes(out["bytecode"]) - bytecode_len = len(bytecode) - bytecode_len_hex = hex(bytecode_len)[2:].rjust(4, "0") - # prepend a quick deploy preamble - deploy_preamble = HexBytes("61" + bytecode_len_hex + "3d81600a3d39f3") - deploy_bytecode = HexBytes(deploy_preamble) + bytecode - - deployer_abi = [] # just a constructor - c = w3.eth.contract(abi=deployer_abi, bytecode=deploy_bytecode) - deploy_transaction = c.constructor() - tx_info = {"from": w3.eth.accounts[0], "value": 0, "gasPrice": 0} - - tx_hash = deploy_transaction.transact(tx_info) - address = w3.eth.get_transaction_receipt(tx_hash)["contractAddress"] - - # sanity check - assert w3.eth.get_code(address) == bytecode, (w3.eth.get_code(address), bytecode) - - def factory(address): - return w3.eth.contract( - address, abi=abi, bytecode=bytecode, ContractFactoryClass=VyperContract - ) +def deploy_blueprint_for(env, output_formats): + def fn(source_code, *args, **kwargs): + # we don't pass any settings, but it will pick up the global settings + return env.deploy_blueprint(source_code, output_formats, *args, **kwargs) - return w3.eth.contract(address, bytecode=deploy_bytecode), factory + return fn @pytest.fixture(scope="module") -def deploy_blueprint_for(w3, optimize, experimental_codegen, output_formats): - def deploy_blueprint_for(source_code, *args, **kwargs): - return _deploy_blueprint_for( - w3, source_code, optimize, experimental_codegen, output_formats, *args, **kwargs - ) - - return deploy_blueprint_for +def get_logs(env): + return env.get_logs # TODO: this should not be a fixture. # remove me and replace all uses with `with pytest.raises`. @pytest.fixture -def assert_compile_failed(): +def assert_compile_failed(tx_failed): def assert_compile_failed(function_to_test, exception=Exception): - with pytest.raises(exception): + with tx_failed(exception): function_to_test() return assert_compile_failed @@ -558,8 +292,7 @@ def foo(s: {ret_type}) -> {ret_type}: self.counter += 1 return s """ - contract = get_contract(code) - return contract + return get_contract(code) return generate @@ -577,23 +310,14 @@ def assert_side_effects_invoked(side_effects_contract, side_effects_trigger, n=1 return assert_side_effects_invoked -@pytest.fixture -def get_logs(w3): - def get_logs(tx_hash, c, event_name): - tx_receipt = w3.eth.get_transaction_receipt(tx_hash) - return c._classic_contract.events[event_name]().process_receipt(tx_receipt) - - return get_logs - - +# should probably be renamed since there is no longer a transaction object @pytest.fixture(scope="module") -def tx_failed(tester): +def tx_failed(env): @contextmanager - def fn(exception=TransactionFailed, exc_text=None): - snapshot_id = tester.take_snapshot() + def fn(exception=EvmError, exc_text=None): with pytest.raises(exception) as excinfo: - yield excinfo - tester.revert_to_snapshot(snapshot_id) + yield + if exc_text: # TODO test equality assert exc_text in str(excinfo.value), (exc_text, excinfo.value) @@ -601,12 +325,21 @@ def fn(exception=TransactionFailed, exc_text=None): return fn -def pytest_runtest_call(item): +@pytest.hookimpl(hookwrapper=True) +def pytest_runtest_call(item) -> Generator: marker = item.get_closest_marker("requires_evm_version") if marker: assert len(marker.args) == 1 version = marker.args[0] - if not version_check(begin=version): + if not evm_opcodes.version_check(begin=version): item.add_marker( pytest.mark.xfail(reason="Wrong EVM version", raises=EvmVersionException) ) + + # Isolate tests by reverting the state of the environment after each test + env = item.funcargs.get("env") + if env: + with env.anchor(): + yield + else: + yield diff --git a/tests/evm_backends/__init__.py b/tests/evm_backends/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/evm_backends/abi.py b/tests/evm_backends/abi.py new file mode 100644 index 0000000000..c540468d44 --- /dev/null +++ b/tests/evm_backends/abi.py @@ -0,0 +1,64 @@ +# wrapper module around whatever encoder we are using +from decimal import Decimal +from typing import Any + +from eth.codecs.abi.decoder import Decoder +from eth.codecs.abi.encoder import Encoder +from eth.codecs.abi.exceptions import ABIError +from eth.codecs.abi.nodes import ABITypeNode, AddressNode, BytesNode, FixedNode +from eth.codecs.abi.parser import Parser +from hexbytes import HexBytes + +_parsers: dict[str, ABITypeNode] = {} + + +class _Encoder(Encoder): + """ + Custom encoder that converts some types to the expected format. + """ + + @classmethod + def visit_BytesNode(cls, node: BytesNode, value: bytes | str) -> bytes: + if isinstance(value, str): + assert value.startswith("0x"), "Sanity check failed: expected hex string" + value = bytes.fromhex(value[2:]) + return super().visit_BytesNode(node, value) + + @classmethod + def visit_FixedNode(cls, node: FixedNode, value: Decimal | int) -> bytes: + # REVIEW: note coming changes to decimal (PR #3696) + if isinstance(value, int): + value = Decimal(value) + return super().visit_FixedNode(node, value) + + @classmethod + def visit_AddressNode(cls, node: AddressNode, value: str | bytes | HexBytes) -> bytes: + if isinstance(value, HexBytes): + value = value.hex() + if isinstance(value, bytes): + value = "0x" + value.hex() + return super().visit_AddressNode(node, value) + + +def _get_parser(schema: str): + try: + return _parsers[schema] + except KeyError: + _parsers[schema] = (ret := Parser.parse(schema)) + return ret + + +def abi_encode(schema: str, data: Any) -> bytes: + return _Encoder.encode(_get_parser(schema), data) + + +def abi_decode(schema: str, data: bytes) -> Any: + return Decoder.decode(_get_parser(schema), data) + + +def is_abi_encodable(abi_type: str, data: Any) -> bool: + try: + abi_encode(abi_type, data) + return True + except ABIError: + return False diff --git a/tests/evm_backends/abi_contract.py b/tests/evm_backends/abi_contract.py new file mode 100644 index 0000000000..d9cc6cb481 --- /dev/null +++ b/tests/evm_backends/abi_contract.py @@ -0,0 +1,415 @@ +from collections import defaultdict +from dataclasses import dataclass, make_dataclass +from functools import cached_property +from os.path import basename +from typing import TYPE_CHECKING, Any, Optional, Union +from warnings import warn + +from eth_typing import ChecksumAddress, HexAddress +from eth_utils import to_checksum_address + +from vyper.semantics.analysis.base import FunctionVisibility, StateMutability +from vyper.utils import keccak256, method_id + +from .abi import abi_decode, abi_encode, is_abi_encodable + +if TYPE_CHECKING: + from tests.evm_backends.base_env import BaseEnv, LogEntry + + +@dataclass +class ABILog: + """Represents a parsed log entry from a contract.""" + + address: ChecksumAddress + args: tuple + event: str + topics: list[bytes] + raw_data: bytes + + +class ABILogTopic: + """Represents a log event topic in an ABI.""" + + def __init__(self, event_abi: dict, contract_name: str): + self._abi = event_abi + self._contract_name = contract_name + + @cached_property + def topic_id(self) -> bytes: + """The keccak256 hash of the event signature.""" + if self._abi.get("anonymous") is True: + return b"" + return keccak256((self.name + self.signature).encode()) + + @property + def name(self) -> str: + return self._abi.get("name") or self._abi["type"] + + @property + def indexed_inputs(self) -> list[dict]: + return [item for item in self._abi["inputs"] if item["indexed"]] + + @property + def unindexed_inputs(self) -> list[dict]: + return [item for item in self._abi["inputs"] if not item["indexed"]] + + @cached_property + def indexed_types(self) -> list[str]: + return [_abi_from_json(i) for i in self.indexed_inputs] + + @cached_property + def unindexed_types(self) -> list[str]: + return [_abi_from_json(i) for i in self.unindexed_inputs] + + @property + def signature(self) -> str: + return f"({_format_abi_type(self.indexed_types + self.unindexed_types)})" + + def __repr__(self) -> str: + return f"ABITopic {self._contract_name}.{self.signature} (0x{self.topic_id.hex()})" + + def parse(self, log: "LogEntry") -> ABILog: + topics, raw_data = log.data + return ABILog( + address=to_checksum_address(log.address), + args=self._parse_args(log), + event=self.name, + topics=topics, + raw_data=raw_data, + ) + + @cached_property + def data_type(self) -> type: + """ + Create a dataclass for the log event data. + """ + inputs = self.indexed_inputs + self.unindexed_inputs + fields = [(item["name"], item["type"]) for item in inputs] + return make_dataclass(self.name, fields) + + def _parse_args(self, log: "LogEntry") -> Any: + """Convert the log data into a dataclass instance.""" + topics, data = log.data + assert len(topics) == 1 + len(self.indexed_inputs), "Invalid log topic count" + indexed = [ + t if self._is_hashed(typ) else abi_decode(f"{_format_abi_type([typ])}", t) + for typ, t in zip(self.indexed_types, topics[1:]) + ] + decoded = abi_decode(f"({_format_abi_type(self.unindexed_types)})", data) + return self.data_type(*indexed, *decoded) + + @staticmethod + def _is_hashed(typ): + """Check if a type is hashed when included in a log topic.""" + return typ in ("bytes", "string", "tuple") or typ.endswith("[]") + + +class ABIFunction: + """A single function in an ABI. It does not include overloads.""" + + def __init__(self, abi: dict, contract_name: str): + """ + :param abi: the ABI entry for this function + :param contract_name: the name of the contract this function belongs to + """ + self._abi = abi + self._contract_name = contract_name + self._function_visibility = FunctionVisibility.EXTERNAL + self._mutability = StateMutability.from_abi(abi) + self.contract: Optional["ABIContract"] = None + + @property + def name(self) -> str: + # note: the `constructor` definition does not have a name + return self._abi.get("name") or self._abi["type"] + + @cached_property + def argument_types(self) -> list: + return [_abi_from_json(i) for i in self._abi["inputs"]] + + @property + def argument_count(self) -> int: + return len(self.argument_types) + + @property + def _args_signature(self) -> str: + return f"({_format_abi_type(self.argument_types)})" + + @cached_property + def return_type(self) -> list: + return [_abi_from_json(o) for o in self._abi["outputs"]] + + @property + def full_signature(self) -> str: + return f"{self.name}{self._args_signature}" + + @property + def pretty_signature(self) -> str: + return f"{self.name}{self._args_signature} -> {self.return_type}" + + @cached_property + def method_id(self) -> bytes: + if self._abi["type"] == "constructor": + return b"" # constructors don't have method IDs + return method_id(self.name + self._args_signature) + + def __repr__(self) -> str: + return f"ABI {self._contract_name}.{self.pretty_signature}" + + def __str__(self) -> str: + return repr(self) + + @property + def is_mutable(self) -> bool: + return self._mutability > StateMutability.VIEW + + def is_encodable(self, *args, **kwargs) -> bool: + """Check whether this function accepts the given arguments after eventual encoding.""" + if len(kwargs) + len(args) != self.argument_count: + return False + parsed_args = self._merge_kwargs(*args, **kwargs) + return all( + is_abi_encodable(abi_type, arg) + for abi_type, arg in zip(self.argument_types, parsed_args) + ) + + def prepare_calldata(self, *args, **kwargs) -> bytes: + """Prepare the call data for the function call.""" + abi_args = self._merge_kwargs(*args, **kwargs) + return self.method_id + abi_encode(self._args_signature, abi_args) + + def _merge_kwargs(self, *args, **kwargs) -> list: + """Merge positional and keyword arguments into a single list.""" + if len(kwargs) + len(args) != self.argument_count: + raise TypeError( + "invocation failed due to improper number of arguments to" + f" `{repr(self)}` (expected {self.argument_count} " + f"arguments, got {len(args)} args and {len(kwargs)} kwargs)" + ) + try: + kwarg_inputs = self._abi["inputs"][len(args) :] + return list(args) + [kwargs.pop(i["name"]) for i in kwarg_inputs] + except KeyError as e: + error = ( + f"Missing keyword argument {e} for `{self._args_signature}`. Passed {args} {kwargs}" + ) + raise TypeError(error) + + def __call__(self, *args, value=0, gas=None, gas_price=0, sender=None, **kwargs): + """Calls the function with the given arguments based on the ABI contract.""" + if not self.contract or not self.contract.env: + raise Exception(f"Cannot call {self} without deploying contract.") + + if sender is None: + sender = self.contract.env.deployer + + computation = self.contract.env.message_call( + to=self.contract.address, + sender=sender, + data=self.prepare_calldata(*args, **kwargs), + value=value, + gas=gas, + gas_price=gas_price, + is_modifying=self.is_mutable, + ) + + match self.contract.marshal_to_python(computation, self.return_type): + case (): + return None + case (single,): + return single + case multiple: + return multiple + + +class ABIOverload: + """ + Represents a set of functions that have the same name but different + argument types. This is used to implement function overloading. + """ + + @staticmethod + def create( + functions: list[ABIFunction], contract: "ABIContract" + ) -> Union["ABIOverload", ABIFunction]: + """ + Create an ABIOverload if there are multiple functions, otherwise + return the single function. + :param functions: a list of functions with the same name + :param contract: the ABIContract that these functions belong to + """ + for f in functions: + f.contract = contract + if len(functions) == 1: + return functions[0] + return ABIOverload(functions) + + def __init__(self, functions: list[ABIFunction]): + self.functions = functions + + @cached_property + def name(self) -> str: + return self.functions[0].name + + def __call__( + self, *args, value=0, gas=None, sender=None, disambiguate_signature=None, **kwargs + ): + """ + Call the function that matches the given arguments. + :raises Exception: if a single function is not found + """ + function = self._pick_overload( + *args, disambiguate_signature=disambiguate_signature, **kwargs + ) + return function(*args, value=value, gas=gas, sender=sender, **kwargs) + + def _pick_overload(self, *args, disambiguate_signature=None, **kwargs) -> ABIFunction: + """Pick the function that matches the given arguments.""" + if disambiguate_signature is None: + matches = [f for f in self.functions if f.is_encodable(*args, **kwargs)] + else: + matches = [f for f in self.functions if disambiguate_signature == f.full_signature] + assert len(matches) <= 1, "ABI signature must be unique" + + match matches: + case [function]: + return function + case []: + raise Exception( + f"Could not find matching {self.name} function for given arguments." + ) + case multiple: + raise Exception( + f"Ambiguous call to {self.name}. " + f"Arguments can be encoded to multiple overloads: " + f"{', '.join(self.name + f._args_signature for f in multiple)}. " + f"(Hint: try using `disambiguate_signature=` to disambiguate)." + ) + + +class ABIContract: + """A contract that has been deployed to the blockchain and created via an ABI.""" + + @property + def address(self) -> HexAddress: + assert self._address is not None + return self._address + + def __init__( + self, + env: "BaseEnv", + name: str, + abi: dict, + functions: list[ABIFunction], + log_topics: list[ABILogTopic], + bytecode: Optional[bytes], + address: HexAddress, + filename: Optional[str] = None, + ): + self.env = env + self._address = address # this can be overridden by subclasses + self.filename = filename + self.abi = abi + self._name = name + self._functions = functions + self.log_topics = log_topics + self.bytecode = bytecode + self._deployed_bytecode = self.env.get_code(address) + if not self._deployed_bytecode: + warn(f"Requested {self} but there is no bytecode at that address!", stacklevel=2) + + overloads = defaultdict(list) + for f in functions: + overloads[f.name].append(f) + + for name, group in overloads.items(): + setattr(self, name, ABIOverload.create(group, self)) + + self._address = address + + def marshal_to_python(self, result: bytes, abi_type: list[str]) -> list[Any]: + """ + Convert the output of a contract call to a Python object. + :param result: the computation result returned by `message_call` + :param abi_type: the ABI type of the return value. + """ + schema = f"({_format_abi_type(abi_type)})" + return abi_decode(schema, result) + + def __repr__(self): + file_str = f" (file {self.filename})" if self.filename else "" + warn_str = "" if self._deployed_bytecode else " (WARNING: no bytecode at this address!)" + return f"<{self._name} interface at {self.address}{warn_str}>{file_str}" + + def parse_log(self, log: "LogEntry") -> ABILog: + """ + Parse a log entry into an ABILog object. + :param log: the log entry to parse + """ + topic_id_str = log.topics[0] + topic_id = bytes.fromhex(topic_id_str.removeprefix("0x")) + for topic in self.log_topics: + if topic.topic_id == topic_id: + return topic.parse(log) + raise KeyError(f"Could not find event for log {topic_id_str}. Found {self.log_topics}") + + +class ABIContractFactory: + """ + Represents an ABI contract that has not been coupled with an address yet. + This is named `Factory` instead of `Deployer` because it doesn't actually + do any contract deployment. + """ + + def __init__( + self, + name: str, + abi: dict, + functions: list[ABIFunction], + log_topics: list[ABILogTopic], + bytecode: Optional[bytes] = None, + ): + self._name = name + self._abi = abi + self._functions = functions + self._log_topics = log_topics + self._bytecode = bytecode + + @classmethod + def from_abi_dict(cls, abi, name="", bytecode: Optional[bytes] = None): + functions = [ABIFunction(item, name) for item in abi if item.get("type") == "function"] + log_topics = [ABILogTopic(item, name) for item in abi if item.get("type") == "event"] + return cls(basename(name), abi, functions, log_topics, bytecode) + + def at(self, env, address: HexAddress) -> ABIContract: + """ + Create an ABI contract object for a deployed contract at `address`. + """ + return ABIContract( + env, self._name, self._abi, self._functions, self._log_topics, self._bytecode, address + ) + + +def _abi_from_json(abi: dict) -> str: + """ + Parses an ABI type into its schema string. + :param abi: The ABI type to parse. + :return: The schema string for the given abi type. + """ + if "components" in abi: + components = ",".join([_abi_from_json(item) for item in abi["components"]]) + if abi["type"].startswith("tuple"): + return f"({components}){abi['type'][5:]}" + raise ValueError("Components found in non-tuple type " + abi["type"]) + + return abi["type"] + + +def _format_abi_type(types: list) -> str: + """ + Converts a list of ABI types into a comma-separated string. + """ + return ",".join( + item if isinstance(item, str) else f"({_format_abi_type(item)})" for item in types + ) diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py new file mode 100644 index 0000000000..9d7548e037 --- /dev/null +++ b/tests/evm_backends/base_env.py @@ -0,0 +1,209 @@ +import json +from contextlib import contextmanager +from dataclasses import dataclass +from typing import Callable, Optional + +from eth_keys.datatypes import PrivateKey +from eth_utils import to_checksum_address + +from tests.evm_backends.abi import abi_decode +from tests.evm_backends.abi_contract import ABIContract, ABIContractFactory, ABIFunction +from vyper.ast.grammar import parse_vyper_source +from vyper.compiler import CompilerData, InputBundle, Settings, compile_code +from vyper.utils import ERC5202_PREFIX, method_id + + +# a very simple log representation for the raw log entries +@dataclass +class LogEntry: + address: str + topics: list[str] + data: tuple[list[bytes], bytes] # (topic list, non-topic) + + +# object returned by `last_result` property +@dataclass +class ExecutionResult: + is_success: bool + logs: list[LogEntry] + gas_refunded: int + gas_used: int + + +class EvmError(RuntimeError): + """Exception raised when a call fails.""" + + +class ExecutionReverted(EvmError): + """Exception raised when a call reverts.""" + + +class BaseEnv: + """ + Base class for EVM backends. + It provides a common interface for deploying contracts and interacting with them. + """ + + INVALID_OPCODE_ERROR = "NotImplemented" # must be implemented by subclasses + DEFAULT_CHAIN_ID = 1 + + def __init__(self, gas_limit: int, account_keys: list[PrivateKey]) -> None: + self.gas_limit = gas_limit + self._keys = account_keys + self.deployer: str = self._keys[0].public_key.to_checksum_address() + + def deploy(self, abi: list[dict], bytecode: bytes, value=0, *args, **kwargs): + """Deploy a contract with the given ABI and bytecode.""" + factory = ABIContractFactory.from_abi_dict(abi, bytecode=bytecode) + + initcode = bytecode + if args or kwargs: + ctor_abi = next(i for i in abi if i["type"] == "constructor") + ctor = ABIFunction(ctor_abi, contract_name=factory._name) + initcode += ctor.prepare_calldata(*args, **kwargs) + + deployed_at = self._deploy(initcode, value) + address = to_checksum_address(deployed_at) + return factory.at(self, address) + + def deploy_source( + self, + source_code: str, + output_formats: dict[str, Callable[[CompilerData], str]], + *args, + compiler_settings: Settings = None, + input_bundle: InputBundle = None, + value: int = 0, + **kwargs, + ) -> ABIContract: + """Compile and deploy a contract from source code.""" + abi, bytecode = _compile(source_code, output_formats, input_bundle, compiler_settings) + return self.deploy(abi, bytecode, value, *args, **kwargs) + + def deploy_blueprint( + self, + source_code, + output_formats, + *args, + input_bundle: InputBundle = None, + initcode_prefix: bytes = ERC5202_PREFIX, + ): + """Deploy a contract with a blueprint pattern.""" + abi, bytecode = _compile(source_code, output_formats, input_bundle) + bytecode = initcode_prefix + bytecode + bytecode_len = len(bytecode) + bytecode_len_hex = hex(bytecode_len)[2:].rjust(4, "0") + # prepend a quick deploy preamble + deploy_preamble = bytes.fromhex("61" + bytecode_len_hex + "3d81600a3d39f3") + deploy_bytecode = deploy_preamble + bytecode + + deployer_abi: list[dict] = [] # just a constructor + deployer = self.deploy(deployer_abi, deploy_bytecode, *args) + + def factory(address): + return ABIContractFactory.from_abi_dict(abi).at(self, address) + + return deployer, factory + + def get_logs(self, contract: ABIContract, event_name: str = None, raw=False): + logs = [log for log in self.last_result.logs if contract.address == log.address] + if raw: + return [log.data for log in logs] + + parsed_logs = [contract.parse_log(log) for log in logs] + if event_name: + return [log for log in parsed_logs if log.event == event_name] + + return parsed_logs + + @property + def accounts(self) -> list[str]: + return [key.public_key.to_checksum_address() for key in self._keys] + + @contextmanager + def anchor(self): + raise NotImplementedError # must be implemented by subclasses + + def get_balance(self, address: str) -> int: + raise NotImplementedError # must be implemented by subclasses + + def set_balance(self, address: str, value: int): + raise NotImplementedError # must be implemented by subclasses + + @property + def block_number(self) -> int: + raise NotImplementedError # must be implemented by subclasses + + @block_number.setter + def block_number(self, value: int): + raise NotImplementedError + + @property + def timestamp(self) -> int | None: + raise NotImplementedError # must be implemented by subclasses + + @timestamp.setter + def timestamp(self, value: int): + raise NotImplementedError # must be implemented by subclasses + + @property + def last_result(self) -> ExecutionResult: + raise NotImplementedError # must be implemented by subclasses + + def message_call( + self, + to: str, + sender: str | None = None, + data: bytes | str = b"", + value: int = 0, + gas: int | None = None, + gas_price: int = 0, + is_modifying: bool = True, + blob_hashes: Optional[list[bytes]] = None, # for blobbasefee >= Cancun + ) -> bytes: + raise NotImplementedError # must be implemented by subclasses + + def clear_transient_storage(self) -> None: + raise NotImplementedError # must be implemented by subclasses + + def get_code(self, address: str) -> bytes: + raise NotImplementedError # must be implemented by subclasses + + def get_excess_blob_gas(self) -> Optional[int]: + raise NotImplementedError # must be implemented by subclasses + + def set_excess_blob_gas(self, param): + raise NotImplementedError # must be implemented by subclasses + + def _deploy(self, code: bytes, value: int, gas: int | None = None) -> str: + raise NotImplementedError # must be implemented by subclasses + + @staticmethod + def _parse_revert(output_bytes: bytes, error: Exception, gas_used: int): + """ + Tries to parse the EIP-838 revert reason from the output bytes. + """ + if output_bytes[:4] == method_id("Error(string)"): + (msg,) = abi_decode("(string)", output_bytes[4:]) + raise ExecutionReverted(f"{msg}", gas_used) from error + + raise ExecutionReverted(f"0x{output_bytes.hex()}", gas_used) from error + + +def _compile( + source_code: str, + output_formats: dict[str, Callable[[CompilerData], str]], + input_bundle: InputBundle = None, + settings: Settings = None, +) -> tuple[list[dict], bytes]: + out = compile_code( + source_code, + # test that all output formats can get generated + output_formats=output_formats, + settings=settings, + input_bundle=input_bundle, + show_gas_estimates=True, # Enable gas estimates for testing + ) + parse_vyper_source(source_code) # Test grammar. + json.dumps(out["metadata"]) # test metadata is json serializable + return out["abi"], bytes.fromhex(out["bytecode"].removeprefix("0x")) diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py new file mode 100644 index 0000000000..fa960867c9 --- /dev/null +++ b/tests/evm_backends/pyevm_env.py @@ -0,0 +1,217 @@ +import logging +from contextlib import contextmanager +from typing import Optional + +import rlp +from cached_property import cached_property +from eth.abc import ChainAPI, ComputationAPI +from eth.chains.mainnet import MainnetChain +from eth.constants import CREATE_CONTRACT_ADDRESS, GENESIS_DIFFICULTY +from eth.db.atomic import AtomicDB +from eth.exceptions import Revert, VMError +from eth.tools.builder import chain as chain_builder +from eth.vm.base import StateAPI +from eth.vm.execution_context import ExecutionContext +from eth.vm.message import Message +from eth.vm.transaction_context import BaseTransactionContext +from eth_keys.datatypes import PrivateKey +from eth_typing import Address +from eth_utils import setup_DEBUG2_logging, to_canonical_address, to_checksum_address + +import vyper.evm.opcodes as evm_opcodes +from tests.evm_backends.base_env import BaseEnv, EvmError, ExecutionResult, LogEntry +from vyper.utils import keccak256 + + +class PyEvmEnv(BaseEnv): + """EVM backend environment using the Py-EVM library.""" + + INVALID_OPCODE_ERROR = "Invalid opcode" + + def __init__( + self, + gas_limit: int, + account_keys: list[PrivateKey], + tracing: bool, + block_number: int, + evm_version: str, + ) -> None: + super().__init__(gas_limit, account_keys) + + evm_opcodes.DEFAULT_EVM_VERSION = evm_version + + if tracing: + logger = logging.getLogger("eth.vm.computation.BaseComputation") + setup_DEBUG2_logging() + logger.setLevel("DEBUG2") + # from vdb import vdb + # vdb.set_evm_opcode_debugger() + + spec = getattr(chain_builder, evm_version + "_at")(block_number) + self._chain: ChainAPI = chain_builder.build(MainnetChain, spec).from_genesis( + base_db=AtomicDB(), + genesis_params={"difficulty": GENESIS_DIFFICULTY, "gas_limit": gas_limit}, + ) + + self._last_computation: ComputationAPI = None + + @cached_property + def _state(self) -> StateAPI: + return self._vm.state + + @cached_property + def _vm(self): + return self._chain.get_vm() + + @cached_property + def _context(self) -> ExecutionContext: + context = self._state.execution_context + assert isinstance(context, ExecutionContext) # help mypy + return context + + @contextmanager + def anchor(self): + snapshot_id = self._state.snapshot() + try: + yield + finally: + self._state.revert(snapshot_id) + + def get_balance(self, address: str) -> int: + return self._state.get_balance(_addr(address)) + + def set_balance(self, address: str, value: int): + self._state.set_balance(_addr(address), value) + + @property + def block_number(self) -> int: + return self._context.block_number + + @block_number.setter + def block_number(self, value: int): + self._context._block_number = value + + @property + def timestamp(self) -> int | None: + return self._context.timestamp + + @timestamp.setter + def timestamp(self, value: int): + self._context._timestamp = value + + @property + def last_result(self) -> ExecutionResult: + result = self._last_computation + return ExecutionResult( + is_success=not result.is_error, + logs=list(_parse_log_entries(result)), + gas_refunded=result.get_gas_refund(), + gas_used=result.get_gas_used(), + ) + + def message_call( + self, + to: str, + sender: str | None = None, + data: bytes | str = b"", + value: int = 0, + gas: int | None = None, + gas_price: int = 0, + is_modifying: bool = True, + blob_hashes: Optional[list[bytes]] = None, # for blobbasefee >= Cancun + ): + if isinstance(data, str): + data = bytes.fromhex(data.removeprefix("0x")) + sender = _addr(sender or self.deployer) + try: + computation = self._state.computation_class.apply_message( + state=self._state, + message=Message( + to=_addr(to), + sender=sender, + data=data, + code=self.get_code(to), + value=value, + gas=self.gas_limit if gas is None else gas, + is_static=not is_modifying, + ), + transaction_context=BaseTransactionContext(origin=sender, gas_price=gas_price), + ) + except VMError as e: + # py-evm raises when user is out-of-funds instead of returning a failed computation + raise EvmError(*e.args) from e + + self._check_computation(computation) + return computation.output + + def clear_transient_storage(self) -> None: + try: + self._state.clear_transient_storage() + except AttributeError as e: + assert e.args == ("No transient_storage has been set for this State",) + + def _check_computation(self, computation): + self._last_computation = computation + if computation.is_error: + if isinstance(computation.error, Revert): + (output,) = computation.error.args + gas_used = computation.get_gas_used() + self._parse_revert(output, computation.error, gas_used) + + raise EvmError(*computation.error.args) from computation.error + + def get_code(self, address: str): + return self._state.get_code(_addr(address)) + + def get_excess_blob_gas(self) -> Optional[int]: + return self._context.excess_blob_gas + + def set_excess_blob_gas(self, param): + self._context._excess_blob_gas = param + + def _deploy(self, code: bytes, value: int, gas: int = None) -> str: + sender = _addr(self.deployer) + target_address = self._generate_contract_address(sender) + + try: + computation = self._state.computation_class.apply_create_message( + state=self._state, + message=Message( + to=CREATE_CONTRACT_ADDRESS, # i.e., b"" + sender=sender, + value=value, + code=code, + data=b"", + gas=gas or self.gas_limit, + create_address=target_address, + ), + transaction_context=BaseTransactionContext(origin=sender, gas_price=0), + ) + except VMError as e: + # py-evm raises when user is out-of-funds instead of returning a failed computation + raise EvmError(*e.args) from e + + self._check_computation(computation) + return "0x" + target_address.hex() + + def _generate_contract_address(self, sender: Address) -> Address: + nonce = self._state.get_nonce(sender) + self._state.increment_nonce(sender) + next_account_hash = keccak256(rlp.encode([sender, nonce])) + return to_canonical_address(next_account_hash[-20:]) + + +def _parse_log_entries(result: ComputationAPI): + """ + Parses the raw log entries from a computation result into a more + usable format similar to the revm backend. + """ + for address, topics, data in result.get_log_entries(): + topic_bytes = [t.to_bytes(32, "big") for t in topics] + topic_ids = ["0x" + t.hex() for t in topic_bytes] + yield LogEntry(to_checksum_address(address), topic_ids, (topic_bytes, data)) + + +def _addr(address: str) -> Address: + """Convert an address string to an Address object.""" + return Address(bytes.fromhex(address.removeprefix("0x"))) diff --git a/tests/evm_backends/revm_env.py b/tests/evm_backends/revm_env.py new file mode 100644 index 0000000000..de75fd4f7d --- /dev/null +++ b/tests/evm_backends/revm_env.py @@ -0,0 +1,138 @@ +import re +from contextlib import contextmanager +from typing import Optional + +from eth_keys.datatypes import PrivateKey +from pyrevm import EVM, BlockEnv, Env + +from tests.evm_backends.base_env import BaseEnv, EvmError, ExecutionResult + + +class RevmEnv(BaseEnv): + INVALID_OPCODE_ERROR = "InvalidFEOpcode" + + def __init__( + self, + gas_limit: int, + account_keys: list[PrivateKey], + tracing: bool, + block_number: int, + evm_version: str, + ) -> None: + super().__init__(gas_limit, account_keys) + self._evm = EVM( + gas_limit=gas_limit, + tracing=tracing, + spec_id=evm_version, + env=Env(block=BlockEnv(number=block_number)), + ) + + @contextmanager + def anchor(self): + snapshot_id = self._evm.snapshot() + try: + yield + finally: + try: + self._evm.revert(snapshot_id) + except OverflowError: + # snapshot_id is reverted by the transaction already. + # revm updates are needed to make the journal more robust. + pass + + def get_balance(self, address: str) -> int: + return self._evm.get_balance(address) + + def set_balance(self, address: str, value: int): + self._evm.set_balance(address, value) + + @property + def block_number(self) -> int: + return self._evm.env.block.number + + @block_number.setter + def block_number(self, value: int): + block = self._evm.env.block + block.number = value + self._evm.set_block_env(block) + + @property + def timestamp(self) -> int | None: + return self._evm.env.block.timestamp + + @timestamp.setter + def timestamp(self, value: int): + block = self._evm.env.block + block.timestamp = value + self._evm.set_block_env(block) + + @property + def last_result(self) -> ExecutionResult: + result = self._evm.result + return ExecutionResult( + gas_refunded=result.gas_refunded, + gas_used=result.gas_used, + is_success=result.is_success, + logs=result.logs, + ) + + def message_call( + self, + to: str, + sender: str | None = None, + data: bytes | str = b"", + value: int = 0, + gas: int | None = None, + gas_price: int = 0, + is_modifying: bool = True, + blob_hashes: Optional[list[bytes]] = None, # for blobbasefee >= Cancun + ): + if isinstance(data, str): + data = bytes.fromhex(data.removeprefix("0x")) + if blob_hashes is not None: + tx = self._evm.env.tx + tx.blob_hashes = blob_hashes + self._evm.set_tx_env(tx) + + try: + return self._evm.message_call( + to=to, + caller=sender or self.deployer, + calldata=data, + value=value, + gas=self.gas_limit if gas is None else gas, + gas_price=gas_price, + is_static=not is_modifying, + ) + except RuntimeError as e: + self._parse_error(e) + raise EvmError(*e.args) from e + + def clear_transient_storage(self) -> None: + self._evm.reset_transient_storage() + + def get_code(self, address: str): + return self._evm.basic(address).code.rstrip(b"\0") + + def get_excess_blob_gas(self) -> Optional[int]: + return self._evm.env.block.excess_blob_gas + + def get_blob_gasprice(self) -> Optional[int]: + return self._evm.env.block.blob_gasprice + + def set_excess_blob_gas(self, value): + self._evm.env.block.excess_blob_gas = value + + def _deploy(self, code: bytes, value: int, gas: int = None) -> str: + try: + return self._evm.deploy(self.deployer, code, value, gas) + except RuntimeError as e: + self._parse_error(e) + raise EvmError(*e.args) from e + + def _parse_error(self, e: RuntimeError): + # TODO: Create a custom error in pyrevm instead parsing strings + if match := re.match(r"Revert \{ gas_used: (\d+), output: 0x([0-9a-f]*) }", e.args[0]): + gas_used, output_str = match.groups() + output_bytes = bytes.fromhex(output_str) + super()._parse_revert(output_bytes, e, int(gas_used)) diff --git a/tests/functional/builtins/codegen/test_abi_decode.py b/tests/functional/builtins/codegen/test_abi_decode.py index 77e88c0277..af8a2d6adb 100644 --- a/tests/functional/builtins/codegen/test_abi_decode.py +++ b/tests/functional/builtins/codegen/test_abi_decode.py @@ -69,10 +69,10 @@ def abi_decode_struct(x: Bytes[544]) -> Human: "foobar", ("vyper", TEST_ADDR, 123, True, decimal_to_int("123.4"), [123, 456, 789], test_bytes32), ) - args = tuple([human_tuple[0]] + list(human_tuple[1])) + human_t = "((string,(string,address,int128,bool,int168,uint256[3],bytes32)))" human_encoded = abi.encode(human_t, (human_tuple,)) - assert tuple(c.abi_decode_struct(human_encoded)) == ( + assert c.abi_decode_struct(human_encoded) == ( "foobar", ("vyper", TEST_ADDR, 123, True, decimal_to_int("123.4"), [123, 456, 789], test_bytes32), ) @@ -91,9 +91,7 @@ def abi_decode_struct(x: Bytes[544]) -> Human: ([123, 456, 789], 160, "DynArray[uint256, 3]", "(uint256[])", True), ], ) -def test_abi_decode_single( - w3, get_contract, expected, input_len, output_typ, abi_typ, unwrap_tuple -): +def test_abi_decode_single(get_contract, expected, input_len, output_typ, abi_typ, unwrap_tuple): contract = f""" @external def foo(x: Bytes[{input_len}]) -> {output_typ}: @@ -275,7 +273,7 @@ def foo(bs: Bytes[160]) -> (uint256, DynArray[uint256, 3]): c = get_contract(code) bs = [1, 2, 3] encoded = abi.encode("(uint256[])", (bs,)) - assert c.foo(encoded) == [2**256 - 1, bs] + assert c.foo(encoded) == (2**256 - 1, bs) def test_abi_decode_private_nested_dynarray(get_contract): @@ -299,7 +297,7 @@ def foo(bs: Bytes[1696]) -> (uint256, DynArray[DynArray[DynArray[uint256, 3], 3] [[19, 20, 21], [22, 23, 24], [25, 26, 27]], ] encoded = abi.encode("(uint256[][][])", (bs,)) - assert c.foo(encoded) == [2**256 - 1, bs] + assert c.foo(encoded) == (2**256 - 1, bs) def test_abi_decode_return(get_contract): diff --git a/tests/functional/builtins/codegen/test_abi_encode.py b/tests/functional/builtins/codegen/test_abi_encode.py index 387dab789a..7acf00e0b6 100644 --- a/tests/functional/builtins/codegen/test_abi_encode.py +++ b/tests/functional/builtins/codegen/test_abi_encode.py @@ -310,7 +310,7 @@ def foo(bs: Bytes[32]) -> (uint256, Bytes[96]): """ c = get_contract(code) bs = b"\x00" * 32 - assert c.foo(bs) == [2**256 - 1, abi.encode("(bytes)", (bs,))] + assert c.foo(bs) == (2**256 - 1, abi.encode("(bytes)", (bs,))) def test_abi_encode_private_dynarray(get_contract): @@ -327,7 +327,7 @@ def foo(bs: DynArray[uint256, 3]) -> (uint256, Bytes[160]): """ c = get_contract(code) bs = [1, 2, 3] - assert c.foo(bs) == [2**256 - 1, abi.encode("(uint256[])", (bs,))] + assert c.foo(bs) == (2**256 - 1, abi.encode("(uint256[])", (bs,))) def test_abi_encode_private_nested_dynarray(get_contract): @@ -349,7 +349,7 @@ def foo(bs: DynArray[DynArray[DynArray[uint256, 3], 3], 3]) -> (uint256, Bytes[1 [[10, 11, 12], [13, 14, 15], [16, 17, 18]], [[19, 20, 21], [22, 23, 24], [25, 26, 27]], ] - assert c.foo(bs) == [2**256 - 1, abi.encode("(uint256[][][])", (bs,))] + assert c.foo(bs) == (2**256 - 1, abi.encode("(uint256[][][])", (bs,))) @pytest.mark.parametrize("empty_literal", ('b""', '""', "empty(Bytes[1])", "empty(String[1])")) diff --git a/tests/functional/builtins/codegen/test_addmod.py b/tests/functional/builtins/codegen/test_addmod.py index 10fe4bfc54..9e070555ee 100644 --- a/tests/functional/builtins/codegen/test_addmod.py +++ b/tests/functional/builtins/codegen/test_addmod.py @@ -1,11 +1,11 @@ -def test_uint256_addmod(tx_failed, get_contract_with_gas_estimation): +def test_uint256_addmod(tx_failed, get_contract): uint256_code = """ @external def _uint256_addmod(x: uint256, y: uint256, z: uint256) -> uint256: return uint256_addmod(x, y, z) """ - c = get_contract_with_gas_estimation(uint256_code) + c = get_contract(uint256_code) assert c._uint256_addmod(1, 2, 2) == 1 assert c._uint256_addmod(32, 2, 32) == 2 @@ -15,9 +15,7 @@ def _uint256_addmod(x: uint256, y: uint256, z: uint256) -> uint256: c._uint256_addmod(1, 2, 0) -def test_uint256_addmod_ext_call( - w3, side_effects_contract, assert_side_effects_invoked, get_contract -): +def test_uint256_addmod_ext_call(side_effects_contract, assert_side_effects_invoked, get_contract): code = """ interface Foo: def foo(x: uint256) -> uint256: payable @@ -31,10 +29,10 @@ def foo(f: Foo) -> uint256: c2 = get_contract(code) assert c2.foo(c1.address) == 2 - assert_side_effects_invoked(c1, lambda: c2.foo(c1.address, transact={})) + assert_side_effects_invoked(c1, lambda: c2.foo(c1.address)) -def test_uint256_addmod_internal_call(get_contract_with_gas_estimation): +def test_uint256_addmod_internal_call(get_contract): code = """ @external def foo() -> uint256: @@ -53,12 +51,12 @@ def c() -> uint256: return 32 """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == 2 -def test_uint256_addmod_evaluation_order(get_contract_with_gas_estimation): +def test_uint256_addmod_evaluation_order(get_contract): code = """ a: uint256 @@ -83,7 +81,7 @@ def bar() -> uint256: return 2 """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo1() == 1 assert c.foo2() == 2 diff --git a/tests/functional/builtins/codegen/test_as_wei_value.py b/tests/functional/builtins/codegen/test_as_wei_value.py index 7ceaefd347..d63f5a8a9c 100644 --- a/tests/functional/builtins/codegen/test_as_wei_value.py +++ b/tests/functional/builtins/codegen/test_as_wei_value.py @@ -1,4 +1,5 @@ import pytest +from eth_utils import to_wei from tests.utils import decimal_to_int from vyper.semantics.types import DecimalT @@ -100,7 +101,7 @@ def foo(a: {data_type}) -> uint256: assert c.foo(0) == 0 -def test_ext_call(w3, side_effects_contract, assert_side_effects_invoked, get_contract): +def test_ext_call(side_effects_contract, assert_side_effects_invoked, get_contract): code = """ interface Foo: def foo(x: uint8) -> uint8: nonpayable @@ -113,11 +114,11 @@ def foo(a: Foo) -> uint256: c1 = side_effects_contract("uint8") c2 = get_contract(code) - assert c2.foo(c1.address) == w3.to_wei(7, "ether") - assert_side_effects_invoked(c1, lambda: c2.foo(c1.address, transact={})) + assert c2.foo(c1.address) == to_wei(7, "ether") + assert_side_effects_invoked(c1, lambda: c2.foo(c1.address)) -def test_internal_call(w3, get_contract_with_gas_estimation): +def test_internal_call(get_contract): code = """ @external def foo() -> uint256: @@ -127,7 +128,5 @@ def foo() -> uint256: def bar() -> uint8: return 7 """ - - c = get_contract_with_gas_estimation(code) - - assert c.foo() == w3.to_wei(7, "ether") + c = get_contract(code) + assert c.foo() == to_wei(7, "ether") diff --git a/tests/functional/builtins/codegen/test_bitwise.py b/tests/functional/builtins/codegen/test_bitwise.py index 1d62a5be79..088484839d 100644 --- a/tests/functional/builtins/codegen/test_bitwise.py +++ b/tests/functional/builtins/codegen/test_bitwise.py @@ -37,8 +37,8 @@ def test_bitwise_opcodes(): assert "SHR" in opcodes -def test_test_bitwise(get_contract_with_gas_estimation): - c = get_contract_with_gas_estimation(code) +def test_test_bitwise(get_contract): + c = get_contract(code) x = 126416208461208640982146408124 y = 7128468721412412459 assert c._bitwise_and(x, y) == (x & y) @@ -52,7 +52,7 @@ def test_test_bitwise(get_contract_with_gas_estimation): assert c._shl(t, s) == (t << s) % (2**256) -def test_signed_shift(get_contract_with_gas_estimation): +def test_signed_shift(get_contract): code = """ @external def _sar(x: int256, y: uint256) -> int256: @@ -62,7 +62,7 @@ def _sar(x: int256, y: uint256) -> int256: def _shl(x: int256, y: uint256) -> int256: return x << y """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) x = 126416208461208640982146408124 y = 7128468721412412459 cases = [x, y, -x, -y] @@ -168,5 +168,5 @@ def foo() -> uint256: @pytest.mark.parametrize("bad_code,exc", fail_list) -def test_shift_fail(get_contract_with_gas_estimation, bad_code, exc, assert_compile_failed): - assert_compile_failed(lambda: get_contract_with_gas_estimation(bad_code), exc) +def test_shift_fail(get_contract, bad_code, exc, assert_compile_failed): + assert_compile_failed(lambda: get_contract(bad_code), exc) diff --git a/tests/functional/builtins/codegen/test_ceil.py b/tests/functional/builtins/codegen/test_ceil.py index be8efd3e70..89356ba30b 100644 --- a/tests/functional/builtins/codegen/test_ceil.py +++ b/tests/functional/builtins/codegen/test_ceil.py @@ -4,7 +4,7 @@ from tests.utils import decimal_to_int -def test_ceil(get_contract_with_gas_estimation): +def test_ceil(get_contract): code = """ x: decimal @@ -40,7 +40,7 @@ def fou() -> int256: return ceil(c) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.x_ceil() == 505 assert c.foo() == 1 @@ -51,7 +51,7 @@ def fou() -> int256: # ceil(x) should yield the smallest integer greater than or equal to x -def test_ceil_negative(get_contract_with_gas_estimation): +def test_ceil_negative(get_contract): code = """ x: decimal @@ -95,7 +95,7 @@ def ceil_param(p: decimal) -> int256: return ceil(p) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.x_ceil() == -504 assert c.foo() == -11 @@ -108,7 +108,7 @@ def ceil_param(p: decimal) -> int256: assert c.ceil_param(decimal_to_int("-7777777.7777777")) == -7777777 -def test_ceil_ext_call(w3, side_effects_contract, assert_side_effects_invoked, get_contract): +def test_ceil_ext_call(side_effects_contract, assert_side_effects_invoked, get_contract): code = """ interface Foo: def foo(x: decimal) -> decimal: payable @@ -123,10 +123,10 @@ def foo(a: Foo) -> int256: assert c2.foo(c1.address) == 3 - assert_side_effects_invoked(c1, lambda: c2.foo(c1.address, transact={})) + assert_side_effects_invoked(c1, lambda: c2.foo(c1.address)) -def test_ceil_internal_call(get_contract_with_gas_estimation): +def test_ceil_internal_call(get_contract): code = """ @external def foo() -> int256: @@ -137,6 +137,6 @@ def bar() -> decimal: return 2.5 """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == 3 diff --git a/tests/functional/builtins/codegen/test_concat.py b/tests/functional/builtins/codegen/test_concat.py index 37bdaaaf7b..42d11dd062 100644 --- a/tests/functional/builtins/codegen/test_concat.py +++ b/tests/functional/builtins/codegen/test_concat.py @@ -1,4 +1,4 @@ -def test_concat(get_contract_with_gas_estimation): +def test_concat(get_contract): test_concat = """ @external def foo2(input1: Bytes[50], input2: Bytes[50]) -> Bytes[1000]: @@ -9,7 +9,7 @@ def foo3(input1: Bytes[50], input2: Bytes[50], input3: Bytes[50]) -> Bytes[1000] return concat(input1, input2, input3) """ - c = get_contract_with_gas_estimation(test_concat) + c = get_contract(test_concat) assert c.foo2(b"h", b"orse") == b"horse" assert c.foo2(b"h", b"") == b"h" assert c.foo2(b"", b"") == b"" @@ -24,7 +24,7 @@ def foo3(input1: Bytes[50], input2: Bytes[50], input3: Bytes[50]) -> Bytes[1000] print("Passed simple concat test") -def test_concat2(get_contract_with_gas_estimation): +def test_concat2(get_contract): test_concat2 = """ @external def foo(inp: Bytes[50]) -> Bytes[1000]: @@ -32,12 +32,12 @@ def foo(inp: Bytes[50]) -> Bytes[1000]: return concat(x, inp, x, inp, x, inp, x, inp, x, inp) """ - c = get_contract_with_gas_estimation(test_concat2) + c = get_contract(test_concat2) assert c.foo(b"horse" * 9 + b"vyper") == (b"horse" * 9 + b"vyper") * 10 print("Passed second concat test") -def test_crazy_concat_code(get_contract_with_gas_estimation): +def test_crazy_concat_code(get_contract): crazy_concat_code = """ y: Bytes[10] @@ -48,7 +48,7 @@ def krazykonkat(z: Bytes[10]) -> Bytes[25]: return concat(x, b" ", self.y, b" ", z) """ - c = get_contract_with_gas_estimation(crazy_concat_code) + c = get_contract(crazy_concat_code) assert c.krazykonkat(b"moose") == b"cow horse moose" @@ -119,7 +119,7 @@ def foo() -> int256: assert c.foo() == -1 -def test_concat_bytes32(get_contract_with_gas_estimation): +def test_concat_bytes32(get_contract): test_concat_bytes32 = """ @external def sandwich(inp: Bytes[100], inp2: bytes32) -> Bytes[164]: @@ -130,7 +130,7 @@ def fivetimes(inp: bytes32) -> Bytes[160]: return concat(inp, inp, inp, inp, inp) """ - c = get_contract_with_gas_estimation(test_concat_bytes32) + c = get_contract(test_concat_bytes32) assert c.sandwich(b"cow", b"\x35" * 32) == b"\x35" * 32 + b"cow" + b"\x35" * 32, c.sandwich( b"cow", b"\x35" * 32 ) # noqa: E501 @@ -143,7 +143,7 @@ def fivetimes(inp: bytes32) -> Bytes[160]: print("Passed concat bytes32 test") -def test_konkat_code(get_contract_with_gas_estimation): +def test_konkat_code(get_contract): konkat_code = """ ecks: bytes32 @@ -162,7 +162,7 @@ def hoo(x: bytes32, y: bytes32) -> Bytes[64]: return concat(x, y) """ - c = get_contract_with_gas_estimation(konkat_code) + c = get_contract(konkat_code) assert c.foo(b"\x35" * 32, b"\x00" * 32) == b"\x35" * 32 + b"\x00" * 32 assert c.goo(b"\x35" * 32, b"\x00" * 32) == b"\x35" * 32 + b"\x00" * 32 assert c.hoo(b"\x35" * 32, b"\x00" * 32) == b"\x35" * 32 + b"\x00" * 32 @@ -170,19 +170,19 @@ def hoo(x: bytes32, y: bytes32) -> Bytes[64]: print("Passed second concat tests") -def test_small_output(get_contract_with_gas_estimation): +def test_small_output(get_contract): code = """ @external def small_output(a: String[5], b: String[4]) -> String[9]: c: String[9] = concat(a, b) return c """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.small_output("abcde", "fghi") == "abcdefghi" assert c.small_output("", "") == "" -def test_small_bytes(get_contract_with_gas_estimation): +def test_small_bytes(get_contract): # TODO maybe use parametrization or hypothesis for the examples code = """ @external @@ -201,7 +201,7 @@ def small_bytes3(a: bytes4, b: bytes32) -> Bytes[36]: def small_bytes4(a: bytes8, b: Bytes[32], c: bytes8) -> Bytes[48]: return concat(a, b, c) """ - contract = get_contract_with_gas_estimation(code) + contract = get_contract(code) i = 0 diff --git a/tests/functional/builtins/codegen/test_convert.py b/tests/functional/builtins/codegen/test_convert.py index 423bee744d..9947223e75 100644 --- a/tests/functional/builtins/codegen/test_convert.py +++ b/tests/functional/builtins/codegen/test_convert.py @@ -26,8 +26,6 @@ TEST_TYPES = BASE_TYPES | {BytesT(32)} | {StringT(32)} -ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" - # decimal increment, aka smallest decimal > 0 DECIMAL_EPSILON = Decimal(1) / DECIMAL_DIVISOR @@ -429,13 +427,8 @@ def _vyper_literal(val, typ): @pytest.mark.parametrize("i_typ,o_typ,val", generate_passing_cases()) @pytest.mark.fuzzing -def test_convert_passing( - get_contract_with_gas_estimation, assert_compile_failed, i_typ, o_typ, val -): +def test_convert_passing(get_contract, assert_compile_failed, i_typ, o_typ, val): expected_val = _py_convert(val, i_typ, o_typ) - if isinstance(o_typ, AddressT) and expected_val == "0x" + "00" * 20: - # web3 has special formatter for zero address - expected_val = None if isinstance(o_typ, DecimalT): expected_val = decimal_to_int(expected_val) @@ -450,7 +443,6 @@ def test_convert() -> {o_typ}: return convert({_vyper_literal(val, i_typ)}, {o_typ}) """ - c1_exception = None skip_c1 = False # Skip bytes20 literals when there is ambiguity with `address` since address takes precedence. @@ -462,10 +454,8 @@ def test_convert() -> {o_typ}: if isinstance(i_typ, AddressT) and o_typ == BYTES20_T and val == val.lower(): skip_c1 = True - if c1_exception is not None: - assert_compile_failed(lambda: get_contract_with_gas_estimation(contract_1), c1_exception) - elif not skip_c1: - c1 = get_contract_with_gas_estimation(contract_1) + if not skip_c1: + c1 = get_contract(contract_1) assert c1.test_convert() == expected_val contract_2 = f""" @@ -474,7 +464,7 @@ def test_input_convert(x: {i_typ}) -> {o_typ}: return convert(x, {o_typ}) """ - c2 = get_contract_with_gas_estimation(contract_2) + c2 = get_contract(contract_2) assert c2.test_input_convert(input_val) == expected_val contract_3 = f""" @@ -486,7 +476,7 @@ def test_state_variable_convert() -> {o_typ}: return convert(self.bar, {o_typ}) """ - c3 = get_contract_with_gas_estimation(contract_3) + c3 = get_contract(contract_3) assert c3.test_state_variable_convert() == expected_val contract_4 = f""" @@ -496,13 +486,13 @@ def test_memory_variable_convert(x: {i_typ}) -> {o_typ}: return convert(y, {o_typ}) """ - c4 = get_contract_with_gas_estimation(contract_4) + c4 = get_contract(contract_4) assert c4.test_memory_variable_convert(input_val) == expected_val @pytest.mark.parametrize("typ", ["uint8", "int128", "int256", "uint256"]) @pytest.mark.parametrize("val", [1, 2, 2**128, 2**256 - 1, 2**256 - 2]) -def test_flag_conversion(get_contract_with_gas_estimation, assert_compile_failed, val, typ): +def test_flag_conversion(get_contract, assert_compile_failed, val, typ): roles = "\n ".join([f"ROLE_{i}" for i in range(256)]) contract = f""" flag Roles: @@ -517,18 +507,16 @@ def bar(a: uint256) -> Roles: return convert(a, Roles) """ if typ == "uint256": - c = get_contract_with_gas_estimation(contract) + c = get_contract(contract) assert c.foo(val) == val assert c.bar(val) == val else: - assert_compile_failed(lambda: get_contract_with_gas_estimation(contract), TypeMismatch) + assert_compile_failed(lambda: get_contract(contract), TypeMismatch) @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, tx_failed, val, typ -): +def test_flag_conversion_2(get_contract, assert_compile_failed, tx_failed, val, typ): contract = f""" flag Status: STARTED @@ -540,7 +528,7 @@ def foo(a: {typ}) -> Status: return convert(a, Status) """ if typ == "uint256": - c = get_contract_with_gas_estimation(contract) + c = get_contract(contract) lo, hi = int_bounds(signed=False, bits=3) if lo <= val <= hi: assert c.foo(val) == val @@ -548,7 +536,7 @@ def foo(a: {typ}) -> Status: with tx_failed(): c.foo(val) else: - assert_compile_failed(lambda: get_contract_with_gas_estimation(contract), TypeMismatch) + assert_compile_failed(lambda: get_contract(contract), TypeMismatch) # uint256 conversion is currently valid due to type inference on literals @@ -648,7 +636,7 @@ def foo() -> {typ}: @pytest.mark.parametrize("n", range(1, 33)) -def test_Bytes_to_bytes(get_contract, n): +def test_Bytes_to_bytes(get_contract, n: int): t_bytes = f"bytes{n}" t_Bytes = f"Bytes[{n}]" @@ -676,9 +664,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, tx_failed, i_typ, o_typ, val -): +def test_conversion_failures(get_contract, assert_compile_failed, tx_failed, i_typ, o_typ, val): """ Test multiple contracts and check for a specific exception. If no exception is provided, a runtime revert is expected (e.g. clamping). @@ -709,7 +695,7 @@ def foo() -> {o_typ}: # skip_c1 = True if not skip_c1: - assert_compile_failed(lambda: get_contract_with_gas_estimation(contract_1), c1_exception) + assert_compile_failed(lambda: get_contract(contract_1), c1_exception) contract_2 = f""" @external @@ -718,7 +704,7 @@ def foo(): foobar: {o_typ} = convert(bar, {o_typ}) """ - c2 = get_contract_with_gas_estimation(contract_2) + c2 = get_contract(contract_2) with tx_failed(): c2.foo() @@ -728,7 +714,7 @@ def foo(bar: {i_typ}) -> {o_typ}: return convert(bar, {o_typ}) """ - c3 = get_contract_with_gas_estimation(contract_3) + c3 = get_contract(contract_3) input_val = val if isinstance(i_typ, DecimalT): input_val = decimal_to_int(input_val) diff --git a/tests/functional/builtins/codegen/test_create_functions.py b/tests/functional/builtins/codegen/test_create_functions.py index ce832cd3cb..14d81bbd13 100644 --- a/tests/functional/builtins/codegen/test_create_functions.py +++ b/tests/functional/builtins/codegen/test_create_functions.py @@ -4,6 +4,7 @@ from hexbytes import HexBytes import vyper.ir.compile_ir as compile_ir +from tests.utils import ZERO_ADDRESS from vyper.codegen.ir_node import IRnode from vyper.compiler.settings import OptimizationLevel from vyper.utils import EIP_170_LIMIT, ERC5202_PREFIX, checksum_encode, keccak256 @@ -42,7 +43,7 @@ def test() -> address: assert c.test() == checksum_encode("0x" + expected_create_address.hex()) -def test_create_minimal_proxy_to_call(get_contract, w3): +def test_create_minimal_proxy_to_call(get_contract): code = """ interface SubContract: def hello() -> Bytes[100]: view @@ -66,11 +67,11 @@ def test2() -> Bytes[100]: c = get_contract(code) assert c.hello() == b"hello world!" - c.test(transact={}) + c.test() assert c.test2() == b"hello world!" -def test_minimal_proxy_exception(w3, get_contract, tx_failed): +def test_minimal_proxy_exception(env, get_contract, tx_failed): code = """ interface SubContract: def hello(a: uint256) -> Bytes[100]: view @@ -95,19 +96,18 @@ def test2(a: uint256) -> Bytes[100]: c = get_contract(code) assert c.hello(1) == b"hello world!" - c.test(transact={}) + c.test() assert c.test2(1) == b"hello world!" - with tx_failed(): + with tx_failed(exc_text="invaliddddd"): c.test2(0) - GAS_SENT = 30000 - tx_hash = c.test2(0, transact={"gas": GAS_SENT}) - - receipt = w3.eth.get_transaction_receipt(tx_hash) + gas_sent = 30000 + with tx_failed(exc_text="invaliddddd"): + c.test2(0, gas=gas_sent) - assert receipt["status"] == 0 - assert receipt["gasUsed"] < GAS_SENT + # check we issued `revert`, which does not consume all gas + assert env.last_result.gas_used < gas_sent @pytest.mark.parametrize("revert_on_failure", [True, False, None]) @@ -127,17 +127,15 @@ def test(_salt: bytes32) -> address: c = get_contract(code) salt = keccak(b"vyper") - assert HexBytes(c.test(salt)) == create2_address_of( - c.address, salt, eip1167_initcode(c.address) - ) + result = c.test(salt) + assert HexBytes(result) == create2_address_of(c.address, salt, eip1167_initcode(c.address)) - c.test(salt, transact={}) # revert on collision if revert_on_failure is False: - assert not c.test(salt) + assert c.test(salt) == ZERO_ADDRESS else: with tx_failed(): - c.test(salt, transact={}) + c.test(salt) # test blueprints with various prefixes - 0xfe would block calls to the blueprint @@ -147,7 +145,7 @@ def test(_salt: bytes32) -> address: def test_create_from_blueprint( get_contract, deploy_blueprint_for, - w3, + env, keccak, create2_address_of, tx_failed, @@ -178,16 +176,16 @@ def test2(target: address, salt: bytes32): # deploy a foo, so we can compare its bytecode with factory deployed version foo_contract = get_contract(code) - expected_runtime_code = w3.eth.get_code(foo_contract.address) + expected_runtime_code = env.get_code(foo_contract.address) f, FooContract = deploy_blueprint_for(code, initcode_prefix=blueprint_prefix) d = get_contract(deployer_code) - d.test(f.address, transact={}) + d.test(f.address) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert env.get_code(test.address) == expected_runtime_code assert test.foo() == 123 # extcodesize check @@ -197,14 +195,14 @@ def test2(target: address, salt: bytes32): # now same thing but with create2 salt = keccak(b"vyper") - d.test2(f.address, salt, transact={}) + d.test2(f.address, salt) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert env.get_code(test.address) == expected_runtime_code assert test.foo() == 123 # check if the create2 address matches our offchain calculation - initcode = w3.eth.get_code(f.address) + initcode = env.get_code(f.address) initcode = initcode[len(blueprint_prefix) :] # strip the prefix assert HexBytes(test.address) == create2_address_of(d.address, salt, initcode) @@ -219,7 +217,7 @@ def test2(target: address, salt: bytes32): # test blueprints with 0xfe7100 prefix, which is the EIP 5202 standard. # code offset by default should be 3 here. def test_create_from_blueprint_default_offset( - get_contract, deploy_blueprint_for, w3, keccak, create2_address_of, tx_failed + get_contract, deploy_blueprint_for, env, keccak, create2_address_of, tx_failed ): code = """ @external @@ -241,16 +239,16 @@ def test2(target: address, salt: bytes32): # deploy a foo so we can compare its bytecode with factory deployed version foo_contract = get_contract(code) - expected_runtime_code = w3.eth.get_code(foo_contract.address) + expected_runtime_code = env.get_code(foo_contract.address) f, FooContract = deploy_blueprint_for(code) d = get_contract(deployer_code) - d.test(f.address, transact={}) + d.test(f.address) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert env.get_code(test.address) == expected_runtime_code assert test.foo() == 123 # extcodesize check @@ -260,14 +258,14 @@ def test2(target: address, salt: bytes32): # now same thing but with create2 salt = keccak(b"vyper") - d.test2(f.address, salt, transact={}) + d.test2(f.address, salt) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert env.get_code(test.address) == expected_runtime_code assert test.foo() == 123 # check if the create2 address matches our offchain calculation - initcode = w3.eth.get_code(f.address) + initcode = env.get_code(f.address) initcode = initcode[len(ERC5202_PREFIX) :] # strip the prefix assert HexBytes(test.address) == create2_address_of(d.address, salt, initcode) @@ -277,7 +275,7 @@ def test2(target: address, salt: bytes32): def test_create_from_blueprint_bad_code_offset( - get_contract, get_contract_from_ir, deploy_blueprint_for, w3, tx_failed + get_contract, get_contract_from_ir, deploy_blueprint_for, env, tx_failed ): deployer_code = """ BLUEPRINT: immutable(address) @@ -301,11 +299,8 @@ def test(code_ofst: uint256) -> address: compile_ir.compile_to_assembly(ir, optimize=OptimizationLevel.NONE) ) # manually deploy the bytecode - c = w3.eth.contract(abi=[], bytecode=bytecode) - deploy_transaction = c.constructor() - tx_info = {"from": w3.eth.accounts[0], "value": 0, "gasPrice": 0} - tx_hash = deploy_transaction.transact(tx_info) - blueprint_address = w3.eth.get_transaction_receipt(tx_hash)["contractAddress"] + c = env.deploy(abi=[], bytecode=bytecode) + blueprint_address = c.address d = get_contract(deployer_code, blueprint_address) @@ -326,7 +321,7 @@ def test(code_ofst: uint256) -> address: # test create_from_blueprint with args def test_create_from_blueprint_args( - get_contract, deploy_blueprint_for, w3, keccak, create2_address_of, tx_failed + get_contract, deploy_blueprint_for, env, keccak, create2_address_of, tx_failed ): code = """ struct Bar: @@ -380,18 +375,18 @@ def should_fail(target: address, arg1: String[129], arg2: Bar): # deploy a foo so we can compare its bytecode with factory deployed version foo_contract = get_contract(code, FOO, BAR) - expected_runtime_code = w3.eth.get_code(foo_contract.address) + expected_runtime_code = env.get_code(foo_contract.address) f, FooContract = deploy_blueprint_for(code) d = get_contract(deployer_code) - initcode = w3.eth.get_code(f.address)[3:] + initcode = env.get_code(f.address)[3:] - d.test(f.address, FOO, BAR, transact={}) + d.test(f.address, FOO, BAR) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert env.get_code(test.address) == expected_runtime_code assert test.foo() == FOO assert test.bar() == BAR @@ -401,25 +396,25 @@ def should_fail(target: address, arg1: String[129], arg2: Bar): # now same thing but with create2 salt = keccak(b"vyper") - d.test2(f.address, FOO, BAR, salt, transact={}) + d.test2(f.address, FOO, BAR, salt) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert env.get_code(test.address) == expected_runtime_code assert test.foo() == FOO assert test.bar() == BAR encoded_args = abi.encode("(string,(string))", (FOO, BAR)) assert HexBytes(test.address) == create2_address_of(d.address, salt, initcode + encoded_args) - d.test3(f.address, encoded_args, transact={}) + d.test3(f.address, encoded_args) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert env.get_code(test.address) == expected_runtime_code assert test.foo() == FOO assert test.bar() == BAR - d.test4(f.address, encoded_args, keccak(b"test4"), transact={}) + d.test4(f.address, encoded_args, keccak(b"test4")) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert env.get_code(test.address) == expected_runtime_code assert test.foo() == FOO assert test.bar() == BAR @@ -432,7 +427,7 @@ def should_fail(target: address, arg1: String[129], arg2: Bar): # but creating a contract with different args is ok FOO = "bar" - d.test2(f.address, FOO, BAR, salt, transact={}) + d.test2(f.address, FOO, BAR, salt) # just for kicks assert FooContract(d.created_address()).foo() == FOO assert FooContract(d.created_address()).bar() == BAR @@ -443,11 +438,13 @@ def should_fail(target: address, arg1: String[129], arg2: Bar): sig = keccak("should_fail(address,string,(string))".encode()).hex()[:10] encoded = abi.encode("(address,string,(string))", (f.address, FOO, BAR)).hex() with tx_failed(): - w3.eth.send_transaction({"to": d.address, "data": f"{sig}{encoded}"}) + env.message_call(d.address, env.deployer, f"{sig}{encoded}") @pytest.mark.parametrize("revert_on_failure", [True, False, None]) -def test_create_copy_of(get_contract, w3, keccak, create2_address_of, tx_failed, revert_on_failure): +def test_create_copy_of( + get_contract, env, keccak, create2_address_of, tx_failed, revert_on_failure +): revert_arg = "" if revert_on_failure is None else f", revert_on_failure={revert_on_failure}" code = f""" created_address: public(address) @@ -475,29 +472,26 @@ def test2(target: address, salt: bytes32) -> address: """ c = get_contract(code) - bytecode = w3.eth.get_code(c.address) + bytecode = env.get_code(c.address) - c.test(c.address, transact={}) + c.test(c.address) test1 = c.created_address() - assert w3.eth.get_code(test1) == bytecode + assert env.get_code(test1) == bytecode # extcodesize check with tx_failed(): c.test("0x" + "00" * 20) - # test1 = c.test(b"\x01") - # assert w3.eth.get_code(test1) == b"\x01" - salt = keccak(b"vyper") - c.test2(c.address, salt, transact={}) + c.test2(c.address, salt) test2 = c.created_address() - assert w3.eth.get_code(test2) == bytecode + assert env.get_code(test2) == bytecode assert HexBytes(test2) == create2_address_of(c.address, salt, vyper_initcode(bytecode)) # can't create2 where contract already exists if revert_on_failure is False: - assert not c.test2(c.address, salt) + assert c.test2(c.address, salt) == ZERO_ADDRESS else: with tx_failed(): c.test2(c.address, salt) @@ -509,7 +503,7 @@ def test2(target: address, salt: bytes32) -> address: # changes in calling convention and memory layout @pytest.mark.parametrize("blueprint_prefix", [b"", b"\xfe", b"\xfe\71\x00"]) def test_create_from_blueprint_complex_value( - get_contract, deploy_blueprint_for, w3, blueprint_prefix + get_contract, deploy_blueprint_for, env, blueprint_prefix ): # check msize allocator does not get trampled by value= kwarg code = """ @@ -551,22 +545,23 @@ def test(target: address): """ foo_contract = get_contract(code, 12) - expected_runtime_code = w3.eth.get_code(foo_contract.address) + expected_runtime_code = env.get_code(foo_contract.address) f, FooContract = deploy_blueprint_for(code, initcode_prefix=blueprint_prefix) d = get_contract(deployer_code) - d.test(f.address, transact={"value": 3}) + env.set_balance(env.deployer, 3) + d.test(f.address, value=3) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert env.get_code(test.address) == expected_runtime_code assert test.foo() == 12 @pytest.mark.parametrize("blueprint_prefix", [b"", b"\xfe", b"\xfe\71\x00"]) def test_create_from_blueprint_complex_salt_raw_args( - get_contract, deploy_blueprint_for, w3, blueprint_prefix + get_contract, deploy_blueprint_for, env, blueprint_prefix ): # test msize allocator does not get trampled by salt= kwarg code = """ @@ -609,22 +604,22 @@ def test(target: address): """ foo_contract = get_contract(code, 12) - expected_runtime_code = w3.eth.get_code(foo_contract.address) + expected_runtime_code = env.get_code(foo_contract.address) f, FooContract = deploy_blueprint_for(code, initcode_prefix=blueprint_prefix) d = get_contract(deployer_code) - d.test(f.address, transact={}) + d.test(f.address) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert env.get_code(test.address) == expected_runtime_code assert test.foo() == 12 @pytest.mark.parametrize("blueprint_prefix", [b"", b"\xfe", b"\xfe\71\x00"]) def test_create_from_blueprint_complex_salt_no_constructor_args( - get_contract, deploy_blueprint_for, w3, blueprint_prefix + get_contract, deploy_blueprint_for, env, blueprint_prefix ): # test msize allocator does not get trampled by salt= kwarg code = """ @@ -657,20 +652,20 @@ def test(target: address): """ foo_contract = get_contract(code) - expected_runtime_code = w3.eth.get_code(foo_contract.address) + expected_runtime_code = env.get_code(foo_contract.address) f, FooContract = deploy_blueprint_for(code, initcode_prefix=blueprint_prefix) d = get_contract(deployer_code) - d.test(f.address, transact={}) + d.test(f.address) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert env.get_code(test.address) == expected_runtime_code assert test.foo() == 12 -def test_create_copy_of_complex_kwargs(get_contract, w3): +def test_create_copy_of_complex_kwargs(get_contract, env): # test msize allocator does not get trampled by salt= kwarg complex_salt = """ created_address: public(address) @@ -686,10 +681,11 @@ def test(target: address) -> address: """ c = get_contract(complex_salt) - bytecode = w3.eth.get_code(c.address) - c.test(c.address, transact={}) - test1 = c.created_address() - assert w3.eth.get_code(test1) == bytecode + bytecode = env.get_code(c.address) + assert bytecode # Sanity check + c.test(c.address) + test1 = c.address + assert env.get_code(test1) == bytecode # test msize allocator does not get trampled by value= kwarg complex_value = """ @@ -705,8 +701,9 @@ def test(target: address) -> address: """ c = get_contract(complex_value) - bytecode = w3.eth.get_code(c.address) + bytecode = env.get_code(c.address) + env.set_balance(env.deployer, 2) - c.test(c.address, transact={"value": 2}) - test1 = c.created_address() - assert w3.eth.get_code(test1) == bytecode + c.test(c.address, value=2) + test1 = c.address + assert env.get_code(test1) == bytecode diff --git a/tests/functional/builtins/codegen/test_ec.py b/tests/functional/builtins/codegen/test_ec.py index d90d9d0afb..e81b8c2faf 100644 --- a/tests/functional/builtins/codegen/test_ec.py +++ b/tests/functional/builtins/codegen/test_ec.py @@ -15,7 +15,7 @@ curve_order = 21888242871839275222246405745257275088548364400416034343698204186575808495617 -def test_ecadd(get_contract_with_gas_estimation): +def test_ecadd(get_contract): ecadder = """ x3: uint256[2] y3: uint256[2] @@ -37,7 +37,7 @@ def _ecadd3(x: uint256[2], y: uint256[2]) -> uint256[2]: return ecadd(self.x3, self.y3) """ - c = get_contract_with_gas_estimation(ecadder) + c = get_contract(ecadder) assert c._ecadd(G1, G1) == G1_times_two assert c._ecadd2(G1, G1_times_two) == G1_times_three @@ -45,7 +45,7 @@ def _ecadd3(x: uint256[2], y: uint256[2]) -> uint256[2]: assert c._ecadd3(G1, negative_G1) == [0, 0] -def test_ecadd_internal_call(get_contract_with_gas_estimation): +def test_ecadd_internal_call(get_contract): code = """ @internal def a() -> uint256[2]: @@ -55,11 +55,11 @@ def a() -> uint256[2]: def foo() -> uint256[2]: return ecadd([1, 2], self.a()) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == G1_times_two -def test_ecadd_ext_call(w3, side_effects_contract, assert_side_effects_invoked, get_contract): +def test_ecadd_ext_call(side_effects_contract, assert_side_effects_invoked, get_contract): code = """ interface Foo: def foo(x: uint256[2]) -> uint256[2]: payable @@ -73,10 +73,10 @@ def foo(a: Foo) -> uint256[2]: assert c2.foo(c1.address) == G1_times_two - assert_side_effects_invoked(c1, lambda: c2.foo(c1.address, transact={})) + assert_side_effects_invoked(c1, lambda: c2.foo(c1.address)) -def test_ecadd_evaluation_order(get_contract_with_gas_estimation): +def test_ecadd_evaluation_order(get_contract): code = """ x: uint256[2] @@ -92,11 +92,11 @@ def foo() -> bool: b: uint256[2] = ecadd(self.x, self.bar()) return a[0] == b[0] and a[1] == b[1] """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() is True -def test_ecmul(get_contract_with_gas_estimation): +def test_ecmul(get_contract): ecmuller = """ x3: uint256[2] y3: uint256 @@ -118,7 +118,7 @@ def _ecmul3(x: uint256[2], y: uint256) -> uint256[2]: return ecmul(self.x3, self.y3) """ - c = get_contract_with_gas_estimation(ecmuller) + c = get_contract(ecmuller) assert c._ecmul(G1, 0) == [0, 0] assert c._ecmul(G1, 1) == G1 @@ -127,7 +127,7 @@ def _ecmul3(x: uint256[2], y: uint256) -> uint256[2]: assert c._ecmul(G1, curve_order) == [0, 0] -def test_ecmul_internal_call(get_contract_with_gas_estimation): +def test_ecmul_internal_call(get_contract): code = """ @internal def a() -> uint256: @@ -137,11 +137,11 @@ def a() -> uint256: def foo() -> uint256[2]: return ecmul([1, 2], self.a()) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == G1_times_three -def test_ecmul_ext_call(w3, side_effects_contract, assert_side_effects_invoked, get_contract): +def test_ecmul_ext_call(side_effects_contract, assert_side_effects_invoked, get_contract): code = """ interface Foo: def foo(x: uint256) -> uint256: payable @@ -155,10 +155,10 @@ def foo(a: Foo) -> uint256[2]: assert c2.foo(c1.address) == G1_times_three - assert_side_effects_invoked(c1, lambda: c2.foo(c1.address, transact={})) + assert_side_effects_invoked(c1, lambda: c2.foo(c1.address)) -def test_ecmul_evaluation_order(get_contract_with_gas_estimation): +def test_ecmul_evaluation_order(get_contract): code = """ x: uint256[2] @@ -174,5 +174,5 @@ def foo() -> bool: b: uint256[2] = ecmul(self.x, self.bar()) return a[0] == b[0] and a[1] == b[1] """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() is True diff --git a/tests/functional/builtins/codegen/test_ecrecover.py b/tests/functional/builtins/codegen/test_ecrecover.py index ce24868afe..8db51fdd07 100644 --- a/tests/functional/builtins/codegen/test_ecrecover.py +++ b/tests/functional/builtins/codegen/test_ecrecover.py @@ -1,8 +1,10 @@ from eth_account import Account from eth_account._utils.signing import to_bytes32 +from tests.utils import ZERO_ADDRESS -def test_ecrecover_test(get_contract_with_gas_estimation): + +def test_ecrecover_test(get_contract): ecrecover_test = """ @external def test_ecrecover(h: bytes32, v: uint8, r: bytes32, s: bytes32) -> address: @@ -28,7 +30,7 @@ def test_ecrecover_uints2() -> address: """ - c = get_contract_with_gas_estimation(ecrecover_test) + c = get_contract(ecrecover_test) h = b"\x35" * 32 local_account = Account.from_key(b"\x46" * 32) @@ -56,8 +58,7 @@ def test_ecrecover(hash: bytes32, v: uint8, r: uint256) -> address: hash_ = bytes(i for i in range(32)) v = 0 # invalid v! ecrecover precompile will not write to output buffer r = 0 - # note web3.py decoding of 0x000..00 address is None. - assert c.test_ecrecover(hash_, v, r) is None + assert c.test_ecrecover(hash_, v, r) == ZERO_ADDRESS # slightly more subtle example: get_v() stomps memory location 0, diff --git a/tests/functional/builtins/codegen/test_empty.py b/tests/functional/builtins/codegen/test_empty.py index 74c8e765ae..c8e6fc374e 100644 --- a/tests/functional/builtins/codegen/test_empty.py +++ b/tests/functional/builtins/codegen/test_empty.py @@ -97,8 +97,8 @@ def foo() -> bool: """, ], ) -def test_empty_basic_type(contract, get_contract_with_gas_estimation): - c = get_contract_with_gas_estimation(contract) +def test_empty_basic_type(contract, get_contract): + c = get_contract(contract) c.foo() @@ -223,8 +223,8 @@ def foo(): """, ], ) -def test_empty_basic_type_lists(contract, get_contract_with_gas_estimation): - c = get_contract_with_gas_estimation(contract) +def test_empty_basic_type_lists(contract, get_contract): + c = get_contract(contract) c.foo() @@ -259,11 +259,11 @@ def foo(): """, ], ) -def test_clear_literals(contract, assert_compile_failed, get_contract_with_gas_estimation): - assert_compile_failed(lambda: get_contract_with_gas_estimation(contract), Exception) +def test_clear_literals(contract, assert_compile_failed, get_contract): + assert_compile_failed(lambda: get_contract(contract), Exception) -def test_empty_bytes(get_contract_with_gas_estimation): +def test_empty_bytes(get_contract): code = """ foobar: Bytes[5] @@ -278,7 +278,7 @@ def foo() -> (Bytes[5], Bytes[5]): return (self.foobar, bar) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) a, b = c.foo() assert a == b == b"" @@ -297,13 +297,13 @@ def foo() -> (Bytes[5], Bytes[5]): ], ) @pytest.mark.parametrize("op", ["==", "!="]) -def test_empty_string_comparison(get_contract_with_gas_estimation, length, value, result, op): +def test_empty_string_comparison(get_contract, length, value, result, op): contract = f""" @external def foo(xs: String[{length}]) -> bool: return xs {op} empty(String[{length}]) """ - c = get_contract_with_gas_estimation(contract) + c = get_contract(contract) if op == "==": assert c.foo(value) == result elif op == "!=": @@ -324,20 +324,20 @@ def foo(xs: String[{length}]) -> bool: ], ) @pytest.mark.parametrize("op", ["==", "!="]) -def test_empty_bytes_comparison(get_contract_with_gas_estimation, length, value, result, op): +def test_empty_bytes_comparison(get_contract, length, value, result, op): contract = f""" @external def foo(xs: Bytes[{length}]) -> bool: return empty(Bytes[{length}]) {op} xs """ - c = get_contract_with_gas_estimation(contract) + c = get_contract(contract) if op == "==": assert c.foo(value) == result elif op == "!=": assert c.foo(value) != result -def test_empty_struct(get_contract_with_gas_estimation): +def test_empty_struct(get_contract): code = """ struct FOOBAR: a: int128 @@ -386,11 +386,11 @@ def foo(): assert bar.f == empty(address) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) c.foo() -def test_empty_dynarray(get_contract_with_gas_estimation): +def test_empty_dynarray(get_contract): code = """ foobar: DynArray[uint256, 10] bar: uint256 @@ -407,13 +407,13 @@ def foo(): assert self.bar == 1 """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) c.foo() # param empty not working yet @pytest.mark.xfail -def test_param_empty(get_contract_with_gas_estimation): +def test_param_empty(get_contract): code = """ interface Mirror: # reuse the contract for this test by compiling two copies of it @@ -447,8 +447,8 @@ def pub3(x: address) -> bool: self.write_junk_to_memory() return staticcall Mirror(x).test_empty(empty(int128[111]), empty(Bytes[1024]), empty(Bytes[31])) """ - c = get_contract_with_gas_estimation(code) - mirror = get_contract_with_gas_estimation(code) + c = get_contract(code) + mirror = get_contract(code) assert c.test_empty([0] * 111, b"", b"") assert c.pub2() @@ -457,7 +457,7 @@ def pub3(x: address) -> bool: # return empty not working yet @pytest.mark.xfail -def test_return_empty(get_contract_with_gas_estimation): +def test_return_empty(get_contract): code = """ struct X: foo: int128 @@ -497,16 +497,16 @@ def e() -> X: self.write_junk_to_memory() return empty(X) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.a() == 0 - assert c.b() == [0] * 5 - assert c.c() == [[0] * 5] * 5 + assert c.b() == (0) * 5 + assert c.c() == ([0] * 5) * 5 assert c.d() == b"" assert c.e() == (0, "0x" + "0" * 40, 0x0, [0]) -def test_map_clear(get_contract_with_gas_estimation): +def test_map_clear(get_contract): code = """ big_storage: HashMap[bytes32, bytes32] @@ -523,19 +523,19 @@ def delete(key: bytes32): self.big_storage[key] = empty(bytes32) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) key = b"test".ljust(32) val = b"value".ljust(32) assert c.get(key) == b"\x00" * 32 - c.set(key, val, transact={}) + c.set(key, val) assert c.get(key)[:5] == b"value" - c.delete(key, transact={}) + c.delete(key) assert c.get(key) == b"\x00" * 32 -def test_map_clear_nested(get_contract_with_gas_estimation): +def test_map_clear_nested(get_contract): code = """ big_storage: HashMap[bytes32, HashMap[bytes32, bytes32]] @@ -552,20 +552,20 @@ def delete(key1: bytes32, key2: bytes32): self.big_storage[key1][key2] = empty(bytes32) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) key1 = b"test1".ljust(32) key2 = b"test2".ljust(32) val = b"value".ljust(32) assert c.get(key1, key2) == b"\x00" * 32 - c.set(key1, key2, val, transact={}) + c.set(key1, key2, val) assert c.get(key1, key2)[:5] == b"value" - c.delete(key1, key2, transact={}) + c.delete(key1, key2) assert c.get(key1, key2) == b"\x00" * 32 -def test_map_clear_struct(get_contract_with_gas_estimation): +def test_map_clear_struct(get_contract): code = """ struct X: a: int128 @@ -586,13 +586,13 @@ def delete(): self.structmap[123] = empty(X) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) - assert c.get() == [0, 0] - c.set(transact={}) - assert c.get() == [333, 444] - c.delete(transact={}) - assert c.get() == [0, 0] + assert c.get() == (0, 0) + c.set() + assert c.get() == (333, 444) + c.delete() + assert c.get() == (0, 0) @pytest.mark.parametrize( @@ -622,20 +622,20 @@ def test_clear_typecheck(contract, get_contract, assert_compile_failed): @pytest.mark.parametrize( "a,b,expected", [ - ("empty(Bytes[65])", "b'hello'", [b"hello", b""]), - ("b'hello'", "empty(Bytes[33])", [b"", b"hello"]), + ("empty(Bytes[65])", "b'hello'", (b"hello", b"")), + ("b'hello'", "empty(Bytes[33])", (b"", b"hello")), ( "empty(Bytes[65])", "b'thirty three bytes long baby!!!!!'", - [b"thirty three bytes long baby!!!!!", b""], + (b"thirty three bytes long baby!!!!!", b""), ), ( "b'thirty three bytes long baby!!!aathirty three bytes long baby!!!a'", "b'thirty three bytes long baby!!!aa'", - [ + ( b"thirty three bytes long baby!!!aa", b"thirty three bytes long baby!!!aathirty three bytes long baby!!!a", - ], + ), ), ], ) @@ -664,7 +664,7 @@ def bar(a: address) -> (uint256, Bytes[33], Bytes[65], uint256): c1 = get_contract(code_a) c2 = get_contract(code_b) - assert c2.bar(c1.address) == [12] + expected + [42] + assert c2.bar(c1.address) == (12, *expected, 42) def test_empty_array_in_event_logging(get_contract, get_logs): @@ -688,7 +688,8 @@ def foo(): """ c = get_contract(code) - log = get_logs(c.foo(transact={}), c, "MyLog")[0] + c.foo() + (log,) = get_logs(c, "MyLog") assert log.args.arg1 == b"hello" * 9 assert log.args.arg2 == [[0, 0], [0, 0], [0, 0]] diff --git a/tests/functional/builtins/codegen/test_extract32.py b/tests/functional/builtins/codegen/test_extract32.py index 96280ce862..8a92adbb07 100644 --- a/tests/functional/builtins/codegen/test_extract32.py +++ b/tests/functional/builtins/codegen/test_extract32.py @@ -4,7 +4,7 @@ @pytest.mark.parametrize("location", ["storage", "transient"]) -def test_extract32_extraction(tx_failed, get_contract_with_gas_estimation, location): +def test_extract32_extraction(tx_failed, get_contract, location): if location == "transient" and not version_check(begin="cancun"): pytest.skip( "Skipping test as storage_location is 'transient' and EVM version is pre-Cancun" @@ -32,7 +32,7 @@ def extrakt32_storage(index: uint256, inp: Bytes[100]) -> bytes32: return extract32(self.y, index) """ - c = get_contract_with_gas_estimation(extract32_code) + c = get_contract(extract32_code) test_cases = ( (b"c" * 31, 0), (b"c" * 32, 0), @@ -60,7 +60,7 @@ def extrakt32_storage(index: uint256, inp: Bytes[100]) -> bytes32: c.extrakt32(S, i) -def test_extract32_code(tx_failed, get_contract_with_gas_estimation): +def test_extract32_code(tx_failed, get_contract): extract32_code = """ @external def foo(inp: Bytes[32]) -> int128: @@ -83,7 +83,7 @@ def foq(inp: Bytes[32]) -> address: return extract32(inp, 0, output_type=address) """ - c = get_contract_with_gas_estimation(extract32_code) + c = get_contract(extract32_code) assert c.foo(b"\x00" * 30 + b"\x01\x01") == 257 assert c.bar(b"\x00" * 30 + b"\x01\x01") == 257 diff --git a/tests/functional/builtins/codegen/test_floor.py b/tests/functional/builtins/codegen/test_floor.py index 1063579531..4c5aeadf86 100644 --- a/tests/functional/builtins/codegen/test_floor.py +++ b/tests/functional/builtins/codegen/test_floor.py @@ -4,7 +4,7 @@ from tests.utils import decimal_to_int -def test_floor(get_contract_with_gas_estimation): +def test_floor(get_contract): code = """ x: decimal @@ -43,7 +43,7 @@ def fou() -> int256: c: decimal = a / b return floor(c) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.x_floor() == 504 assert c.foo() == 1 assert c.fop() == 1 @@ -53,7 +53,7 @@ def fou() -> int256: assert c.fou() == 3 -def test_floor_negative(get_contract_with_gas_estimation): +def test_floor_negative(get_contract): code = """ x: decimal @@ -99,7 +99,7 @@ def floor_param(p: decimal) -> int256: return floor(p) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.x_floor() == -505 assert c.foo() == -7 @@ -112,7 +112,7 @@ def floor_param(p: decimal) -> int256: assert c.floor_param(decimal_to_int("-0.0000000001")) == -1 -def test_floor_ext_call(w3, side_effects_contract, assert_side_effects_invoked, get_contract): +def test_floor_ext_call(side_effects_contract, assert_side_effects_invoked, get_contract): code = """ interface Foo: def foo(x: decimal) -> decimal: nonpayable @@ -127,10 +127,10 @@ def foo(a: Foo) -> int256: assert c2.foo(c1.address) == 2 - assert_side_effects_invoked(c1, lambda: c2.foo(c1.address, transact={})) + assert_side_effects_invoked(c1, lambda: c2.foo(c1.address)) -def test_floor_internal_call(get_contract_with_gas_estimation): +def test_floor_internal_call(get_contract): code = """ @external def foo() -> int256: @@ -141,6 +141,6 @@ def bar() -> decimal: return 2.5 """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == 2 diff --git a/tests/functional/builtins/codegen/test_is_contract.py b/tests/functional/builtins/codegen/test_is_contract.py index 5887763a93..b7654d2ea3 100644 --- a/tests/functional/builtins/codegen/test_is_contract.py +++ b/tests/functional/builtins/codegen/test_is_contract.py @@ -1,4 +1,4 @@ -def test_is_contract(w3, get_contract_with_gas_estimation): +def test_is_contract(env, get_contract): contract_1 = """ @external def foo(arg1: address) -> bool: @@ -11,9 +11,9 @@ def foo(arg1: address) -> bool: def foo(arg1: address) -> bool: return arg1.is_contract """ - a0, a1 = w3.eth.accounts[:2] - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + a0, a1 = env.accounts[:2] + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) assert c1.foo(c1.address) is True assert c1.foo(c2.address) is True diff --git a/tests/functional/builtins/codegen/test_keccak256.py b/tests/functional/builtins/codegen/test_keccak256.py index 3f73be551a..ac5da75d2e 100644 --- a/tests/functional/builtins/codegen/test_keccak256.py +++ b/tests/functional/builtins/codegen/test_keccak256.py @@ -1,7 +1,7 @@ from vyper.utils import hex_to_int -def test_hash_code(get_contract_with_gas_estimation, keccak): +def test_hash_code(get_contract, keccak): hash_code = """ @external def foo(inp: Bytes[100]) -> bytes32: @@ -16,7 +16,7 @@ def bar() -> bytes32: return keccak256("inp") """ - c = get_contract_with_gas_estimation(hash_code) + c = get_contract(hash_code) for inp in (b"", b"cow", b"s" * 31, b"\xff" * 32, b"\n" * 33, b"g" * 64, b"h" * 65): assert c.foo(inp) == keccak(inp) @@ -24,18 +24,18 @@ def bar() -> bytes32: assert c.foob() == keccak(b"inp") -def test_hash_code2(get_contract_with_gas_estimation): +def test_hash_code2(get_contract): hash_code2 = """ @external def foo(inp: Bytes[100]) -> bool: return keccak256(inp) == keccak256("badminton") """ - c = get_contract_with_gas_estimation(hash_code2) + c = get_contract(hash_code2) assert c.foo(b"badminto") is False assert c.foo(b"badminton") is True -def test_hash_code3(get_contract_with_gas_estimation): +def test_hash_code3(get_contract): hash_code3 = """ test: Bytes[100] @@ -61,22 +61,22 @@ def try32(inp: bytes32) -> bool: return keccak256(inp) == keccak256(self.test) """ - c = get_contract_with_gas_estimation(hash_code3) - c.set_test(b"", transact={}) + c = get_contract(hash_code3) + c.set_test(b"") assert c.tryy(b"") is True assert c.tryy_str("") is True assert c.trymem(b"") is True assert c.tryy(b"cow") is False - c.set_test(b"cow", transact={}) + c.set_test(b"cow") assert c.tryy(b"") is False assert c.tryy(b"cow") is True assert c.tryy_str("cow") is True - c.set_test(b"\x35" * 32, transact={}) + c.set_test(b"\x35" * 32) assert c.tryy(b"\x35" * 32) is True assert c.trymem(b"\x35" * 32) is True assert c.try32(b"\x35" * 32) is True assert c.tryy(b"\x35" * 33) is False - c.set_test(b"\x35" * 33, transact={}) + c.set_test(b"\x35" * 33) assert c.tryy(b"\x35" * 32) is False assert c.trymem(b"\x35" * 32) is False assert c.try32(b"\x35" * 32) is False @@ -85,7 +85,7 @@ def try32(inp: bytes32) -> bool: print("Passed KECCAK256 hash test") -def test_hash_constant_bytes32(get_contract_with_gas_estimation, keccak): +def test_hash_constant_bytes32(get_contract, keccak): hex_val = "0x1234567890123456789012345678901234567890123456789012345678901234" code = f""" FOO: constant(bytes32) = {hex_val} @@ -95,11 +95,11 @@ def foo() -> bytes32: x: bytes32 = BAR return x """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == keccak(hex_to_int(hex_val).to_bytes(32, "big")) -def test_hash_constant_string(get_contract_with_gas_estimation, keccak): +def test_hash_constant_string(get_contract, keccak): str_val = "0x1234567890123456789012345678901234567890123456789012345678901234" code = f""" FOO: constant(String[66]) = "{str_val}" @@ -109,5 +109,5 @@ def foo() -> bytes32: x: bytes32 = BAR return x """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == keccak(str_val.encode()) diff --git a/tests/functional/builtins/codegen/test_length.py b/tests/functional/builtins/codegen/test_length.py index e127405b90..fbb659f81c 100644 --- a/tests/functional/builtins/codegen/test_length.py +++ b/tests/functional/builtins/codegen/test_length.py @@ -1,7 +1,7 @@ import pytest -def test_test_length(get_contract_with_gas_estimation): +def test_test_length(get_contract): test_length = """ y: Bytes[10] @@ -12,13 +12,13 @@ def foo(inp: Bytes[10]) -> uint256: return len(inp) * 100 + len(x) * 10 + len(self.y) """ - c = get_contract_with_gas_estimation(test_length) + c = get_contract(test_length) assert c.foo(b"badminton") == 954, c.foo(b"badminton") print("Passed length test") @pytest.mark.parametrize("typ", ["DynArray[uint256, 50]", "Bytes[50]", "String[50]"]) -def test_zero_length(get_contract_with_gas_estimation, typ): +def test_zero_length(get_contract, typ): code = f""" @external def boo() -> uint256: @@ -26,5 +26,5 @@ def boo() -> uint256: return e """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.boo() == 0 diff --git a/tests/functional/builtins/codegen/test_method_id.py b/tests/functional/builtins/codegen/test_method_id.py index c6bcc78bc7..4286851ade 100644 --- a/tests/functional/builtins/codegen/test_method_id.py +++ b/tests/functional/builtins/codegen/test_method_id.py @@ -1,4 +1,4 @@ -def test_method_id_test(get_contract_with_gas_estimation): +def test_method_id_test(get_contract): method_id_test = """ @external def double(x: int128) -> int128: @@ -9,7 +9,7 @@ def returnten() -> int128: ans: Bytes[32] = raw_call(self, concat(method_id("double(int128)"), convert(5, bytes32)), gas=50000, max_outsize=32) # noqa: E501 return convert(convert(ans, bytes32), int128) """ - c = get_contract_with_gas_estimation(method_id_test) + c = get_contract(method_id_test) assert c.returnten() == 10 diff --git a/tests/functional/builtins/codegen/test_minmax.py b/tests/functional/builtins/codegen/test_minmax.py index e339547b37..5aaee963d5 100644 --- a/tests/functional/builtins/codegen/test_minmax.py +++ b/tests/functional/builtins/codegen/test_minmax.py @@ -4,7 +4,7 @@ from vyper.semantics.types import IntegerT -def test_minmax(get_contract_with_gas_estimation): +def test_minmax(get_contract): minmax_test = """ @external def foo() -> decimal: @@ -15,7 +15,7 @@ def goo() -> uint256: return min(3, 5) + max(40, 80) """ - c = get_contract_with_gas_estimation(minmax_test) + c = get_contract(minmax_test) assert c.foo() == decimal_to_int("58223.123") assert c.goo() == 83 @@ -23,7 +23,7 @@ def goo() -> uint256: @pytest.mark.parametrize("return_type", sorted(IntegerT.all())) -def test_minmax_var_and_literal_and_bultin(get_contract_with_gas_estimation, return_type): +def test_minmax_var_and_literal_and_bultin(get_contract, return_type): """ Tests to verify that min and max work as expected when a variable/literal and a literal are passed for all integer types. @@ -59,7 +59,7 @@ def both_builtins_max() -> {return_type}: def both_builtins_min() -> {return_type}: return min(min_value({return_type}), max_value({return_type})) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == hi assert c.bar() == lo assert c.both_literals_max() == hi @@ -68,7 +68,7 @@ def both_builtins_min() -> {return_type}: assert c.both_builtins_min() == lo -def test_max_var_uint256_literal_int128(get_contract_with_gas_estimation): +def test_max_var_uint256_literal_int128(get_contract): """ Tests to verify that max works as expected when a variable/literal uint256 and a literal int128 are passed. @@ -102,7 +102,7 @@ def baz() -> uint256: def both_literals() -> uint256: return max(2 ** 200, 2) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == 2**200 + 5 assert c.goo() == 2**200 + 5 assert c.bar() == 5 + 5 @@ -110,7 +110,7 @@ def both_literals() -> uint256: assert c.both_literals() == 2**200 -def test_min_var_uint256_literal_int128(get_contract_with_gas_estimation): +def test_min_var_uint256_literal_int128(get_contract): """ Tests to verify that max works as expected when a variable/literal uint256 and a literal int128 are passed. @@ -144,7 +144,7 @@ def baz() -> uint256: def both_literals() -> uint256: return min(2 ** 200, 2) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == 5 + 5 assert c.goo() == 5 + 5 assert c.bar() == 2 + 5 @@ -152,7 +152,7 @@ def both_literals() -> uint256: assert c.both_literals() == 2 -def test_minmax_var_uint256_var_int128(get_contract_with_gas_estimation, assert_compile_failed): +def test_minmax_var_uint256_var_int128(get_contract, assert_compile_failed): """ Tests to verify that max throws an error if a variable uint256 and a variable int128 are passed. @@ -166,7 +166,7 @@ def foo() -> uint256: b: int128 = 3 return max(a, b) """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code_1), TypeMismatch) + assert_compile_failed(lambda: get_contract(code_1), TypeMismatch) code_2 = """ @external @@ -175,7 +175,7 @@ def foo() -> uint256: b: int128 = 3 return max(b, a) """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code_2), TypeMismatch) + assert_compile_failed(lambda: get_contract(code_2), TypeMismatch) code_3 = """ @external @@ -184,7 +184,7 @@ def foo() -> uint256: b: int128 = 3 return min(a, b) """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code_3), TypeMismatch) + assert_compile_failed(lambda: get_contract(code_3), TypeMismatch) code_4 = """ @external @@ -193,12 +193,10 @@ def foo() -> uint256: b: int128 = 3 return min(b, a) """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code_4), TypeMismatch) + assert_compile_failed(lambda: get_contract(code_4), TypeMismatch) -def test_minmax_var_uint256_negative_int128( - get_contract_with_gas_estimation, tx_failed, assert_compile_failed -): +def test_minmax_var_uint256_negative_int128(get_contract, tx_failed, assert_compile_failed): from vyper.exceptions import TypeMismatch code_1 = """ @@ -207,7 +205,7 @@ def foo() -> uint256: a: uint256 = 2 ** 200 return max(a, -1) """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code_1), TypeMismatch) + assert_compile_failed(lambda: get_contract(code_1), TypeMismatch) code_2 = """ @external @@ -215,10 +213,10 @@ def foo() -> uint256: a: uint256 = 2 ** 200 return min(a, -1) """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code_2), TypeMismatch) + assert_compile_failed(lambda: get_contract(code_2), TypeMismatch) -def test_unsigned(get_contract_with_gas_estimation): +def test_unsigned(get_contract): code = """ @external def foo1() -> uint256: @@ -237,14 +235,14 @@ def foo4() -> uint256: return max(2**255, 0) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo1() == 0 assert c.foo2() == 0 assert c.foo3() == 2**255 assert c.foo4() == 2**255 -def test_signed(get_contract_with_gas_estimation): +def test_signed(get_contract): code = """ @external def foo1() -> int128: @@ -263,7 +261,7 @@ def foo4() -> int128: return max(max_value(int128), min_value(int128)) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo1() == -(2**127) assert c.foo2() == -(2**127) assert c.foo3() == 2**127 - 1 diff --git a/tests/functional/builtins/codegen/test_mulmod.py b/tests/functional/builtins/codegen/test_mulmod.py index 9af8cafaf8..1bb66ae598 100644 --- a/tests/functional/builtins/codegen/test_mulmod.py +++ b/tests/functional/builtins/codegen/test_mulmod.py @@ -1,11 +1,11 @@ -def test_uint256_mulmod(tx_failed, get_contract_with_gas_estimation): +def test_uint256_mulmod(tx_failed, get_contract): uint256_code = """ @external def _uint256_mulmod(x: uint256, y: uint256, z: uint256) -> uint256: return uint256_mulmod(x, y, z) """ - c = get_contract_with_gas_estimation(uint256_code) + c = get_contract(uint256_code) assert c._uint256_mulmod(3, 1, 2) == 1 assert c._uint256_mulmod(200, 3, 601) == 600 @@ -15,7 +15,7 @@ def _uint256_mulmod(x: uint256, y: uint256, z: uint256) -> uint256: c._uint256_mulmod(2, 2, 0) -def test_uint256_mulmod_complex(get_contract_with_gas_estimation): +def test_uint256_mulmod_complex(get_contract): modexper = """ @external def exponential(base: uint256, exponent: uint256, modulus: uint256) -> uint256: @@ -27,14 +27,12 @@ def exponential(base: uint256, exponent: uint256, modulus: uint256) -> uint256: return o """ - c = get_contract_with_gas_estimation(modexper) + c = get_contract(modexper) assert c.exponential(3, 5, 100) == 43 assert c.exponential(2, 997, 997) == 2 -def test_uint256_mulmod_ext_call( - w3, side_effects_contract, assert_side_effects_invoked, get_contract -): +def test_uint256_mulmod_ext_call(side_effects_contract, assert_side_effects_invoked, get_contract): code = """ interface Foo: def foo(x: uint256) -> uint256: nonpayable @@ -49,10 +47,10 @@ def foo(f: Foo) -> uint256: assert c2.foo(c1.address) == 600 - assert_side_effects_invoked(c1, lambda: c2.foo(c1.address, transact={})) + assert_side_effects_invoked(c1, lambda: c2.foo(c1.address)) -def test_uint256_mulmod_internal_call(get_contract_with_gas_estimation): +def test_uint256_mulmod_internal_call(get_contract): code = """ @external def foo() -> uint256: @@ -71,12 +69,12 @@ def c() -> uint256: return 601 """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == 600 -def test_uint256_mulmod_evaluation_order(get_contract_with_gas_estimation): +def test_uint256_mulmod_evaluation_order(get_contract): code = """ a: uint256 @@ -101,7 +99,7 @@ def bar() -> uint256: return 5 """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo1() == 2 assert c.foo2() == 1 diff --git a/tests/functional/builtins/codegen/test_raw_call.py b/tests/functional/builtins/codegen/test_raw_call.py index e5201e9bb2..5defb72706 100644 --- a/tests/functional/builtins/codegen/test_raw_call.py +++ b/tests/functional/builtins/codegen/test_raw_call.py @@ -1,6 +1,7 @@ import pytest from hexbytes import HexBytes +from tests.utils import ZERO_ADDRESS from vyper import compile_code from vyper.builtins.functions import eip1167_bytecode from vyper.exceptions import ArgumentException, StateAccessViolation, TypeMismatch @@ -50,14 +51,14 @@ def foo() -> Bytes[5]: assert c.foo() == b"moose" -def test_multiple_levels(w3, get_contract_with_gas_estimation): +def test_multiple_levels(env, get_contract): inner_code = """ @external def returnten() -> int128: return 10 """ - c = get_contract_with_gas_estimation(inner_code) + c = get_contract(inner_code) outer_code = """ @external @@ -72,16 +73,16 @@ def create_and_return_proxy(inp: address) -> address: return x """ - c2 = get_contract_with_gas_estimation(outer_code) + c2 = get_contract(outer_code) assert c2.create_and_call_returnten(c.address) == 10 - c2.create_and_call_returnten(c.address, transact={}) + c2.create_and_call_returnten(c.address) _, preamble, callcode = eip1167_bytecode() - c3 = c2.create_and_return_proxy(c.address, call={}) - c2.create_and_return_proxy(c.address, transact={}) + c3 = c2.create_and_return_proxy(c.address) + c2.create_and_return_proxy(c.address) - c3_contract_code = w3.to_bytes(w3.eth.get_code(c3)) + c3_contract_code = env.get_code(c3) assert c3_contract_code[:10] == HexBytes(preamble) assert c3_contract_code[-15:] == HexBytes(callcode) @@ -91,14 +92,14 @@ 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(tx_failed, get_contract_with_gas_estimation): +def test_multiple_levels2(tx_failed, get_contract): inner_code = """ @external def returnten() -> int128: raise """ - c = get_contract_with_gas_estimation(inner_code) + c = get_contract(inner_code) outer_code = """ @external @@ -112,7 +113,7 @@ def create_and_return_proxy(inp: address) -> address: return create_minimal_proxy_to(inp) """ - c2 = get_contract_with_gas_estimation(outer_code) + c2 = get_contract(outer_code) with tx_failed(): c2.create_and_call_returnten(c.address) @@ -120,7 +121,7 @@ def create_and_return_proxy(inp: address) -> address: print("Passed minimal proxy exception test") -def test_delegate_call(w3, get_contract): +def test_delegate_call(env, get_contract): inner_code = """ a: address # this is required for storage alignment... owners: public(address[5]) @@ -155,20 +156,19 @@ def set(i: int128, owner: address): ) """ - a0, a1, a2 = w3.eth.accounts[:3] - outer_contract = get_contract(outer_code, *[inner_contract.address]) + a0, a1, a2 = env.accounts[:3] + outer_contract = get_contract(outer_code, inner_contract.address) # Test setting on inners contract's state setting works. - inner_contract.set_owner(1, a2, transact={}) + inner_contract.set_owner(1, a2) assert inner_contract.owners(1) == a2 # Confirm outer contract's state is empty and contract to call has been set. assert outer_contract.owner_setter_contract() == inner_contract.address - assert outer_contract.owners(1) is None + assert outer_contract.owners(1) == ZERO_ADDRESS # Call outer contract, that make a delegate call to inner_contract. - tx_hash = outer_contract.set(1, a1, transact={}) - assert w3.eth.get_transaction_receipt(tx_hash)["status"] == 1 + outer_contract.set(1, a1) assert outer_contract.owners(1) == a1 @@ -202,7 +202,7 @@ def foo_call(_addr: address): outer_contract.foo_call(inner_contract.address) # manually specifying an insufficient amount should fail - outer_contract = get_contract(outer_code.format(", gas=15000")) + outer_contract = get_contract(outer_code.format(", gas=2250")) with tx_failed(): outer_contract.foo_call(inner_contract.address) @@ -234,7 +234,7 @@ def foo(_addr: address) -> int128: assert caller.foo(target.address) == 42 -def test_forward_calldata(get_contract, w3, keccak): +def test_forward_calldata(get_contract, env, keccak): target_source = """ @external def foo() -> uint256: @@ -256,11 +256,11 @@ def __default__(): target = get_contract(target_source) caller = get_contract(caller_source) - caller.set_target(target.address, transact={}) + caller.set_target(target.address) # manually construct msg.data for `caller` contract sig = keccak("foo()".encode()).hex()[:10] - w3.eth.send_transaction({"to": caller.address, "data": sig}) + assert env.message_call(caller.address, data=sig) == b"" # check max_outsize=0 does same thing as not setting max_outsize. @@ -517,7 +517,7 @@ def foo() -> String[32]: assert c.foo() == "goo" -def test_raw_call_clean_mem_kwargs_value(get_contract): +def test_raw_call_clean_mem_kwargs_value(get_contract, env): # test msize uses clean memory and does not get overwritten by # any raw_call() kwargs code = """ @@ -544,6 +544,7 @@ def bar(f: uint256) -> Bytes[100]: ) return self.buf """ + env.set_balance(env.deployer, 1) c = get_contract(code, value=1) assert ( @@ -552,7 +553,7 @@ def bar(f: uint256) -> Bytes[100]: ) -def test_raw_call_clean_mem_kwargs_gas(get_contract): +def test_raw_call_clean_mem_kwargs_gas(get_contract, env): # test msize uses clean memory and does not get overwritten by # any raw_call() kwargs code = """ @@ -579,6 +580,7 @@ def bar(f: uint256) -> Bytes[100]: ) return self.buf """ + env.set_balance(env.deployer, 1) c = get_contract(code, value=1) assert ( @@ -634,7 +636,5 @@ def foo(_addr: address): @pytest.mark.parametrize("source_code,exc", uncompilable_code) -def test_invalid_type_exception( - assert_compile_failed, get_contract_with_gas_estimation, source_code, exc -): - assert_compile_failed(lambda: get_contract_with_gas_estimation(source_code), exc) +def test_invalid_type_exception(assert_compile_failed, get_contract, source_code, exc): + assert_compile_failed(lambda: get_contract(source_code), exc) diff --git a/tests/functional/builtins/codegen/test_send.py b/tests/functional/builtins/codegen/test_send.py index 779c67e7e5..66c0dfb6ff 100644 --- a/tests/functional/builtins/codegen/test_send.py +++ b/tests/functional/builtins/codegen/test_send.py @@ -1,4 +1,7 @@ -def test_send(tx_failed, get_contract): +from tests.utils import ZERO_ADDRESS + + +def test_send(tx_failed, get_contract, env): send_test = """ @external def foo(): @@ -8,15 +11,18 @@ def foo(): def fop(): send(msg.sender, 10) """ + env.set_balance(env.deployer, 1000) c = get_contract(send_test, value=10) with tx_failed(): - c.foo(transact={}) - c.fop(transact={}) + c.foo() + assert env.get_balance(c.address) == 10 + c.fop() + assert env.get_balance(c.address) == 0 with tx_failed(): - c.fop(transact={}) + c.fop() -def test_default_gas(get_contract, w3): +def test_default_gas(get_contract, env, tx_failed): """ Tests to verify that send to default function will send limited gas (2300), but raw_call can send more. @@ -42,25 +48,27 @@ def __default__(): self.last_sender = msg.sender """ + env.set_balance(env.deployer, 300000) sender = get_contract(sender_code, value=1) receiver = get_contract(receiver_code) - sender.test_send(receiver.address, transact={"gas": 100000}) + with tx_failed(): + sender.test_send(receiver.address, gas=100000) # no value transfer happened, variable was not changed - assert receiver.last_sender() is None - assert w3.eth.get_balance(sender.address) == 1 - assert w3.eth.get_balance(receiver.address) == 0 + assert receiver.last_sender() == ZERO_ADDRESS + assert env.get_balance(sender.address) == 1 + assert env.get_balance(receiver.address) == 0 - sender.test_call(receiver.address, transact={"gas": 100000}) + sender.test_call(receiver.address, gas=100000) # value transfer happened, variable was changed assert receiver.last_sender() == sender.address - assert w3.eth.get_balance(sender.address) == 0 - assert w3.eth.get_balance(receiver.address) == 1 + assert env.get_balance(sender.address) == 0 + assert env.get_balance(receiver.address) == 1 -def test_send_gas_stipend(get_contract, w3): +def test_send_gas_stipend(get_contract, env): """ Tests to verify that adding gas stipend to send() will send sufficient gas """ @@ -83,12 +91,13 @@ def __default__(): self.last_sender = msg.sender """ + env.set_balance(env.deployer, 300000) sender = get_contract(sender_code, value=1) receiver = get_contract(receiver_code) - sender.test_send_stipend(receiver.address, transact={"gas": 100000}) + sender.test_send_stipend(receiver.address, gas=100000) # value transfer happened, variable was changed assert receiver.last_sender() == sender.address - assert w3.eth.get_balance(sender.address) == 0 - assert w3.eth.get_balance(receiver.address) == 1 + assert env.get_balance(sender.address) == 0 + assert env.get_balance(receiver.address) == 1 diff --git a/tests/functional/builtins/codegen/test_sha256.py b/tests/functional/builtins/codegen/test_sha256.py index 8e1b89bd31..137d3e6205 100644 --- a/tests/functional/builtins/codegen/test_sha256.py +++ b/tests/functional/builtins/codegen/test_sha256.py @@ -7,19 +7,19 @@ pytestmark = pytest.mark.usefixtures("memory_mocker") -def test_sha256_string_literal(get_contract_with_gas_estimation): +def test_sha256_string_literal(get_contract): code = """ @external def bar() -> bytes32: return sha256("test") """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.bar() == hashlib.sha256(b"test").digest() -def test_sha256_literal_bytes(get_contract_with_gas_estimation): +def test_sha256_literal_bytes(get_contract): code = """ @external def bar() -> (bytes32 , bytes32): @@ -27,32 +27,32 @@ def bar() -> (bytes32 , bytes32): y: bytes32 = sha256(b"test") return x, y """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) h = hashlib.sha256(b"test").digest() - assert c.bar() == [h, h] + assert c.bar() == (h, h) -def test_sha256_bytes32(get_contract_with_gas_estimation): +def test_sha256_bytes32(get_contract): code = """ @external def bar(a: bytes32) -> bytes32: return sha256(a) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) test_val = 8 * b"bBaA" assert c.bar(test_val) == hashlib.sha256(test_val).digest() -def test_sha256_bytearraylike(get_contract_with_gas_estimation): +def test_sha256_bytearraylike(get_contract): code = """ @external def bar(a: String[100]) -> bytes32: return sha256(a) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) test_val = "test me! test me!" assert c.bar(test_val) == hashlib.sha256(test_val.encode()).digest() @@ -60,7 +60,7 @@ def bar(a: String[100]) -> bytes32: assert c.bar(test_val) == hashlib.sha256(test_val.encode()).digest() -def test_sha256_bytearraylike_storage(get_contract_with_gas_estimation): +def test_sha256_bytearraylike_storage(get_contract): code = """ a: public(Bytes[100]) @@ -73,15 +73,15 @@ def bar() -> bytes32: return sha256(self.a) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) test_val = b"test me! test me!" - c.set(test_val, transact={}) + c.set(test_val) assert c.a() == test_val assert c.bar() == hashlib.sha256(test_val).digest() -def test_sha256_constant_bytes32(get_contract_with_gas_estimation): +def test_sha256_constant_bytes32(get_contract): hex_val = "0x1234567890123456789012345678901234567890123456789012345678901234" code = f""" FOO: constant(bytes32) = {hex_val} @@ -91,11 +91,11 @@ def foo() -> bytes32: x: bytes32 = BAR return x """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == hashlib.sha256(hex_to_int(hex_val).to_bytes(32, "big")).digest() -def test_sha256_constant_string(get_contract_with_gas_estimation): +def test_sha256_constant_string(get_contract): str_val = "0x1234567890123456789012345678901234567890123456789012345678901234" code = f""" FOO: constant(String[66]) = "{str_val}" @@ -105,5 +105,5 @@ def foo() -> bytes32: x: bytes32 = BAR return x """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == hashlib.sha256(str_val.encode()).digest() diff --git a/tests/functional/builtins/codegen/test_slice.py b/tests/functional/builtins/codegen/test_slice.py index 03dc7cc56d..5c2cc1b6ec 100644 --- a/tests/functional/builtins/codegen/test_slice.py +++ b/tests/functional/builtins/codegen/test_slice.py @@ -14,7 +14,7 @@ def _generate_bytes(length): return bytes(list(range(length))) -def test_basic_slice(get_contract_with_gas_estimation): +def test_basic_slice(get_contract): code = """ @external def slice_tower_test(inp1: Bytes[50]) -> Bytes[50]: @@ -23,7 +23,7 @@ def slice_tower_test(inp1: Bytes[50]) -> Bytes[50]: inp = slice(inp, 1, 30 - i * 2) return inp """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) x = c.slice_tower_test(b"abcdefghijklmnopqrstuvwxyz1234") assert x == b"klmnopqrst", x @@ -166,7 +166,12 @@ def do_slice(inp: Bytes[{length_bound}], start: uint256, length: uint256) -> Byt """ def _get_contract(): - return get_contract(code, bytesdata, override_opt_level=opt_level) + if "__init__" in code: + # eth-tester used to ignore constructor arguments if no constructor was defined + # now we raise an exception, so only call the constructor if it exists + # TODO: Refactor so we don't rely on searching the source code. + return get_contract(code, bytesdata, override_opt_level=opt_level) + return get_contract(code, override_opt_level=opt_level) # length bound is the container size; input_bound is the bound on the input # (which can be different, if the input is a literal) @@ -237,12 +242,12 @@ def foo(x: uint256, y: uint256) -> (uint256, String[12]): return dont_clobber_me, self.bytez """ c = get_contract(code) - assert c.foo(0, 12) == [2**256 - 1, "hello, world"] - assert c.foo(12, 0) == [2**256 - 1, ""] - assert c.foo(7, 5) == [2**256 - 1, "world"] - assert c.foo(0, 5) == [2**256 - 1, "hello"] - assert c.foo(0, 1) == [2**256 - 1, "h"] - assert c.foo(11, 1) == [2**256 - 1, "d"] + assert c.foo(0, 12) == (2**256 - 1, "hello, world") + assert c.foo(12, 0) == (2**256 - 1, "") + assert c.foo(7, 5) == (2**256 - 1, "world") + assert c.foo(0, 5) == (2**256 - 1, "hello") + assert c.foo(0, 1) == (2**256 - 1, "h") + assert c.foo(11, 1) == (2**256 - 1, "d") def test_slice_storage_bytes32(get_contract): @@ -259,7 +264,7 @@ def dice() -> Bytes[1]: assert c.dice() == b"A" -def test_slice_immutable_length_arg(get_contract_with_gas_estimation): +def test_slice_immutable_length_arg(get_contract): code = """ LENGTH: immutable(uint256) @@ -271,7 +276,7 @@ def __init__(): def do_slice(inp: Bytes[50]) -> Bytes[50]: return slice(inp, 0, LENGTH) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) x = c.do_slice(b"abcdefghijklmnopqrstuvwxyz1234") assert x == b"abcde", x diff --git a/tests/functional/builtins/codegen/test_uint2str.py b/tests/functional/builtins/codegen/test_uint2str.py index d9edea154b..e0f3324d6d 100644 --- a/tests/functional/builtins/codegen/test_uint2str.py +++ b/tests/functional/builtins/codegen/test_uint2str.py @@ -9,7 +9,7 @@ @pytest.mark.parametrize("bits", VALID_BITS) -def test_mkstr(get_contract_with_gas_estimation, bits): +def test_mkstr(get_contract, bits): n_digits = math.ceil(bits * math.log(2) / math.log(10)) code = f""" @external @@ -17,7 +17,7 @@ def foo(inp: uint{bits}) -> String[{n_digits}]: return uint2str(inp) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) for i in [1, 2, 2**bits - 1, 0]: assert c.foo(i) == str(i), (i, c.foo(i)) diff --git a/tests/functional/codegen/calling_convention/test_default_function.py b/tests/functional/codegen/calling_convention/test_default_function.py index 411f38eac9..2e22bc855d 100644 --- a/tests/functional/codegen/calling_convention/test_default_function.py +++ b/tests/functional/codegen/calling_convention/test_default_function.py @@ -1,4 +1,7 @@ -def test_throw_on_sending(w3, tx_failed, get_contract_with_gas_estimation): +from eth_utils import to_wei + + +def test_throw_on_sending(env, tx_failed, get_contract): code = """ x: public(int128) @@ -6,16 +9,16 @@ def test_throw_on_sending(w3, tx_failed, get_contract_with_gas_estimation): def __init__(): self.x = 123 """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.x() == 123 - assert w3.eth.get_balance(c.address) == 0 + assert env.get_balance(c.address) == 0 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 + env.message_call(c.address, value=to_wei(0.1, "ether"), data=b"") # call default function + assert env.get_balance(c.address) == 0 -def test_basic_default(w3, get_logs, get_contract_with_gas_estimation): +def test_basic_default(env, get_logs, get_contract): code = """ event Sent: sender: indexed(address) @@ -25,14 +28,15 @@ def test_basic_default(w3, get_logs, get_contract_with_gas_estimation): def __default__(): log Sent(msg.sender) """ - c = get_contract_with_gas_estimation(code) - - logs = get_logs(w3.eth.send_transaction({"to": c.address, "value": 10**17}), c, "Sent") - assert w3.eth.accounts[0] == logs[0].args.sender - assert w3.eth.get_balance(c.address) == w3.to_wei(0.1, "ether") + c = get_contract(code) + env.set_balance(env.deployer, 10**18) + env.message_call(c.address, value=10**17, data=b"") # call default function + (log,) = get_logs(c, "Sent") + assert env.deployer == log.args.sender + assert env.get_balance(c.address) == to_wei(0.1, "ether") -def test_basic_default_default_param_function(w3, get_logs, get_contract_with_gas_estimation): +def test_basic_default_default_param_function(env, get_logs, get_contract): code = """ event Sent: sender: indexed(address) @@ -48,14 +52,15 @@ def fooBar(a: int128 = 12345) -> int128: def __default__(): log Sent(msg.sender) """ - c = get_contract_with_gas_estimation(code) - - logs = get_logs(w3.eth.send_transaction({"to": c.address, "value": 10**17}), c, "Sent") - assert w3.eth.accounts[0] == logs[0].args.sender - assert w3.eth.get_balance(c.address) == w3.to_wei(0.1, "ether") + c = get_contract(code) + env.set_balance(env.deployer, 10**18) + env.message_call(c.address, value=10**17, data=b"") # call default function + (log,) = get_logs(c, "Sent") + assert env.deployer == log.args.sender + assert env.get_balance(c.address) == to_wei(0.1, "ether") -def test_basic_default_not_payable(w3, tx_failed, get_contract_with_gas_estimation): +def test_basic_default_not_payable(env, tx_failed, get_contract): code = """ event Sent: sender: indexed(address) @@ -64,32 +69,32 @@ def test_basic_default_not_payable(w3, tx_failed, get_contract_with_gas_estimati def __default__(): log Sent(msg.sender) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) with tx_failed(): - w3.eth.send_transaction({"to": c.address, "value": 10**17}) + env.message_call(c.address, value=10**17, data=b"") # call default function -def test_multi_arg_default(assert_compile_failed, get_contract_with_gas_estimation): +def test_multi_arg_default(assert_compile_failed, get_contract): code = """ @payable @external def __default__(arg1: int128): pass """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code)) + assert_compile_failed(lambda: get_contract(code)) -def test_always_public(assert_compile_failed, get_contract_with_gas_estimation): +def test_always_public(assert_compile_failed, get_contract): code = """ @internal def __default__(): pass """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code)) + assert_compile_failed(lambda: get_contract(code)) -def test_always_public_2(assert_compile_failed, get_contract_with_gas_estimation): +def test_always_public_2(assert_compile_failed, get_contract): code = """ event Sent: sender: indexed(address) @@ -97,10 +102,10 @@ def test_always_public_2(assert_compile_failed, get_contract_with_gas_estimation def __default__(): log Sent(msg.sender) """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code)) + assert_compile_failed(lambda: get_contract(code)) -def test_zero_method_id(w3, get_logs, get_contract, tx_failed): +def test_zero_method_id(env, get_logs, get_contract, tx_failed): # test a method with 0x00000000 selector, # expects at least 36 bytes of calldata. code = """ @@ -124,10 +129,10 @@ def __default__(): def _call_with_bytes(hexstr): # call our special contract and return the logged value - logs = get_logs( - w3.eth.send_transaction({"to": c.address, "value": 0, "data": hexstr}), c, "Sent" - ) - return logs[0].args.sig + data = bytes.fromhex(hexstr.removeprefix("0x")) + env.message_call(c.address, value=0, data=data) + (log,) = get_logs(c, "Sent") + return log.args.sig assert 1 == _call_with_bytes("0x") @@ -147,7 +152,7 @@ def _call_with_bytes(hexstr): _call_with_bytes(f"0x{'00' * i}") -def test_another_zero_method_id(w3, get_logs, get_contract, tx_failed): +def test_another_zero_method_id(env, get_logs, get_contract, tx_failed): # test another zero method id but which only expects 4 bytes of calldata code = """ event Sent: @@ -170,10 +175,10 @@ def __default__(): def _call_with_bytes(hexstr): # call our special contract and return the logged value - logs = get_logs( - w3.eth.send_transaction({"to": c.address, "value": 0, "data": hexstr}), c, "Sent" - ) - return logs[0].args.sig + data = bytes.fromhex(hexstr.removeprefix("0x")) + env.message_call(c.address, value=0, data=data, gas=10**6) + (log,) = get_logs(c, "Sent") + return log.args.sig assert 1 == _call_with_bytes("0x") @@ -188,7 +193,7 @@ def _call_with_bytes(hexstr): assert 1 == _call_with_bytes("0x" + "00" * i) -def test_partial_selector_match_trailing_zeroes(w3, get_logs, get_contract): +def test_partial_selector_match_trailing_zeroes(env, get_logs, get_contract): code = """ event Sent: sig: uint256 @@ -211,10 +216,10 @@ def __default__(): def _call_with_bytes(hexstr): # call our special contract and return the logged value - logs = get_logs( - w3.eth.send_transaction({"to": c.address, "value": 0, "data": hexstr}), c, "Sent" - ) - return logs[0].args.sig + data = bytes.fromhex(hexstr.removeprefix("0x")) + env.message_call(c.address, value=0, data=data) + (log,) = get_logs(c, "Sent") + return log.args.sig # check we can call default function assert 1 == _call_with_bytes("0x") diff --git a/tests/functional/codegen/calling_convention/test_default_parameters.py b/tests/functional/codegen/calling_convention/test_default_parameters.py index e4db72ab8d..5e73e007db 100644 --- a/tests/functional/codegen/calling_convention/test_default_parameters.py +++ b/tests/functional/codegen/calling_convention/test_default_parameters.py @@ -1,5 +1,6 @@ import pytest +from tests.utils import ZERO_ADDRESS from vyper.compiler import compile_code from vyper.exceptions import ( InvalidLiteral, @@ -8,6 +9,7 @@ TypeMismatch, UndeclaredDefinition, ) +from vyper.utils import method_id def test_default_param_abi(get_contract): @@ -17,7 +19,7 @@ def test_default_param_abi(get_contract): def safeTransferFrom(_data: Bytes[100] = b"test", _b: int128 = 1): pass """ - abi = get_contract(code)._classic_contract.abi + abi = get_contract(code).abi assert len(abi) == 3 assert set([fdef["name"] for fdef in abi]) == {"safeTransferFrom"} @@ -51,8 +53,8 @@ def fooBar(a:int128, b: uint256 = 333) -> (int128, uint256): """ c = get_contract(code) - assert c.fooBar(456, 444) == [456, 444] - assert c.fooBar(456) == [456, 333] + assert c.fooBar(456, 444) == (456, 444) + assert c.fooBar(456) == (456, 333) def test_basic_default_param_set_2args(get_contract): @@ -68,11 +70,11 @@ def fooBar(a:int128, b: uint256 = 999, c: address = 0x00000000000000000000000000 addr2 = "0x1000000000000000000000000000000000004321" # b default value, c default value - assert c.fooBar(123) == [123, b_default_value, c_default_value] + assert c.fooBar(123) == (123, b_default_value, c_default_value) # c default_value, b set from param - assert c.fooBar(456, 444) == [456, 444, c_default_value] + assert c.fooBar(456, 444) == (456, 444, c_default_value) # no default values - assert c.fooBar(6789, 4567, addr2) == [6789, 4567, addr2] + assert c.fooBar(6789, 4567, addr2) == (6789, 4567, addr2) def test_default_param_bytes(get_contract): @@ -86,11 +88,11 @@ def fooBar(a: Bytes[100], b: int128, c: Bytes[100] = b"testing", d: uint256 = 99 d_default = 999 # c set, 7d default value - assert c.fooBar(b"booo", 12321, b"woo") == [b"booo", 12321, b"woo", d_default] + assert c.fooBar(b"booo", 12321, b"woo") == (b"booo", 12321, b"woo", d_default) # d set, c set - assert c.fooBar(b"booo", 12321, b"lucky", 777) == [b"booo", 12321, b"lucky", 777] + assert c.fooBar(b"booo", 12321, b"lucky", 777) == (b"booo", 12321, b"lucky", 777) # no default values - assert c.fooBar(b"booo", 12321) == [b"booo", 12321, c_default, d_default] + assert c.fooBar(b"booo", 12321) == (b"booo", 12321, c_default, d_default) def test_default_param_array(get_contract): @@ -104,11 +106,11 @@ def fooBar(a: Bytes[100], b: uint256[2], c: Bytes[6] = b"hello", d: int128[3] = d_default = 8 # c set, d default value - assert c.fooBar(b"booo", [99, 88], b"woo") == [b"booo", 88, b"woo", d_default] + assert c.fooBar(b"booo", [99, 88], b"woo") == (b"booo", 88, b"woo", d_default) # d set, c set - assert c.fooBar(b"booo", [22, 11], b"lucky", [24, 25, 26]) == [b"booo", 11, b"lucky", 26] + assert c.fooBar(b"booo", [22, 11], b"lucky", [24, 25, 26]) == (b"booo", 11, b"lucky", 26) # no default values - assert c.fooBar(b"booo", [55, 66]) == [b"booo", 66, c_default, d_default] + assert c.fooBar(b"booo", [55, 66]) == (b"booo", 66, c_default, d_default) def test_default_param_interface(get_contract): @@ -137,8 +139,8 @@ def faz(a: uint256, b: Foo = FOO) -> Foo: assert c.bar(1) == addr2 assert c.bar(1, addr1) == addr1 - assert c.baz(1) is None - assert c.baz(1, "0x0000000000000000000000000000000000000000") is None + assert c.baz(1) == ZERO_ADDRESS + assert c.baz(1, ZERO_ADDRESS) == ZERO_ADDRESS assert c.faz(1) == addr1 assert c.faz(1, addr1) == addr1 @@ -182,7 +184,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, tx_failed): +def test_default_param_clamp(env, get_contract, tx_failed): code = """ @external def bar(a: int128, b: int128 = -1) -> (int128, int128): # noqa: E501 @@ -191,17 +193,16 @@ def bar(a: int128, b: int128 = -1) -> (int128, int128): # noqa: E501 c = get_contract(code) - assert c.bar(-123) == [-123, -1] - assert c.bar(100, 100) == [100, 100] + assert c.bar(-123) == (-123, -1) + assert c.bar(100, 100) == (100, 100) - def validate_value(cls, value): - pass + method = method_id("bar(int128,int128)") + good_data = (200).to_bytes(32, "big") + (2**127 - 1).to_bytes(32, "big") + bad_data = (200).to_bytes(32, "big") + (2**127).to_bytes(32, "big") - monkeypatch.setattr("eth_abi.encoding.NumberEncoder.validate_value", validate_value) - - assert c.bar(200, 2**127 - 1) == [200, 2**127 - 1] + assert env.message_call(c.address, data=method + good_data) == good_data with tx_failed(): - c.bar(200, 2**127) + env.message_call(c.address, data=method + bad_data) def test_default_param_private(get_contract): @@ -226,11 +227,11 @@ def callMeMaybe() -> (Bytes[100], uint256, Bytes[20]): c = get_contract(code) - # assert c.callMe() == [b'hello there', 123456, b'crazy'] - assert c.callMeMaybe() == [b"here is my number", 555123456, b"baby"] + # assert c.callMe() == (b'hello there', 123456, b'crazy') + assert c.callMeMaybe() == (b"here is my number", 555123456, b"baby") -def test_environment_vars_as_default(get_contract): +def test_environment_vars_as_default(get_contract, env): code = """ xx: uint256 @@ -249,11 +250,13 @@ def get_balance() -> uint256: return self.balance """ c = get_contract(code) - c.foo(transact={"value": 31337}) + env.set_balance(env.deployer, 31337 + 9001) + c.foo(value=31337) assert c.bar() == 31337 - c.foo(666, transact={"value": 9001}) + c.foo(666, value=9001) assert c.bar() == 31337 + 666 assert c.get_balance() == 31337 + 9001 + assert env.get_balance(env.deployer) == 0 PASSING_CONTRACTS = [ diff --git a/tests/functional/codegen/calling_convention/test_erc20_abi.py b/tests/functional/codegen/calling_convention/test_erc20_abi.py index 3f71aff3fa..a09a94a63e 100644 --- a/tests/functional/codegen/calling_convention/test_erc20_abi.py +++ b/tests/functional/codegen/calling_convention/test_erc20_abi.py @@ -1,5 +1,5 @@ import pytest -from web3.exceptions import ValidationError +from eth.codecs.abi.exceptions import EncodeError TOKEN_NAME = "Vypercoin" TOKEN_SYMBOL = "FANG" @@ -72,47 +72,47 @@ def allowance(_owner: address, _spender: address) -> uint256: return get_contract(erc20_caller_code, *[erc20.address]) -def test_initial_state(w3, erc20_caller): +def test_initial_state(env, erc20_caller): assert erc20_caller.totalSupply() == TOKEN_TOTAL_SUPPLY - assert erc20_caller.balanceOf(w3.eth.accounts[0]) == TOKEN_TOTAL_SUPPLY - assert erc20_caller.balanceOf(w3.eth.accounts[1]) == 0 + assert erc20_caller.balanceOf(env.deployer) == TOKEN_TOTAL_SUPPLY + assert erc20_caller.balanceOf(env.accounts[1]) == 0 assert erc20_caller.name() == TOKEN_NAME assert erc20_caller.symbol() == TOKEN_SYMBOL assert erc20_caller.decimals() == TOKEN_DECIMALS -def test_call_transfer(w3, erc20, erc20_caller, tx_failed): +def test_call_transfer(env, erc20, erc20_caller, tx_failed): # Basic transfer. - erc20.transfer(erc20_caller.address, 10, transact={}) + erc20.transfer(erc20_caller.address, 10) assert erc20.balanceOf(erc20_caller.address) == 10 - erc20_caller.transfer(w3.eth.accounts[1], 10, transact={}) + erc20_caller.transfer(env.accounts[1], 10) assert erc20.balanceOf(erc20_caller.address) == 0 - assert erc20.balanceOf(w3.eth.accounts[1]) == 10 + assert erc20.balanceOf(env.accounts[1]) == 10 # more than allowed with tx_failed(): - erc20_caller.transfer(w3.eth.accounts[1], TOKEN_TOTAL_SUPPLY) + erc20_caller.transfer(env.accounts[1], TOKEN_TOTAL_SUPPLY) # Negative transfer value. - with tx_failed(ValidationError): - erc20_caller.transfer(w3.eth.accounts[1], -1) + with tx_failed(EncodeError): + erc20_caller.transfer(env.accounts[1], -1) -def test_caller_approve_allowance(w3, erc20, erc20_caller): +def test_caller_approve_allowance(env, erc20, erc20_caller): assert erc20_caller.allowance(erc20.address, erc20_caller.address) == 0 - assert erc20.approve(erc20_caller.address, 10, transact={}) - assert erc20_caller.allowance(w3.eth.accounts[0], erc20_caller.address) == 10 + assert erc20.approve(erc20_caller.address, 10) + assert erc20_caller.allowance(env.deployer, erc20_caller.address) == 10 -def test_caller_tranfer_from(w3, erc20, erc20_caller, tx_failed): +def test_caller_tranfer_from(env, erc20, erc20_caller, tx_failed): # Cannot transfer tokens that are unavailable with tx_failed(): - erc20_caller.transferFrom(w3.eth.accounts[0], erc20_caller.address, 10) + erc20_caller.transferFrom(env.deployer, 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={}) + assert erc20.approve(erc20_caller.address, 10) + erc20_caller.transferFrom(env.deployer, erc20_caller.address, 5) assert erc20.balanceOf(erc20_caller.address) == 5 - assert erc20_caller.allowance(w3.eth.accounts[0], erc20_caller.address) == 5 - erc20_caller.transferFrom(w3.eth.accounts[0], erc20_caller.address, 3, transact={}) + assert erc20_caller.allowance(env.deployer, erc20_caller.address) == 5 + erc20_caller.transferFrom(env.deployer, erc20_caller.address, 3) assert erc20.balanceOf(erc20_caller.address) == 8 - assert erc20_caller.allowance(w3.eth.accounts[0], erc20_caller.address) == 2 + assert erc20_caller.allowance(env.deployer, erc20_caller.address) == 2 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 2125b6c4a8..0b1969df7d 100644 --- a/tests/functional/codegen/calling_convention/test_external_contract_calls.py +++ b/tests/functional/codegen/calling_convention/test_external_contract_calls.py @@ -14,14 +14,14 @@ from vyper.utils import method_id -def test_external_contract_calls(get_contract, get_contract_with_gas_estimation): +def test_external_contract_calls(get_contract): contract_1 = """ @external def foo(arg1: int128) -> int128: return arg1 """ - c = get_contract_with_gas_estimation(contract_1) + c = get_contract(contract_1) contract_2 = """ interface Foo: @@ -37,7 +37,7 @@ def bar(arg1: address, arg2: int128) -> int128: print("Successfully executed an external contract call") -def test_complicated_external_contract_calls(get_contract, get_contract_with_gas_estimation): +def test_complicated_external_contract_calls(get_contract): contract_1 = """ lucky: public(int128) @@ -55,7 +55,7 @@ def array() -> Bytes[3]: """ lucky_number = 7 - c = get_contract_with_gas_estimation(contract_1, *[lucky_number]) + c = get_contract(contract_1, *[lucky_number]) contract_2 = """ interface Foo: @@ -69,7 +69,6 @@ def bar(arg1: address) -> int128: c2 = get_contract(contract_2) assert c2.bar(c.address) == lucky_number - print("Successfully executed a complicated external contract call") @pytest.mark.parametrize("length", [3, 32, 33, 64]) @@ -168,8 +167,8 @@ def get_array(arg1: address) -> (Bytes[{a}], int128, Bytes[{b}]): """ c2 = get_contract(contract_2) - assert c.array() == [b"dog", 255, b"cat"] - assert c2.get_array(c.address) == [b"dog", 255, b"cat"] + assert c.array() == (b"dog", 255, b"cat") + assert c2.get_array(c.address) == (b"dog", 255, b"cat") @pytest.mark.parametrize("a,b", [(18, 7), (18, 18), (19, 6), (64, 6), (7, 19)]) @@ -197,7 +196,7 @@ 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 c.array() == (b"nineteen characters", 255, b"seven!!") with tx_failed(): c2.get_array(c.address) @@ -225,7 +224,7 @@ 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 c.array() == (b"nineteen characters", 255, b"seven!!") with tx_failed(): c2.get_array(c.address) @@ -301,8 +300,8 @@ def bar(arg1: address) -> (uint{a}, Bytes[3], uint{b}): """ c2 = get_contract(contract_2) - assert c.foo() == [255, b"dog", 255] - assert c2.bar(c.address) == [255, b"dog", 255] + assert c.foo() == (255, b"dog", 255) + assert c2.bar(c.address) == (255, b"dog", 255) @pytest.mark.parametrize("a,b", [(8, 256), (256, 8), (256, 256)]) @@ -329,7 +328,7 @@ 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 c.foo() == (int(f"{(2**a)-1}"), b"dog", int(f"{(2**b)-1}")) with tx_failed(): c2.bar(c.address) @@ -358,7 +357,7 @@ 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 c.foo() == (int(f"{(2**b)-1}"), b"dog", int(f"{(2**a)-1}")) with tx_failed(): c2.bar(c.address) @@ -434,8 +433,8 @@ def bar(arg1: address) -> (int{a}, Bytes[3], int{b}): """ c2 = get_contract(contract_2) - assert c.foo() == [255, b"dog", 255] - assert c2.bar(c.address) == [255, b"dog", 255] + assert c.foo() == (255, b"dog", 255) + assert c2.bar(c.address) == (255, b"dog", 255) @pytest.mark.parametrize("a,b", [(128, 256), (256, 128), (256, 256)]) @@ -462,7 +461,7 @@ 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 c.foo() == (int(f"{(2**(a-1))-1}"), b"dog", int(f"{(2**(b-1))-1}")) with tx_failed(): c2.bar(c.address) @@ -491,7 +490,7 @@ 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 c.foo() == (int(f"{(2**(b-1))-1}"), b"dog", int(f"{(2**(a-1))-1}")) with tx_failed(): c2.bar(c.address) @@ -567,9 +566,9 @@ def bar(arg1: address) -> (decimal, Bytes[3], decimal): """ c2 = get_contract(contract_2) - assert c.foo() == [0, b"dog", 1] + assert c.foo() == (0, b"dog", 1) result = c2.bar(c.address) - assert result == [decimal_to_int("0.0"), b"dog", decimal_to_int("1e-10")] + assert result == (decimal_to_int("0.0"), b"dog", decimal_to_int("1e-10")) @pytest.mark.parametrize("a,b", [(8, 256), (256, 8), (256, 256)]) @@ -596,7 +595,7 @@ 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 c.foo() == (2 ** (a - 1), b"dog", 2 ** (b - 1)) with tx_failed(): c2.bar(c.address) @@ -672,8 +671,8 @@ def bar(arg1: address) -> (bool, Bytes[3], bool): """ c2 = get_contract(contract_2) - assert c.foo() == [1, b"dog", 0] - assert c2.bar(c.address) == [True, b"dog", False] + assert c.foo() == (1, b"dog", 0) + assert c2.bar(c.address) == (True, b"dog", False) @pytest.mark.parametrize("a", ["uint8", "uint256", "int128", "int256"]) @@ -701,7 +700,7 @@ def bar(arg1: address) -> (bool, Bytes[3], bool): """ c2 = get_contract(contract_2) - assert c.foo() == [1, b"dog", 2] + assert c.foo() == (1, b"dog", 2) with tx_failed(): c2.bar(c.address) @@ -801,12 +800,12 @@ def bar(arg1: address) -> (address, Bytes[3], address): """ c2 = get_contract(contract_2) - assert c.foo() == [16, b"dog", 1] - assert c2.bar(c.address) == [ + assert c.foo() == (16, b"dog", 1) + assert c2.bar(c.address) == ( "0x0000000000000000000000000000000000000010", b"dog", "0x0000000000000000000000000000000000000001", - ] + ) @pytest.mark.parametrize("a", ["uint256", "int256"]) @@ -834,7 +833,7 @@ def bar(arg1: address) -> (address, Bytes[3], address): """ c2 = get_contract(contract_2) - assert c.foo() == [(2**160) - 1, b"dog", (2**160) - 2] + assert c.foo() == ((2**160) - 1, b"dog", (2**160) - 2) result = c2.bar(c.address) assert len(result) == 3 assert result[0].lower() == "0xffffffffffffffffffffffffffffffffffffffff" @@ -867,7 +866,7 @@ def bar(arg1: address) -> (address, Bytes[3], address): """ c2 = get_contract(contract_2) - assert c.foo() == [(2**160) - 1, b"dog", 2**160] + assert c.foo() == ((2**160) - 1, b"dog", 2**160) with tx_failed(): c2.bar(c.address) @@ -895,7 +894,7 @@ def set_lucky(arg1: address, arg2: int128): c2 = get_contract(contract_2) assert c.lucky() == 0 - c2.set_lucky(c.address, lucky_number, transact={}) + c2.set_lucky(c.address, lucky_number) assert c.lucky() == lucky_number print("Successfully executed an external contract call state change") @@ -961,8 +960,8 @@ def set_lucky(arg1: address, arg2: int128): """ c3 = get_contract(contract_3) - c3.set_lucky(c.address, lucky_number_1, transact={}) - c3.set_lucky(c2.address, lucky_number_2, transact={}) + c3.set_lucky(c.address, lucky_number_1) + c3.set_lucky(c2.address, lucky_number_2) assert c.lucky() == lucky_number_1 assert c2.lucky() == lucky_number_2 print( @@ -1120,7 +1119,7 @@ def _expr(x: address) -> int128: assert c2._expr(c2.address) == 1 -def test_invalid_nonexistent_contract_call(w3, tx_failed, get_contract): +def test_invalid_nonexistent_contract_call(env, tx_failed, get_contract): contract_1 = """ @external def bar() -> int128: @@ -1141,9 +1140,9 @@ def foo(x: address) -> int128: assert c2.foo(c1.address) == 1 with tx_failed(): - c2.foo(w3.eth.accounts[0]) + c2.foo(env.deployer) with tx_failed(): - c2.foo(w3.eth.accounts[3]) + c2.foo(env.accounts[3]) def test_invalid_contract_reference_declaration(tx_failed, get_contract): @@ -1243,15 +1242,15 @@ def get_lucky(contract_address: address) -> int128: c2 = get_contract(contract_2) assert c1.get_lucky() == 0 assert c2.get_lucky(c1.address) == 0 - c1.set_lucky(6, transact={}) + c1.set_lucky(6) assert c1.get_lucky() == 6 assert c2.get_lucky(c1.address) == 6 - c2.set_lucky(c1.address, transact={}) + c2.set_lucky(c1.address) assert c1.get_lucky() == 1 assert c2.get_lucky(c1.address) == 1 -def test_complex_external_contract_call_declaration(get_contract_with_gas_estimation): +def test_complex_external_contract_call_declaration(get_contract): contract_1 = """ @external def get_lucky() -> int128: @@ -1280,14 +1279,14 @@ def get_lucky() -> int128: return staticcall self.bar_contract.get_lucky() """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) - c3 = get_contract_with_gas_estimation(contract_3) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) + c3 = get_contract(contract_3) assert c1.get_lucky() == 1 assert c2.get_lucky() == 2 - c3.set_contract(c1.address, transact={}) + c3.set_contract(c1.address) assert c3.get_lucky() == 1 - c3.set_contract(c2.address, transact={}) + c3.set_contract(c2.address) assert c3.get_lucky() == 2 @@ -1313,7 +1312,7 @@ def get_bar() -> int128: """ c1 = get_contract(contract_1) c2 = get_contract(contract_2) - c2.foo(c1.address, transact={}) + c2.foo(c1.address) assert c2.bar_contract() == c1.address assert c2.get_bar() == 1 @@ -1352,7 +1351,7 @@ def foo(contract_address: address) -> int128: get_contract(contract_1) -def test_external_with_payable_value(w3, get_contract_with_gas_estimation): +def test_external_with_payable_value(env, get_contract): contract_1 = """ @payable @external @@ -1383,34 +1382,34 @@ def get_lucky(amount_to_send: uint256) -> int128: return extcall self.bar_contract.get_lucky(value=msg.value) """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) # Set address. assert c1.get_lucky() == 1 assert c1.get_balance() == 0 - c2.set_contract(c1.address, transact={}) + c2.set_contract(c1.address) # Send some eth - assert c2.get_lucky(0, call={"value": 500}) == 1 - c2.get_lucky(0, transact={"value": 500}) + env.set_balance(env.deployer, 10000) + + assert c2.get_lucky(0, value=500) == 1 # Contract 1 received money. assert c1.get_balance() == 500 - assert w3.eth.get_balance(c1.address) == 500 - assert w3.eth.get_balance(c2.address) == 0 + assert env.get_balance(c1.address) == 500 + assert env.get_balance(c2.address) == 0 # Send subset of amount - assert c2.get_lucky(250, call={"value": 500}) == 1 - c2.get_lucky(250, transact={"value": 500}) - + assert c2.get_lucky(250, value=500) == 1 # Contract 1 received more money. assert c1.get_balance() == 750 - assert w3.eth.get_balance(c1.address) == 750 - assert w3.eth.get_balance(c2.address) == 250 + assert env.get_balance(c1.address) == 750 + assert env.get_balance(c2.address) == 250 + assert env.get_balance(env.deployer) == 9000 -def test_external_call_with_gas(tx_failed, get_contract_with_gas_estimation): +def test_external_call_with_gas(tx_failed, get_contract): contract_1 = """ @external def get_lucky() -> int128: @@ -1433,16 +1432,16 @@ def get_lucky(gas_amount: uint256) -> int128: return staticcall self.bar_contract.get_lucky(gas=gas_amount) """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) - c2.set_contract(c1.address, transact={}) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) + c2.set_contract(c1.address) assert c2.get_lucky(1000) == 656598 with tx_failed(): c2.get_lucky(50) # too little gas. -def test_skip_contract_check(get_contract_with_gas_estimation): +def test_skip_contract_check(get_contract): contract_2 = """ @external @view @@ -1465,13 +1464,13 @@ def call_baz(): # would fail if extcodesize check were on extcall Bar(addr).baz(skip_contract_check=True) """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) c1.call_bar(c2.address) c1.call_baz() -def test_invalid_keyword_on_call(assert_compile_failed, get_contract_with_gas_estimation): +def test_invalid_keyword_on_call(assert_compile_failed, get_contract): contract_1 = """ interface Bar: def set_lucky(arg1: int128): nonpayable @@ -1484,10 +1483,10 @@ def get_lucky(amount_to_send: int128) -> int128: return staticcall self.bar_contract.get_lucky(gass=1) """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(contract_1), ArgumentException) + assert_compile_failed(lambda: get_contract(contract_1), ArgumentException) -def test_invalid_contract_declaration(assert_compile_failed, get_contract_with_gas_estimation): +def test_invalid_contract_declaration(assert_compile_failed, get_contract): contract_1 = """ interface Bar: def set_lucky(arg1: int128): nonpayable @@ -1495,7 +1494,7 @@ def set_lucky(arg1: int128): nonpayable bar_contract: Barr """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(contract_1), UnknownType) + assert_compile_failed(lambda: get_contract(contract_1), UnknownType) FAILING_CONTRACTS_STRUCTURE_EXCEPTION = [ @@ -1538,11 +1537,11 @@ def foo(a: address, x: uint256, y: uint256): @pytest.mark.parametrize("bad_code", FAILING_CONTRACTS_STRUCTURE_EXCEPTION) -def test_bad_code_struct_exc(assert_compile_failed, get_contract_with_gas_estimation, bad_code): - assert_compile_failed(lambda: get_contract_with_gas_estimation(bad_code), ArgumentException) +def test_bad_code_struct_exc(assert_compile_failed, get_contract, bad_code): + assert_compile_failed(lambda: get_contract(bad_code), ArgumentException) -def test_bad_skip_contract_check(assert_compile_failed, get_contract_with_gas_estimation): +def test_bad_skip_contract_check(assert_compile_failed, get_contract): code = """ # variable value for skip_contract_check interface Bar: @@ -1580,11 +1579,11 @@ def test(addr: address) -> (int128, address, Bytes[10]): c1 = get_contract(contract_1) c2 = get_contract(contract_2) - assert c1.out_literals() == [1, "0x0000000000000000000000000000000000000123", b"random"] - assert c2.test(c1.address) == [1, "0x0000000000000000000000000000000000000123", b"random"] + assert c1.out_literals() == (1, "0x0000000000000000000000000000000000000123", b"random") + assert c2.test(c1.address) == (1, "0x0000000000000000000000000000000000000123", b"random") -def test_struct_return_external_contract_call_1(get_contract_with_gas_estimation): +def test_struct_return_external_contract_call_1(get_contract): contract_1 = """ struct X: x: int128 @@ -1607,15 +1606,15 @@ def test(addr: address) -> (int128, address): return ret.x, ret.y """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) assert c1.out_literals() == (1, "0x0000000000000000000000000000000000012345") - assert c2.test(c1.address) == list(c1.out_literals()) + assert c2.test(c1.address) == c1.out_literals() @pytest.mark.parametrize("i,ln,s,", [(100, 6, "abcde"), (41, 40, "a" * 34), (57, 70, "z" * 68)]) -def test_struct_return_external_contract_call_2(get_contract_with_gas_estimation, i, ln, s): +def test_struct_return_external_contract_call_2(get_contract, i, ln, s): contract_1 = f""" struct X: x: int128 @@ -1640,14 +1639,14 @@ def test(addr: address) -> (int128, String[{ln}], Bytes[{ln}]): return ret.x, ret.y, ret.z """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) assert c1.get_struct_x() == (i, s, bytes(s, "utf-8")) - assert c2.test(c1.address) == list(c1.get_struct_x()) + assert c2.test(c1.address) == c1.get_struct_x() -def test_struct_return_external_contract_call_3(get_contract_with_gas_estimation): +def test_struct_return_external_contract_call_3(get_contract): contract_1 = """ struct X: x: int128 @@ -1668,14 +1667,14 @@ def test(addr: address) -> int128: return ret.x """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) assert c1.out_literals() == (1,) assert [c2.test(c1.address)] == list(c1.out_literals()) -def test_constant_struct_return_external_contract_call_1(get_contract_with_gas_estimation): +def test_constant_struct_return_external_contract_call_1(get_contract): contract_1 = """ struct X: x: int128 @@ -1701,17 +1700,15 @@ def test(addr: address) -> (int128, address): return ret.x, ret.y """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) assert c1.out_literals() == (1, "0x0000000000000000000000000000000000012345") - assert c2.test(c1.address) == list(c1.out_literals()) + assert c2.test(c1.address) == c1.out_literals() @pytest.mark.parametrize("i,ln,s,", [(100, 6, "abcde"), (41, 40, "a" * 34), (57, 70, "z" * 68)]) -def test_constant_struct_return_external_contract_call_2( - get_contract_with_gas_estimation, i, ln, s -): +def test_constant_struct_return_external_contract_call_2(get_contract, i, ln, s): contract_1 = f""" struct X: x: int128 @@ -1739,14 +1736,14 @@ def test(addr: address) -> (int128, String[{ln}], Bytes[{ln}]): return ret.x, ret.y, ret.z """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) assert c1.get_struct_x() == (i, s, bytes(s, "utf-8")) - assert c2.test(c1.address) == list(c1.get_struct_x()) + assert c2.test(c1.address) == c1.get_struct_x() -def test_constant_struct_return_external_contract_call_3(get_contract_with_gas_estimation): +def test_constant_struct_return_external_contract_call_3(get_contract): contract_1 = """ struct X: x: int128 @@ -1770,14 +1767,14 @@ def test(addr: address) -> int128: return ret.x """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) assert c1.out_literals() == (1,) assert [c2.test(c1.address)] == list(c1.out_literals()) -def test_constant_struct_member_return_external_contract_call_1(get_contract_with_gas_estimation): +def test_constant_struct_member_return_external_contract_call_1(get_contract): contract_1 = """ struct X: x: int128 @@ -1799,17 +1796,15 @@ def test(addr: address) -> address: ret: address = staticcall Test(addr).get_y() return ret """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) assert c1.get_y() == "0x0000000000000000000000000000000000012345" assert c2.test(c1.address) == "0x0000000000000000000000000000000000012345" @pytest.mark.parametrize("i,ln,s,", [(100, 6, "abcde"), (41, 40, "a" * 34), (57, 70, "z" * 68)]) -def test_constant_struct_member_return_external_contract_call_2( - get_contract_with_gas_estimation, i, ln, s -): +def test_constant_struct_member_return_external_contract_call_2(get_contract, i, ln, s): contract_1 = f""" struct X: x: int128 @@ -1833,14 +1828,14 @@ def test(addr: address) -> String[{ln}]: return ret """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) assert c1.get_y() == s assert c2.test(c1.address) == s -def test_constant_struct_member_return_external_contract_call_3(get_contract_with_gas_estimation): +def test_constant_struct_member_return_external_contract_call_3(get_contract): contract_1 = """ struct X: x: int128 @@ -1862,14 +1857,14 @@ def test(addr: address) -> int128: return ret """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) assert c1.get_x() == 1 assert c2.test(c1.address) == 1 -def test_constant_nested_struct_return_external_contract_call_1(get_contract_with_gas_estimation): +def test_constant_nested_struct_return_external_contract_call_1(get_contract): contract_1 = """ struct X: x: int128 @@ -1903,17 +1898,15 @@ def test(addr: address) -> (X, uint256): ret: A = staticcall Test(addr).out_literals() return ret.a, ret.b """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) assert c1.out_literals() == ((1, "0x0000000000000000000000000000000000012345"), 777) - assert c2.test(c1.address) == list(c1.out_literals()) + assert c2.test(c1.address) == c1.out_literals() @pytest.mark.parametrize("i,ln,s,", [(100, 6, "abcde"), (41, 40, "a" * 34), (57, 70, "z" * 68)]) -def test_constant_nested_struct_return_external_contract_call_2( - get_contract_with_gas_estimation, i, ln, s -): +def test_constant_nested_struct_return_external_contract_call_2(get_contract, i, ln, s): contract_1 = f""" struct X: x: int128 @@ -1950,14 +1943,14 @@ def test(addr: address) -> (X, uint256): return ret.a, ret.b """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) assert c1.get_struct_a() == ((i, s, bytes(s, "utf-8")), 777) - assert c2.test(c1.address) == list(c1.get_struct_a()) + assert c2.test(c1.address) == c1.get_struct_a() -def test_constant_nested_struct_return_external_contract_call_3(get_contract_with_gas_estimation): +def test_constant_nested_struct_return_external_contract_call_3(get_contract): contract_1 = """ struct X: x: int128 @@ -1999,16 +1992,14 @@ def test(addr: address) -> (A, bool): ret: C = staticcall Test(addr).out_literals() return ret.c, ret.d """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) - assert c1.out_literals() == (((1, -1), 777), True) - assert c2.test(c1.address) == list(c1.out_literals()) + assert c1.out_literals() == ((((1, -1), 777)), True) + assert c2.test(c1.address) == c1.out_literals() -def test_constant_nested_struct_member_return_external_contract_call_1( - get_contract_with_gas_estimation, -): +def test_constant_nested_struct_member_return_external_contract_call_1(get_contract): contract_1 = """ struct X: x: int128 @@ -2034,17 +2025,15 @@ def test(addr: address) -> address: ret: address = staticcall Test(addr).get_y() return ret """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) assert c1.get_y() == "0x0000000000000000000000000000000000012345" assert c2.test(c1.address) == "0x0000000000000000000000000000000000012345" @pytest.mark.parametrize("i,ln,s,", [(100, 6, "abcde"), (41, 40, "a" * 34), (57, 70, "z" * 68)]) -def test_constant_nested_struct_member_return_external_contract_call_2( - get_contract_with_gas_estimation, i, ln, s -): +def test_constant_nested_struct_member_return_external_contract_call_2(get_contract, i, ln, s): contract_1 = f""" struct X: x: int128 @@ -2073,16 +2062,14 @@ def test(addr: address) -> String[{ln}]: return ret """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) assert c1.get_y() == s assert c2.test(c1.address) == s -def test_constant_nested_struct_member_return_external_contract_call_3( - get_contract_with_gas_estimation, -): +def test_constant_nested_struct_member_return_external_contract_call_3(get_contract): contract_1 = """ struct X: x: int128 @@ -2122,8 +2109,8 @@ def test2(addr: address) -> uint256: ret: uint256 = staticcall Test(addr).get_b() return ret """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) assert c1.get_y() == -1 assert c2.test(c1.address) == -1 @@ -2132,7 +2119,7 @@ def test2(addr: address) -> uint256: assert c2.test2(c1.address) == 777 -def test_dynamically_sized_struct_external_contract_call(get_contract_with_gas_estimation): +def test_dynamically_sized_struct_external_contract_call(get_contract): contract_1 = """ struct X: x: uint256 @@ -2157,14 +2144,14 @@ def bar(addr: address) -> Bytes[6]: return extcall Foo(addr).foo(_X) """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) assert c1.foo((1, b"hello")) == b"hello" assert c2.bar(c1.address) == b"hello" -def test_dynamically_sized_struct_external_contract_call_2(get_contract_with_gas_estimation): +def test_dynamically_sized_struct_external_contract_call_2(get_contract): contract_1 = """ struct X: x: uint256 @@ -2189,14 +2176,14 @@ def bar(addr: address) -> String[6]: return extcall Foo(addr).foo(_X) """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) assert c1.foo((1, "hello")) == "hello" assert c2.bar(c1.address) == "hello" -def test_dynamically_sized_struct_member_external_contract_call(get_contract_with_gas_estimation): +def test_dynamically_sized_struct_member_external_contract_call(get_contract): contract_1 = """ @external def foo(b: Bytes[6]) -> Bytes[6]: @@ -2217,14 +2204,14 @@ def bar(addr: address) -> Bytes[6]: return extcall Foo(addr).foo(_X.y) """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) assert c1.foo(b"hello") == b"hello" assert c2.bar(c1.address) == b"hello" -def test_dynamically_sized_struct_member_external_contract_call_2(get_contract_with_gas_estimation): +def test_dynamically_sized_struct_member_external_contract_call_2(get_contract): contract_1 = """ @external def foo(s: String[6]) -> String[6]: @@ -2245,21 +2232,21 @@ def bar(addr: address) -> String[6]: return extcall Foo(addr).foo(_X.y) """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) assert c1.foo("hello") == "hello" assert c2.bar(c1.address) == "hello" -def test_list_external_contract_call(get_contract, get_contract_with_gas_estimation): +def test_list_external_contract_call(get_contract): contract_1 = """ @external def array() -> int128[3]: return [0, 0, 0] """ - c = get_contract_with_gas_estimation(contract_1) + c = get_contract(contract_1) contract_2 = """ interface Foo: @@ -2496,7 +2483,7 @@ def do_stuff(f: Foo) -> uint256: @pytest.mark.parametrize("typ,val", [("address", TEST_ADDR)]) -def test_calldata_clamp(w3, get_contract, tx_failed, typ, val): +def test_calldata_clamp(env, get_contract, tx_failed, typ, val): code = f""" @external def foo(a: {typ}): @@ -2510,17 +2497,17 @@ def foo(a: {typ}): # Static size is short by 1 byte malformed = data[:-2] with tx_failed(): - w3.eth.send_transaction({"to": c1.address, "data": malformed}) + env.message_call(c1.address, data=malformed) # Static size is exact - w3.eth.send_transaction({"to": c1.address, "data": data}) + env.message_call(c1.address, data=data) # Static size exceeds by 1 byte, ok - w3.eth.send_transaction({"to": c1.address, "data": data + "ff"}) + env.message_call(c1.address, data=data + "ff") @pytest.mark.parametrize("typ,val", [("address", ([TEST_ADDR] * 3, "vyper"))]) -def test_dynamic_calldata_clamp(w3, get_contract, tx_failed, typ, val): +def test_dynamic_calldata_clamp(env, get_contract, tx_failed, typ, val): code = f""" @external def foo(a: DynArray[{typ}, 3], b: String[5]): @@ -2535,8 +2522,8 @@ def foo(a: DynArray[{typ}, 3], b: String[5]): # Dynamic size is short by 1 byte malformed = data[:264] with tx_failed(): - w3.eth.send_transaction({"to": c1.address, "data": malformed}) + env.message_call(c1.address, data=malformed) # Dynamic size is at least minimum (132 bytes * 2 + 2 (for 0x) = 266) valid = data[:266] - w3.eth.send_transaction({"to": c1.address, "data": valid}) + env.message_call(c1.address, data=valid) 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 156b0f8870..a6f3e5ba90 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 @@ -40,11 +40,11 @@ def static_set_lucky(_lucky: int128): c1 = get_contract(contract_1) c2 = get_contract(contract_2, *[c1.address]) - c2.modifiable_set_lucky(7, transact={}) + c2.modifiable_set_lucky(7) assert c1.lucky() == 7 # Fails attempting a state change after a call to a static address with tx_failed(): - c2.static_set_lucky(5, transact={}) + c2.static_set_lucky(5) assert c1.lucky() == 7 @@ -85,11 +85,11 @@ def static_set_lucky(_lucky: int128): c1 = get_contract(contract_1) c2 = get_contract(contract_2, *[c1.address]) - c2.modifiable_set_lucky(7, transact={}) + c2.modifiable_set_lucky(7) assert c1.lucky() == 7 # Fails attempting a state change after a call to a static address with tx_failed(): - c2.static_set_lucky(5, transact={}) + c2.static_set_lucky(5) assert c1.lucky() == 7 @@ -166,14 +166,14 @@ def static_modifiable_set_lucky(_lucky: int128) -> int128: c3 = get_contract(contract_3, *[c2.address]) assert c1.lucky() == 0 - c3.modifiable_modifiable_set_lucky(7, transact={}) + c3.modifiable_modifiable_set_lucky(7) assert c1.lucky() == 7 with tx_failed(): - c3.modifiable_static_set_lucky(6, transact={}) + c3.modifiable_static_set_lucky(6) with tx_failed(): - c3.static_modifiable_set_lucky(6, transact={}) + c3.static_modifiable_set_lucky(6) with tx_failed(): - c3.static_static_set_lucky(6, transact={}) + c3.static_static_set_lucky(6) assert c1.lucky() == 7 @@ -199,7 +199,7 @@ def get_bar() -> int128: """ c1 = get_contract(contract_1) c2 = get_contract(contract_2) - c2.foo(c1.address, transact={}) + c2.foo(c1.address) assert c2.bar_contract() == c1.address assert c2.get_bar() == 1 diff --git a/tests/functional/codegen/calling_convention/test_return.py b/tests/functional/codegen/calling_convention/test_return.py index fdf6e04d10..6c7c0aeec5 100644 --- a/tests/functional/codegen/calling_convention/test_return.py +++ b/tests/functional/codegen/calling_convention/test_return.py @@ -1,32 +1,26 @@ import pytest +from tests.utils import ZERO_ADDRESS from vyper import compile_code from vyper.exceptions import TypeMismatch pytestmark = pytest.mark.usefixtures("memory_mocker") -def test_correct_abi_right_padding(tester, w3, get_contract_with_gas_estimation): +def test_correct_abi_right_padding(env, get_contract): selfcall_code_6 = """ @external def hardtest(arg1: Bytes[64], arg2: Bytes[64]) -> Bytes[128]: return concat(arg1, arg2) """ - c = get_contract_with_gas_estimation(selfcall_code_6) + c = get_contract(selfcall_code_6) assert c.hardtest(b"hello" * 5, b"hello" * 10) == b"hello" * 15 - # Make sure underlying structe is correctly right padded - classic_contract = c._classic_contract - func = classic_contract.functions.hardtest(b"hello" * 5, b"hello" * 10) - tx = func.build_transaction({"gasPrice": 0}) - del tx["chainId"] - del tx["gasPrice"] - - tx["from"] = w3.eth.accounts[0] - res = w3.to_bytes(hexstr=tester.call(tx)) - + res = env.message_call( + to=c.address, data=c.hardtest.prepare_calldata(b"hello" * 5, b"hello" * 10) + ) static_offset = int.from_bytes(res[:32], "big") assert static_offset == 32 @@ -41,7 +35,7 @@ def hardtest(arg1: Bytes[64], arg2: Bytes[64]) -> Bytes[128]: assert dyn_section[32 + len_value :] == b"\x00" * (len(dyn_section) - 32 - len_value) -def test_return_type(get_contract_with_gas_estimation): +def test_return_type(get_contract): long_string = 35 * "test" code = """ @@ -90,39 +84,39 @@ def out_very_long_bytes() -> (int128, Bytes[1024], int128, address): return 5555, b"testtesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttest", 6666, 0x0000000000000000000000000000000000001234 # noqa """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) - assert c.out() == [3333, "0x0000000000000000000000000000000000000001"] - assert c.out_literals() == [1, None, b"random"] - assert c.out_bytes_first() == [b"test", 1234] - assert c.out_bytes_a(5555555, b"test") == [5555555, b"test"] - assert c.out_bytes_b(5555555, b"test") == [b"test", 5555555, b"test"] - assert c.four() == [1234, b"bytes", b"test", 4321] - assert c.out_chunk() == [b"hello", 5678, b"world"] - assert c.out_very_long_bytes() == [ + assert c.out() == (3333, "0x0000000000000000000000000000000000000001") + assert c.out_literals() == (1, ZERO_ADDRESS, b"random") + assert c.out_bytes_first() == (b"test", 1234) + assert c.out_bytes_a(5555555, b"test") == (5555555, b"test") + assert c.out_bytes_b(5555555, b"test") == (b"test", 5555555, b"test") + assert c.four() == (1234, b"bytes", b"test", 4321) + assert c.out_chunk() == (b"hello", 5678, b"world") + assert c.out_very_long_bytes() == ( 5555, long_string.encode(), 6666, "0x0000000000000000000000000000000000001234", - ] + ) -def test_return_type_signatures(get_contract_with_gas_estimation): +def test_return_type_signatures(get_contract): code = """ @external def out_literals() -> (int128, address, Bytes[6]): return 1, 0x0000000000000000000000000000000000000000, b"random" """ - c = get_contract_with_gas_estimation(code) - assert c._classic_contract.abi[0]["outputs"] == [ + c = get_contract(code) + assert c.abi[0]["outputs"] == [ {"type": "int128", "name": ""}, {"type": "address", "name": ""}, {"type": "bytes", "name": ""}, ] -def test_return_tuple_assign(get_contract_with_gas_estimation): +def test_return_tuple_assign(get_contract): code = """ @internal def _out_literals() -> (int128, address, Bytes[10]): @@ -141,12 +135,12 @@ def test() -> (int128, address, Bytes[10]): return a, b, c """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) - assert c.out_literals() == c.test() == [1, None, b"random"] + assert c.out_literals() == c.test() == (1, ZERO_ADDRESS, b"random") -def test_return_tuple_assign_storage(get_contract_with_gas_estimation): +def test_return_tuple_assign_storage(get_contract): code = """ a: int128 b: address @@ -179,13 +173,13 @@ def test3() -> (address, int128): return x, self.a """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) addr = "0x" + "00" * 19 + "23" - assert c.out_literals() == [1, b"testtesttest", addr, b"random"] + assert c.out_literals() == (1, b"testtesttest", addr, b"random") assert c.out_literals() == c.test1() - assert c.test2() == [1, c.out_literals()[2]] - assert c.test3() == [c.out_literals()[2], 1] + assert c.test2() == (1, c.out_literals()[2]) + assert c.test3() == (c.out_literals()[2], 1) @pytest.mark.parametrize("string", ["a", "abc", "abcde", "potato"]) @@ -207,7 +201,7 @@ def test_values(a: address) -> (String[6], uint256): """ c2 = get_contract(code) - assert c2.test_values(c1.address) == [string, 42] + assert c2.test_values(c1.address) == (string, 42) @pytest.mark.parametrize("string", ["a", "abc", "abcde", "potato"]) @@ -229,10 +223,10 @@ def test_values(a: address) -> (Bytes[6], uint256): """ c2 = get_contract(code) - assert c2.test_values(c1.address) == [bytes(string, "utf-8"), 42] + assert c2.test_values(c1.address) == (bytes(string, "utf-8"), 42) -def test_tuple_return_typecheck(tx_failed, get_contract_with_gas_estimation): +def test_tuple_return_typecheck(tx_failed, get_contract): code = """ @external def getTimeAndBalance() -> (bool, address): @@ -242,7 +236,7 @@ def getTimeAndBalance() -> (bool, address): compile_code(code) -def test_struct_return_abi(get_contract_with_gas_estimation): +def test_struct_return_abi(get_contract): code = """ struct Voter: weight: int128 @@ -259,12 +253,12 @@ def test() -> Voter: assert abi["name"] == "test" - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.test() == (123, True) -def test_single_struct_return_abi(get_contract_with_gas_estimation): +def test_single_struct_return_abi(get_contract): code = """ struct Voter: voted: bool @@ -281,12 +275,12 @@ def test() -> Voter: assert abi["name"] == "test" assert abi["outputs"][0]["type"] == "tuple" - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.test() == (True,) -def test_struct_return(get_contract_with_gas_estimation): +def test_struct_return(get_contract): code = """ struct Foo: x: int128 @@ -335,7 +329,7 @@ def pub6() -> Foo: """ foo = (123, 456) - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.pub1() == (1, 2) assert c.pub2() == (3, 4) @@ -345,7 +339,7 @@ def pub6() -> Foo: assert c.pub6() == foo -def test_single_struct_return(get_contract_with_gas_estimation): +def test_single_struct_return(get_contract): code = """ struct Foo: x: int128 @@ -392,7 +386,7 @@ def pub6() -> Foo: """ foo = (123,) - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.pub1() == (1,) assert c.pub2() == (3,) diff --git a/tests/functional/codegen/calling_convention/test_self_call_struct.py b/tests/functional/codegen/calling_convention/test_self_call_struct.py index 56b36c6492..64e45de2e8 100644 --- a/tests/functional/codegen/calling_convention/test_self_call_struct.py +++ b/tests/functional/codegen/calling_convention/test_self_call_struct.py @@ -1,7 +1,7 @@ from tests.utils import decimal_to_int -def test_call_to_self_struct(w3, get_contract): +def test_call_to_self_struct(env, get_contract): code = """ struct MyStruct: e1: decimal @@ -26,11 +26,11 @@ def wrap_get_my_struct_BROKEN(_e1: decimal) -> MyStruct: c = get_contract(code) assert c.wrap_get_my_struct_WORKING(decimal_to_int("0.1")) == ( decimal_to_int("0.1"), - w3.eth.get_block(w3.eth.block_number)["timestamp"], + env.timestamp, ) assert c.wrap_get_my_struct_BROKEN(decimal_to_int("0.1")) == ( decimal_to_int("0.1"), - w3.eth.get_block(w3.eth.block_number)["timestamp"], + env.timestamp, ) diff --git a/tests/functional/codegen/environment_variables/test_blobbasefee.py b/tests/functional/codegen/environment_variables/test_blobbasefee.py index b92824491c..3da5c686b6 100644 --- a/tests/functional/codegen/environment_variables/test_blobbasefee.py +++ b/tests/functional/codegen/environment_variables/test_blobbasefee.py @@ -4,47 +4,34 @@ @pytest.mark.requires_evm_version("cancun") -def test_blobbasefee(get_contract_with_gas_estimation, w3): +def test_blobbasefee(env, get_contract): code = """ @external @view def get_blobbasefee() -> uint256: return block.blobbasefee """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.get_blobbasefee() == MIN_BLOB_BASE_FEE - a0 = w3.eth.account.from_key(f"0x{'00' * 31}01") - - text = b"Vyper is the language of the sneks" - # Blobs contain 4096 32-byte field elements. - blob_data = text.rjust(32 * 4096) - - for _i in range(10): - tx = { - "type": 3, - "chainId": 1337, - "from": a0.address, - "to": "0xb45BEc6eeCA2a09f4689Dd308F550Ad7855051B5", # random address - "value": 0, - "gas": 21000, - "maxFeePerGas": 10**10, - "maxPriorityFeePerGas": 10**10, - "maxFeePerBlobGas": 10**10, - "nonce": w3.eth.get_transaction_count(a0.address), - } - - signed = a0.sign_transaction(tx, blobs=[blob_data] * 6) - w3.eth.send_raw_transaction(signed.rawTransaction) - - block = w3.eth.get_block("latest") - excess_blob_gas = block["excessBlobGas"] - expected_blobbasefee = fake_exponential( - MIN_BLOB_BASE_FEE, excess_blob_gas, BLOB_BASE_FEE_UPDATE_FRACTION - ) - - assert c.get_blobbasefee() == expected_blobbasefee - - # sanity check that blobbasefee has increased above the minimum - assert c.get_blobbasefee() > MIN_BLOB_BASE_FEE + env.set_balance(env.deployer, 10**20) + env.set_excess_blob_gas(10**6) + + # kzg_hash(b"Vyper is the language of the sneks") + blob_hashes = [ + (bytes.fromhex("015a5c97e3cc516f22a95faf7eefff00eb2fee7a65037fde07ac5446fc93f2a0")) + ] * 6 + + env.message_call( + "0xb45BEc6eeCA2a09f4689Dd308F550Ad7855051B5", # random address + gas=21000, + gas_price=10**10, + blob_hashes=blob_hashes, + ) + + excess_blob_gas = env.get_excess_blob_gas() + expected_blobbasefee = fake_exponential( + MIN_BLOB_BASE_FEE, excess_blob_gas, BLOB_BASE_FEE_UPDATE_FRACTION + ) + assert c.get_blobbasefee() == expected_blobbasefee diff --git a/tests/functional/codegen/environment_variables/test_block_number.py b/tests/functional/codegen/environment_variables/test_block_number.py index 269371a32d..c963e2e175 100644 --- a/tests/functional/codegen/environment_variables/test_block_number.py +++ b/tests/functional/codegen/environment_variables/test_block_number.py @@ -1,11 +1,11 @@ -def test_block_number(get_contract_with_gas_estimation, w3): +def test_block_number(get_contract, env): block_number_code = """ @external def block_number() -> uint256: return block.number """ - c = get_contract_with_gas_estimation(block_number_code) + c = get_contract(block_number_code) assert c.block_number() == 1 - w3.testing.mine(1) + env.block_number += 1 assert c.block_number() == 2 diff --git a/tests/functional/codegen/environment_variables/test_blockhash.py b/tests/functional/codegen/environment_variables/test_blockhash.py index 68db053b12..4ddbec080b 100644 --- a/tests/functional/codegen/environment_variables/test_blockhash.py +++ b/tests/functional/codegen/environment_variables/test_blockhash.py @@ -1,6 +1,4 @@ -def test_blockhash(get_contract_with_gas_estimation, w3): - w3.testing.mine(1) - +def test_blockhash(get_contract): block_number_code = """ @external def prev() -> bytes32: @@ -10,37 +8,37 @@ def prev() -> bytes32: def previous_blockhash() -> bytes32: return blockhash(block.number - 1) """ - c = get_contract_with_gas_estimation(block_number_code) + c = get_contract(block_number_code) assert c.prev() == c.previous_blockhash() -def test_negative_blockhash(assert_compile_failed, get_contract_with_gas_estimation): +def test_negative_blockhash(assert_compile_failed, get_contract): code = """ @external def foo() -> bytes32: return blockhash(-1) """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code)) + assert_compile_failed(lambda: get_contract(code)) -def test_too_old_blockhash(tx_failed, get_contract_with_gas_estimation, w3): - w3.testing.mine(257) +def test_too_old_blockhash(tx_failed, get_contract, env): + env.block_number += 257 code = """ @external def get_50_blockhash() -> bytes32: return blockhash(block.number - 257) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) with tx_failed(): c.get_50_blockhash() -def test_non_existing_blockhash(tx_failed, get_contract_with_gas_estimation): +def test_non_existing_blockhash(tx_failed, get_contract): code = """ @external def get_future_blockhash() -> bytes32: return blockhash(block.number + 1) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) with tx_failed(): c.get_future_blockhash() diff --git a/tests/functional/codegen/environment_variables/test_tx.py b/tests/functional/codegen/environment_variables/test_tx.py index 3bc6ce2eff..efdde8a919 100644 --- a/tests/functional/codegen/environment_variables/test_tx.py +++ b/tests/functional/codegen/environment_variables/test_tx.py @@ -1,9 +1,10 @@ -def test_tx_gasprice(get_contract): +def test_tx_gasprice(get_contract, env): code = """ @external def tx_gasprice() -> uint256: return tx.gasprice """ + env.set_balance(env.deployer, 10**20) c = get_contract(code) for i in range(10): - assert c.tx_gasprice(call={"gasPrice": 10**i}) == 10**i + assert c.tx_gasprice(gas_price=10**i) == 10**i diff --git a/tests/functional/codegen/features/decorators/test_nonreentrant.py b/tests/functional/codegen/features/decorators/test_nonreentrant.py index 11beeb08d9..5586acbe6d 100644 --- a/tests/functional/codegen/features/decorators/test_nonreentrant.py +++ b/tests/functional/codegen/features/decorators/test_nonreentrant.py @@ -165,35 +165,35 @@ def __default__(): contract = get_contract(protected_code) malicious = get_contract(malicious_code) - contract.set_callback(malicious.address, transact={}) + contract.set_callback(malicious.address) assert contract.callback() == malicious.address # Test unprotected function. - contract.unprotected_function("some value", True, transact={}) + contract.unprotected_function("some value", True) assert contract.special_value() == "surprise!" # Test protected function. - contract.protected_function("some value", False, transact={}) + contract.protected_function("some value", False) assert contract.special_value() == "some value" assert contract.protected_view_fn() == "some value" with tx_failed(): - contract.protected_function("zzz value", True, transact={}) + contract.protected_function("zzz value", True) - contract.protected_function2("another value", False, transact={}) + contract.protected_function2("another value", False) assert contract.special_value() == "another value" with tx_failed(): - contract.protected_function2("zzz value", True, transact={}) + contract.protected_function2("zzz value", True) - contract.protected_function3("another value", False, transact={}) + contract.protected_function3("another value", False) assert contract.special_value() == "another value" with tx_failed(): - contract.protected_function3("zzz value", True, transact={}) + contract.protected_function3("zzz value", True) -def test_nonreentrant_decorator_for_default(w3, get_contract, tx_failed): +def test_nonreentrant_decorator_for_default(env, get_contract, tx_failed): calling_contract_code = """ @external def send_funds(_amount: uint256): @@ -256,30 +256,31 @@ def __default__(): reentrant_contract = get_contract(reentrant_code) calling_contract = get_contract(calling_contract_code) - reentrant_contract.set_callback(calling_contract.address, transact={}) + reentrant_contract.set_callback(calling_contract.address) assert reentrant_contract.callback() == calling_contract.address # Test unprotected function without callback. - reentrant_contract.unprotected_function("some value", False, transact={"value": 1000}) + env.set_balance(env.deployer, 10**6) + reentrant_contract.unprotected_function("some value", False, value=1000) assert reentrant_contract.special_value() == "some value" - assert w3.eth.get_balance(reentrant_contract.address) == 0 - assert w3.eth.get_balance(calling_contract.address) == 1000 + assert env.get_balance(reentrant_contract.address) == 0 + assert env.get_balance(calling_contract.address) == 1000 # Test unprotected function with callback to default. - reentrant_contract.unprotected_function("another value", True, transact={"value": 1000}) + reentrant_contract.unprotected_function("another value", True, value=1000) assert reentrant_contract.special_value() == "another value" - assert w3.eth.get_balance(reentrant_contract.address) == 1000 - assert w3.eth.get_balance(calling_contract.address) == 1000 + assert env.get_balance(reentrant_contract.address) == 1000 + assert env.get_balance(calling_contract.address) == 1000 # Test protected function without callback. - reentrant_contract.protected_function("surprise!", False, transact={"value": 1000}) + reentrant_contract.protected_function("surprise!", False, value=1000) assert reentrant_contract.special_value() == "surprise!" - assert w3.eth.get_balance(reentrant_contract.address) == 1000 - assert w3.eth.get_balance(calling_contract.address) == 2000 + assert env.get_balance(reentrant_contract.address) == 1000 + assert env.get_balance(calling_contract.address) == 2000 # Test protected function with callback to default. with tx_failed(): - reentrant_contract.protected_function("zzz value", True, transact={"value": 1000}) + reentrant_contract.protected_function("zzz value", True, 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 bd4cadd5aa..e5157f5050 100644 --- a/tests/functional/codegen/features/decorators/test_payable.py +++ b/tests/functional/codegen/features/decorators/test_payable.py @@ -180,13 +180,13 @@ def baz() -> bool: @pytest.mark.parametrize("code", nonpayable_code) -def test_nonpayable_runtime_assertion(w3, keccak, tx_failed, get_contract, code): +def test_nonpayable_runtime_assertion(env, keccak, tx_failed, get_contract, code): c = get_contract(code) - c.foo(transact={"value": 0}) + c.foo(value=0) sig = keccak("foo()".encode()).hex()[:10] with tx_failed(): - w3.eth.send_transaction({"to": c.address, "data": sig, "value": 10**18}) + env.message_call(c.address, data=sig, value=10**18) payable_code = [ @@ -334,14 +334,14 @@ def bar() -> bool: @pytest.mark.parametrize("code", payable_code) -def test_payable_runtime_assertion(get_contract, code): +def test_payable_runtime_assertion(env, get_contract, code): c = get_contract(code) + env.set_balance(env.deployer, 10**18) + c.foo(value=10**18) + c.foo(value=0) - c.foo(transact={"value": 10**18}) - c.foo(transact={"value": 0}) - -def test_payable_default_func_invalid_calldata(get_contract, w3): +def test_payable_default_func_invalid_calldata(get_contract, env): code = """ @external def foo() -> bool: @@ -352,12 +352,12 @@ def foo() -> bool: def __default__(): pass """ - c = get_contract(code) - w3.eth.send_transaction({"to": c.address, "value": 100, "data": "0x12345678"}) + env.set_balance(env.deployer, 100) + env.message_call(c.address, value=100, data="0x12345678") -def test_nonpayable_default_func_invalid_calldata(get_contract, w3, tx_failed): +def test_nonpayable_default_func_invalid_calldata(get_contract, env, tx_failed): code = """ @external @payable @@ -370,12 +370,12 @@ def __default__(): """ c = get_contract(code) - w3.eth.send_transaction({"to": c.address, "value": 0, "data": "0x12345678"}) + env.message_call(c.address, value=0, data="0x12345678") with tx_failed(): - w3.eth.send_transaction({"to": c.address, "value": 100, "data": "0x12345678"}) + env.message_call(c.address, value=100, data="0x12345678") -def test_batch_nonpayable(get_contract, w3, tx_failed): +def test_batch_nonpayable(get_contract, env, tx_failed): code = """ @external def foo() -> bool: @@ -387,9 +387,9 @@ def __default__(): """ c = get_contract(code) - w3.eth.send_transaction({"to": c.address, "value": 0, "data": "0x12345678"}) + env.message_call(c.address, value=0, data="0x12345678") data = bytes([1, 2, 3, 4]) for i in range(5): calldata = "0x" + data[:i].hex() with tx_failed(): - w3.eth.send_transaction({"to": c.address, "value": 100, "data": calldata}) + env.message_call(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 15243ae3f3..d313aa3bda 100644 --- a/tests/functional/codegen/features/decorators/test_private.py +++ b/tests/functional/codegen/features/decorators/test_private.py @@ -1,7 +1,8 @@ import pytest +from eth_utils import to_wei -def test_private_test(get_contract_with_gas_estimation): +def test_private_test(get_contract): private_test_code = """ @internal def a() -> int128: @@ -12,7 +13,7 @@ def returnten() -> int128: return self.a() * 2 """ - c = get_contract_with_gas_estimation(private_test_code) + c = get_contract(private_test_code) assert c.returnten() == 10 @@ -41,7 +42,7 @@ def return_it() -> int128: assert c.return_it() == 777 -def test_private_with_more_vars_nested(get_contract_with_gas_estimation): +def test_private_with_more_vars_nested(get_contract): private_test_code = """ @internal def more() -> int128: @@ -67,11 +68,11 @@ def return_it() -> int128: return a + b + c """ - c = get_contract_with_gas_estimation(private_test_code) + c = get_contract(private_test_code) assert c.return_it() == 999 -def test_private_with_args(get_contract_with_gas_estimation): +def test_private_with_args(get_contract): private_test_code = """ @internal def add_times2(a: uint256, b: uint256) -> uint256: @@ -87,11 +88,11 @@ def return_it() -> uint256: return a + b + c """ - c = get_contract_with_gas_estimation(private_test_code) + c = get_contract(private_test_code) assert c.return_it() == 555 -def test_private_with_args_nested(get_contract_with_gas_estimation): +def test_private_with_args_nested(get_contract): private_test_code = """ @internal def multiply(a: uint256, b: uint256) -> uint256: @@ -112,11 +113,11 @@ def return_it() -> uint256: return a + b + c """ - c = get_contract_with_gas_estimation(private_test_code) + c = get_contract(private_test_code) assert c.return_it() == 666 -def test_private_bytes(get_contract_with_gas_estimation): +def test_private_bytes(get_contract): private_test_code = """ greeting: public(Bytes[100]) @@ -134,12 +135,12 @@ def hithere(name: Bytes[100]) -> Bytes[200]: return d """ - c = get_contract_with_gas_estimation(private_test_code) + c = get_contract(private_test_code) assert c.hithere(b"bob") == b"Hello bob" assert c.hithere(b"alice") == b"Hello alice" -def test_private_statement(get_contract_with_gas_estimation): +def test_private_statement(get_contract): private_test_code = """ greeting: public(Bytes[20]) @@ -175,14 +176,14 @@ def hithere(name: Bytes[20]) -> Bytes[40]: return d """ - c = get_contract_with_gas_estimation(private_test_code) + c = get_contract(private_test_code) assert c.greeting() == b"Hello " assert c.hithere(b"Bob") == b"Hello Bob" - c.iprefer(b"Hi there, ", transact={}) + c.iprefer(b"Hi there, ") assert c.hithere(b"Alice") == b"Hi there, Alice" -def test_private_default_parameter(get_contract_with_gas_estimation): +def test_private_default_parameter(get_contract): private_test_code = """ @internal def addition(a: uint256, b: uint256 = 1) -> uint256: @@ -206,13 +207,13 @@ def added(a: uint256, b: uint256) -> uint256: return d """ - c = get_contract_with_gas_estimation(private_test_code) + c = get_contract(private_test_code) assert c.add_one(20) == 21 assert c.added(10, 20) == 30 -def test_private_return_bytes(get_contract_with_gas_estimation): +def test_private_return_bytes(get_contract): code = """ a_message: Bytes[50] @@ -259,16 +260,16 @@ def test4() -> (Bytes[100]): return self.get_msg() """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) test_str = b" 1 2" assert c.test() == b"hello" + test_str assert c.test2() == b"hello" + test_str assert c.test3(b"alice") == b"alice" - c.set(b"hello daar", transact={}) + c.set(b"hello daar") assert c.test4() == b"hello daar" -def test_private_bytes_as_args(get_contract_with_gas_estimation): +def test_private_bytes_as_args(get_contract): code = """ @internal def _test(a: Bytes[40]) -> (Bytes[100]): @@ -287,12 +288,12 @@ def test2() -> Bytes[100]: return self._test(c) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.test(b"bob") == b"hello bob, jack attack" assert c.test2() == b"hello alice" -def test_private_return_tuple_base_types(get_contract_with_gas_estimation): +def test_private_return_tuple_base_types(get_contract): code = """ @internal def _test(a: bytes32) -> (bytes32, uint256, int128): @@ -314,13 +315,13 @@ def test2(a: bytes32) -> (bytes32, uint256, int128): return self._test(a) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) - assert c.test(b"test" + b"\x00" * 28) == [b"test" + 28 * b"\x00", 1000, -1200] - assert c.test2(b"test" + b"\x00" * 28) == [b"test" + 28 * b"\x00", 1000, -1200] + assert c.test(b"test" + b"\x00" * 28) == (b"test" + 28 * b"\x00", 1000, -1200) + assert c.test2(b"test" + b"\x00" * 28) == (b"test" + 28 * b"\x00", 1000, -1200) -def test_private_return_tuple_bytes(get_contract_with_gas_estimation): +def test_private_return_tuple_bytes(get_contract): code = """ @internal def _test(a: int128, b: Bytes[50]) -> (int128, Bytes[100]): @@ -361,15 +362,15 @@ def test4(a: Bytes[40]) -> (int128, Bytes[100], Bytes[100]): return self._test_combined(a, 8, b) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) - assert c.test(11, b"jill") == [14, b"badabing:jill_one", b"jill_one"] - assert c.test2(b"jack") == [6, b"badabing:jack_one"] - assert c.test3(b"hill") == [10, b"hill", b"hill_two"] - assert c.test4(b"bucket") == [10, b"bucket", b"bucket_one_two"] + assert c.test(11, b"jill") == (14, b"badabing:jill_one", b"jill_one") + assert c.test2(b"jack") == (6, b"badabing:jack_one") + assert c.test3(b"hill") == (10, b"hill", b"hill_two") + assert c.test4(b"bucket") == (10, b"bucket", b"bucket_one_two") -def test_private_return_list_types(get_contract_with_gas_estimation): +def test_private_return_list_types(get_contract): code = """ @internal def _test(b: int128[4]) -> int128[4]: @@ -384,12 +385,12 @@ def test() -> int128[4]: c: int128[2] = [11, 22] return self._test(b) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.test() == [0, 1, 0, 1] -def test_private_payable(w3, get_contract_with_gas_estimation): +def test_private_payable(env, get_contract): code = """ @internal def _send_it(a: address, _value: uint256): @@ -406,18 +407,18 @@ def __default__(): pass """ - c = get_contract_with_gas_estimation(code) - - w3.eth.send_transaction({"to": c.address, "value": w3.to_wei(1, "ether")}) - assert w3.eth.get_balance(c.address) == w3.to_wei(1, "ether") - a3 = w3.eth.accounts[2] - assert w3.eth.get_balance(a3) == w3.to_wei(1000000, "ether") - c.test(True, a3, w3.to_wei(0.05, "ether"), transact={}) - assert w3.eth.get_balance(a3) == w3.to_wei(1000000.05, "ether") - assert w3.eth.get_balance(c.address) == w3.to_wei(0.95, "ether") + c = get_contract(code) + env.set_balance(env.deployer, to_wei(1, "ether")) + env.message_call(c.address, value=to_wei(1, "ether")) + assert env.get_balance(c.address) == to_wei(1, "ether") + a3 = env.accounts[2] + env.set_balance(a3, to_wei(1000000, "ether")) + c.test(True, a3, to_wei(0.05, "ether")) + assert env.get_balance(a3) == to_wei(1000000.05, "ether") + assert env.get_balance(c.address) == to_wei(0.95, "ether") -def test_private_msg_sender(get_contract, w3): +def test_private_msg_sender(get_contract, env, get_logs): code = """ event Addr: addr: address @@ -442,11 +443,10 @@ def whoami() -> address: c = get_contract(code) assert c.i_am_me() - addr = w3.eth.accounts[1] - txhash = c.whoami(transact={"from": addr}) - receipt = w3.eth.wait_for_transaction_receipt(txhash) - logged_addr = w3.to_checksum_address(receipt.logs[0].data[-20:]) - assert logged_addr == addr, "oh no" + addr = env.accounts[1] + c.whoami(sender=addr) + (log,) = get_logs(c) + assert log.args.addr == addr def test_nested_static_params_only(get_contract, tx_failed): @@ -537,7 +537,7 @@ def start(): c = get_contract(code) assert c.test() is False - c.start(transact={}) + c.start() assert c.test() is True @@ -585,7 +585,7 @@ def foo(a: int128) -> (int128, int128): return self._test(a) """, (11,), - [13, 2], + (13, 2), ), ( """ @@ -636,7 +636,7 @@ def foo() -> (uint256[4], uint256): return out.many, out.one """, (), - [[1, 2, 3, 4], 5], + ([1, 2, 3, 4], 5), ), ( """ @@ -649,7 +649,7 @@ def foo() -> (uint256[2], uint256[2], uint256[2]): return self._foo()[0], [3, 4], self._foo()[1] """, (), - [[1, 2], [3, 4], [5, 6]], + ([1, 2], [3, 4], [5, 6]), ), ( """ @@ -662,7 +662,7 @@ def foo(a: int128, b: int128[3], c: int128[3]) -> (int128[3], int128, int128[3]) return self._foo(a, b, c) """, (6, [7, 5, 8], [1, 2, 3]), - [[1, 2, 3], 4, [5, 6, 7]], + ([1, 2, 3], 4, [5, 6, 7]), ), ( """ @@ -675,7 +675,7 @@ def foo(a: int128, b: int128[3], c: int128[3]) -> (int128[3], int128, int128[3]) return c, 4, self._foo(a, b, c)[2] """, (6, [7, 5, 8], [1, 2, 3]), - [[1, 2, 3], 4, [5, 6, 7]], + ([1, 2, 3], 4, [5, 6, 7]), ), ] diff --git a/tests/functional/codegen/features/decorators/test_public.py b/tests/functional/codegen/features/decorators/test_public.py index e3d4b7eb7c..f9a1e52e7f 100644 --- a/tests/functional/codegen/features/decorators/test_public.py +++ b/tests/functional/codegen/features/decorators/test_public.py @@ -1,9 +1,7 @@ from vyper.exceptions import FunctionDeclarationException -def test_invalid_if_both_public_and_internal( - assert_compile_failed, get_contract_with_gas_estimation -): +def test_invalid_if_both_public_and_internal(assert_compile_failed, get_contract): code = """ @external @internal @@ -11,19 +9,13 @@ def foo(): x: uint256 = 1 """ - assert_compile_failed( - lambda: get_contract_with_gas_estimation(code), FunctionDeclarationException - ) + assert_compile_failed(lambda: get_contract(code), FunctionDeclarationException) -def test_invalid_if_visibility_isnt_declared( - assert_compile_failed, get_contract_with_gas_estimation -): +def test_invalid_if_visibility_isnt_declared(assert_compile_failed, get_contract): code = """ def foo(): x: uint256 = 1 """ - assert_compile_failed( - lambda: get_contract_with_gas_estimation(code), FunctionDeclarationException - ) + assert_compile_failed(lambda: get_contract(code), FunctionDeclarationException) diff --git a/tests/functional/codegen/features/decorators/test_view.py b/tests/functional/codegen/features/decorators/test_view.py index 9d4b57c44e..d54b4e5e86 100644 --- a/tests/functional/codegen/features/decorators/test_view.py +++ b/tests/functional/codegen/features/decorators/test_view.py @@ -3,7 +3,7 @@ from vyper.exceptions import FunctionDeclarationException -def test_constant_test(get_contract_with_gas_estimation_for_constants): +def test_constant_test(get_contract): constant_test = """ @external @view @@ -11,7 +11,7 @@ def foo() -> int128: return 5 """ - c = get_contract_with_gas_estimation_for_constants(constant_test) + c = get_contract(constant_test) assert c.foo() == 5 print("Passed constant function test") @@ -31,9 +31,7 @@ def foo() -> uint256: assert c.foo() == 0 -def test_invalid_constant_and_payable( - get_contract_with_gas_estimation_for_constants, assert_compile_failed -): +def test_invalid_constant_and_payable(get_contract, assert_compile_failed): code = """ @external @payable @@ -41,6 +39,4 @@ def test_invalid_constant_and_payable( def foo() -> num: return 5 """ - assert_compile_failed( - lambda: get_contract_with_gas_estimation_for_constants(code), FunctionDeclarationException - ) + assert_compile_failed(lambda: get_contract(code), FunctionDeclarationException) diff --git a/tests/functional/codegen/features/iteration/test_break.py b/tests/functional/codegen/features/iteration/test_break.py index e939c2f0c6..12cc519f40 100644 --- a/tests/functional/codegen/features/iteration/test_break.py +++ b/tests/functional/codegen/features/iteration/test_break.py @@ -4,7 +4,7 @@ from vyper.exceptions import StructureException -def test_break_test(get_contract_with_gas_estimation): +def test_break_test(get_contract): break_test = """ @external def foo(n: decimal) -> int128: @@ -18,7 +18,7 @@ def foo(n: decimal) -> int128: return output """ - c = get_contract_with_gas_estimation(break_test) + c = get_contract(break_test) assert c.foo(decimal_to_int("1")) == 0 assert c.foo(decimal_to_int("2")) == 3 @@ -28,7 +28,7 @@ def foo(n: decimal) -> int128: print("Passed for-loop break test") -def test_break_test_2(get_contract_with_gas_estimation): +def test_break_test_2(get_contract): break_test_2 = """ @external def foo(n: decimal) -> int128: @@ -47,7 +47,7 @@ def foo(n: decimal) -> int128: return output """ - c = get_contract_with_gas_estimation(break_test_2) + c = get_contract(break_test_2) assert c.foo(decimal_to_int("1")) == 0 assert c.foo(decimal_to_int("2")) == 3 assert c.foo(decimal_to_int("10")) == 10 @@ -56,7 +56,7 @@ def foo(n: decimal) -> int128: print("Passed for-loop break test 2") -def test_break_test_3(get_contract_with_gas_estimation): +def test_break_test_3(get_contract): break_test_3 = """ @external def foo(n: int128) -> int128: @@ -75,7 +75,7 @@ def foo(n: int128) -> int128: return output """ - c = get_contract_with_gas_estimation(break_test_3) + c = get_contract(break_test_3) assert c.foo(1) == 0 assert c.foo(2) == 3 assert c.foo(10) == 10 @@ -118,5 +118,5 @@ def foo(): @pytest.mark.parametrize("bad_code,exc", fail_list) -def test_block_fail(assert_compile_failed, get_contract_with_gas_estimation, bad_code, exc): - assert_compile_failed(lambda: get_contract_with_gas_estimation(bad_code), exc) +def test_block_fail(assert_compile_failed, get_contract, bad_code, exc): + assert_compile_failed(lambda: get_contract(bad_code), exc) diff --git a/tests/functional/codegen/features/iteration/test_continue.py b/tests/functional/codegen/features/iteration/test_continue.py index 1b2fcab460..69d1aa8370 100644 --- a/tests/functional/codegen/features/iteration/test_continue.py +++ b/tests/functional/codegen/features/iteration/test_continue.py @@ -3,7 +3,7 @@ from vyper.exceptions import StructureException -def test_continue1(get_contract_with_gas_estimation): +def test_continue1(get_contract): code = """ @external def foo() -> bool: @@ -12,11 +12,11 @@ def foo() -> bool: return False return True """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() -def test_continue2(get_contract_with_gas_estimation): +def test_continue2(get_contract): code = """ @external def foo() -> int128: @@ -27,11 +27,11 @@ def foo() -> int128: x -= 1 return x """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == 3 -def test_continue3(get_contract_with_gas_estimation): +def test_continue3(get_contract): code = """ @external def foo() -> int128: @@ -41,11 +41,11 @@ def foo() -> int128: continue return x """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == 3 -def test_continue4(get_contract_with_gas_estimation): +def test_continue4(get_contract): code = """ @external def foo() -> int128: @@ -56,7 +56,7 @@ def foo() -> int128: x += 1 return x """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == 3 @@ -94,5 +94,5 @@ def foo(): @pytest.mark.parametrize("bad_code,exc", fail_list) -def test_block_fail(assert_compile_failed, get_contract_with_gas_estimation, bad_code, exc): - assert_compile_failed(lambda: get_contract_with_gas_estimation(bad_code), exc) +def test_block_fail(assert_compile_failed, get_contract, bad_code, exc): + assert_compile_failed(lambda: get_contract(bad_code), exc) diff --git a/tests/functional/codegen/features/iteration/test_for_in_list.py b/tests/functional/codegen/features/iteration/test_for_in_list.py index 6a017e92c1..184e6a2859 100644 --- a/tests/functional/codegen/features/iteration/test_for_in_list.py +++ b/tests/functional/codegen/features/iteration/test_for_in_list.py @@ -166,7 +166,7 @@ def test_basic_for_in_lists(code, data, get_contract): assert c.data() == data -def test_basic_for_list_storage(get_contract_with_gas_estimation): +def test_basic_for_list_storage(get_contract): code = """ x: int128[4] @@ -182,14 +182,14 @@ def data() -> int128: return -1 """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.data() == -1 - c.set(transact={}) + c.set() assert c.data() == 7 -def test_basic_for_dyn_array_storage(get_contract_with_gas_estimation): +def test_basic_for_dyn_array_storage(get_contract): code = """ x: DynArray[int128, 4] @@ -205,16 +205,16 @@ def data() -> int128: return t """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.data() == 0 # test all sorts of lists for xs in [[3, 5, 7, 9], [4, 6, 8], [1, 2], [5], []]: - c.set(xs, transact={}) + c.set(xs) assert c.data() == sum(xs) -def test_basic_for_list_storage_address(get_contract_with_gas_estimation): +def test_basic_for_list_storage_address(get_contract): code = """ addresses: address[3] @@ -236,16 +236,16 @@ def iterate_return_second() -> address: return empty(address) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) - c.set(0, "0x82A978B3f5962A5b0957d9ee9eEf472EE55B42F1", transact={}) - c.set(1, "0x7d577a597B2742b498Cb5Cf0C26cDCD726d39E6e", transact={}) - c.set(2, "0xDCEceAF3fc5C0a63d195d69b1A90011B7B19650D", transact={}) + c.set(0, "0x82A978B3f5962A5b0957d9ee9eEf472EE55B42F1") + c.set(1, "0x7d577a597B2742b498Cb5Cf0C26cDCD726d39E6e") + c.set(2, "0xDCEceAF3fc5C0a63d195d69b1A90011B7B19650D") assert c.ret(1) == c.iterate_return_second() == "0x7d577a597B2742b498Cb5Cf0C26cDCD726d39E6e" -def test_basic_for_list_storage_decimal(get_contract_with_gas_estimation): +def test_basic_for_list_storage_decimal(get_contract): code = """ readings: decimal[3] @@ -267,18 +267,18 @@ def i_return(break_count: int128) -> decimal: return -1.111 """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) - c.set(0, decimal_to_int("0.0001"), transact={}) - c.set(1, decimal_to_int("1.1"), transact={}) - c.set(2, decimal_to_int("2.2"), transact={}) + c.set(0, decimal_to_int("0.0001")) + c.set(1, decimal_to_int("1.1")) + c.set(2, decimal_to_int("2.2")) assert c.ret(2) == c.i_return(2) == decimal_to_int("2.2") assert c.ret(1) == c.i_return(1) == decimal_to_int("1.1") assert c.ret(0) == c.i_return(0) == decimal_to_int("0.0001") -def test_for_in_list_iter_type(get_contract_with_gas_estimation): +def test_for_in_list_iter_type(get_contract): code = """ @external @view @@ -292,12 +292,12 @@ def func(amounts: uint256[3]) -> uint256: return total """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.func([100, 200, 300]) == 600 -def test_for_in_dyn_array(get_contract_with_gas_estimation): +def test_for_in_dyn_array(get_contract): code = """ @external @view @@ -311,7 +311,7 @@ def func(amounts: DynArray[uint256, 3]) -> uint256: return total """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.func([100, 200, 300]) == 600 assert c.func([100, 200]) == 300 diff --git a/tests/functional/codegen/features/iteration/test_for_range.py b/tests/functional/codegen/features/iteration/test_for_range.py index 0fd2c6212e..61c6f453d6 100644 --- a/tests/functional/codegen/features/iteration/test_for_range.py +++ b/tests/functional/codegen/features/iteration/test_for_range.py @@ -4,7 +4,7 @@ from vyper.utils import SizeLimits -def test_basic_repeater(get_contract_with_gas_estimation): +def test_basic_repeater(get_contract): basic_repeater = """ @external def repeat(z: int128) -> int128: @@ -13,7 +13,7 @@ def repeat(z: int128) -> int128: x = x + z return(x) """ - c = get_contract_with_gas_estimation(basic_repeater) + c = get_contract(basic_repeater) assert c.repeat(9) == 54 @@ -131,7 +131,7 @@ def get_last(start: uint256, end: uint256) -> uint256: c.get_last(UINT_MAX, UINT_MAX - n) -def test_digit_reverser(get_contract_with_gas_estimation): +def test_digit_reverser(get_contract): digit_reverser = """ @external def reverse_digits(x: int128) -> int128: @@ -147,11 +147,11 @@ def reverse_digits(x: int128) -> int128: """ - c = get_contract_with_gas_estimation(digit_reverser) + c = get_contract(digit_reverser) assert c.reverse_digits(123456) == 654321 -def test_more_complex_repeater(get_contract_with_gas_estimation): +def test_more_complex_repeater(get_contract): more_complex_repeater = """ @external def repeat() -> int128: @@ -163,12 +163,12 @@ def repeat() -> int128: return(out) """ - c = get_contract_with_gas_estimation(more_complex_repeater) + c = get_contract(more_complex_repeater) assert c.repeat() == 666666 @pytest.mark.parametrize("typ", ["int128", "uint256"]) -def test_offset_repeater(get_contract_with_gas_estimation, typ): +def test_offset_repeater(get_contract, typ): offset_repeater = f""" @external def sum() -> {typ}: @@ -178,12 +178,12 @@ def sum() -> {typ}: return out """ - c = get_contract_with_gas_estimation(offset_repeater) + c = get_contract(offset_repeater) assert c.sum() == 4100 @pytest.mark.parametrize("typ", ["int128", "uint256"]) -def test_offset_repeater_2(get_contract_with_gas_estimation, typ): +def test_offset_repeater_2(get_contract, typ): offset_repeater_2 = f""" @external def sum(frm: {typ}, to: {typ}) -> {typ}: @@ -195,12 +195,12 @@ def sum(frm: {typ}, to: {typ}) -> {typ}: return out """ - c = get_contract_with_gas_estimation(offset_repeater_2) + c = get_contract(offset_repeater_2) assert c.sum(100, 99999) == 15150 assert c.sum(70, 131) == 6100 -def test_loop_call_priv(get_contract_with_gas_estimation): +def test_loop_call_priv(get_contract): code = """ @internal def _bar() -> bool: @@ -213,7 +213,7 @@ def foo() -> bool: return True """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() is True @@ -400,7 +400,7 @@ def foo(a: {typ}): self.result = 31337 """ c = get_contract(code) - c.foo(val, transact={}) + c.foo(val) if val + 1 >= 19: assert c.result() == 31337 else: diff --git a/tests/functional/codegen/features/iteration/test_range_in.py b/tests/functional/codegen/features/iteration/test_range_in.py index f381f60b35..6870bc3d48 100644 --- a/tests/functional/codegen/features/iteration/test_range_in.py +++ b/tests/functional/codegen/features/iteration/test_range_in.py @@ -1,7 +1,7 @@ from vyper.exceptions import TypeMismatch -def test_basic_in_list(get_contract_with_gas_estimation): +def test_basic_in_list(get_contract): code = """ @external def testin(x: int128) -> bool: @@ -12,7 +12,7 @@ def testin(x: int128) -> bool: return False """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.testin(0) is True assert c.testin(1) is True @@ -23,7 +23,7 @@ def testin(x: int128) -> bool: assert c.testin(-1) is False -def test_in_storage_list(get_contract_with_gas_estimation): +def test_in_storage_list(get_contract): code = """ allowed: int128[10] @@ -35,7 +35,7 @@ def in_test(x: int128) -> bool: return False """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.in_test(1) is True assert c.in_test(9) is True @@ -44,7 +44,7 @@ def in_test(x: int128) -> bool: assert c.in_test(32000) is False -def test_in_calldata_list(get_contract_with_gas_estimation): +def test_in_calldata_list(get_contract): code = """ @external def in_test(x: int128, y: int128[10]) -> bool: @@ -53,7 +53,7 @@ def in_test(x: int128, y: int128[10]) -> bool: return False """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.in_test(1, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) is True assert c.in_test(9, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) is True @@ -62,7 +62,7 @@ def in_test(x: int128, y: int128[10]) -> bool: assert c.in_test(32000, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) is False -def test_cmp_in_list(get_contract_with_gas_estimation): +def test_cmp_in_list(get_contract): code = """ @external def in_test(x: int128) -> bool: @@ -71,7 +71,7 @@ def in_test(x: int128) -> bool: return False """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.in_test(1) is False assert c.in_test(-7) is False @@ -80,7 +80,7 @@ def in_test(x: int128) -> bool: assert c.in_test(7) is True -def test_cmp_not_in_list(get_contract_with_gas_estimation): +def test_cmp_not_in_list(get_contract): code = """ @external def in_test(x: int128) -> bool: @@ -89,7 +89,7 @@ def in_test(x: int128) -> bool: return False """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.in_test(1) is True assert c.in_test(-7) is True @@ -98,7 +98,7 @@ def in_test(x: int128) -> bool: assert c.in_test(7) is False -def test_mixed_in_list(assert_compile_failed, get_contract_with_gas_estimation): +def test_mixed_in_list(assert_compile_failed, get_contract): code = """ @external def testin() -> bool: @@ -107,10 +107,10 @@ def testin() -> bool: return True return False """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code), TypeMismatch) + assert_compile_failed(lambda: get_contract(code), TypeMismatch) -def test_ownership(w3, tx_failed, get_contract_with_gas_estimation): +def test_ownership(env, tx_failed, get_contract): code = """ owners: address[2] @@ -128,25 +128,25 @@ def set_owner(i: int128, new_owner: address): def is_owner() -> bool: return msg.sender in self.owners """ - a1 = w3.eth.accounts[1] - c = get_contract_with_gas_estimation(code) + a1 = env.accounts[1] + c = get_contract(code) assert c.is_owner() is True # contract creator is owner. - assert c.is_owner(call={"from": a1}) is False # no one else is. + assert c.is_owner(sender=a1) is False # no one else is. # only an owner may set another owner. with tx_failed(): - c.set_owner(1, a1, call={"from": a1}) + c.set_owner(1, a1, sender=a1) - c.set_owner(1, a1, transact={}) - assert c.is_owner(call={"from": a1}) is True + c.set_owner(1, a1) + assert c.is_owner(sender=a1) is True # Owner in place 0 can be replaced. - c.set_owner(0, a1, transact={}) + c.set_owner(0, a1) assert c.is_owner() is False -def test_in_fails_when_types_dont_match(get_contract_with_gas_estimation, tx_failed): +def test_in_fails_when_types_dont_match(get_contract, tx_failed): code = """ @external def testin(x: address) -> bool: @@ -156,4 +156,4 @@ def testin(x: address) -> bool: return False """ with tx_failed(TypeMismatch): - get_contract_with_gas_estimation(code) + get_contract(code) diff --git a/tests/functional/codegen/features/test_address_balance.py b/tests/functional/codegen/features/test_address_balance.py index 58736cc07e..7777802405 100644 --- a/tests/functional/codegen/features/test_address_balance.py +++ b/tests/functional/codegen/features/test_address_balance.py @@ -1,4 +1,4 @@ -def test_constant_address_balance(w3, get_contract_with_gas_estimation): +def test_constant_address_balance(env, get_contract): code = """ a: constant(address) = 0x776Ba14735FF84789320718cf0aa43e91F7A8Ce1 @@ -9,10 +9,11 @@ def foo() -> uint256: """ address = "0x776Ba14735FF84789320718cf0aa43e91F7A8Ce1" - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == 0 - w3.eth.send_transaction({"to": address, "value": 1337}) + env.set_balance(env.deployer, 1337) + env.message_call(address, value=1337) assert c.foo() == 1337 diff --git a/tests/functional/codegen/features/test_assert.py b/tests/functional/codegen/features/test_assert.py index 406bade926..9604707916 100644 --- a/tests/functional/codegen/features/test_assert.py +++ b/tests/functional/codegen/features/test_assert.py @@ -1,32 +1,23 @@ import pytest -from eth_tester.exceptions import TransactionFailed -# web3 returns f"execution reverted: {err_str}" -# 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, tx_failed): +def test_assert_refund(env, get_contract, tx_failed): code = """ @external def foo(): raise """ - c = get_contract_with_gas_estimation(code) - a0 = w3.eth.accounts[0] + c = get_contract(code) + env.set_balance(env.deployer, 10**7) gas_sent = 10**6 - tx_hash = c.foo(transact={"from": a0, "gas": gas_sent, "gasPrice": 10}) - # More info on receipt status: - # https://github.com/ethereum/EIPs/blob/master/EIPS/eip-658.md#specification. - tx_receipt = w3.eth.get_transaction_receipt(tx_hash) - assert tx_receipt["status"] == 0 - # Checks for gas refund from revert - assert tx_receipt["gasUsed"] < gas_sent + with tx_failed(): + c.foo(gas=gas_sent, gas_price=10) + + # check we issued `revert`, which does not consume all gas + assert env.last_result.gas_used < gas_sent -def test_assert_reason(w3, get_contract_with_gas_estimation, tx_failed, memory_mocker): +def test_assert_reason(env, get_contract, tx_failed, memory_mocker): code = """ err: String[32] @@ -57,36 +48,33 @@ def test5(reason_str: String[32]): self.err = reason_str raise self.err """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.test(2) == 3 - with pytest.raises(TransactionFailed) as e_info: + with tx_failed(exc_text="larger than one please"): c.test(0) - assert _fixup_err_str(e_info.value.args[0]) == "larger than one please" # a = 0, b = 1 - with pytest.raises(TransactionFailed) as e_info: + with tx_failed(exc_text="a is not large enough"): c.test2(0, 1, "") - assert _fixup_err_str(e_info.value.args[0]) == "a is not large enough" + # a = 1, b = 0 - with pytest.raises(TransactionFailed) as e_info: + with tx_failed(exc_text="b may only be 1 because I said so"): c.test2(2, 2, " because I said so") - assert _fixup_err_str(e_info.value.args[0]) == "b may only be 1" + " because I said so" + # return correct value assert c.test2(5, 1, "") == 17 - with pytest.raises(TransactionFailed) as e_info: + with tx_failed(exc_text="An exception"): c.test3("An exception") - assert _fixup_err_str(e_info.value.args[0]) == "An exception" assert c.test4(2, "msg") == 3 - with pytest.raises(TransactionFailed) as e_info: + + with tx_failed(exc_text="larger than one again please"): c.test4(0, "larger than one again please") - assert _fixup_err_str(e_info.value.args[0]) == "larger than one again please" - with pytest.raises(TransactionFailed) as e_info: + with tx_failed(exc_text="A storage exception"): c.test5("A storage exception") - assert _fixup_err_str(e_info.value.args[0]) == "A storage exception" invalid_code = [ @@ -146,7 +134,7 @@ def test_valid_assertions(get_contract, code): get_contract(code) -def test_assert_staticcall(get_contract, tx_failed, memory_mocker): +def test_assert_staticcall(get_contract, env, tx_failed, memory_mocker): foreign_code = """ state: uint256 @external @@ -159,14 +147,15 @@ def not_really_constant() -> uint256: def not_really_constant() -> uint256: view @external -def test(): - assert staticcall ForeignContract(msg.sender).not_really_constant() == 1 +def test(c: ForeignContract): + assert staticcall c.not_really_constant() == 1 """ c1 = get_contract(foreign_code) - c2 = get_contract(code, *[c1.address]) + c2 = get_contract(code) + # static call prohibits state change with tx_failed(): - c2.test() + c2.test(c1.address) def test_assert_in_for_loop(get_contract, tx_failed, memory_mocker): @@ -209,7 +198,7 @@ def test(x: uint256[3]) -> bool: c.test([1, 3, 5]) -def test_assert_reason_revert_length(w3, get_contract, tx_failed, memory_mocker): +def test_assert_reason_revert_length(env, get_contract, tx_failed, memory_mocker): code = """ @external def test() -> int128: diff --git a/tests/functional/codegen/features/test_assert_unreachable.py b/tests/functional/codegen/features/test_assert_unreachable.py index 4db00bce7c..ee6ccef8da 100644 --- a/tests/functional/codegen/features/test_assert_unreachable.py +++ b/tests/functional/codegen/features/test_assert_unreachable.py @@ -1,21 +1,20 @@ -def test_unreachable_refund(w3, get_contract): +def test_unreachable_refund(env, get_contract, tx_failed): code = """ @external def foo(): assert msg.sender != msg.sender, UNREACHABLE """ + env.set_balance(env.deployer, 10**20) c = get_contract(code) - a0 = w3.eth.accounts[0] gas_sent = 10**6 - tx_hash = c.foo(transact={"from": a0, "gas": gas_sent, "gasPrice": 10}) - tx_receipt = w3.eth.get_transaction_receipt(tx_hash) + with tx_failed(): + c.foo(gas=gas_sent, gas_price=10) - assert tx_receipt["status"] == 0 - assert tx_receipt["gasUsed"] == gas_sent # Drains all gains sent + assert env.last_result.gas_used == gas_sent # Drains all gas sent per INVALID opcode -def test_basic_unreachable(w3, get_contract, tx_failed): +def test_basic_unreachable(env, get_contract, tx_failed): code = """ @external def foo(val: int128) -> bool: @@ -28,15 +27,15 @@ def foo(val: int128) -> bool: assert c.foo(2) is True - with tx_failed(exc_text="Invalid opcode 0xfe"): + with tx_failed(exc_text=env.INVALID_OPCODE_ERROR): c.foo(1) - with tx_failed(exc_text="Invalid opcode 0xfe"): + with tx_failed(exc_text=env.INVALID_OPCODE_ERROR): c.foo(-1) - with tx_failed(exc_text="Invalid opcode 0xfe"): + with tx_failed(exc_text=env.INVALID_OPCODE_ERROR): c.foo(-2) -def test_basic_call_unreachable(w3, get_contract, tx_failed): +def test_basic_call_unreachable(env, get_contract, tx_failed): code = """ @view @@ -54,13 +53,13 @@ def foo(val: int128) -> int128: assert c.foo(33) == -123 - with tx_failed(exc_text="Invalid opcode 0xfe"): + with tx_failed(exc_text=env.INVALID_OPCODE_ERROR): c.foo(1) - with tx_failed(exc_text="Invalid opcode 0xfe"): + with tx_failed(exc_text=env.INVALID_OPCODE_ERROR): c.foo(-1) -def test_raise_unreachable(w3, get_contract, tx_failed): +def test_raise_unreachable(env, get_contract, tx_failed): code = """ @external def foo(): @@ -69,5 +68,5 @@ def foo(): c = get_contract(code) - with tx_failed(exc_text="Invalid opcode 0xfe"): + with tx_failed(exc_text=env.INVALID_OPCODE_ERROR): c.foo() diff --git a/tests/functional/codegen/features/test_assignment.py b/tests/functional/codegen/features/test_assignment.py index 8f3270e4bc..eaafb527c1 100644 --- a/tests/functional/codegen/features/test_assignment.py +++ b/tests/functional/codegen/features/test_assignment.py @@ -3,7 +3,7 @@ from vyper.exceptions import ImmutableViolation, InvalidType, TypeMismatch -def test_augassign(get_contract_with_gas_estimation): +def test_augassign(get_contract): augassign_test = """ @external def augadd(x: int128, y: int128) -> int128: @@ -30,7 +30,7 @@ def augmod(x: int128, y: int128) -> int128: return z """ - c = get_contract_with_gas_estimation(augassign_test) + c = get_contract(augassign_test) assert c.augadd(5, 12) == 17 assert c.augmul(5, 12) == 60 @@ -48,7 +48,7 @@ def augmod(x: int128, y: int128) -> int128: ("Bytes[5]", b"vyper", b"conda"), ], ) -def test_internal_assign(get_contract_with_gas_estimation, typ, in_val, out_val): +def test_internal_assign(get_contract, typ, in_val, out_val): code = f""" @internal def foo(x: {typ}) -> {typ}: @@ -59,12 +59,12 @@ def foo(x: {typ}) -> {typ}: def bar(x: {typ}) -> {typ}: return self.foo(x) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.bar(in_val) == out_val -def test_internal_assign_struct(get_contract_with_gas_estimation): +def test_internal_assign_struct(get_contract): code = """ flag Bar: BAD @@ -85,12 +85,12 @@ def foo(x: Foo) -> Foo: def bar(x: Foo) -> Foo: return self.foo(x) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.bar((123, [1, 2, 4], "vyper")) == (789, [4, 2, 1], "conda") -def test_internal_assign_struct_member(get_contract_with_gas_estimation): +def test_internal_assign_struct_member(get_contract): code = """ flag Bar: BAD @@ -112,12 +112,12 @@ def foo(x: Foo) -> Foo: def bar(x: Foo) -> Foo: return self.foo(x) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.bar((123, [1, 2, 4], "vyper")) == (789, [1, 2], "vyper") -def test_internal_augassign(get_contract_with_gas_estimation): +def test_internal_augassign(get_contract): code = """ @internal def foo(x: int128) -> int128: @@ -128,13 +128,13 @@ def foo(x: int128) -> int128: def bar(x: int128) -> int128: return self.foo(x) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.bar(123) == 200 @pytest.mark.parametrize("typ", ["DynArray[uint256, 3]", "uint256[3]"]) -def test_internal_augassign_arrays(get_contract_with_gas_estimation, typ): +def test_internal_augassign_arrays(get_contract, typ): code = f""" @internal def foo(x: {typ}) -> {typ}: @@ -145,30 +145,30 @@ def foo(x: {typ}) -> {typ}: def bar(x: {typ}) -> {typ}: return self.foo(x) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.bar([1, 2, 3]) == [1, 79, 3] -def test_invalid_external_assign(assert_compile_failed, get_contract_with_gas_estimation): +def test_invalid_external_assign(assert_compile_failed, get_contract): code = """ @external def foo(x: int128): x = 5 """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code), ImmutableViolation) + assert_compile_failed(lambda: get_contract(code), ImmutableViolation) -def test_invalid_external_augassign(assert_compile_failed, get_contract_with_gas_estimation): +def test_invalid_external_augassign(assert_compile_failed, get_contract): code = """ @external def foo(x: int128): x += 5 """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code), ImmutableViolation) + assert_compile_failed(lambda: get_contract(code), ImmutableViolation) -def test_valid_literal_increment(get_contract_with_gas_estimation): +def test_valid_literal_increment(get_contract): code = """ storx: uint256 @@ -190,14 +190,14 @@ def foo3(y: uint256) -> uint256: self.storx += 1 return self.storx """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo1() == 123 assert c.foo2() == 123 assert c.foo3(11) == 12 -def test_invalid_uint256_assignment(assert_compile_failed, get_contract_with_gas_estimation): +def test_invalid_uint256_assignment(assert_compile_failed, get_contract): code = """ storx: uint256 @@ -207,10 +207,10 @@ def foo2() -> uint256: x += 1 return x """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code), TypeMismatch) + assert_compile_failed(lambda: get_contract(code), TypeMismatch) -def test_invalid_uint256_assignment_calculate_literals(get_contract_with_gas_estimation): +def test_invalid_uint256_assignment_calculate_literals(get_contract): code = """ storx: uint256 @@ -220,13 +220,13 @@ def foo2() -> uint256: x = 3 * 4 // 2 + 1 - 2 return x """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo2() == 5 # See #838. Confirm that nested keys and structs work properly. -def test_nested_map_key_works(get_contract_with_gas_estimation): +def test_nested_map_key_works(get_contract): code = """ struct X: a: int128 @@ -248,12 +248,12 @@ def get(i: int128) -> int128: idx: int128 = self.test_map1[i].a return self.test_map2[idx].c """ - c = get_contract_with_gas_estimation(code) - assert c.set(transact={}) + c = get_contract(code) + c.set() assert c.get(1) == 111 -def test_nested_map_key_problem(get_contract_with_gas_estimation): +def test_nested_map_key_problem(get_contract): code = """ struct X: a: int128 @@ -274,8 +274,8 @@ def set(): def get() -> int128: return self.test_map2[self.test_map1[1].a].c """ - c = get_contract_with_gas_estimation(code) - assert c.set(transact={}) + c = get_contract(code) + c.set() assert c.get() == 111 @@ -349,13 +349,11 @@ def foo(): """, ], ) -def test_invalid_implicit_conversions( - contract, assert_compile_failed, get_contract_with_gas_estimation -): - assert_compile_failed(lambda: get_contract_with_gas_estimation(contract), TypeMismatch) +def test_invalid_implicit_conversions(contract, assert_compile_failed, get_contract): + assert_compile_failed(lambda: get_contract(contract), TypeMismatch) -def test_invalid_nonetype_assignment(assert_compile_failed, get_contract_with_gas_estimation): +def test_invalid_nonetype_assignment(assert_compile_failed, get_contract): code = """ @internal def bar(): @@ -365,7 +363,7 @@ def bar(): def foo(): ret : bool = self.bar() """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code), InvalidType) + assert_compile_failed(lambda: get_contract(code), InvalidType) # GH issue 2418 diff --git a/tests/functional/codegen/features/test_bytes_map_keys.py b/tests/functional/codegen/features/test_bytes_map_keys.py index c70ffb26ce..dfb775015b 100644 --- a/tests/functional/codegen/features/test_bytes_map_keys.py +++ b/tests/functional/codegen/features/test_bytes_map_keys.py @@ -3,7 +3,7 @@ from vyper.exceptions import TypeMismatch -def test_basic_bytes_keys(w3, get_contract): +def test_basic_bytes_keys(env, get_contract): code = """ mapped_bytes: HashMap[Bytes[5], int128] @@ -18,7 +18,7 @@ def get(k: Bytes[5]) -> int128: c = get_contract(code) - c.set(b"test", 54321, transact={}) + c.set(b"test", 54321) assert c.get(b"test") == 54321 @@ -38,7 +38,7 @@ def get(k: Bytes[5]) -> int128: c = get_contract(code) - c.set(54321, transact={}) + c.set(54321) assert c.get(b"test") == 54321 @@ -58,7 +58,7 @@ def get(k: Bytes[34]) -> int128: c = get_contract(code) - c.set(b"a" * 34, 6789, transact={"gas": 10**6}) + c.set(b"a" * 34, 6789, gas=10**6) assert c.get(b"a" * 34) == 6789 diff --git a/tests/functional/codegen/features/test_clampers.py b/tests/functional/codegen/features/test_clampers.py index 5df8ac4970..1adffcf29a 100644 --- a/tests/functional/codegen/features/test_clampers.py +++ b/tests/functional/codegen/features/test_clampers.py @@ -4,23 +4,23 @@ from eth.codecs import abi from eth_utils import keccak -from tests.utils import decimal_to_int +from tests.utils import ZERO_ADDRESS, decimal_to_int from vyper.exceptions import StackTooDeep from vyper.utils import int_bounds -def _make_tx(w3, address, signature, values): - # helper function to broadcast transactions that fail clamping check +def _make_tx(env, address, signature, values): + # helper function to create data that will fail runtime clamp sig = keccak(signature.encode()).hex()[:8] data = "".join(int(i).to_bytes(32, "big", signed=i < 0).hex() for i in values) - w3.eth.send_transaction({"to": address, "data": f"0x{sig}{data}"}) + env.message_call(address, data=f"0x{sig}{data}") -def _make_abi_encode_tx(w3, address, signature, input_types, values): +def _make_abi_encode_tx(env, address, signature, input_types, values): # helper function to broadcast transactions where data is constructed from abi_encode sig = keccak(signature.encode()).hex()[:8] data = abi.encode(input_types, values).hex() - w3.eth.send_transaction({"to": address, "data": f"0x{sig}{data}"}) + env.message_call(address, data=f"0x{sig}{data}") def _make_dynarray_data(offset, length, values): @@ -29,26 +29,26 @@ def _make_dynarray_data(offset, length, values): return data -def _make_invalid_dynarray_tx(w3, address, signature, data): +def _make_invalid_dynarray_tx(env, address, signature, data): sig = keccak(signature.encode()).hex()[:8] - w3.eth.send_transaction({"to": address, "data": f"0x{sig}{data}"}) + env.message_call(address, data=f"0x{sig}{data}") -def test_bytes_clamper(tx_failed, get_contract_with_gas_estimation): +def test_bytes_clamper(tx_failed, get_contract): clamper_test_code = """ @external def foo(s: Bytes[3]) -> Bytes[3]: return s """ - c = get_contract_with_gas_estimation(clamper_test_code) + c = get_contract(clamper_test_code) assert c.foo(b"ca") == b"ca" assert c.foo(b"cat") == b"cat" with tx_failed(): c.foo(b"cate") -def test_bytes_clamper_multiple_slots(tx_failed, get_contract_with_gas_estimation): +def test_bytes_clamper_multiple_slots(tx_failed, get_contract): clamper_test_code = """ @external def foo(s: Bytes[40]) -> Bytes[40]: @@ -56,7 +56,7 @@ def foo(s: Bytes[40]) -> Bytes[40]: """ data = b"this is exactly forty characters long!!!" - c = get_contract_with_gas_estimation(clamper_test_code) + c = get_contract(clamper_test_code) assert c.foo(data[:30]) == data[:30] assert c.foo(data) == data @@ -64,7 +64,7 @@ def foo(s: Bytes[40]) -> Bytes[40]: c.foo(data + b"!") -def test_bytes_clamper_on_init(tx_failed, get_contract_with_gas_estimation): +def test_bytes_clamper_on_init(tx_failed, get_contract): clamper_test_code = """ foo: Bytes[3] @@ -77,15 +77,15 @@ def get_foo() -> Bytes[3]: return self.foo """ - c = get_contract_with_gas_estimation(clamper_test_code, *[b"cat"]) + c = get_contract(clamper_test_code, b"cat") assert c.get_foo() == b"cat" with tx_failed(): - get_contract_with_gas_estimation(clamper_test_code, *[b"cats"]) + get_contract(clamper_test_code, b"cats") @pytest.mark.parametrize("n", list(range(1, 33))) -def test_bytes_m_clamper_passing(w3, get_contract, n): +def test_bytes_m_clamper_passing(env, get_contract, n): values = [b"\xff" * (i + 1) for i in range(n)] code = f""" @@ -101,7 +101,7 @@ def foo(s: bytes{n}) -> bytes{n}: @pytest.mark.parametrize("n", list(range(1, 32))) # bytes32 always passes -def test_bytes_m_clamper_failing(w3, get_contract, tx_failed, n): +def test_bytes_m_clamper_failing(env, get_contract, tx_failed, n): values = [] values.append(b"\x00" * n + b"\x80") # just one bit set values.append(b"\xff" * n + b"\x80") # n*8 + 1 bits set @@ -120,13 +120,13 @@ def foo(s: bytes{n}) -> bytes{n}: c = get_contract(code) for v in values: # munge for `_make_tx` + int_value = int.from_bytes(v, byteorder="big") with tx_failed(): - int_value = int.from_bytes(v, byteorder="big") - _make_tx(w3, c.address, f"foo(bytes{n})", [int_value]) + _make_tx(env, c.address, f"foo(bytes{n})", [int_value]) @pytest.mark.parametrize("n", list(range(32))) -def test_sint_clamper_passing(w3, get_contract, n): +def test_sint_clamper_passing(env, get_contract, n): bits = 8 * (n + 1) lo, hi = int_bounds(True, bits) values = [-1, 0, 1, lo, hi] @@ -142,7 +142,7 @@ def foo(s: int{bits}) -> int{bits}: @pytest.mark.parametrize("n", list(range(31))) # int256 does not clamp -def test_sint_clamper_failing(w3, tx_failed, get_contract, n): +def test_sint_clamper_failing(env, tx_failed, get_contract, n): bits = 8 * (n + 1) lo, hi = int_bounds(True, bits) values = [-(2**255), 2**255 - 1, lo - 1, hi + 1] @@ -155,11 +155,11 @@ def foo(s: int{bits}) -> int{bits}: c = get_contract(code) for v in values: with tx_failed(): - _make_tx(w3, c.address, f"foo(int{bits})", [v]) + _make_tx(env, c.address, f"foo(int{bits})", [v]) @pytest.mark.parametrize("value", [True, False]) -def test_bool_clamper_passing(w3, get_contract, value): +def test_bool_clamper_passing(env, get_contract, value): code = """ @external def foo(s: bool) -> bool: @@ -171,7 +171,7 @@ def foo(s: bool) -> bool: @pytest.mark.parametrize("value", [2, 3, 4, 8, 16, 2**256 - 1]) -def test_bool_clamper_failing(w3, tx_failed, get_contract, value): +def test_bool_clamper_failing(env, tx_failed, get_contract, value): code = """ @external def foo(s: bool) -> bool: @@ -180,11 +180,11 @@ def foo(s: bool) -> bool: c = get_contract(code) with tx_failed(): - _make_tx(w3, c.address, "foo(bool)", [value]) + _make_tx(env, c.address, "foo(bool)", [value]) @pytest.mark.parametrize("value", [0] + [2**i for i in range(5)]) -def test_flag_clamper_passing(w3, get_contract, value): +def test_flag_clamper_passing(env, get_contract, value): code = """ flag Roles: USER @@ -203,7 +203,7 @@ def foo(s: Roles) -> Roles: @pytest.mark.parametrize("value", [2**i for i in range(5, 256)]) -def test_flag_clamper_failing(w3, tx_failed, get_contract, value): +def test_flag_clamper_failing(env, tx_failed, get_contract, value): code = """ flag Roles: USER @@ -219,11 +219,11 @@ def foo(s: Roles) -> Roles: c = get_contract(code) with tx_failed(): - _make_tx(w3, c.address, "foo(uint256)", [value]) + _make_tx(env, c.address, "foo(uint256)", [value]) @pytest.mark.parametrize("n", list(range(32))) -def test_uint_clamper_passing(w3, get_contract, n): +def test_uint_clamper_passing(env, get_contract, n): bits = 8 * (n + 1) values = [0, 1, 2**bits - 1] code = f""" @@ -238,7 +238,7 @@ def foo(s: uint{bits}) -> uint{bits}: @pytest.mark.parametrize("n", list(range(31))) # uint256 has no failing cases -def test_uint_clamper_failing(w3, tx_failed, get_contract, n): +def test_uint_clamper_failing(env, tx_failed, get_contract, n): bits = 8 * (n + 1) values = [-1, -(2**255), 2**bits] code = f""" @@ -249,24 +249,18 @@ def foo(s: uint{bits}) -> uint{bits}: c = get_contract(code) for v in values: with tx_failed(): - _make_tx(w3, c.address, f"foo(uint{bits})", [v]) + _make_tx(env, c.address, f"foo(uint{bits})", [v]) @pytest.mark.parametrize( - "value,expected", + "address", [ - ("0x0000000000000000000000000000000000000000", None), - ( - "0x0000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000001", - ), - ( - "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF", - "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF", - ), + ZERO_ADDRESS, + "0x0000000000000000000000000000000000000001", + "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF", ], ) -def test_address_clamper_passing(w3, get_contract, value, expected): +def test_address_clamper_passing(get_contract, address): code = """ @external def foo(s: address) -> address: @@ -274,11 +268,11 @@ def foo(s: address) -> address: """ c = get_contract(code) - assert c.foo(value) == expected + assert c.foo(address) == address @pytest.mark.parametrize("value", [2**160, 2**256 - 1]) -def test_address_clamper_failing(w3, tx_failed, get_contract, value): +def test_address_clamper_failing(env, tx_failed, get_contract, value): code = """ @external def foo(s: address) -> address: @@ -287,7 +281,7 @@ def foo(s: address) -> address: c = get_contract(code) with tx_failed(): - _make_tx(w3, c.address, "foo(address)", [value]) + _make_tx(env, c.address, "foo(address)", [value]) @pytest.mark.parametrize( @@ -330,7 +324,7 @@ def foo(s: decimal) -> decimal: -187072209578355573530071658587684226515959365500929, # - (2 ** 127 - 1e-10) ], ) -def test_decimal_clamper_failing(w3, tx_failed, get_contract, value): +def test_decimal_clamper_failing(env, tx_failed, get_contract, value): code = """ @external def foo(s: decimal) -> decimal: @@ -340,11 +334,11 @@ def foo(s: decimal) -> decimal: c = get_contract(code) with tx_failed(): - _make_tx(w3, c.address, "foo(int168)", [value]) + _make_tx(env, c.address, "foo(int168)", [value]) @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) -def test_int128_array_clamper_passing(w3, get_contract, value): +def test_int128_array_clamper_passing(get_contract, value): code = """ @external def foo(a: uint256, b: int128[5], c: uint256) -> int128[5]: @@ -360,7 +354,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, tx_failed, get_contract, bad_value, idx): +def test_int128_array_clamper_failing(env, tx_failed, get_contract, bad_value, idx): # ensure the invalid value is detected at all locations in the array code = """ @external @@ -373,11 +367,11 @@ def foo(b: int128[5]) -> int128[5]: c = get_contract(code) with tx_failed(): - _make_tx(w3, c.address, "foo(int128[5])", values) + _make_tx(env, c.address, "foo(int128[5])", values) @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) -def test_int128_array_looped_clamper_passing(w3, get_contract, value): +def test_int128_array_looped_clamper_passing(get_contract, value): # when an array is > 5 items, the arg clamper runs in a loop to reduce bytecode size code = """ @external @@ -392,7 +386,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, tx_failed, get_contract, bad_value, idx): +def test_int128_array_looped_clamper_failing(env, tx_failed, get_contract, bad_value, idx): code = """ @external def foo(b: int128[10]) -> int128[10]: @@ -404,11 +398,11 @@ def foo(b: int128[10]) -> int128[10]: c = get_contract(code) with tx_failed(): - _make_tx(w3, c.address, "foo(int128[10])", values) + _make_tx(env, c.address, "foo(int128[10])", values) @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) -def test_multidimension_array_clamper_passing(w3, get_contract, value): +def test_multidimension_array_clamper_passing(get_contract, value): code = """ @external def foo(a: uint256, b: int128[6][3][1][8], c: uint256) -> int128[6][3][1][8]: @@ -418,12 +412,12 @@ def foo(a: uint256, b: int128[6][3][1][8], c: uint256) -> int128[6][3][1][8]: # 6 * 3 * 1 * 8 = 144, the total number of values in our multidimensional array d = [[[[value] * 6] * 3] * 1] * 8 c = get_contract(code) - assert c.foo(2**127, d, 2**127, call={"gasPrice": 0}) == d + assert c.foo(2**127, d, 2**127) == d @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, tx_failed, get_contract, bad_value, idx): +def test_multidimension_array_clamper_failing(env, tx_failed, get_contract, bad_value, idx): code = """ @external def foo(b: int128[6][1][2]) -> int128[6][1][2]: @@ -435,11 +429,11 @@ def foo(b: int128[6][1][2]) -> int128[6][1][2]: c = get_contract(code) with tx_failed(): - _make_tx(w3, c.address, "foo(int128[6][1][2]])", values) + _make_tx(env, c.address, "foo(int128[6][1][2]])", values) @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) -def test_int128_dynarray_clamper_passing(w3, get_contract, value): +def test_int128_dynarray_clamper_passing(get_contract, value): code = """ @external def foo(a: uint256, b: DynArray[int128, 5], c: uint256) -> DynArray[int128, 5]: @@ -455,7 +449,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, tx_failed, get_contract, bad_value, idx): +def test_int128_dynarray_clamper_failing(env, tx_failed, get_contract, bad_value, idx): # ensure the invalid value is detected at all locations in the array code = """ @external @@ -471,11 +465,11 @@ def foo(b: int128[5]) -> int128[5]: data = _make_dynarray_data(32, 5, values) with tx_failed(): - _make_invalid_dynarray_tx(w3, c.address, signature, data) + _make_invalid_dynarray_tx(env, c.address, signature, data) @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) -def test_int128_dynarray_looped_clamper_passing(w3, get_contract, value): +def test_int128_dynarray_looped_clamper_passing(get_contract, value): # when an array is > 5 items, the arg clamper runs in a loop to reduce bytecode size code = """ @external @@ -489,7 +483,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, tx_failed, get_contract, bad_value, idx): +def test_int128_dynarray_looped_clamper_failing(env, tx_failed, get_contract, bad_value, idx): code = """ @external def foo(b: DynArray[int128, 10]) -> DynArray[int128, 10]: @@ -504,12 +498,12 @@ def foo(b: DynArray[int128, 10]) -> DynArray[int128, 10]: data = _make_dynarray_data(32, 10, values) signature = "foo(int128[])" with tx_failed(): - _make_invalid_dynarray_tx(w3, c.address, signature, data) + _make_invalid_dynarray_tx(env, c.address, signature, data) @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) @pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") -def test_multidimension_dynarray_clamper_passing(w3, get_contract, value): +def test_multidimension_dynarray_clamper_passing(get_contract, value): code = """ @external def foo( @@ -522,12 +516,12 @@ def foo( # Out of gas exception if outermost length is 6 and greater d = [[[[value] * 5] * 6] * 7] * 8 c = get_contract(code) - assert c.foo(2**127, d, 2**127, call={"gasPrice": 0}) == d + assert c.foo(2**127, d, 2**127) == d @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, tx_failed, get_contract, bad_value, idx): +def test_multidimension_dynarray_clamper_failing(env, tx_failed, get_contract, bad_value, idx): code = """ @external def foo(b: DynArray[DynArray[int128, 2], 2]) -> DynArray[DynArray[int128, 2], 2]: @@ -548,11 +542,11 @@ def foo(b: DynArray[DynArray[int128, 2], 2]) -> DynArray[DynArray[int128, 2], 2] c = get_contract(code) with tx_failed(): - _make_invalid_dynarray_tx(w3, c.address, signature, data) + _make_invalid_dynarray_tx(env, c.address, signature, data) @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) -def test_dynarray_list_clamper_passing(w3, get_contract, value): +def test_dynarray_list_clamper_passing(get_contract, value): code = """ @external def foo( @@ -569,7 +563,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, tx_failed, get_contract, bad_value, idx): +def test_dynarray_list_clamper_failing(env, tx_failed, get_contract, bad_value, idx): # ensure the invalid value is detected at all locations in the array code = """ @external @@ -588,4 +582,4 @@ def foo(b: DynArray[int128[5], 2]) -> DynArray[int128[5], 2]: c = get_contract(code) signature = "foo(int128[5][])" with tx_failed(): - _make_invalid_dynarray_tx(w3, c.address, signature, data) + _make_invalid_dynarray_tx(env, c.address, signature, data) diff --git a/tests/functional/codegen/features/test_comments.py b/tests/functional/codegen/features/test_comments.py index 03d2ff20a6..1a96819745 100644 --- a/tests/functional/codegen/features/test_comments.py +++ b/tests/functional/codegen/features/test_comments.py @@ -1,4 +1,4 @@ -def test_comment_test(get_contract_with_gas_estimation): +def test_comment_test(get_contract): comment_test = """ @external def foo() -> int128: @@ -6,6 +6,6 @@ def foo() -> int128: return 3 """ - c = get_contract_with_gas_estimation(comment_test) + c = get_contract(comment_test) assert c.foo() == 3 print("Passed comment test") diff --git a/tests/functional/codegen/features/test_conditionals.py b/tests/functional/codegen/features/test_conditionals.py index 3b0e57eeca..355af5d39f 100644 --- a/tests/functional/codegen/features/test_conditionals.py +++ b/tests/functional/codegen/features/test_conditionals.py @@ -1,4 +1,4 @@ -def test_conditional_return_code(get_contract_with_gas_estimation): +def test_conditional_return_code(get_contract): conditional_return_code = """ @external def foo(i: bool) -> int128: @@ -9,25 +9,25 @@ def foo(i: bool) -> int128: return 7 """ - c = get_contract_with_gas_estimation(conditional_return_code) + c = get_contract(conditional_return_code) assert c.foo(True) == 5 assert c.foo(False) == 7 print("Passed conditional return tests") -def test_single_branch_underflow_public(get_contract_with_gas_estimation): +def test_single_branch_underflow_public(get_contract): code = """ @external def doit(): if False: raw_call(msg.sender, b"", max_outsize=0, value=0, gas=msg.gas) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) c.doit() -def test_single_branch_underflow_private(get_contract_with_gas_estimation): +def test_single_branch_underflow_private(get_contract): code = """ @internal def priv() -> uint256: @@ -38,5 +38,5 @@ def dont_doit(): if False: self.priv() """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) c.dont_doit() diff --git a/tests/functional/codegen/features/test_constructor.py b/tests/functional/codegen/features/test_constructor.py index 9146ace8a6..6cc7007bb2 100644 --- a/tests/functional/codegen/features/test_constructor.py +++ b/tests/functional/codegen/features/test_constructor.py @@ -1,8 +1,8 @@ -import pytest -from web3.exceptions import ValidationError +from tests.evm_backends.base_env import _compile +from vyper.utils import method_id -def test_init_argument_test(get_contract_with_gas_estimation): +def test_init_argument_test(get_contract): init_argument_test = """ moose: int128 @@ -15,12 +15,12 @@ def returnMoose() -> int128: return self.moose """ - c = get_contract_with_gas_estimation(init_argument_test, *[5]) + c = get_contract(init_argument_test, *[5]) assert c.returnMoose() == 5 print("Passed init argument test") -def test_constructor_mapping(get_contract_with_gas_estimation): +def test_constructor_mapping(get_contract): contract = """ foo: HashMap[bytes4, bool] @@ -36,11 +36,11 @@ def check_foo(a: bytes4) -> bool: return self.foo[a] """ - c = get_contract_with_gas_estimation(contract) + c = get_contract(contract) assert c.check_foo("0x01ffc9a7") is True -def test_constructor_advanced_code(get_contract_with_gas_estimation): +def test_constructor_advanced_code(get_contract): constructor_advanced_code = """ twox: int128 @@ -52,11 +52,11 @@ def __init__(x: int128): def get_twox() -> int128: return self.twox """ - c = get_contract_with_gas_estimation(constructor_advanced_code, *[5]) + c = get_contract(constructor_advanced_code, *[5]) assert c.get_twox() == 10 -def test_constructor_advanced_code2(get_contract_with_gas_estimation): +def test_constructor_advanced_code2(get_contract): constructor_advanced_code2 = """ comb: uint256 @@ -68,28 +68,31 @@ def __init__(x: uint256[2], y: Bytes[3], z: uint256): def get_comb() -> uint256: return self.comb """ - c = get_contract_with_gas_estimation(constructor_advanced_code2, *[[5, 7], b"dog", 8]) + c = get_contract(constructor_advanced_code2, *[[5, 7], b"dog", 8]) assert c.get_comb() == 5738 print("Passed advanced init argument tests") -def test_large_input_code(get_contract_with_gas_estimation): +def test_large_input_code(env, get_contract, tx_failed): large_input_code = """ @external def foo(x: int128) -> int128: return 3 """ - c = get_contract_with_gas_estimation(large_input_code) - c.foo(1274124) - c.foo(2**120) + c = get_contract(large_input_code) + signature = "(int128)" + method = method_id(f"foo{signature}") - with pytest.raises(ValidationError): - c.foo(2**130) + env.message_call(c.address, data=method + (1274124).to_bytes(32, "big")) + env.message_call(c.address, data=method + (2**120).to_bytes(32, "big")) + with tx_failed(): + env.message_call(c.address, data=method + (2**130).to_bytes(32, "big")) -def test_large_input_code_2(w3, get_contract_with_gas_estimation): - large_input_code_2 = """ + +def test_large_input_code_2(env, get_contract, tx_failed, output_formats): + code = """ @deploy def __init__(x: int128): y: int128 = x @@ -99,15 +102,15 @@ def foo() -> int128: return 5 """ - get_contract_with_gas_estimation(large_input_code_2, *[17]) - - with pytest.raises(TypeError): - get_contract_with_gas_estimation(large_input_code_2, *[2**130]) + _, bytecode = _compile(code, output_formats) + ctor_args = (2**127 - 1).to_bytes(32, "big") + env._deploy(bytecode + ctor_args, value=0) - print("Passed invalid input tests") + with tx_failed(): + env._deploy(bytecode + (2**127).to_bytes(32, "big"), value=0) -def test_initialise_array_with_constant_key(get_contract_with_gas_estimation): +def test_initialise_array_with_constant_key(get_contract): contract = """ X: constant(uint256) = 4 @@ -123,11 +126,11 @@ def check_foo(a: uint256) -> int16: return self.foo[a] """ - c = get_contract_with_gas_estimation(contract) + c = get_contract(contract) assert c.check_foo(3) == -2 -def test_initialise_dynarray_with_constant_key(get_contract_with_gas_estimation): +def test_initialise_dynarray_with_constant_key(get_contract): contract = """ X: constant(int16) = 4 @@ -143,11 +146,11 @@ def check_foo(a: uint64) -> int16: return self.foo[a] """ - c = get_contract_with_gas_estimation(contract) + c = get_contract(contract) assert c.check_foo(3) == -2 -def test_nested_dynamic_array_constructor_arg(w3, get_contract_with_gas_estimation): +def test_nested_dynamic_array_constructor_arg(env, get_contract): code = """ foo: uint256 @@ -159,11 +162,11 @@ def __init__(x: DynArray[DynArray[uint256, 3], 3]): def get_foo() -> uint256: return self.foo """ - c = get_contract_with_gas_estimation(code, *[[[3, 5, 7], [11, 13, 17], [19, 23, 29]]]) + c = get_contract(code, *[[[3, 5, 7], [11, 13, 17], [19, 23, 29]]]) assert c.get_foo() == 39 -def test_nested_dynamic_array_constructor_arg_2(w3, get_contract_with_gas_estimation): +def test_nested_dynamic_array_constructor_arg_2(env, get_contract): code = """ foo: int128 @@ -175,7 +178,7 @@ def __init__(x: DynArray[DynArray[DynArray[int128, 3], 3], 3]): def get_foo() -> int128: return self.foo """ - c = get_contract_with_gas_estimation( + c = get_contract( code, *[ [ @@ -188,7 +191,7 @@ def get_foo() -> int128: assert c.get_foo() == 9580 -def test_initialise_nested_dynamic_array(w3, get_contract_with_gas_estimation): +def test_initialise_nested_dynamic_array(env, get_contract): code = """ foo: DynArray[DynArray[uint256, 3], 3] @@ -204,11 +207,11 @@ def __init__(x: uint256, y: uint256, z: uint256): def get_foo() -> DynArray[DynArray[uint256, 3], 3]: return self.foo """ - c = get_contract_with_gas_estimation(code, *[37, 41, 73]) + c = get_contract(code, *[37, 41, 73]) assert c.get_foo() == [[37, 41, 73], [37041, 41073, 73037], [146, 123, 148]] -def test_initialise_nested_dynamic_array_2(w3, get_contract_with_gas_estimation): +def test_initialise_nested_dynamic_array_2(env, get_contract): code = """ foo: DynArray[DynArray[DynArray[int128, 3], 3], 3] @@ -232,7 +235,7 @@ def __init__(x: int128, y: int128, z: int128): def get_foo() -> DynArray[DynArray[DynArray[int128, 3], 3], 3]: return self.foo """ - c = get_contract_with_gas_estimation(code, *[37, 41, 73]) + c = get_contract(code, *[37, 41, 73]) assert c.get_foo() == [ [[37, 41, 73], [41, 73, 37], [73, 41, 37]], [[37041, 41073, 73037], [-37041, -41073, -73037], [-36959, -40927, -72963]], diff --git a/tests/functional/codegen/features/test_gas.py b/tests/functional/codegen/features/test_gas.py index c62a463905..b8bc3a5063 100644 --- a/tests/functional/codegen/features/test_gas.py +++ b/tests/functional/codegen/features/test_gas.py @@ -1,11 +1,11 @@ -def test_gas_call(get_contract_with_gas_estimation): +def test_gas_call(get_contract): gas_call = """ @external def foo() -> uint256: return msg.gas """ - c = get_contract_with_gas_estimation(gas_call) + c = get_contract(gas_call) - assert c.foo(call={"gas": 50000}) < 50000 - assert c.foo(call={"gas": 50000}) > 25000 + assert c.foo(gas=50000) < 50000 + assert c.foo(gas=50000) > 25000 diff --git a/tests/functional/codegen/features/test_immutable.py b/tests/functional/codegen/features/test_immutable.py index 49ff54b353..c556e1ffc1 100644 --- a/tests/functional/codegen/features/test_immutable.py +++ b/tests/functional/codegen/features/test_immutable.py @@ -76,7 +76,7 @@ def get_values() -> (uint256, address, String[64]): """ values = (3, "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "Hello world") c = get_contract(code, *values) - assert c.get_values() == list(values) + assert c.get_values() == values def test_struct_immutable(get_contract): @@ -393,11 +393,11 @@ def fix(): assert c.x() == 2 assert c.d() == 2 - c.thrash(transact={}) + c.thrash() assert c.x() == 2 assert c.d() == 2 + 5 - c.fix(transact={}) + c.fix() assert c.x() == 2 assert c.d() == 2 diff --git a/tests/functional/codegen/features/test_internal_call.py b/tests/functional/codegen/features/test_internal_call.py index ad89341fd9..90c415d919 100644 --- a/tests/functional/codegen/features/test_internal_call.py +++ b/tests/functional/codegen/features/test_internal_call.py @@ -11,7 +11,7 @@ pytestmark = pytest.mark.usefixtures("memory_mocker") -def test_selfcall_code(get_contract_with_gas_estimation): +def test_selfcall_code(get_contract): selfcall_code = """ @internal def _foo() -> int128: @@ -22,13 +22,13 @@ def bar() -> int128: return self._foo() """ - c = get_contract_with_gas_estimation(selfcall_code) + c = get_contract(selfcall_code) assert c.bar() == 3 print("Passed no-argument self-call test") -def test_selfcall_code_2(get_contract_with_gas_estimation, keccak): +def test_selfcall_code_2(get_contract, keccak): selfcall_code_2 = """ @internal def _double(x: int128) -> int128: @@ -47,7 +47,7 @@ def return_hash_of_rzpadded_cow() -> bytes32: return self._hashy(0x636f770000000000000000000000000000000000000000000000000000000000) """ - c = get_contract_with_gas_estimation(selfcall_code_2) + c = get_contract(selfcall_code_2) assert c.returnten() == 10 assert c.return_hash_of_rzpadded_cow() == keccak(b"cow" + b"\x00" * 29) @@ -69,10 +69,10 @@ def foo() -> (uint256, uint256): return x, self.counter """ c = get_contract(code) - assert c.foo() == [0, 1] + assert c.foo() == (0, 1) -def test_selfcall_code_3(get_contract_with_gas_estimation, keccak): +def test_selfcall_code_3(get_contract, keccak): selfcall_code_3 = """ @internal def _hashy2(x: Bytes[100]) -> bytes32: @@ -91,14 +91,14 @@ def returnten() -> uint256: return self._len(b"badminton!") """ - c = get_contract_with_gas_estimation(selfcall_code_3) + c = get_contract(selfcall_code_3) assert c.return_hash_of_cow_x_30() == keccak(b"cow" * 30) assert c.returnten() == 10 print("Passed single variable-size argument self-call test") -def test_selfcall_code_4(get_contract_with_gas_estimation): +def test_selfcall_code_4(get_contract): selfcall_code_4 = """ @internal def _summy(x: int128, y: int128) -> int128: @@ -133,7 +133,7 @@ def return_goose2() -> Bytes[10]: return self._slicey2(5, b"goosedog") """ - c = get_contract_with_gas_estimation(selfcall_code_4) + c = get_contract(selfcall_code_4) assert c.returnten() == 10 assert c.return_mongoose() == b"mongoose" assert c.return_goose() == b"goose" @@ -142,7 +142,7 @@ def return_goose2() -> Bytes[10]: print("Passed multi-argument self-call test") -def test_selfcall_code_5(get_contract_with_gas_estimation): +def test_selfcall_code_5(get_contract): selfcall_code_5 = """ counter: int128 @@ -156,13 +156,13 @@ def returnten() -> int128: self._increment() return self.counter """ - c = get_contract_with_gas_estimation(selfcall_code_5) + c = get_contract(selfcall_code_5) assert c.returnten() == 10 print("Passed self-call statement test") -def test_selfcall_code_6(get_contract_with_gas_estimation): +def test_selfcall_code_6(get_contract): selfcall_code_6 = """ excls: Bytes[32] @@ -184,13 +184,13 @@ def return_mongoose_revolution_32_excls() -> Bytes[201]: return self._hardtest(b"megamongoose123", 4, 8, concat(b"russian revolution", self.excls), 8, 42) """ - c = get_contract_with_gas_estimation(selfcall_code_6) + c = get_contract(selfcall_code_6) assert c.return_mongoose_revolution_32_excls() == b"mongoose_revolution" + b"!" * 32 print("Passed composite self-call test") -def test_list_call(get_contract_with_gas_estimation): +def test_list_call(get_contract): code = """ @internal def _foo0(x: int128[2]) -> int128: @@ -221,14 +221,14 @@ def bar3() -> int128: return self._foo1(x) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.bar() == 0 assert c.foo1([0, 0]) == 0 assert c.bar2() == 55 assert c.bar3() == 66 -def test_list_storage_call(get_contract_with_gas_estimation): +def test_list_storage_call(get_contract): code = """ y: int128[2] @@ -253,13 +253,13 @@ def bar1() -> int128: return self._foo1(self.y) """ - c = get_contract_with_gas_estimation(code) - c.set(transact={}) + c = get_contract(code) + c.set() assert c.bar0() == 88 assert c.bar1() == 99 -def test_multi_arg_list_call(get_contract_with_gas_estimation): +def test_multi_arg_list_call(get_contract): code = """ @internal def _foo0(y: decimal, x: int128[2]) -> int128: @@ -322,7 +322,7 @@ def bar6() -> int128: """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.bar() == 0 assert c.foo1([0, 0], decimal_to_int("0")) == 0 assert c.bar2() == 55 @@ -331,7 +331,7 @@ def bar6() -> int128: assert c.bar5() == 88 -def test_multi_mixed_arg_list_call(get_contract_with_gas_estimation): +def test_multi_mixed_arg_list_call(get_contract): code = """ @internal def _fooz(x: int128[2], y: decimal, z: int128[2], a: decimal) -> int128: @@ -350,11 +350,11 @@ def bar() -> (int128, decimal): return self._fooz(x, y, z, a), self._fooa(x, y, z, a) """ - c = get_contract_with_gas_estimation(code) - assert c.bar() == [66, decimal_to_int("66.77")] + c = get_contract(code) + assert c.bar() == (66, decimal_to_int("66.77")) -def test_internal_function_multiple_lists_as_args(get_contract_with_gas_estimation): +def test_internal_function_multiple_lists_as_args(get_contract): code = """ @internal def _foo(y: int128[2], x: Bytes[5]) -> int128: @@ -373,12 +373,12 @@ def bar2() -> int128: return self._foo2(b"hello", [1, 2]) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.bar() == 1 assert c.bar2() == 1 -def test_multi_mixed_arg_list_bytes_call(get_contract_with_gas_estimation): +def test_multi_mixed_arg_list_bytes_call(get_contract): code = """ @internal def _fooz(x: int128[2], y: decimal, z: Bytes[11], a: decimal) -> Bytes[11]: @@ -402,8 +402,8 @@ def bar() -> (Bytes[11], decimal, int128): return self._fooz(x, y, z, a), self._fooa(x, y, z, a), self._foox(x, y, z, a) """ - c = get_contract_with_gas_estimation(code) - assert c.bar() == [b"hello world", decimal_to_int("66.77"), 44] + c = get_contract(code) + assert c.bar() == (b"hello world", decimal_to_int("66.77"), 44) FAILING_CONTRACTS_CALL_VIOLATION = [ @@ -541,7 +541,7 @@ def test_selfcall_kwarg_raises(failing_contract_code, decorator, assert_compile_ @pytest.mark.parametrize("i,ln,s,", [(100, 6, "abcde"), (41, 40, "a" * 34), (57, 70, "z" * 68)]) -def test_struct_return_1(get_contract_with_gas_estimation, i, ln, s): +def test_struct_return_1(get_contract, i, ln, s): contract = f""" struct X: x: int128 @@ -558,12 +558,12 @@ def test() -> (int128, String[{ln}], Bytes[{ln}]): return ret.x, ret.y, ret.z """ - c = get_contract_with_gas_estimation(contract) + c = get_contract(contract) - assert c.test() == [i, s, bytes(s, "utf-8")] + assert c.test() == (i, s, bytes(s, "utf-8")) -def test_dynamically_sized_struct_as_arg(get_contract_with_gas_estimation): +def test_dynamically_sized_struct_as_arg(get_contract): contract = """ struct X: x: uint256 @@ -579,12 +579,12 @@ def bar() -> Bytes[6]: return self._foo(_X) """ - c = get_contract_with_gas_estimation(contract) + c = get_contract(contract) assert c.bar() == b"hello" -def test_dynamically_sized_struct_as_arg_2(get_contract_with_gas_estimation): +def test_dynamically_sized_struct_as_arg_2(get_contract): contract = """ struct X: x: uint256 @@ -600,12 +600,12 @@ def bar() -> String[6]: return self._foo(_X) """ - c = get_contract_with_gas_estimation(contract) + c = get_contract(contract) assert c.bar() == "hello" -def test_dynamically_sized_struct_member_as_arg(get_contract_with_gas_estimation): +def test_dynamically_sized_struct_member_as_arg(get_contract): contract = """ struct X: x: uint256 @@ -621,12 +621,12 @@ def bar() -> Bytes[6]: return self._foo(_X.y) """ - c = get_contract_with_gas_estimation(contract) + c = get_contract(contract) assert c.bar() == b"hello" -def test_dynamically_sized_struct_member_as_arg_2(get_contract_with_gas_estimation): +def test_dynamically_sized_struct_member_as_arg_2(get_contract): contract = """ struct X: x: uint256 @@ -642,7 +642,7 @@ def bar() -> String[6]: return self._foo(_X.y) """ - c = get_contract_with_gas_estimation(contract) + c = get_contract(contract) assert c.bar() == "hello" @@ -697,10 +697,10 @@ def test4(x1: {typ1}, x2: {typ2}) -> ({typ1}, {typ2}): return self.foo(x1, x2) """ c = get_contract(code) - assert c.test0() == [default1, default2] - assert c.test1() == [kwarg1, default2] - assert c.test2() == [kwarg1, kwarg2] - assert c.test3(kwarg1) == [kwarg1, default2] - assert c.test4(kwarg1, kwarg2) == [kwarg1, kwarg2] + assert c.test0() == (default1, default2) + assert c.test1() == (kwarg1, default2) + assert c.test2() == (kwarg1, kwarg2) + assert c.test3(kwarg1) == (kwarg1, default2) + assert c.test4(kwarg1, kwarg2) == (kwarg1, kwarg2) fuzz() diff --git a/tests/functional/codegen/features/test_logging.py b/tests/functional/codegen/features/test_logging.py index f8d30429a8..fef9f50763 100644 --- a/tests/functional/codegen/features/test_logging.py +++ b/tests/functional/codegen/features/test_logging.py @@ -1,5 +1,6 @@ import pytest from eth.codecs import abi +from eth_utils import to_text from tests.utils import decimal_to_int from vyper import compile_code @@ -17,7 +18,7 @@ pytestmark = pytest.mark.usefixtures("memory_mocker") -def test_empty_event_logging(w3, tester, keccak, get_contract_with_gas_estimation): +def test_empty_event_logging(get_logs, keccak, get_contract): loggy_code = """ event MyLog: pass @@ -26,26 +27,21 @@ def foo(): log MyLog() """ - c = get_contract_with_gas_estimation(loggy_code) - tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c = get_contract(loggy_code) + c.foo() + (log,) = get_logs(c) event_id = keccak(bytes("MyLog()", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() + assert log.topics == [event_id] # Event abi is created correctly - assert c._classic_contract.abi[0] == { - "name": "MyLog", - "inputs": [], - "anonymous": False, - "type": "event", - } + assert c.abi[0] == {"name": "MyLog", "inputs": [], "anonymous": False, "type": "event"} # Event is decoded correctly - assert hasattr(c._classic_contract.events, "MyLog") + assert log.event == "MyLog" -def test_event_logging_with_topics(w3, tester, keccak, get_logs, get_contract_with_gas_estimation): +def test_event_logging_with_topics(get_logs, keccak, get_contract): loggy_code = """ a: Bytes[3] @@ -59,15 +55,15 @@ def foo(): log MyLog(self.a) """ - c = get_contract_with_gas_estimation(loggy_code) - tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c = get_contract(loggy_code) + c.foo() event_id = keccak(bytes("MyLog(bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() + (log,) = get_logs(c) + assert log.topics[0] == event_id # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "name": "MyLog", "inputs": [{"type": "bytes", "name": "arg1", "indexed": True}], "anonymous": False, @@ -75,9 +71,7 @@ def foo(): } -def test_event_logging_with_multiple_topics( - w3, tester, keccak, get_logs, get_contract_with_gas_estimation -): +def test_event_logging_with_multiple_topics(env, keccak, get_logs, get_contract): loggy_code = """ event MyLog: arg1: indexed(int128) @@ -89,15 +83,15 @@ def foo(): log MyLog(-2, True, self) """ - c = get_contract_with_gas_estimation(loggy_code) - tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c = get_contract(loggy_code) + c.foo() event_id = keccak(bytes("MyLog(int128,bool,address)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() + (log,) = get_logs(c) + assert log.topics[0] == event_id # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "name": "MyLog", "inputs": [ {"type": "int128", "name": "arg1", "indexed": True}, @@ -108,16 +102,14 @@ def foo(): "type": "event", } # Event is decoded correctly - logs = get_logs(tx_hash, c, "MyLog") - assert logs[0].event == "MyLog" - assert logs[0].args.arg1 == -2 - assert logs[0].args.arg2 is True - assert logs[0].args.arg3 == c._classic_contract.address + (log,) = get_logs(c, "MyLog") + assert log.event == "MyLog" + assert log.args.arg1 == -2 + assert log.args.arg2 is True + assert log.args.arg3 == c.address -def test_event_logging_with_multiple_topics_var_and_store( - tester, get_contract_with_gas_estimation, get_logs -): +def test_event_logging_with_multiple_topics_var_and_store(get_contract, get_logs): code = """ event MyLog: arg1: indexed(int128) @@ -133,20 +125,17 @@ def foo(arg1: int128): log MyLog(arg1, a, self.b) """ - c = get_contract_with_gas_estimation(code) - tx_hash = c.foo(31337, transact={}) + c = get_contract(code) + c.foo(31337) # Event is decoded correctly - log = get_logs(tx_hash, c, "MyLog")[0] - + (log,) = get_logs(c, "MyLog") assert log.args.arg1 == 31337 assert log.args.arg2 is True assert log.args.arg3 == c.address -def test_logging_the_same_event_multiple_times_with_topics( - w3, tester, keccak, get_logs, get_contract_with_gas_estimation -): +def test_logging_the_same_event_multiple_times_with_topics(env, keccak, get_logs, get_contract): loggy_code = """ event MyLog: arg1: indexed(int128) @@ -163,18 +152,18 @@ def bar(): log MyLog(1, self) """ - c = get_contract_with_gas_estimation(loggy_code) - tx_hash1 = c.foo(transact={}) - tx_hash2 = c.bar(transact={}) - receipt1 = tester.get_transaction_receipt(tx_hash1.hex()) - receipt2 = tester.get_transaction_receipt(tx_hash2.hex()) + c = get_contract(loggy_code) + c.foo() + log1, log2 = get_logs(c) + c.bar() + log3, _ = get_logs(c) event_id = keccak(bytes("MyLog(int128,address)", "utf-8")) # Event id is always the first topic - assert receipt1["logs"][0]["topics"][0] == "0x" + event_id.hex() - assert receipt2["logs"][0]["topics"][0] == "0x" + event_id.hex() + assert log1.topics[0] == event_id + assert log3.topics[0] == event_id # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "name": "MyLog", "inputs": [ {"type": "int128", "name": "arg1", "indexed": True}, @@ -185,16 +174,13 @@ def bar(): } # Event is decoded correctly - logs = get_logs(tx_hash1, c, "MyLog") - assert logs[0].args.arg1 == 1 - assert logs[0].args.arg2 == c.address - assert logs[1].args.arg1 == 1 - assert logs[1].args.arg2 == c.address + assert log1.args.arg1 == 1 + assert log1.args.arg2 == c.address + assert log2.args.arg1 == 1 + assert log2.args.arg2 == c.address -def test_event_logging_cannot_have_more_than_three_topics( - tx_failed, get_contract_with_gas_estimation -): +def test_event_logging_cannot_have_more_than_three_topics(tx_failed, get_contract): loggy_code = """ event MyLog: arg1: indexed(Bytes[3]) @@ -207,7 +193,7 @@ def test_event_logging_cannot_have_more_than_three_topics( compile_code(loggy_code) -def test_event_logging_with_data(w3, tester, keccak, get_logs, get_contract_with_gas_estimation): +def test_event_logging_with_data(get_logs, keccak, get_contract): loggy_code = """ event MyLog: arg1: int128 @@ -217,15 +203,15 @@ def foo(): log MyLog(123) """ - c = get_contract_with_gas_estimation(loggy_code) - tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c = get_contract(loggy_code) + c.foo() event_id = keccak(bytes("MyLog(int128)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() + (log,) = get_logs(c) + assert log.topics == [event_id] # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "name": "MyLog", "inputs": [{"type": "int128", "name": "arg1", "indexed": False}], "anonymous": False, @@ -233,13 +219,11 @@ def foo(): } # Event is decoded correctly - logs = get_logs(tx_hash, c, "MyLog") - assert logs[0].args.arg1 == 123 + (log,) = get_logs(c, "MyLog") + assert log.args.arg1 == 123 -def test_event_logging_with_fixed_array_data( - w3, tester, keccak, get_logs, get_contract_with_gas_estimation -): +def test_event_logging_with_fixed_array_data(env, keccak, get_logs, get_contract): loggy_code = """ event MyLog: arg1: int128[2] @@ -253,16 +237,16 @@ def foo(): log MyLog([1,2], [block.timestamp, block.timestamp+1, block.timestamp+2], [[1,2],[1,2]]) """ - c = get_contract_with_gas_estimation(loggy_code) - tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c = get_contract(loggy_code) + c.foo() event_id = keccak(bytes("MyLog(int128[2],uint256[3],int128[2][2])", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() + log, _ = get_logs(c) + assert log.topics == [event_id] # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "name": "MyLog", "inputs": [ {"type": "int128[2]", "name": "arg1", "indexed": False}, @@ -274,17 +258,13 @@ def foo(): } # Event is decoded correctly - timestamp = w3.eth.get_block(w3.eth.block_number).timestamp - logs = get_logs(tx_hash, c, "MyLog") + timestamp = env.timestamp + assert log.args.arg1 == [1, 2] + assert log.args.arg2 == [timestamp, timestamp + 1, timestamp + 2] + assert log.args.arg3 == [[1, 2], [1, 2]] - assert logs[0].args.arg1 == [1, 2] - assert logs[0].args.arg2 == [timestamp, timestamp + 1, timestamp + 2] - assert logs[0].args.arg3 == [[1, 2], [1, 2]] - -def test_logging_with_input_bytes_1( - w3, tester, keccak, get_logs, bytes_helper, get_contract_with_gas_estimation -): +def test_logging_with_input_bytes_1(env, keccak, get_logs, get_contract): loggy_code = """ event MyLog: arg1: Bytes[4] @@ -296,15 +276,15 @@ def foo(arg1: Bytes[29], arg2: Bytes[31]): log MyLog(b'bar', arg1, arg2) """ - c = get_contract_with_gas_estimation(loggy_code) - tx_hash = c.foo(b"bar", b"foo", transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c = get_contract(loggy_code) + c.foo(b"bar", b"foo") event_id = keccak(bytes("MyLog(bytes,bytes,bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() + (log,) = get_logs(c) + assert log.topics[0] == event_id # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "name": "MyLog", "inputs": [ {"type": "bytes", "name": "arg1", "indexed": False}, @@ -315,16 +295,14 @@ def foo(arg1: Bytes[29], arg2: Bytes[31]): "type": "event", } # Event is decoded correctly - logs = get_logs(tx_hash, c, "MyLog") + (log,) = get_logs(c, "MyLog") - assert logs[0].args.arg1 == b"bar" - assert logs[0].args.arg2 == keccak(b"bar") - assert logs[0].args.arg3 == b"foo" + assert log.args.arg1 == b"bar" + assert log.args.arg2 == keccak(b"bar") + assert log.args.arg3 == b"foo" -def test_event_logging_with_bytes_input_2( - w3, tester, keccak, get_logs, get_contract_with_gas_estimation -): +def test_event_logging_with_bytes_input_2(env, keccak, get_logs, get_contract): loggy_code = """ event MyLog: arg1: Bytes[20] @@ -334,26 +312,25 @@ def foo(_arg1: Bytes[20]): log MyLog(_arg1) """ - c = get_contract_with_gas_estimation(loggy_code) - tx_hash = c.foo(b"hello", transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c = get_contract(loggy_code) + c.foo(b"hello") event_id = keccak(bytes("MyLog(bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() + (log,) = get_logs(c) + assert log.topics[0] == event_id # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "anonymous": False, "inputs": [{"indexed": False, "name": "arg1", "type": "bytes"}], "name": "MyLog", "type": "event", } # Event is decoded correctly - logs = get_logs(tx_hash, c, "MyLog") - assert logs[0].args.arg1 == b"hello" + assert log.args.arg1 == b"hello" -def test_event_logging_with_bytes_input_3(w3, tester, keccak, get_logs, get_contract): +def test_event_logging_with_bytes_input_3(get_logs, keccak, get_contract): loggy_code = """ event MyLog: arg1: Bytes[5] @@ -364,27 +341,25 @@ def foo(_arg1: Bytes[5]): """ c = get_contract(loggy_code) - tx_hash = c.foo(b"hello", transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c.foo(b"hello") event_id = keccak(bytes("MyLog(bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() + (log,) = get_logs(c) + assert log.topics == [event_id] # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "anonymous": False, "inputs": [{"indexed": False, "name": "arg1", "type": "bytes"}], "name": "MyLog", "type": "event", } # Event is decoded correctly - logs = get_logs(tx_hash, c, "MyLog") - assert logs[0].args.arg1 == b"hello" + (log,) = get_logs(c, "MyLog") + assert log.args.arg1 == b"hello" -def test_event_logging_with_data_with_different_types( - w3, tester, keccak, get_logs, get_contract_with_gas_estimation -): +def test_event_logging_with_data_with_different_types(env, keccak, get_logs, get_contract): loggy_code = """ event MyLog: arg1: int128 @@ -399,15 +374,15 @@ def foo(): log MyLog(123, b'home', b'bar', 0xc305c901078781C232A2a521C2aF7980f8385ee9, self, block.timestamp) # noqa: E501 """ - c = get_contract_with_gas_estimation(loggy_code) - tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c = get_contract(loggy_code) + c.foo() event_id = keccak(bytes("MyLog(int128,bytes,bytes,address,address,uint256)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() + (log,) = get_logs(c) + assert log.topics == [event_id] # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "name": "MyLog", "inputs": [ {"type": "int128", "name": "arg1", "indexed": False}, @@ -422,20 +397,16 @@ def foo(): } # Event is decoded correctly - timestamp = w3.eth.get_block(w3.eth.block_number).timestamp - logs = get_logs(tx_hash, c, "MyLog") - args = logs[0].args + args = log.args assert args.arg1 == 123 assert args.arg2 == b"home" assert args.arg3 == b"bar" assert args.arg4 == "0xc305c901078781C232A2a521C2aF7980f8385ee9" assert args.arg5 == c.address - assert args.arg6 == timestamp + assert args.arg6 == env.timestamp -def test_event_logging_with_topics_and_data_1( - w3, tester, keccak, get_logs, get_contract_with_gas_estimation -): +def test_event_logging_with_topics_and_data_1(env, keccak, get_logs, get_contract): loggy_code = """ event MyLog: arg1: indexed(int128) @@ -446,15 +417,15 @@ def foo(): log MyLog(1, b'bar') """ - c = get_contract_with_gas_estimation(loggy_code) - tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c = get_contract(loggy_code) + c.foo() event_id = keccak(bytes("MyLog(int128,bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() + (log,) = get_logs(c) + assert log.topics[0] == event_id # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "anonymous": False, "inputs": [ {"indexed": True, "name": "arg1", "type": "int128"}, @@ -464,15 +435,12 @@ def foo(): "type": "event", } # Event is decoded correctly - logs = get_logs(tx_hash, c, "MyLog") - args = logs[0].args - assert args.arg1 == 1 - assert args.arg2 == b"bar" + (log,) = get_logs(c, "MyLog") + assert log.args.arg1 == 1 + assert log.args.arg2 == b"bar" -def test_event_logging_with_multiple_logs_topics_and_data( - w3, tester, keccak, get_logs, get_contract_with_gas_estimation -): +def test_event_logging_with_multiple_logs_topics_and_data(env, keccak, get_logs, get_contract): loggy_code = """ struct SmallStruct: t: String[5] @@ -495,20 +463,18 @@ def foo(): log YourLog(self, MyStruct(x=1, y=b'abc', z=SmallStruct(t='house', w=13.5))) """ - c = get_contract_with_gas_estimation(loggy_code) - tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c = get_contract(loggy_code) + c.foo() - logs1 = receipt["logs"][0] - logs2 = receipt["logs"][1] + log1, log2 = get_logs(c) event_id1 = keccak(bytes("MyLog(int128,bytes)", "utf-8")) event_id2 = keccak(bytes("YourLog(address,(uint256,bytes,(string,int168)))", "utf-8")) # Event id is always the first topic - assert logs1["topics"][0] == "0x" + event_id1.hex() - assert logs2["topics"][0] == "0x" + event_id2.hex() + assert log1.topics[0] == event_id1 + assert log2.topics[0] == event_id2 # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "name": "MyLog", "inputs": [ {"type": "int128", "name": "arg1", "indexed": True}, @@ -517,7 +483,7 @@ def foo(): "anonymous": False, "type": "event", } - assert c._classic_contract.abi[1] == { + assert c.abi[1] == { "name": "YourLog", "inputs": [ {"name": "arg1", "type": "address", "indexed": True}, @@ -544,17 +510,16 @@ def foo(): } # Event is decoded correctly - logs = get_logs(tx_hash, c, "MyLog") - args = logs[0].args - assert args.arg1 == 1 - assert args.arg2 == b"bar" - logs = get_logs(tx_hash, c, "YourLog") - args = logs[0].args - assert args.arg1 == c.address - assert args.arg2 == {"x": 1, "y": b"abc", "z": {"t": "house", "w": decimal_to_int("13.5")}} + (my_log,) = get_logs(c, "MyLog") + assert my_log.args.arg1 == 1 + assert my_log.args.arg2 == b"bar" + (your_log,) = get_logs(c, "YourLog") + assert your_log.args.arg1 == c.address + assert your_log.args.arg2 == (1, b"abc", ("house", decimal_to_int("13.5"))) -def test_fails_when_input_is_the_wrong_type(tx_failed, get_contract_with_gas_estimation): + +def test_fails_when_input_is_the_wrong_type(tx_failed, get_contract): loggy_code = """ event MyLog: arg1: indexed(int128) @@ -565,10 +530,10 @@ def foo_(): """ with tx_failed(TypeMismatch): - get_contract_with_gas_estimation(loggy_code) + get_contract(loggy_code) -def test_fails_when_topic_is_the_wrong_size(tx_failed, get_contract_with_gas_estimation): +def test_fails_when_topic_is_the_wrong_size(tx_failed, get_contract): loggy_code = """ event MyLog: arg1: indexed(Bytes[3]) @@ -580,10 +545,10 @@ def foo(): """ with tx_failed(TypeMismatch): - get_contract_with_gas_estimation(loggy_code) + get_contract(loggy_code) -def test_fails_when_input_topic_is_the_wrong_size(tx_failed, get_contract_with_gas_estimation): +def test_fails_when_input_topic_is_the_wrong_size(tx_failed, get_contract): loggy_code = """ event MyLog: arg1: indexed(Bytes[3]) @@ -594,10 +559,10 @@ def foo(arg1: Bytes[4]): """ with tx_failed(TypeMismatch): - get_contract_with_gas_estimation(loggy_code) + get_contract(loggy_code) -def test_fails_when_data_is_the_wrong_size(tx_failed, get_contract_with_gas_estimation): +def test_fails_when_data_is_the_wrong_size(tx_failed, get_contract): loggy_code = """ event MyLog: arg1: Bytes[3] @@ -608,10 +573,10 @@ def foo(): """ with tx_failed(TypeMismatch): - get_contract_with_gas_estimation(loggy_code) + get_contract(loggy_code) -def test_fails_when_input_data_is_the_wrong_size(tx_failed, get_contract_with_gas_estimation): +def test_fails_when_input_data_is_the_wrong_size(tx_failed, get_contract): loggy_code = """ event MyLog: arg1: Bytes[3] @@ -622,10 +587,10 @@ def foo(arg1: Bytes[4]): """ with tx_failed(TypeMismatch): - get_contract_with_gas_estimation(loggy_code) + get_contract(loggy_code) -def test_topic_over_32_bytes(get_contract_with_gas_estimation): +def test_topic_over_32_bytes(get_contract): loggy_code = """ event MyLog: arg1: indexed(Bytes[100]) @@ -634,10 +599,10 @@ def test_topic_over_32_bytes(get_contract_with_gas_estimation): def foo(): pass """ - get_contract_with_gas_estimation(loggy_code) + get_contract(loggy_code) -def test_logging_fails_with_over_three_topics(tx_failed, get_contract_with_gas_estimation): +def test_logging_fails_with_over_three_topics(tx_failed, get_contract): loggy_code = """ event MyLog: arg1: indexed(int128) @@ -651,10 +616,10 @@ def __init__(): """ with tx_failed(EventDeclarationException): - get_contract_with_gas_estimation(loggy_code) + get_contract(loggy_code) -def test_logging_fails_with_duplicate_log_names(tx_failed, get_contract_with_gas_estimation): +def test_logging_fails_with_duplicate_log_names(tx_failed, get_contract): loggy_code = """ event MyLog: pass event MyLog: pass @@ -665,10 +630,10 @@ def foo(): """ with tx_failed(NamespaceCollision): - get_contract_with_gas_estimation(loggy_code) + get_contract(loggy_code) -def test_logging_fails_with_when_log_is_undeclared(tx_failed, get_contract_with_gas_estimation): +def test_logging_fails_with_when_log_is_undeclared(tx_failed, get_contract): loggy_code = """ @external @@ -677,10 +642,10 @@ def foo(): """ with tx_failed(UndeclaredDefinition): - get_contract_with_gas_estimation(loggy_code) + get_contract(loggy_code) -def test_logging_fails_with_topic_type_mismatch(tx_failed, get_contract_with_gas_estimation): +def test_logging_fails_with_topic_type_mismatch(tx_failed, get_contract): loggy_code = """ event MyLog: arg1: indexed(int128) @@ -691,10 +656,10 @@ def foo(): """ with tx_failed(TypeMismatch): - get_contract_with_gas_estimation(loggy_code) + get_contract(loggy_code) -def test_logging_fails_with_data_type_mismatch(tx_failed, get_contract_with_gas_estimation): +def test_logging_fails_with_data_type_mismatch(tx_failed, get_contract): loggy_code = """ event MyLog: arg1: Bytes[3] @@ -705,11 +670,11 @@ def foo(): """ with tx_failed(TypeMismatch): - get_contract_with_gas_estimation(loggy_code) + get_contract(loggy_code) def test_logging_fails_when_number_of_arguments_is_greater_than_declaration( - tx_failed, get_contract_with_gas_estimation + tx_failed, get_contract ): loggy_code = """ event MyLog: @@ -720,12 +685,10 @@ def foo(): log MyLog(1, 2) """ with tx_failed(ArgumentException): - get_contract_with_gas_estimation(loggy_code) + get_contract(loggy_code) -def test_logging_fails_when_number_of_arguments_is_less_than_declaration( - tx_failed, get_contract_with_gas_estimation -): +def test_logging_fails_when_number_of_arguments_is_less_than_declaration(tx_failed, get_contract): loggy_code = """ event MyLog: arg1: int128 @@ -736,10 +699,10 @@ def foo(): log MyLog(1) """ with tx_failed(ArgumentException): - get_contract_with_gas_estimation(loggy_code) + get_contract(loggy_code) -def test_loggy_code(w3, tester, get_contract_with_gas_estimation): +def test_loggy_code(get_logs, get_contract): loggy_code = """ s: Bytes[100] @@ -761,35 +724,32 @@ def ioo(inp: Bytes[100]): raw_log([], inp) """ - c = get_contract_with_gas_estimation(loggy_code) + c = get_contract(loggy_code) + + c.foo() + ((topics, data),) = get_logs(c, raw=True) - tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) - logs = receipt["logs"] + assert to_text(data) == "moo" + c.goo() + ((topics, data),) = get_logs(c, raw=True) - assert w3.to_text(logs[0]["data"]) == "moo" - tx_hash = c.goo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) - logs = receipt["logs"] - assert w3.to_text(logs[0]["data"]) == "moo2" - assert ( - logs[0]["topics"][0] == "0x1234567812345678123456781234567812345678123456781234567812345678" - ) # noqa: E501 + assert to_text(data) == "moo2" + assert topics[0] == bytes.fromhex( + "1234567812345678123456781234567812345678123456781234567812345678" + ) - tx_hash = c.hoo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) - logs = receipt["logs"] - assert w3.to_text(logs[0]["data"]) == "moo3" + c.hoo() + ((topics, data),) = get_logs(c, raw=True) + assert to_text(data) == "moo3" - tx_hash = c.ioo(b"moo4", transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) - logs = receipt["logs"] - assert w3.to_text(logs[0]["data"]) == "moo4" + c.ioo(b"moo4") + ((topics, data),) = get_logs(c, raw=True) + assert to_text(data) == "moo4" print("Passed raw log tests") -def test_raw_call_bytes32_data(w3, tester, get_contract_with_gas_estimation): +def test_raw_call_bytes32_data(get_logs, get_contract): code = """ b: uint256 @@ -802,17 +762,16 @@ def foo(): raw_log([], convert(b"testmessage", bytes32)) raw_log([], keccak256(b"")) """ - c = get_contract_with_gas_estimation(code) - tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) - logs = receipt["logs"] - assert logs[0]["data"] == w3.to_hex((1234).to_bytes(32, "big")) - assert logs[1]["data"] == w3.to_hex((4321).to_bytes(32, "big")) - assert logs[2]["data"] == w3.to_hex(b"testmessage").ljust(32 * 2 + 2, "0") - assert logs[3]["data"] == w3.to_hex(keccak256(b"")) + c = get_contract(code) + c.foo() + logs = get_logs(c, raw=True) + assert logs[0][1] == (1234).to_bytes(32, "big") + assert logs[1][1] == (4321).to_bytes(32, "big") + assert logs[2][1] == b"testmessage".ljust(32, b"\0") + assert logs[3][1] == keccak256(b"") -def test_variable_list_packing(get_logs, get_contract_with_gas_estimation): +def test_variable_list_packing(get_logs, get_contract): code = """ event Bar: _value: int128[4] @@ -822,14 +781,14 @@ def foo(): a: int128[4] = [1, 2, 3, 4] log Bar(a) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) - tx_hash = c.foo(transact={}) - logs = get_logs(tx_hash, c, "Bar") - assert logs[0].args._value == [1, 2, 3, 4] + c.foo() + (log,) = get_logs(c, "Bar") + assert log.args._value == [1, 2, 3, 4] -def test_literal_list_packing(get_logs, get_contract_with_gas_estimation): +def test_literal_list_packing(get_logs, get_contract): code = """ event Bar: _value: int128[4] @@ -838,14 +797,14 @@ def test_literal_list_packing(get_logs, get_contract_with_gas_estimation): def foo(): log Bar([1, 2, 3, 4]) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) - tx_hash = c.foo(transact={}) - logs = get_logs(tx_hash, c, "Bar") - assert logs[0].args._value == [1, 2, 3, 4] + c.foo() + (log,) = get_logs(c, "Bar") + assert log.args._value == [1, 2, 3, 4] -def test_storage_list_packing(get_logs, bytes_helper, get_contract_with_gas_estimation): +def test_storage_list_packing(get_logs, get_contract): code = """ event Bar: _value: int128[4] @@ -860,18 +819,18 @@ def foo(): def set_list(): self.x = [1, 2, 3, 4] """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) - tx_hash = c.foo(transact={}) - logs = get_logs(tx_hash, c, "Bar") - assert logs[0].args._value == [0, 0, 0, 0] - c.set_list(transact={}) - tx_hash = c.foo(transact={}) - logs = get_logs(tx_hash, c, "Bar") - assert logs[0].args._value == [1, 2, 3, 4] + c.foo() + (log,) = get_logs(c, "Bar") + assert log.args._value == [0, 0, 0, 0] + c.set_list() + c.foo() + (log,) = get_logs(c, "Bar") + assert log.args._value == [1, 2, 3, 4] -def test_passed_list_packing(get_logs, get_contract_with_gas_estimation): +def test_passed_list_packing(get_logs, get_contract): code = """ event Bar: _value: int128[4] @@ -880,14 +839,14 @@ def test_passed_list_packing(get_logs, get_contract_with_gas_estimation): def foo(barbaric: int128[4]): log Bar(barbaric) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) - tx_hash = c.foo([4, 5, 6, 7], transact={}) - logs = get_logs(tx_hash, c, "Bar") - assert logs[0].args._value == [4, 5, 6, 7] + c.foo([4, 5, 6, 7]) + (log,) = get_logs(c, "Bar") + assert log.args._value == [4, 5, 6, 7] -def test_variable_decimal_list_packing(get_logs, get_contract_with_gas_estimation): +def test_variable_decimal_list_packing(get_logs, get_contract): code = """ event Bar: _value: decimal[4] @@ -896,11 +855,11 @@ def test_variable_decimal_list_packing(get_logs, get_contract_with_gas_estimatio def foo(): log Bar([1.11, 2.22, 3.33, 4.44]) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) - tx_hash = c.foo(transact={}) - logs = get_logs(tx_hash, c, "Bar") - assert logs[0].args._value == [ + c.foo() + (log,) = get_logs(c, "Bar") + assert log.args._value == [ decimal_to_int("1.11"), decimal_to_int("2.22"), decimal_to_int("3.33"), @@ -908,7 +867,7 @@ def foo(): ] -def test_storage_byte_packing(get_logs, bytes_helper, get_contract_with_gas_estimation): +def test_storage_byte_packing(get_logs, get_contract): code = """ event MyLog: arg1: Bytes[29] @@ -924,17 +883,17 @@ def setbytez(): self.x = b'hello' """ - c = get_contract_with_gas_estimation(code) - tx_hash = c.foo(0, transact={}) - logs = get_logs(tx_hash, c, "MyLog") - assert logs[0].args.arg1 == b"" - c.setbytez(transact={}) - tx_hash = c.foo(0, transact={}) - logs = get_logs(tx_hash, c, "MyLog") - assert logs[0].args.arg1 == b"hello" + c = get_contract(code) + c.foo(0) + (log,) = get_logs(c, "MyLog") + assert log.args.arg1 == b"" + c.setbytez() + c.foo(0) + (log,) = get_logs(c, "MyLog") + assert log.args.arg1 == b"hello" -def test_storage_decimal_list_packing(get_logs, bytes_helper, get_contract_with_gas_estimation): +def test_storage_decimal_list_packing(get_logs, get_contract): code = """ event Bar: _value: decimal[4] @@ -949,15 +908,15 @@ def foo(): def set_list(): self.x = [1.33, 2.33, 3.33, 4.33] """ - c = get_contract_with_gas_estimation(code) - - tx_hash = c.foo(transact={}) - logs = get_logs(tx_hash, c, "Bar") - assert logs[0].args._value == [decimal_to_int("0")] * 4 - c.set_list(transact={}) - tx_hash = c.foo(transact={}) - logs = get_logs(tx_hash, c, "Bar") - assert logs[0].args._value == [ + c = get_contract(code) + + c.foo() + (log,) = get_logs(c, "Bar") + assert log.args._value == [decimal_to_int("0")] * 4 + c.set_list() + c.foo() + (log,) = get_logs(c, "Bar") + assert log.args._value == [ decimal_to_int("1.33"), decimal_to_int("2.33"), decimal_to_int("3.33"), @@ -965,7 +924,7 @@ def set_list(): ] -def test_logging_fails_when_input_is_too_big(tx_failed, get_contract_with_gas_estimation): +def test_logging_fails_when_input_is_too_big(tx_failed, get_contract): code = """ event Bar: _value: indexed(Bytes[32]) @@ -975,10 +934,10 @@ def foo(inp: Bytes[33]): log Bar(inp) """ with tx_failed(TypeMismatch): - get_contract_with_gas_estimation(code) + get_contract(code) -def test_2nd_var_list_packing(get_logs, get_contract_with_gas_estimation): +def test_2nd_var_list_packing(get_logs, get_contract): code = """ event Bar: arg1: int128 @@ -989,13 +948,13 @@ def foo(): a: int128[4] = [1, 2, 3, 4] log Bar(10, a) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) - tx_hash = c.foo(transact={}) - assert get_logs(tx_hash, c, "Bar")[0].args.arg2 == [1, 2, 3, 4] + c.foo() + assert get_logs(c, "Bar")[0].args.arg2 == [1, 2, 3, 4] -def test_2nd_var_storage_list_packing(get_logs, get_contract_with_gas_estimation): +def test_2nd_var_storage_list_packing(get_logs, get_contract): code = """ event Bar: arg1: int128 @@ -1011,16 +970,16 @@ def foo(): def set_list(): self.x = [1, 2, 3, 4] """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) - tx_hash = c.foo(transact={}) - assert get_logs(tx_hash, c, "Bar")[0].args.arg2 == [0, 0, 0, 0] - c.set_list(transact={}) - tx_hash = c.foo(transact={}) - assert get_logs(tx_hash, c, "Bar")[0].args.arg2 == [1, 2, 3, 4] + c.foo() + assert get_logs(c, "Bar")[0].args.arg2 == [0, 0, 0, 0] + c.set_list() + c.foo() + assert get_logs(c, "Bar")[0].args.arg2 == [1, 2, 3, 4] -def test_mixed_var_list_packing(get_logs, get_contract_with_gas_estimation): +def test_mixed_var_list_packing(get_logs, get_contract): code = """ event Bar: arg1: int128 @@ -1045,24 +1004,25 @@ def foo(): def set_list(): self.x = [1, 2, 3, 4] """ - c = get_contract_with_gas_estimation(code) - - tx_hash = c.foo(transact={}) - log = get_logs(tx_hash, c, "Bar")[0] - assert log.args["arg2"] == [0, 0, 0, 0] - assert log.args["arg3"] == b"test" - assert log.args["arg4"] == [7, 8, 9] - assert log.args["arg5"] == [1024, 2048] - c.set_list(transact={}) - tx_hash = c.foo(transact={}) - log = get_logs(tx_hash, c, "Bar")[0] - assert log.args["arg2"] == [1, 2, 3, 4] - assert log.args["arg3"] == b"test" - assert log.args["arg4"] == [7, 8, 9] - assert log.args["arg5"] == [1024, 2048] - - -def test_hashed_indexed_topics_calldata(tester, keccak, get_contract): + c = get_contract(code) + + c.foo() + (log,) = get_logs(c, "Bar") + assert log.args.arg2 == [0, 0, 0, 0] + assert log.args.arg3 == b"test" + assert log.args.arg4 == [7, 8, 9] + assert log.args.arg5 == [1024, 2048] + + c.set_list() + c.foo() + (log,) = get_logs(c, "Bar") + assert log.args.arg2 == [1, 2, 3, 4] + assert log.args.arg3 == b"test" + assert log.args.arg4 == [7, 8, 9] + assert log.args.arg5 == [1024, 2048] + + +def test_hashed_indexed_topics_calldata(get_logs, keccak, get_contract): loggy_code = """ event MyLog: arg1: indexed(Bytes[36]) @@ -1075,24 +1035,19 @@ def foo(a: Bytes[36], b: int128, c: String[7]): """ c = get_contract(loggy_code) - tx_hash = c.foo(b"bar", 1, "weird", transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c.foo(b"bar", 1, "weird") # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() - - topic1 = f"0x{keccak256(b'bar').hex()}" - assert receipt["logs"][0]["topics"][1] == topic1 + topic1 = keccak256(b"bar") + topic2 = abi.encode("int128", 1) + topic3 = keccak256(b"weird") - topic2 = f"0x{abi.encode('int128', 1).hex()}" - assert receipt["logs"][0]["topics"][2] == topic2 - - topic3 = f"0x{keccak256(b'weird').hex()}" - assert receipt["logs"][0]["topics"][3] == topic3 + (log,) = get_logs(c) + assert log.topics == [event_id, topic1, topic2, topic3] # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "name": "MyLog", "inputs": [ {"type": "bytes", "name": "arg1", "indexed": True}, @@ -1104,7 +1059,7 @@ def foo(a: Bytes[36], b: int128, c: String[7]): } -def test_hashed_indexed_topics_memory(tester, keccak, get_contract): +def test_hashed_indexed_topics_memory(get_logs, keccak, get_contract): loggy_code = """ event MyLog: arg1: indexed(Bytes[10]) @@ -1120,24 +1075,18 @@ def foo(): """ c = get_contract(loggy_code) - tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c.foo() # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() - - topic1 = f"0x{keccak256(b'potato').hex()}" - assert receipt["logs"][0]["topics"][1] == topic1 - - topic2 = f"0x{abi.encode('int128', -777).hex()}" - assert receipt["logs"][0]["topics"][2] == topic2 - - topic3 = f"0x{keccak256(b'why hello, neighbor! how are you today?').hex()}" - assert receipt["logs"][0]["topics"][3] == topic3 + topic1 = keccak256(b"potato") + topic2 = abi.encode("int128", -777) + topic3 = keccak256(b"why hello, neighbor! how are you today?") + (log,) = get_logs(c) + assert log.topics == [event_id, topic1, topic2, topic3] # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "name": "MyLog", "inputs": [ {"type": "bytes", "name": "arg1", "indexed": True}, @@ -1149,7 +1098,7 @@ def foo(): } -def test_hashed_indexed_topics_storage(tester, keccak, get_contract): +def test_hashed_indexed_topics_storage(get_logs, keccak, get_contract): loggy_code = """ event MyLog: arg1: indexed(Bytes[32]) @@ -1173,25 +1122,20 @@ def foo(): """ c = get_contract(loggy_code) - c.setter(b"zonk", -2109, "yessir", transact={}) - tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c.setter(b"zonk", -2109, "yessir") + c.foo() # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() - - topic1 = f"0x{keccak256(b'zonk').hex()}" - assert receipt["logs"][0]["topics"][1] == topic1 - - topic2 = f"0x{abi.encode('int128', -2109).hex()}" - assert receipt["logs"][0]["topics"][2] == topic2 + topic1 = keccak256(b"zonk") + topic2 = abi.encode("int128", -2109) + topic3 = keccak256(b"yessir") - topic3 = f"0x{keccak256(b'yessir').hex()}" - assert receipt["logs"][0]["topics"][3] == topic3 + (log,) = get_logs(c) + assert log.topics == [event_id, topic1, topic2, topic3] # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "name": "MyLog", "inputs": [ {"type": "bytes", "name": "arg1", "indexed": True}, @@ -1203,7 +1147,7 @@ def foo(): } -def test_hashed_indexed_topics_storxxage(tester, keccak, get_contract): +def test_hashed_indexed_topics_storxxage(get_logs, keccak, get_contract): loggy_code = """ event MyLog: arg1: indexed(Bytes[64]) @@ -1216,21 +1160,16 @@ def foo(): """ c = get_contract(loggy_code) - tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c.foo() # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() - - topic1 = f"0x{keccak256(b'wow').hex()}" - assert receipt["logs"][0]["topics"][1] == topic1 - - topic2 = f"0x{abi.encode('int128', 666).hex()}" - assert receipt["logs"][0]["topics"][2] == topic2 + topic1 = keccak256(b"wow") + topic2 = abi.encode("int128", 666) + topic3 = keccak256(b"madness!") - topic3 = f"0x{keccak256(b'madness!').hex()}" - assert receipt["logs"][0]["topics"][3] == topic3 + (log,) = get_logs(c) + assert log.topics == [event_id, topic1, topic2, topic3] fail_list = [ @@ -1280,5 +1219,5 @@ def foo(): @pytest.mark.parametrize("bad_code,exc", fail_list) -def test_raw_log_fail(get_contract_with_gas_estimation, bad_code, exc, assert_compile_failed): - assert_compile_failed(lambda: get_contract_with_gas_estimation(bad_code), exc) +def test_raw_log_fail(get_contract, bad_code, exc, assert_compile_failed): + assert_compile_failed(lambda: get_contract(bad_code), exc) diff --git a/tests/functional/codegen/features/test_logging_bytes_extended.py b/tests/functional/codegen/features/test_logging_bytes_extended.py index 4ee83dd3fc..6b84cdd23a 100644 --- a/tests/functional/codegen/features/test_logging_bytes_extended.py +++ b/tests/functional/codegen/features/test_logging_bytes_extended.py @@ -1,4 +1,4 @@ -def test_bytes_logging_extended(get_contract_with_gas_estimation, get_logs): +def test_bytes_logging_extended(get_contract, get_logs): code = """ event MyLog: arg1: int128 @@ -10,15 +10,16 @@ def foo(): log MyLog(667788, b'hellohellohellohellohellohellohellohellohello', 334455) """ - c = get_contract_with_gas_estimation(code) - log = get_logs(c.foo(transact={}), c, "MyLog") + c = get_contract(code) + c.foo() + (log,) = get_logs(c, "MyLog") - assert log[0].args.arg1 == 667788 - assert log[0].args.arg2 == b"hello" * 9 - assert log[0].args.arg3 == 334455 + assert log.args.arg1 == 667788 + assert log.args.arg2 == b"hello" * 9 + assert log.args.arg3 == 334455 -def test_bytes_logging_extended_variables(get_contract_with_gas_estimation, get_logs): +def test_bytes_logging_extended_variables(get_contract, get_logs): code = """ event MyLog: arg1: Bytes[64] @@ -33,15 +34,15 @@ def foo(): log MyLog(a, b, b'hello') """ - c = get_contract_with_gas_estimation(code) - log = get_logs(c.foo(transact={}), c, "MyLog") - - assert log[0].args.arg1 == b"hello" * 9 - assert log[0].args.arg2 == b"hello" * 8 - assert log[0].args.arg3 == b"hello" * 1 + c = get_contract(code) + c.foo() + (log,) = get_logs(c, "MyLog") + assert log.args.arg1 == b"hello" * 9 + assert log.args.arg2 == b"hello" * 8 + assert log.args.arg3 == b"hello" * 1 -def test_bytes_logging_extended_passthrough(get_contract_with_gas_estimation, get_logs): +def test_bytes_logging_extended_passthrough(get_contract, get_logs): code = """ event MyLog: arg1: int128 @@ -53,16 +54,17 @@ def foo(a: int128, b: Bytes[64], c: int128): log MyLog(a, b, c) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) - log = get_logs(c.foo(333, b"flower" * 8, 444, transact={}), c, "MyLog") + c.foo(333, b"flower" * 8, 444) + log = get_logs(c, "MyLog") assert log[0].args.arg1 == 333 assert log[0].args.arg2 == b"flower" * 8 assert log[0].args.arg3 == 444 -def test_bytes_logging_extended_storage(get_contract_with_gas_estimation, get_logs): +def test_bytes_logging_extended_storage(get_contract, get_logs): code = """ event MyLog: arg1: int128 @@ -84,24 +86,24 @@ def set(x: int128, y: Bytes[64], z: int128): self.c = z """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) c.foo() - log = get_logs(c.foo(transact={}), c, "MyLog") + log = get_logs(c, "MyLog") assert log[0].args.arg1 == 0 assert log[0].args.arg2 == b"" assert log[0].args.arg3 == 0 - c.set(333, b"flower" * 8, 444, transact={}) - - log = get_logs(c.foo(transact={}), c, "MyLog")[0] + c.set(333, b"flower" * 8, 444) + c.foo() + (log,) = get_logs(c, "MyLog") assert log.args.arg1 == 333 assert log.args.arg2 == b"flower" * 8 assert log.args.arg3 == 444 -def test_bytes_logging_extended_mixed_with_lists(get_contract_with_gas_estimation, get_logs): +def test_bytes_logging_extended_mixed_with_lists(get_contract, get_logs): code = """ event MyLog: arg1: int128[2][2] @@ -119,8 +121,9 @@ def foo(): ) """ - c = get_contract_with_gas_estimation(code) - log = get_logs(c.foo(transact={}), c, "MyLog")[0] + c = get_contract(code) + c.foo() + (log,) = get_logs(c, "MyLog") assert log.args.arg1 == [[24, 26], [12, 10]] assert log.args.arg2 == b"hello" * 9 diff --git a/tests/functional/codegen/features/test_logging_from_call.py b/tests/functional/codegen/features/test_logging_from_call.py index 7b4ee4f67d..6c9d803c3e 100644 --- a/tests/functional/codegen/features/test_logging_from_call.py +++ b/tests/functional/codegen/features/test_logging_from_call.py @@ -1,9 +1,10 @@ import pytest +from eth_utils import to_int pytestmark = pytest.mark.usefixtures("memory_mocker") -def test_log_dynamic_static_combo(get_logs, get_contract_with_gas_estimation, w3): +def test_log_dynamic_static_combo(get_logs, get_contract): code = """ event TestLog: testData1: bytes32 @@ -30,24 +31,22 @@ def test_func(_value: uint256): log TestLog(loggedValue, data2, loggedValue2) """ - c = get_contract_with_gas_estimation(code) - - tx_hash = c.test_func(123, transact={}) + c = get_contract(code) - logs = get_logs(tx_hash, c, "TestLog") + c.test_func(123) + log, log2 = get_logs(c, "TestLog") - log = logs[0].args - assert w3.to_int(log.testData1) == 123 - assert w3.to_int(log.testData2[:32]) == 123 - assert log.testData2[-7:] == b"testing" - assert log.testData2[32:] == b"\x00\x00\x00\x00\x00\x00\x00{testing" - assert log.testData3 == b"\x00\x00\x00\x00\x00\x00\x00{" - assert w3.to_int(log.testData3) == 123 + assert to_int(log.args.testData1) == 123 + assert to_int(log.args.testData2[:32]) == 123 + assert log.args.testData2[-7:] == b"testing" + assert log.args.testData2[32:] == b"\x00\x00\x00\x00\x00\x00\x00{testing" + assert log.args.testData3 == b"\x00\x00\x00\x00\x00\x00\x00{" + assert to_int(log.args.testData3) == 123 - assert logs[0].args == logs[1].args + assert log.args == log2.args -def test_log_dynamic_static_combo2(get_logs, get_contract, w3): +def test_log_dynamic_static_combo2(get_logs, get_contract): code = """ event TestLog: testData1: bytes32 @@ -75,20 +74,18 @@ def test_func(_value: uint256,input: Bytes[133]): c = get_contract(code) - # assert c.test_func(2**255, b'x' * 129, call={}) == b'x' * 129 - tx_hash = c.test_func(1234444, b"x" * 129, transact={}) - tx_receipt = w3.eth.get_transaction_receipt(tx_hash) - print(tx_receipt) - logs = get_logs(tx_hash, c, "TestLog") + # assert c.test_func(2**255, b'x' * 129) == b'x' * 129 + c.test_func(1234444, b"x" * 129) + logs = get_logs(c, "TestLog") print(logs[0].args) - assert w3.to_int(logs[0].args.testData1) == 1234444 + assert to_int(logs[0].args.testData1) == 1234444 assert logs[0].args.testData3 == "bababa" assert logs[0].args.testData2 == b"x" * 129 -def test_log_single_function_call(get_logs, get_contract, w3): +def test_log_single_function_call(get_logs, get_contract): code = """ event TestLog: testData1: bytes32 @@ -111,14 +108,14 @@ def test_func(_value: uint256,input: Bytes[133]): c = get_contract(code) - tx_hash = c.test_func(1234444, b"x" * 129, transact={}) - logs = get_logs(tx_hash, c, "TestLog") + c.test_func(1234444, b"x" * 129) + (log,) = get_logs(c, "TestLog") - assert w3.to_int(logs[0].args.testData1) == 1234444 - assert logs[0].args.testData2 == b"x" * 129 + assert to_int(log.args.testData1) == 1234444 + assert log.args.testData2 == b"x" * 129 -def test_original_problem_function(get_logs, get_contract, w3): +def test_original_problem_function(get_logs, get_contract): # See #1205 for further details, this is kept as test case as it introduces very specific # edge cases to the ABI encoder when logging. code = """ @@ -153,18 +150,15 @@ def test_func(_value: uint256,input: Bytes[2048]): c = get_contract(code) - tx_hash = c.test_func(333, b"x" * 132, transact={}) - tx_receipt = w3.eth.get_transaction_receipt(tx_hash) - print(tx_receipt) - logs = get_logs(tx_hash, c, "TestLog") - - print(logs[0].args) + c.test_func(333, b"x" * 132) + log1, log2 = get_logs(c, "TestLog") - assert w3.to_int(logs[0].args.testData1) == 333 + print(log1.args) - assert w3.to_int(logs[0].args.testData2[0:8]) == 333 - assert w3.to_int(logs[0].args.testData2[8:16]) == 333 - assert logs[0].args.testData2[16:] == b"x" * 132 - assert w3.to_int(logs[0].args.testData3) == 333 + assert to_int(log1.args.testData1) == 333 + assert to_int(log1.args.testData2[0:8]) == 333 + assert to_int(log1.args.testData2[8:16]) == 333 + assert log1.args.testData2[16:] == b"x" * 132 + assert to_int(log1.args.testData3) == 333 - assert logs[0].args == logs[1].args + assert log1.args == log2.args diff --git a/tests/functional/codegen/features/test_packing.py b/tests/functional/codegen/features/test_packing.py index 3a18b5e88b..84f18e3e4b 100644 --- a/tests/functional/codegen/features/test_packing.py +++ b/tests/functional/codegen/features/test_packing.py @@ -1,4 +1,4 @@ -def test_packing_test(get_contract_with_gas_estimation, memory_mocker): +def test_packing_test(get_contract, memory_mocker): packing_test = """ struct Bar: a: int128 @@ -46,7 +46,7 @@ def fop() -> int128: _z.bar[0].a + _z.bar[0].b + _z.bar[1].a + _z.bar[1].b + _a """ - c = get_contract_with_gas_estimation(packing_test) + c = get_contract(packing_test) assert c.foo() == 1023, c.foo() assert c.fop() == 1023, c.fop() print("Passed packing test") diff --git a/tests/functional/codegen/features/test_reverting.py b/tests/functional/codegen/features/test_reverting.py index f24886ce96..d69e5ec722 100644 --- a/tests/functional/codegen/features/test_reverting.py +++ b/tests/functional/codegen/features/test_reverting.py @@ -1,13 +1,12 @@ import pytest from eth.codecs import abi -from eth_tester.exceptions import TransactionFailed from vyper.utils import method_id pytestmark = pytest.mark.usefixtures("memory_mocker") -def test_revert_reason(w3, tx_failed, get_contract_with_gas_estimation): +def test_revert_reason(env, tx_failed, get_contract): reverty_code = """ @external def foo(): @@ -17,11 +16,11 @@ def foo(): revert_bytes = method_id("NoFives()") - with tx_failed(TransactionFailed, exc_text=f"execution reverted: {revert_bytes}"): - get_contract_with_gas_estimation(reverty_code).foo(transact={}) + with tx_failed(exc_text=revert_bytes.hex()): + get_contract(reverty_code).foo() -def test_revert_reason_typed(w3, tx_failed, get_contract_with_gas_estimation): +def test_revert_reason_typed(env, tx_failed, get_contract): reverty_code = """ @external def foo(): @@ -32,11 +31,11 @@ def foo(): revert_bytes = method_id("NoFives(uint256)") + abi.encode("(uint256)", (5,)) - with tx_failed(TransactionFailed, exc_text=f"execution reverted: {revert_bytes}"): - get_contract_with_gas_estimation(reverty_code).foo(transact={}) + with tx_failed(exc_text=revert_bytes.hex()): + get_contract(reverty_code).foo() -def test_revert_reason_typed_no_variable(w3, tx_failed, get_contract_with_gas_estimation): +def test_revert_reason_typed_no_variable(env, tx_failed, get_contract): reverty_code = """ @external def foo(): @@ -46,5 +45,5 @@ def foo(): revert_bytes = method_id("NoFives(uint256)") + abi.encode("(uint256)", (5,)) - with tx_failed(TransactionFailed, exc_text=f"execution reverted: {revert_bytes}"): - get_contract_with_gas_estimation(reverty_code).foo(transact={}) + with tx_failed(exc_text=revert_bytes.hex()): + get_contract(reverty_code).foo() diff --git a/tests/functional/codegen/features/test_short_circuiting.py b/tests/functional/codegen/features/test_short_circuiting.py index 5e464dd389..8ae16e5f08 100644 --- a/tests/functional/codegen/features/test_short_circuiting.py +++ b/tests/functional/codegen/features/test_short_circuiting.py @@ -3,7 +3,7 @@ import pytest -def test_short_circuit_and_left_is_false(w3, get_contract): +def test_short_circuit_and_left_is_false(get_contract): code = """ called_left: public(bool) @@ -26,12 +26,12 @@ def foo() -> bool: c = get_contract(code) assert not c.foo() - c.foo(transact={}) + c.foo() assert c.called_left() assert not c.called_right() -def test_short_circuit_and_left_is_true(w3, get_contract): +def test_short_circuit_and_left_is_true(get_contract): code = """ called_left: public(bool) @@ -54,12 +54,12 @@ def foo() -> bool: c = get_contract(code) assert c.foo() - c.foo(transact={}) + c.foo() assert c.called_left() assert c.called_right() -def test_short_circuit_or_left_is_true(w3, get_contract): +def test_short_circuit_or_left_is_true(get_contract): code = """ called_left: public(bool) @@ -82,12 +82,12 @@ def foo() -> bool: c = get_contract(code) assert c.foo() - c.foo(transact={}) + c.foo() assert c.called_left() assert not c.called_right() -def test_short_circuit_or_left_is_false(w3, get_contract): +def test_short_circuit_or_left_is_false(get_contract): code = """ called_left: public(bool) @@ -110,14 +110,14 @@ def foo() -> bool: c = get_contract(code) assert not c.foo() - c.foo(transact={}) + c.foo() assert c.called_left() assert c.called_right() @pytest.mark.parametrize("op", ["and", "or"]) @pytest.mark.parametrize("a, b", itertools.product([True, False], repeat=2)) -def test_from_memory(w3, get_contract, a, b, op): +def test_from_memory(get_contract, a, b, op): code = f""" @external def foo(a: bool, b: bool) -> bool: @@ -131,7 +131,7 @@ def foo(a: bool, b: bool) -> bool: @pytest.mark.parametrize("op", ["and", "or"]) @pytest.mark.parametrize("a, b", itertools.product([True, False], repeat=2)) -def test_from_storage(w3, get_contract, a, b, op): +def test_from_storage(get_contract, a, b, op): code = f""" c: bool d: bool @@ -148,7 +148,7 @@ def foo(a: bool, b: bool) -> bool: @pytest.mark.parametrize("op", ["and", "or"]) @pytest.mark.parametrize("a, b", itertools.product([True, False], repeat=2)) -def test_from_calldata(w3, get_contract, a, b, op): +def test_from_calldata(get_contract, a, b, op): code = f""" @external def foo(a: bool, b: bool) -> bool: @@ -160,7 +160,7 @@ def foo(a: bool, b: bool) -> bool: @pytest.mark.parametrize("a, b, c, d", itertools.product([True, False], repeat=4)) @pytest.mark.parametrize("ops", itertools.product(["and", "or"], repeat=3)) -def test_complex_combination(w3, get_contract, a, b, c, d, ops): +def test_complex_combination(get_contract, a, b, c, d, ops): boolop = f"a {ops[0]} b {ops[1]} c {ops[2]} d" code = f""" diff --git a/tests/functional/codegen/features/test_ternary.py b/tests/functional/codegen/features/test_ternary.py index 661fdc86c9..ab6f50f97f 100644 --- a/tests/functional/codegen/features/test_ternary.py +++ b/tests/functional/codegen/features/test_ternary.py @@ -188,7 +188,7 @@ def test_ternary_tuple(get_contract, code, test): c = get_contract(code) x, y = 1, 2 - assert c.foo(test, x, y) == ([x, y] if test else [y, x]) + assert c.foo(test, x, y) == ((x, y) if test else (y, x)) @pytest.mark.parametrize("test", [True, False]) @@ -269,7 +269,7 @@ def foo(t: bool): """ c = get_contract(code) - c.foo(test, transact={}) + c.foo(test) assert c.foo_retval() == (5 if test else 7) if test: diff --git a/tests/functional/codegen/features/test_transient.py b/tests/functional/codegen/features/test_transient.py index 8dc221fc0d..2532def85b 100644 --- a/tests/functional/codegen/features/test_transient.py +++ b/tests/functional/codegen/features/test_transient.py @@ -1,14 +1,12 @@ import pytest +from tests.utils import ZERO_ADDRESS from vyper.compiler import compile_code from vyper.exceptions import EvmVersionException, VyperException pytestmark = pytest.mark.requires_evm_version("cancun") -# with eth-tester, each call happens in an isolated transaction and so we need to -# test get/set within a single contract call. (we should remove this restriction -# in the future by migrating away from eth-tester). def test_transient_compiles(): getter_code = """ my_map: public(transient(HashMap[address, uint256])) @@ -52,14 +50,14 @@ def setter(k: address, v: uint256): ("uint256", 42, 0), ("int256", -(2**200), 0), ("int128", -(2**126), 0), - ("address", "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", None), + ("address", "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", ZERO_ADDRESS), ("bytes32", b"deadbeef" * 4, b"\x00" * 32), ("bool", True, False), ("String[10]", "Vyper hiss", ""), ("Bytes[10]", b"Vyper hiss", b""), ], ) -def test_value_storage_retrieval(typ, value, zero, get_contract): +def test_value_storage_retrieval(typ, value, zero, get_contract, env): code = f""" bar: public(transient({typ})) @@ -72,13 +70,17 @@ def foo(a: {typ}) -> {typ}: c = get_contract(code) assert c.bar() == zero assert c.foo(value) == value + env.clear_transient_storage() + assert c.bar() == zero assert c.foo(value) == value + env.clear_transient_storage() + assert c.bar() == zero @pytest.mark.parametrize("val", [0, 1, 2**256 - 1]) -def test_usage_in_constructor(get_contract, val): +def test_usage_in_constructor(get_contract, val, env): code = """ A: transient(uint256) a: public(uint256) @@ -98,10 +100,12 @@ def a1() -> uint256: c = get_contract(code, val) assert c.a() == val + env.clear_transient_storage() + assert c.a1() == 0 -def test_multiple_transient_values(get_contract): +def test_multiple_transient_values(get_contract, env): code = """ a: public(transient(uint256)) b: public(transient(address)) @@ -124,14 +128,16 @@ def foo(_a: uint256, _b: address, _c: String[64]) -> (uint256, address, String[6 values = (3, "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "Hello world") c = get_contract(code) - assert c.foo(*values) == list(values) + assert c.foo(*values) == values + env.clear_transient_storage() + assert c.a() == 0 - assert c.b() is None + assert c.b() == ZERO_ADDRESS assert c.c() == "" - assert c.foo(*values) == list(values) + assert c.foo(*values) == values -def test_struct_transient(get_contract): +def test_struct_transient(get_contract, env): code = """ struct MyStruct: a: uint256 @@ -155,11 +161,13 @@ def foo(_a: uint256, _b: uint256, _c: address, _d: int256) -> MyStruct: c = get_contract(code) assert c.foo(*values) == values - assert c.my_struct() == (0, 0, None, 0) + env.clear_transient_storage() + + assert c.my_struct() == (0, 0, ZERO_ADDRESS, 0) assert c.foo(*values) == values -def test_complex_struct_transient(get_contract): +def test_complex_struct_transient(get_contract, env): code = """ struct MyStruct: a: address @@ -184,11 +192,13 @@ def foo(_a: address, _b: MyStruct2, _c: DynArray[DynArray[uint256, 3], 3]) -> My c = get_contract(code) assert c.foo(*values) == values - assert c.my_struct() == (None, ([],), []) + env.clear_transient_storage() + + assert c.my_struct() == (ZERO_ADDRESS, ([],), []) assert c.foo(*values) == values -def test_complex_transient_modifiable(get_contract): +def test_complex_transient_modifiable(get_contract, env): code = """ struct MyStruct: a: uint256 @@ -207,11 +217,13 @@ def foo(a: uint256) -> MyStruct: c = get_contract(code) assert c.foo(1) == (2,) + env.clear_transient_storage() + assert c.my_struct() == (0,) assert c.foo(1) == (2,) -def test_list_transient(get_contract): +def test_list_transient(get_contract, env): code = """ my_list: public(transient(uint256[3])) @@ -224,12 +236,14 @@ def foo(_a: uint256, _b: uint256, _c: uint256) -> uint256[3]: c = get_contract(code) assert c.foo(*values) == list(values) + env.clear_transient_storage() + for i in range(3): assert c.my_list(i) == 0 assert c.foo(*values) == list(values) -def test_hashmap_transient(get_contract): +def test_hashmap_transient(get_contract, env): code = """ my_map: public(transient(HashMap[uint256, uint256])) @@ -242,10 +256,11 @@ def foo(k: uint256, v: uint256) -> uint256: for v in range(5): for k in range(5): assert c.foo(k, v) == v + env.clear_transient_storage() assert c.my_map(k) == 0 -def test_complex_hashmap_transient(get_contract): +def test_complex_hashmap_transient(get_contract, env): code = """ struct MyStruct: a: uint256 @@ -266,17 +281,18 @@ def do_side_effects(): self.my_res[i] = self.my_map[i] """ c = get_contract(code) - c.do_side_effects(transact={}) + c.do_side_effects() for i in range(2): assert c.my_res(i)[0] == i assert c.my_map(i)[0] == 0 + env.clear_transient_storage() + for j in range(3): - print(c.my_res(i)[1]) assert c.my_res(i)[1][j] == i + j assert c.my_map(i)[1] == [] -def test_dynarray_transient(get_contract, tx_failed): +def test_dynarray_transient(get_contract, tx_failed, env): code = """ my_list: public(transient(DynArray[uint256, 3])) @@ -294,9 +310,13 @@ def get_idx_two(_a: uint256, _b: uint256, _c: uint256) -> uint256: c = get_contract(code) assert c.get_my_list(*values) == list(values) + env.clear_transient_storage() + with tx_failed(): c.my_list(0) assert c.get_idx_two(*values) == values[2] + env.clear_transient_storage() + with tx_failed(): c.my_list(0) @@ -323,7 +343,7 @@ def get_idx_two(_a: uint256, _b: uint256, _c: uint256) -> uint256: assert c.get_idx_two(*values) == expected_values[2][2] -def test_nested_dynarray_transient(get_contract, tx_failed): +def test_nested_dynarray_transient(get_contract, tx_failed, env): set_list = """ self.my_list = [ [[x, y, z], [y, z, x], [z, y, x]], @@ -369,18 +389,24 @@ def get_idx_two_using_getter(x: int128, y: int128, z: int128) -> int128: c = get_contract(code) assert c.get_my_list(*values) == expected_values + env.clear_transient_storage() + with tx_failed(): c.my_list(0, 0, 0) assert c.get_idx_two(*values) == expected_values[2][2][2] + env.clear_transient_storage() + with tx_failed(): c.my_list(0, 0, 0) assert c.get_idx_two_using_getter(*values) == expected_values[2][2][2] + env.clear_transient_storage() + with tx_failed(): c.my_list(0, 0, 0) @pytest.mark.parametrize("n", range(5)) -def test_internal_function_with_transient(get_contract, n): +def test_internal_function_with_transient(get_contract, n, env): code = """ @internal def foo() -> uint256: @@ -400,11 +426,13 @@ def bar(x: uint256) -> uint256: c = get_contract(code) assert c.bar(n) == n + 2 + env.clear_transient_storage() + assert c.val() == 0 assert c.bar(n) == n + 2 -def test_nested_internal_function_transient(get_contract): +def test_nested_internal_function_transient(get_contract, env): code = """ d: public(uint256) x: public(transient(uint256)) @@ -426,10 +454,12 @@ def b(): c = get_contract(code) assert c.d() == 2 + env.clear_transient_storage() + assert c.x() == 0 -def test_view_function_transient(get_contract): +def test_view_function_transient(get_contract, env): c1 = """ x: transient(uint256) @@ -460,6 +490,8 @@ def bar(i: uint256, a: address) -> uint256: value = 333 assert c2.bar(value, c1.address) == value + env.clear_transient_storage() + assert c1.get_x() == 0 @@ -496,7 +528,7 @@ def foo() -> (uint256, uint256): input_bundle = make_input_bundle({"lib1.vy": lib1, "lib2.vy": lib2}) c = get_contract(main, input_bundle=input_bundle) - assert c.foo() == [3, 10] + assert c.foo() == (3, 10) def test_complex_modules_transient(get_contract, make_input_bundle): @@ -537,4 +569,4 @@ def foo() -> (uint256[3], uint256, uint256, uint256): input_bundle = make_input_bundle({"lib1.vy": lib1, "lib2.vy": lib2}) c = get_contract(main, input_bundle=input_bundle) - assert c.foo() == [[1, 2, 3], 1, 2, 42] + assert c.foo() == ([1, 2, 3], 1, 2, 42) diff --git a/tests/functional/codegen/integration/test_basics.py b/tests/functional/codegen/integration/test_basics.py index c3953b814a..67d4d9f332 100644 --- a/tests/functional/codegen/integration/test_basics.py +++ b/tests/functional/codegen/integration/test_basics.py @@ -1,19 +1,19 @@ -def test_null_code(get_contract_with_gas_estimation): +def test_null_code(get_contract): null_code = """ @external def foo(): pass """ - c = get_contract_with_gas_estimation(null_code) + c = get_contract(null_code) c.foo() -def test_basic_code(get_contract_with_gas_estimation): +def test_basic_code(get_contract): basic_code = """ @external def foo(x: int128) -> int128: return x * 2 """ - c = get_contract_with_gas_estimation(basic_code) + c = get_contract(basic_code) assert c.foo(9) == 18 diff --git a/tests/functional/codegen/integration/test_crowdfund.py b/tests/functional/codegen/integration/test_crowdfund.py index b07ce5dc22..1644985f9d 100644 --- a/tests/functional/codegen/integration/test_crowdfund.py +++ b/tests/functional/codegen/integration/test_crowdfund.py @@ -1,5 +1,14 @@ +import pytest + + +@pytest.fixture(autouse=True) +def set_balance(env): + for a in env.accounts[:7]: + env.set_balance(a, 10**10) + + # TODO: check, this is probably redundant with examples/test_crowdfund.py -def test_crowdfund(w3, tester, get_contract_with_gas_estimation_for_constants): +def test_crowdfund(env, get_contract): crowdfund = """ struct Funder: @@ -62,40 +71,40 @@ def refund(): self.refundIndex = ind + 30 """ - a0, a1, a2, a3, a4, a5, a6 = w3.eth.accounts[:7] + a0, a1, a2, a3, a4, a5, a6 = env.accounts[:7] - c = get_contract_with_gas_estimation_for_constants(crowdfund, *[a1, 50, 60]) - start_timestamp = w3.eth.get_block(w3.eth.block_number).timestamp + c = get_contract(crowdfund, *[a1, 50, 60]) + start_timestamp = env.timestamp - c.participate(transact={"value": 5}) + c.participate(value=5) assert c.timelimit() == 60 assert c.deadline() - start_timestamp == 60 assert not c.expired() assert not c.reached() - c.participate(transact={"value": 49}) + c.participate(value=49) assert c.reached() - pre_bal = w3.eth.get_balance(a1) - w3.testing.mine(100) + pre_bal = env.get_balance(a1) + env.timestamp += 100 assert c.expired() - c.finalize(transact={}) - post_bal = w3.eth.get_balance(a1) + c.finalize() + post_bal = env.get_balance(a1) assert post_bal - pre_bal == 54 - c = get_contract_with_gas_estimation_for_constants(crowdfund, *[a1, 50, 60]) - c.participate(transact={"value": 1, "from": a3}) - c.participate(transact={"value": 2, "from": a4}) - c.participate(transact={"value": 3, "from": a5}) - c.participate(transact={"value": 4, "from": a6}) - w3.testing.mine(100) + c = get_contract(crowdfund, *[a1, 50, 60]) + c.participate(value=1, sender=a3) + c.participate(value=2, sender=a4) + c.participate(value=3, sender=a5) + c.participate(value=4, sender=a6) + env.timestamp += 100 assert c.expired() assert not c.reached() - pre_bals = [w3.eth.get_balance(x) for x in [a3, a4, a5, a6]] - c.refund(transact={}) - post_bals = [w3.eth.get_balance(x) for x in [a3, a4, a5, a6]] + pre_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] + c.refund() + post_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] assert [y - x for x, y in zip(pre_bals, post_bals)] == [1, 2, 3, 4] -def test_crowdfund2(w3, tester, get_contract_with_gas_estimation_for_constants): +def test_crowdfund2(env, get_contract): crowdfund2 = """ struct Funder: sender: address @@ -156,32 +165,33 @@ def refund(): self.refundIndex = ind + 30 """ - a0, a1, a2, a3, a4, a5, a6 = w3.eth.accounts[:7] - c = get_contract_with_gas_estimation_for_constants(crowdfund2, *[a1, 50, 60]) + a0, a1, a2, a3, a4, a5, a6 = env.accounts[:7] + c = get_contract(crowdfund2, *[a1, 50, 60]) - c.participate(transact={"value": 5}) + c.participate(value=5) + env.timestamp += 1 # make sure auction has started assert c.timelimit() == 60 assert c.deadline() - c.block_timestamp() == 59 assert not c.expired() assert not c.reached() - c.participate(transact={"value": 49}) + c.participate(value=49) assert c.reached() - pre_bal = w3.eth.get_balance(a1) - w3.testing.mine(100) + pre_bal = env.get_balance(a1) + env.timestamp += 100 assert c.expired() - c.finalize(transact={}) - post_bal = w3.eth.get_balance(a1) + c.finalize() + post_bal = env.get_balance(a1) assert post_bal - pre_bal == 54 - c = get_contract_with_gas_estimation_for_constants(crowdfund2, *[a1, 50, 60]) - c.participate(transact={"value": 1, "from": a3}) - c.participate(transact={"value": 2, "from": a4}) - c.participate(transact={"value": 3, "from": a5}) - c.participate(transact={"value": 4, "from": a6}) - w3.testing.mine(100) + c = get_contract(crowdfund2, *[a1, 50, 60]) + c.participate(value=1, sender=a3) + c.participate(value=2, sender=a4) + c.participate(value=3, sender=a5) + c.participate(value=4, sender=a6) + env.timestamp += 100 assert c.expired() assert not c.reached() - pre_bals = [w3.eth.get_balance(x) for x in [a3, a4, a5, a6]] - c.refund(transact={}) - post_bals = [w3.eth.get_balance(x) for x in [a3, a4, a5, a6]] + pre_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] + c.refund() + post_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] assert [y - x for x, y in zip(pre_bals, post_bals)] == [1, 2, 3, 4] diff --git a/tests/functional/codegen/integration/test_escrow.py b/tests/functional/codegen/integration/test_escrow.py index f86b4aa516..879affc719 100644 --- a/tests/functional/codegen/integration/test_escrow.py +++ b/tests/functional/codegen/integration/test_escrow.py @@ -1,7 +1,4 @@ -# from ethereum.tools import tester - - -def test_arbitration_code(w3, get_contract_with_gas_estimation, tx_failed): +def test_arbitration_code(env, get_contract, tx_failed): arbitration_code = """ buyer: address seller: address @@ -25,17 +22,18 @@ def refund(): send(self.buyer, self.balance) """ - a0, a1, a2 = w3.eth.accounts[:3] - c = get_contract_with_gas_estimation(arbitration_code, value=1) - c.setup(a1, a2, transact={}) + a0, a1, a2 = env.accounts[:3] + env.set_balance(a0, 1) + c = get_contract(arbitration_code, value=1) + c.setup(a1, a2) with tx_failed(): - c.finalize(transact={"from": a1}) - c.finalize(transact={}) + c.finalize(sender=a1) + c.finalize() print("Passed escrow test") -def test_arbitration_code_with_init(w3, tx_failed, get_contract_with_gas_estimation): +def test_arbitration_code_with_init(env, tx_failed, get_contract): arbitration_code_with_init = """ buyer: address seller: address @@ -59,10 +57,11 @@ def refund(): assert msg.sender == self.seller or msg.sender == self.arbitrator send(self.buyer, self.balance) """ - a0, a1, a2 = w3.eth.accounts[:3] - c = get_contract_with_gas_estimation(arbitration_code_with_init, *[a1, a2], value=1) + a0, a1, a2 = env.accounts[:3] + env.set_balance(env.deployer, 1) + c = get_contract(arbitration_code_with_init, *[a1, a2], value=1) with tx_failed(): - c.finalize(transact={"from": a1}) - c.finalize(transact={"from": a0}) + c.finalize(sender=a1) + c.finalize(sender=a0) print("Passed escrow test with initializer") diff --git a/tests/functional/codegen/modules/test_events.py b/tests/functional/codegen/modules/test_events.py index 8cec4c6577..ae5198cf90 100644 --- a/tests/functional/codegen/modules/test_events.py +++ b/tests/functional/codegen/modules/test_events.py @@ -17,7 +17,8 @@ def bar(): """ input_bundle = make_input_bundle({"lib1.vy": lib1}) c = get_contract(main, input_bundle=input_bundle) - logs = get_logs(c.bar(transact={}), c, "MyEvent") + c.bar() + logs = get_logs(c, "MyEvent") assert len(logs) == 1 @@ -36,9 +37,9 @@ def bar(): """ input_bundle = make_input_bundle({"lib1.vy": lib1}) c = get_contract(main, input_bundle=input_bundle) - logs = get_logs(c.bar(transact={}), c, "MyEvent") - assert len(logs) == 1 - assert logs[0].args.x == 5 + c.bar() + (log,) = get_logs(c, "MyEvent") + assert log.args.x == 5 def test_module_event_indexed(get_contract, make_input_bundle, get_logs): @@ -60,7 +61,7 @@ def bar(): """ input_bundle = make_input_bundle({"lib1.vy": lib1}) c = get_contract(main, input_bundle=input_bundle) - logs = get_logs(c.bar(transact={}), c, "MyEvent") - assert len(logs) == 1 - assert logs[0].args.x == 5 - assert logs[0].args.y == 6 + c.bar() + (log,) = get_logs(c, "MyEvent") + assert log.args.x == 5 + assert log.args.y == 6 diff --git a/tests/functional/codegen/modules/test_exports.py b/tests/functional/codegen/modules/test_exports.py index b02ed6ba9e..93f4fe6c2f 100644 --- a/tests/functional/codegen/modules/test_exports.py +++ b/tests/functional/codegen/modules/test_exports.py @@ -198,11 +198,11 @@ def qux() -> uint256: @pytest.fixture -def send_failing_tx_to_signature(w3, tx_failed): +def send_failing_tx_to_signature(env, tx_failed): def _send_transaction(c, method_sig): data = method_id(method_sig) with tx_failed(): - w3.eth.send_transaction({"to": c.address, "data": data}) + env.message_call(c.address, data=data) return _send_transaction @@ -407,11 +407,11 @@ def __init__(): input_bundle = make_input_bundle({"lib1.vy": lib1}) c = get_contract(main, input_bundle=input_bundle) assert c.counter() == 100 - c.foo(transact={}) + c.foo() assert c.counter() == 101 -def test_export_module_with_default(w3, get_contract, make_input_bundle): +def test_export_module_with_default(env, get_contract, make_input_bundle): lib1 = """ counter: public(uint256) @@ -438,5 +438,5 @@ def __init__(): assert c.foo() == 1 assert c.counter() == 5 # call `c.__default__()` - w3.eth.send_transaction({"to": c.address}) + env.message_call(c.address) assert c.counter() == 6 diff --git a/tests/functional/codegen/modules/test_module_variables.py b/tests/functional/codegen/modules/test_module_variables.py index 6bb1f9072c..c9b79e1bcc 100644 --- a/tests/functional/codegen/modules/test_module_variables.py +++ b/tests/functional/codegen/modules/test_module_variables.py @@ -26,7 +26,7 @@ def get_counter() -> uint256: c = get_contract(contract, input_bundle=input_bundle) assert c.get_counter() == 0 - c.increment_counter(transact={}) + c.increment_counter() assert c.get_counter() == 1 @@ -75,15 +75,15 @@ def get_lib_counter() -> uint256: assert c.get_counter() == c.get_lib_counter() == 0 - c.increment_counter(transact={}) + c.increment_counter() assert c.get_counter() == 1 assert c.get_lib_counter() == 0 - c.increment_lib_counter(transact={}) + c.increment_lib_counter() assert c.get_lib_counter() == 1 assert c.get_counter() == 1 - c.increment_lib_counter2(transact={}) + c.increment_lib_counter2() assert c.get_lib_counter() == 6 assert c.get_counter() == 1 @@ -310,7 +310,7 @@ def get_hashmap_value(ix: uint256) -> uint256: assert c.get_array_value(0) == 0 assert c.get_hashmap_value(0) == 0 - c.do_things(transact={}) + c.do_things() assert c.get_array_value(0) == 0 assert c.get_hashmap_value(0) == 0 diff --git a/tests/functional/codegen/modules/test_stateless_functions.py b/tests/functional/codegen/modules/test_stateless_functions.py index 33d8b3186c..3f618bf0ea 100644 --- a/tests/functional/codegen/modules/test_stateless_functions.py +++ b/tests/functional/codegen/modules/test_stateless_functions.py @@ -14,7 +14,7 @@ # test modules which have no variables - "libraries" -def test_simple_library(get_contract, make_input_bundle, w3): +def test_simple_library(get_contract, make_input_bundle, env): library_source = """ @internal def foo() -> uint256: @@ -31,7 +31,7 @@ def bar() -> uint256: c = get_contract(main, input_bundle=input_bundle) - assert c.bar() == w3.eth.block_number + assert c.bar() == env.block_number # is this the best place for this? @@ -179,7 +179,7 @@ def qux() -> library.SomeStruct: input_bundle = make_input_bundle({"library.vy": library_source, "contract.vy": contract_source}) c = get_contract(contract_source, input_bundle=input_bundle) - assert c.bar((1,)) == [] + assert c.bar((1,)) is None assert c.baz() == (2,) assert c.qux() == (1,) @@ -207,7 +207,7 @@ def foo(x: uint256): c = get_contract(contract_source, input_bundle=input_bundle) - c.foo(7, transact={}) + c.foo(7) assert c.counter() == 7 diff --git a/tests/functional/codegen/storage_variables/test_getters.py b/tests/functional/codegen/storage_variables/test_getters.py index 9e72bed075..5169bd300d 100644 --- a/tests/functional/codegen/storage_variables/test_getters.py +++ b/tests/functional/codegen/storage_variables/test_getters.py @@ -1,4 +1,4 @@ -def test_state_accessor(get_contract_with_gas_estimation_for_constants): +def test_state_accessor(get_contract): state_accessor = """ y: HashMap[int128, int128] @@ -12,12 +12,12 @@ def foo() -> int128: """ - c = get_contract_with_gas_estimation_for_constants(state_accessor) - c.oo(transact={}) + c = get_contract(state_accessor) + c.oo() assert c.foo() == 5 -def test_getter_code(get_contract_with_gas_estimation_for_constants): +def test_getter_code(get_contract): getter_code = """ interface V: def foo(): nonpayable @@ -58,7 +58,7 @@ def __init__(): e = [2, 3] """ - c = get_contract_with_gas_estimation_for_constants(getter_code) + c = get_contract(getter_code) assert c.x() == 7 assert c.y(1) == 9 assert c.z() == b"cow" @@ -94,7 +94,7 @@ def __init__(): contract = get_contract(code) - for item in contract._classic_contract.abi: + for item in contract.abi: if item["type"] == "constructor": continue assert item["stateMutability"] == "view" diff --git a/tests/functional/codegen/storage_variables/test_setters.py b/tests/functional/codegen/storage_variables/test_setters.py index cf4138b939..c562ef1614 100644 --- a/tests/functional/codegen/storage_variables/test_setters.py +++ b/tests/functional/codegen/storage_variables/test_setters.py @@ -1,7 +1,7 @@ from vyper.exceptions import InvalidAttribute -def test_multi_setter_test(get_contract_with_gas_estimation): +def test_multi_setter_test(get_contract): multi_setter_test = """ dog: int128[3] bar: int128[3][3] @@ -54,11 +54,11 @@ def jop() -> int128: """ - c = get_contract_with_gas_estimation(multi_setter_test) + c = get_contract(multi_setter_test) assert c.foo() == 321 - c.foo(transact={}) + c.foo() assert c.fop() == 654321 - c.fop(transact={}) + c.fop() assert c.goo() == 321 assert c.gop() == 654321 assert c.hoo() == 0 @@ -68,7 +68,7 @@ def jop() -> int128: print("Passed multi-setter literal test") -def test_multi_setter_struct_test(get_contract_with_gas_estimation): +def test_multi_setter_struct_test(get_contract): multi_setter_struct_test = """ struct Dog: foo: int128 @@ -141,7 +141,7 @@ def gop() -> int128: zed[1].bar[1].b * 10000000000000 """ - c = get_contract_with_gas_estimation(multi_setter_struct_test) + c = get_contract(multi_setter_struct_test) assert c.foo() == 654321 assert c.fop() == 87198763254321 assert c.goo() == 654321 @@ -163,7 +163,7 @@ def test2() -> uint256: assert_compile_failed(lambda: get_contract(code), InvalidAttribute) -def test_type_converter_setter_test(get_contract_with_gas_estimation): +def test_type_converter_setter_test(get_contract): type_converter_setter_test = """ pap: decimal[2][2] @@ -177,11 +177,11 @@ def goo() -> int256: self.pap[1][1] * 1000.0) """ - c = get_contract_with_gas_estimation(type_converter_setter_test) + c = get_contract(type_converter_setter_test) assert c.goo() == 4321 -def test_composite_setter_test(get_contract_with_gas_estimation): +def test_composite_setter_test(get_contract): composite_setter_test = """ struct C: c: int128 @@ -217,7 +217,7 @@ def foq() -> int128: return popp.a[0].c + popp.a[1].c * 10 + popp.a[2].c * 100 + popp.b * 1000 """ - c = get_contract_with_gas_estimation(composite_setter_test) + c = get_contract(composite_setter_test) assert c.foo() == 4625 assert c.fop() == 4625 assert c.foq() == 4020 diff --git a/tests/functional/codegen/storage_variables/test_storage_variable.py b/tests/functional/codegen/storage_variables/test_storage_variable.py index 7a22d35e4b..f6ae550b82 100644 --- a/tests/functional/codegen/storage_variables/test_storage_variable.py +++ b/tests/functional/codegen/storage_variables/test_storage_variable.py @@ -3,7 +3,7 @@ from vyper.exceptions import UndeclaredDefinition -def test_permanent_variables_test(get_contract_with_gas_estimation): +def test_permanent_variables_test(get_contract): permanent_variables_test = """ struct Var: a: int128 @@ -20,7 +20,7 @@ def returnMoose() -> int128: return self.var.a * 10 + self.var.b """ - c = get_contract_with_gas_estimation(permanent_variables_test, *[5, 7]) + c = get_contract(permanent_variables_test, *[5, 7]) assert c.returnMoose() == 57 print("Passed init argument and variable member test") diff --git a/tests/functional/codegen/test_interfaces.py b/tests/functional/codegen/test_interfaces.py index aa70667c38..9442362696 100644 --- a/tests/functional/codegen/test_interfaces.py +++ b/tests/functional/codegen/test_interfaces.py @@ -1,6 +1,7 @@ import json import pytest +from eth_utils import to_wei from tests.utils import decimal_to_int from vyper.compiler import compile_code @@ -185,7 +186,7 @@ def test_extract_file_interface_imports_raises( compile_code(code, input_bundle=input_bundle) -def test_external_call_to_interface(w3, get_contract, make_input_bundle): +def test_external_call_to_interface(env, get_contract, make_input_bundle): token_interface = """ @view @external @@ -232,10 +233,10 @@ def test(): test_c = get_contract(code, *[token.address], input_bundle=input_bundle) - sender = w3.eth.accounts[0] + sender = env.deployer assert token.balanceOf(sender) == 0 - test_c.test(transact={}) + test_c.test() assert token.balanceOf(sender) == 1000 @@ -279,12 +280,12 @@ def bar(a_address: address) -> {typ}: """ contract_a = get_contract(code1, input_bundle=input_bundle) - contract_b = get_contract(code2, *[contract_a.address], input_bundle=input_bundle) + contract_b = get_contract(code2, input_bundle=input_bundle) assert contract_b.bar(contract_a.address) == expected -def test_external_call_to_builtin_interface(w3, get_contract): +def test_external_call_to_builtin_interface(env, get_contract): token_code = """ balanceOf: public(HashMap[address, uint256]) @@ -311,14 +312,14 @@ def test(): erc20 = get_contract(token_code) test_c = get_contract(code, *[erc20.address]) - sender = w3.eth.accounts[0] + sender = env.deployer assert erc20.balanceOf(sender) == 0 - test_c.test(transact={}) + test_c.test() assert erc20.balanceOf(sender) == 1000 -def test_address_member(w3, get_contract): +def test_address_member(env, get_contract): code = """ interface Foo: def foo(): payable @@ -331,7 +332,7 @@ def test(addr: address): assert self.f.address == addr """ c = get_contract(code) - for address in w3.eth.accounts: + for address in env.accounts: c.test(address) @@ -503,7 +504,7 @@ def test_fail3() -> Bytes[3]: c.test_fail3() -def test_units_interface(w3, get_contract, make_input_bundle): +def test_units_interface(env, get_contract, make_input_bundle): code = """ import balanceof as BalanceOf @@ -526,7 +527,7 @@ def balanceOf(owner: address) -> uint256: c = get_contract(code, input_bundle=input_bundle) - assert c.balanceOf(w3.eth.accounts[0]) == w3.to_wei(1, "ether") + assert c.balanceOf(env.deployer) == to_wei(1, "ether") def test_simple_implements(make_input_bundle): diff --git a/tests/functional/codegen/test_selector_table.py b/tests/functional/codegen/test_selector_table.py index 94233977c9..d01dbc8981 100644 --- a/tests/functional/codegen/test_selector_table.py +++ b/tests/functional/codegen/test_selector_table.py @@ -512,7 +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, tx_failed, get_logs): +def test_selector_table_fuzz(max_calldata_bytes, opt_level, env, 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) @@ -574,6 +574,7 @@ def __default__(): """ c = get_contract(code, override_opt_level=opt_level) + env.set_balance(env.deployer, 10**18) for func_id, mutability, n_calldata_words, n_strip_bytes, n_default_args in methods: funcname = f"foo{func_id}" @@ -592,14 +593,13 @@ def __default__(): # do payable check if mutability == "@payable": - tx = func(*args, transact={"value": 1}) - (event,) = get_logs(tx, c, "_Return") + func(*args, value=1) + (event,) = get_logs(c, "_Return") assert event.args.val == func_id else: hexstr = (method_id + argsdata).hex() - txdata = {"to": c.address, "data": hexstr, "value": 1} with tx_failed(): - w3.eth.send_transaction(txdata) + env.message_call(c.address, data=hexstr, value=1) # now do calldatasize check # strip some bytes @@ -610,28 +610,28 @@ def __default__(): # no args, hit default function if default_fn_mutability == "": with tx_failed(): - w3.eth.send_transaction(tx_params) + env.message_call(**tx_params) elif default_fn_mutability == "@payable": # we should be able to send eth to it tx_params["value"] = 1 - tx = w3.eth.send_transaction(tx_params) - logs = get_logs(tx, c, "CalledDefault") + env.message_call(**tx_params) + logs = get_logs(c, "CalledDefault") assert len(logs) == 1 else: - tx = w3.eth.send_transaction(tx_params) + env.message_call(**tx_params) # note: can't emit logs from view/pure functions, # so the logging is not tested. if default_fn_mutability == "@nonpayable": - logs = get_logs(tx, c, "CalledDefault") + logs = get_logs(c, "CalledDefault") assert len(logs) == 1 # check default function reverts tx_params["value"] = 1 with tx_failed(): - w3.eth.send_transaction(tx_params) + env.message_call(**tx_params) else: with tx_failed(): - w3.eth.send_transaction(tx_params) + env.message_call(**tx_params) _test() diff --git a/tests/functional/codegen/types/numbers/test_constants.py b/tests/functional/codegen/types/numbers/test_constants.py index 8ad2b559de..f29a20153b 100644 --- a/tests/functional/codegen/types/numbers/test_constants.py +++ b/tests/functional/codegen/types/numbers/test_constants.py @@ -2,7 +2,7 @@ import pytest -from tests.utils import decimal_to_int +from tests.utils import ZERO_ADDRESS, decimal_to_int from vyper.compiler import compile_code from vyper.exceptions import TypeMismatch from vyper.utils import MemoryPositions @@ -15,7 +15,7 @@ def search_for_sublist(ir, sublist): return isinstance(_list, list) and any(search_for_sublist(i, sublist) for i in _list) -def test_builtin_constants(get_contract_with_gas_estimation): +def test_builtin_constants(get_contract): code = """ @external def test_zaddress(a: address) -> bool: @@ -47,32 +47,32 @@ def test_arithmetic(a: int128) -> int128: return max_value(int128) - a """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.test_empty_bytes32(b"\x00" * 32) is True assert c.test_empty_bytes32(b"\x0F" * 32) is False - assert c.test_zaddress("0x0000000000000000000000000000000000000000") is True + assert c.test_zaddress(ZERO_ADDRESS) is True assert c.test_zaddress("0x0000000000000000000000000000000000000012") is False - assert c.test_int128(2**127 - 1) == [True, False] - assert c.test_int128(-(2**127)) == [False, True] - assert c.test_int128(0) == [False, False] + assert c.test_int128(2**127 - 1) == (True, False) + assert c.test_int128(-(2**127)) == (False, True) + assert c.test_int128(0) == (False, False) assert c.test_decimal( decimal_to_int("18707220957835557353007165858768422651595.9365500927") - ) == [True, False] + ) == (True, False) assert c.test_decimal( decimal_to_int("-18707220957835557353007165858768422651595.9365500928") - ) == [False, True] - assert c.test_decimal(decimal_to_int("0.1")) == [False, False] + ) == (False, True) + assert c.test_decimal(decimal_to_int("0.1")) == (False, False) assert c.test_uint256(2**256 - 1) is True assert c.test_arithmetic(5000) == 2**127 - 1 - 5000 -def test_builtin_constants_assignment(get_contract_with_gas_estimation): +def test_builtin_constants_assignment(get_contract): code = """ @external def foo() -> int128: @@ -110,14 +110,14 @@ def zoo() -> uint256: return bar """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == 2**127 - 1 assert c.goo() == -(2**127) assert c.hoo() == b"\x00" * 32 - assert c.joo() is None + assert c.joo() == ZERO_ADDRESS assert c.koo() == (2**167 - 1) assert c.loo() == -(2**167) @@ -197,7 +197,7 @@ def test() -> Bytes[100]: assert c.test() == test_str -def test_constant_folds(): +def test_constant_folds(experimental_codegen): some_prime = 10013677 code = f""" SOME_CONSTANT: constant(uint256) = 11 + 1 @@ -211,7 +211,8 @@ def test() -> uint256: return ret """ ir = compile_code(code, output_formats=["ir"])["ir"] - search = ["mstore", [MemoryPositions.RESERVED_MEMORY], [2**12 * some_prime]] + memory = "$alloca_64_32" if experimental_codegen else MemoryPositions.RESERVED_MEMORY + search = ["mstore", [memory], [2**12 * some_prime]] assert search_for_sublist(ir, search) diff --git a/tests/functional/codegen/types/numbers/test_decimals.py b/tests/functional/codegen/types/numbers/test_decimals.py index 59810776eb..36c14f804d 100644 --- a/tests/functional/codegen/types/numbers/test_decimals.py +++ b/tests/functional/codegen/types/numbers/test_decimals.py @@ -54,7 +54,7 @@ def foo(x: decimal) -> decimal: compile_code(code) -def test_decimal_test(get_contract_with_gas_estimation): +def test_decimal_test(get_contract): decimal_test = """ @external def foo() -> int256: @@ -102,7 +102,7 @@ def foop() -> int256: return(floor(1999.0 % 1000.0)) """ - c = get_contract_with_gas_estimation(decimal_test) + c = get_contract(decimal_test) assert c.foo() == 999 assert c.fop() == 999 @@ -119,7 +119,7 @@ def foop() -> int256: print("Passed basic addition, subtraction and multiplication tests") -def test_harder_decimal_test(get_contract_with_gas_estimation): +def test_harder_decimal_test(get_contract): harder_decimal_test = """ @external def phooey(inp: decimal) -> decimal: @@ -151,7 +151,7 @@ def iarg() -> uint256: return x """ - c = get_contract_with_gas_estimation(harder_decimal_test) + c = get_contract(harder_decimal_test) assert c.phooey(decimal_to_int("1.2")) == decimal_to_int("20736.0") assert c.phooey(decimal_to_int("-1.2")) == decimal_to_int("20736.0") assert c.arg(decimal_to_int("-3.7")) == decimal_to_int("-3.7") @@ -163,7 +163,7 @@ def iarg() -> uint256: print("Passed fractional multiplication test") -def test_mul_overflow(tx_failed, get_contract_with_gas_estimation): +def test_mul_overflow(tx_failed, get_contract): mul_code = """ @external @@ -172,7 +172,7 @@ def _num_mul(x: decimal, y: decimal) -> decimal: """ - c = get_contract_with_gas_estimation(mul_code) + c = get_contract(mul_code) x = decimal_to_int("85070591730234615865843651857942052864") y = decimal_to_int("136112946768375385385349842973") @@ -247,7 +247,7 @@ def foo(x: decimal, y: decimal) -> decimal: ) -def test_decimal_min_max_literals(tx_failed, get_contract_with_gas_estimation): +def test_decimal_min_max_literals(tx_failed, get_contract): code = """ @external def maximum(): @@ -256,13 +256,13 @@ def maximum(): def minimum(): a: decimal = -18707220957835557353007165858768422651595.9365500928 """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) - assert c.maximum() == [] - assert c.minimum() == [] + assert c.maximum() is None + assert c.minimum() is None -def test_scientific_notation(get_contract_with_gas_estimation): +def test_scientific_notation(get_contract): code = """ @external def foo() -> decimal: @@ -272,7 +272,7 @@ def foo() -> decimal: def bar(num: decimal) -> decimal: return num + -1e38 """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == decimal_to_int("1e-10") # Smallest possible decimal assert c.bar(decimal_to_int("1e37")) == decimal_to_int("-9e37") # Math lines up diff --git a/tests/functional/codegen/types/numbers/test_isqrt.py b/tests/functional/codegen/types/numbers/test_isqrt.py index b734323a6e..c460742a98 100644 --- a/tests/functional/codegen/types/numbers/test_isqrt.py +++ b/tests/functional/codegen/types/numbers/test_isqrt.py @@ -7,35 +7,35 @@ @pytest.fixture(scope="module") -def isqrt_contract(get_contract_module): +def isqrt_contract(get_contract): code = """ @external def test(a: uint256) -> uint256: return isqrt(a) """ - c = get_contract_module(code) + c = get_contract(code) return c -def test_isqrt_literal(get_contract_with_gas_estimation): +def test_isqrt_literal(get_contract): val = 2 code = f""" @external def test() -> uint256: return isqrt({val}) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.test() == math.isqrt(val) -def test_isqrt_variable(get_contract_with_gas_estimation): +def test_isqrt_variable(get_contract): code = """ @external def test(a: uint256) -> uint256: return isqrt(a) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) val = 3333 assert c.test(val) == math.isqrt(val) @@ -45,7 +45,7 @@ def test(a: uint256) -> uint256: assert c.test(0) == 0 -def test_isqrt_internal_variable(get_contract_with_gas_estimation): +def test_isqrt_internal_variable(get_contract): val = 44001 code = f""" @external @@ -53,11 +53,11 @@ def test2() -> uint256: a: uint256 = {val} return isqrt(a) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.test2() == math.isqrt(val) -def test_isqrt_storage(get_contract_with_gas_estimation): +def test_isqrt_storage(get_contract): code = """ s_var: uint256 @@ -67,14 +67,14 @@ def test(a: uint256) -> uint256: return isqrt(self.s_var) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) val = 1221 assert c.test(val) == math.isqrt(val + 1) val = 10001 assert c.test(val) == math.isqrt(val + 1) -def test_isqrt_storage_internal_variable(get_contract_with_gas_estimation): +def test_isqrt_storage_internal_variable(get_contract): val = 44444 code = f""" s_var: uint256 @@ -84,11 +84,11 @@ def test2() -> uint256: self.s_var = {val} return isqrt(self.s_var) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.test2() == math.isqrt(val) -def test_isqrt_inline_memory_correct(get_contract_with_gas_estimation): +def test_isqrt_inline_memory_correct(get_contract): code = """ @external def test(a: uint256) -> (uint256, uint256, uint256, uint256, uint256, String[100]): @@ -100,10 +100,10 @@ def test(a: uint256) -> (uint256, uint256, uint256, uint256, uint256, String[100 return a, x, y, z, e, f """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) val = 21 - assert c.test(val) == [val, 1, 2, 3, math.isqrt(val), "hello world"] + assert c.test(val) == (val, 1, 2, 3, math.isqrt(val), "hello world") @pytest.mark.fuzzing diff --git a/tests/functional/codegen/types/numbers/test_modulo.py b/tests/functional/codegen/types/numbers/test_modulo.py index 3b204e8121..48a6db8a29 100644 --- a/tests/functional/codegen/types/numbers/test_modulo.py +++ b/tests/functional/codegen/types/numbers/test_modulo.py @@ -4,7 +4,7 @@ from vyper.exceptions import ZeroDivisionException -def test_modulo(get_contract_with_gas_estimation): +def test_modulo(get_contract): code = """ @external def num_modulo_num() -> int128: @@ -23,20 +23,20 @@ def decimal_modulo_num() -> decimal: def num_modulo_decimal() -> decimal: return 1.5 % 1.0 """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.num_modulo_num() == 1 assert c.decimal_modulo_decimal() == decimal_to_int(".18") assert c.decimal_modulo_num() == decimal_to_int(".5") assert c.num_modulo_decimal() == decimal_to_int(".5") -def test_modulo_with_input_of_zero(tx_failed, get_contract_with_gas_estimation): +def test_modulo_with_input_of_zero(tx_failed, get_contract): code = """ @external def foo(a: decimal, b: decimal) -> decimal: return a % b """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) with tx_failed(): c.foo(decimal_to_int("1"), decimal_to_int("0")) @@ -56,7 +56,7 @@ def bar(a: int128) -> bool: """ c = get_contract(code) - assert c.foo() == [1, 1, -1, -1] + assert c.foo() == (1, 1, -1, -1) assert c.bar(-5) is True diff --git a/tests/functional/codegen/types/numbers/test_signed_ints.py b/tests/functional/codegen/types/numbers/test_signed_ints.py index 01c2cd74c4..608783000a 100644 --- a/tests/functional/codegen/types/numbers/test_signed_ints.py +++ b/tests/functional/codegen/types/numbers/test_signed_ints.py @@ -152,7 +152,7 @@ def foo(x: {typ}) -> {typ}: @pytest.mark.parametrize("typ", types) -def test_negative_nums(get_contract_with_gas_estimation, typ): +def test_negative_nums(get_contract, typ): negative_nums_code = f""" @external def negative_one() -> {typ}: @@ -168,14 +168,14 @@ def negative_four() -> {typ}: return -(a+2) """ - c = get_contract_with_gas_estimation(negative_nums_code) + c = get_contract(negative_nums_code) assert c.negative_one() == -1 assert c.negative_three() == -3 assert c.negative_four() == -4 @pytest.mark.parametrize("typ", types) -def test_num_bound(tx_failed, get_contract_with_gas_estimation, typ): +def test_num_bound(tx_failed, get_contract, typ): lo, hi = typ.ast_bounds num_bound_code = f""" @@ -204,7 +204,7 @@ def _num_min() -> {typ}: return {lo} """ - c = get_contract_with_gas_estimation(num_bound_code) + c = get_contract(num_bound_code) assert c._num_add(hi, 0) == hi assert c._num_sub(lo, 0) == lo diff --git a/tests/functional/codegen/types/numbers/test_sqrt.py b/tests/functional/codegen/types/numbers/test_sqrt.py index 94676404e8..4fb6ff1f45 100644 --- a/tests/functional/codegen/types/numbers/test_sqrt.py +++ b/tests/functional/codegen/types/numbers/test_sqrt.py @@ -2,7 +2,6 @@ import hypothesis import pytest -from eth_tester.exceptions import TransactionFailed from tests.utils import decimal_to_int from vyper.utils import SizeLimits @@ -23,18 +22,18 @@ def decimal_sqrt(val): return decimal_to_int(decimal_truncate(val.sqrt())) -def test_sqrt_literal(get_contract_with_gas_estimation): +def test_sqrt_literal(get_contract): code = """ @external def test() -> decimal: return sqrt(2.0) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.test() == decimal_sqrt(Decimal("2")) # TODO: use parametrization here -def test_sqrt_variable(get_contract_with_gas_estimation): +def test_sqrt_variable(get_contract): code = """ @external def test(a: decimal) -> decimal: @@ -46,7 +45,7 @@ def test2() -> decimal: return sqrt(a) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) val = Decimal("33.33") assert c.test(decimal_to_int(val)) == decimal_sqrt(val) @@ -58,7 +57,7 @@ def test2() -> decimal: assert c.test2() == decimal_sqrt(Decimal("44.001")) -def test_sqrt_storage(get_contract_with_gas_estimation): +def test_sqrt_storage(get_contract): code = """ s_var: decimal @@ -73,7 +72,7 @@ def test2() -> decimal: return sqrt(self.s_var) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) val = Decimal("12.21") assert c.test(decimal_to_int(val)) == decimal_sqrt(val + 1) val = Decimal("100.01") @@ -81,7 +80,7 @@ def test2() -> decimal: assert c.test2() == decimal_sqrt(Decimal("444.44")) -def test_sqrt_inline_memory_correct(get_contract_with_gas_estimation): +def test_sqrt_inline_memory_correct(get_contract): code = """ @external def test(a: decimal) -> (decimal, decimal, decimal, decimal, decimal, String[100]): @@ -93,17 +92,17 @@ def test(a: decimal) -> (decimal, decimal, decimal, decimal, decimal, String[100 return a, x, y, z, e, f """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) val = Decimal("2.1") - assert c.test(decimal_to_int(val)) == [ + assert c.test(decimal_to_int(val)) == ( decimal_to_int(val), decimal_to_int("1"), decimal_to_int("2"), decimal_to_int("3"), decimal_sqrt(val), "hello world", - ] + ) @pytest.mark.parametrize("value", DECIMAL_RANGE) @@ -122,13 +121,13 @@ def test(a: decimal) -> decimal: @pytest.fixture(scope="module") -def sqrt_contract(get_contract_module): +def sqrt_contract(get_contract): code = """ @external def test(a: decimal) -> decimal: return sqrt(a) """ - c = get_contract_module(code) + c = get_contract(code) return c @@ -161,6 +160,6 @@ def test_sqrt_valid_range(sqrt_contract, value): ) @hypothesis.example(value=Decimal(SizeLimits.MIN_INT128)) @hypothesis.example(value=Decimal("-1E10")) -def test_sqrt_invalid_range(sqrt_contract, value): - with pytest.raises(TransactionFailed): +def test_sqrt_invalid_range(tx_failed, sqrt_contract, value): + with tx_failed(): sqrt_contract.test(decimal_to_int(value)) diff --git a/tests/functional/codegen/types/test_array_indexing.py b/tests/functional/codegen/types/test_array_indexing.py index 321f6e620c..45e777d919 100644 --- a/tests/functional/codegen/types/test_array_indexing.py +++ b/tests/functional/codegen/types/test_array_indexing.py @@ -1,10 +1,7 @@ -import pytest -from eth_tester.exceptions import TransactionFailed - # TODO: rewrite the tests in type-centric way, parametrize array and indices types -def test_negative_ix_access(get_contract): +def test_negative_ix_access(get_contract, tx_failed): # Arrays can't be accessed with negative indices code = """ arr: uint256[3] @@ -16,13 +13,15 @@ def foo(i: int128): c = get_contract(code) - with pytest.raises(TransactionFailed): + with tx_failed(): c.foo(-1) + with tx_failed(): c.foo(-3) + with tx_failed(): c.foo(-(2**127) + 1) -def test_negative_ix_access_to_large_arr(get_contract): +def test_negative_ix_access_to_large_arr(get_contract, tx_failed): # Arrays can't be accessed with negative indices code = """ arr: public(uint256[max_value(uint256)-1]) @@ -33,14 +32,17 @@ def set(idx: int256): """ c = get_contract(code) - with pytest.raises(TransactionFailed): + with tx_failed(): c.set(-(2**255)) + with tx_failed(): c.set(-(2**255) + 5) + with tx_failed(): c.set(-(2**128)) + with tx_failed(): c.set(-1) -def test_oob_access_to_large_arr(get_contract): +def test_oob_access_to_large_arr(get_contract, tx_failed): # Test OOB access to large array code = """ arr: public(uint256[max_value(uint256)-1]) @@ -55,9 +57,10 @@ def set2(idx: uint256): """ c = get_contract(code) - with pytest.raises(TransactionFailed): - c.set2(2**256 - 1, transact={}) - c.set2(2**256 - 2, transact={}) + with tx_failed(): + c.set2(2**256 - 1) + with tx_failed(): + c.set2(2**256 - 2) def test_boundary_access_to_arr(get_contract): @@ -79,14 +82,14 @@ def set2(idx: uint256): """ c1 = get_contract(code) - c1.set1(2**255 - 2, transact={}) + c1.set1(2**255 - 2) assert c1.arr1(2**255 - 2) == 3 - c1.set1(0, transact={}) + c1.set1(0) assert c1.arr1(0) == 3 c2 = get_contract(code2) - c2.set2(2**256 - 3, transact={}) + c2.set2(2**256 - 3) assert c2.arr2(2**256 - 3) == 3 @@ -106,9 +109,9 @@ def bar(i: uint256): c = get_contract(code) for i in range(3): - c.foo(i, transact={}) + c.foo(i) assert c.arr(i) == 1 - c.bar(i, transact={}) + c.bar(i) assert c.arr(i) == 2 @@ -124,6 +127,6 @@ def foo(): """ c = get_contract(code) - c.foo(transact={}) + c.foo() for i in range(10): assert c.arr(i) == i diff --git a/tests/functional/codegen/types/test_bytes.py b/tests/functional/codegen/types/test_bytes.py index f8ae65cc54..a5b119f143 100644 --- a/tests/functional/codegen/types/test_bytes.py +++ b/tests/functional/codegen/types/test_bytes.py @@ -3,14 +3,14 @@ from vyper.exceptions import TypeMismatch -def test_test_bytes(get_contract_with_gas_estimation, tx_failed): +def test_test_bytes(get_contract, tx_failed): test_bytes = """ @external def foo(x: Bytes[100]) -> Bytes[100]: return x """ - c = get_contract_with_gas_estimation(test_bytes) + c = get_contract(test_bytes) moo_result = c.foo(b"cow") assert moo_result == b"cow" @@ -27,7 +27,7 @@ def foo(x: Bytes[100]) -> Bytes[100]: print("Passed input-too-long test") -def test_test_bytes2(get_contract_with_gas_estimation): +def test_test_bytes2(get_contract): test_bytes2 = """ @external def foo(x: Bytes[100]) -> Bytes[100]: @@ -35,7 +35,7 @@ def foo(x: Bytes[100]) -> Bytes[100]: return y """ - c = get_contract_with_gas_estimation(test_bytes2) + c = get_contract(test_bytes2) assert c.foo(b"cow") == b"cow" assert c.foo(b"") == b"" assert c.foo(b"\x35" * 63) == b"\x35" * 63 @@ -45,7 +45,7 @@ def foo(x: Bytes[100]) -> Bytes[100]: print("Passed string copying test") -def test_test_bytes3(get_contract_with_gas_estimation): +def test_test_bytes3(get_contract): test_bytes3 = """ x: int128 maa: Bytes[60] @@ -79,24 +79,24 @@ def get_xy() -> int128: return self.x * self.y """ - c = get_contract_with_gas_estimation(test_bytes3) - c.set_maa(b"pig", transact={}) + c = get_contract(test_bytes3) + c.set_maa(b"pig") assert c.get_maa() == b"pig" assert c.get_maa2() == b"pig" - c.set_maa2(b"", transact={}) + c.set_maa2(b"") assert c.get_maa() == b"" assert c.get_maa2() == b"" - c.set_maa(b"\x44" * 60, transact={}) + c.set_maa(b"\x44" * 60) assert c.get_maa() == b"\x44" * 60 assert c.get_maa2() == b"\x44" * 60 - c.set_maa2(b"mongoose", transact={}) + c.set_maa2(b"mongoose") assert c.get_maa() == b"mongoose" assert c.get_xy() == 999 print("Passed advanced string copying test") -def test_test_bytes4(get_contract_with_gas_estimation): +def test_test_bytes4(get_contract): test_bytes4 = """ a: Bytes[60] @external @@ -112,14 +112,14 @@ def bar(inp: Bytes[60]) -> Bytes[60]: return b """ - c = get_contract_with_gas_estimation(test_bytes4) + c = get_contract(test_bytes4) assert c.foo(b"") == b"", c.foo() assert c.bar(b"") == b"" print("Passed string deleting test") -def test_test_bytes5(get_contract_with_gas_estimation): +def test_test_bytes5(get_contract): test_bytes5 = """ struct G: a: Bytes[50] @@ -159,20 +159,20 @@ def quz(inp1: Bytes[40], inp2: Bytes[45]): self.g.b = h.b """ - c = get_contract_with_gas_estimation(test_bytes5) - c.foo(b"cow", b"horse", transact={}) + c = get_contract(test_bytes5) + c.foo(b"cow", b"horse") assert c.check1() == b"cow" assert c.check2() == b"horse" assert c.bar(b"pig", b"moose") == b"pig" assert c.bat(b"pig", b"moose") == b"moose" - c.quz(b"badminton", b"fluffysheep", transact={}) + c.quz(b"badminton", b"fluffysheep") assert c.check1() == b"badminton" assert c.check2() == b"fluffysheep" print("Passed string struct test") -def test_binary_literal(get_contract_with_gas_estimation): +def test_binary_literal(get_contract): bytes_to_num_code = """ r: Bytes[1] @@ -194,7 +194,7 @@ def testsome_storage(y: Bytes[1]) -> bool: return self.r == y """ - c = get_contract_with_gas_estimation(bytes_to_num_code) + c = get_contract(bytes_to_num_code) assert c.getsome() == b"\x0e" assert c.testsome(b"a") @@ -205,7 +205,7 @@ def testsome_storage(y: Bytes[1]) -> bool: assert not c.testsome_storage(b"x") -def test_bytes_comparison(get_contract_with_gas_estimation): +def test_bytes_comparison(get_contract): code = """ @external def get_mismatch(a: Bytes[1]) -> bool: @@ -218,7 +218,7 @@ def get_large(a: Bytes[100]) -> bool: return a == b """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.get_mismatch(b"\x00") is False assert c.get_large(b"\x00") is False assert c.get_large(b"ab") is True @@ -286,11 +286,11 @@ def get_count() -> Bytes[24]: c = get_contract(code) assert c.get_count() == b"\x00\x00\x00\x00\x00\x00\x00\x00" - c.set_count(1, transact={}) + c.set_count(1) assert c.get_count() == b"\x01\x00\x00\x00\x00\x00\x00\x00" - c.set_count(0xF0F0F0, transact={}) + c.set_count(0xF0F0F0) assert c.get_count() == b"\xf0\xf0\xf0\x00\x00\x00\x00\x00" - c.set_count(0x0101010101010101, transact={}) + c.set_count(0x0101010101010101) assert c.get_count() == b"\x01\x01\x01\x01\x01\x01\x01\x01" diff --git a/tests/functional/codegen/types/test_bytes_literal.py b/tests/functional/codegen/types/test_bytes_literal.py index 90aa81a88f..42d3095fb2 100644 --- a/tests/functional/codegen/types/test_bytes_literal.py +++ b/tests/functional/codegen/types/test_bytes_literal.py @@ -3,7 +3,7 @@ import pytest -def test_bytes_literal_code(get_contract_with_gas_estimation): +def test_bytes_literal_code(get_contract): bytes_literal_code = """ @external def foo() -> Bytes[5]: @@ -31,7 +31,7 @@ def baz4() -> Bytes[100]: b"01234567890123456789012345678901234567890123456789") """ - c = get_contract_with_gas_estimation(bytes_literal_code) + c = get_contract(bytes_literal_code) assert c.foo() == b"horse" assert c.bar() == b"badminton" assert c.baz() == b"012345678901234567890123456789012" @@ -43,7 +43,7 @@ def baz4() -> Bytes[100]: @pytest.mark.parametrize("i,e,_s", itertools.product([95, 96, 97], [63, 64, 65], [31, 32, 33])) -def test_bytes_literal_splicing_fuzz(get_contract_with_gas_estimation, i, e, _s): +def test_bytes_literal_splicing_fuzz(get_contract, i, e, _s): kode = f""" moo: Bytes[100] @@ -76,7 +76,7 @@ def baz(s: uint256, L: uint256) -> Bytes[100]: return b"3434346667777" """ - c = get_contract_with_gas_estimation(kode) + c = get_contract(kode) o1 = c.foo(_s, e - _s) o2 = c.bar(_s, e - _s) o3 = c.baz(_s, e - _s) diff --git a/tests/functional/codegen/types/test_bytes_zero_padding.py b/tests/functional/codegen/types/test_bytes_zero_padding.py index 40bd1de6fc..1824f1fc47 100644 --- a/tests/functional/codegen/types/test_bytes_zero_padding.py +++ b/tests/functional/codegen/types/test_bytes_zero_padding.py @@ -3,7 +3,7 @@ @pytest.fixture(scope="module") -def little_endian_contract(get_contract_module): +def little_endian_contract(get_contract): code = """ @internal @view @@ -20,8 +20,7 @@ def to_little_endian_64(_value: uint256) -> Bytes[8]: def get_count(counter: uint256) -> Bytes[24]: return self.to_little_endian_64(counter) """ - c = get_contract_module(code) - return c + return get_contract(code) @pytest.mark.fuzzing diff --git a/tests/functional/codegen/types/test_dynamic_array.py b/tests/functional/codegen/types/test_dynamic_array.py index 1383895c7a..e475b79be1 100644 --- a/tests/functional/codegen/types/test_dynamic_array.py +++ b/tests/functional/codegen/types/test_dynamic_array.py @@ -1,4 +1,5 @@ import itertools +from typing import Any, Callable import pytest @@ -15,7 +16,7 @@ ) -def test_list_tester_code(get_contract_with_gas_estimation): +def test_list_tester_code(get_contract): list_tester_code = """ z: DynArray[int128, 3] z2: DynArray[DynArray[int128, 2], 2] @@ -52,7 +53,7 @@ def loo(x: DynArray[DynArray[int128, 2], 2]) -> int128: return self.z2[0][0] + self.z2[0][1] + self.z3[0] * 10 + self.z3[1] * 10 """ - c = get_contract_with_gas_estimation(list_tester_code) + c = get_contract(list_tester_code) assert c.foo([3, 4, 5]) == 12 assert c.goo([[1, 2], [3, 4]]) == 73 assert c.hoo([3, 4, 5]) == 12 @@ -102,7 +103,7 @@ def foo6() -> DynArray[DynArray[String[32], 2], 2]: assert c.foo6() == [["hello", "world"]] -def test_list_output_tester_code(get_contract_with_gas_estimation): +def test_list_output_tester_code(get_contract): list_output_tester_code = """ flag Foobar: FOO @@ -203,7 +204,7 @@ def uoo(inp: DynArray[Foobar, 2]) -> DynArray[DynArray[Foobar, 2], 2]: return [inp, [Foobar.BAR, Foobar.FOO]] """ - c = get_contract_with_gas_estimation(list_output_tester_code) + c = get_contract(list_output_tester_code) assert c.foo() == [3, 5] assert c.goo() == [3, 5] assert c.hoo() == [3, 5] @@ -231,7 +232,7 @@ def uoo(inp: DynArray[Foobar, 2]) -> DynArray[DynArray[Foobar, 2], 2]: print("Passed list output tests") -def test_array_accessor(get_contract_with_gas_estimation): +def test_array_accessor(get_contract): array_accessor = """ @external def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: @@ -243,12 +244,12 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: return a[0] * 1000 + a[1] * 100 + a[2] * 10 + a[3] """ - c = get_contract_with_gas_estimation(array_accessor) + c = get_contract(array_accessor) assert c.test_array(2, 7, 1, 8) == 2718 print("Passed basic array accessor test") -def test_two_d_array_accessor(get_contract_with_gas_estimation): +def test_two_d_array_accessor(get_contract): two_d_array_accessor = """ @external def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: @@ -260,12 +261,12 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: return a[0][0] * 1000 + a[0][1] * 100 + a[1][0] * 10 + a[1][1] """ - c = get_contract_with_gas_estimation(two_d_array_accessor) + c = get_contract(two_d_array_accessor) assert c.test_array(2, 7, 1, 8) == 2718 print("Passed complex array accessor test") -def test_three_d_array_accessor(get_contract_with_gas_estimation): +def test_three_d_array_accessor(get_contract): three_d_array_accessor = """ @external def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: @@ -282,11 +283,11 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: a[1][1][1] * 1000 + a[1][1][0] * 100 + a[1][0][1] * 10 + a[1][0][0] """ - c = get_contract_with_gas_estimation(three_d_array_accessor) + c = get_contract(three_d_array_accessor) assert c.test_array(2, 7, 1, 8) == -5454 -def test_four_d_array_accessor(get_contract_with_gas_estimation): +def test_four_d_array_accessor(get_contract): four_d_array_accessor = """ @external def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: @@ -315,11 +316,11 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: a[1][1][1][1] * 1000 + a[1][1][1][0] * 100 + a[1][1][0][1] * 10 + a[1][1][0][0] """ - c = get_contract_with_gas_estimation(four_d_array_accessor) + c = get_contract(four_d_array_accessor) assert c.test_array(2, 7, 1, 8) == -10908 -def test_array_negative_accessor(get_contract_with_gas_estimation, assert_compile_failed): +def test_array_negative_accessor(get_contract, assert_compile_failed): array_constant_negative_accessor = """ FOO: constant(int128) = -1 @external @@ -346,9 +347,7 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: return a[-4] * 1000 + a[-3] * 100 + a[-2] * 10 + a[-1] """ - assert_compile_failed( - lambda: get_contract_with_gas_estimation(array_negative_accessor), ArrayIndexException - ) + assert_compile_failed(lambda: get_contract(array_negative_accessor), ArrayIndexException) two_d_array_negative_accessor = """ @external @@ -361,9 +360,7 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: return a[-2][-2] * 1000 + a[-2][-1] * 100 + a[-1][-2] * 10 + a[-1][-1] """ - assert_compile_failed( - lambda: get_contract_with_gas_estimation(two_d_array_negative_accessor), ArrayIndexException - ) + assert_compile_failed(lambda: get_contract(two_d_array_negative_accessor), ArrayIndexException) three_d_array_negative_accessor = """ @external @@ -382,8 +379,7 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: """ assert_compile_failed( - lambda: get_contract_with_gas_estimation(three_d_array_negative_accessor), - ArrayIndexException, + lambda: get_contract(three_d_array_negative_accessor), ArrayIndexException ) four_d_array_negative_accessor = """ @@ -418,10 +414,7 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: 100 + a[-1][-1][-2][-1] * 10 + a[-1][-1][-2][-2] """ - assert_compile_failed( - lambda: get_contract_with_gas_estimation(four_d_array_negative_accessor), - ArrayIndexException, - ) + assert_compile_failed(lambda: get_contract(four_d_array_negative_accessor), ArrayIndexException) @pytest.mark.parametrize( @@ -447,21 +440,21 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: ), ], ) -def test_member_in_list(get_contract_with_gas_estimation, type, values, false_value): +def test_member_in_list(get_contract, type, values, false_value): code = f""" @external def check(a: {type}) -> bool: x: DynArray[{type}, 2] = [{values[0]}, {values[1]}] return a in x """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.check(values[0]) is True assert c.check(values[1]) is True assert c.check(false_value) is False @pytest.mark.parametrize("type_", ("uint256", "bytes32", "address")) -def test_member_in_empty_list(get_contract_with_gas_estimation, type_): +def test_member_in_empty_list(get_contract, type_): code = f""" @external def check_in(s: uint128) -> bool: @@ -475,7 +468,7 @@ def check_not_in(s: uint128) -> bool: x: DynArray[{type_}, 2] = [] return a not in x """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) for s in (0, 1, 2, 3): assert c.check_in(s) is False assert c.check_not_in(s) is True @@ -488,7 +481,7 @@ def check_not_in(s: uint128) -> bool: ("bool", [[True, True], [False, False]], [False, True]), ], ) -def test_member_in_nested_list(get_contract_with_gas_estimation, type, values, false_values): +def test_member_in_nested_list(get_contract, type, values, false_values): code = f""" @external def check1(a: {type}) -> bool: @@ -500,7 +493,7 @@ def check2(a: {type}) -> bool: x: DynArray[DynArray[{type}, 2], 2] = {values} return a in x[1] """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.check1(values[0][0]) is True assert c.check1(values[0][1]) is True assert c.check1(false_values[0]) is False @@ -510,7 +503,7 @@ def check2(a: {type}) -> bool: assert c.check2(false_values[1]) is False -def test_member_in_nested_address_list(get_contract_with_gas_estimation): +def test_member_in_nested_address_list(get_contract): code = """ @external def check1(a: address) -> bool: @@ -540,7 +533,7 @@ def check2(a: address) -> bool: ] return a in x[1] """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.check1("0x0000000000000000000000000000000000000012") is True assert c.check1("0x0000000000000000000000000000000000000024") is True assert c.check1("0x0000000000000000000000000000000000000036") is False @@ -550,7 +543,7 @@ def check2(a: address) -> bool: assert c.check2("0x0000000000000000000000000000000000000024") is False -def test_member_in_nested_bytes32_list(get_contract_with_gas_estimation): +def test_member_in_nested_bytes32_list(get_contract): code = """ @external def check1(a: bytes32) -> bool: @@ -580,7 +573,7 @@ def check2(a: bytes32) -> bool: ] return a in x[1] """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.check1("0x0000000000000000000000000000000000000000000000000000000080ac58ca") is True assert c.check1("0x0000000000000000000000000000000000000000000000000000000080ac58cb") is True assert c.check1("0x0000000000000000000000000000000000000000000000000000000080ac58cc") is False @@ -590,7 +583,7 @@ def check2(a: bytes32) -> bool: assert c.check2("0x0000000000000000000000000000000000000000000000000000000080ac58ca") is False -def test_member_in_updated_list(get_contract_with_gas_estimation): +def test_member_in_updated_list(get_contract): code = """ @external def foo() -> bool: @@ -599,11 +592,11 @@ def foo() -> bool: y: uint256 = 2 return y in xs """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() is False -def test_member_in_updated_nested_list(get_contract_with_gas_estimation): +def test_member_in_updated_nested_list(get_contract): code = """ @external def foo() -> bool: @@ -622,11 +615,11 @@ def foo() -> bool: y in xs[1][0] or y in xs[1][1] or y in xs[1][2] or \\ y in xs[2][0] or y in xs[2][1] or y in xs[2][2] """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() is False -def test_member_in_list_lhs_side_effects(get_contract_with_gas_estimation): +def test_member_in_list_lhs_side_effects(get_contract): code = """ _counter: uint256 @@ -640,11 +633,11 @@ def bar() -> bool: x: DynArray[uint256, 4] = [2, 2, 2, 2] return self.counter() in x """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.bar() is False -def test_member_in_nested_list_lhs_side_effects(get_contract_with_gas_estimation): +def test_member_in_nested_list_lhs_side_effects(get_contract): code = """ _counter: uint256 @@ -662,11 +655,11 @@ def bar() -> bool: ] return self.counter() in x[0][0] """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.bar() is False -def test_member_in_list_rhs_side_effects(get_contract_with_gas_estimation): +def test_member_in_list_rhs_side_effects(get_contract): code = """ counter: uint256 @@ -681,11 +674,11 @@ def bar() -> uint256: t: bool = self.counter in self.foo() return self.counter """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.bar() == 1 -def test_member_in_nested_list_rhs_side_effects(get_contract_with_gas_estimation): +def test_member_in_nested_list_rhs_side_effects(get_contract): code = """ counter: uint256 @@ -704,11 +697,11 @@ def bar() -> uint256: t: bool = self.counter in self.foo()[0][0] return self.counter """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.bar() == 1 -def test_returns_lists(get_contract_with_gas_estimation): +def test_returns_lists(get_contract): code = """ @external def test_array_num_return() -> DynArray[DynArray[int128, 2], 2]: @@ -730,7 +723,7 @@ def test_array_decimal_return3() -> DynArray[DynArray[decimal, 2], 2]: return a """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.test_array_num_return() == [[], [3, 4]] assert c.test_array_decimal_return1() == [ [decimal_to_int(1)], @@ -744,7 +737,7 @@ def test_array_decimal_return3() -> DynArray[DynArray[decimal, 2], 2]: @pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") -def test_mult_list(get_contract_with_gas_estimation): +def test_mult_list(get_contract): code = """ nest3: DynArray[DynArray[DynArray[uint256, 2], 2], 2] nest4: DynArray[DynArray[DynArray[DynArray[uint256, 2], 2], 2], 2] @@ -776,7 +769,7 @@ def test_multi4_2() -> DynArray[DynArray[DynArray[DynArray[uint256, 2], 2], 2], return self.nest4 """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) nest3 = [[[0, 0], [0, 4]], [[0, 7], [0, 123]]] assert c.test_multi3_1() == nest3 @@ -786,13 +779,13 @@ 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, tx_failed): +def test_uint256_accessor(get_contract, 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) + c = get_contract(code) with tx_failed(): c.bounds_check_uint256([], 0) @@ -809,37 +802,37 @@ def bounds_check_uint256(xs: DynArray[uint256, 3], ix: uint256) -> uint256: @pytest.mark.parametrize("list_", ([], [11], [11, 12], [11, 12, 13])) -def test_dynarray_len(get_contract_with_gas_estimation, tx_failed, list_): +def test_dynarray_len(get_contract, tx_failed, list_): code = """ @external def darray_len(xs: DynArray[uint256, 3]) -> uint256: return len(xs) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.darray_len(list_) == len(list_) -def test_dynarray_too_large(get_contract_with_gas_estimation, tx_failed): +def test_dynarray_too_large(get_contract, tx_failed): code = """ @external def darray_len(xs: DynArray[uint256, 3]) -> uint256: return len(xs) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) with tx_failed(): c.darray_len([1, 2, 3, 4]) -def test_int128_accessor(get_contract_with_gas_estimation, tx_failed): +def test_int128_accessor(get_contract, tx_failed): code = """ @external def bounds_check_int128(ix: int128) -> uint256: xs: DynArray[uint256, 3] = [1,2,3] return xs[ix] """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.bounds_check_int128(0) == 1 assert c.bounds_check_int128(2) == 3 with tx_failed(): @@ -848,14 +841,14 @@ def bounds_check_int128(ix: int128) -> uint256: c.bounds_check_int128(-1) -def test_index_exception(get_contract_with_gas_estimation, assert_compile_failed): +def test_index_exception(get_contract, assert_compile_failed): code = """ @external def fail() -> uint256: xs: DynArray[uint256, 3] = [1,2,3] return xs[3] """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code), ArrayIndexException) + assert_compile_failed(lambda: get_contract(code), ArrayIndexException) code = """ @external @@ -863,17 +856,17 @@ def fail() -> uint256: xs: DynArray[uint256, 3] = [1,2,3] return xs[-1] """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code), ArrayIndexException) + assert_compile_failed(lambda: get_contract(code), ArrayIndexException) -def test_compile_time_bounds_check(get_contract_with_gas_estimation, assert_compile_failed): +def test_compile_time_bounds_check(get_contract, assert_compile_failed): code = """ @external def parse_list_fail(): xs: DynArray[uint256, 3] = [2**256, 1, 3] pass """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code), OverflowException) + assert_compile_failed(lambda: get_contract(code), OverflowException) def test_2d_array_input_1(get_contract): @@ -892,7 +885,7 @@ def test_values( """ c = get_contract(code) - assert c.test_values([[1, 2]], 3) == [[[1, 2]], 3] + assert c.test_values([[1, 2]], 3) == ([[1, 2]], 3) def test_2d_array_input_2(get_contract): @@ -913,7 +906,7 @@ def test_values( """ c = get_contract(code) - assert c.test_values([[1, 2], [3, 4], [5, 6]], "abcdef") == [[[1, 2], [3, 4], [5, 6]], "abcdef"] + assert c.test_values([[1, 2], [3, 4], [5, 6]], "abcdef") == ([[1, 2], [3, 4], [5, 6]], "abcdef") def test_nested_index_of_returned_array(get_contract): @@ -948,7 +941,7 @@ def foo() -> (uint256, uint256, uint256, uint256, uint256): """ c = get_contract(code) - assert c.foo() == [1, 2, 3, 4, 5] + assert c.foo() == (1, 2, 3, 4, 5) def test_nested_calls_inside_arrays_with_index_access(get_contract): @@ -971,7 +964,7 @@ def foo() -> (uint256, uint256, uint256, uint256, uint256): """ c = get_contract(code) - assert c.foo() == [1, 2, 3, 4, 5] + assert c.foo() == (1, 2, 3, 4, 5) append_pop_tests = [ @@ -1023,7 +1016,7 @@ def foo(xs: DynArray[uint256, 5]) -> (DynArray[uint256, 5], uint256): self.my_array.append(x) return self.my_array, self.my_array.pop() """, - lambda xs: None if len(xs) == 0 else [xs, xs[-1]], + lambda xs: None if len(xs) == 0 else (xs, xs[-1]), ), # check order of evaluation. ( @@ -1035,7 +1028,7 @@ def foo(xs: DynArray[uint256, 5]) -> (uint256, DynArray[uint256, 5]): self.my_array.append(x) return self.my_array.pop(), self.my_array """, - lambda xs: None if len(xs) == 0 else [xs[-1], xs[:-1]], + lambda xs: None if len(xs) == 0 else (xs[-1], xs[:-1]), ), # test memory arrays ( @@ -1208,7 +1201,7 @@ def test_append_pop(get_contract, tx_failed, code, check_result, test_data): assert c.foo(test_data) == expected_result -append_pop_complex_tests = [ +append_pop_complex_tests: list[tuple[str, Callable[[Any], Any]]] = [ ( """ @external @@ -1238,7 +1231,7 @@ def foo(x: {typ}) -> (DynArray[{typ}, 5], {typ}): self.my_array.append(x) return self.my_array, self.my_array.pop() """, - lambda x: [[x], x], + lambda x: ([x], x), ), ( """ @@ -1248,7 +1241,7 @@ def foo(x: {typ}) -> ({typ}, DynArray[{typ}, 5]): self.my_array.append(x) return self.my_array.pop(), self.my_array """, - lambda x: [x, []], + lambda x: (x, []), ), ( """ @@ -1322,7 +1315,7 @@ def foo() -> (uint256, DynArray[uint256, 3], DynArray[uint256, 2]): return 666, x, [88, self._foo2()[0]] """ c = get_contract(code) - assert c.foo() == [666, [1, 2, 3], [88, 12]] + assert c.foo() == (666, [1, 2, 3], [88, 12]) def test_list_of_structs_arg(get_contract): diff --git a/tests/functional/codegen/types/test_flag.py b/tests/functional/codegen/types/test_flag.py index 68aab1968f..9e82774959 100644 --- a/tests/functional/codegen/types/test_flag.py +++ b/tests/functional/codegen/types/test_flag.py @@ -43,7 +43,7 @@ def set_and_get(a: Actions) -> Actions: c = get_contract(code) for i in range(5): assert c.set_and_get(i) == i - c.set_and_get(i, transact={}) + c.set_and_get(i) assert c.action() == i @@ -152,7 +152,7 @@ def binv_arg(a: Roles) -> Roles: c.bxor_arg(3, 32) -def test_augassign_storage(get_contract, w3, tx_failed): +def test_augassign_storage(get_contract, env, tx_failed): code = """ flag Roles: ADMIN @@ -186,11 +186,11 @@ def checkMinter(minter: address): c = get_contract(code) # check admin - admin_address = w3.eth.accounts[0] - minter_address = w3.eth.accounts[1] + admin_address = env.deployer + minter_address = env.accounts[1] # add minter - c.addMinter(minter_address, transact={}) + c.addMinter(minter_address) c.checkMinter(minter_address) assert c.roles(admin_address) == 0b01 @@ -200,31 +200,31 @@ def checkMinter(minter: address): with tx_failed(): c.checkMinter(admin_address) - c.addMinter(admin_address, transact={}) + c.addMinter(admin_address) # now, admin is a minter assert c.roles(admin_address) == 0b11 c.checkMinter(admin_address) # revoke minter - c.revokeMinter(admin_address, transact={}) + c.revokeMinter(admin_address) assert c.roles(admin_address) == 0b01 with tx_failed(): c.checkMinter(admin_address) # flip minter - c.flipMinter(admin_address, transact={}) + c.flipMinter(admin_address) assert c.roles(admin_address) == 0b11 c.checkMinter(admin_address) # flip minter - c.flipMinter(admin_address, transact={}) + c.flipMinter(admin_address) assert c.roles(admin_address) == 0b01 with tx_failed(): c.checkMinter(admin_address) -def test_in_flag(get_contract_with_gas_estimation): +def test_in_flag(get_contract): code = """ flag Roles: USER @@ -252,7 +252,7 @@ def baz(a: Roles) -> bool: return a in (x & y) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() is True # CEO MANAGER ADMIN STAFF USER @@ -269,7 +269,7 @@ def baz(a: Roles) -> bool: assert c.baz(0b01000) is False # Roles.MANAGER should fail -def test_struct_with_flag(get_contract_with_gas_estimation): +def test_struct_with_flag(get_contract): code = """ flag Foobar: FOO @@ -284,11 +284,11 @@ def get_flag_from_struct() -> Foobar: f: Foo = Foo(a=1, b=Foobar.BAR) return f.b """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.get_flag_from_struct() == 2 -def test_mapping_with_flag(get_contract_with_gas_estimation): +def test_mapping_with_flag(get_contract): code = """ flag Foobar: FOO @@ -301,5 +301,5 @@ def get_key(f: Foobar, i: uint256) -> uint256: self.fb[f] = i return self.fb[f] """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.get_key(1, 777) == 777 diff --git a/tests/functional/codegen/types/test_lists.py b/tests/functional/codegen/types/test_lists.py index 9793ddbc38..953a9a9f9f 100644 --- a/tests/functional/codegen/types/test_lists.py +++ b/tests/functional/codegen/types/test_lists.py @@ -16,7 +16,7 @@ def _map_nested(f, xs): return ret -def test_list_tester_code(get_contract_with_gas_estimation): +def test_list_tester_code(get_contract): list_tester_code = """ z: int128[3] z2: int128[2][2] @@ -53,7 +53,7 @@ def loo(x: int128[2][2]) -> int128: return self.z2[0][0] + self.z2[0][1] + self.z3[0] * 10 + self.z3[1] * 10 """ - c = get_contract_with_gas_estimation(list_tester_code) + c = get_contract(list_tester_code) assert c.foo([3, 4, 5]) == 12 assert c.goo([[1, 2], [3, 4]]) == 73 assert c.hoo([3, 4, 5]) == 12 @@ -63,7 +63,7 @@ def loo(x: int128[2][2]) -> int128: print("Passed list tests") -def test_list_output_tester_code(get_contract_with_gas_estimation): +def test_list_output_tester_code(get_contract): list_output_tester_code = """ z: int128[2] @@ -118,7 +118,7 @@ def roo(inp: decimal[2]) -> decimal[2][2]: return [inp, [3.0, 4.0]] """ - c = get_contract_with_gas_estimation(list_output_tester_code) + c = get_contract(list_output_tester_code) assert c.foo() == [3, 5] assert c.goo() == [3, 5] assert c.hoo() == [3, 5] @@ -134,7 +134,7 @@ def roo(inp: decimal[2]) -> decimal[2][2]: ) -def test_array_accessor(get_contract_with_gas_estimation): +def test_array_accessor(get_contract): array_accessor = """ @external def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: @@ -146,12 +146,12 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: return a[0] * 1000 + a[1] * 100 + a[2] * 10 + a[3] """ - c = get_contract_with_gas_estimation(array_accessor) + c = get_contract(array_accessor) assert c.test_array(2, 7, 1, 8) == 2718 print("Passed basic array accessor test") -def test_two_d_array_accessor(get_contract_with_gas_estimation): +def test_two_d_array_accessor(get_contract): two_d_array_accessor = """ @external def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: @@ -163,12 +163,12 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: return a[0][0] * 1000 + a[0][1] * 100 + a[1][0] * 10 + a[1][1] """ - c = get_contract_with_gas_estimation(two_d_array_accessor) + c = get_contract(two_d_array_accessor) assert c.test_array(2, 7, 1, 8) == 2718 print("Passed complex array accessor test") -def test_three_d_array_accessor(get_contract_with_gas_estimation): +def test_three_d_array_accessor(get_contract): three_d_array_accessor = """ @external def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: @@ -185,11 +185,11 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: a[1][1][1] * 1000 + a[1][1][0] * 100 + a[1][0][1] * 10 + a[1][0][0] """ - c = get_contract_with_gas_estimation(three_d_array_accessor) + c = get_contract(three_d_array_accessor) assert c.test_array(2, 7, 1, 8) == -5454 -def test_four_d_array_accessor(get_contract_with_gas_estimation): +def test_four_d_array_accessor(get_contract): four_d_array_accessor = """ @external def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: @@ -218,11 +218,11 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: a[1][1][1][1] * 1000 + a[1][1][1][0] * 100 + a[1][1][0][1] * 10 + a[1][1][0][0] """ - c = get_contract_with_gas_estimation(four_d_array_accessor) + c = get_contract(four_d_array_accessor) assert c.test_array(2, 7, 1, 8) == -10908 -def test_array_negative_accessor(get_contract_with_gas_estimation, assert_compile_failed): +def test_array_negative_accessor(get_contract, assert_compile_failed): array_negative_accessor = """ @external def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: @@ -234,9 +234,7 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: return a[-4] * 1000 + a[-3] * 100 + a[-2] * 10 + a[-1] """ - assert_compile_failed( - lambda: get_contract_with_gas_estimation(array_negative_accessor), ArrayIndexException - ) + assert_compile_failed(lambda: get_contract(array_negative_accessor), ArrayIndexException) two_d_array_negative_accessor = """ @external @@ -249,9 +247,7 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: return a[-2][-2] * 1000 + a[-2][-1] * 100 + a[-1][-2] * 10 + a[-1][-1] """ - assert_compile_failed( - lambda: get_contract_with_gas_estimation(two_d_array_negative_accessor), ArrayIndexException - ) + assert_compile_failed(lambda: get_contract(two_d_array_negative_accessor), ArrayIndexException) three_d_array_negative_accessor = """ @external @@ -270,8 +266,7 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: """ assert_compile_failed( - lambda: get_contract_with_gas_estimation(three_d_array_negative_accessor), - ArrayIndexException, + lambda: get_contract(three_d_array_negative_accessor), ArrayIndexException ) four_d_array_negative_accessor = """ @@ -306,13 +301,10 @@ def test_array(x: int128, y: int128, z: int128, w: int128) -> int128: a[-1][-1][-2][-1] * 10 + a[-1][-1][-2][-2] """ - assert_compile_failed( - lambda: get_contract_with_gas_estimation(four_d_array_negative_accessor), - ArrayIndexException, - ) + assert_compile_failed(lambda: get_contract(four_d_array_negative_accessor), ArrayIndexException) -def test_returns_lists(get_contract_with_gas_estimation): +def test_returns_lists(get_contract): code = """ @external def test_array_num_return() -> int128[2][2]: @@ -334,14 +326,14 @@ def test_array_decimal_return3() -> decimal[2][2]: return a """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.test_array_num_return() == [[1, 2], [3, 4]] assert c.test_array_decimal_return1() == _map_nested(decimal_to_int, [[1.0, 2.0], [3.0, 4.0]]) assert c.test_array_decimal_return2() == _map_nested(decimal_to_int, [[1.0, 2.0], [3.0, 4.0]]) assert c.test_array_decimal_return3() == _map_nested(decimal_to_int, [[1.0, 2.0], [3.0, 4.0]]) -def test_mult_list(get_contract_with_gas_estimation): +def test_mult_list(get_contract): code = """ @external def test_multi3() -> uint256[2][2][2]: @@ -354,7 +346,7 @@ def test_multi4() -> uint256[2][2][2][2]: return l """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.test_multi3() == [[[0, 0], [0, 4]], [[0, 0], [0, 123]]] assert c.test_multi4() == [ @@ -364,14 +356,14 @@ def test_multi4() -> uint256[2][2][2][2]: @pytest.mark.parametrize("type_", ["uint8", "uint256"]) -def test_unsigned_accessors(get_contract_with_gas_estimation, tx_failed, type_): +def test_unsigned_accessors(get_contract, tx_failed, type_): code = f""" @external def bounds_check(ix: {type_}) -> uint256: xs: uint256[3] = [1,2,3] return xs[ix] """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.bounds_check(0) == 1 assert c.bounds_check(2) == 3 with tx_failed(): @@ -379,14 +371,14 @@ def bounds_check(ix: {type_}) -> uint256: @pytest.mark.parametrize("type_", ["int128", "int256"]) -def test_signed_accessors(get_contract_with_gas_estimation, tx_failed, type_): +def test_signed_accessors(get_contract, tx_failed, type_): code = f""" @external def bounds_check(ix: {type_}) -> uint256: xs: uint256[3] = [1,2,3] return xs[ix] """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.bounds_check(0) == 1 assert c.bounds_check(2) == 3 with tx_failed(): @@ -395,31 +387,31 @@ def bounds_check(ix: {type_}) -> uint256: c.bounds_check(-1) -def test_list_check_heterogeneous_types(get_contract_with_gas_estimation, assert_compile_failed): +def test_list_check_heterogeneous_types(get_contract, assert_compile_failed): code = """ @external def fail() -> uint256: xs: uint256[3] = [1,2,3] return xs[3] """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code), ArrayIndexException) + assert_compile_failed(lambda: get_contract(code), ArrayIndexException) code = """ @external def fail() -> uint256: xs: uint256[3] = [1,2,3] return xs[-1] """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code), ArrayIndexException) + assert_compile_failed(lambda: get_contract(code), ArrayIndexException) -def test_compile_time_bounds_check(get_contract_with_gas_estimation, assert_compile_failed): +def test_compile_time_bounds_check(get_contract, assert_compile_failed): code = """ @external def parse_list_fail(): xs: uint256[3] = [2**256, 1, 3] pass """ - assert_compile_failed(lambda: get_contract_with_gas_estimation(code), OverflowException) + assert_compile_failed(lambda: get_contract(code), OverflowException) def test_2d_array_input_1(get_contract): @@ -434,7 +426,7 @@ def test_values(arr: int128[2][1], i: int128) -> (int128[2][1], int128): """ c = get_contract(code) - assert c.test_values([[1, 2]], 3) == [[[1, 2]], 3] + assert c.test_values([[1, 2]], 3) == ([[1, 2]], 3) def test_2d_array_input_2(get_contract): @@ -449,7 +441,7 @@ def test_values(arr: int128[2][3], s: String[10]) -> (int128[2][3], String[10]): """ c = get_contract(code) - assert c.test_values([[1, 2], [3, 4], [5, 6]], "abcdef") == [[[1, 2], [3, 4], [5, 6]], "abcdef"] + assert c.test_values([[1, 2], [3, 4], [5, 6]], "abcdef") == ([[1, 2], [3, 4], [5, 6]], "abcdef") def test_nested_index_of_returned_array(get_contract): @@ -484,7 +476,7 @@ def foo() -> (uint256, uint256, uint256, uint256, uint256): """ c = get_contract(code) - assert c.foo() == [1, 2, 3, 4, 5] + assert c.foo() == (1, 2, 3, 4, 5) def test_nested_calls_inside_arrays_with_index_access(get_contract): @@ -504,7 +496,7 @@ def foo() -> (uint256, uint256, uint256, uint256, uint256): """ c = get_contract(code) - assert c.foo() == [1, 2, 3, 4, 5] + assert c.foo() == (1, 2, 3, 4, 5) def test_so_many_things_you_should_never_do(get_contract): @@ -525,7 +517,7 @@ def foo() -> (uint256, uint256[3], uint256[2]): return 666, x, [88, self._foo2()[0]] """ c = get_contract(code) - assert c.foo() == [666, [1, 2, 3], [88, 12]] + assert c.foo() == (666, [1, 2, 3], [88, 12]) def test_list_of_dynarray(get_contract): diff --git a/tests/functional/codegen/types/test_string.py b/tests/functional/codegen/types/test_string.py index 8871a69983..a573df47c2 100644 --- a/tests/functional/codegen/types/test_string.py +++ b/tests/functional/codegen/types/test_string.py @@ -3,7 +3,7 @@ pytestmark = pytest.mark.usefixtures("memory_mocker") -def test_string_return(get_contract_with_gas_estimation): +def test_string_return(get_contract): code = """ @external def testb() -> String[100]: @@ -15,13 +15,13 @@ def testa(inp: String[100]) -> String[100]: return inp """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.testa("meh") == "meh" assert c.testb() == "test return" -def test_string_concat(get_contract_with_gas_estimation): +def test_string_concat(get_contract): code = """ @external def testb(inp: String[10]) -> String[128]: @@ -35,13 +35,13 @@ def testa(inp: String[10]) -> String[160]: return concat("Funny ", inp, " ", inp, a) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.testb("bob") == "return message: bob" assert c.testa("foo") == "Funny foo foo<-- return message" -def test_basic_long_string_as_keys(get_contract, w3): +def test_basic_long_string_as_keys(get_contract): code = """ mapped_string: HashMap[String[34], int128] @@ -56,19 +56,19 @@ def get(k: String[34]) -> int128: c = get_contract(code) - c.set("a" * 34, 6789, transact={"gas": 10**6}) + c.set("a" * 34, 6789, gas=10**6) assert c.get("a" * 34) == 6789 -def test_string_slice(get_contract_with_gas_estimation, tx_failed): +def test_string_slice(get_contract, tx_failed): test_slice4 = """ @external def foo(inp: String[10], start: uint256, _len: uint256) -> String[10]: return slice(inp, start, _len) """ - c = get_contract_with_gas_estimation(test_slice4) + c = get_contract(test_slice4) assert c.foo("badminton", 3, 3) == "min" assert c.foo("badminton", 0, 9) == "badminton" assert c.foo("badminton", 1, 8) == "adminton" @@ -86,7 +86,7 @@ def foo(inp: String[10], start: uint256, _len: uint256) -> String[10]: c.foo("badminton", 10, 0) -def test_private_string(get_contract_with_gas_estimation): +def test_private_string(get_contract): private_test_code = """ greeting: public(String[100]) @@ -104,12 +104,12 @@ def hithere(name: String[100]) -> String[200]: return d """ - c = get_contract_with_gas_estimation(private_test_code) + c = get_contract(private_test_code) assert c.hithere("bob") == "Hello bob" assert c.hithere("alice") == "Hello alice" -def test_logging_extended_string(get_contract_with_gas_estimation, get_logs): +def test_logging_extended_string(get_contract, get_logs): code = """ event MyLog: arg1: int128 @@ -121,15 +121,16 @@ def foo(): log MyLog(667788, 'hellohellohellohellohellohellohellohellohello', 334455) """ - c = get_contract_with_gas_estimation(code) - log = get_logs(c.foo(transact={}), c, "MyLog") + c = get_contract(code) + c.foo() + (log,) = get_logs(c, "MyLog") - assert log[0].args.arg1 == 667788 - assert log[0].args.arg2 == "hello" * 9 - assert log[0].args.arg3 == 334455 + assert log.args.arg1 == 667788 + assert log.args.arg2 == "hello" * 9 + assert log.args.arg3 == 334455 -def test_tuple_return_external_contract_call_string(get_contract_with_gas_estimation): +def test_tuple_return_external_contract_call_string(get_contract): contract_1 = """ @external def out_literals() -> (int128, address, String[10]): @@ -148,14 +149,14 @@ def test(addr: address) -> (int128, address, String[10]): (a, b, c) = staticcall Test(addr).out_literals() return a, b,c """ - c1 = get_contract_with_gas_estimation(contract_1) - c2 = get_contract_with_gas_estimation(contract_2) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) - assert c1.out_literals() == [1, "0x0000000000000000000000000000000000000123", "random"] - assert c2.test(c1.address) == [1, "0x0000000000000000000000000000000000000123", "random"] + assert c1.out_literals() == (1, "0x0000000000000000000000000000000000000123", "random") + assert c2.test(c1.address) == (1, "0x0000000000000000000000000000000000000123", "random") -def test_default_arg_string(get_contract_with_gas_estimation): +def test_default_arg_string(get_contract): code = """ @external def test(a: uint256, b: String[50] = "foo") -> Bytes[100]: @@ -165,7 +166,7 @@ def test(a: uint256, b: String[50] = "foo") -> Bytes[100]: ) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.test(12345)[-3:] == b"foo" assert c.test(12345, "bar")[-3:] == b"bar" @@ -189,7 +190,7 @@ def test(a: uint256, b: String[50] = "foo") -> Bytes[100]: @pytest.mark.parametrize("len_,a,b", string_equality_tests) -def test_string_equality(get_contract_with_gas_estimation, len_, a, b): +def test_string_equality(get_contract, len_, a, b): # fixtures to initialize strings with dirty bytes a_init = "\\1" * len_ b_init = "\\2" * len_ @@ -332,7 +333,7 @@ def compare_var_storage_not_equal_false() -> bool: return self.a != b """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.equal_true() is True assert c.equal_false() is False assert c.not_equal_true() is True diff --git a/tests/functional/codegen/types/test_string_literal.py b/tests/functional/codegen/types/test_string_literal.py index 1cdd743ab2..90d403471a 100644 --- a/tests/functional/codegen/types/test_string_literal.py +++ b/tests/functional/codegen/types/test_string_literal.py @@ -1,4 +1,4 @@ -def test_string_literal_return(get_contract_with_gas_estimation): +def test_string_literal_return(get_contract): code = """ @external def test() -> String[100]: @@ -10,13 +10,13 @@ def testb() -> Bytes[100]: return b"hello world!" """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.test() == "hello world!" assert c.testb() == b"hello world!" -def test_string_convert(get_contract_with_gas_estimation): +def test_string_convert(get_contract): code = """ @external def testb() -> String[100]: @@ -27,13 +27,13 @@ def testbb() -> String[100]: return convert(convert("hello world!", Bytes[100]), String[100]) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.testb() == "hello world!" assert c.testbb() == "hello world!" -def test_str_assign(get_contract_with_gas_estimation): +def test_str_assign(get_contract): code = """ @external def test() -> String[100]: @@ -41,6 +41,6 @@ def test() -> String[100]: return a """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.test() == "baba black sheep" diff --git a/tests/functional/codegen/types/test_struct.py b/tests/functional/codegen/types/test_struct.py index 0a6132200d..c749de4127 100644 --- a/tests/functional/codegen/types/test_struct.py +++ b/tests/functional/codegen/types/test_struct.py @@ -21,10 +21,8 @@ def modify_nested_struct(_human: Human) -> Human: c = get_contract(code) addr1 = "0x1234567890123456789012345678901234567890" addr2 = "0x1234567890123456789012345678900000000000" - # assert c.modify_nested_tuple([addr1, 123], [addr2, 456]) == [[addr1, 124], [addr2, 457]] - assert c.modify_nested_struct( - {"location": addr1, "animal": {"location": addr2, "fur": "wool"}} - ) == (addr1, (addr2, "wool is great")) + # assert c.modify_nested_tuple([addr1, 123], [addr2, 456]) == ([addr1, 124], [addr2, 457]) + assert c.modify_nested_struct((addr1, (addr2, "wool"))) == (addr1, (addr2, "wool is great")) def test_nested_single_struct(get_contract): @@ -47,4 +45,4 @@ def modify_nested_single_struct(_human: Human) -> Human: """ c = get_contract(code) - assert c.modify_nested_single_struct({"animal": {"fur": "wool"}}) == (("wool is great",),) + assert c.modify_nested_single_struct((("wool",),)) == (("wool is great",),) diff --git a/tests/functional/examples/auctions/test_blind_auction.py b/tests/functional/examples/auctions/test_blind_auction.py index dcd4e0bf8b..06f0656f1d 100644 --- a/tests/functional/examples/auctions/test_blind_auction.py +++ b/tests/functional/examples/auctions/test_blind_auction.py @@ -1,5 +1,7 @@ import pytest +from tests.utils import ZERO_ADDRESS + MAX_BIDS = 128 BIDDING_TIME = 150 @@ -8,21 +10,21 @@ @pytest.fixture -def auction_contract(w3, get_contract): +def auction_contract(env, get_contract): with open("examples/auctions/blind_auction.vy") as f: contract_code = f.read() - contract = get_contract(contract_code, *[w3.eth.accounts[0], BIDDING_TIME, REVEAL_TIME]) - return contract + + for acc in env.accounts[1:4]: + env.set_balance(acc, 10**20) + + return get_contract(contract_code, *[env.deployer, BIDDING_TIME, REVEAL_TIME]) -def test_initial_state(w3, tester, auction_contract): +def test_initial_state(env, auction_contract): # Check beneficiary is correct - assert auction_contract.beneficiary() == w3.eth.accounts[0] + assert auction_contract.beneficiary() == env.deployer # Check that bidding end time is correct - assert ( - auction_contract.biddingEnd() - == tester.get_block_by_number("latest")["timestamp"] + BIDDING_TIME - ) # noqa: E501 + assert auction_contract.biddingEnd() == env.timestamp + BIDDING_TIME # Check that the reveal end time is correct assert auction_contract.revealEnd() == auction_contract.biddingEnd() + REVEAL_TIME # Check auction has not ended @@ -30,19 +32,19 @@ def test_initial_state(w3, tester, auction_contract): # Check highest bid is 0 assert auction_contract.highestBid() == 0 # Check highest bidder is empty - assert auction_contract.highestBidder() is None + assert auction_contract.highestBidder() == ZERO_ADDRESS -def test_late_bid(w3, auction_contract, tx_failed): - k1 = w3.eth.accounts[1] +def test_late_bid(env, auction_contract, tx_failed, keccak): + k1 = env.accounts[1] # Move time forward past bidding end - w3.testing.mine(BIDDING_TIME + TEST_INCREMENT) + env.timestamp += BIDDING_TIME + TEST_INCREMENT # Try to bid after bidding has ended with tx_failed(): auction_contract.bid( - w3.keccak( + keccak( b"".join( [ (200).to_bytes(32, byteorder="big"), @@ -51,17 +53,18 @@ def test_late_bid(w3, auction_contract, tx_failed): ] ) ), - transact={"value": 200, "from": k1}, + value=200, + sender=k1, ) -def test_too_many_bids(w3, auction_contract, tx_failed): - k1 = w3.eth.accounts[1] +def test_too_many_bids(env, auction_contract, tx_failed, keccak): + k1 = env.accounts[1] # First 128 bids should be able to be placed successfully for i in range(MAX_BIDS): auction_contract.bid( - w3.keccak( + keccak( b"".join( [ (i).to_bytes(32, byteorder="big"), @@ -70,13 +73,14 @@ def test_too_many_bids(w3, auction_contract, tx_failed): ] ) ), - transact={"value": i, "from": k1}, + value=i, + sender=k1, ) # 129th bid should fail with tx_failed(): auction_contract.bid( - w3.keccak( + keccak( b"".join( [ (128).to_bytes(32, byteorder="big"), @@ -85,16 +89,17 @@ def test_too_many_bids(w3, auction_contract, tx_failed): ] ) ), - transact={"value": 128, "from": k1}, + value=128, + sender=k1, ) -def test_early_reval(w3, auction_contract, tx_failed): - k1 = w3.eth.accounts[1] +def test_early_reval(env, auction_contract, tx_failed, keccak): + k1 = env.accounts[1] # k1 places 1 real bid auction_contract.bid( - w3.keccak( + keccak( b"".join( [ (100).to_bytes(32, byteorder="big"), @@ -103,11 +108,12 @@ def test_early_reval(w3, auction_contract, tx_failed): ] ) ), - transact={"value": 100, "from": k1}, + value=100, + sender=k1, ) # Move time slightly forward (still before bidding has ended) - w3.testing.mine(TEST_INCREMENT) + env.timestamp += TEST_INCREMENT # Try to reveal early _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -118,22 +124,20 @@ def test_early_reval(w3, auction_contract, tx_failed): _fakes[0] = False _secrets[0] = (8675309).to_bytes(32, byteorder="big") with tx_failed(): - auction_contract.reveal( - _numBids, _values, _fakes, _secrets, transact={"value": 0, "from": k1} - ) + auction_contract.reveal(_numBids, _values, _fakes, _secrets, value=0, sender=k1) # Check highest bidder is still empty - assert auction_contract.highestBidder() is None + assert auction_contract.highestBidder() == ZERO_ADDRESS # Check highest bid is still 0 assert auction_contract.highestBid() == 0 -def test_late_reveal(w3, auction_contract, tx_failed): - k1 = w3.eth.accounts[1] +def test_late_reveal(env, auction_contract, tx_failed, keccak): + k1 = env.accounts[1] # k1 places 1 real bid auction_contract.bid( - w3.keccak( + keccak( b"".join( [ (100).to_bytes(32, byteorder="big"), @@ -142,11 +146,12 @@ def test_late_reveal(w3, auction_contract, tx_failed): ] ) ), - transact={"value": 100, "from": k1}, + value=100, + sender=k1, ) # Move time forward past bidding _and_ reveal time - w3.testing.mine(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) + env.timestamp += BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT # Try to reveal late _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -157,40 +162,40 @@ def test_late_reveal(w3, auction_contract, tx_failed): _fakes[0] = False _secrets[0] = (8675309).to_bytes(32, byteorder="big") with tx_failed(): - auction_contract.reveal( - _numBids, _values, _fakes, _secrets, transact={"value": 0, "from": k1} - ) + auction_contract.reveal(_numBids, _values, _fakes, _secrets, value=0, sender=k1) # Check highest bidder is still empty - assert auction_contract.highestBidder() is None + assert auction_contract.highestBidder() == ZERO_ADDRESS # Check highest bid is still 0 assert auction_contract.highestBid() == 0 -def test_early_end(w3, auction_contract, tx_failed): - k0 = w3.eth.accounts[0] +def test_early_end(env, auction_contract, tx_failed): + k0 = env.deployer # Should not be able to end auction before reveal time has ended with tx_failed(): - auction_contract.auctionEnd(transact={"value": 0, "from": k0}) + auction_contract.auctionEnd(value=0, sender=k0) -def test_double_end(w3, auction_contract, tx_failed): - k0 = w3.eth.accounts[0] +def test_double_end(env, auction_contract, tx_failed): + k0 = env.deployer # Move time forward past bidding and reveal end - w3.testing.mine(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) + env.timestamp += BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT # First auction end should succeed - auction_contract.auctionEnd(transact={"value": 0, "from": k0}) + auction_contract.auctionEnd(value=0, sender=k0) # Should not be able to end auction twice with tx_failed(): - auction_contract.auctionEnd(transact={"value": 0, "from": k0}) + auction_contract.auctionEnd(value=0, sender=k0) -def test_blind_auction(w3, auction_contract): - k0, k1, k2, k3 = w3.eth.accounts[0:4] +def test_blind_auction(env, auction_contract, keccak): + k0, k1, k2, k3 = env.accounts[0:4] + for acc in env.accounts[1:4]: + env.set_balance(acc, 10**20) ################################################################### # Place bids # @@ -198,7 +203,7 @@ def test_blind_auction(w3, auction_contract): # k1 places 1 real bid auction_contract.bid( - w3.keccak( + keccak( b"".join( [ (100).to_bytes(32, byteorder="big"), @@ -207,12 +212,13 @@ def test_blind_auction(w3, auction_contract): ] ) ), - transact={"value": 100, "from": k1}, + value=100, + sender=k1, ) # k2 places 1 real bid (highest) and 2 fake auction_contract.bid( - w3.keccak( + keccak( b"".join( [ (150).to_bytes(32, byteorder="big"), @@ -221,10 +227,11 @@ def test_blind_auction(w3, auction_contract): ] ) ), - transact={"value": 150, "from": k2}, + value=150, + sender=k2, ) auction_contract.bid( - w3.keccak( + keccak( b"".join( [ (200).to_bytes(32, byteorder="big"), @@ -233,10 +240,11 @@ def test_blind_auction(w3, auction_contract): ] ) ), - transact={"value": 250, "from": k2}, + value=250, + sender=k2, ) auction_contract.bid( - w3.keccak( + keccak( b"".join( [ (300).to_bytes(32, byteorder="big"), @@ -245,12 +253,13 @@ def test_blind_auction(w3, auction_contract): ] ) ), - transact={"value": 300, "from": k2}, + value=300, + sender=k2, ) # k3 places 2 fake bids auction_contract.bid( - w3.keccak( + keccak( b"".join( [ (175).to_bytes(32, byteorder="big"), @@ -259,10 +268,11 @@ def test_blind_auction(w3, auction_contract): ] ) ), - transact={"value": 175, "from": k3}, + value=175, + sender=k3, ) auction_contract.bid( - w3.keccak( + keccak( b"".join( [ (275).to_bytes(32, byteorder="big"), @@ -271,7 +281,8 @@ def test_blind_auction(w3, auction_contract): ] ) ), - transact={"value": 275, "from": k3}, + value=275, + sender=k3, ) ################################################################### @@ -279,7 +290,7 @@ def test_blind_auction(w3, auction_contract): ################################################################### # Move time forward past bidding end (still within reveal end) - w3.testing.mine(BIDDING_TIME + TEST_INCREMENT) + env.timestamp += BIDDING_TIME + TEST_INCREMENT # Reveal k1 bids _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -289,7 +300,7 @@ def test_blind_auction(w3, auction_contract): _values[0] = 100 _fakes[0] = False _secrets[0] = (8675309).to_bytes(32, byteorder="big") - auction_contract.reveal(_numBids, _values, _fakes, _secrets, transact={"value": 0, "from": k1}) + auction_contract.reveal(_numBids, _values, _fakes, _secrets, value=0, sender=k1) #: Check that highest bidder and highest bid have updated assert auction_contract.highestBid() == 100 @@ -308,9 +319,9 @@ def test_blind_auction(w3, auction_contract): _values[2] = 300 _fakes[2] = True _secrets[2] = (1234567).to_bytes(32, byteorder="big") - balance_before_reveal = w3.eth.get_balance(k2) - auction_contract.reveal(3, _values, _fakes, _secrets, transact={"value": 0, "from": k2}) - balance_after_reveal = w3.eth.get_balance(k2) + balance_before_reveal = env.get_balance(k2) + auction_contract.reveal(3, _values, _fakes, _secrets, value=0, sender=k2) + balance_after_reveal = env.get_balance(k2) #: Check that highest bidder and highest bid have updated assert auction_contract.highestBid() == 200 @@ -329,9 +340,9 @@ def test_blind_auction(w3, auction_contract): _values[1] = 275 _fakes[1] = True _secrets[1] = (9876543).to_bytes(32, byteorder="big") - balance_before_reveal = w3.eth.get_balance(k3) - auction_contract.reveal(2, _values, _fakes, _secrets, transact={"value": 0, "from": k3}) - balance_after_reveal = w3.eth.get_balance(k3) + balance_before_reveal = env.get_balance(k3) + auction_contract.reveal(2, _values, _fakes, _secrets, value=0, sender=k3) + balance_after_reveal = env.get_balance(k3) #: Check that highest bidder and highest bid have NOT updated assert auction_contract.highestBidder() == k2 @@ -345,12 +356,12 @@ def test_blind_auction(w3, auction_contract): ################################################################### # Move time forward past bidding and reveal end - w3.testing.mine(REVEAL_TIME) + env.timestamp += REVEAL_TIME # End the auction - balance_before_end = w3.eth.get_balance(k0) - auction_contract.auctionEnd(transact={"value": 0, "from": k0}) - balance_after_end = w3.eth.get_balance(k0) + balance_before_end = env.get_balance(k0) + auction_contract.auctionEnd(value=0, sender=k0) + balance_after_end = env.get_balance(k0) # Check that auction indeed ended assert auction_contract.ended() is True @@ -359,7 +370,7 @@ def test_blind_auction(w3, auction_contract): assert balance_after_end == (balance_before_end + 200) # Check that k1 is able to withdraw their outbid bid - balance_before_withdraw = w3.eth.get_balance(k1) - auction_contract.withdraw(transact={"value": 0, "from": k1}) - balance_after_withdraw = w3.eth.get_balance(k1) + balance_before_withdraw = env.get_balance(k1) + auction_contract.withdraw(value=0, sender=k1) + balance_after_withdraw = env.get_balance(k1) assert balance_after_withdraw == (balance_before_withdraw + 100) diff --git a/tests/functional/examples/auctions/test_simple_open_auction.py b/tests/functional/examples/auctions/test_simple_open_auction.py index 46f34f31cd..430294fa79 100644 --- a/tests/functional/examples/auctions/test_simple_open_auction.py +++ b/tests/functional/examples/auctions/test_simple_open_auction.py @@ -1,24 +1,30 @@ import pytest +from tests.utils import ZERO_ADDRESS + EXPIRY = 16 @pytest.fixture -def auction_start(w3): - return w3.eth.get_block("latest").timestamp + 1 +def auction_start(env): + return env.timestamp + 1 @pytest.fixture -def auction_contract(w3, get_contract, auction_start): +def auction_contract(env, get_contract, auction_start): with open("examples/auctions/simple_open_auction.vy") as f: contract_code = f.read() - contract = get_contract(contract_code, *[w3.eth.accounts[0], auction_start, EXPIRY]) - return contract + for acc in env.accounts[:5]: + env.set_balance(acc, 10**20) + + env.timestamp += 1 # make sure auction has started + return get_contract(contract_code, *[env.accounts[0], auction_start, EXPIRY]) -def test_initial_state(w3, tester, auction_contract, auction_start): + +def test_initial_state(env, auction_contract, auction_start): # Check beneficiary is correct - assert auction_contract.beneficiary() == w3.eth.accounts[0] + assert auction_contract.beneficiary() == env.accounts[0] # Check start time is `auction_start` assert auction_contract.auctionStart() == auction_start # Check time difference between start time and end time is EXPIRY @@ -26,71 +32,74 @@ def test_initial_state(w3, tester, auction_contract, auction_start): # Check auction has not ended assert auction_contract.ended() is False # Check highest bidder is empty - assert auction_contract.highestBidder() is None + assert auction_contract.highestBidder() == ZERO_ADDRESS # Check highest bid is 0 assert auction_contract.highestBid() == 0 # Check end time is more than current block timestamp - assert auction_contract.auctionEnd() >= tester.get_block_by_number("latest")["timestamp"] + assert auction_contract.auctionEnd() >= env.timestamp + +def test_bid(env, auction_contract, tx_failed): + k1, k2, k3, k4, k5 = env.accounts[:5] -def test_bid(w3, tester, auction_contract, tx_failed): - k1, k2, k3, k4, k5 = w3.eth.accounts[:5] # Bidder cannot bid 0 with tx_failed(): - auction_contract.bid(transact={"value": 0, "from": k1}) + auction_contract.bid(value=0, sender=k1) + # Bidder can bid - auction_contract.bid(transact={"value": 1, "from": k1}) + auction_contract.bid(value=1, sender=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 with tx_failed(): - auction_contract.bid(transact={"value": 1, "from": k1}) + auction_contract.bid(value=1, sender=k1) # Higher bid can replace current highest bid - auction_contract.bid(transact={"value": 2, "from": k2}) + auction_contract.bid(value=2, sender=k2) # Check that highest bidder and highest bid have changed accordingly assert auction_contract.highestBidder() == k2 assert auction_contract.highestBid() == 2 # Multiple bidders can bid - auction_contract.bid(transact={"value": 3, "from": k3}) - auction_contract.bid(transact={"value": 4, "from": k4}) - auction_contract.bid(transact={"value": 5, "from": k5}) + auction_contract.bid(value=3, sender=k3) + auction_contract.bid(value=4, sender=k4) + auction_contract.bid(value=5, sender=k5) # Check that highest bidder and highest bid have changed accordingly assert auction_contract.highestBidder() == k5 assert auction_contract.highestBid() == 5 - auction_contract.bid(transact={"value": 1 * 10**10, "from": k1}) + auction_contract.bid(value=1 * 10**10, sender=k1) pending_return_before_outbid = auction_contract.pendingReturns(k1) - auction_contract.bid(transact={"value": 2 * 10**10, "from": k2}) + auction_contract.bid(value=2 * 10**10, sender=k2) pending_return_after_outbid = auction_contract.pendingReturns(k1) # Account has a greater pending return balance after being outbid assert pending_return_after_outbid > pending_return_before_outbid - balance_before_withdrawal = w3.eth.get_balance(k1) - auction_contract.withdraw(transact={"from": k1}) - balance_after_withdrawal = w3.eth.get_balance(k1) + balance_before_withdrawal = env.get_balance(k1) + auction_contract.withdraw(sender=k1) + balance_after_withdrawal = env.get_balance(k1) # Balance increases after withdrawal assert balance_after_withdrawal > balance_before_withdrawal # Pending return balance is reset to 0 assert auction_contract.pendingReturns(k1) == 0 -def test_end_auction(w3, tester, auction_contract, tx_failed): - k1, k2, k3, k4, k5 = w3.eth.accounts[:5] +def test_end_auction(env, auction_contract, tx_failed): + k1, k2, k3, k4, k5 = env.accounts[:5] + # Fails if auction end time has not been reached with tx_failed(): auction_contract.endAuction() - auction_contract.bid(transact={"value": 1 * 10**10, "from": k2}) + + auction_contract.bid(value=1 * 10**10, sender=k2) # Move block timestamp forward to reach auction end time - # tester.time_travel(tester.get_block_by_number('latest')['timestamp'] + EXPIRY) - w3.testing.mine(EXPIRY) - balance_before_end = w3.eth.get_balance(k1) - auction_contract.endAuction(transact={"from": k2}) - balance_after_end = w3.eth.get_balance(k1) + env.timestamp += EXPIRY + balance_before_end = env.get_balance(k1) + auction_contract.endAuction(sender=k2) + balance_after_end = env.get_balance(k1) # 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 with tx_failed(): - auction_contract.bid(transact={"value": 10, "from": k1}) + auction_contract.bid(value=10, sender=k1) # Auction cannot be ended twice 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 5933a14e86..35b4951471 100644 --- a/tests/functional/examples/company/test_company.py +++ b/tests/functional/examples/company/test_company.py @@ -2,125 +2,128 @@ @pytest.fixture -def c(w3, get_contract): +def c(env, get_contract): with open("examples/stock/company.vy") as f: contract_code = f.read() - contract = get_contract(contract_code, *[w3.eth.accounts[0], 1000, 10**6]) - return contract + for acc in env.accounts[:5]: + env.set_balance(acc, 10**20) -def test_overbuy(w3, c, tx_failed): + return get_contract(contract_code, *[env.accounts[0], 1000, 10**6]) + + +def test_overbuy(env, c, tx_failed): # If all the stock has been bought, no one can buy more - a1, a2 = w3.eth.accounts[1:3] + a1, a2 = env.accounts[1:3] test_shares = int(c.totalShares() / 2) test_value = int(test_shares * c.price()) - c.buyStock(transact={"from": a1, "value": test_value}) - c.buyStock(transact={"from": a1, "value": test_value}) + c.buyStock(value=test_value, sender=a1) + c.buyStock(value=test_value, sender=a1) assert c.stockAvailable() == 0 assert c.getHolding(a1) == (test_shares * 2) one_stock = c.price() with tx_failed(): - c.buyStock(transact={"from": a1, "value": one_stock}) + c.buyStock(value=one_stock, sender=a1) with tx_failed(): - c.buyStock(transact={"from": a2, "value": one_stock}) + c.buyStock(value=one_stock, sender=a2) -def test_sell_without_stock(w3, c, tx_failed): - a1, a2 = w3.eth.accounts[1:3] +def test_sell_without_stock(env, c, tx_failed): + a1, a2 = env.accounts[1:3] # If you don't have any stock, you can't sell with tx_failed(): - c.sellStock(1, transact={"from": a1}) + c.sellStock(1, sender=a1) with tx_failed(): - c.sellStock(1, transact={"from": a2}) + c.sellStock(1, sender=a2) # But if you do, you can! test_shares = int(c.totalShares()) test_value = int(test_shares * c.price()) - c.buyStock(transact={"from": a1, "value": test_value}) + c.buyStock(value=test_value, sender=a1) assert c.getHolding(a1) == test_shares - c.sellStock(test_shares, transact={"from": a1}) + c.sellStock(test_shares, sender=a1) # But only until you run out with tx_failed(): - c.sellStock(1, transact={"from": a1}) + c.sellStock(1, sender=a1) -def test_oversell(w3, c, tx_failed): - a0, a1, a2 = w3.eth.accounts[:3] +def test_oversell(env, c, tx_failed): + a0, a1, a2 = env.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}) + c.buyStock(value=test_value, sender=a1) with tx_failed(): - c.sellStock(test_shares + 1, transact={"from": a1}) + c.sellStock(test_shares + 1, sender=a1) -def test_transfer(w3, c, tx_failed): +def test_transfer(env, c, tx_failed): # If you don't have any stock, you can't transfer - a1, a2 = w3.eth.accounts[1:3] + a1, a2 = env.accounts[1:3] with tx_failed(): - c.transferStock(a2, 1, transact={"from": a1}) + c.transferStock(a2, 1, sender=a1) with tx_failed(): - c.transferStock(a1, 1, transact={"from": a2}) + c.transferStock(a1, 1, sender=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}) + c.buyStock(value=test_value, sender=a1) assert c.getHolding(a1) == test_shares - c.transferStock(a2, test_shares, transact={"from": a1}) + c.transferStock(a2, test_shares, sender=a1) with tx_failed(): - c.sellStock(1, transact={"from": a1}) + c.sellStock(1, sender=a1) # But the other person does - c.sellStock(test_shares, transact={"from": a2}) + c.sellStock(test_shares, sender=a2) -def test_paybill(w3, c, tx_failed): - a0, a1, a2, a3 = w3.eth.accounts[:4] +def test_paybill(env, c, tx_failed): + a0, a1, a2, a3 = env.accounts[:4] # Only the company can authorize payments with tx_failed(): - c.payBill(a2, 1, transact={"from": a1}) + c.payBill(a2, 1, sender=a1) # A company can only pay someone if it has the money with tx_failed(): - c.payBill(a2, 1, transact={"from": a0}) + c.payBill(a2, 1, sender=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}) + c.buyStock(value=test_value, sender=a1) + c.payBill(a2, test_value, sender=a0) # Until it runs out of money with tx_failed(): - c.payBill(a3, 1, transact={"from": a0}) + c.payBill(a3, 1, sender=a0) # Then no stockholders can sell their stock either with tx_failed(): - c.sellStock(1, transact={"from": a1}) + c.sellStock(1, sender=a1) -def test_valuation(w3, c): - a1 = w3.eth.accounts[1] +def test_valuation(env, c): + a1 = env.accounts[1] # Valuation is number of shares held times price assert c.debt() == 0 test_value = int(c.totalShares() * c.price()) - c.buyStock(transact={"from": a1, "value": test_value}) + c.buyStock(value=test_value, sender=a1) assert c.debt() == test_value -def test_logs(w3, c, get_logs): - a0, a1, a2, a3 = w3.eth.accounts[:4] +def test_logs(env, c, get_logs): + a0, a1, a2, a3 = env.accounts[:4] # Buy is logged - logs = get_logs(c.buyStock(transact={"from": a1, "value": 7 * c.price()}), c, "Buy") - assert len(logs) == 1 - assert logs[0].args.buy_order == 7 + c.buyStock(value=7 * c.price(), sender=a1) + (log,) = get_logs(c, "Buy") + assert log.args.buy_order == 7 # Sell is logged - logs = get_logs(c.sellStock(3, transact={"from": a1}), c, "Sell") - assert len(logs) == 1 - assert logs[0].args.sell_order == 3 + c.sellStock(3, sender=a1) + (log,) = get_logs(c, "Sell") + assert log.args.sell_order == 3 # Transfer is logged - logs = get_logs(c.transferStock(a2, 4, transact={"from": a1}), c, "Transfer") - assert len(logs) == 1 - assert logs[0].event == "Transfer" - assert logs[0].args.value == 4 + c.transferStock(a2, 4, sender=a1) + (log,) = get_logs(c, "Transfer") + assert log.event == "Transfer" + assert log.args.value == 4 # Pay is logged amount = 10**4 - logs = get_logs(c.payBill(a3, amount, transact={}), c, "Pay") - assert len(logs) == 1 - assert logs[0].args.amount == amount + c.payBill(a3, amount) + (log,) = get_logs(c, "Pay") + assert log.args.amount == amount diff --git a/tests/functional/examples/crowdfund/test_crowdfund_example.py b/tests/functional/examples/crowdfund/test_crowdfund_example.py index e75a88bf48..ff0d85d61e 100644 --- a/tests/functional/examples/crowdfund/test_crowdfund_example.py +++ b/tests/functional/examples/crowdfund/test_crowdfund_example.py @@ -2,50 +2,54 @@ @pytest.fixture -def c(w3, get_contract): +def c(env, get_contract): with open("examples/crowdfund.vy") as f: contract_code = f.read() - contract = get_contract(contract_code, *[w3.eth.accounts[1], 50, 60]) - return contract + return get_contract(contract_code, *[env.accounts[1], 50, 60]) -def test_crowdfund_example(c, w3): - a0, a1, a2, a3, a4, a5, a6 = w3.eth.accounts[:7] - c.participate(transact={"value": 5}) +def test_crowdfund_example(c, env): + a0, a1, a2, a3, a4, a5, a6 = env.accounts[:7] + env.set_balance(a0, 100) + c.participate(value=5) + env.timestamp += 1 # make sure auction has started assert c.timelimit() == 60 - assert c.deadline() - w3.eth.get_block("latest").timestamp == 59 - assert not w3.eth.get_block("latest").timestamp >= c.deadline() # expired - assert not w3.eth.get_balance(c.address) >= c.goal() # not reached - c.participate(transact={"value": 49}) + assert c.deadline() - env.timestamp == 59 + assert env.timestamp < c.deadline() # expired + assert env.get_balance(c.address) < c.goal() # not reached + c.participate(value=49) # assert c.reached() - pre_bal = w3.eth.get_balance(a1) - w3.testing.mine(100) - assert not w3.eth.get_block("latest").number >= c.deadline() # expired - c.finalize(transact={}) - post_bal = w3.eth.get_balance(a1) + pre_bal = env.get_balance(a1) + env.timestamp += 100 + assert env.timestamp > c.deadline() # expired + c.finalize() + post_bal = env.get_balance(a1) assert post_bal - pre_bal == 54 -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}) - c.participate(transact={"value": 3, "from": a5}) - c.participate(transact={"value": 4, "from": a6}) +def test_crowdfund_example2(c, env, tx_failed): + a0, a1, a2, a3, a4, a5, a6 = env.accounts[:7] + for i, a in enumerate(env.accounts[3:7]): + env.set_balance(a, i + 1) + + c.participate(value=1, sender=a3) + c.participate(value=2, sender=a4) + c.participate(value=3, sender=a5) + c.participate(value=4, sender=a6) assert c.timelimit() == 60 - w3.testing.mine(100) + env.timestamp += 100 # assert c.expired() # assert not c.reached() - pre_bals = [w3.eth.get_balance(x) for x in [a3, a4, a5, a6]] + pre_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] with tx_failed(): - c.refund(transact={"from": a0}) - c.refund(transact={"from": a3}) + c.refund(sender=a0) + c.refund(sender=a3) with tx_failed(): - c.refund(transact={"from": a3}) - c.refund(transact={"from": a4}) - c.refund(transact={"from": a5}) - c.refund(transact={"from": a6}) - post_bals = [w3.eth.get_balance(x) for x in [a3, a4, a5, a6]] + c.refund(sender=a3) + c.refund(sender=a4) + c.refund(sender=a5) + c.refund(sender=a6) + post_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] assert [y - x for x, y in zip(pre_bals, post_bals)] == [1, 2, 3, 4] diff --git a/tests/functional/examples/factory/test_factory.py b/tests/functional/examples/factory/test_factory.py index 18f6222c20..ecfc0bf557 100644 --- a/tests/functional/examples/factory/test_factory.py +++ b/tests/functional/examples/factory/test_factory.py @@ -2,7 +2,6 @@ from eth_utils import keccak import vyper -from vyper.compiler.settings import Settings @pytest.fixture @@ -17,29 +16,25 @@ def create_token(): @pytest.fixture -def create_exchange(w3, get_contract): +def create_exchange(env, get_contract): with open("examples/factory/Exchange.vy") as f: code = f.read() def create_exchange(token, factory): exchange = get_contract(code, *[token.address, factory.address]) # NOTE: Must initialize exchange to register it with factory - exchange.initialize(transact={"from": w3.eth.accounts[0]}) + exchange.initialize(sender=env.accounts[0]) return exchange return create_exchange @pytest.fixture -def factory(get_contract, optimize, experimental_codegen): +def factory(get_contract): with open("examples/factory/Exchange.vy") as f: code = f.read() - exchange_interface = vyper.compile_code( - code, - output_formats=["bytecode_runtime"], - settings=Settings(optimize=optimize, experimental_codegen=experimental_codegen), - ) + exchange_interface = vyper.compile_code(code, output_formats=["bytecode_runtime"]) exchange_deployed_bytecode = exchange_interface["bytecode_runtime"] with open("examples/factory/Factory.vy") as f: @@ -49,23 +44,23 @@ def factory(get_contract, optimize, experimental_codegen): return get_contract(code, keccak(hexstr=exchange_deployed_bytecode)) -def test_exchange(w3, factory, create_token, create_exchange): - a = w3.eth.accounts[0] +def test_exchange(env, factory, create_token, create_exchange): + a = env.accounts[0] token1 = create_token() exchange1 = create_exchange(token1, factory) token2 = create_token() exchange2 = create_exchange(token2, factory) # user has token 1 - token1.mint(a, 1, transact={"from": a}) + token1.mint(a, 1, sender=a) # exchange has token 2 - token2.mint(exchange2.address, 1, transact={"from": a}) + token2.mint(exchange2.address, 1, sender=a) # So approval doesn't fail for transferFrom - token1.approve(exchange1.address, 1, transact={"from": a}) + token1.approve(exchange1.address, 1, sender=a) # trade token 1 for token 2 assert token1.balanceOf(a) == 1 assert token2.balanceOf(a) == 0 - factory.trade(token1.address, token2.address, 1, transact={"from": a}) + factory.trade(token1.address, token2.address, 1, sender=a) assert token1.balanceOf(a) == 0 assert token2.balanceOf(a) == 1 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 235a0ea66f..4f76c93ecc 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 @@ -1,4 +1,7 @@ import pytest +from eth_utils import to_wei + +from tests.utils import ZERO_ADDRESS @pytest.fixture @@ -28,14 +31,15 @@ def test_initial_state(market_maker): assert market_maker.totalEthQty() == 0 assert market_maker.totalTokenQty() == 0 assert market_maker.invariant() == 0 - assert market_maker.owner() is None + assert market_maker.owner() == ZERO_ADDRESS -def test_initiate(w3, market_maker, erc20, tx_failed): - a0 = w3.eth.accounts[0] - 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}) +def test_initiate(env, market_maker, erc20, tx_failed): + a0 = env.accounts[0] + ether, ethers = to_wei(1, "ether"), to_wei(2, "ether") + env.set_balance(a0, ethers) + erc20.approve(market_maker.address, ethers) + market_maker.initiate(erc20.address, ether, value=ethers) assert market_maker.totalEthQty() == ethers assert market_maker.totalTokenQty() == ether assert market_maker.invariant() == 2 * 10**36 @@ -45,69 +49,67 @@ def test_initiate(w3, market_maker, erc20, tx_failed): # Initiate cannot be called twice with tx_failed(): - market_maker.initiate(erc20.address, ether, transact={"value": ethers}) + market_maker.initiate(erc20.address, ether, value=ethers) -def test_eth_to_tokens(w3, market_maker, erc20): - a1 = w3.eth.accounts[1] - 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 erc20.balanceOf(market_maker.address) == w3.to_wei(1, "ether") +def test_eth_to_tokens(env, market_maker, erc20): + a0, a1 = env.accounts[:2] + env.set_balance(a0, to_wei(2, "ether")) + erc20.approve(market_maker.address, to_wei(2, "ether")) + market_maker.initiate(erc20.address, to_wei(1, "ether"), value=to_wei(2, "ether")) + assert erc20.balanceOf(market_maker.address) == to_wei(1, "ether") assert erc20.balanceOf(a1) == 0 - assert market_maker.totalTokenQty() == w3.to_wei(1, "ether") - assert market_maker.totalEthQty() == w3.to_wei(2, "ether") + assert market_maker.totalTokenQty() == to_wei(1, "ether") + assert market_maker.totalEthQty() == to_wei(2, "ether") - market_maker.ethToTokens(transact={"value": 100, "from": a1}) + env.set_balance(a1, 100) + market_maker.ethToTokens(value=100, sender=a1) assert erc20.balanceOf(market_maker.address) == 999999999999999950 assert erc20.balanceOf(a1) == 50 assert market_maker.totalTokenQty() == 999999999999999950 assert market_maker.totalEthQty() == 2000000000000000100 -def test_tokens_to_eth(w3, market_maker, erc20): - a1 = w3.eth.accounts[1] - a1_balance_before = w3.eth.get_balance(a1) +def test_tokens_to_eth(env, market_maker, erc20): + a1 = env.accounts[1] + a1_balance_before = to_wei(2, "ether") + env.set_balance(a1, a1_balance_before) - erc20.transfer(a1, w3.to_wei(2, "ether"), transact={}) - erc20.approve(market_maker.address, w3.to_wei(2, "ether"), transact={"from": a1}) - market_maker.initiate( - erc20.address, w3.to_wei(1, "ether"), transact={"value": w3.to_wei(2, "ether"), "from": a1} - ) - assert w3.eth.get_balance(market_maker.address) == w3.to_wei(2, "ether") + erc20.transfer(a1, to_wei(2, "ether")) + erc20.approve(market_maker.address, to_wei(2, "ether"), sender=a1) + market_maker.initiate(erc20.address, to_wei(1, "ether"), value=to_wei(2, "ether"), sender=a1) + assert env.get_balance(market_maker.address) == to_wei(2, "ether") # sent 2 eth, with initiate. - assert w3.eth.get_balance(a1) == a1_balance_before - w3.to_wei(2, "ether") - assert market_maker.totalTokenQty() == w3.to_wei(1, "ether") + assert env.get_balance(a1) == a1_balance_before - to_wei(2, "ether") + assert market_maker.totalTokenQty() == to_wei(1, "ether") - erc20.approve(market_maker.address, w3.to_wei(1, "ether"), transact={"from": a1}) - market_maker.tokensToEth(w3.to_wei(1, "ether"), transact={"from": a1}) + erc20.approve(market_maker.address, to_wei(1, "ether"), sender=a1) + market_maker.tokensToEth(to_wei(1, "ether"), sender=a1) # 1 eth less in market. - assert w3.eth.get_balance(market_maker.address) == w3.to_wei(1, "ether") + assert env.get_balance(market_maker.address) == to_wei(1, "ether") # got 1 eth back, for trade. - assert w3.eth.get_balance(a1) == a1_balance_before - w3.to_wei(1, "ether") + assert env.get_balance(a1) == a1_balance_before - to_wei(1, "ether") # Tokens increased by 1 - assert market_maker.totalTokenQty() == w3.to_wei(2, "ether") - assert market_maker.totalEthQty() == w3.to_wei(1, "ether") + assert market_maker.totalTokenQty() == to_wei(2, "ether") + assert market_maker.totalEthQty() == to_wei(1, "ether") -def test_owner_withdraw(w3, market_maker, erc20, tx_failed): - a0, a1 = w3.eth.accounts[:2] - a0_balance_before = w3.eth.get_balance(a0) +def test_owner_withdraw(env, market_maker, erc20, tx_failed): + a0, a1 = env.accounts[:2] + a0_balance_before = to_wei(10, "ether") + env.set_balance(a0, a0_balance_before) # Approve 2 eth transfers. - erc20.approve(market_maker.address, w3.to_wei(2, "ether"), transact={}) + erc20.approve(market_maker.address, to_wei(2, "ether")) # Initiate market with 2 eth value. - market_maker.initiate( - erc20.address, w3.to_wei(1, "ether"), transact={"value": w3.to_wei(2, "ether")} - ) + market_maker.initiate(erc20.address, to_wei(1, "ether"), value=to_wei(2, "ether")) # 2 eth was sent to market_maker contract. - assert w3.eth.get_balance(a0) == a0_balance_before - w3.to_wei(2, "ether") + assert env.get_balance(a0) == a0_balance_before - to_wei(2, "ether") # a0's balance is locked up in market_maker contract. - assert erc20.balanceOf(a0) == TOKEN_TOTAL_SUPPLY - w3.to_wei(1, "ether") + assert erc20.balanceOf(a0) == TOKEN_TOTAL_SUPPLY - to_wei(1, "ether") # Only owner can call ownerWithdraw 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. + market_maker.ownerWithdraw(sender=a1) + market_maker.ownerWithdraw() + assert env.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 a2e92a7c52..7437b29de7 100644 --- a/tests/functional/examples/name_registry/test_name_registry.py +++ b/tests/functional/examples/name_registry/test_name_registry.py @@ -1,9 +1,9 @@ -def test_name_registry(w3, get_contract, tx_failed): - a0, a1 = w3.eth.accounts[:2] +def test_name_registry(env, get_contract, tx_failed): + a0, a1 = env.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={}) + c.register(b"jacques", a0) assert c.lookup(b"jacques") == a0 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 60ff57efda..4f891fb4d3 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 @@ -12,6 +12,7 @@ # 4. Buyer confirms receiving the item. Buyer's deposit (value) is returned. # Seller's deposit (2*value) + items value is returned. Balance is 0. import pytest +from eth_utils import to_wei @pytest.fixture @@ -22,62 +23,68 @@ def contract_code(get_contract): @pytest.fixture -def get_balance(w3): +def get_balance(env): def get_balance(): - a0, a1 = w3.eth.accounts[:2] + a0, a1 = env.accounts[:2] # balance of a1 = seller, a2 = buyer - return w3.eth.get_balance(a0), w3.eth.get_balance(a1) + return env.get_balance(a0), env.get_balance(a1) return get_balance -def test_initial_state(w3, tx_failed, get_contract, get_balance, contract_code): +def test_initial_state(env, tx_failed, get_contract, get_balance, contract_code): # Initial deposit has to be divisible by two with tx_failed(): get_contract(contract_code, value=13) + env.set_balance(env.deployer, to_wei(2, "ether")) # Seller puts item up for sale a0_pre_bal, a1_pre_bal = get_balance() - c = get_contract(contract_code, value_in_eth=2) + c = get_contract(contract_code, value=to_wei(2, "ether")) # Check that the seller is set correctly - assert c.seller() == w3.eth.accounts[0] + assert c.seller() == env.accounts[0] # Check if item value is set correctly (Half of deposit) - assert c.value() == w3.to_wei(1, "ether") + assert c.value() == to_wei(1, "ether") # Check if unlocked() works correctly after initialization assert c.unlocked() is True # Check that sellers (and buyers) balance is correct - assert get_balance() == ((a0_pre_bal - w3.to_wei(2, "ether")), a1_pre_bal) + assert get_balance() == ((a0_pre_bal - to_wei(2, "ether")), a1_pre_bal) -def test_abort(w3, tx_failed, get_balance, get_contract, contract_code): - a0, a1, a2 = w3.eth.accounts[:3] +def test_abort(env, tx_failed, get_balance, get_contract, contract_code): + a0, a1, a2 = env.accounts[:3] + for a in env.accounts[:3]: + env.set_balance(a, 10**20) 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") + c = get_contract(contract_code, value=to_wei(2, "ether")) + assert c.value() == to_wei(1, "ether") # Only sender can trigger refund with tx_failed(): - c.abort(transact={"from": a2}) + c.abort(sender=a2) # Refund works correctly - c.abort(transact={"from": a0}) + c.abort(sender=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}) + c.purchase(value=2, sender=a1) with tx_failed(): - c.abort(transact={"from": a0}) + c.abort(sender=a0) -def test_purchase(w3, get_contract, tx_failed, get_balance, contract_code): - a0, a1, a2, a3 = w3.eth.accounts[:4] +def test_purchase(env, get_contract, tx_failed, get_balance, contract_code): + a0, a1, a2, a3 = env.accounts[:4] + env.set_balance(a0, 10**18) + env.set_balance(a1, 10**18) + init_bal_a0, init_bal_a1 = get_balance() c = get_contract(contract_code, value=2) # Purchase for too low/high price with tx_failed(): - c.purchase(transact={"value": 1, "from": a1}) + c.purchase(value=1, sender=a1) with tx_failed(): - c.purchase(transact={"value": 3, "from": a1}) + c.purchase(value=3, sender=a1) # Purchase for the correct price - c.purchase(transact={"value": 2, "from": a1}) + c.purchase(value=2, sender=a1) # Check if buyer is set correctly assert c.buyer() == a1 # Check if contract is locked correctly @@ -86,28 +93,30 @@ def test_purchase(w3, get_contract, tx_failed, get_balance, contract_code): assert get_balance() == (init_bal_a0 - 2, init_bal_a1 - 2) # Allow nobody else to purchase with tx_failed(): - c.purchase(transact={"value": 2, "from": a3}) + c.purchase(value=2, sender=a3) -def test_received(w3, get_contract, tx_failed, get_balance, contract_code): - a0, a1 = w3.eth.accounts[:2] +def test_received(env, get_contract, tx_failed, get_balance, contract_code): + a0, a1 = env.accounts[:2] + env.set_balance(a0, 10**18) + env.set_balance(a1, 10**18) init_bal_a0, init_bal_a1 = get_balance() c = get_contract(contract_code, value=2) # Can only be called after purchase with tx_failed(): - c.received(transact={"from": a1}) + c.received(sender=a1) # Purchase completed - c.purchase(transact={"value": 2, "from": a1}) + c.purchase(value=2, sender=a1) # Check that e.g. sender cannot trigger received with tx_failed(): - c.received(transact={"from": a0}) + c.received(sender=a0) # Check if buyer can call receive - c.received(transact={"from": a1}) + c.received(sender=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, tx_failed, get_balance, contract_code): +def test_received_reentrancy(env, get_contract, tx_failed, get_balance, contract_code): buyer_contract_code = """ interface PurchaseContract: @@ -142,24 +151,28 @@ def __default__(): """ - a0 = w3.eth.accounts[0] + a0, a1 = env.accounts[:2] + for a in env.accounts[:2]: + env.set_balance(a, 10**18) + c = get_contract(contract_code, value=2) buyer_contract = get_contract(buyer_contract_code, *[c.address]) buyer_contract_address = buyer_contract.address init_bal_a0, init_bal_buyer_contract = ( - w3.eth.get_balance(a0), - w3.eth.get_balance(buyer_contract_address), + env.get_balance(a0), + env.get_balance(buyer_contract_address), ) # Start purchase - buyer_contract.start_purchase(transact={"value": 4, "from": w3.eth.accounts[1], "gas": 100000}) + buyer_contract.start_purchase(value=4, sender=a1, gas=100000) assert c.unlocked() is False assert c.buyer() == buyer_contract_address # Trigger "re-entry" - buyer_contract.start_received(transact={"from": w3.eth.accounts[1], "gas": 100000}) + with tx_failed(): + buyer_contract.start_received(sender=a1, gas=100000) # Final check if everything worked. 1 value has been transferred - assert w3.eth.get_balance(a0), w3.eth.get_balance(buyer_contract_address) == ( + assert env.get_balance(a0), env.get_balance(buyer_contract_address) == ( init_bal_a0 + 1, init_bal_buyer_contract - 1, ) diff --git a/tests/functional/examples/storage/test_advanced_storage.py b/tests/functional/examples/storage/test_advanced_storage.py index 313d1a7e5c..51e5a1729e 100644 --- a/tests/functional/examples/storage/test_advanced_storage.py +++ b/tests/functional/examples/storage/test_advanced_storage.py @@ -1,11 +1,11 @@ import pytest -from web3.exceptions import ValidationError +from eth.codecs.abi.exceptions import EncodeError INITIAL_VALUE = 4 @pytest.fixture -def adv_storage_contract(w3, get_contract): +def adv_storage_contract(get_contract): with open("examples/storage/advanced_storage.vy") as f: contract_code = f.read() # Pass constructor variables directly to the contract @@ -18,49 +18,44 @@ def test_initial_state(adv_storage_contract): assert adv_storage_contract.storedData() == INITIAL_VALUE -def test_failed_transactions(w3, adv_storage_contract, tx_failed): - k1 = w3.eth.accounts[1] +def test_failed_transactions(env, adv_storage_contract, tx_failed): + k1 = env.accounts[1] + env.set_balance(k1, 10**18) # Try to set the storage to a negative amount with tx_failed(): - adv_storage_contract.set(-10, transact={"from": k1}) + adv_storage_contract.set(-10, sender=k1) # Lock the contract by storing more than 100. Then try to change the value - adv_storage_contract.set(150, transact={"from": k1}) + adv_storage_contract.set(150, sender=k1) with tx_failed(): - adv_storage_contract.set(10, transact={"from": k1}) + adv_storage_contract.set(10, sender=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}) + adv_storage_contract.reset(sender=k1) + adv_storage_contract.set(10, sender=k1) assert adv_storage_contract.storedData() == 10 # Assert a different exception (ValidationError for non-matching argument type) - with tx_failed(ValidationError): - adv_storage_contract.set("foo", transact={"from": k1}) + with tx_failed(EncodeError): + adv_storage_contract.set("foo", sender=k1) # Assert a different exception that contains specific text - with tx_failed(ValidationError, "invocation failed due to improper number of arguments"): - adv_storage_contract.set(1, 2, transact={"from": k1}) + with tx_failed(TypeError, "invocation failed due to improper number of arguments"): + adv_storage_contract.set(1, 2, sender=k1) -def test_events(w3, adv_storage_contract, get_logs): - k1, k2 = w3.eth.accounts[:2] +def test_events(env, adv_storage_contract, get_logs): + k1, k2 = env.accounts[:2] - tx1 = adv_storage_contract.set(10, transact={"from": k1}) - tx2 = adv_storage_contract.set(20, transact={"from": k2}) - tx3 = adv_storage_contract.reset(transact={"from": k1}) - - # Save DataChange logs from all three transactions - logs1 = get_logs(tx1, adv_storage_contract, "DataChange") - logs2 = get_logs(tx2, adv_storage_contract, "DataChange") - logs3 = get_logs(tx3, adv_storage_contract, "DataChange") + adv_storage_contract.set(10, sender=k1) + (log1,) = get_logs(adv_storage_contract, "DataChange") + adv_storage_contract.set(20, sender=k2) + (log2,) = get_logs(adv_storage_contract, "DataChange") + adv_storage_contract.reset(sender=k1) + logs3 = get_logs(adv_storage_contract, "DataChange") # Check log contents - assert len(logs1) == 1 - assert logs1[0].args.value == 10 - - assert len(logs2) == 1 - assert logs2[0].args.setter == k2 - - assert not logs3 # tx3 does not generate a log + assert log1.args.value == 10 + assert log2.args.setter == k2 + assert logs3 == [] # tx3 does not generate a log diff --git a/tests/functional/examples/storage/test_storage.py b/tests/functional/examples/storage/test_storage.py index ee12f59cba..cdb71c5810 100644 --- a/tests/functional/examples/storage/test_storage.py +++ b/tests/functional/examples/storage/test_storage.py @@ -4,7 +4,7 @@ @pytest.fixture -def storage_contract(w3, get_contract): +def storage_contract(get_contract): with open("examples/storage/storage.vy") as f: contract_code = f.read() # Pass constructor variables directly to the contract @@ -17,13 +17,9 @@ def test_initial_state(storage_contract): assert storage_contract.storedData() == INITIAL_VALUE -def test_set(w3, storage_contract): - k0 = w3.eth.accounts[0] - - # Let k0 try to set the value to 10 - storage_contract.set(10, transact={"from": k0}) +def test_set(storage_contract): + storage_contract.set(10) assert storage_contract.storedData() == 10 # Directly access storedData - # Let k0 try to set the value to -5 - storage_contract.set(-5, transact={"from": k0}) + storage_contract.set(-5) assert storage_contract.storedData() == -5 diff --git a/tests/functional/examples/tokens/test_erc1155.py b/tests/functional/examples/tokens/test_erc1155.py index 526fd387bd..afbfa8d56d 100644 --- a/tests/functional/examples/tokens/test_erc1155.py +++ b/tests/functional/examples/tokens/test_erc1155.py @@ -1,5 +1,7 @@ import pytest +from tests.utils import ZERO_ADDRESS + # ERC1155 ownable, opensea compatible tests # @author Dr. Pixel (github: @Doc-Pixel) @@ -18,7 +20,6 @@ ERC165_INTERFACE_ID = "0x01ffc9a7" ERC1155_INTERFACE_ID = "0xd9b67a26" ERC1155_INTERFACE_ID_METADATA = "0x0e89341c" -ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" DUMMY_BYTES32_DATA = "0x0101010101010101010101010101010101010101010101010101010101010101" # minting test lists @@ -29,32 +30,32 @@ @pytest.fixture -def erc1155(get_contract, w3, tx_failed): - owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] +def erc1155(get_contract, env, tx_failed): + owner, a1, a2, a3, a4, a5 = env.accounts[0:6] with open("examples/tokens/ERC1155ownable.vy") as f: code = f.read() c = get_contract(code, *[CONTRACT_NAME, CONTRACT_SYMBOL, CONTRACT_URI, CONTRACT_METADATA_URI]) assert c.owner() == owner - c.mintBatch(a1, mintBatch, minBatchSetOf10, transact={"from": owner}) - c.mintBatch(a3, mintBatch2, minBatchSetOf10, transact={"from": owner}) + c.mintBatch(a1, mintBatch, minBatchSetOf10, sender=owner) + c.mintBatch(a3, mintBatch2, minBatchSetOf10, sender=owner) assert c.balanceOf(a1, 1) == 1 assert c.balanceOf(a1, 2) == 1 assert c.balanceOf(a1, 3) == 1 with tx_failed(): - c.mintBatch(ZERO_ADDRESS, mintBatch, minBatchSetOf10, transact={"from": owner}) + c.mintBatch(ZERO_ADDRESS, mintBatch, minBatchSetOf10, sender=owner) with tx_failed(): - c.mintBatch(a1, [1, 2, 3], [1, 1], transact={"from": owner}) + c.mintBatch(a1, [1, 2, 3], [1, 1], sender=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}) + c.mint(a1, 21, 1, sender=owner) + c.mint(a1, 22, 1, sender=owner) + c.mint(a1, 23, 1, sender=owner) + c.mint(a1, 24, 1, sender=owner) with tx_failed(): - c.mint(a1, 24, 1, transact={"from": a3}) + c.mint(a1, 24, 1, sender=a3) with tx_failed(): - c.mint(ZERO_ADDRESS, 24, 1, transact={"from": owner}) + c.mint(ZERO_ADDRESS, 24, 1, sender=owner) assert c.balanceOf(a1, 21) == 1 assert c.balanceOf(a1, 22) == 1 @@ -82,18 +83,18 @@ def test_initial_state(erc1155): assert erc1155.supportsInterface(ERC1155_INTERFACE_ID_METADATA) -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 +def test_pause(erc1155, env, tx_failed): + owner, a1, a2, a3, a4, a5 = env.accounts[0:6] + # check the pause status, pause, check, unpause, check, with owner and non-owner 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 with tx_failed(): - erc1155.pause(transact={"from": a1}) + erc1155.pause(sender=a1) # now pause the contract and check status - erc1155.pause(transact={"from": owner}) + erc1155.pause(sender=owner) assert erc1155.paused() # try pausing a paused contract @@ -112,16 +113,16 @@ def test_pause(erc1155, w3, tx_failed): # check mint and mintbatch with tx_failed(): - erc1155.mint(a1, 21, 1, transact={"from": owner}) + erc1155.mint(a1, 21, 1, sender=owner) with tx_failed(): - erc1155.mintBatch(a1, mintBatch, minBatchSetOf10, transact={"from": owner}) + erc1155.mintBatch(a1, mintBatch, minBatchSetOf10, sender=owner) # check safetransferfrom and safebatchtransferfrom with tx_failed(): - erc1155.safeTransferFrom(a1, a2, 21, 1, DUMMY_BYTES32_DATA, transact={"from": a1}) + erc1155.safeTransferFrom(a1, a2, 21, 1, DUMMY_BYTES32_DATA, sender=a1) with tx_failed(): erc1155.safeBatchTransferFrom( - a1, a2, [21, 22, 23], [1, 1, 1], DUMMY_BYTES32_DATA, transact={"from": a1} + a1, a2, [21, 22, 23], [1, 1, 1], DUMMY_BYTES32_DATA, sender=a1 ) # check ownership functions @@ -136,9 +137,9 @@ def test_pause(erc1155, w3, tx_failed): # try and unpause as non-owner with tx_failed(): - erc1155.unpause(transact={"from": a1}) + erc1155.unpause(sender=a1) - erc1155.unpause(transact={"from": owner}) + erc1155.unpause(sender=owner) assert not erc1155.paused() # try un pausing an unpaused contract @@ -146,16 +147,16 @@ def test_pause(erc1155, w3, tx_failed): erc1155.unpause() -def test_contractURI(erc1155, w3, tx_failed): - owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] +def test_contractURI(erc1155, env, tx_failed): + owner, a1, a2, a3, a4, a5 = env.accounts[0:6] # change contract URI and restore. assert erc1155.contractURI() == CONTRACT_METADATA_URI with tx_failed(): - erc1155.setContractURI(NEW_CONTRACT_METADATA_URI, transact={"from": a1}) - erc1155.setContractURI(NEW_CONTRACT_METADATA_URI, transact={"from": owner}) + erc1155.setContractURI(NEW_CONTRACT_METADATA_URI, sender=a1) + erc1155.setContractURI(NEW_CONTRACT_METADATA_URI, sender=owner) assert erc1155.contractURI() == NEW_CONTRACT_METADATA_URI assert erc1155.contractURI() != CONTRACT_METADATA_URI - erc1155.setContractURI(CONTRACT_METADATA_URI, transact={"from": owner}) + erc1155.setContractURI(CONTRACT_METADATA_URI, sender=owner) assert erc1155.contractURI() != NEW_CONTRACT_METADATA_URI assert erc1155.contractURI() == CONTRACT_METADATA_URI @@ -163,14 +164,14 @@ def test_contractURI(erc1155, w3, tx_failed): erc1155.setContractURI(CONTRACT_METADATA_URI) -def test_URI(erc1155, w3, tx_failed): - owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] +def test_URI(erc1155, env, tx_failed): + owner, a1, a2, a3, a4, a5 = env.accounts[0:6] # change contract URI and restore. assert erc1155.uri(0) == CONTRACT_URI - erc1155.setURI(NEW_CONTRACT_URI, transact={"from": owner}) + erc1155.setURI(NEW_CONTRACT_URI, sender=owner) assert erc1155.uri(0) == NEW_CONTRACT_URI assert erc1155.uri(0) != CONTRACT_URI - erc1155.setURI(CONTRACT_URI, transact={"from": owner}) + erc1155.setURI(CONTRACT_URI, sender=owner) assert erc1155.uri(0) != NEW_CONTRACT_URI assert erc1155.uri(0) == CONTRACT_URI @@ -178,55 +179,55 @@ def test_URI(erc1155, w3, tx_failed): erc1155.setURI(CONTRACT_URI) # set contract to dynamic URI - erc1155.toggleDynUri(True, transact={"from": owner}) - erc1155.setURI(CONTRACT_DYNURI, transact={"from": owner}) + erc1155.toggleDynUri(True, sender=owner) + erc1155.setURI(CONTRACT_DYNURI, sender=owner) assert erc1155.uri(0) == CONTRACT_DYNURI + str(0) + ".json" -def test_safeTransferFrom_balanceOf_single(erc1155, w3, tx_failed): - owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] +def test_safeTransferFrom_balanceOf_single(erc1155, env, tx_failed): + owner, a1, a2, a3, a4, a5 = env.accounts[0:6] assert erc1155.balanceOf(a1, 24) == 1 # transfer by non-owner with tx_failed(): - erc1155.safeTransferFrom(a1, a2, 24, 1, DUMMY_BYTES32_DATA, transact={"from": a2}) + erc1155.safeTransferFrom(a1, a2, 24, 1, DUMMY_BYTES32_DATA, sender=a2) # transfer to zero address with tx_failed(): - erc1155.safeTransferFrom(a1, ZERO_ADDRESS, 24, 1, DUMMY_BYTES32_DATA, transact={"from": a1}) + erc1155.safeTransferFrom(a1, ZERO_ADDRESS, 24, 1, DUMMY_BYTES32_DATA, sender=a1) # transfer to self with tx_failed(): - erc1155.safeTransferFrom(a1, a1, 24, 1, DUMMY_BYTES32_DATA, transact={"from": a1}) + erc1155.safeTransferFrom(a1, a1, 24, 1, DUMMY_BYTES32_DATA, sender=a1) # transfer more than owned with tx_failed(): - erc1155.safeTransferFrom(a1, a2, 24, 500, DUMMY_BYTES32_DATA, transact={"from": a1}) + erc1155.safeTransferFrom(a1, a2, 24, 500, DUMMY_BYTES32_DATA, sender=a1) # transfer item not owned / not existing with tx_failed(): - erc1155.safeTransferFrom(a1, a2, 500, 1, DUMMY_BYTES32_DATA, transact={"from": a1}) + erc1155.safeTransferFrom(a1, a2, 500, 1, DUMMY_BYTES32_DATA, sender=a1) - erc1155.safeTransferFrom(a1, a2, 21, 1, DUMMY_BYTES32_DATA, transact={"from": a1}) + erc1155.safeTransferFrom(a1, a2, 21, 1, DUMMY_BYTES32_DATA, sender=a1) assert erc1155.balanceOf(a2, 21) == 1 # try to transfer item again with tx_failed(): - erc1155.safeTransferFrom(a1, a2, 21, 1, DUMMY_BYTES32_DATA, transact={"from": a1}) + erc1155.safeTransferFrom(a1, a2, 21, 1, DUMMY_BYTES32_DATA, sender=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, tx_failed): # test_mint_batch - owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] +def test_mintBatch_balanceOf(erc1155, env, tx_failed): # test_mint_batch + owner, a1, a2, a3, a4, a5 = env.accounts[0:6] # Use the mint three fixture to mint the tokens. # this test checks the balances of this test for i in range(1, 10): assert erc1155.balanceOf(a1, i) == 1 -def test_safeBatchTransferFrom_balanceOf_batch(erc1155, w3, tx_failed): # test_mint_batch - owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] +def test_safeBatchTransferFrom_balanceOf_batch(erc1155, env, tx_failed): # test_mint_batch + owner, a1, a2, a3, a4, a5 = env.accounts[0:6] # check a1 balances for NFTs 21-24 assert erc1155.balanceOf(a1, 21) == 1 @@ -237,82 +238,78 @@ def test_safeBatchTransferFrom_balanceOf_batch(erc1155, w3, tx_failed): # test_ # 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} + a1, a2, [21, 22, 23], [1, 1, 1], DUMMY_BYTES32_DATA, sender=a2 ) # try to transfer item to zero address with tx_failed(): erc1155.safeBatchTransferFrom( - a1, ZERO_ADDRESS, [21, 22, 23], [1, 1, 1], DUMMY_BYTES32_DATA, transact={"from": a1} + a1, ZERO_ADDRESS, [21, 22, 23], [1, 1, 1], DUMMY_BYTES32_DATA, sender=a1 ) # try to transfer item to self with tx_failed(): erc1155.safeBatchTransferFrom( - a1, a1, [21, 22, 23], [1, 1, 1], DUMMY_BYTES32_DATA, transact={"from": a1} + a1, a1, [21, 22, 23], [1, 1, 1], DUMMY_BYTES32_DATA, sender=a1 ) # try to transfer more items than we own with tx_failed(): erc1155.safeBatchTransferFrom( - a1, a2, [21, 22, 23], [1, 125, 1], DUMMY_BYTES32_DATA, transact={"from": a1} + a1, a2, [21, 22, 23], [1, 125, 1], DUMMY_BYTES32_DATA, sender=a1 ) # mismatched item and amounts with tx_failed(): - erc1155.safeBatchTransferFrom( - a1, a2, [21, 22, 23], [1, 1], DUMMY_BYTES32_DATA, transact={"from": a1} - ) + erc1155.safeBatchTransferFrom(a1, a2, [21, 22, 23], [1, 1], DUMMY_BYTES32_DATA, sender=a1) # try to transfer nonexisting item with tx_failed(): erc1155.safeBatchTransferFrom( - a1, a2, [21, 22, 500], [1, 1, 1], DUMMY_BYTES32_DATA, transact={"from": a1} + a1, a2, [21, 22, 500], [1, 1, 1], DUMMY_BYTES32_DATA, sender=a1 ) - assert erc1155.safeBatchTransferFrom( - a1, a2, [21, 22, 23], [1, 1, 1], DUMMY_BYTES32_DATA, transact={"from": a1} - ) + erc1155.safeBatchTransferFrom(a1, a2, [21, 22, 23], [1, 1, 1], DUMMY_BYTES32_DATA, sender=a1) # try to transfer again, our balances are zero now, should fail with tx_failed(): erc1155.safeBatchTransferFrom( - a1, a2, [21, 22, 23], [1, 1, 1], DUMMY_BYTES32_DATA, transact={"from": a1} + a1, a2, [21, 22, 23], [1, 1, 1], DUMMY_BYTES32_DATA, sender=a1 ) with tx_failed(): - erc1155.balanceOfBatch([a2, a2, a2], [21, 22], transact={"from": owner}) + erc1155.balanceOfBatch([a2, a2, a2], [21, 22], sender=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, tx_failed): - owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] +def test_mint_one_burn_one(erc1155, env, tx_failed): + owner, a1, a2, a3, a4, a5 = env.accounts[0:6] # check the balance from an owner and non-owner account - erc1155.mint(owner, 25, 1, transact={"from": owner}) + erc1155.mint(owner, 25, 1, sender=owner) assert erc1155.balanceOf(owner, 25) == 1 assert erc1155.balanceOf(owner, 25) == 1 # try and burn an item we don't control with tx_failed(): - erc1155.burn(25, 1, transact={"from": a3}) + erc1155.burn(25, 1, sender=a3) # burn an item that contains something we don't own with tx_failed(): - erc1155.burn(595, 1, transact={"from": a1}) + erc1155.burn(595, 1, sender=a1) # burn ah item passing a higher amount than we own with tx_failed(): - erc1155.burn(25, 500, transact={"from": a1}) + erc1155.burn(25, 500, sender=a1) - erc1155.burn(25, 1, transact={"from": owner}) + erc1155.burn(25, 1, sender=owner) assert erc1155.balanceOf(owner, 25) == 0 -def test_mint_batch_burn_batch(erc1155, w3, tx_failed): - owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] +def test_mint_batch_burn_batch(erc1155, env, tx_failed): + owner, a1, a2, a3, a4, a5 = env.accounts[0:6] # mint NFTs 11-20 # check the balance @@ -324,37 +321,37 @@ def test_mint_batch_burn_batch(erc1155, w3, tx_failed): # ids and amounts array length not matching with tx_failed(): - erc1155.burnBatch([1, 2, 3], [1, 1], transact={"from": a1}) + erc1155.burnBatch([1, 2, 3], [1, 1], sender=a1) # burn a batch that contains something we don't own with tx_failed(): - erc1155.burnBatch([2, 3, 595], [1, 1, 1], transact={"from": a1}) + erc1155.burnBatch([2, 3, 595], [1, 1, 1], sender=a1) # burn a batch passing a higher amount than we own with tx_failed(): - erc1155.burnBatch([1, 2, 3], [1, 500, 1], transact={"from": a1}) + erc1155.burnBatch([1, 2, 3], [1, 500, 1], sender=a1) # burn existing - erc1155.burnBatch([11, 12], [1, 1], transact={"from": a3}) + erc1155.burnBatch([11, 12], [1, 1], sender=a3) assert erc1155.balanceOfBatch([a3, a3, a3], [11, 12, 13]) == [0, 0, 1] # burn again, should revert with tx_failed(): - erc1155.burnBatch([11, 12], [1, 1], transact={"from": a3}) + erc1155.burnBatch([11, 12], [1, 1], sender=a3) assert erc1155.balanceOfBatch([a3, a3, a3], [1, 2, 3]) == [0, 0, 0] -def test_approval_functions(erc1155, w3, tx_failed): # test_mint_batch - owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] +def test_approval_functions(erc1155, env, tx_failed): # test_mint_batch + owner, a1, a2, a3, a4, a5 = env.accounts[0:6] # self-approval by the owner with tx_failed(): - erc1155.setApprovalForAll(a5, a5, True, transact={"from": a5}) + erc1155.setApprovalForAll(a5, a5, True, sender=a5) # let's approve and operator for somebody else's account with tx_failed(): - erc1155.setApprovalForAll(owner, a5, True, transact={"from": a3}) + erc1155.setApprovalForAll(owner, a5, True, sender=a3) # set approval correctly erc1155.setApprovalForAll(owner, a5, True) @@ -366,8 +363,8 @@ def test_approval_functions(erc1155, w3, tx_failed): # test_mint_batch erc1155.setApprovalForAll(owner, a5, False) -def test_max_batch_size_violation(erc1155, w3, tx_failed): - owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] +def test_max_batch_size_violation(erc1155, env, tx_failed): + owner, a1, a2, a3, a4, a5 = env.accounts[0:6] TOTAL_BAD_BATCH = 200 ids = [] amounts = [] @@ -376,42 +373,42 @@ def test_max_batch_size_violation(erc1155, w3, tx_failed): amounts.append(1) with tx_failed(): - erc1155.mintBatch(a1, ids, amounts, transact={"from": owner}) + erc1155.mintBatch(a1, ids, amounts, sender=owner) # Transferring back and forth -def test_ownership_functions(erc1155, w3, tx_failed, tester): - owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] +def test_ownership_functions(erc1155, env, tx_failed): + owner, a1, a2, a3, a4, a5 = env.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 with tx_failed(): - erc1155.transferOwnership(a1, transact={"from": a2}) + erc1155.transferOwnership(a1, sender=a2) # try to transfer ownership to current owner with tx_failed(): erc1155.transferOwnership(owner) # try to transfer ownership to ZERO ADDRESS with tx_failed(): - erc1155.transferOwnership("0x0000000000000000000000000000000000000000") + erc1155.transferOwnership(ZERO_ADDRESS) # Transfer ownership to account 1 - erc1155.transferOwnership(a1, transact={"from": owner}) + erc1155.transferOwnership(a1, sender=owner) # assert erc1155.owner() == a1 assert erc1155.owner() == a1 -def test_renounce_ownership(erc1155, w3, tx_failed): - owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] +def test_renounce_ownership(erc1155, env, tx_failed): + owner, a1, a2, a3, a4, a5 = env.accounts[0:6] assert erc1155.owner() == owner # try to transfer ownership from non-owner account with tx_failed(): - erc1155.renounceOwnership(transact={"from": a2}) + erc1155.renounceOwnership(sender=a2) - erc1155.renounceOwnership(transact={"from": owner}) + erc1155.renounceOwnership(sender=owner) # assert erc1155.owner() == ZERO_ADDRESS diff --git a/tests/functional/examples/tokens/test_erc20.py b/tests/functional/examples/tokens/test_erc20.py index ce507f75f8..aef43768cb 100644 --- a/tests/functional/examples/tokens/test_erc20.py +++ b/tests/functional/examples/tokens/test_erc20.py @@ -2,9 +2,10 @@ # Modified from Philip Daian's tests: # https://github.com/vyperlang/vyper/blob/v0.1.0-beta.5/tests/examples/tokens/ERC20_solidity_compatible/test/erc20_tests_1.py import pytest -from web3.exceptions import ValidationError +from eth.codecs.abi.exceptions import EncodeError + +from tests.utils import ZERO_ADDRESS -ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" MAX_UINT256 = (2**256) - 1 # Max uint256 value TOKEN_NAME = "Vypercoin" TOKEN_SYMBOL = "FANG" @@ -13,38 +14,25 @@ @pytest.fixture -def c(get_contract, w3): +def c(get_contract): with open("examples/tokens/ERC20.vy") as f: code = f.read() - c = get_contract(code, *[TOKEN_NAME, TOKEN_SYMBOL, TOKEN_DECIMALS, TOKEN_INITIAL_SUPPLY]) - return c + return get_contract(code, *[TOKEN_NAME, TOKEN_SYMBOL, TOKEN_DECIMALS, TOKEN_INITIAL_SUPPLY]) @pytest.fixture -def c_bad(get_contract, w3): +def c_bad(get_contract): # Bad contract is used for overflow checks on totalSupply corrupted with open("examples/tokens/ERC20.vy") as f: code = f.read() bad_code = code.replace("self.totalSupply += _value", "").replace( "self.totalSupply -= _value", "" ) - c = get_contract(bad_code, *[TOKEN_NAME, TOKEN_SYMBOL, TOKEN_DECIMALS, TOKEN_INITIAL_SUPPLY]) - return c - - -@pytest.fixture -def get_log_args(get_logs): - def get_log_args(tx_hash, c, event_name): - logs = get_logs(tx_hash, c, event_name) - assert len(logs) > 0 - args = logs[0].args - return args - - return get_log_args + return get_contract(bad_code, *[TOKEN_NAME, TOKEN_SYMBOL, TOKEN_DECIMALS, TOKEN_INITIAL_SUPPLY]) -def test_initial_state(c, w3): - a1, a2, a3 = w3.eth.accounts[1:4] +def test_initial_state(c, env): + a1, a2, a3 = env.accounts[1:4] # Check total supply, name, symbol and decimals are correctly set assert c.totalSupply() == TOKEN_INITIAL_SUPPLY assert c.name() == TOKEN_NAME @@ -61,310 +49,313 @@ def test_initial_state(c, w3): assert c.allowance(a2, a3) == 0 -def test_mint_and_burn(c, w3, tx_failed): - minter, a1, a2 = w3.eth.accounts[0:3] +def test_mint_and_burn(c, env, tx_failed): + minter, a1, a2 = env.accounts[0:3] # Test scenario were mints 2 to a1, burns twice (check balance consistency) assert c.balanceOf(a1) == 0 - c.mint(a1, 2, transact={"from": minter}) + c.mint(a1, 2, sender=minter) assert c.balanceOf(a1) == 2 - c.burn(2, transact={"from": a1}) + c.burn(2, sender=a1) assert c.balanceOf(a1) == 0 with tx_failed(): - c.burn(2, transact={"from": a1}) + c.burn(2, sender=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}) + c.mint(a2, 0, sender=minter) assert c.balanceOf(a2) == 0 with tx_failed(): - c.burn(2, transact={"from": a2}) + c.burn(2, sender=a2) # Check that a1 cannot burn after depleting their balance with tx_failed(): - c.burn(1, transact={"from": a1}) + c.burn(1, sender=a1) # Check that a1, a2 cannot mint with tx_failed(): - c.mint(a1, 1, transact={"from": a1}) + c.mint(a1, 1, sender=a1) with tx_failed(): - c.mint(a2, 1, transact={"from": a2}) + c.mint(a2, 1, sender=a2) # Check that mint to ZERO_ADDRESS failed with tx_failed(): - c.mint(ZERO_ADDRESS, 1, transact={"from": a1}) + c.mint(ZERO_ADDRESS, 1, sender=a1) with tx_failed(): - c.mint(ZERO_ADDRESS, 1, transact={"from": minter}) + c.mint(ZERO_ADDRESS, 1, sender=minter) -def test_totalSupply(c, w3, tx_failed): +def test_totalSupply(c, env, tx_failed): # Test total supply initially, after mint, between two burns, and after failed burn - minter, a1 = w3.eth.accounts[0:2] + minter, a1 = env.accounts[0:2] assert c.totalSupply() == 0 - c.mint(a1, 2, transact={"from": minter}) + c.mint(a1, 2, sender=minter) assert c.totalSupply() == 2 - c.burn(1, transact={"from": a1}) + c.burn(1, sender=a1) assert c.totalSupply() == 1 - c.burn(1, transact={"from": a1}) + c.burn(1, sender=a1) assert c.totalSupply() == 0 with tx_failed(): - c.burn(1, transact={"from": a1}) + c.burn(1, sender=a1) assert c.totalSupply() == 0 # Test that 0-valued mint can't affect supply - c.mint(a1, 0, transact={"from": minter}) + c.mint(a1, 0, sender=minter) assert c.totalSupply() == 0 -def test_transfer(c, w3, tx_failed): - minter, a1, a2 = w3.eth.accounts[0:3] +def test_transfer(c, env, tx_failed): + minter, a1, a2 = env.accounts[0:3] 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}) + c.burn(1, sender=a2) + c.mint(a1, 2, sender=minter) + c.burn(1, sender=a1) + c.transfer(a2, 1, sender=a1) with tx_failed(): - c.burn(1, transact={"from": a1}) - c.burn(1, transact={"from": a2}) + c.burn(1, sender=a1) + c.burn(1, sender=a2) with tx_failed(): - c.burn(1, transact={"from": a2}) + c.burn(1, sender=a2) # Ensure transfer fails with insufficient balance with tx_failed(): - c.transfer(a1, 1, transact={"from": a2}) + c.transfer(a1, 1, sender=a2) # Ensure 0-transfer always succeeds - c.transfer(a1, 0, transact={"from": a2}) + c.transfer(a1, 0, sender=a2) -def test_maxInts(c, w3, tx_failed): - minter, a1, a2 = w3.eth.accounts[0:3] - c.mint(a1, MAX_UINT256, transact={"from": minter}) +def test_maxInts(c, env, tx_failed): + minter, a1, a2 = env.accounts[0:3] + c.mint(a1, MAX_UINT256, sender=minter) assert c.balanceOf(a1) == MAX_UINT256 with tx_failed(): - c.mint(a1, 1, transact={"from": a1}) + c.mint(a1, 1, sender=a1) with tx_failed(): - c.mint(a1, MAX_UINT256, transact={"from": a1}) + c.mint(a1, MAX_UINT256, sender=a1) # Check that totalSupply cannot overflow, even when mint to other account with tx_failed(): - c.mint(a2, 1, transact={"from": minter}) + c.mint(a2, 1, sender=minter) # Check that corresponding mint is allowed after burn - c.burn(1, transact={"from": a1}) - c.mint(a2, 1, transact={"from": minter}) + c.burn(1, sender=a1) + c.mint(a2, 1, sender=minter) with tx_failed(): - c.mint(a2, 1, transact={"from": minter}) - c.transfer(a1, 1, transact={"from": a2}) + c.mint(a2, 1, sender=minter) + c.transfer(a1, 1, sender=a2) # Assert that after obtaining max number of tokens, a1 can transfer those but no more assert c.balanceOf(a1) == MAX_UINT256 - c.transfer(a2, MAX_UINT256, transact={"from": a1}) + c.transfer(a2, MAX_UINT256, sender=a1) assert c.balanceOf(a2) == MAX_UINT256 assert c.balanceOf(a1) == 0 # [ next line should never work in EVM ] - with pytest.raises(ValidationError): - c.transfer(a1, MAX_UINT256 + 1, transact={"from": a2}) + with pytest.raises(EncodeError): + c.transfer(a1, MAX_UINT256 + 1, sender=a2) # Check approve/allowance w max possible token values assert c.balanceOf(a2) == MAX_UINT256 - c.approve(a1, MAX_UINT256, transact={"from": a2}) - c.transferFrom(a2, a1, MAX_UINT256, transact={"from": a1}) + c.approve(a1, MAX_UINT256, sender=a2) + c.transferFrom(a2, a1, MAX_UINT256, sender=a1) assert c.balanceOf(a1) == MAX_UINT256 assert c.balanceOf(a2) == 0 # Check that max amount can be burned - c.burn(MAX_UINT256, transact={"from": a1}) + c.burn(MAX_UINT256, sender=a1) assert c.balanceOf(a1) == 0 -def test_transferFrom_and_Allowance(c, w3, tx_failed): - minter, a1, a2, a3 = w3.eth.accounts[0:4] +def test_transferFrom_and_Allowance(c, env, tx_failed): + minter, a1, a2, a3 = env.accounts[0:4] 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}) + c.burn(1, sender=a2) + c.mint(a1, 1, sender=minter) + c.mint(a2, 1, sender=minter) + c.burn(1, sender=a1) # This should fail; no allowance or balance (0 always succeeds) with tx_failed(): - c.transferFrom(a1, a3, 1, transact={"from": a2}) - c.transferFrom(a1, a3, 0, transact={"from": a2}) + c.transferFrom(a1, a3, 1, sender=a2) + c.transferFrom(a1, a3, 0, sender=a2) # Correct call to approval should update allowance (but not for reverse pair) - c.approve(a2, 1, transact={"from": a1}) + c.approve(a2, 1, sender=a1) assert c.allowance(a1, a2) == 1 assert c.allowance(a2, a1) == 0 # transferFrom should succeed when allowed, fail with wrong sender with tx_failed(): - c.transferFrom(a1, a3, 1, transact={"from": a3}) + c.transferFrom(a1, a3, 1, sender=a3) assert c.balanceOf(a2) == 1 - c.approve(a1, 1, transact={"from": a2}) - c.transferFrom(a2, a3, 1, transact={"from": a1}) + c.approve(a1, 1, sender=a2) + c.transferFrom(a2, a3, 1, sender=a1) # Allowance should be correctly updated after transferFrom assert c.allowance(a2, a1) == 0 # transferFrom with no funds should fail despite approval - c.approve(a1, 1, transact={"from": a2}) + c.approve(a1, 1, sender=a2) assert c.allowance(a2, a1) == 1 with tx_failed(): - c.transferFrom(a2, a3, 1, transact={"from": a1}) + c.transferFrom(a2, a3, 1, sender=a1) # 0-approve should not change balance or allow transferFrom to change balance - c.mint(a2, 1, transact={"from": minter}) + c.mint(a2, 1, sender=minter) assert c.allowance(a2, a1) == 1 - c.approve(a1, 0, transact={"from": a2}) + c.approve(a1, 0, sender=a2) assert c.allowance(a2, a1) == 0 - c.approve(a1, 0, transact={"from": a2}) + c.approve(a1, 0, sender=a2) assert c.allowance(a2, a1) == 0 with tx_failed(): - c.transferFrom(a2, a3, 1, transact={"from": a1}) + c.transferFrom(a2, a3, 1, sender=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 # the final spec insists on NOT using this behavior assert c.allowance(a2, a1) == 0 - c.approve(a1, 1, transact={"from": a2}) + c.approve(a1, 1, sender=a2) assert c.allowance(a2, a1) == 1 - c.approve(a1, 2, transact={"from": a2}) + c.approve(a1, 2, sender=a2) assert c.allowance(a2, a1) == 2 # Check that approving 0 then amount also works - c.approve(a1, 0, transact={"from": a2}) + c.approve(a1, 0, sender=a2) assert c.allowance(a2, a1) == 0 - c.approve(a1, 5, transact={"from": a2}) + c.approve(a1, 5, sender=a2) assert c.allowance(a2, a1) == 5 -def test_burnFrom_and_Allowance(c, w3, tx_failed): - minter, a1, a2, a3 = w3.eth.accounts[0:4] +def test_burnFrom_and_Allowance(c, env, tx_failed): + minter, a1, a2, a3 = env.accounts[0:4] 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}) + c.burn(1, sender=a2) + c.mint(a1, 1, sender=minter) + c.mint(a2, 1, sender=minter) + c.burn(1, sender=a1) # This should fail; no allowance or balance (0 always succeeds) with tx_failed(): - c.burnFrom(a1, 1, transact={"from": a2}) - c.burnFrom(a1, 0, transact={"from": a2}) + c.burnFrom(a1, 1, sender=a2) + c.burnFrom(a1, 0, sender=a2) # Correct call to approval should update allowance (but not for reverse pair) - c.approve(a2, 1, transact={"from": a1}) + c.approve(a2, 1, sender=a1) assert c.allowance(a1, a2) == 1 assert c.allowance(a2, a1) == 0 # transferFrom should succeed when allowed, fail with wrong sender with tx_failed(): - c.burnFrom(a2, 1, transact={"from": a3}) + c.burnFrom(a2, 1, sender=a3) assert c.balanceOf(a2) == 1 - c.approve(a1, 1, transact={"from": a2}) - c.burnFrom(a2, 1, transact={"from": a1}) + c.approve(a1, 1, sender=a2) + c.burnFrom(a2, 1, sender=a1) # Allowance should be correctly updated after transferFrom assert c.allowance(a2, a1) == 0 # transferFrom with no funds should fail despite approval - c.approve(a1, 1, transact={"from": a2}) + c.approve(a1, 1, sender=a2) assert c.allowance(a2, a1) == 1 with tx_failed(): - c.burnFrom(a2, 1, transact={"from": a1}) + c.burnFrom(a2, 1, sender=a1) # 0-approve should not change balance or allow transferFrom to change balance - c.mint(a2, 1, transact={"from": minter}) + c.mint(a2, 1, sender=minter) assert c.allowance(a2, a1) == 1 - c.approve(a1, 0, transact={"from": a2}) + c.approve(a1, 0, sender=a2) assert c.allowance(a2, a1) == 0 - c.approve(a1, 0, transact={"from": a2}) + c.approve(a1, 0, sender=a2) assert c.allowance(a2, a1) == 0 with tx_failed(): - c.burnFrom(a2, 1, transact={"from": a1}) + c.burnFrom(a2, 1, sender=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 # the final spec insists on NOT using this behavior assert c.allowance(a2, a1) == 0 - c.approve(a1, 1, transact={"from": a2}) + c.approve(a1, 1, sender=a2) assert c.allowance(a2, a1) == 1 - c.approve(a1, 2, transact={"from": a2}) + c.approve(a1, 2, sender=a2) assert c.allowance(a2, a1) == 2 # Check that approving 0 then amount also works - c.approve(a1, 0, transact={"from": a2}) + c.approve(a1, 0, sender=a2) assert c.allowance(a2, a1) == 0 - c.approve(a1, 5, transact={"from": a2}) + c.approve(a1, 5, sender=a2) assert c.allowance(a2, a1) == 5 # Check that burnFrom to ZERO_ADDRESS failed with tx_failed(): - c.burnFrom(ZERO_ADDRESS, 0, transact={"from": a1}) + c.burnFrom(ZERO_ADDRESS, 0, sender=a1) + +def test_raw_logs(c, env, get_logs): + minter, a1, a2, a3 = env.accounts[0:4] -def test_raw_logs(c, w3, get_log_args): - minter, a1, a2, a3 = w3.eth.accounts[0:4] + def get_log_args(_, c, event_name): + return get_logs(c, event_name)[0].args # Check that mint appropriately emits Transfer event - args = get_log_args(c.mint(a1, 2, transact={"from": minter}), c, "Transfer") + args = get_log_args(c.mint(a1, 2, sender=minter), c, "Transfer") assert args.sender == ZERO_ADDRESS assert args.receiver == a1 assert args.value == 2 - args = get_log_args(c.mint(a1, 0, transact={"from": minter}), c, "Transfer") + args = get_log_args(c.mint(a1, 0, sender=minter), c, "Transfer") assert args.sender == ZERO_ADDRESS assert args.receiver == a1 assert args.value == 0 # Check that burn appropriately emits Transfer event - args = get_log_args(c.burn(1, transact={"from": a1}), c, "Transfer") + args = get_log_args(c.burn(1, sender=a1), c, "Transfer") assert args.sender == a1 assert args.receiver == ZERO_ADDRESS assert args.value == 1 - args = get_log_args(c.burn(0, transact={"from": a1}), c, "Transfer") + args = get_log_args(c.burn(0, sender=a1), c, "Transfer") assert args.sender == a1 assert args.receiver == ZERO_ADDRESS assert args.value == 0 # Check that transfer appropriately emits Transfer event - args = get_log_args(c.transfer(a2, 1, transact={"from": a1}), c, "Transfer") + args = get_log_args(c.transfer(a2, 1, sender=a1), c, "Transfer") assert args.sender == a1 assert args.receiver == a2 assert args.value == 1 - args = get_log_args(c.transfer(a2, 0, transact={"from": a1}), c, "Transfer") + args = get_log_args(c.transfer(a2, 0, sender=a1), c, "Transfer") assert args.sender == a1 assert args.receiver == a2 assert args.value == 0 # Check that approving amount emits events - args = get_log_args(c.approve(a1, 1, transact={"from": a2}), c, "Approval") + args = get_log_args(c.approve(a1, 1, sender=a2), c, "Approval") assert args.owner == a2 assert args.spender == a1 assert args.value == 1 - args = get_log_args(c.approve(a2, 0, transact={"from": a3}), c, "Approval") + args = get_log_args(c.approve(a2, 0, sender=a3), c, "Approval") assert args.owner == a3 assert args.spender == a2 assert args.value == 0 # Check that transferFrom appropriately emits Transfer event - args = get_log_args(c.transferFrom(a2, a3, 1, transact={"from": a1}), c, "Transfer") + args = get_log_args(c.transferFrom(a2, a3, 1, sender=a1), c, "Transfer") assert args.sender == a2 assert args.receiver == a3 assert args.value == 1 - args = get_log_args(c.transferFrom(a2, a3, 0, transact={"from": a1}), c, "Transfer") + args = get_log_args(c.transferFrom(a2, a3, 0, sender=a1), c, "Transfer") assert args.sender == a2 assert args.receiver == a3 assert args.value == 0 -def test_bad_transfer(c_bad, w3, tx_failed): +def test_bad_transfer(c_bad, env, 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}) + minter, a1, a2 = env.accounts[0:3] + c_bad.mint(a1, MAX_UINT256, sender=minter) + c_bad.mint(a2, 1, sender=minter) with tx_failed(): - c_bad.transfer(a1, 1, transact={"from": a2}) - c_bad.transfer(a2, MAX_UINT256 - 1, transact={"from": a1}) + c_bad.transfer(a1, 1, sender=a2) + c_bad.transfer(a2, MAX_UINT256 - 1, sender=a1) assert c_bad.balanceOf(a1) == 1 assert c_bad.balanceOf(a2) == MAX_UINT256 -def test_bad_burn(c_bad, w3, tx_failed): +def test_bad_burn(c_bad, env, tx_failed): # Ensure burn fails if it would otherwise underflow balance when totalSupply is corrupted - minter, a1 = w3.eth.accounts[0:2] + minter, a1 = env.accounts[0:2] assert c_bad.balanceOf(a1) == 0 - c_bad.mint(a1, 2, transact={"from": minter}) + c_bad.mint(a1, 2, sender=minter) assert c_bad.balanceOf(a1) == 2 with tx_failed(): - c_bad.burn(3, transact={"from": a1}) + c_bad.burn(3, sender=a1) -def test_bad_transferFrom(c_bad, w3, tx_failed): +def test_bad_transferFrom(c_bad, env, 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}) + minter, a1, a2 = env.accounts[0:3] + c_bad.mint(a1, MAX_UINT256, sender=minter) + c_bad.mint(a2, 1, sender=minter) + c_bad.approve(a1, 1, sender=a2) with tx_failed(): - c_bad.transferFrom(a2, a1, 1, transact={"from": a1}) - c_bad.approve(a2, MAX_UINT256 - 1, transact={"from": a1}) + c_bad.transferFrom(a2, a1, 1, sender=a1) + c_bad.approve(a2, MAX_UINT256 - 1, sender=a1) assert c_bad.allowance(a1, a2) == MAX_UINT256 - 1 - c_bad.transferFrom(a1, a2, MAX_UINT256 - 1, transact={"from": a2}) + c_bad.transferFrom(a1, a2, MAX_UINT256 - 1, sender=a2) assert c_bad.balanceOf(a2) == MAX_UINT256 diff --git a/tests/functional/examples/tokens/test_erc4626.py b/tests/functional/examples/tokens/test_erc4626.py index 2469a7abd0..f0fb79efae 100644 --- a/tests/functional/examples/tokens/test_erc4626.py +++ b/tests/functional/examples/tokens/test_erc4626.py @@ -25,8 +25,8 @@ def test_asset(vault, token): assert vault.asset() == token.address -def test_max_methods(w3, vault): - a = w3.eth.accounts[0] +def test_max_methods(env, vault): + a = env.accounts[0] assert vault.maxDeposit(a) == 2**256 - 1 assert vault.maxMint(a) == 2**256 - 1 @@ -34,8 +34,8 @@ def test_max_methods(w3, vault): assert vault.maxRedeem(a) == 2**256 - 1 -def test_preview_methods(w3, token, vault): - a = w3.eth.accounts[0] +def test_preview_methods(env, token, vault): + a = env.accounts[0] assert vault.totalAssets() == 0 assert vault.convertToAssets(10**18) == 0 # no assets @@ -45,9 +45,9 @@ def test_preview_methods(w3, token, vault): assert vault.previewWithdraw(AMOUNT) == 0 # but no assets assert vault.previewRedeem(AMOUNT) == 0 # but no assets - token.mint(a, AMOUNT, transact={"from": a}) - token.approve(vault.address, AMOUNT, transact={"from": a}) - vault.deposit(AMOUNT, transact={"from": a}) + token.mint(a, AMOUNT, sender=a) + token.approve(vault.address, AMOUNT, sender=a) + vault.deposit(AMOUNT, sender=a) assert vault.totalAssets() == AMOUNT assert vault.convertToAssets(10**18) == 10**18 # 1:1 price @@ -57,7 +57,7 @@ def test_preview_methods(w3, token, vault): assert vault.previewWithdraw(AMOUNT) == AMOUNT # 1:1 price assert vault.previewRedeem(AMOUNT) == AMOUNT # 1:1 price - token.mint(vault.address, AMOUNT, transact={"from": a}) + token.mint(vault.address, AMOUNT, sender=a) assert vault.totalAssets() == 2 * AMOUNT assert vault.convertToAssets(10**18) == 2 * 10**18 # 2:1 price @@ -67,7 +67,7 @@ def test_preview_methods(w3, token, vault): assert vault.previewWithdraw(AMOUNT) == AMOUNT // 2 # 2:1 price assert vault.previewRedeem(AMOUNT // 2) == AMOUNT # 2:1 price - vault.DEBUG_steal_tokens(AMOUNT, transact={"from": a}) + vault.DEBUG_steal_tokens(AMOUNT, sender=a) assert vault.totalAssets() == AMOUNT assert vault.convertToAssets(10**18) == 10**18 # 1:1 price @@ -77,7 +77,7 @@ def test_preview_methods(w3, token, vault): assert vault.previewWithdraw(AMOUNT) == AMOUNT # 1:1 price assert vault.previewRedeem(AMOUNT) == AMOUNT # 1:1 price - vault.DEBUG_steal_tokens(AMOUNT // 2, transact={"from": a}) + vault.DEBUG_steal_tokens(AMOUNT // 2, sender=a) assert vault.totalAssets() == AMOUNT // 2 assert vault.convertToAssets(10**18) == 10**18 // 2 # 1:2 price diff --git a/tests/functional/examples/tokens/test_erc721.py b/tests/functional/examples/tokens/test_erc721.py index 4f55807ed3..1ed26f64dc 100644 --- a/tests/functional/examples/tokens/test_erc721.py +++ b/tests/functional/examples/tokens/test_erc721.py @@ -1,30 +1,31 @@ import pytest +from tests.utils import ZERO_ADDRESS + SOMEONE_TOKEN_IDS = [1, 2, 3] OPERATOR_TOKEN_ID = 10 NEW_TOKEN_ID = 20 INVALID_TOKEN_ID = 99 -ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" ERC165_SIG = "0x01ffc9a7" ERC165_INVALID_SIG = "0xffffffff" ERC721_SIG = "0x80ac58cd" @pytest.fixture -def c(get_contract, w3): +def c(get_contract, env): with open("examples/tokens/ERC721.vy") as f: code = f.read() c = get_contract(code) - minter, someone, operator = w3.eth.accounts[:3] + minter, someone, operator = env.accounts[:3] # someone owns 3 tokens for i in SOMEONE_TOKEN_IDS: - c.mint(someone, i, transact={"from": minter}) + c.mint(someone, i, sender=minter) # operator owns 1 tokens - c.mint(operator, OPERATOR_TOKEN_ID, transact={"from": minter}) + c.mint(operator, OPERATOR_TOKEN_ID, sender=minter) return c -def test_erc165(w3, c): +def test_erc165(env, c): # From EIP-165: # The source contract makes a STATICCALL to the destination address with input data: # 0x01ffc9a701ffc9a700000000000000000000000000000000000000000000000000000000 @@ -40,161 +41,143 @@ def test_erc165(w3, c): assert c.supportsInterface(ERC721_SIG) -def test_balanceOf(c, w3, tx_failed): - someone = w3.eth.accounts[1] +def test_balanceOf(c, env, tx_failed): + someone = env.accounts[1] assert c.balanceOf(someone) == 3 with tx_failed(): c.balanceOf(ZERO_ADDRESS) -def test_ownerOf(c, w3, tx_failed): - someone = w3.eth.accounts[1] +def test_ownerOf(c, env, tx_failed): + someone = env.accounts[1] assert c.ownerOf(SOMEONE_TOKEN_IDS[0]) == someone with tx_failed(): c.ownerOf(INVALID_TOKEN_ID) -def test_getApproved(c, w3): - someone, operator = w3.eth.accounts[1:3] +def test_getApproved(c, env): + someone, operator = env.accounts[1:3] - assert c.getApproved(SOMEONE_TOKEN_IDS[0]) is None + assert c.getApproved(SOMEONE_TOKEN_IDS[0]) == ZERO_ADDRESS - c.approve(operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) + c.approve(operator, SOMEONE_TOKEN_IDS[0], sender=someone) assert c.getApproved(SOMEONE_TOKEN_IDS[0]) == operator -def test_isApprovedForAll(c, w3): - someone, operator = w3.eth.accounts[1:3] +def test_isApprovedForAll(c, env): + someone, operator = env.accounts[1:3] assert c.isApprovedForAll(someone, operator) == 0 - c.setApprovalForAll(operator, True, transact={"from": someone}) + c.setApprovalForAll(operator, True, sender=someone) assert c.isApprovedForAll(someone, operator) == 1 -def test_transferFrom_by_owner(c, w3, tx_failed, get_logs): - someone, operator = w3.eth.accounts[1:3] +def test_transferFrom_by_owner(c, env, tx_failed, get_logs): + someone, operator = env.accounts[1:3] # transfer from zero address with tx_failed(): - c.transferFrom(ZERO_ADDRESS, operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) + c.transferFrom(ZERO_ADDRESS, operator, SOMEONE_TOKEN_IDS[0], sender=someone) # transfer to zero address with tx_failed(): - c.transferFrom(someone, ZERO_ADDRESS, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) + c.transferFrom(someone, ZERO_ADDRESS, SOMEONE_TOKEN_IDS[0], sender=someone) # transfer token without ownership with tx_failed(): - c.transferFrom(someone, operator, OPERATOR_TOKEN_ID, transact={"from": someone}) + c.transferFrom(someone, operator, OPERATOR_TOKEN_ID, sender=someone) # transfer invalid token with tx_failed(): - c.transferFrom(someone, operator, INVALID_TOKEN_ID, transact={"from": someone}) + c.transferFrom(someone, operator, INVALID_TOKEN_ID, sender=someone) # transfer by owner - tx_hash = c.transferFrom(someone, operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) - - logs = get_logs(tx_hash, c, "Transfer") + c.transferFrom(someone, operator, SOMEONE_TOKEN_IDS[0], sender=someone) - assert len(logs) > 0 - args = logs[0].args - assert args.sender == someone - assert args.receiver == operator - assert args.token_id == SOMEONE_TOKEN_IDS[0] + (log,) = get_logs(c, "Transfer") + assert log.args.sender == someone + assert log.args.receiver == operator + assert log.args.token_id == SOMEONE_TOKEN_IDS[0] assert c.ownerOf(SOMEONE_TOKEN_IDS[0]) == operator assert c.balanceOf(someone) == 2 assert c.balanceOf(operator) == 2 -def test_transferFrom_by_approved(c, w3, get_logs): - someone, operator = w3.eth.accounts[1:3] +def test_transferFrom_by_approved(c, env, get_logs): + someone, operator = env.accounts[1:3] # transfer by approved - c.approve(operator, SOMEONE_TOKEN_IDS[1], transact={"from": someone}) - tx_hash = c.transferFrom(someone, operator, SOMEONE_TOKEN_IDS[1], transact={"from": operator}) - - logs = get_logs(tx_hash, c, "Transfer") + c.approve(operator, SOMEONE_TOKEN_IDS[1], sender=someone) + c.transferFrom(someone, operator, SOMEONE_TOKEN_IDS[1], sender=operator) - assert len(logs) > 0 - args = logs[0].args - assert args.sender == someone - assert args.receiver == operator - assert args.token_id == SOMEONE_TOKEN_IDS[1] + (log,) = get_logs(c, "Transfer") + assert log.args.sender == someone + assert log.args.receiver == operator + assert log.args.token_id == SOMEONE_TOKEN_IDS[1] assert c.ownerOf(SOMEONE_TOKEN_IDS[1]) == operator assert c.balanceOf(someone) == 2 assert c.balanceOf(operator) == 2 -def test_transferFrom_by_operator(c, w3, get_logs): - someone, operator = w3.eth.accounts[1:3] +def test_transferFrom_by_operator(c, env, get_logs): + someone, operator = env.accounts[1:3] # transfer by operator - c.setApprovalForAll(operator, True, transact={"from": someone}) - tx_hash = c.transferFrom(someone, operator, SOMEONE_TOKEN_IDS[2], transact={"from": operator}) - - logs = get_logs(tx_hash, c, "Transfer") + c.setApprovalForAll(operator, True, sender=someone) + c.transferFrom(someone, operator, SOMEONE_TOKEN_IDS[2], sender=operator) - assert len(logs) > 0 - args = logs[0].args - assert args.sender == someone - assert args.receiver == operator - assert args.token_id == SOMEONE_TOKEN_IDS[2] + (log,) = get_logs(c, "Transfer") + assert log.args.sender == someone + assert log.args.receiver == operator + assert log.args.token_id == SOMEONE_TOKEN_IDS[2] assert c.ownerOf(SOMEONE_TOKEN_IDS[2]) == operator assert c.balanceOf(someone) == 2 assert c.balanceOf(operator) == 2 -def test_safeTransferFrom_by_owner(c, w3, tx_failed, get_logs): - someone, operator = w3.eth.accounts[1:3] +def test_safeTransferFrom_by_owner(c, env, tx_failed, get_logs): + someone, operator = env.accounts[1:3] # transfer from zero address with tx_failed(): - c.safeTransferFrom(ZERO_ADDRESS, operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) + c.safeTransferFrom(ZERO_ADDRESS, operator, SOMEONE_TOKEN_IDS[0], sender=someone) # transfer to zero address with tx_failed(): - c.safeTransferFrom(someone, ZERO_ADDRESS, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) + c.safeTransferFrom(someone, ZERO_ADDRESS, SOMEONE_TOKEN_IDS[0], sender=someone) # transfer token without ownership with tx_failed(): - c.safeTransferFrom(someone, operator, OPERATOR_TOKEN_ID, transact={"from": someone}) + c.safeTransferFrom(someone, operator, OPERATOR_TOKEN_ID, sender=someone) # transfer invalid token with tx_failed(): - c.safeTransferFrom(someone, operator, INVALID_TOKEN_ID, transact={"from": someone}) + c.safeTransferFrom(someone, operator, INVALID_TOKEN_ID, sender=someone) # transfer by owner - tx_hash = c.safeTransferFrom( - someone, operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone} - ) - - logs = get_logs(tx_hash, c, "Transfer") + c.safeTransferFrom(someone, operator, SOMEONE_TOKEN_IDS[0], sender=someone) - assert len(logs) > 0 - args = logs[0].args - assert args.sender == someone - assert args.receiver == operator - assert args.token_id == SOMEONE_TOKEN_IDS[0] + (log,) = get_logs(c, "Transfer") + assert log.args.sender == someone + assert log.args.receiver == operator + assert log.args.token_id == SOMEONE_TOKEN_IDS[0] assert c.ownerOf(SOMEONE_TOKEN_IDS[0]) == operator assert c.balanceOf(someone) == 2 assert c.balanceOf(operator) == 2 -def test_safeTransferFrom_by_approved(c, w3, get_logs): - someone, operator = w3.eth.accounts[1:3] +def test_safeTransferFrom_by_approved(c, env, get_logs): + someone, operator = env.accounts[1:3] # transfer by approved - c.approve(operator, SOMEONE_TOKEN_IDS[1], transact={"from": someone}) - tx_hash = c.safeTransferFrom( - someone, operator, SOMEONE_TOKEN_IDS[1], transact={"from": operator} - ) - - logs = get_logs(tx_hash, c, "Transfer") + c.approve(operator, SOMEONE_TOKEN_IDS[1], sender=someone) + c.safeTransferFrom(someone, operator, SOMEONE_TOKEN_IDS[1], sender=operator) - assert len(logs) > 0 - args = logs[0].args + (log,) = get_logs(c, "Transfer") + args = log.args assert args.sender == someone assert args.receiver == operator assert args.token_id == SOMEONE_TOKEN_IDS[1] @@ -203,33 +186,28 @@ def test_safeTransferFrom_by_approved(c, w3, get_logs): assert c.balanceOf(operator) == 2 -def test_safeTransferFrom_by_operator(c, w3, get_logs): - someone, operator = w3.eth.accounts[1:3] +def test_safeTransferFrom_by_operator(c, env, get_logs): + someone, operator = env.accounts[1:3] # transfer by operator - c.setApprovalForAll(operator, True, transact={"from": someone}) - tx_hash = c.safeTransferFrom( - someone, operator, SOMEONE_TOKEN_IDS[2], transact={"from": operator} - ) + c.setApprovalForAll(operator, True, sender=someone) + c.safeTransferFrom(someone, operator, SOMEONE_TOKEN_IDS[2], sender=operator) - logs = get_logs(tx_hash, c, "Transfer") - - assert len(logs) > 0 - args = logs[0].args - assert args.sender == someone - assert args.receiver == operator - assert args.token_id == SOMEONE_TOKEN_IDS[2] + (log,) = get_logs(c, "Transfer") + assert log.args.sender == someone + assert log.args.receiver == operator + assert log.args.token_id == SOMEONE_TOKEN_IDS[2] assert c.ownerOf(SOMEONE_TOKEN_IDS[2]) == operator assert c.balanceOf(someone) == 2 assert c.balanceOf(operator) == 2 -def test_safeTransferFrom_to_contract(c, w3, tx_failed, get_logs, get_contract): - someone = w3.eth.accounts[1] +def test_safeTransferFrom_to_contract(c, env, tx_failed, get_logs, get_contract): + someone = env.accounts[1] # Can't transfer to a contract that doesn't implement the receiver code with tx_failed(): - c.safeTransferFrom(someone, c.address, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) + c.safeTransferFrom(someone, c.address, SOMEONE_TOKEN_IDS[0], sender=someone) # Only to an address that implements that function receiver = get_contract( @@ -244,79 +222,70 @@ def onERC721Received( return method_id("onERC721Received(address,address,uint256,bytes)", output_type=bytes4) """ ) - tx_hash = c.safeTransferFrom( - someone, receiver.address, SOMEONE_TOKEN_IDS[0], transact={"from": someone} - ) + c.safeTransferFrom(someone, receiver.address, SOMEONE_TOKEN_IDS[0], sender=someone) - logs = get_logs(tx_hash, c, "Transfer") - - assert len(logs) > 0 - args = logs[0].args - assert args.sender == someone - assert args.receiver == receiver.address - assert args.token_id == SOMEONE_TOKEN_IDS[0] + (log,) = get_logs(c, "Transfer") + assert log.args.sender == someone + assert log.args.receiver == receiver.address + assert log.args.token_id == SOMEONE_TOKEN_IDS[0] assert c.ownerOf(SOMEONE_TOKEN_IDS[0]) == receiver.address assert c.balanceOf(someone) == 2 assert c.balanceOf(receiver.address) == 1 -def test_approve(c, w3, tx_failed, get_logs): - someone, operator = w3.eth.accounts[1:3] +def test_approve(c, env, tx_failed, get_logs): + someone, operator = env.accounts[1:3] # approve myself with tx_failed(): - c.approve(someone, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) + c.approve(someone, SOMEONE_TOKEN_IDS[0], sender=someone) # approve token without ownership with tx_failed(): - c.approve(operator, OPERATOR_TOKEN_ID, transact={"from": someone}) + c.approve(operator, OPERATOR_TOKEN_ID, sender=someone) # approve invalid token with tx_failed(): - c.approve(operator, INVALID_TOKEN_ID, transact={"from": someone}) + c.approve(operator, INVALID_TOKEN_ID, sender=someone) - tx_hash = c.approve(operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) - logs = get_logs(tx_hash, c, "Approval") + c.approve(operator, SOMEONE_TOKEN_IDS[0], sender=someone) + (log,) = get_logs(c, "Approval") - assert len(logs) > 0 - args = logs[0].args - assert args.owner == someone - assert args.approved == operator - assert args.token_id == SOMEONE_TOKEN_IDS[0] + assert log.args.owner == someone + assert log.args.approved == operator + assert log.args.token_id == SOMEONE_TOKEN_IDS[0] -def test_setApprovalForAll(c, w3, tx_failed, get_logs): - someone, operator = w3.eth.accounts[1:3] +def test_setApprovalForAll(c, env, tx_failed, get_logs): + someone, operator = env.accounts[1:3] approved = True # setApprovalForAll myself with tx_failed(): - c.setApprovalForAll(someone, approved, transact={"from": someone}) + c.setApprovalForAll(someone, approved, sender=someone) - tx_hash = c.setApprovalForAll(operator, approved, transact={"from": someone}) - logs = get_logs(tx_hash, c, "ApprovalForAll") - - assert len(logs) > 0 - args = logs[0].args + c.setApprovalForAll(operator, approved, sender=someone) + (log,) = get_logs(c, "ApprovalForAll") + args = log.args assert args.owner == someone assert args.operator == operator assert args.approved == approved -def test_mint(c, w3, tx_failed, get_logs): - minter, someone = w3.eth.accounts[:2] +def test_mint(c, env, tx_failed, get_logs): + minter, someone = env.accounts[:2] # mint by non-minter with tx_failed(): - c.mint(someone, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) + c.mint(someone, SOMEONE_TOKEN_IDS[0], sender=someone) # mint to zero address with tx_failed(): - c.mint(ZERO_ADDRESS, SOMEONE_TOKEN_IDS[0], transact={"from": minter}) + c.mint(ZERO_ADDRESS, SOMEONE_TOKEN_IDS[0], sender=minter) # mint by minter - tx_hash = c.mint(someone, NEW_TOKEN_ID, transact={"from": minter}) - logs = get_logs(tx_hash, c, "Transfer") + c.mint(someone, NEW_TOKEN_ID, sender=minter) + logs = get_logs(c, "Transfer") assert len(logs) > 0 args = logs[0].args @@ -327,16 +296,16 @@ def test_mint(c, w3, tx_failed, get_logs): assert c.balanceOf(someone) == 4 -def test_burn(c, w3, tx_failed, get_logs): - someone, operator = w3.eth.accounts[1:3] +def test_burn(c, env, tx_failed, get_logs): + someone, operator = env.accounts[1:3] # burn token without ownership with tx_failed(): - c.burn(SOMEONE_TOKEN_IDS[0], transact={"from": operator}) + c.burn(SOMEONE_TOKEN_IDS[0], sender=operator) # burn token by owner - tx_hash = c.burn(SOMEONE_TOKEN_IDS[0], transact={"from": someone}) - logs = get_logs(tx_hash, c, "Transfer") + c.burn(SOMEONE_TOKEN_IDS[0], sender=someone) + logs = get_logs(c, "Transfer") assert len(logs) > 0 args = logs[0].args diff --git a/tests/functional/examples/voting/test_ballot.py b/tests/functional/examples/voting/test_ballot.py index 9c3a09fc83..2135feff72 100644 --- a/tests/functional/examples/voting/test_ballot.py +++ b/tests/functional/examples/voting/test_ballot.py @@ -1,5 +1,7 @@ import pytest +from tests.utils import ZERO_ADDRESS + PROPOSAL_1_NAME = b"Clinton" + b"\x00" * 25 PROPOSAL_2_NAME = b"Trump" + b"\x00" * 27 @@ -11,11 +13,11 @@ def c(get_contract): return get_contract(contract_code, *[[PROPOSAL_1_NAME, PROPOSAL_2_NAME]]) -z0 = "0x0000000000000000000000000000000000000000" +z0 = ZERO_ADDRESS -def test_initial_state(w3, c): - a0 = w3.eth.accounts[0] +def test_initial_state(env, c): + a0 = env.accounts[0] # Check chairperson is msg.sender assert c.chairperson() == a0 # Check propsal names are correct @@ -27,80 +29,77 @@ def test_initial_state(w3, c): # Check voterCount is 0 assert c.voterCount() == 0 # Check voter starts empty - assert c.voters(z0)[2] is None # Voter.delegate - assert c.voters(z0)[3] == 0 # Voter.vote - assert c.voters(z0)[1] is False # Voter.voted - assert c.voters(z0)[0] == 0 # Voter.weight + assert c.voters(z0) == (0, False, ZERO_ADDRESS, 0) -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={}) +def test_give_the_right_to_vote(env, c, tx_failed): + a0, a1, a2, a3, a4, a5 = env.accounts[:6] + c.giveRightToVote(a1) # Check voter given right has weight of 1 assert c.voters(a1)[0] == 1 # Voter.weight # Check no other voter attributes have changed - assert c.voters(a1)[2] is None # Voter.delegate + assert c.voters(a1)[2] == ZERO_ADDRESS # Voter.delegate assert c.voters(a1)[3] == 0 # Voter.vote assert c.voters(a1)[1] is False # Voter.voted # Chairperson can give themselves the right to vote - c.giveRightToVote(a0, transact={}) + c.giveRightToVote(a0) # Check chairperson has weight of 1 assert c.voters(a0)[0] == 1 # Voter.weight # Check voter_acount is 2 assert c.voterCount() == 2 # Check several giving rights to vote - c.giveRightToVote(a2, transact={}) - c.giveRightToVote(a3, transact={}) - c.giveRightToVote(a4, transact={}) - c.giveRightToVote(a5, transact={}) + c.giveRightToVote(a2) + c.giveRightToVote(a3) + c.giveRightToVote(a4) + c.giveRightToVote(a5) # Check voter_acount is now 6 assert c.voterCount() == 6 # Check chairperson cannot give the right to vote twice to the same voter with tx_failed(): - c.giveRightToVote(a5, transact={}) + c.giveRightToVote(a5) # Check voters weight didn't change assert c.voters(a5)[0] == 1 # Voter.weight -def test_forward_weight(w3, c): - a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = w3.eth.accounts[:10] - c.giveRightToVote(a0, transact={}) - c.giveRightToVote(a1, transact={}) - c.giveRightToVote(a2, transact={}) - c.giveRightToVote(a3, transact={}) - c.giveRightToVote(a4, transact={}) - c.giveRightToVote(a5, transact={}) - c.giveRightToVote(a6, transact={}) - c.giveRightToVote(a7, transact={}) - c.giveRightToVote(a8, transact={}) - c.giveRightToVote(a9, transact={}) +def test_forward_weight(env, c): + a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = env.accounts[:10] + c.giveRightToVote(a0) + c.giveRightToVote(a1) + c.giveRightToVote(a2) + c.giveRightToVote(a3) + c.giveRightToVote(a4) + c.giveRightToVote(a5) + c.giveRightToVote(a6) + c.giveRightToVote(a7) + c.giveRightToVote(a8) + c.giveRightToVote(a9) # aN(V) in these comments means address aN has vote weight V - c.delegate(a2, transact={"from": a1}) + c.delegate(a2, sender=a1) # a1(0) -> a2(2) a3(1) - c.delegate(a3, transact={"from": a2}) + c.delegate(a3, sender=a2) # a1(0) -> a2(0) -> a3(3) assert c.voters(a1)[0] == 0 # Voter.weight assert c.voters(a2)[0] == 0 # Voter.weight assert c.voters(a3)[0] == 3 # Voter.weight - c.delegate(a9, transact={"from": a8}) + c.delegate(a9, sender=a8) # a7(1) a8(0) -> a9(2) - c.delegate(a8, transact={"from": a7}) + c.delegate(a8, sender=a7) # a7(0) -> a8(0) -> a9(3) assert c.voters(a7)[0] == 0 # Voter.weight assert c.voters(a8)[0] == 0 # Voter.weight assert c.voters(a9)[0] == 3 # Voter.weight - c.delegate(a7, transact={"from": a6}) - c.delegate(a6, transact={"from": a5}) - c.delegate(a5, transact={"from": a4}) + c.delegate(a7, sender=a6) + c.delegate(a6, sender=a5) + c.delegate(a5, sender=a4) # a4(0) -> a5(0) -> a6(0) -> a7(0) -> a8(0) -> a9(6) assert c.voters(a9)[0] == 6 # Voter.weight assert c.voters(a8)[0] == 0 # Voter.weight # a3(3) a4(0) -> a5(0) -> a6(0) -> a7(0) -> a8(0) -> a9(6) - c.delegate(a4, transact={"from": a3}) + c.delegate(a4, sender=a3) # a3(0) -> a4(0) -> a5(0) -> a6(0) -> a7(0) -> a8(3) -> a9(6) # a3's vote weight of 3 only makes it to a8 in the delegation chain: assert c.voters(a8)[0] == 3 # Voter.weight @@ -108,13 +107,13 @@ def test_forward_weight(w3, c): # call forward_weight again to move the vote weight the # rest of the way: - c.forwardWeight(a8, transact={}) + c.forwardWeight(a8) # a3(0) -> a4(0) -> a5(0) -> a6(0) -> a7(0) -> a8(0) -> a9(9) assert c.voters(a8)[0] == 0 # Voter.weight assert c.voters(a9)[0] == 9 # Voter.weight # a0(1) -> a1(0) -> a2(0) -> a3(0) -> a4(0) -> a5(0) -> a6(0) -> a7(0) -> a8(0) -> a9(9) - c.delegate(a1, transact={"from": a0}) + c.delegate(a1, sender=a0) # a0's vote weight of 1 only makes it to a5 in the delegation chain: # a0(0) -> a1(0) -> a2(0) -> a3(0) -> a4(0) -> a5(1) -> a6(0) -> a7(0) -> a8(0) -> a9(9) assert c.voters(a5)[0] == 1 # Voter.weight @@ -122,46 +121,46 @@ def test_forward_weight(w3, c): # once again call forward_weight to move the vote weight the # rest of the way: - c.forwardWeight(a5, transact={}) + c.forwardWeight(a5) # a0(0) -> a1(0) -> a2(0) -> a3(0) -> a4(0) -> a5(0) -> a6(0) -> a7(0) -> a8(0) -> a9(10) assert c.voters(a5)[0] == 0 # Voter.weight assert c.voters(a9)[0] == 10 # Voter.weight -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={}) - c.giveRightToVote(a2, transact={}) - c.giveRightToVote(a3, transact={}) - c.giveRightToVote(a4, transact={}) - c.giveRightToVote(a5, transact={}) +def test_block_short_cycle(env, c, tx_failed): + a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = env.accounts[:10] + c.giveRightToVote(a0) + c.giveRightToVote(a1) + c.giveRightToVote(a2) + c.giveRightToVote(a3) + c.giveRightToVote(a4) + c.giveRightToVote(a5) - c.delegate(a1, transact={"from": a0}) - c.delegate(a2, transact={"from": a1}) - c.delegate(a3, transact={"from": a2}) - c.delegate(a4, transact={"from": a3}) + c.delegate(a1, sender=a0) + c.delegate(a2, sender=a1) + c.delegate(a3, sender=a2) + c.delegate(a4, sender=a3) # would create a length 5 cycle: with tx_failed(): - c.delegate(a0, transact={"from": a4}) + c.delegate(a0, sender=a4) - c.delegate(a5, transact={"from": a4}) + c.delegate(a5, sender=a4) # can't detect length 6 cycle, so this works: - c.delegate(a0, transact={"from": a5}) + c.delegate(a0, sender=a5) # which is fine for the contract; those votes are simply spoiled. # but this is something the frontend should prevent for user friendliness -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={}) - c.giveRightToVote(a2, transact={}) - c.giveRightToVote(a3, transact={}) +def test_delegate(env, c, tx_failed): + a0, a1, a2, a3, a4, a5, a6 = env.accounts[:7] + c.giveRightToVote(a0) + c.giveRightToVote(a1) + c.giveRightToVote(a2) + c.giveRightToVote(a3) # Voter's weight is 1 assert c.voters(a1)[0] == 1 # Voter.weight # Voter can delegate: a1 -> a0 - c.delegate(a0, transact={"from": a1}) + c.delegate(a0, sender=a1) # Voter's weight is now 0 assert c.voters(a1)[0] == 0 # Voter.weight # Voter has voted @@ -170,34 +169,34 @@ def test_delegate(w3, c, tx_failed): assert c.voters(a0)[0] == 2 # Voter.weight # Voter cannot delegate twice with tx_failed(): - c.delegate(a2, transact={"from": a1}) + c.delegate(a2, sender=a1) # Voter cannot delegate to themselves with tx_failed(): - c.delegate(a2, transact={"from": a2}) + c.delegate(a2, sender=a2) # Voter CAN delegate to someone who hasn't been granted right to vote # Exercise: prevent that - c.delegate(a6, transact={"from": a2}) + c.delegate(a6, sender=a2) # Voter's delegatation is passed up to final delegate, yielding: # a3 -> a1 -> a0 - c.delegate(a1, transact={"from": a3}) + c.delegate(a1, sender=a3) # Delegate's weight is 3 assert c.voters(a0)[0] == 3 # Voter.weight -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={}) - c.giveRightToVote(a2, transact={}) - c.giveRightToVote(a3, transact={}) - c.giveRightToVote(a4, transact={}) - c.giveRightToVote(a5, transact={}) - c.giveRightToVote(a6, transact={}) - c.giveRightToVote(a7, transact={}) - c.delegate(a0, transact={"from": a1}) - c.delegate(a1, transact={"from": a3}) +def test_vote(env, c, tx_failed): + a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = env.accounts[:10] + c.giveRightToVote(a0) + c.giveRightToVote(a1) + c.giveRightToVote(a2) + c.giveRightToVote(a3) + c.giveRightToVote(a4) + c.giveRightToVote(a5) + c.giveRightToVote(a6) + c.giveRightToVote(a7) + c.delegate(a0, sender=a1) + c.delegate(a1, sender=a3) # Voter can vote - c.vote(0, transact={}) + c.vote(0) # Vote count changes based on voters weight assert c.proposals(0)[1] == 3 # Proposal.voteCount # Voter cannot vote twice @@ -205,43 +204,43 @@ def test_vote(w3, c, tx_failed): c.vote(0) # Voter cannot vote if they've delegated with tx_failed(): - c.vote(0, transact={"from": a1}) + c.vote(0, sender=a1) # Several voters can vote - c.vote(1, transact={"from": a4}) - c.vote(1, transact={"from": a2}) - c.vote(1, transact={"from": a5}) - c.vote(1, transact={"from": a6}) + c.vote(1, sender=a4) + c.vote(1, sender=a2) + c.vote(1, sender=a5) + c.vote(1, sender=a6) assert c.proposals(1)[1] == 4 # Proposal.voteCount # Can't vote on a non-proposal with tx_failed(): - c.vote(2, transact={"from": a7}) + c.vote(2, sender=a7) -def test_winning_proposal(w3, c): - a0, a1, a2 = w3.eth.accounts[:3] - c.giveRightToVote(a0, transact={}) - c.giveRightToVote(a1, transact={}) - c.giveRightToVote(a2, transact={}) - c.vote(0, transact={}) +def test_winning_proposal(env, c): + a0, a1, a2 = env.accounts[:3] + c.giveRightToVote(a0) + c.giveRightToVote(a1) + c.giveRightToVote(a2) + c.vote(0) # Proposal 0 is now winning assert c.winningProposal() == 0 - c.vote(1, transact={"from": a1}) + c.vote(1, sender=a1) # Proposal 0 is still winning (the proposals are tied) assert c.winningProposal() == 0 - c.vote(1, transact={"from": a2}) + c.vote(1, sender=a2) # Proposal 2 is now winning assert c.winningProposal() == 1 -def test_winner_namer(w3, c): - a0, a1, a2 = w3.eth.accounts[:3] - c.giveRightToVote(a0, transact={}) - c.giveRightToVote(a1, transact={}) - c.giveRightToVote(a2, transact={}) - c.delegate(a1, transact={"from": a2}) - c.vote(0, transact={}) +def test_winner_namer(env, c): + a0, a1, a2 = env.accounts[:3] + c.giveRightToVote(a0) + c.giveRightToVote(a1) + c.giveRightToVote(a2) + c.delegate(a1, sender=a2) + c.vote(0) # Proposal 0 is now winning assert c.winnerName()[:7] == b"Clinton" - c.vote(1, transact={"from": a1}) + c.vote(1, sender=a1) # Proposal 2 is now winning assert c.winnerName()[:5] == b"Trump" diff --git a/tests/functional/examples/wallet/test_wallet.py b/tests/functional/examples/wallet/test_wallet.py index b9db5acee3..c639974a31 100644 --- a/tests/functional/examples/wallet/test_wallet.py +++ b/tests/functional/examples/wallet/test_wallet.py @@ -2,17 +2,20 @@ from eth_account import Account from eth_account.messages import encode_defunct from eth_keys import KeyAPI -from eth_utils import is_same_address +from eth_utils import is_same_address, to_bytes, to_checksum_address, to_int + +from tests.utils import ZERO_ADDRESS @pytest.fixture -def c(w3, get_contract): - a0, a1, a2, a3, a4, a5, a6 = w3.eth.accounts[:7] +def c(env, get_contract): + a0, a1, a2, a3, a4, a5, a6 = env.accounts[:7] with open("examples/wallet/wallet.vy") as f: code = f.read() # Sends wei to the contract for future transactions gas costs c = get_contract(code, *[[a1, a2, a3, a4, a5], 3]) - w3.eth.send_transaction({"to": c.address, "value": 10**17}) + env.set_balance(a0, 10**17) + env.message_call(c.address, value=10**17) return c @@ -29,12 +32,13 @@ def _sign(seq, to, value, data, key): return _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] +def test_approve(env, c, tx_failed, sign): + a0, a1, a2, a3, a4, a5, a6 = env.accounts[:7] + k0, k1, k2, k3, k4, k5, k6, k7 = env._keys[:8] + env.set_balance(a1, 10**18) to, value, data = b"\x35" * 20, 10**16, b"" - to_address = w3.to_checksum_address(to) + to_address = to_checksum_address(to) def pack_and_sign(seq, *args): sigs = [sign(seq, to, value, data, k) if k else [0, 0, 0] for k in args] @@ -42,35 +46,34 @@ def pack_and_sign(seq, *args): # Legitimate approval sigs = pack_and_sign(0, k1, 0, k3, 0, k5) - c.approve(0, "0x" + to.hex(), value, data, sigs, transact={"value": value, "from": a1}) + c.approve(0, "0x" + to.hex(), value, data, sigs, value=value, sender=a1) # Approve fails if only 2 signatures are given sigs = pack_and_sign(1, k1, 0, k3, 0, 0) with tx_failed(): - c.approve(1, to_address, value, data, sigs, transact={"value": value, "from": a1}) + c.approve(1, to_address, value, data, sigs, value=value, sender=a1) # Approve fails if an invalid signature is given sigs = pack_and_sign(1, k1, 0, k7, 0, k5) with tx_failed(): - c.approve(1, to_address, value, data, sigs, transact={"value": value, "from": a1}) + c.approve(1, to_address, value, data, sigs, value=value, sender=a1) # Approve fails if transaction number is incorrect (the first argument should be 1) sigs = pack_and_sign(0, k1, 0, k3, 0, k5) with tx_failed(): - c.approve(0, to_address, value, data, sigs, transact={"value": value, "from": a1}) + c.approve(0, to_address, value, data, sigs, value=value, sender=a1) # Approve fails if not enough value is sent sigs = pack_and_sign(1, k1, 0, k3, 0, k5) with tx_failed(): - c.approve(1, to_address, value, data, sigs, transact={"value": 0, "from": a1}) + c.approve(1, to_address, value, data, sigs, value=0, sender=a1) sigs = pack_and_sign(1, k1, 0, k3, 0, k5) # this call should succeed - c.approve(1, to_address, value, data, sigs, call={"value": value, "from": a1}) + c.approve(1, to_address, value, data, sigs, value=value, sender=a1) print("Basic tests passed") -def test_javascript_signatures(w3, get_contract): - a3 = w3.eth.accounts[2] +def test_javascript_signatures(env, get_contract, keccak): + a3 = env.accounts[2] # The zero address will cause `approve` to default to valid signatures - zero_address = "0x0000000000000000000000000000000000000000" accounts = [ "0x776ba14735ff84789320718cf0aa43e91f7a8ce1", "0x095ce4e4240fa66ff90282c26847456e3f3b5002", @@ -85,14 +88,14 @@ def test_javascript_signatures(w3, get_contract): # Turns the raw sigs into sigs sigs = [ - (w3.to_int(x[64:]), w3.to_int(x[:32]), w3.to_int(x[32:64])) # v # r # s - for x in map(lambda z: w3.to_bytes(hexstr=z[2:]), raw_sigs) + (to_int(x[64:]), to_int(x[:32]), to_int(x[32:64])) # v # r # s + for x in map(lambda z: to_bytes(hexstr=z[2:]), raw_sigs) ] - h = w3.keccak( + h = keccak( (0).to_bytes(32, "big") + b"\x00" * 12 - + w3.to_bytes(hexstr=recipient[2:]) + + to_bytes(hexstr=recipient[2:]) + (25).to_bytes(32, "big") + b"" ) # noqa: E501 @@ -104,15 +107,12 @@ def test_javascript_signatures(w3, get_contract): # Set the owners to zero addresses with open("examples/wallet/wallet.vy") as f: - owners = [w3.to_checksum_address(x) for x in accounts + [a3, zero_address, zero_address]] + owners = [to_checksum_address(x) for x in accounts + [a3, ZERO_ADDRESS, ZERO_ADDRESS]] x2 = get_contract(f.read(), *[owners, 2]) - w3.eth.send_transaction({"to": x2.address, "value": 10**17}) + env.set_balance(env.deployer, 10**18) + env.message_call(x2.address, value=10**17) # There's no need to pass in signatures because the owners are 0 addresses # causing them to default to valid signatures - x2.approve( - 0, recipient, 25, b"", sigs + [[0, 0, 0]] * 3, call={"to": x2.address, "value": 10**17} - ) - - print("Javascript signature tests passed") + x2.approve(0, recipient, 25, b"", sigs + [[0, 0, 0]] * 3, value=10**17) diff --git a/tests/functional/syntax/test_address_code.py b/tests/functional/syntax/test_address_code.py index 1ef99c2a28..bf1651ef43 100644 --- a/tests/functional/syntax/test_address_code.py +++ b/tests/functional/syntax/test_address_code.py @@ -1,11 +1,9 @@ +import json from typing import Type import pytest -from eth_tester.exceptions import TransactionFailed -from web3 import Web3 from vyper import compiler -from vyper.compiler.settings import Settings from vyper.exceptions import NamespaceCollision, StructureException, VyperException # For reproducibility, use precompiled data of `hello: public(uint256)` using vyper 0.3.1 @@ -15,30 +13,29 @@ PRECOMPILED = bytes.fromhex(PRECOMPILED_BYTECODE_RUNTIME[2:]) -def _deploy_precompiled_contract(w3: Web3): - Precompiled = w3.eth.contract(abi=PRECOMPILED_ABI, bytecode=PRECOMPILED_BYTECODE) - tx_hash = Precompiled.constructor().transact() - tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash) - address = tx_receipt["contractAddress"] - return w3.eth.contract(address=address, abi=PRECOMPILED_ABI) +@pytest.fixture +def precompiled_contract(env): + bytecode = bytes.fromhex(PRECOMPILED_BYTECODE.removeprefix("0x")) + return env.deploy(json.loads(PRECOMPILED_ABI), bytecode) @pytest.mark.parametrize( ("start", "length", "expected"), [(0, 5, PRECOMPILED[:5]), (5, 10, PRECOMPILED[5:][:10])] ) -def test_address_code_slice(start: int, length: int, expected: bytes, w3: Web3, get_contract): +def test_address_code_slice( + start: int, length: int, expected: bytes, precompiled_contract, get_contract +): code = f""" @external def code_slice(x: address) -> Bytes[{length}]: return slice(x.code, {start}, {length}) """ contract = get_contract(code) - precompiled_contract = _deploy_precompiled_contract(w3) actual = contract.code_slice(precompiled_contract.address) assert actual == expected -def test_address_code_runtime_error_slice_too_long(w3: Web3, get_contract): +def test_address_code_runtime_error_slice_too_long(precompiled_contract, get_contract, tx_failed): start = len(PRECOMPILED) - 5 length = 10 code = f""" @@ -47,19 +44,18 @@ def code_slice(x: address) -> Bytes[{length}]: return slice(x.code, {start}, {length}) """ contract = get_contract(code) - precompiled_contract = _deploy_precompiled_contract(w3) - with pytest.raises(TransactionFailed): + with tx_failed(): contract.code_slice(precompiled_contract.address) -def test_address_code_runtime_error_no_code(get_contract): +def test_address_code_runtime_error_no_code(get_contract, tx_failed): code = """ @external def code_slice(x: address) -> Bytes[4]: return slice(x.code, 0, 4) """ contract = get_contract(code) - with pytest.raises(TransactionFailed): + with tx_failed(): contract.code_slice(b"\x00" * 20) @@ -161,7 +157,7 @@ def test_address_code_compile_success(code: str): compiler.compile_code(code) -def test_address_code_self_success(get_contract, optimize, experimental_codegen): +def test_address_code_self_success(get_contract): code = """ code_deployment: public(Bytes[32]) @@ -174,15 +170,12 @@ def code_runtime() -> Bytes[32]: return slice(self.code, 0, 32) """ contract = get_contract(code) - settings = Settings(optimize=optimize, experimental_codegen=experimental_codegen) - code_compiled = compiler.compile_code( - code, output_formats=["bytecode", "bytecode_runtime"], settings=settings - ) + code_compiled = compiler.compile_code(code, output_formats=["bytecode", "bytecode_runtime"]) assert contract.code_deployment() == bytes.fromhex(code_compiled["bytecode"][2:])[:32] assert contract.code_runtime() == bytes.fromhex(code_compiled["bytecode_runtime"][2:])[:32] -def test_address_code_self_runtime_error_deployment(get_contract): +def test_address_code_self_runtime_error_deployment(get_contract, tx_failed): code = """ dummy: public(Bytes[1000000]) @@ -190,16 +183,16 @@ def test_address_code_self_runtime_error_deployment(get_contract): def __init__(): self.dummy = slice(self.code, 0, 1000000) """ - with pytest.raises(TransactionFailed): + with tx_failed(): get_contract(code) -def test_address_code_self_runtime_error_runtime(get_contract): +def test_address_code_self_runtime_error_runtime(get_contract, tx_failed): code = """ @external def code_runtime() -> Bytes[1000000]: return slice(self.code, 0, 1000000) """ contract = get_contract(code) - with pytest.raises(TransactionFailed): + with tx_failed(): contract.code_runtime() diff --git a/tests/functional/syntax/test_as_wei_value.py b/tests/functional/syntax/test_as_wei_value.py index 40562530d1..6d394e763d 100644 --- a/tests/functional/syntax/test_as_wei_value.py +++ b/tests/functional/syntax/test_as_wei_value.py @@ -127,5 +127,5 @@ def foo(): @pytest.mark.parametrize("good_code", valid_list) -def test_as_wei_success(good_code, get_contract_with_gas_estimation): - assert get_contract_with_gas_estimation(good_code) is not None +def test_as_wei_success(good_code, get_contract): + assert get_contract(good_code) is not None diff --git a/tests/functional/syntax/test_bool.py b/tests/functional/syntax/test_bool.py index fef40406b6..1b224af253 100644 --- a/tests/functional/syntax/test_bool.py +++ b/tests/functional/syntax/test_bool.py @@ -152,13 +152,13 @@ def test_bool_success(good_code): ], ) @pytest.mark.parametrize("op", ["==", "!="]) -def test_empty_string_comparison(get_contract_with_gas_estimation, length, value, result, op): +def test_empty_string_comparison(get_contract, length, value, result, op): contract = f""" @external def foo(xs: String[{length}]) -> bool: return xs {op} "" """ - c = get_contract_with_gas_estimation(contract) + c = get_contract(contract) if op == "==": assert c.foo(value) == result elif op == "!=": @@ -179,13 +179,13 @@ def foo(xs: String[{length}]) -> bool: ], ) @pytest.mark.parametrize("op", ["==", "!="]) -def test_empty_bytes_comparison(get_contract_with_gas_estimation, length, value, result, op): +def test_empty_bytes_comparison(get_contract, length, value, result, op): contract = f""" @external def foo(xs: Bytes[{length}]) -> bool: return b"" {op} xs """ - c = get_contract_with_gas_estimation(contract) + c = get_contract(contract) if op == "==": assert c.foo(value) == result elif op == "!=": diff --git a/tests/functional/syntax/test_bool_ops.py b/tests/functional/syntax/test_bool_ops.py index 86a3578e2e..78f9e4a6cc 100644 --- a/tests/functional/syntax/test_bool_ops.py +++ b/tests/functional/syntax/test_bool_ops.py @@ -1,4 +1,4 @@ -def test_convert_from_bool(get_contract_with_gas_estimation): +def test_convert_from_bool(get_contract): code = """ @external def foo() -> bool: @@ -31,7 +31,7 @@ def oofrab() -> bool: return val """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() is False assert c.bar() is True assert c.foobar() is False diff --git a/tests/functional/syntax/test_chainid.py b/tests/functional/syntax/test_chainid.py index 3ff540f212..5950218c71 100644 --- a/tests/functional/syntax/test_chainid.py +++ b/tests/functional/syntax/test_chainid.py @@ -81,12 +81,12 @@ def test_chain_success(good_code): assert compiler.compile_code(good_code) is not None -def test_chainid_operation(get_contract_with_gas_estimation): +def test_chainid_operation(get_contract, env): code = """ @external @view def get_chain_id() -> uint256: return chain.id """ - c = get_contract_with_gas_estimation(code) - assert c.get_chain_id() == 131277322940537 # Default value of py-evm + c = get_contract(code) + assert c.get_chain_id() == env.DEFAULT_CHAIN_ID diff --git a/tests/functional/syntax/test_codehash.py b/tests/functional/syntax/test_codehash.py index 7aa01a68e9..b2463025c2 100644 --- a/tests/functional/syntax/test_codehash.py +++ b/tests/functional/syntax/test_codehash.py @@ -1,9 +1,8 @@ from vyper.compiler import compile_code -from vyper.compiler.settings import Settings from vyper.utils import keccak256 -def test_get_extcodehash(get_contract, optimize, experimental_codegen): +def test_get_extcodehash(get_contract): code = """ a: address @@ -28,8 +27,7 @@ def foo3() -> bytes32: def foo4() -> bytes32: return self.a.codehash """ - settings = Settings(optimize=optimize, experimental_codegen=experimental_codegen) - compiled = compile_code(code, output_formats=["bytecode_runtime"], settings=settings) + compiled = compile_code(code, output_formats=["bytecode_runtime"]) bytecode = bytes.fromhex(compiled["bytecode_runtime"][2:]) hash_ = keccak256(bytecode) diff --git a/tests/functional/syntax/test_concat.py b/tests/functional/syntax/test_concat.py index 8431e5ecf2..0efc8e5a53 100644 --- a/tests/functional/syntax/test_concat.py +++ b/tests/functional/syntax/test_concat.py @@ -89,8 +89,8 @@ def large_output(a: String[33], b: String[33], reverse=True) -> String[64]: @pytest.mark.parametrize("bad_code,exc", fail_list) -def test_block_fail(assert_compile_failed, get_contract_with_gas_estimation, bad_code, exc): - assert_compile_failed(lambda: get_contract_with_gas_estimation(bad_code), exc) +def test_block_fail(assert_compile_failed, get_contract, bad_code, exc): + assert_compile_failed(lambda: get_contract(bad_code), exc) valid_list = [ diff --git a/tests/functional/syntax/test_extract32.py b/tests/functional/syntax/test_extract32.py index caec38e5d1..4768357c83 100644 --- a/tests/functional/syntax/test_extract32.py +++ b/tests/functional/syntax/test_extract32.py @@ -48,8 +48,8 @@ def foo(inp: Bytes[32]) -> bool: @pytest.mark.parametrize("bad_code,exc", fail_list) -def test_extract32_fail(assert_compile_failed, get_contract_with_gas_estimation, bad_code, exc): - assert_compile_failed(lambda: get_contract_with_gas_estimation(bad_code), exc) +def test_extract32_fail(assert_compile_failed, get_contract, bad_code, exc): + assert_compile_failed(lambda: get_contract(bad_code), exc) valid_list = [ @@ -80,5 +80,5 @@ def foo() -> uint256: @pytest.mark.parametrize("good_code", valid_list) -def test_extract32_success(get_contract_with_gas_estimation, good_code): - assert get_contract_with_gas_estimation(good_code) is not None +def test_extract32_success(get_contract, good_code): + assert get_contract(good_code) is not None diff --git a/tests/functional/syntax/test_msg_data.py b/tests/functional/syntax/test_msg_data.py index 20ec9382ec..a2cf022f21 100644 --- a/tests/functional/syntax/test_msg_data.py +++ b/tests/functional/syntax/test_msg_data.py @@ -1,12 +1,12 @@ import pytest -from eth_tester.exceptions import TransactionFailed +from eth_utils import to_bytes from vyper import compiler from vyper.exceptions import StructureException, TypeMismatch from vyper.utils import method_id -def test_variable_assignment(get_contract, keccak): +def test_variable_assignment(get_contract): code = """ @external def foo() -> Bytes[4]: @@ -31,7 +31,7 @@ def foo(_value: uint256) -> uint256: assert contract.foo(42) == 42 -def test_get_full_calldata(get_contract, keccak, w3): +def test_get_full_calldata(get_contract): code = """ @external def foo(bar: uint256) -> Bytes[36]: @@ -41,9 +41,9 @@ def foo(bar: uint256) -> Bytes[36]: contract = get_contract(code) # 2fbebd38000000000000000000000000000000000000000000000000000000000000002a - selector_hex = method_id("foo(uint256)") # 2fbebd38 - encoded_42 = (42).to_bytes(32, "big") - expected_result = selector_hex + encoded_42 + foo_method_id = method_id("foo(uint256)") # 2fbebd38 + encoded_42 = to_bytes(42) # 2a + expected_result = foo_method_id + b"\0" * 31 + encoded_42 assert contract.foo(42) == expected_result @@ -73,10 +73,10 @@ def foo() -> (uint256, Bytes[4], uint256): """ contract = get_contract(code) - assert contract.foo() == [2**256 - 1, method_id("foo()"), 2**256 - 1] + assert contract.foo() == (2**256 - 1, method_id("foo()"), 2**256 - 1) -def test_assignment_to_storage(w3, get_contract, keccak): +def test_assignment_to_storage(get_contract, keccak): code = """ cache: public(Bytes[4]) @@ -84,10 +84,8 @@ def test_assignment_to_storage(w3, get_contract, keccak): def foo(): self.cache = slice(msg.data, 0, 4) """ - acct = w3.eth.accounts[0] contract = get_contract(code) - - contract.foo(transact={"from": acct}) + contract.foo() assert contract.cache() == method_id("foo()") @@ -158,7 +156,7 @@ def test_invalid_usages_compile_error(bad_code): compiler.compile_code(bad_code[0]) -def test_runtime_failure_bounds_check(get_contract): +def test_runtime_failure_bounds_check(get_contract, tx_failed): code = """ @external def foo(_value: uint256) -> uint256: @@ -167,6 +165,5 @@ def foo(_value: uint256) -> uint256: """ contract = get_contract(code) - - with pytest.raises(TransactionFailed): + with tx_failed(): contract.foo(42) diff --git a/tests/functional/syntax/test_no_none.py b/tests/functional/syntax/test_no_none.py index ebe32816bd..14b1155887 100644 --- a/tests/functional/syntax/test_no_none.py +++ b/tests/functional/syntax/test_no_none.py @@ -1,7 +1,7 @@ from vyper.exceptions import InvalidLiteral, SyntaxException -def test_no_none_assign(assert_compile_failed, get_contract_with_gas_estimation): +def test_no_none_assign(assert_compile_failed, get_contract): contracts = [ # noqa: E122 """ @external @@ -72,12 +72,10 @@ def foo(): ] for contract in contracts: - assert_compile_failed( - lambda c=contract: get_contract_with_gas_estimation(c), InvalidLiteral - ) + assert_compile_failed(lambda c=contract: get_contract(c), InvalidLiteral) -def test_no_is_none(assert_compile_failed, get_contract_with_gas_estimation): +def test_no_is_none(assert_compile_failed, get_contract): contracts = [ # noqa: E122 """ @external @@ -118,12 +116,10 @@ def foo(): ] for contract in contracts: - assert_compile_failed( - lambda c=contract: get_contract_with_gas_estimation(c), SyntaxException - ) + assert_compile_failed(lambda c=contract: get_contract(c), SyntaxException) -def test_no_eq_none(assert_compile_failed, get_contract_with_gas_estimation): +def test_no_eq_none(assert_compile_failed, get_contract): contracts = [ # noqa: E122 """ @external @@ -164,12 +160,10 @@ def foo(): ] for contract in contracts: - assert_compile_failed( - lambda c=contract: get_contract_with_gas_estimation(c), InvalidLiteral - ) + assert_compile_failed(lambda c=contract: get_contract(c), InvalidLiteral) -def test_struct_none(assert_compile_failed, get_contract_with_gas_estimation): +def test_struct_none(assert_compile_failed, get_contract): contracts = [ # noqa: E122 """ struct Mom: @@ -201,6 +195,4 @@ def foo(): ] for contract in contracts: - assert_compile_failed( - lambda c=contract: get_contract_with_gas_estimation(c), InvalidLiteral - ) + assert_compile_failed(lambda c=contract: get_contract(c), InvalidLiteral) diff --git a/tests/functional/syntax/test_return_tuple.py b/tests/functional/syntax/test_return_tuple.py index 52640b883e..5364cc9206 100644 --- a/tests/functional/syntax/test_return_tuple.py +++ b/tests/functional/syntax/test_return_tuple.py @@ -34,7 +34,7 @@ def foo() -> (uint256, uint256, uint256, uint256, uint256): c = get_contract(code) - assert c.foo() == [1, 2, 3, 4, 5] + assert c.foo() == (1, 2, 3, 4, 5) def test_call_in_call(get_contract): @@ -55,7 +55,7 @@ def foo() -> (uint256, uint256, uint256, uint256, uint256): c = get_contract(code) - assert c.foo() == [1, 2, 3, 4, 5] + assert c.foo() == (1, 2, 3, 4, 5) def test_nested_calls_in_tuple_return(get_contract): @@ -86,7 +86,7 @@ def foo() -> (uint256, uint256, uint256, uint256, uint256): c = get_contract(code) - assert c.foo() == [1, 2, 3, 4, 5] + assert c.foo() == (1, 2, 3, 4, 5) def test_external_call_in_return_tuple(get_contract): @@ -109,7 +109,7 @@ def foo(a: address) -> (uint256, uint256, uint256, uint256, uint256): c = get_contract(code) c2 = get_contract(code2) - assert c2.foo(c.address) == [1, 2, 3, 4, 5] + assert c2.foo(c.address) == (1, 2, 3, 4, 5) def test_nested_external_call_in_return_tuple(get_contract): @@ -144,7 +144,7 @@ def foo(a: address) -> (uint256, uint256, uint256, uint256, uint256): c = get_contract(code) c2 = get_contract(code2) - assert c2.foo(c.address) == [1, 2, 3, 4, 5] + assert c2.foo(c.address) == (1, 2, 3, 4, 5) def test_single_type_tuple_int(get_contract): @@ -162,8 +162,8 @@ def foo2(a: int128, b: int128) -> (int128[5], int128, int128[2]): c = get_contract(code) - assert c.foo() == [[1, 2, 3], 4, [[5, 6], [7, 8]]] - assert c.foo2(4, 6) == [[1, 2, 3, 4, 5], 6, [7, 8]] + assert c.foo() == ([1, 2, 3], 4, [[5, 6], [7, 8]]) + assert c.foo2(4, 6) == ([1, 2, 3, 4, 5], 6, [7, 8]) def test_single_type_tuple_address(get_contract): @@ -179,13 +179,13 @@ def foo() -> (address, address[2]): c = get_contract(code) - assert c.foo() == [ + assert c.foo() == ( c.address, [ "0xF5D4020dCA6a62bB1efFcC9212AAF3c9819E30D7", "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF", ], - ] + ) def test_single_type_tuple_bytes(get_contract): @@ -198,4 +198,4 @@ def foo() -> (Bytes[5], Bytes[5]): c = get_contract(code) - assert c.foo() == [b"hello", b"there"] + assert c.foo() == (b"hello", b"there") diff --git a/tests/functional/syntax/test_self_balance.py b/tests/functional/syntax/test_self_balance.py index 4f844088f6..0da491b262 100644 --- a/tests/functional/syntax/test_self_balance.py +++ b/tests/functional/syntax/test_self_balance.py @@ -1,7 +1,7 @@ from vyper import compiler -def test_self_balance(w3, get_contract_with_gas_estimation): +def test_self_balance(env, get_contract): code = """ @external @view @@ -17,7 +17,10 @@ def __default__(): opcodes = compiler.compile_code(code, output_formats=["opcodes"])["opcodes"] assert "SELFBALANCE" in opcodes - c = get_contract_with_gas_estimation(code) - w3.eth.send_transaction({"to": c.address, "value": 1337}) + c = get_contract(code) + env.set_balance(env.deployer, 1337) + env.message_call(c.address, value=1337) assert c.get_balance() == 1337 + assert env.get_balance(c.address) == 1337 + assert env.get_balance(env.deployer) == 0 diff --git a/tests/functional/syntax/test_string.py b/tests/functional/syntax/test_string.py index 6252011bd9..77cb7eaee6 100644 --- a/tests/functional/syntax/test_string.py +++ b/tests/functional/syntax/test_string.py @@ -54,5 +54,5 @@ def foo(): @pytest.mark.parametrize("bad_code,exc", invalid_list) -def test_string_fail(assert_compile_failed, get_contract_with_gas_estimation, bad_code, exc): - assert_compile_failed(lambda: get_contract_with_gas_estimation(bad_code), exc) +def test_string_fail(assert_compile_failed, get_contract, bad_code, exc): + assert_compile_failed(lambda: get_contract(bad_code), exc) diff --git a/tests/unit/cli/vyper_json/test_compile_json.py b/tests/unit/cli/vyper_json/test_compile_json.py index 62a799db65..82c332d185 100644 --- a/tests/unit/cli/vyper_json/test_compile_json.py +++ b/tests/unit/cli/vyper_json/test_compile_json.py @@ -72,7 +72,7 @@ def oopsie(a: uint256) -> bool: @pytest.fixture(scope="function") -def input_json(): +def input_json(optimize, evm_version, experimental_codegen): return { "language": "Vyper", "sources": { @@ -81,7 +81,12 @@ def input_json(): "contracts/bar.vy": {"content": BAR_CODE}, }, "interfaces": {"contracts/ibar.json": {"abi": BAR_ABI}}, - "settings": {"outputSelection": {"*": ["*"]}}, + "settings": { + "outputSelection": {"*": ["*"]}, + "optimize": optimize.name.lower(), + "evmVersion": evm_version, + "experimentalCodegen": experimental_codegen, + }, } diff --git a/tests/unit/compiler/test_bytecode_runtime.py b/tests/unit/compiler/test_bytecode_runtime.py index 64cee3a75c..213adce017 100644 --- a/tests/unit/compiler/test_bytecode_runtime.py +++ b/tests/unit/compiler/test_bytecode_runtime.py @@ -124,13 +124,11 @@ def test_bytecode_signature_immutables(): # check that deployed bytecode actually matches the cbor metadata @pytest.mark.parametrize("code", [simple_contract_code, has_immutables, many_functions]) -def test_bytecode_signature_deployed(code, get_contract, w3): +def test_bytecode_signature_deployed(code, get_contract, env): c = get_contract(code) - deployed_code = w3.eth.get_code(c.address) + deployed_code = env.get_code(c.address) - initcode = c._classic_contract.bytecode - - metadata = _parse_cbor_metadata(initcode) + metadata = _parse_cbor_metadata(c.bytecode) runtime_len, data_section_lengths, immutables_len, compiler = metadata assert compiler == {"vyper": list(vyper.version.version_tuple)} diff --git a/tests/unit/compiler/test_source_map.py b/tests/unit/compiler/test_source_map.py index 04bd141185..e4d5e69770 100644 --- a/tests/unit/compiler/test_source_map.py +++ b/tests/unit/compiler/test_source_map.py @@ -2,6 +2,7 @@ from vyper.compiler import compile_code from vyper.compiler.output import _compress_source_map +from vyper.compiler.settings import OptimizationLevel from vyper.compiler.utils import expand_source_map TEST_CODE = """ @@ -31,20 +32,30 @@ def foo(a: uint256) -> int128: """ -def test_jump_map(): +def test_jump_map(optimize): source_map = compile_code(TEST_CODE, output_formats=["source_map"])["source_map"] pos_map = source_map["pc_pos_map"] jump_map = source_map["pc_jump_map"] - assert len([v for v in jump_map.values() if v == "o"]) == 1 + expected_jumps = 1 + if optimize == OptimizationLevel.NONE: + expected_jumps = 3 # some jumps get optimized out when optimizer is on + + assert len([v for v in jump_map.values() if v == "o"]) == expected_jumps assert len([v for v in jump_map.values() if v == "i"]) == 2 code_lines = [i + "\n" for i in TEST_CODE.split("\n")] for pc in [k for k, v in jump_map.items() if v == "o"]: + if pc not in pos_map: + assert optimize == OptimizationLevel.NONE + continue # some jump is not being optimized out lineno, col_offset, _, end_col_offset = pos_map[pc] assert code_lines[lineno - 1][col_offset:end_col_offset].startswith("return") for pc in [k for k, v in jump_map.items() if v == "i"]: + if pc not in pos_map: + assert optimize == OptimizationLevel.NONE + continue # some jump is not being optimized out lineno, col_offset, _, end_col_offset = pos_map[pc] assert code_lines[lineno - 1][col_offset:end_col_offset].startswith("self.") diff --git a/tests/utils.py b/tests/utils.py index badbb2545e..8548c4f47a 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -6,6 +6,8 @@ from vyper.semantics.analysis.constant_folding import constant_fold from vyper.utils import DECIMAL_EPSILON, round_towards_zero +ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" + @contextlib.contextmanager def working_directory(directory): diff --git a/vyper/cli/vyper_json.py b/vyper/cli/vyper_json.py index 8f39eb55e6..71b0c6a1b3 100755 --- a/vyper/cli/vyper_json.py +++ b/vyper/cli/vyper_json.py @@ -262,6 +262,7 @@ def compile_from_input_dict( evm_version = get_evm_version(input_dict) optimize = input_dict["settings"].get("optimize") + experimental_codegen = input_dict["settings"].get("experimentalCodegen", False) if isinstance(optimize, bool): # bool optimization level for backwards compatibility warnings.warn( @@ -274,7 +275,9 @@ def compile_from_input_dict( else: assert optimize is None - settings = Settings(evm_version=evm_version, optimize=optimize) + settings = Settings( + evm_version=evm_version, optimize=optimize, experimental_codegen=experimental_codegen + ) no_bytecode_metadata = not input_dict["settings"].get("bytecodeMetadata", True) diff --git a/vyper/compiler/__init__.py b/vyper/compiler/__init__.py index 835877e124..47e2054bd8 100644 --- a/vyper/compiler/__init__.py +++ b/vyper/compiler/__init__.py @@ -1,14 +1,12 @@ -from collections import OrderedDict from pathlib import Path -from typing import Any, Callable, Dict, Optional, Sequence, Union +from typing import Callable, Dict, Optional -import vyper.ast as vy_ast # break an import cycle import vyper.codegen.core as codegen import vyper.compiler.output as output from vyper.compiler.input_bundle import FileInput, InputBundle, PathLike from vyper.compiler.phases import CompilerData -from vyper.compiler.settings import Settings, anchor_settings -from vyper.typing import ContractPath, OutputFormats, StorageLayout +from vyper.compiler.settings import Settings, anchor_settings, get_global_settings +from vyper.typing import OutputFormats, StorageLayout OUTPUT_FORMATS = { # requires vyper_module @@ -95,7 +93,7 @@ def compile_from_file_input( Dict Compiler output as `{'output key': "output data"}` """ - settings = settings or Settings() + settings = settings or get_global_settings() or Settings() if output_formats is None: output_formats = ("bytecode",)