From 5a7082610eaf5b3410f654fa780187f230d93349 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 8 Mar 2024 13:30:06 +0100 Subject: [PATCH 01/87] First tests with pyrevm --- setup.py | 1 + tests/conftest.py | 14 + tests/functional/builtins/folding/conftest.py | 6 + .../builtins/codegen => revm}/__init__.py | 0 tests/revm/abi.py | 47 +++ tests/revm/abi_contract.py | 345 ++++++++++++++++++ tests/revm/base_evm_contract.py | 47 +++ tests/revm/revm_env.py | 104 ++++++ tests/revm/vm_utils.py | 18 + 9 files changed, 582 insertions(+) create mode 100644 tests/functional/builtins/folding/conftest.py rename tests/{functional/builtins/codegen => revm}/__init__.py (100%) create mode 100644 tests/revm/abi.py create mode 100644 tests/revm/abi_contract.py create mode 100644 tests/revm/base_evm_contract.py create mode 100644 tests/revm/revm_env.py create mode 100644 tests/revm/vm_utils.py diff --git a/setup.py b/setup.py index f5d643ad88..f144214556 100644 --- a/setup.py +++ b/setup.py @@ -20,6 +20,7 @@ "lark==1.1.2", "hypothesis[lark]>=5.37.1,<6.0", "eth-stdlib==0.2.6", + "pyrevm==0.2.1", ], "lint": [ "black==23.12.0", diff --git a/tests/conftest.py b/tests/conftest.py index 54c8549867..b64e19588b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -15,6 +15,7 @@ from web3.contract import Contract from web3.providers.eth_tester import EthereumTesterProvider +from tests.revm.revm_env import RevmEnv from tests.utils import working_directory from vyper import compiler from vyper.ast.grammar import parse_vyper_source @@ -157,6 +158,11 @@ def tester(): return EthereumTester(backend=backend) +@pytest.fixture(scope="module") +def revm_env(): + return RevmEnv() + + def zero_gas_price_strategy(web3, transaction_params=None): return 0 # zero gas price makes testing simpler. @@ -340,6 +346,14 @@ def fn(source_code, *args, **kwargs): return fn +@pytest.fixture(scope="module") +def get_revm_contract(revm_env, optimize, output_formats): + def fn(source_code, *args, **kwargs): + return revm_env.deploy_source(source_code, optimize, output_formats, *args, **kwargs) + + return fn + + @pytest.fixture def get_contract_with_gas_estimation(tester, w3, optimize, output_formats): def get_contract_with_gas_estimation(source_code, *args, **kwargs): diff --git a/tests/functional/builtins/folding/conftest.py b/tests/functional/builtins/folding/conftest.py new file mode 100644 index 0000000000..c7174d14fd --- /dev/null +++ b/tests/functional/builtins/folding/conftest.py @@ -0,0 +1,6 @@ +import pytest + + +@pytest.fixture(scope="module") +def get_contract(get_revm_contract): + return get_revm_contract diff --git a/tests/functional/builtins/codegen/__init__.py b/tests/revm/__init__.py similarity index 100% rename from tests/functional/builtins/codegen/__init__.py rename to tests/revm/__init__.py diff --git a/tests/revm/abi.py b/tests/revm/abi.py new file mode 100644 index 0000000000..ad848e1f2b --- /dev/null +++ b/tests/revm/abi.py @@ -0,0 +1,47 @@ +# wrapper module around whatever encoder we are using +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, BytesNode +from eth.codecs.abi.parser import Parser + +_parsers: dict[str, ABITypeNode] = {} + + +class _Encoder(Encoder): + """ + Custom encoder that parses bytes from hex to bytes + """ + + @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) + + +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/revm/abi_contract.py b/tests/revm/abi_contract.py new file mode 100644 index 0000000000..2e267fd4b6 --- /dev/null +++ b/tests/revm/abi_contract.py @@ -0,0 +1,345 @@ +from collections import defaultdict +from functools import cached_property +from os.path import basename +from typing import TYPE_CHECKING, Any, Optional, Union +from warnings import warn + +from eth.abc import ComputationAPI + +from vyper.semantics.analysis.base import FunctionVisibility, StateMutability +from vyper.utils import method_id + +from .abi import ABIError, abi_decode, abi_encode, is_abi_encodable +from .base_evm_contract import BoaError, StackTrace, _handle_child_trace + +if TYPE_CHECKING: + from tests.revm.revm_env import RevmEnv + + +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: + return self._abi["name"] + + @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 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.signature}" + + @property + def pretty_signature(self) -> str: + return f"{self.name}{self.signature} -> {self.return_type}" + + @cached_property + def method_id(self) -> bytes: + return method_id(self.name + self.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 _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( + f"Bad args to `{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.signature}`. Passed {args} {kwargs}" + raise TypeError(error) + + def __call__(self, *args, value=0, gas=None, sender=None, transact=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 + + args = self._merge_kwargs(*args, **kwargs) + computation = self.contract.env.execute_code( + to_address=self.contract.address, + sender=sender, + data=self.method_id + abi_encode(self.signature, args), + value=value, + gas=gas, + is_modifying=self.is_mutable, + contract=self.contract, + ) + + match self.contract.marshal_to_python(computation, self.return_type): + case (): + return None + case (single,): + return single + case multiple: + return tuple(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, + transact=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, transact=transact, **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.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) -> str: + assert self._address is not None + return self._address + + def __init__( + self, + env: "RevmEnv", + name: str, + abi: dict, + functions: list[ABIFunction], + address: str, + 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._bytecode = self.env.get_code(address) + if not self._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 + + @cached_property + def method_id_map(self): + """ + Returns a mapping from method id to function object. + This is used to create the stack trace when an error occurs. + """ + return {function.method_id: function for function in self._functions} + + def handle_error(self, computation): + raise BoaError(self.stack_trace(computation)) + + def marshal_to_python(self, computation, abi_type: list[str]) -> tuple[Any, ...]: + """ + Convert the output of a contract call to a Python object. + :param computation: the computation object returned by `execute_code` + :param abi_type: the ABI type of the return value. + """ + # when there's no contract in the address, the computation output is empty + # if computation.is_error: + # return self.handle_error(computation) + + schema = f"({_format_abi_type(abi_type)})" + try: + return abi_decode(schema, computation) + except ABIError as e: + raise BoaError(self.stack_trace(computation)) from e + + def stack_trace(self, computation: ComputationAPI) -> StackTrace: + """ + Create a stack trace for a failed contract call. + """ + calldata_method_id = bytes(computation.msg.data[:4]) + if calldata_method_id in self.method_id_map: + function = self.method_id_map[calldata_method_id] + msg = f" ({self}.{function.pretty_signature})" + else: + # Method might not be specified in the ABI + msg = f" (unknown method id {self}.0x{calldata_method_id.hex()})" + + return_trace = StackTrace([msg]) + return _handle_child_trace(computation, self.env, return_trace) + + @property + def deployer(self) -> "ABIContractFactory": + """ + Returns a factory that can be used to retrieve another deployed contract. + """ + return ABIContractFactory(self._name, self.abi, self._functions) + + def __repr__(self): + file_str = f" (file {self.filename})" if self.filename else "" + warn_str = "" if self._bytecode else " (WARNING: no bytecode at this address!)" + return f"<{self._name} interface at {self.address}{warn_str}>{file_str}" + + +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"], filename: Optional[str] = None + ): + self._name = name + self._abi = abi + self._functions = functions + self._filename = filename + + @classmethod + def from_abi_dict(cls, abi, name=""): + functions = [ABIFunction(item, name) for item in abi if item.get("type") == "function"] + return cls(basename(name), abi, functions, filename=name) + + def at(self, env, address: str) -> ABIContract: + """ + Create an ABI contract object for a deployed contract at `address`. + """ + contract = ABIContract(env, self._name, self._abi, self._functions, address, self._filename) + env.register_contract(address, contract) + return contract + + +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"] == "tuple": + return f"({components})" + if abi["type"] == "tuple[]": + return f"({components})[]" + 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/revm/base_evm_contract.py b/tests/revm/base_evm_contract.py new file mode 100644 index 0000000000..5d171752a2 --- /dev/null +++ b/tests/revm/base_evm_contract.py @@ -0,0 +1,47 @@ +from dataclasses import dataclass + + +class StackTrace(list): + def __str__(self): + return "\n\n".join(str(x) for x in self) + + @property + def last_frame(self): + return self[-1] + + +def _trace_for_unknown_contract(computation, env): + ret = StackTrace( + [f""] + ) + return _handle_child_trace(computation, env, ret) + + +def _handle_child_trace(computation, env, return_trace): + if len(computation.children) == 0: + return return_trace + if not computation.children[-1].is_error: + return return_trace + child = computation.children[-1] + + child_obj = env.lookup_contract(child.msg.code_address) + + if child_obj is None: + child_trace = _trace_for_unknown_contract(child, env) + else: + child_trace = child_obj.stack_trace(child) + return StackTrace(child_trace + return_trace) + + +@dataclass +class BoaError(Exception): + stack_trace: StackTrace + + def __str__(self): + frame = self.stack_trace[-1] + if hasattr(frame, "vm_error"): + err = frame.vm_error + err.args = (frame.pretty_vm_reason, *err.args[1:]) + else: + err = frame + return f"{err}\n\n{self.stack_trace}" diff --git a/tests/revm/revm_env.py b/tests/revm/revm_env.py new file mode 100644 index 0000000000..b7aa70fef1 --- /dev/null +++ b/tests/revm/revm_env.py @@ -0,0 +1,104 @@ +import json +from typing import Callable + +from eth_account import Account +from eth_tester.backends.pyevm.main import get_default_account_keys +from eth_tester.exceptions import TransactionFailed +from eth_typing import HexAddress +from eth_utils import to_checksum_address +from pyrevm import EVM, BlockEnv, Env + +from tests.revm.abi_contract import ABIContract, ABIContractFactory +from vyper.ast.grammar import parse_vyper_source +from vyper.compiler import CompilerData, Settings, compile_code +from vyper.compiler.settings import OptimizationLevel + + +class RevmEnv: + def __init__(self) -> None: + self.block = BlockEnv(timestamp=100, prevrandao=bytes([0] * 32)) + self.env = Env(block=self.block) + self.evm = EVM(env=self.env) + self.bytecode: dict[HexAddress, str] = {} + self.contracts: dict[HexAddress, ABIContract] = {} + self._accounts: list[Account] = get_default_account_keys() + + @property + def deployer(self) -> HexAddress: + return self._accounts[0].public_key.to_checksum_address() + + def execute_code( + self, + to_address: str, + sender: str, + data: bytes, + value: bytes, + gas: int, + is_modifying: bool, + contract: "ABIContract", + ): + try: + output = self.evm.call_raw( + to=to_address, + caller=sender, + data=data, + value=value, + # gas=gas, + # is_modifying=self.is_mutable, + # contract=self.contract, + ) + return bytes(output) + except RuntimeError as e: + assert e.args == ("Revert",), f"Expected revert, got {e.args}" + raise TransactionFailed() + + def get_code(self, address: str): + return self.bytecode[address] + + def register_contract(self, address: str, contract: "ABIContract"): + self.contracts[address] = contract + + def deploy_source( + self, + source_code: str, + optimize: OptimizationLevel, + output_formats: dict[str, Callable[[CompilerData], str]], + *args, + override_opt_level=None, + input_bundle=None, + **kwargs, + ) -> ABIContract: + out = compile_code( + source_code, + # test that all output formats can get generated + output_formats=output_formats, + settings=Settings( + evm_version=kwargs.pop("evm_version", None), + optimize=override_opt_level or optimize, + ), + 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 + + abi = out["abi"] + bytecode = out["bytecode"] + value = kwargs.pop("value_in_eth", 0) * 10**18 # Handle deploying with an eth value. + + return self.deploy(abi, bytecode, value, *args, **kwargs) + + def deploy(self, abi: list[dict], bytecode: str, value: int, *args, **kwargs): + factory = ABIContractFactory.from_abi_dict(abi=abi) + # Deploy the contract + deployed_at = self.evm.deploy( + deployer=self.deployer, + code=list(bytes.fromhex(bytecode[2:])), + value=value, + _abi=json.dumps(abi), + ) + address = to_checksum_address(deployed_at) + self.bytecode[address] = bytecode + # tx_info = {"from": self.deployer, "value": value, "gasPrice": 0, **kwargs} + return factory.at(self, address) diff --git a/tests/revm/vm_utils.py b/tests/revm/vm_utils.py new file mode 100644 index 0000000000..0cb3ed4754 --- /dev/null +++ b/tests/revm/vm_utils.py @@ -0,0 +1,18 @@ +def ceil32(n): + return floor32(n + 31) + + +def floor32(n): + return n & ~31 + + +def to_int(stack_item) -> int: + if isinstance(stack_item, int): + return stack_item + return int.from_bytes(stack_item, "big") + + +def to_bytes(stack_item) -> bytes: + if isinstance(stack_item, bytes): + return stack_item.rjust(32, b"\x00") + return stack_item.to_bytes(32, "big") From f0d8b745f291a51a7df334c27696dbb7733fbaac Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 8 Mar 2024 17:56:35 +0100 Subject: [PATCH 02/87] Fix some pyrevm tests --- setup.py | 2 +- tests/conftest.py | 16 ++++--- .../builtins/codegen/test_abi_decode.py | 4 +- .../builtins/codegen/test_abi_encode.py | 4 +- .../builtins/codegen/test_addmod.py | 6 +-- .../builtins/codegen/test_as_wei_value.py | 2 +- .../functional/builtins/codegen/test_ceil.py | 2 +- .../builtins/{folding => }/conftest.py | 0 tests/revm/abi.py | 9 +++- tests/revm/abi_contract.py | 41 ++++------------ tests/revm/base_evm_contract.py | 47 ------------------- tests/revm/revm_env.py | 23 +++++---- tests/revm/vm_utils.py | 18 ------- 13 files changed, 48 insertions(+), 126 deletions(-) rename tests/functional/builtins/{folding => }/conftest.py (100%) delete mode 100644 tests/revm/base_evm_contract.py delete mode 100644 tests/revm/vm_utils.py diff --git a/setup.py b/setup.py index 2f91cb4253..acaaa907ce 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ "lark==1.1.9", "hypothesis[lark]>=5.37.1,<6.0", "eth-stdlib==0.2.6", - "pyrevm==0.2.1", + "git+https://github.com/gakonst/pyrevm", ], "lint": [ "black==23.12.0", diff --git a/tests/conftest.py b/tests/conftest.py index b64e19588b..124b56c839 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -149,18 +149,23 @@ def _none_addr(datatype, data): @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}) + return 10**10 + + +@pytest.fixture(scope="module") +def tester(gas_limit): + custom_genesis = PyEVMBackend._generate_genesis_params(overrides={"gas_limit": gas_limit}) custom_genesis["base_fee_per_gas"] = 0 backend = PyEVMBackend(genesis_parameters=custom_genesis) return EthereumTester(backend=backend) @pytest.fixture(scope="module") -def revm_env(): - return RevmEnv() +def revm_env(gas_limit): + return RevmEnv(gas_limit) def zero_gas_price_strategy(web3, transaction_params=None): @@ -480,8 +485,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 diff --git a/tests/functional/builtins/codegen/test_abi_decode.py b/tests/functional/builtins/codegen/test_abi_decode.py index d281851f8e..1c38ea91ea 100644 --- a/tests/functional/builtins/codegen/test_abi_decode.py +++ b/tests/functional/builtins/codegen/test_abi_decode.py @@ -270,7 +270,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): @@ -294,7 +294,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 f014c47a19..7445b8b0fe 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): @@ -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..595d7d588f 100644 --- a/tests/functional/builtins/codegen/test_addmod.py +++ b/tests/functional/builtins/codegen/test_addmod.py @@ -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,7 +29,7 @@ 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): diff --git a/tests/functional/builtins/codegen/test_as_wei_value.py b/tests/functional/builtins/codegen/test_as_wei_value.py index d0a2a948be..0028183f04 100644 --- a/tests/functional/builtins/codegen/test_as_wei_value.py +++ b/tests/functional/builtins/codegen/test_as_wei_value.py @@ -109,7 +109,7 @@ def foo(a: Foo) -> uint256: 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_side_effects_invoked(c1, lambda: c2.foo(c1.address)) def test_internal_call(w3, get_contract_with_gas_estimation): diff --git a/tests/functional/builtins/codegen/test_ceil.py b/tests/functional/builtins/codegen/test_ceil.py index a5b5cbc561..52f254d82d 100644 --- a/tests/functional/builtins/codegen/test_ceil.py +++ b/tests/functional/builtins/codegen/test_ceil.py @@ -121,7 +121,7 @@ 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): diff --git a/tests/functional/builtins/folding/conftest.py b/tests/functional/builtins/conftest.py similarity index 100% rename from tests/functional/builtins/folding/conftest.py rename to tests/functional/builtins/conftest.py diff --git a/tests/revm/abi.py b/tests/revm/abi.py index ad848e1f2b..a0bf7671d9 100644 --- a/tests/revm/abi.py +++ b/tests/revm/abi.py @@ -1,10 +1,11 @@ # 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, BytesNode +from eth.codecs.abi.nodes import ABITypeNode, BytesNode, FixedNode from eth.codecs.abi.parser import Parser _parsers: dict[str, ABITypeNode] = {} @@ -22,6 +23,12 @@ def visit_BytesNode(cls, node: BytesNode, value: bytes | str) -> bytes: value = bytes.fromhex(value[2:]) return super().visit_BytesNode(node, value) + @classmethod + def visit_FixedNode(cls, node: FixedNode, value: Decimal | int) -> bytes: + if isinstance(value, int): + value = Decimal(value) + return super().visit_FixedNode(node, value) + def _get_parser(schema: str): try: diff --git a/tests/revm/abi_contract.py b/tests/revm/abi_contract.py index 2e267fd4b6..e5ffbdf409 100644 --- a/tests/revm/abi_contract.py +++ b/tests/revm/abi_contract.py @@ -4,13 +4,12 @@ from typing import TYPE_CHECKING, Any, Optional, Union from warnings import warn -from eth.abc import ComputationAPI +from eth_typing import HexAddress from vyper.semantics.analysis.base import FunctionVisibility, StateMutability from vyper.utils import method_id -from .abi import ABIError, abi_decode, abi_encode, is_abi_encodable -from .base_evm_contract import BoaError, StackTrace, _handle_child_trace +from .abi import abi_decode, abi_encode, is_abi_encodable if TYPE_CHECKING: from tests.revm.revm_env import RevmEnv @@ -113,6 +112,7 @@ def __call__(self, *args, value=0, gas=None, sender=None, transact=None, **kwarg gas=gas, is_modifying=self.is_mutable, contract=self.contract, + transact=transact, ) match self.contract.marshal_to_python(computation, self.return_type): @@ -210,7 +210,7 @@ def __init__( name: str, abi: dict, functions: list[ABIFunction], - address: str, + address: HexAddress, filename: Optional[str] = None, ): self.env = env @@ -243,39 +243,14 @@ def method_id_map(self): """ return {function.method_id: function for function in self._functions} - def handle_error(self, computation): - raise BoaError(self.stack_trace(computation)) - - def marshal_to_python(self, computation, abi_type: list[str]) -> tuple[Any, ...]: + def marshal_to_python(self, result: bytes, abi_type: list[str]) -> tuple[Any, ...]: """ Convert the output of a contract call to a Python object. - :param computation: the computation object returned by `execute_code` + :param result: the computation result returned by `execute_code` :param abi_type: the ABI type of the return value. """ - # when there's no contract in the address, the computation output is empty - # if computation.is_error: - # return self.handle_error(computation) - schema = f"({_format_abi_type(abi_type)})" - try: - return abi_decode(schema, computation) - except ABIError as e: - raise BoaError(self.stack_trace(computation)) from e - - def stack_trace(self, computation: ComputationAPI) -> StackTrace: - """ - Create a stack trace for a failed contract call. - """ - calldata_method_id = bytes(computation.msg.data[:4]) - if calldata_method_id in self.method_id_map: - function = self.method_id_map[calldata_method_id] - msg = f" ({self}.{function.pretty_signature})" - else: - # Method might not be specified in the ABI - msg = f" (unknown method id {self}.0x{calldata_method_id.hex()})" - - return_trace = StackTrace([msg]) - return _handle_child_trace(computation, self.env, return_trace) + return abi_decode(schema, result) @property def deployer(self) -> "ABIContractFactory": @@ -310,7 +285,7 @@ def from_abi_dict(cls, abi, name=""): functions = [ABIFunction(item, name) for item in abi if item.get("type") == "function"] return cls(basename(name), abi, functions, filename=name) - def at(self, env, address: str) -> ABIContract: + def at(self, env, address: HexAddress) -> ABIContract: """ Create an ABI contract object for a deployed contract at `address`. """ diff --git a/tests/revm/base_evm_contract.py b/tests/revm/base_evm_contract.py deleted file mode 100644 index 5d171752a2..0000000000 --- a/tests/revm/base_evm_contract.py +++ /dev/null @@ -1,47 +0,0 @@ -from dataclasses import dataclass - - -class StackTrace(list): - def __str__(self): - return "\n\n".join(str(x) for x in self) - - @property - def last_frame(self): - return self[-1] - - -def _trace_for_unknown_contract(computation, env): - ret = StackTrace( - [f""] - ) - return _handle_child_trace(computation, env, ret) - - -def _handle_child_trace(computation, env, return_trace): - if len(computation.children) == 0: - return return_trace - if not computation.children[-1].is_error: - return return_trace - child = computation.children[-1] - - child_obj = env.lookup_contract(child.msg.code_address) - - if child_obj is None: - child_trace = _trace_for_unknown_contract(child, env) - else: - child_trace = child_obj.stack_trace(child) - return StackTrace(child_trace + return_trace) - - -@dataclass -class BoaError(Exception): - stack_trace: StackTrace - - def __str__(self): - frame = self.stack_trace[-1] - if hasattr(frame, "vm_error"): - err = frame.vm_error - err.args = (frame.pretty_vm_reason, *err.args[1:]) - else: - err = frame - return f"{err}\n\n{self.stack_trace}" diff --git a/tests/revm/revm_env.py b/tests/revm/revm_env.py index b7aa70fef1..05a51e13df 100644 --- a/tests/revm/revm_env.py +++ b/tests/revm/revm_env.py @@ -15,10 +15,10 @@ class RevmEnv: - def __init__(self) -> None: + def __init__(self, gas_limit) -> None: self.block = BlockEnv(timestamp=100, prevrandao=bytes([0] * 32)) self.env = Env(block=self.block) - self.evm = EVM(env=self.env) + self.evm = EVM(env=self.env, gas_limit=gas_limit) self.bytecode: dict[HexAddress, str] = {} self.contracts: dict[HexAddress, ABIContract] = {} self._accounts: list[Account] = get_default_account_keys() @@ -29,16 +29,18 @@ def deployer(self) -> HexAddress: def execute_code( self, - to_address: str, - sender: str, - data: bytes, - value: bytes, + to_address: HexAddress, + sender: HexAddress, + data: list[int] | None, + value: int | None, gas: int, is_modifying: bool, contract: "ABIContract", + transact=None, ): try: - output = self.evm.call_raw( + fn = self.evm.call_raw_committing if transact is None else self.evm.call_raw + output = fn( to=to_address, caller=sender, data=data, @@ -49,13 +51,14 @@ def execute_code( ) return bytes(output) except RuntimeError as e: - assert e.args == ("Revert",), f"Expected revert, got {e.args}" + (cause,) = e.args + assert cause in ("Revert", "OutOfGas"), f"Unexpected error {e}" raise TransactionFailed() - def get_code(self, address: str): + def get_code(self, address: HexAddress): return self.bytecode[address] - def register_contract(self, address: str, contract: "ABIContract"): + def register_contract(self, address: HexAddress, contract: "ABIContract"): self.contracts[address] = contract def deploy_source( diff --git a/tests/revm/vm_utils.py b/tests/revm/vm_utils.py deleted file mode 100644 index 0cb3ed4754..0000000000 --- a/tests/revm/vm_utils.py +++ /dev/null @@ -1,18 +0,0 @@ -def ceil32(n): - return floor32(n + 31) - - -def floor32(n): - return n & ~31 - - -def to_int(stack_item) -> int: - if isinstance(stack_item, int): - return stack_item - return int.from_bytes(stack_item, "big") - - -def to_bytes(stack_item) -> bytes: - if isinstance(stack_item, bytes): - return stack_item.rjust(32, b"\x00") - return stack_item.to_bytes(32, "big") From e81a5e2f775b4944298d233b301809ea727cb732 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 8 Mar 2024 18:02:11 +0100 Subject: [PATCH 03/87] Version specifier --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index acaaa907ce..e5c6ac240d 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ "lark==1.1.9", "hypothesis[lark]>=5.37.1,<6.0", "eth-stdlib==0.2.6", - "git+https://github.com/gakonst/pyrevm", + "pyrevm @ git+https://github.com/gakonst/pyrevm", ], "lint": [ "black==23.12.0", From c403845104b33ff78ccdd85feec05eee4272a48b Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 8 Mar 2024 18:32:18 +0100 Subject: [PATCH 04/87] Lint + DaniPopes branch --- setup.py | 2 +- tests/revm/abi_contract.py | 5 +---- tests/revm/revm_env.py | 3 +-- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/setup.py b/setup.py index e5c6ac240d..0ebf10a7e2 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ "lark==1.1.9", "hypothesis[lark]>=5.37.1,<6.0", "eth-stdlib==0.2.6", - "pyrevm @ git+https://github.com/gakonst/pyrevm", + "pyrevm @ git+https://github.com/DaniPopes/pyrevm.git#egg=update", ], "lint": [ "black==23.12.0", diff --git a/tests/revm/abi_contract.py b/tests/revm/abi_contract.py index e5ffbdf409..2389716dc1 100644 --- a/tests/revm/abi_contract.py +++ b/tests/revm/abi_contract.py @@ -221,10 +221,7 @@ def __init__( self._functions = functions self._bytecode = self.env.get_code(address) if not self._bytecode: - warn( - f"Requested {self} but there is no bytecode at that address!", - stacklevel=2, - ) + warn(f"Requested {self} but there is no bytecode at that address!", stacklevel=2) overloads = defaultdict(list) for f in functions: diff --git a/tests/revm/revm_env.py b/tests/revm/revm_env.py index 05a51e13df..fd0fbe3d2b 100644 --- a/tests/revm/revm_env.py +++ b/tests/revm/revm_env.py @@ -76,8 +76,7 @@ def deploy_source( # test that all output formats can get generated output_formats=output_formats, settings=Settings( - evm_version=kwargs.pop("evm_version", None), - optimize=override_opt_level or optimize, + evm_version=kwargs.pop("evm_version", None), optimize=override_opt_level or optimize ), input_bundle=input_bundle, show_gas_estimates=True, # Enable gas estimates for testing From f5330d75535afc3751fb58b6b7bc776df4717a4a Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 8 Mar 2024 20:25:52 +0100 Subject: [PATCH 05/87] Get rid of w3 --- setup.py | 2 +- tests/functional/__init__.py | 0 .../builtins/codegen/test_abi_decode.py | 4 +- .../builtins/codegen/test_as_wei_value.py | 11 +- .../functional/builtins/codegen/test_ceil.py | 2 +- .../builtins/codegen/test_create_functions.py | 101 ++++++++++-------- tests/functional/builtins/codegen/test_ec.py | 4 +- .../functional/builtins/codegen/test_floor.py | 2 +- .../builtins/codegen/test_is_contract.py | 4 +- .../builtins/codegen/test_mulmod.py | 4 +- .../builtins/codegen/test_raw_call.py | 19 ++-- tests/functional/codegen/__init__.py | 0 tests/functional/codegen/modules/__init__.py | 0 tests/functional/syntax/__init__.py | 0 tests/functional/syntax/modules/__init__.py | 0 tests/revm/abi.py | 22 +++- tests/revm/abi_contract.py | 5 +- tests/revm/revm_env.py | 45 +++++--- tests/unit/__init__.py | 0 tests/unit/compiler/__init__.py | 2 - tests/unit/compiler/ir/__init__.py | 0 21 files changed, 131 insertions(+), 96 deletions(-) delete mode 100644 tests/functional/__init__.py delete mode 100644 tests/functional/codegen/__init__.py delete mode 100644 tests/functional/codegen/modules/__init__.py delete mode 100644 tests/functional/syntax/__init__.py delete mode 100644 tests/functional/syntax/modules/__init__.py delete mode 100644 tests/unit/__init__.py delete mode 100644 tests/unit/compiler/__init__.py delete mode 100644 tests/unit/compiler/ir/__init__.py diff --git a/setup.py b/setup.py index 0ebf10a7e2..8e1944deed 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ "lark==1.1.9", "hypothesis[lark]>=5.37.1,<6.0", "eth-stdlib==0.2.6", - "pyrevm @ git+https://github.com/DaniPopes/pyrevm.git#egg=update", + "pyrevm @ git+https://github.com/DaniPopes/pyrevm.git@update", ], "lint": [ "black==23.12.0", diff --git a/tests/functional/__init__.py b/tests/functional/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/functional/builtins/codegen/test_abi_decode.py b/tests/functional/builtins/codegen/test_abi_decode.py index 1c38ea91ea..86843bb197 100644 --- a/tests/functional/builtins/codegen/test_abi_decode.py +++ b/tests/functional/builtins/codegen/test_abi_decode.py @@ -86,9 +86,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}: diff --git a/tests/functional/builtins/codegen/test_as_wei_value.py b/tests/functional/builtins/codegen/test_as_wei_value.py index 0028183f04..278a114fe8 100644 --- a/tests/functional/builtins/codegen/test_as_wei_value.py +++ b/tests/functional/builtins/codegen/test_as_wei_value.py @@ -1,6 +1,7 @@ from decimal import Decimal import pytest +from eth_utils import to_wei wei_denoms = { "femtoether": 3, @@ -95,7 +96,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 @@ -108,11 +109,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 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_with_gas_estimation): code = """ @external def foo() -> uint256: @@ -122,7 +123,5 @@ def foo() -> uint256: def bar() -> uint8: return 7 """ - c = get_contract_with_gas_estimation(code) - - assert c.foo() == w3.to_wei(7, "ether") + assert c.foo() == to_wei(7, "ether") diff --git a/tests/functional/builtins/codegen/test_ceil.py b/tests/functional/builtins/codegen/test_ceil.py index 52f254d82d..0bf387cebf 100644 --- a/tests/functional/builtins/codegen/test_ceil.py +++ b/tests/functional/builtins/codegen/test_ceil.py @@ -106,7 +106,7 @@ def ceil_param(p: decimal) -> int256: assert c.ceil_param(Decimal("-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 diff --git a/tests/functional/builtins/codegen/test_create_functions.py b/tests/functional/builtins/codegen/test_create_functions.py index c99942d99d..f5c341546b 100644 --- a/tests/functional/builtins/codegen/test_create_functions.py +++ b/tests/functional/builtins/codegen/test_create_functions.py @@ -42,7 +42,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, revm_env): code = """ interface SubContract: def hello() -> Bytes[100]: view @@ -70,7 +70,7 @@ def test2() -> Bytes[100]: assert c.test2() == b"hello world!" -def test_minimal_proxy_exception(w3, get_contract, tx_failed): +def test_minimal_proxy_exception(revm_env, get_contract, tx_failed): code = """ interface SubContract: def hello(a: uint256) -> Bytes[100]: view @@ -104,7 +104,7 @@ def test2(a: uint256) -> Bytes[100]: GAS_SENT = 30000 tx_hash = c.test2(0, transact={"gas": GAS_SENT}) - receipt = w3.eth.get_transaction_receipt(tx_hash) + receipt = revm_env.get_transaction_receipt(tx_hash) assert receipt["status"] == 0 assert receipt["gasUsed"] < GAS_SENT @@ -137,7 +137,13 @@ def test(_salt: bytes32) -> address: # contract, and 0xfe7100 is ERC5202 magic @pytest.mark.parametrize("blueprint_prefix", [b"", b"\xfe", ERC5202_PREFIX]) def test_create_from_blueprint( - get_contract, deploy_blueprint_for, w3, keccak, create2_address_of, tx_failed, blueprint_prefix + get_contract, + deploy_blueprint_for, + revm_env, + keccak, + create2_address_of, + tx_failed, + blueprint_prefix, ): code = """ @external @@ -160,7 +166,7 @@ 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 = revm_env.get_code(foo_contract.address) f, FooContract = deploy_blueprint_for(code, initcode_prefix=blueprint_prefix) @@ -169,7 +175,7 @@ def test2(target: address, salt: bytes32): d.test(f.address, transact={}) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert revm_env.get_code(test.address) == expected_runtime_code assert test.foo() == 123 # extcodesize check @@ -182,11 +188,11 @@ def test2(target: address, salt: bytes32): d.test2(f.address, salt, transact={}) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert revm_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 = revm_env.get_code(f.address) initcode = initcode[len(blueprint_prefix) :] # strip the prefix assert HexBytes(test.address) == create2_address_of(d.address, salt, initcode) @@ -198,7 +204,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, revm_env, keccak, create2_address_of, tx_failed ): code = """ @external @@ -220,7 +226,7 @@ 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 = revm_env.get_code(foo_contract.address) f, FooContract = deploy_blueprint_for(code) @@ -229,7 +235,7 @@ def test2(target: address, salt: bytes32): d.test(f.address, transact={}) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert revm_env.get_code(test.address) == expected_runtime_code assert test.foo() == 123 # extcodesize check @@ -242,11 +248,11 @@ def test2(target: address, salt: bytes32): d.test2(f.address, salt, transact={}) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert revm_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 = revm_env.get_code(f.address) initcode = initcode[len(ERC5202_PREFIX) :] # strip the prefix assert HexBytes(test.address) == create2_address_of(d.address, salt, initcode) @@ -256,7 +262,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, revm_env, tx_failed ): deployer_code = """ BLUEPRINT: immutable(address) @@ -280,11 +286,11 @@ 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) + c = revm_env.contract(abi=[], bytecode=bytecode) deploy_transaction = c.constructor() - tx_info = {"from": w3.eth.accounts[0], "value": 0, "gasPrice": 0} + tx_info = {"from": revm_env.accounts[0], "value": 0, "gasPrice": 0} tx_hash = deploy_transaction.transact(tx_info) - blueprint_address = w3.eth.get_transaction_receipt(tx_hash)["contractAddress"] + blueprint_address = revm_env.get_transaction_receipt(tx_hash)["contractAddress"] d = get_contract(deployer_code, blueprint_address) @@ -305,7 +311,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, revm_env, keccak, create2_address_of, tx_failed ): code = """ struct Bar: @@ -359,18 +365,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 = revm_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 = revm_env.get_code(f.address)[3:] d.test(f.address, FOO, BAR, transact={}) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert revm_env.get_code(test.address) == expected_runtime_code assert test.foo() == FOO assert test.bar() == BAR @@ -383,7 +389,7 @@ def should_fail(target: address, arg1: String[129], arg2: Bar): d.test2(f.address, FOO, BAR, salt, transact={}) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert revm_env.get_code(test.address) == expected_runtime_code assert test.foo() == FOO assert test.bar() == BAR @@ -392,13 +398,13 @@ def should_fail(target: address, arg1: String[129], arg2: Bar): d.test3(f.address, encoded_args, transact={}) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert revm_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={}) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert revm_env.get_code(test.address) == expected_runtime_code assert test.foo() == FOO assert test.bar() == BAR @@ -422,10 +428,10 @@ 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}"}) + revm_env.send_transaction({"to": d.address, "data": f"{sig}{encoded}"}) -def test_create_copy_of(get_contract, w3, keccak, create2_address_of, tx_failed): +def test_create_copy_of(get_contract, revm_env, keccak, create2_address_of, tx_failed): code = """ created_address: public(address) @internal @@ -452,23 +458,23 @@ def test2(target: address, salt: bytes32) -> address: """ c = get_contract(code) - bytecode = w3.eth.get_code(c.address) + bytecode = revm_env.get_code(c.address) c.test(c.address, transact={}) test1 = c.created_address() - assert w3.eth.get_code(test1) == bytecode + assert revm_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" + # assert revm_env.get_code(test1) == b"\x01" salt = keccak(b"vyper") c.test2(c.address, salt, transact={}) test2 = c.created_address() - assert w3.eth.get_code(test2) == bytecode + assert revm_env.get_code(test2) == bytecode assert HexBytes(test2) == create2_address_of(c.address, salt, vyper_initcode(bytecode)) @@ -489,7 +495,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, revm_env, blueprint_prefix ): # check msize allocator does not get trampled by value= kwarg code = """ @@ -531,7 +537,7 @@ def test(target: address): """ foo_contract = get_contract(code, 12) - expected_runtime_code = w3.eth.get_code(foo_contract.address) + expected_runtime_code = revm_env.get_code(foo_contract.address) f, FooContract = deploy_blueprint_for(code, initcode_prefix=blueprint_prefix) @@ -540,13 +546,13 @@ def test(target: address): d.test(f.address, transact={"value": 3}) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert revm_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, revm_env, blueprint_prefix ): # test msize allocator does not get trampled by salt= kwarg code = """ @@ -589,7 +595,7 @@ def test(target: address): """ foo_contract = get_contract(code, 12) - expected_runtime_code = w3.eth.get_code(foo_contract.address) + expected_runtime_code = revm_env.get_code(foo_contract.address) f, FooContract = deploy_blueprint_for(code, initcode_prefix=blueprint_prefix) @@ -598,13 +604,13 @@ def test(target: address): d.test(f.address, transact={}) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert revm_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, revm_env, blueprint_prefix ): # test msize allocator does not get trampled by salt= kwarg code = """ @@ -637,7 +643,7 @@ def test(target: address): """ foo_contract = get_contract(code) - expected_runtime_code = w3.eth.get_code(foo_contract.address) + expected_runtime_code = revm_env.get_code(foo_contract.address) f, FooContract = deploy_blueprint_for(code, initcode_prefix=blueprint_prefix) @@ -646,11 +652,11 @@ def test(target: address): d.test(f.address, transact={}) test = FooContract(d.created_address()) - assert w3.eth.get_code(test.address) == expected_runtime_code + assert revm_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, revm_env): # test msize allocator does not get trampled by salt= kwarg complex_salt = """ created_address: public(address) @@ -666,10 +672,10 @@ def test(target: address) -> address: """ c = get_contract(complex_salt) - bytecode = w3.eth.get_code(c.address) + bytecode = revm_env.get_code(c.address) c.test(c.address, transact={}) - test1 = c.created_address() - assert w3.eth.get_code(test1) == bytecode + test1 = c.address + assert bytecode and revm_env.get_code(test1) == bytecode # test msize allocator does not get trampled by value= kwarg complex_value = """ @@ -685,8 +691,9 @@ def test(target: address) -> address: """ c = get_contract(complex_value) - bytecode = w3.eth.get_code(c.address) + bytecode = revm_env.get_code(c.address) + revm_env.set_balance(revm_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 revm_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..fdc864866a 100644 --- a/tests/functional/builtins/codegen/test_ec.py +++ b/tests/functional/builtins/codegen/test_ec.py @@ -59,7 +59,7 @@ def foo() -> uint256[2]: 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 @@ -141,7 +141,7 @@ def foo() -> uint256[2]: 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 diff --git a/tests/functional/builtins/codegen/test_floor.py b/tests/functional/builtins/codegen/test_floor.py index 968cf1ec91..1f394c28fe 100644 --- a/tests/functional/builtins/codegen/test_floor.py +++ b/tests/functional/builtins/codegen/test_floor.py @@ -110,7 +110,7 @@ def floor_param(p: decimal) -> int256: assert c.floor_param(Decimal("-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 diff --git a/tests/functional/builtins/codegen/test_is_contract.py b/tests/functional/builtins/codegen/test_is_contract.py index 5887763a93..d35053a8d4 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(revm_env, get_contract_with_gas_estimation): contract_1 = """ @external def foo(arg1: address) -> bool: @@ -11,7 +11,7 @@ def foo(arg1: address) -> bool: def foo(arg1: address) -> bool: return arg1.is_contract """ - a0, a1 = w3.eth.accounts[:2] + a0, a1 = revm_env.accounts[:2] c1 = get_contract_with_gas_estimation(contract_1) c2 = get_contract_with_gas_estimation(contract_2) diff --git a/tests/functional/builtins/codegen/test_mulmod.py b/tests/functional/builtins/codegen/test_mulmod.py index 9af8cafaf8..4f97af5c39 100644 --- a/tests/functional/builtins/codegen/test_mulmod.py +++ b/tests/functional/builtins/codegen/test_mulmod.py @@ -32,9 +32,7 @@ def exponential(base: uint256, exponent: uint256, modulus: uint256) -> uint256: 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 diff --git a/tests/functional/builtins/codegen/test_raw_call.py b/tests/functional/builtins/codegen/test_raw_call.py index e5201e9bb2..7784bfa2f7 100644 --- a/tests/functional/builtins/codegen/test_raw_call.py +++ b/tests/functional/builtins/codegen/test_raw_call.py @@ -120,7 +120,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(revm_env, get_contract): inner_code = """ a: address # this is required for storage alignment... owners: public(address[5]) @@ -155,11 +155,11 @@ 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 = revm_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. @@ -167,12 +167,11 @@ def set(i: int128, owner: address): assert outer_contract.owners(1) is None # 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 -def test_gas(get_contract, tx_failed): +def test_gas(get_contract, tx_failed, revm_env): inner_code = """ bar: bytes32 @@ -517,7 +516,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, revm_env): # test msize uses clean memory and does not get overwritten by # any raw_call() kwargs code = """ @@ -544,6 +543,7 @@ def bar(f: uint256) -> Bytes[100]: ) return self.buf """ + revm_env.set_balance(revm_env.deployer, 1) c = get_contract(code, value=1) assert ( @@ -552,7 +552,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, revm_env): # test msize uses clean memory and does not get overwritten by # any raw_call() kwargs code = """ @@ -579,6 +579,7 @@ def bar(f: uint256) -> Bytes[100]: ) return self.buf """ + revm_env.set_balance(revm_env.deployer, 1) c = get_contract(code, value=1) assert ( diff --git a/tests/functional/codegen/__init__.py b/tests/functional/codegen/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/functional/codegen/modules/__init__.py b/tests/functional/codegen/modules/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/functional/syntax/__init__.py b/tests/functional/syntax/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/functional/syntax/modules/__init__.py b/tests/functional/syntax/modules/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/revm/abi.py b/tests/revm/abi.py index a0bf7671d9..6776ca8652 100644 --- a/tests/revm/abi.py +++ b/tests/revm/abi.py @@ -5,15 +5,25 @@ 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, BytesNode, FixedNode +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 _Decoder(Decoder): + @classmethod + def visit_AddressNode( + cls, node: AddressNode, value: bytes, checksum: bool = True, **kwargs: Any + ) -> str | None: + address = super().visit_AddressNode(node, value, checksum, **kwargs) + return address if address != "0x0000000000000000000000000000000000000000" else None + + class _Encoder(Encoder): """ - Custom encoder that parses bytes from hex to bytes + Custom encoder that converts some types to the expected format. """ @classmethod @@ -29,6 +39,12 @@ def visit_FixedNode(cls, node: FixedNode, value: Decimal | int) -> bytes: value = Decimal(value) return super().visit_FixedNode(node, value) + @classmethod + def visit_AddressNode(cls, node: AddressNode, value: str | HexBytes) -> bytes: + if isinstance(value, HexBytes): + value = value.hex() + return super().visit_AddressNode(node, value) + def _get_parser(schema: str): try: @@ -43,7 +59,7 @@ def abi_encode(schema: str, data: Any) -> bytes: def abi_decode(schema: str, data: bytes) -> Any: - return Decoder.decode(_get_parser(schema), data) + return _Decoder.decode(_get_parser(schema), data) def is_abi_encodable(abi_type: str, data: Any) -> bool: diff --git a/tests/revm/abi_contract.py b/tests/revm/abi_contract.py index 2389716dc1..f806eaa275 100644 --- a/tests/revm/abi_contract.py +++ b/tests/revm/abi_contract.py @@ -31,7 +31,8 @@ def __init__(self, abi: dict, contract_name: str): @property def name(self) -> str: - return self._abi["name"] + # 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: @@ -200,7 +201,7 @@ class ABIContract: """A contract that has been deployed to the blockchain and created via an ABI.""" @property - def address(self) -> str: + def address(self) -> HexAddress: assert self._address is not None return self._address diff --git a/tests/revm/revm_env.py b/tests/revm/revm_env.py index fd0fbe3d2b..1c4e78483b 100644 --- a/tests/revm/revm_env.py +++ b/tests/revm/revm_env.py @@ -1,31 +1,38 @@ import json from typing import Callable -from eth_account import Account +from eth_keys.datatypes import PrivateKey from eth_tester.backends.pyevm.main import get_default_account_keys from eth_tester.exceptions import TransactionFailed from eth_typing import HexAddress from eth_utils import to_checksum_address -from pyrevm import EVM, BlockEnv, Env +from pyrevm import EVM, Env -from tests.revm.abi_contract import ABIContract, ABIContractFactory +from tests.revm.abi import abi_encode +from tests.revm.abi_contract import ABIContract, ABIContractFactory, ABIFunction from vyper.ast.grammar import parse_vyper_source from vyper.compiler import CompilerData, Settings, compile_code from vyper.compiler.settings import OptimizationLevel class RevmEnv: - def __init__(self, gas_limit) -> None: - self.block = BlockEnv(timestamp=100, prevrandao=bytes([0] * 32)) - self.env = Env(block=self.block) + def __init__(self, gas_limit: int) -> None: + self.env = Env() self.evm = EVM(env=self.env, gas_limit=gas_limit) self.bytecode: dict[HexAddress, str] = {} self.contracts: dict[HexAddress, ABIContract] = {} - self._accounts: list[Account] = get_default_account_keys() + self._keys: list[PrivateKey] = get_default_account_keys() + + @property + def accounts(self) -> list[HexAddress]: + return [k.public_key.to_checksum_address() for k in self._keys] @property def deployer(self) -> HexAddress: - return self._accounts[0].public_key.to_checksum_address() + return self._keys[0].public_key.to_checksum_address() + + def set_balance(self, address: HexAddress, value: int): + self.evm.set_balance(address, value) def execute_code( self, @@ -53,7 +60,7 @@ def execute_code( except RuntimeError as e: (cause,) = e.args assert cause in ("Revert", "OutOfGas"), f"Unexpected error {e}" - raise TransactionFailed() + raise TransactionFailed(cause) def get_code(self, address: HexAddress): return self.bytecode[address] @@ -87,20 +94,30 @@ def deploy_source( abi = out["abi"] bytecode = out["bytecode"] - value = kwargs.pop("value_in_eth", 0) * 10**18 # Handle deploying with an eth value. + value = ( + kwargs.pop("value", 0) or kwargs.pop("value_in_eth", 0) * 10**18 + ) # Handle deploying with an eth value. return self.deploy(abi, bytecode, value, *args, **kwargs) def deploy(self, abi: list[dict], bytecode: str, value: int, *args, **kwargs): factory = ABIContractFactory.from_abi_dict(abi=abi) - # Deploy the contract + + initcode = bytes.fromhex(bytecode[2:]) + 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 += abi_encode(ctor.signature, ctor._merge_kwargs(*args, **kwargs)) + deployed_at = self.evm.deploy( deployer=self.deployer, - code=list(bytes.fromhex(bytecode[2:])), + code=list(initcode), value=value, _abi=json.dumps(abi), ) address = to_checksum_address(deployed_at) self.bytecode[address] = bytecode - # tx_info = {"from": self.deployer, "value": value, "gasPrice": 0, **kwargs} - return factory.at(self, address) + + abi_contract = factory.at(self, address) + + return abi_contract diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/unit/compiler/__init__.py b/tests/unit/compiler/__init__.py deleted file mode 100644 index 35a11f851b..0000000000 --- a/tests/unit/compiler/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# prevent module name collision between tests/compiler/test_pre_parser.py -# and tests/ast/test_pre_parser.py diff --git a/tests/unit/compiler/ir/__init__.py b/tests/unit/compiler/ir/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 From c68d50523a4ae68487def7840347732b028e7039 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 11 Mar 2024 12:48:27 +0100 Subject: [PATCH 06/87] Restore init files --- tests/functional/__init__.py | 0 tests/functional/builtins/codegen/__init__.py | 0 tests/functional/builtins/codegen/test_abi_encode.py | 2 +- tests/functional/builtins/folding/__init__.py | 0 tests/functional/codegen/__init__.py | 0 tests/functional/codegen/modules/__init__.py | 0 tests/functional/syntax/__init__.py | 0 tests/functional/syntax/modules/__init__.py | 0 tests/unit/__init__.py | 0 tests/unit/compiler/__init__.py | 2 ++ tests/unit/compiler/ir/__init__.py | 0 11 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 tests/functional/__init__.py create mode 100644 tests/functional/builtins/codegen/__init__.py create mode 100644 tests/functional/builtins/folding/__init__.py create mode 100644 tests/functional/codegen/__init__.py create mode 100644 tests/functional/codegen/modules/__init__.py create mode 100644 tests/functional/syntax/__init__.py create mode 100644 tests/functional/syntax/modules/__init__.py create mode 100644 tests/unit/__init__.py create mode 100644 tests/unit/compiler/__init__.py create mode 100644 tests/unit/compiler/ir/__init__.py diff --git a/tests/functional/__init__.py b/tests/functional/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/functional/builtins/codegen/__init__.py b/tests/functional/builtins/codegen/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/functional/builtins/codegen/test_abi_encode.py b/tests/functional/builtins/codegen/test_abi_encode.py index 7445b8b0fe..9ab6efbd65 100644 --- a/tests/functional/builtins/codegen/test_abi_encode.py +++ b/tests/functional/builtins/codegen/test_abi_encode.py @@ -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): diff --git a/tests/functional/builtins/folding/__init__.py b/tests/functional/builtins/folding/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/functional/codegen/__init__.py b/tests/functional/codegen/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/functional/codegen/modules/__init__.py b/tests/functional/codegen/modules/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/functional/syntax/__init__.py b/tests/functional/syntax/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/functional/syntax/modules/__init__.py b/tests/functional/syntax/modules/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/unit/compiler/__init__.py b/tests/unit/compiler/__init__.py new file mode 100644 index 0000000000..35a11f851b --- /dev/null +++ b/tests/unit/compiler/__init__.py @@ -0,0 +1,2 @@ +# prevent module name collision between tests/compiler/test_pre_parser.py +# and tests/ast/test_pre_parser.py diff --git a/tests/unit/compiler/ir/__init__.py b/tests/unit/compiler/ir/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From 98310881fb352a4168bbb4d4292c4176d5d1cc3f Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 11 Mar 2024 12:52:35 +0100 Subject: [PATCH 07/87] Use gakonst fork again --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 8e1944deed..b7db1b602e 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ "lark==1.1.9", "hypothesis[lark]>=5.37.1,<6.0", "eth-stdlib==0.2.6", - "pyrevm @ git+https://github.com/DaniPopes/pyrevm.git@update", + "pyrevm @ git+https://github.com/gakonst/pyrevm.git@master", ], "lint": [ "black==23.12.0", From 99bc687af4c31a6477c1638ad9ee53b98f825182 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 11 Mar 2024 20:17:13 +0100 Subject: [PATCH 08/87] Investigate tests + lint --- tests/functional/builtins/codegen/test_slice.py | 4 +++- tests/revm/revm_env.py | 8 +++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/functional/builtins/codegen/test_slice.py b/tests/functional/builtins/codegen/test_slice.py index 0c5a8fc485..4b45338e9d 100644 --- a/tests/functional/builtins/codegen/test_slice.py +++ b/tests/functional/builtins/codegen/test_slice.py @@ -147,7 +147,9 @@ 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: + 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) diff --git a/tests/revm/revm_env.py b/tests/revm/revm_env.py index 1c4e78483b..1389bc93f0 100644 --- a/tests/revm/revm_env.py +++ b/tests/revm/revm_env.py @@ -40,6 +40,7 @@ def execute_code( sender: HexAddress, data: list[int] | None, value: int | None, + # todo: use or remove arguments gas: int, is_modifying: bool, contract: "ABIContract", @@ -59,7 +60,7 @@ def execute_code( return bytes(output) except RuntimeError as e: (cause,) = e.args - assert cause in ("Revert", "OutOfGas"), f"Unexpected error {e}" + assert cause in ("Revert", "OutOfGas", "InvalidOperandOOG"), f"Unexpected error {e}" raise TransactionFailed(cause) def get_code(self, address: HexAddress): @@ -110,10 +111,7 @@ def deploy(self, abi: list[dict], bytecode: str, value: int, *args, **kwargs): initcode += abi_encode(ctor.signature, ctor._merge_kwargs(*args, **kwargs)) deployed_at = self.evm.deploy( - deployer=self.deployer, - code=list(initcode), - value=value, - _abi=json.dumps(abi), + deployer=self.deployer, code=list(initcode), value=value, _abi=json.dumps(abi) ) address = to_checksum_address(deployed_at) self.bytecode[address] = bytecode From 88d029615f2a869f4236b6d535e227c30fad6db7 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 19 Mar 2024 17:54:47 +0100 Subject: [PATCH 09/87] Implement create from blueprint --- tests/conftest.py | 10 ++- .../builtins/codegen/test_create_functions.py | 18 ++-- tests/functional/builtins/conftest.py | 5 ++ tests/revm/revm_env.py | 83 +++++++++++++------ 4 files changed, 80 insertions(+), 36 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 124b56c839..26db216ccc 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -165,7 +165,7 @@ def tester(gas_limit): @pytest.fixture(scope="module") def revm_env(gas_limit): - return RevmEnv(gas_limit) + return RevmEnv(gas_limit, tracing=False) def zero_gas_price_strategy(web3, transaction_params=None): @@ -446,6 +446,14 @@ def deploy_blueprint_for(source_code, *args, **kwargs): return deploy_blueprint_for +@pytest.fixture(scope="module") +def deploy_blueprint_revm(revm_env, optimize, output_formats): + def deploy_blueprint_revm(source_code, *args, **kwargs): + return revm_env.deploy_blueprint(source_code, optimize, output_formats, *args, **kwargs) + + return deploy_blueprint_revm + + # TODO: this should not be a fixture. # remove me and replace all uses with `with pytest.raises`. @pytest.fixture diff --git a/tests/functional/builtins/codegen/test_create_functions.py b/tests/functional/builtins/codegen/test_create_functions.py index f5c341546b..aaa63a3df7 100644 --- a/tests/functional/builtins/codegen/test_create_functions.py +++ b/tests/functional/builtins/codegen/test_create_functions.py @@ -123,14 +123,12 @@ 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 with tx_failed(): - c.test(salt, transact={}) + c.test(salt) # test blueprints with various prefixes - 0xfe would block calls to the blueprint @@ -164,18 +162,16 @@ def test2(target: address, salt: bytes32): self.created_address = create_from_blueprint(target, code_offset={prefix_len}, salt=salt) """ - # deploy a foo so we can compare its bytecode with factory deployed version + # deploy a foo, so we can compare its bytecode with factory deployed version foo_contract = get_contract(code) - expected_runtime_code = revm_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 revm_env.get_code(test.address) == expected_runtime_code + assert revm_env.get_code(test.address) == revm_env.get_code(foo_contract.address) assert test.foo() == 123 # extcodesize check @@ -188,7 +184,7 @@ def test2(target: address, salt: bytes32): d.test2(f.address, salt, transact={}) test = FooContract(d.created_address()) - assert revm_env.get_code(test.address) == expected_runtime_code + assert revm_env.get_code(test.address) == revm_env.get_code(foo_contract.address) assert test.foo() == 123 # check if the create2 address matches our offchain calculation diff --git a/tests/functional/builtins/conftest.py b/tests/functional/builtins/conftest.py index c7174d14fd..a8b18bb8aa 100644 --- a/tests/functional/builtins/conftest.py +++ b/tests/functional/builtins/conftest.py @@ -4,3 +4,8 @@ @pytest.fixture(scope="module") def get_contract(get_revm_contract): return get_revm_contract + + +@pytest.fixture(scope="module") +def deploy_blueprint_for(deploy_blueprint_revm): + return deploy_blueprint_revm diff --git a/tests/revm/revm_env.py b/tests/revm/revm_env.py index 1389bc93f0..b02ac9e182 100644 --- a/tests/revm/revm_env.py +++ b/tests/revm/revm_env.py @@ -6,19 +6,20 @@ from eth_tester.exceptions import TransactionFailed from eth_typing import HexAddress from eth_utils import to_checksum_address -from pyrevm import EVM, Env +from hexbytes import HexBytes +from pyrevm import EVM from tests.revm.abi import abi_encode from tests.revm.abi_contract import ABIContract, ABIContractFactory, ABIFunction from vyper.ast.grammar import parse_vyper_source from vyper.compiler import CompilerData, Settings, compile_code from vyper.compiler.settings import OptimizationLevel +from vyper.utils import ERC5202_PREFIX class RevmEnv: - def __init__(self, gas_limit: int) -> None: - self.env = Env() - self.evm = EVM(env=self.env, gas_limit=gas_limit) + def __init__(self, gas_limit: int, tracing=False) -> None: + self.evm = EVM(gas_limit=gas_limit, tracing=tracing) self.bytecode: dict[HexAddress, str] = {} self.contracts: dict[HexAddress, ABIContract] = {} self._keys: list[PrivateKey] = get_default_account_keys() @@ -38,7 +39,7 @@ def execute_code( self, to_address: HexAddress, sender: HexAddress, - data: list[int] | None, + data: bytes | None, value: int | None, # todo: use or remove arguments gas: int, @@ -51,7 +52,7 @@ def execute_code( output = fn( to=to_address, caller=sender, - data=data, + calldata=data, value=value, # gas=gas, # is_modifying=self.is_mutable, @@ -59,12 +60,10 @@ def execute_code( ) return bytes(output) except RuntimeError as e: - (cause,) = e.args - assert cause in ("Revert", "OutOfGas", "InvalidOperandOOG"), f"Unexpected error {e}" - raise TransactionFailed(cause) + raise TransactionFailed(*e.args) from e def get_code(self, address: HexAddress): - return self.bytecode[address] + return self.evm.basic(address).code def register_contract(self, address: HexAddress, contract: "ABIContract"): self.contracts[address] = contract @@ -77,31 +76,63 @@ def deploy_source( *args, override_opt_level=None, input_bundle=None, + evm_version=None, **kwargs, ) -> ABIContract: + abi, bytecode = self._compile( + source_code, optimize, output_formats, override_opt_level, input_bundle, evm_version + ) + value = ( + kwargs.pop("value", 0) or kwargs.pop("value_in_eth", 0) * 10**18 + ) # Handle deploying with an eth value. + + return self.deploy(abi, bytecode, value, *args, **kwargs) + + def _compile( + self, source_code, optimize, output_formats, override_opt_level, input_bundle, evm_version + ): out = compile_code( source_code, # test that all output formats can get generated output_formats=output_formats, - settings=Settings( - evm_version=kwargs.pop("evm_version", None), optimize=override_opt_level or optimize - ), + settings=Settings(evm_version=evm_version, optimize=override_opt_level or optimize), 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"], out["bytecode"] - abi = out["abi"] - bytecode = out["bytecode"] - value = ( - kwargs.pop("value", 0) or kwargs.pop("value_in_eth", 0) * 10**18 - ) # Handle deploying with an eth value. + def deploy_blueprint( + self, + source_code, + optimize, + output_formats, + *args, + override_opt_level=None, + input_bundle=None, + evm_version=None, + initcode_prefix=ERC5202_PREFIX, + ): + abi, bytecode = self._compile( + source_code, optimize, output_formats, override_opt_level, input_bundle, evm_version + ) + bytecode = HexBytes(initcode_prefix) + HexBytes(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 - return self.deploy(abi, bytecode, value, *args, **kwargs) + deployer_abi = [] # just a constructor + deployer = self.deploy(deployer_abi, deploy_bytecode.hex()) + + def factory(address): + return ABIContractFactory.from_abi_dict(abi).at(self, address) - def deploy(self, abi: list[dict], bytecode: str, value: int, *args, **kwargs): + return deployer, factory + + def deploy(self, abi: list[dict], bytecode: str, value=0, *args, **kwargs): factory = ABIContractFactory.from_abi_dict(abi=abi) initcode = bytes.fromhex(bytecode[2:]) @@ -110,9 +141,13 @@ def deploy(self, abi: list[dict], bytecode: str, value: int, *args, **kwargs): ctor = ABIFunction(ctor_abi, contract_name=factory._name) initcode += abi_encode(ctor.signature, ctor._merge_kwargs(*args, **kwargs)) - deployed_at = self.evm.deploy( - deployer=self.deployer, code=list(initcode), value=value, _abi=json.dumps(abi) - ) + try: + deployed_at = self.evm.deploy( + deployer=self.deployer, code=list(initcode), value=value, _abi=json.dumps(abi) + ) + except RuntimeError as e: + raise TransactionFailed(*e.args) from e + address = to_checksum_address(deployed_at) self.bytecode[address] = bytecode From 0e696f9aeaf00e87007e49020a104dcad69fffe9 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 22 Mar 2024 11:12:28 +0100 Subject: [PATCH 10/87] Update pyrevm --- .../builtins/codegen/test_create_functions.py | 16 +++---- tests/revm/revm_env.py | 48 +++++++++---------- 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/tests/functional/builtins/codegen/test_create_functions.py b/tests/functional/builtins/codegen/test_create_functions.py index aaa63a3df7..5a46af89f0 100644 --- a/tests/functional/builtins/codegen/test_create_functions.py +++ b/tests/functional/builtins/codegen/test_create_functions.py @@ -42,7 +42,7 @@ def test() -> address: assert c.test() == checksum_encode("0x" + expected_create_address.hex()) -def test_create_minimal_proxy_to_call(get_contract, revm_env): +def test_create_minimal_proxy_to_call(get_contract): code = """ interface SubContract: def hello() -> Bytes[100]: view @@ -102,7 +102,7 @@ def test2(a: uint256) -> Bytes[100]: c.test2(0) GAS_SENT = 30000 - tx_hash = c.test2(0, transact={"gas": GAS_SENT}) + tx_hash = c.test2(0) receipt = revm_env.get_transaction_receipt(tx_hash) @@ -282,11 +282,8 @@ def test(code_ofst: uint256) -> address: compile_ir.compile_to_assembly(ir, optimize=OptimizationLevel.NONE) ) # manually deploy the bytecode - c = revm_env.contract(abi=[], bytecode=bytecode) - deploy_transaction = c.constructor() - tx_info = {"from": revm_env.accounts[0], "value": 0, "gasPrice": 0} - tx_hash = deploy_transaction.transact(tx_info) - blueprint_address = revm_env.get_transaction_receipt(tx_hash)["contractAddress"] + c = revm_env.deploy(abi=[], bytecode=bytecode) + blueprint_address = c.address d = get_contract(deployer_code, blueprint_address) @@ -424,7 +421,7 @@ 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(): - revm_env.send_transaction({"to": d.address, "data": f"{sig}{encoded}"}) + revm_env.execute_code(d.address, revm_env.deployer, HexBytes(f"{sig}{encoded}")) def test_create_copy_of(get_contract, revm_env, keccak, create2_address_of, tx_failed): @@ -539,7 +536,8 @@ def test(target: address): d = get_contract(deployer_code) - d.test(f.address, transact={"value": 3}) + revm_env.set_balance(revm_env.deployer, 3) + d.test(f.address, value=3) test = FooContract(d.created_address()) assert revm_env.get_code(test.address) == expected_runtime_code diff --git a/tests/revm/revm_env.py b/tests/revm/revm_env.py index b02ac9e182..61a79ce382 100644 --- a/tests/revm/revm_env.py +++ b/tests/revm/revm_env.py @@ -1,5 +1,5 @@ import json -from typing import Callable +from typing import Callable, Tuple from eth_keys.datatypes import PrivateKey from eth_tester.backends.pyevm.main import get_default_account_keys @@ -20,7 +20,6 @@ class RevmEnv: def __init__(self, gas_limit: int, tracing=False) -> None: self.evm = EVM(gas_limit=gas_limit, tracing=tracing) - self.bytecode: dict[HexAddress, str] = {} self.contracts: dict[HexAddress, ABIContract] = {} self._keys: list[PrivateKey] = get_default_account_keys() @@ -35,35 +34,36 @@ def deployer(self) -> HexAddress: def set_balance(self, address: HexAddress, value: int): self.evm.set_balance(address, value) + def contract(self, abi, bytecode) -> "ABIContract": + return ABIContractFactory.from_abi_dict(abi).at(self, bytecode) + def execute_code( self, to_address: HexAddress, sender: HexAddress, data: bytes | None, - value: int | None, - # todo: use or remove arguments - gas: int, - is_modifying: bool, - contract: "ABIContract", + value: int | None = None, + gas: int = 0, + is_modifying: bool = True, + # TODO: Remove the following. They are not used. transact=None, + contract=None, ): try: - fn = self.evm.call_raw_committing if transact is None else self.evm.call_raw - output = fn( + output = self.evm.message_call( to=to_address, caller=sender, calldata=data, value=value, - # gas=gas, - # is_modifying=self.is_mutable, - # contract=self.contract, + gas=gas, + is_static=not is_modifying, ) return bytes(output) except RuntimeError as e: raise TransactionFailed(*e.args) from e def get_code(self, address: HexAddress): - return self.evm.basic(address).code + return HexBytes(self.evm.basic(address).code.rstrip(b"\0")) def register_contract(self, address: HexAddress, contract: "ABIContract"): self.contracts[address] = contract @@ -90,7 +90,7 @@ def deploy_source( def _compile( self, source_code, optimize, output_formats, override_opt_level, input_bundle, evm_version - ): + ) -> Tuple[list[dict], HexBytes]: out = compile_code( source_code, # test that all output formats can get generated @@ -101,7 +101,7 @@ def _compile( ) parse_vyper_source(source_code) # Test grammar. json.dumps(out["metadata"]) # test metadata is json serializable - return out["abi"], out["bytecode"] + return out["abi"], HexBytes(out["bytecode"]) def deploy_blueprint( self, @@ -117,25 +117,25 @@ def deploy_blueprint( abi, bytecode = self._compile( source_code, optimize, output_formats, override_opt_level, input_bundle, evm_version ) - bytecode = HexBytes(initcode_prefix) + HexBytes(bytecode) + bytecode = HexBytes(initcode_prefix + 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 + deploy_bytecode = deploy_preamble + bytecode deployer_abi = [] # just a constructor - deployer = self.deploy(deployer_abi, deploy_bytecode.hex()) + deployer = self.deploy(deployer_abi, deploy_bytecode, value=0, *args) def factory(address): return ABIContractFactory.from_abi_dict(abi).at(self, address) return deployer, factory - def deploy(self, abi: list[dict], bytecode: str, value=0, *args, **kwargs): + def deploy(self, abi: list[dict], bytecode: bytes, value=0, *args, **kwargs): factory = ABIContractFactory.from_abi_dict(abi=abi) - initcode = bytes.fromhex(bytecode[2:]) + 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) @@ -143,14 +143,10 @@ def deploy(self, abi: list[dict], bytecode: str, value=0, *args, **kwargs): try: deployed_at = self.evm.deploy( - deployer=self.deployer, code=list(initcode), value=value, _abi=json.dumps(abi) + deployer=self.deployer, code=initcode, value=value, _abi=json.dumps(abi) ) except RuntimeError as e: raise TransactionFailed(*e.args) from e address = to_checksum_address(deployed_at) - self.bytecode[address] = bytecode - - abi_contract = factory.at(self, address) - - return abi_contract + return factory.at(self, address) From 4e66d1c2629a9708bdee0b0f26ae36984bba6024 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 22 Mar 2024 11:13:28 +0100 Subject: [PATCH 11/87] Use fork --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 345e9155c9..4c3d281c9a 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ "hypothesis[lark]>=6.0,<7.0", "eth-stdlib==0.2.7", "setuptools", - "pyrevm @ git+https://github.com/gakonst/pyrevm.git@master", + "pyrevm @ git+https://github.com/DanielSchiavini/pyrevm.git@revm", "typing_extensions", # we can remove this once dependencies upgrade to eth-rlp>=2.0 ], "lint": [ From 9b757c0a3eeabcfd4359e3ca6d591949ff7f3ccb Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 22 Mar 2024 15:15:04 +0100 Subject: [PATCH 12/87] Fix tests, do not return tuples --- .../builtins/codegen/test_abi_decode.py | 4 ++-- .../builtins/codegen/test_abi_encode.py | 6 ++--- .../builtins/codegen/test_create_functions.py | 10 ++++---- .../functional/builtins/codegen/test_empty.py | 6 +++-- .../builtins/codegen/test_raw_call.py | 2 +- .../functional/builtins/codegen/test_send.py | 24 +++++++++++-------- tests/revm/abi.py | 6 +++++ tests/revm/abi_contract.py | 5 ++-- tests/revm/revm_env.py | 9 +++++-- 9 files changed, 45 insertions(+), 27 deletions(-) diff --git a/tests/functional/builtins/codegen/test_abi_decode.py b/tests/functional/builtins/codegen/test_abi_decode.py index 86843bb197..1cefd49ee2 100644 --- a/tests/functional/builtins/codegen/test_abi_decode.py +++ b/tests/functional/builtins/codegen/test_abi_decode.py @@ -268,7 +268,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): @@ -292,7 +292,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 9ab6efbd65..f014c47a19 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_create_functions.py b/tests/functional/builtins/codegen/test_create_functions.py index 5a46af89f0..43274d8038 100644 --- a/tests/functional/builtins/codegen/test_create_functions.py +++ b/tests/functional/builtins/codegen/test_create_functions.py @@ -102,12 +102,12 @@ def test2(a: uint256) -> Bytes[100]: c.test2(0) GAS_SENT = 30000 - tx_hash = c.test2(0) - - receipt = revm_env.get_transaction_receipt(tx_hash) + with tx_failed(): + c.test2(0, transact={"gas": GAS_SENT}) - assert receipt["status"] == 0 - assert receipt["gasUsed"] < GAS_SENT + receipt = revm_env.evm.result + assert receipt.is_success is False + assert receipt.gas_used < GAS_SENT def test_create_minimal_proxy_to_create2(get_contract, create2_address_of, keccak, tx_failed): diff --git a/tests/functional/builtins/codegen/test_empty.py b/tests/functional/builtins/codegen/test_empty.py index 74c8e765ae..7820555c32 100644 --- a/tests/functional/builtins/codegen/test_empty.py +++ b/tests/functional/builtins/codegen/test_empty.py @@ -1,5 +1,6 @@ import pytest +from tests.conftest import _get_contract from vyper.exceptions import InstantiationException, TypeMismatch @@ -667,7 +668,7 @@ def bar(a: address) -> (uint256, Bytes[33], Bytes[65], uint256): assert c2.bar(c1.address) == [12] + expected + [42] -def test_empty_array_in_event_logging(get_contract, get_logs): +def test_empty_array_in_event_logging(get_contract, get_logs, optimize, output_formats, w3): code = """ event MyLog: arg1: Bytes[64] @@ -687,7 +688,8 @@ def foo(): ) """ - c = get_contract(code) + # todo: add logs to pyrevm + c = _get_contract(w3, code, optimize, output_formats) log = get_logs(c.foo(transact={}), c, "MyLog")[0] assert log.args.arg1 == b"hello" * 9 diff --git a/tests/functional/builtins/codegen/test_raw_call.py b/tests/functional/builtins/codegen/test_raw_call.py index 7784bfa2f7..8897784560 100644 --- a/tests/functional/builtins/codegen/test_raw_call.py +++ b/tests/functional/builtins/codegen/test_raw_call.py @@ -201,7 +201,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) diff --git a/tests/functional/builtins/codegen/test_send.py b/tests/functional/builtins/codegen/test_send.py index 779c67e7e5..a3f203b321 100644 --- a/tests/functional/builtins/codegen/test_send.py +++ b/tests/functional/builtins/codegen/test_send.py @@ -1,4 +1,4 @@ -def test_send(tx_failed, get_contract): +def test_send(tx_failed, get_contract, revm_env): send_test = """ @external def foo(): @@ -8,6 +8,7 @@ def foo(): def fop(): send(msg.sender, 10) """ + revm_env.set_balance(revm_env.deployer, 1000) c = get_contract(send_test, value=10) with tx_failed(): c.foo(transact={}) @@ -16,7 +17,7 @@ def fop(): c.fop(transact={}) -def test_default_gas(get_contract, w3): +def test_default_gas(get_contract, revm_env, tx_failed): """ Tests to verify that send to default function will send limited gas (2300), but raw_call can send more. @@ -42,25 +43,27 @@ def __default__(): self.last_sender = msg.sender """ + revm_env.set_balance(revm_env.deployer, 100000 * 3) 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, transact={"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 revm_env.get_balance(sender.address) == 1 + assert revm_env.get_balance(receiver.address) == 0 sender.test_call(receiver.address, transact={"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 revm_env.get_balance(sender.address) == 0 + assert revm_env.get_balance(receiver.address) == 1 -def test_send_gas_stipend(get_contract, w3): +def test_send_gas_stipend(get_contract, revm_env): """ Tests to verify that adding gas stipend to send() will send sufficient gas """ @@ -83,6 +86,7 @@ def __default__(): self.last_sender = msg.sender """ + revm_env.set_balance(revm_env.deployer, 100000 * 3) sender = get_contract(sender_code, value=1) receiver = get_contract(receiver_code) @@ -90,5 +94,5 @@ def __default__(): # 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 revm_env.get_balance(sender.address) == 0 + assert revm_env.get_balance(receiver.address) == 1 diff --git a/tests/revm/abi.py b/tests/revm/abi.py index 6776ca8652..fbf65b00da 100644 --- a/tests/revm/abi.py +++ b/tests/revm/abi.py @@ -2,6 +2,7 @@ from decimal import Decimal from typing import Any +from eth.codecs.abi import nodes from eth.codecs.abi.decoder import Decoder from eth.codecs.abi.encoder import Encoder from eth.codecs.abi.exceptions import ABIError @@ -20,6 +21,11 @@ def visit_AddressNode( address = super().visit_AddressNode(node, value, checksum, **kwargs) return address if address != "0x0000000000000000000000000000000000000000" else None + @classmethod + def visit_TupleNode(cls, node: nodes.TupleNode, value: bytes, **kwargs) -> list: + tup = super().visit_TupleNode(node, value, **kwargs) + return list(tup) + class _Encoder(Encoder): """ diff --git a/tests/revm/abi_contract.py b/tests/revm/abi_contract.py index f806eaa275..eb2241f4e2 100644 --- a/tests/revm/abi_contract.py +++ b/tests/revm/abi_contract.py @@ -122,7 +122,8 @@ def __call__(self, *args, value=0, gas=None, sender=None, transact=None, **kwarg case (single,): return single case multiple: - return tuple(multiple) + # this should return a tuple, but for backwards compatibility we return a list + return multiple class ABIOverload: @@ -241,7 +242,7 @@ def method_id_map(self): """ return {function.method_id: function for function in self._functions} - def marshal_to_python(self, result: bytes, abi_type: list[str]) -> tuple[Any, ...]: + 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 `execute_code` diff --git a/tests/revm/revm_env.py b/tests/revm/revm_env.py index 61a79ce382..1bee815b81 100644 --- a/tests/revm/revm_env.py +++ b/tests/revm/revm_env.py @@ -31,6 +31,9 @@ def accounts(self) -> list[HexAddress]: def deployer(self) -> HexAddress: return self._keys[0].public_key.to_checksum_address() + def get_balance(self, address: HexAddress) -> int: + return self.evm.get_balance(address) + def set_balance(self, address: HexAddress, value: int): self.evm.set_balance(address, value) @@ -46,9 +49,10 @@ def execute_code( gas: int = 0, is_modifying: bool = True, # TODO: Remove the following. They are not used. - transact=None, + transact: dict | None = None, contract=None, ): + gas = transact.get("gas", gas) if transact else gas try: output = self.evm.message_call( to=to_address, @@ -125,7 +129,8 @@ def deploy_blueprint( deploy_bytecode = deploy_preamble + bytecode deployer_abi = [] # just a constructor - deployer = self.deploy(deployer_abi, deploy_bytecode, value=0, *args) + value = 0 + deployer = self.deploy(deployer_abi, deploy_bytecode, value, *args) def factory(address): return ABIContractFactory.from_abi_dict(abi).at(self, address) From c74d53136ea7a38fe17c405192efb1b5fddecb25 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 22 Mar 2024 15:40:53 +0100 Subject: [PATCH 13/87] Expect lists --- tests/functional/builtins/codegen/test_abi_decode.py | 12 ++++++------ .../builtins/codegen/test_create_functions.py | 4 +++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/functional/builtins/codegen/test_abi_decode.py b/tests/functional/builtins/codegen/test_abi_decode.py index 1cefd49ee2..23c10d0263 100644 --- a/tests/functional/builtins/codegen/test_abi_decode.py +++ b/tests/functional/builtins/codegen/test_abi_decode.py @@ -60,17 +60,17 @@ def abi_decode_struct(x: Bytes[544]) -> Human: assert tuple(c.abi_decode(encoded)) == (TEST_ADDR, -1, True, Decimal("-123.4"), test_bytes32) test_bytes32 = b"".join(chr(i).encode("utf-8") for i in range(32)) - human_tuple = ( + human_tuple = [ "foobar", ("vyper", TEST_ADDR, 123, True, Decimal("123.4"), [123, 456, 789], test_bytes32), - ) - args = tuple([human_tuple[0]] + list(human_tuple[1])) + ] + human_t = "((string,(string,address,int128,bool,fixed168x10,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("123.4"), [123, 456, 789], test_bytes32), - ) + ["vyper", TEST_ADDR, 123, True, Decimal("123.4"), [123, 456, 789], test_bytes32], + ] @pytest.mark.parametrize( diff --git a/tests/functional/builtins/codegen/test_create_functions.py b/tests/functional/builtins/codegen/test_create_functions.py index 43274d8038..e924c2cccf 100644 --- a/tests/functional/builtins/codegen/test_create_functions.py +++ b/tests/functional/builtins/codegen/test_create_functions.py @@ -354,7 +354,9 @@ def should_fail(target: address, arg1: String[129], arg2: Bar): self.created_address = create_from_blueprint(target, arg1, arg2) """ FOO = "hello!" - BAR = ("world!",) + BAR = [ + "world!", + ] # deploy a foo so we can compare its bytecode with factory deployed version foo_contract = get_contract(code, FOO, BAR) From a1cbc01955473fd0c9f6aa1defa0e246ba4b962f Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 25 Mar 2024 09:34:41 +0100 Subject: [PATCH 14/87] Reformat --- tests/functional/builtins/codegen/test_create_functions.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/functional/builtins/codegen/test_create_functions.py b/tests/functional/builtins/codegen/test_create_functions.py index e924c2cccf..299fef6661 100644 --- a/tests/functional/builtins/codegen/test_create_functions.py +++ b/tests/functional/builtins/codegen/test_create_functions.py @@ -354,9 +354,7 @@ def should_fail(target: address, arg1: String[129], arg2: Bar): self.created_address = create_from_blueprint(target, arg1, arg2) """ FOO = "hello!" - BAR = [ - "world!", - ] + BAR = ["world!"] # deploy a foo so we can compare its bytecode with factory deployed version foo_contract = get_contract(code, FOO, BAR) From fc1bcbe64674d68d2430f1c2119d54597a78ab76 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 25 Mar 2024 14:37:11 +0100 Subject: [PATCH 15/87] Implement revm log parsing --- .../functional/builtins/codegen/test_empty.py | 6 +- tests/functional/builtins/conftest.py | 12 +++ tests/revm/abi_contract.py | 99 +++++++++++++++++-- 3 files changed, 105 insertions(+), 12 deletions(-) diff --git a/tests/functional/builtins/codegen/test_empty.py b/tests/functional/builtins/codegen/test_empty.py index 7820555c32..74c8e765ae 100644 --- a/tests/functional/builtins/codegen/test_empty.py +++ b/tests/functional/builtins/codegen/test_empty.py @@ -1,6 +1,5 @@ import pytest -from tests.conftest import _get_contract from vyper.exceptions import InstantiationException, TypeMismatch @@ -668,7 +667,7 @@ def bar(a: address) -> (uint256, Bytes[33], Bytes[65], uint256): assert c2.bar(c1.address) == [12] + expected + [42] -def test_empty_array_in_event_logging(get_contract, get_logs, optimize, output_formats, w3): +def test_empty_array_in_event_logging(get_contract, get_logs): code = """ event MyLog: arg1: Bytes[64] @@ -688,8 +687,7 @@ def foo(): ) """ - # todo: add logs to pyrevm - c = _get_contract(w3, code, optimize, output_formats) + c = get_contract(code) log = get_logs(c.foo(transact={}), c, "MyLog")[0] assert log.args.arg1 == b"hello" * 9 diff --git a/tests/functional/builtins/conftest.py b/tests/functional/builtins/conftest.py index a8b18bb8aa..3d4f242482 100644 --- a/tests/functional/builtins/conftest.py +++ b/tests/functional/builtins/conftest.py @@ -1,5 +1,7 @@ import pytest +from tests.revm.abi_contract import ABIContract + @pytest.fixture(scope="module") def get_contract(get_revm_contract): @@ -9,3 +11,13 @@ def get_contract(get_revm_contract): @pytest.fixture(scope="module") def deploy_blueprint_for(deploy_blueprint_revm): return deploy_blueprint_revm + + +@pytest.fixture(scope="module") +def get_logs(revm_env): + def get_logs(tx_result, c: ABIContract, event_name): + logs = revm_env.evm.result.logs + parsed_logs = [c.parse_log(log) for log in logs if c.address == log.address] + return [log for log in parsed_logs if log.event == event_name] + + return get_logs diff --git a/tests/revm/abi_contract.py b/tests/revm/abi_contract.py index eb2241f4e2..d096c8b948 100644 --- a/tests/revm/abi_contract.py +++ b/tests/revm/abi_contract.py @@ -1,13 +1,17 @@ -from collections import defaultdict +from collections import defaultdict, namedtuple +from dataclasses import dataclass from functools import cached_property from os.path import basename -from typing import TYPE_CHECKING, Any, Optional, Union +from typing import TYPE_CHECKING, Any, Optional, Type, Union from warnings import warn -from eth_typing import HexAddress +from eth_typing import ChecksumAddress, HexAddress +from eth_utils import to_checksum_address +from hexbytes import HexBytes +from pyrevm import Log from vyper.semantics.analysis.base import FunctionVisibility, StateMutability -from vyper.utils import method_id +from vyper.utils import keccak256, method_id from .abi import abi_decode, abi_encode, is_abi_encodable @@ -15,6 +19,64 @@ from tests.revm.revm_env import RevmEnv +@dataclass +class ABILog: + """Represents a parsed log entry from a contract.""" + + address: ChecksumAddress + args: tuple + event: str + + +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"): + return b"" + return keccak256((self.name + self.signature).encode()) + + @property + def name(self) -> str: + 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 signature(self) -> str: + return f"({_format_abi_type(self.argument_types)})" + + def __repr__(self) -> str: + return f"ABI {self._contract_name}.{self.signature} (0x{self.topic_id.hex()})" + + def __str__(self) -> str: + return repr(self) + + def parse(self, log: Log) -> ABILog: + return ABILog( + address=to_checksum_address(log.address), + args=self._parse_args(log), + event=self.name, + ) + + @property + def data_type(self) -> Type[tuple]: + return namedtuple(self.name, [item["name"] for item in self._abi["inputs"]]) + + def _parse_args(self, log: Log) -> tuple: + _, data = log.data + decoded = abi_decode(self.signature, data) + return self.data_type(*decoded) + + class ABIFunction: """A single function in an ABI. It does not include overloads.""" @@ -212,6 +274,7 @@ def __init__( name: str, abi: dict, functions: list[ABIFunction], + log_topics: list[ABILogTopic], address: HexAddress, filename: Optional[str] = None, ): @@ -221,6 +284,7 @@ def __init__( self.abi = abi self._name = name self._functions = functions + self.log_topics = log_topics self._bytecode = self.env.get_code(address) if not self._bytecode: warn(f"Requested {self} but there is no bytecode at that address!", stacklevel=2) @@ -256,13 +320,23 @@ def deployer(self) -> "ABIContractFactory": """ Returns a factory that can be used to retrieve another deployed contract. """ - return ABIContractFactory(self._name, self.abi, self._functions) + return ABIContractFactory(self._name, self.abi, self._functions, self.log_topics) def __repr__(self): file_str = f" (file {self.filename})" if self.filename else "" warn_str = "" if self._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: Log): + """ + Parse a log entry into an ABILog object. + :param log: the log entry to parse + """ + for topic in self.log_topics: + if any(topic.topic_id == HexBytes(t) for t in log.topics): + return topic.parse(log) + raise KeyError(f"Could not find event for log {log.topics}. Found {self.log_topics}") + class ABIContractFactory: """ @@ -272,23 +346,32 @@ class ABIContractFactory: """ def __init__( - self, name: str, abi: dict, functions: list["ABIFunction"], filename: Optional[str] = None + self, + name: str, + abi: dict, + functions: list[ABIFunction], + log_topics: list[ABILogTopic], + filename: Optional[str] = None, ): self._name = name self._abi = abi self._functions = functions + self._log_topics = log_topics self._filename = filename @classmethod def from_abi_dict(cls, abi, name=""): functions = [ABIFunction(item, name) for item in abi if item.get("type") == "function"] - return cls(basename(name), abi, functions, filename=name) + log_topics = [ABILogTopic(item, name) for item in abi if item.get("type") == "event"] + return cls(basename(name), abi, functions, log_topics, filename=name) def at(self, env, address: HexAddress) -> ABIContract: """ Create an ABI contract object for a deployed contract at `address`. """ - contract = ABIContract(env, self._name, self._abi, self._functions, address, self._filename) + contract = ABIContract( + env, self._name, self._abi, self._functions, self._log_topics, address, self._filename + ) env.register_contract(address, contract) return contract From 5150c309e3cb926833e3e36272a148ff896be063 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 25 Mar 2024 14:54:54 +0100 Subject: [PATCH 16/87] Convert more tests to revm --- tests/conftest.py | 11 ++++++++++ tests/functional/builtins/conftest.py | 11 ++-------- tests/functional/grammar/conftest.py | 16 ++++++++++++++ tests/functional/syntax/conftest.py | 16 ++++++++++++++ tests/functional/syntax/test_address_code.py | 22 ++++++++++---------- tests/revm/abi.py | 4 +++- 6 files changed, 59 insertions(+), 21 deletions(-) create mode 100644 tests/functional/grammar/conftest.py create mode 100644 tests/functional/syntax/conftest.py diff --git a/tests/conftest.py b/tests/conftest.py index 1a1da70bf9..352fbb941f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -16,6 +16,7 @@ from web3.providers.eth_tester import EthereumTesterProvider import vyper.evm.opcodes as evm +from tests.revm.abi_contract import ABIContract from tests.revm.revm_env import RevmEnv from tests.utils import working_directory from vyper import compiler @@ -472,6 +473,16 @@ def deploy_blueprint_revm(source_code, *args, **kwargs): return deploy_blueprint_revm +@pytest.fixture(scope="module") +def get_logs_revm(revm_env): + def get_logs(tx_result, c: ABIContract, event_name): + logs = revm_env.evm.result.logs + parsed_logs = [c.parse_log(log) for log in logs if c.address == log.address] + return [log for log in parsed_logs if log.event == event_name] + + return get_logs + + # TODO: this should not be a fixture. # remove me and replace all uses with `with pytest.raises`. @pytest.fixture diff --git a/tests/functional/builtins/conftest.py b/tests/functional/builtins/conftest.py index 3d4f242482..2616a458c8 100644 --- a/tests/functional/builtins/conftest.py +++ b/tests/functional/builtins/conftest.py @@ -1,7 +1,5 @@ import pytest -from tests.revm.abi_contract import ABIContract - @pytest.fixture(scope="module") def get_contract(get_revm_contract): @@ -14,10 +12,5 @@ def deploy_blueprint_for(deploy_blueprint_revm): @pytest.fixture(scope="module") -def get_logs(revm_env): - def get_logs(tx_result, c: ABIContract, event_name): - logs = revm_env.evm.result.logs - parsed_logs = [c.parse_log(log) for log in logs if c.address == log.address] - return [log for log in parsed_logs if log.event == event_name] - - return get_logs +def get_logs(get_logs_revm): + return get_logs_revm diff --git a/tests/functional/grammar/conftest.py b/tests/functional/grammar/conftest.py new file mode 100644 index 0000000000..2616a458c8 --- /dev/null +++ b/tests/functional/grammar/conftest.py @@ -0,0 +1,16 @@ +import pytest + + +@pytest.fixture(scope="module") +def get_contract(get_revm_contract): + return get_revm_contract + + +@pytest.fixture(scope="module") +def deploy_blueprint_for(deploy_blueprint_revm): + return deploy_blueprint_revm + + +@pytest.fixture(scope="module") +def get_logs(get_logs_revm): + return get_logs_revm diff --git a/tests/functional/syntax/conftest.py b/tests/functional/syntax/conftest.py new file mode 100644 index 0000000000..2616a458c8 --- /dev/null +++ b/tests/functional/syntax/conftest.py @@ -0,0 +1,16 @@ +import pytest + + +@pytest.fixture(scope="module") +def get_contract(get_revm_contract): + return get_revm_contract + + +@pytest.fixture(scope="module") +def deploy_blueprint_for(deploy_blueprint_revm): + return deploy_blueprint_revm + + +@pytest.fixture(scope="module") +def get_logs(get_logs_revm): + return get_logs_revm diff --git a/tests/functional/syntax/test_address_code.py b/tests/functional/syntax/test_address_code.py index 6556fc90b9..dc648d981b 100644 --- a/tests/functional/syntax/test_address_code.py +++ b/tests/functional/syntax/test_address_code.py @@ -1,8 +1,9 @@ +import json from typing import Type import pytest from eth_tester.exceptions import TransactionFailed -from web3 import Web3 +from hexbytes import HexBytes from vyper import compiler from vyper.compiler.settings import Settings @@ -15,30 +16,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 deploy_precompiled_contract(revm_env): + return lambda: revm_env.deploy(json.loads(PRECOMPILED_ABI), HexBytes(PRECOMPILED_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, deploy_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) + precompiled_contract = deploy_precompiled_contract() 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(deploy_precompiled_contract, get_contract): start = len(PRECOMPILED) - 5 length = 10 code = f""" @@ -47,7 +47,7 @@ def code_slice(x: address) -> Bytes[{length}]: return slice(x.code, {start}, {length}) """ contract = get_contract(code) - precompiled_contract = _deploy_precompiled_contract(w3) + precompiled_contract = deploy_precompiled_contract() with pytest.raises(TransactionFailed): contract.code_slice(precompiled_contract.address) diff --git a/tests/revm/abi.py b/tests/revm/abi.py index fbf65b00da..15eb849a2e 100644 --- a/tests/revm/abi.py +++ b/tests/revm/abi.py @@ -46,9 +46,11 @@ def visit_FixedNode(cls, node: FixedNode, value: Decimal | int) -> bytes: return super().visit_FixedNode(node, value) @classmethod - def visit_AddressNode(cls, node: AddressNode, value: str | HexBytes) -> bytes: + 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) From d162f5c92c7b8ad83bda744d8a0ecc2e9d8b9fbe Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 26 Mar 2024 17:01:16 +0100 Subject: [PATCH 17/87] Convert functional tests to revm --- tests/conftest.py | 20 +- .../builtins/codegen/test_abi_decode.py | 10 +- .../builtins/codegen/test_abi_encode.py | 6 +- .../builtins/codegen/test_create_functions.py | 2 +- .../functional/builtins/codegen/test_empty.py | 22 +- .../builtins/codegen/test_raw_call.py | 6 +- .../builtins/codegen/test_sha256.py | 2 +- .../functional/builtins/codegen/test_slice.py | 12 +- .../test_default_function.py | 63 ++-- .../test_default_parameters.py | 43 +-- .../calling_convention/test_erc20_abi.py | 36 +-- .../test_external_contract_calls.py | 106 +++---- .../codegen/calling_convention/test_return.py | 49 ++- .../test_self_call_struct.py | 6 +- .../test_block_number.py | 8 +- .../codegen/environment_variables/test_tx.py | 3 +- .../codegen/features/decorators/conftest.py | 6 + .../features/decorators/test_nonreentrant.py | 14 +- .../features/decorators/test_payable.py | 20 +- .../features/decorators/test_private.py | 51 ++-- .../features/iteration/test_range_in.py | 4 +- .../codegen/features/test_address_balance.py | 12 +- .../codegen/features/test_assert.py | 32 +- .../features/test_assert_unreachable.py | 39 ++- .../codegen/features/test_assignment.py | 4 +- .../codegen/features/test_bytes_map_keys.py | 2 +- .../codegen/features/test_clampers.py | 94 +++--- .../codegen/features/test_constructor.py | 16 +- .../codegen/features/test_immutable.py | 2 +- .../codegen/features/test_internal_call.py | 18 +- .../codegen/features/test_logging.py | 285 +++++++++--------- .../features/test_logging_from_call.py | 31 +- .../codegen/features/test_reverting.py | 12 +- .../codegen/features/test_short_circuiting.py | 16 +- .../codegen/features/test_ternary.py | 2 +- .../codegen/integration/test_crowdfund.py | 12 +- .../codegen/integration/test_escrow.py | 15 +- .../modules/test_stateless_functions.py | 6 +- .../codegen/storage_variables/test_getters.py | 2 +- tests/functional/codegen/test_interfaces.py | 19 +- .../functional/codegen/test_selector_table.py | 17 +- .../codegen/types/numbers/test_constants.py | 16 +- .../codegen/types/numbers/test_decimals.py | 4 +- .../codegen/types/numbers/test_isqrt.py | 2 +- .../codegen/types/numbers/test_modulo.py | 2 +- .../codegen/types/numbers/test_sqrt.py | 4 +- .../codegen/types/test_dynamic_array.py | 21 +- tests/functional/codegen/types/test_flag.py | 6 +- tests/functional/codegen/types/test_lists.py | 10 +- tests/functional/codegen/types/test_string.py | 4 +- tests/functional/codegen/types/test_struct.py | 8 +- tests/functional/{builtins => }/conftest.py | 10 + .../examples/tokens/test_erc1155.py | 8 +- tests/functional/grammar/conftest.py | 16 - tests/functional/syntax/conftest.py | 16 - tests/functional/syntax/test_msg_data.py | 2 +- tests/functional/syntax/test_return_tuple.py | 16 +- tests/revm/abi.py | 6 - tests/revm/abi_contract.py | 71 +++-- tests/revm/revm_env.py | 78 +++-- 60 files changed, 759 insertions(+), 666 deletions(-) create mode 100644 tests/functional/codegen/features/decorators/conftest.py rename tests/functional/{builtins => }/conftest.py (55%) delete mode 100644 tests/functional/grammar/conftest.py delete mode 100644 tests/functional/syntax/conftest.py diff --git a/tests/conftest.py b/tests/conftest.py index 352fbb941f..607ca40137 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -172,10 +172,15 @@ def _none_addr(datatype, data): @pytest.fixture(scope="module") def gas_limit(): # set absurdly high gas limit so that london basefee never adjusts - # (note: 2**63 - 1 is max that evm allows) + # (note: 2**63 - 1 is max that py-evm allows) return 10**10 +@pytest.fixture(scope="module") +def initial_balance(): + return 0 + + @pytest.fixture(scope="module") def tester(gas_limit): custom_genesis = PyEVMBackend._generate_genesis_params(overrides={"gas_limit": gas_limit}) @@ -185,8 +190,10 @@ def tester(gas_limit): @pytest.fixture(scope="module") -def revm_env(gas_limit): - return RevmEnv(gas_limit, tracing=False) +def revm_env(gas_limit, initial_balance): + revm = RevmEnv(gas_limit, tracing=False, block_number=1) + revm.set_balance(revm.deployer, initial_balance) + return revm def zero_gas_price_strategy(web3, transaction_params=None): @@ -364,13 +371,18 @@ def _get_contract( @pytest.fixture(scope="module") -def get_contract(w3, optimize, output_formats): +def get_contract_pyevm(w3, optimize, output_formats): def fn(source_code, *args, **kwargs): return _get_contract(w3, source_code, optimize, output_formats, *args, **kwargs) return fn +@pytest.fixture(scope="module") +def get_contract(get_contract_pyevm): + return get_contract_pyevm + + @pytest.fixture(scope="module") def get_revm_contract(revm_env, optimize, output_formats): def fn(source_code, *args, **kwargs): diff --git a/tests/functional/builtins/codegen/test_abi_decode.py b/tests/functional/builtins/codegen/test_abi_decode.py index 23c10d0263..e276e03944 100644 --- a/tests/functional/builtins/codegen/test_abi_decode.py +++ b/tests/functional/builtins/codegen/test_abi_decode.py @@ -67,10 +67,10 @@ def abi_decode_struct(x: Bytes[544]) -> Human: human_t = "((string,(string,address,int128,bool,fixed168x10,uint256[3],bytes32)))" human_encoded = abi.encode(human_t, (human_tuple,)) - assert c.abi_decode_struct(human_encoded) == [ + assert c.abi_decode_struct(human_encoded) == ( "foobar", - ["vyper", TEST_ADDR, 123, True, Decimal("123.4"), [123, 456, 789], test_bytes32], - ] + ("vyper", TEST_ADDR, 123, True, Decimal("123.4"), [123, 456, 789], test_bytes32), + ) @pytest.mark.parametrize( @@ -268,7 +268,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): @@ -292,7 +292,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 f014c47a19..9ab6efbd65 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_create_functions.py b/tests/functional/builtins/codegen/test_create_functions.py index 299fef6661..43274d8038 100644 --- a/tests/functional/builtins/codegen/test_create_functions.py +++ b/tests/functional/builtins/codegen/test_create_functions.py @@ -354,7 +354,7 @@ def should_fail(target: address, arg1: String[129], arg2: Bar): self.created_address = create_from_blueprint(target, arg1, arg2) """ FOO = "hello!" - BAR = ["world!"] + BAR = ("world!",) # deploy a foo so we can compare its bytecode with factory deployed version foo_contract = get_contract(code, FOO, BAR) diff --git a/tests/functional/builtins/codegen/test_empty.py b/tests/functional/builtins/codegen/test_empty.py index 74c8e765ae..6f630aed18 100644 --- a/tests/functional/builtins/codegen/test_empty.py +++ b/tests/functional/builtins/codegen/test_empty.py @@ -500,8 +500,8 @@ def e() -> X: c = get_contract_with_gas_estimation(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]) @@ -588,11 +588,11 @@ def delete(): c = get_contract_with_gas_estimation(code) - assert c.get() == [0, 0] + assert c.get() == (0, 0) c.set(transact={}) - assert c.get() == [333, 444] + assert c.get() == (333, 444) c.delete(transact={}) - assert c.get() == [0, 0] + 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): diff --git a/tests/functional/builtins/codegen/test_raw_call.py b/tests/functional/builtins/codegen/test_raw_call.py index 8897784560..4228c98187 100644 --- a/tests/functional/builtins/codegen/test_raw_call.py +++ b/tests/functional/builtins/codegen/test_raw_call.py @@ -50,7 +50,7 @@ def foo() -> Bytes[5]: assert c.foo() == b"moose" -def test_multiple_levels(w3, get_contract_with_gas_estimation): +def test_multiple_levels(revm_env, get_contract_with_gas_estimation): inner_code = """ @external def returnten() -> int128: @@ -78,10 +78,10 @@ def create_and_return_proxy(inp: address) -> address: _, preamble, callcode = eip1167_bytecode() - c3 = c2.create_and_return_proxy(c.address, call={}) + c3 = c2.create_and_return_proxy(c.address) c2.create_and_return_proxy(c.address, transact={}) - c3_contract_code = w3.to_bytes(w3.eth.get_code(c3)) + c3_contract_code = revm_env.get_code(c3) assert c3_contract_code[:10] == HexBytes(preamble) assert c3_contract_code[-15:] == HexBytes(callcode) diff --git a/tests/functional/builtins/codegen/test_sha256.py b/tests/functional/builtins/codegen/test_sha256.py index 8e1b89bd31..17e3dbc307 100644 --- a/tests/functional/builtins/codegen/test_sha256.py +++ b/tests/functional/builtins/codegen/test_sha256.py @@ -29,7 +29,7 @@ def bar() -> (bytes32 , bytes32): """ c = get_contract_with_gas_estimation(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): diff --git a/tests/functional/builtins/codegen/test_slice.py b/tests/functional/builtins/codegen/test_slice.py index 1d3b863073..5eb81f2dfa 100644 --- a/tests/functional/builtins/codegen/test_slice.py +++ b/tests/functional/builtins/codegen/test_slice.py @@ -213,12 +213,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): diff --git a/tests/functional/codegen/calling_convention/test_default_function.py b/tests/functional/codegen/calling_convention/test_default_function.py index 411f38eac9..0fd4a3510d 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(revm_env, tx_failed, get_contract_with_gas_estimation): code = """ x: public(int128) @@ -9,13 +12,13 @@ def __init__(): c = get_contract_with_gas_estimation(code) assert c.x() == 123 - assert w3.eth.get_balance(c.address) == 0 + assert revm_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 + revm_env.execute_code(c.address, value=to_wei(0.1, "ether")) + assert revm_env.get_balance(c.address) == 0 -def test_basic_default(w3, get_logs, get_contract_with_gas_estimation): +def test_basic_default(revm_env, get_logs, get_contract_with_gas_estimation): code = """ event Sent: sender: indexed(address) @@ -26,13 +29,13 @@ 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") + revm_env.set_balance(revm_env.deployer, 10**18) + (log,) = get_logs(revm_env.execute_code(c.address, value=10**17), c, "Sent") + assert revm_env.deployer == log.args.sender + assert revm_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(revm_env, get_logs, get_contract_with_gas_estimation): code = """ event Sent: sender: indexed(address) @@ -50,12 +53,12 @@ def __default__(): """ 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") + (log,) = get_logs(revm_env.execute_code(c.address, value=10**17), c, "Sent") + assert revm_env.deployer == log.args.sender + assert revm_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(revm_env, tx_failed, get_contract_with_gas_estimation): code = """ event Sent: sender: indexed(address) @@ -67,7 +70,7 @@ def __default__(): c = get_contract_with_gas_estimation(code) with tx_failed(): - w3.eth.send_transaction({"to": c.address, "value": 10**17}) + revm_env.execute_code(c.address, value=10**17) def test_multi_arg_default(assert_compile_failed, get_contract_with_gas_estimation): @@ -100,7 +103,7 @@ def __default__(): assert_compile_failed(lambda: get_contract_with_gas_estimation(code)) -def test_zero_method_id(w3, get_logs, get_contract, tx_failed): +def test_zero_method_id(revm_env, get_logs, get_contract, tx_failed): # test a method with 0x00000000 selector, # expects at least 36 bytes of calldata. code = """ @@ -124,10 +127,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")) + result = revm_env.execute_code(c.address, value=0, data=data) + (log,) = get_logs(result, c, "Sent") + return log.args.sig assert 1 == _call_with_bytes("0x") @@ -147,7 +150,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(revm_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 +173,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")) + result = revm_env.execute_code(c.address, value=0, data=data, gas=10**6) + (log,) = get_logs(result, c, "Sent") + return log.args.sig assert 1 == _call_with_bytes("0x") @@ -188,7 +191,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(revm_env, get_logs, get_contract): code = """ event Sent: sig: uint256 @@ -211,10 +214,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")) + result = revm_env.execute_code(c.address, value=0, data=data) + (log,) = get_logs(result, 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..c9aaa5368d 100644 --- a/tests/functional/codegen/calling_convention/test_default_parameters.py +++ b/tests/functional/codegen/calling_convention/test_default_parameters.py @@ -1,4 +1,5 @@ import pytest +from eth.codecs.abi.exceptions import EncodeError from vyper.compiler import compile_code from vyper.exceptions import ( @@ -17,7 +18,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 +52,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 +69,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 +87,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 +105,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): @@ -191,17 +192,17 @@ 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 monkeypatch.setattr("eth_abi.encoding.NumberEncoder.validate_value", validate_value) - assert c.bar(200, 2**127 - 1) == [200, 2**127 - 1] - with tx_failed(): - c.bar(200, 2**127) + assert c.bar(200, 2**127 - 1) == (200, 2**127 - 1) + with tx_failed(EncodeError): + c.bar(200, 2**127, disambiguate_signature="bar(int128,int128)") 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, revm_env): code = """ xx: uint256 @@ -249,11 +250,13 @@ def get_balance() -> uint256: return self.balance """ c = get_contract(code) + revm_env.set_balance(revm_env.deployer, 31337 + 9001) c.foo(transact={"value": 31337}) assert c.bar() == 31337 c.foo(666, transact={"value": 9001}) assert c.bar() == 31337 + 666 assert c.get_balance() == 31337 + 9001 + assert revm_env.get_balance(revm_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..8cd5b5926f 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(revm_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(revm_env.deployer) == TOKEN_TOTAL_SUPPLY + assert erc20_caller.balanceOf(revm_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(revm_env, erc20, erc20_caller, tx_failed): # Basic transfer. erc20.transfer(erc20_caller.address, 10, transact={}) assert erc20.balanceOf(erc20_caller.address) == 10 - erc20_caller.transfer(w3.eth.accounts[1], 10, transact={}) + erc20_caller.transfer(revm_env.accounts[1], 10, transact={}) assert erc20.balanceOf(erc20_caller.address) == 0 - assert erc20.balanceOf(w3.eth.accounts[1]) == 10 + assert erc20.balanceOf(revm_env.accounts[1]) == 10 # more than allowed with tx_failed(): - erc20_caller.transfer(w3.eth.accounts[1], TOKEN_TOTAL_SUPPLY) + erc20_caller.transfer(revm_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(revm_env.accounts[1], -1) -def test_caller_approve_allowance(w3, erc20, erc20_caller): +def test_caller_approve_allowance(revm_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_caller.allowance(revm_env.deployer, erc20_caller.address) == 10 -def test_caller_tranfer_from(w3, erc20, erc20_caller, tx_failed): +def test_caller_tranfer_from(revm_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(revm_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={}) + erc20_caller.transferFrom(revm_env.deployer, erc20_caller.address, 5, transact={}) 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(revm_env.deployer, erc20_caller.address) == 5 + erc20_caller.transferFrom(revm_env.deployer, erc20_caller.address, 3, transact={}) assert erc20.balanceOf(erc20_caller.address) == 8 - assert erc20_caller.allowance(w3.eth.accounts[0], erc20_caller.address) == 2 + assert erc20_caller.allowance(revm_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 0f5f915a48..13ec633c26 100644 --- a/tests/functional/codegen/calling_convention/test_external_contract_calls.py +++ b/tests/functional/codegen/calling_convention/test_external_contract_calls.py @@ -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("0.0"), b"dog", Decimal("1e-10")] + assert result == (Decimal("0.0"), b"dog", Decimal("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) @@ -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(revm_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(revm_env.deployer) with tx_failed(): - c2.foo(w3.eth.accounts[3]) + c2.foo(revm_env.accounts[3]) def test_invalid_contract_reference_declaration(tx_failed, get_contract): @@ -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(revm_env, get_contract_with_gas_estimation): contract_1 = """ @payable @external @@ -1393,21 +1392,26 @@ def get_lucky(amount_to_send: uint256) -> int128: c2.set_contract(c1.address, transact={}) # Send some eth - assert c2.get_lucky(0, call={"value": 500}) == 1 + revm_env.set_balance(revm_env.deployer, 10000) + with revm_env.anchor(): + assert c2.get_lucky(0, transact={"value": 500}) == 1 + c2.get_lucky(0, transact={"value": 500}) # 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 revm_env.get_balance(c1.address) == 500 + assert revm_env.get_balance(c2.address) == 0 # Send subset of amount - assert c2.get_lucky(250, call={"value": 500}) == 1 + with revm_env.anchor(): + assert c2.get_lucky(250, transact={"value": 500}) == 1 c2.get_lucky(250, transact={"value": 500}) # 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 revm_env.get_balance(c1.address) == 750 + assert revm_env.get_balance(c2.address) == 250 + assert revm_env.get_balance(revm_env.deployer) == 9000 def test_external_call_with_gas(tx_failed, get_contract_with_gas_estimation): @@ -1580,8 +1584,8 @@ 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): @@ -1611,7 +1615,7 @@ def test(addr: address) -> (int128, address): c2 = get_contract_with_gas_estimation(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)]) @@ -1644,7 +1648,7 @@ def test(addr: address) -> (int128, String[{ln}], Bytes[{ln}]): c2 = get_contract_with_gas_estimation(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): @@ -1705,7 +1709,7 @@ def test(addr: address) -> (int128, address): c2 = get_contract_with_gas_estimation(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)]) @@ -1743,7 +1747,7 @@ def test(addr: address) -> (int128, String[{ln}], Bytes[{ln}]): c2 = get_contract_with_gas_estimation(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): @@ -1907,7 +1911,7 @@ def test(addr: address) -> (X, uint256): c2 = get_contract_with_gas_estimation(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)]) @@ -1954,7 +1958,7 @@ def test(addr: address) -> (X, uint256): c2 = get_contract_with_gas_estimation(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): @@ -2002,8 +2006,8 @@ def test(addr: address) -> (A, bool): c1 = get_contract_with_gas_estimation(contract_1) c2 = get_contract_with_gas_estimation(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( @@ -2496,7 +2500,7 @@ def do_stuff(f: Foo) -> uint256: @pytest.mark.parametrize("typ,val", [("address", TEST_ADDR)]) -def test_calldata_clamp(w3, get_contract, tx_failed, keccak, typ, val): +def test_calldata_clamp(revm_env, get_contract, tx_failed, keccak, typ, val): code = f""" @external def foo(a: {typ}): @@ -2510,17 +2514,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}) + revm_env.execute_code(c1.address, data=malformed) # Static size is exact - w3.eth.send_transaction({"to": c1.address, "data": data}) + revm_env.execute_code(c1.address, data=data) # Static size exceeds by 1 byte, ok - w3.eth.send_transaction({"to": c1.address, "data": data + "ff"}) + revm_env.execute_code(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, keccak, typ, val): +def test_dynamic_calldata_clamp(revm_env, get_contract, tx_failed, keccak, typ, val): code = f""" @external def foo(a: DynArray[{typ}, 3], b: String[5]): @@ -2535,8 +2539,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}) + revm_env.execute_code(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}) + revm_env.execute_code(c1.address, data=valid) diff --git a/tests/functional/codegen/calling_convention/test_return.py b/tests/functional/codegen/calling_convention/test_return.py index fdf6e04d10..614e919fd9 100644 --- a/tests/functional/codegen/calling_convention/test_return.py +++ b/tests/functional/codegen/calling_convention/test_return.py @@ -6,7 +6,7 @@ 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(revm_env, get_contract_with_gas_estimation): selfcall_code_6 = """ @external def hardtest(arg1: Bytes[64], arg2: Bytes[64]) -> Bytes[128]: @@ -17,16 +17,11 @@ def hardtest(arg1: Bytes[64], arg2: Bytes[64]) -> Bytes[128]: 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)) - + # Make sure underlying struct is correctly right padded + res = revm_env.execute_code( + to_address=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 @@ -92,19 +87,19 @@ def out_very_long_bytes() -> (int128, Bytes[1024], int128, address): c = get_contract_with_gas_estimation(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, 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() == ( 5555, long_string.encode(), 6666, "0x0000000000000000000000000000000000001234", - ] + ) def test_return_type_signatures(get_contract_with_gas_estimation): @@ -115,7 +110,7 @@ def out_literals() -> (int128, address, Bytes[6]): """ c = get_contract_with_gas_estimation(code) - assert c._classic_contract.abi[0]["outputs"] == [ + assert c.abi[0]["outputs"] == [ {"type": "int128", "name": ""}, {"type": "address", "name": ""}, {"type": "bytes", "name": ""}, @@ -143,7 +138,7 @@ def test() -> (int128, address, Bytes[10]): c = get_contract_with_gas_estimation(code) - assert c.out_literals() == c.test() == [1, None, b"random"] + assert c.out_literals() == c.test() == (1, None, b"random") def test_return_tuple_assign_storage(get_contract_with_gas_estimation): @@ -182,10 +177,10 @@ def test3() -> (address, int128): c = get_contract_with_gas_estimation(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 +202,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,7 +224,7 @@ 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): 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 f3ec96f1c0..b7dda7a823 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 decimal import Decimal -def test_call_to_self_struct(w3, get_contract): +def test_call_to_self_struct(revm_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("0.1")) == ( Decimal("0.1"), - w3.eth.get_block(w3.eth.block_number)["timestamp"], + revm_env.get_block().timestamp, ) assert c.wrap_get_my_struct_BROKEN(Decimal("0.1")) == ( Decimal("0.1"), - w3.eth.get_block(w3.eth.block_number)["timestamp"], + revm_env.get_block().timestamp, ) diff --git a/tests/functional/codegen/environment_variables/test_block_number.py b/tests/functional/codegen/environment_variables/test_block_number.py index 269371a32d..8ed72043c4 100644 --- a/tests/functional/codegen/environment_variables/test_block_number.py +++ b/tests/functional/codegen/environment_variables/test_block_number.py @@ -1,4 +1,7 @@ -def test_block_number(get_contract_with_gas_estimation, w3): +from pyrevm import EVM, BlockEnv, Env + + +def test_block_number(get_contract_with_gas_estimation, revm_env, optimize, output_formats): block_number_code = """ @external def block_number() -> uint256: @@ -7,5 +10,6 @@ def block_number() -> uint256: c = get_contract_with_gas_estimation(block_number_code) assert c.block_number() == 1 - w3.testing.mine(1) + revm_env.evm = EVM(env=Env(block=BlockEnv(number=2))) + c = revm_env.deploy_source(block_number_code, optimize, output_formats) assert c.block_number() == 2 diff --git a/tests/functional/codegen/environment_variables/test_tx.py b/tests/functional/codegen/environment_variables/test_tx.py index 3bc6ce2eff..0170cb83c3 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, revm_env): code = """ @external def tx_gasprice() -> uint256: return tx.gasprice """ + revm_env.set_balance(revm_env.deployer, 10**20) c = get_contract(code) for i in range(10): assert c.tx_gasprice(call={"gasPrice": 10**i}) == 10**i diff --git a/tests/functional/codegen/features/decorators/conftest.py b/tests/functional/codegen/features/decorators/conftest.py new file mode 100644 index 0000000000..1e98c3b24c --- /dev/null +++ b/tests/functional/codegen/features/decorators/conftest.py @@ -0,0 +1,6 @@ +import pytest + + +@pytest.fixture(scope="module") +def initial_balance(): + return 10**20 diff --git a/tests/functional/codegen/features/decorators/test_nonreentrant.py b/tests/functional/codegen/features/decorators/test_nonreentrant.py index 11beeb08d9..4b290e6119 100644 --- a/tests/functional/codegen/features/decorators/test_nonreentrant.py +++ b/tests/functional/codegen/features/decorators/test_nonreentrant.py @@ -193,7 +193,7 @@ def __default__(): contract.protected_function3("zzz value", True, transact={}) -def test_nonreentrant_decorator_for_default(w3, get_contract, tx_failed): +def test_nonreentrant_decorator_for_default(revm_env, get_contract, tx_failed): calling_contract_code = """ @external def send_funds(_amount: uint256): @@ -262,20 +262,20 @@ def __default__(): # Test unprotected function without callback. reentrant_contract.unprotected_function("some value", False, transact={"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 revm_env.get_balance(reentrant_contract.address) == 0 + assert revm_env.get_balance(calling_contract.address) == 1000 # Test unprotected function with callback to default. reentrant_contract.unprotected_function("another value", True, transact={"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 revm_env.get_balance(reentrant_contract.address) == 1000 + assert revm_env.get_balance(calling_contract.address) == 1000 # Test protected function without callback. reentrant_contract.protected_function("surprise!", False, transact={"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 revm_env.get_balance(reentrant_contract.address) == 1000 + assert revm_env.get_balance(calling_contract.address) == 2000 # Test protected function with callback to default. with tx_failed(): diff --git a/tests/functional/codegen/features/decorators/test_payable.py b/tests/functional/codegen/features/decorators/test_payable.py index bd4cadd5aa..696c1d02e2 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(revm_env, keccak, tx_failed, get_contract, code): c = get_contract(code) c.foo(transact={"value": 0}) sig = keccak("foo()".encode()).hex()[:10] with tx_failed(): - w3.eth.send_transaction({"to": c.address, "data": sig, "value": 10**18}) + revm_env.execute_code(c.address, data=sig, value=10**18) payable_code = [ @@ -341,7 +341,7 @@ def test_payable_runtime_assertion(get_contract, code): c.foo(transact={"value": 0}) -def test_payable_default_func_invalid_calldata(get_contract, w3): +def test_payable_default_func_invalid_calldata(get_contract, revm_env): code = """ @external def foo() -> bool: @@ -354,10 +354,10 @@ def __default__(): """ c = get_contract(code) - w3.eth.send_transaction({"to": c.address, "value": 100, "data": "0x12345678"}) + revm_env.execute_code(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, revm_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"}) + revm_env.execute_code(c.address, value=0, data="0x12345678") with tx_failed(): - w3.eth.send_transaction({"to": c.address, "value": 100, "data": "0x12345678"}) + revm_env.execute_code(c.address, value=100, data="0x12345678") -def test_batch_nonpayable(get_contract, w3, tx_failed): +def test_batch_nonpayable(get_contract, revm_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"}) + revm_env.execute_code(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}) + revm_env.execute_code(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..59d49322c2 100644 --- a/tests/functional/codegen/features/decorators/test_private.py +++ b/tests/functional/codegen/features/decorators/test_private.py @@ -1,4 +1,5 @@ import pytest +from eth_utils import to_checksum_address, to_wei def test_private_test(get_contract_with_gas_estimation): @@ -316,8 +317,8 @@ def test2(a: bytes32) -> (bytes32, uint256, int128): c = get_contract_with_gas_estimation(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): @@ -363,10 +364,10 @@ def test4(a: Bytes[40]) -> (int128, Bytes[100], Bytes[100]): c = get_contract_with_gas_estimation(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): @@ -389,7 +390,7 @@ def test() -> int128[4]: assert c.test() == [0, 1, 0, 1] -def test_private_payable(w3, get_contract_with_gas_estimation): +def test_private_payable(revm_env, get_contract_with_gas_estimation): code = """ @internal def _send_it(a: address, _value: uint256): @@ -408,16 +409,16 @@ def __default__(): 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") + revm_env.execute_code(c.address, value=to_wei(1, "ether")) + assert revm_env.get_balance(c.address) == to_wei(1, "ether") + a3 = revm_env.accounts[2] + revm_env.set_balance(a3, to_wei(1000000, "ether")) + c.test(True, a3, to_wei(0.05, "ether"), transact={}) + assert revm_env.get_balance(a3) == to_wei(1000000.05, "ether") + assert revm_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, revm_env): code = """ event Addr: addr: address @@ -442,11 +443,11 @@ 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 = revm_env.accounts[1] + c.whoami(transact={"from": addr}) + (log,) = revm_env.evm.result.logs + _, data = log.data + assert to_checksum_address(data[-20:]) == addr, "oh no" def test_nested_static_params_only(get_contract, tx_failed): @@ -585,7 +586,7 @@ def foo(a: int128) -> (int128, int128): return self._test(a) """, (11,), - [13, 2], + (13, 2), ), ( """ @@ -636,7 +637,7 @@ def foo() -> (uint256[4], uint256): return out.many, out.one """, (), - [[1, 2, 3, 4], 5], + ([1, 2, 3, 4], 5), ), ( """ @@ -649,7 +650,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 +663,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 +676,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/iteration/test_range_in.py b/tests/functional/codegen/features/iteration/test_range_in.py index f381f60b35..adee33b657 100644 --- a/tests/functional/codegen/features/iteration/test_range_in.py +++ b/tests/functional/codegen/features/iteration/test_range_in.py @@ -110,7 +110,7 @@ def testin() -> bool: assert_compile_failed(lambda: get_contract_with_gas_estimation(code), TypeMismatch) -def test_ownership(w3, tx_failed, get_contract_with_gas_estimation): +def test_ownership(revm_env, tx_failed, get_contract_with_gas_estimation): code = """ owners: address[2] @@ -128,7 +128,7 @@ def set_owner(i: int128, new_owner: address): def is_owner() -> bool: return msg.sender in self.owners """ - a1 = w3.eth.accounts[1] + a1 = revm_env.accounts[1] c = get_contract_with_gas_estimation(code) assert c.is_owner() is True # contract creator is owner. diff --git a/tests/functional/codegen/features/test_address_balance.py b/tests/functional/codegen/features/test_address_balance.py index 58736cc07e..a016d48c70 100644 --- a/tests/functional/codegen/features/test_address_balance.py +++ b/tests/functional/codegen/features/test_address_balance.py @@ -1,4 +1,12 @@ -def test_constant_address_balance(w3, get_contract_with_gas_estimation): +import pytest + + +@pytest.fixture(scope="module") +def initial_balance(): + return 10**5 + + +def test_constant_address_balance(revm_env, get_contract_with_gas_estimation): code = """ a: constant(address) = 0x776Ba14735FF84789320718cf0aa43e91F7A8Ce1 @@ -13,6 +21,6 @@ def foo() -> uint256: assert c.foo() == 0 - w3.eth.send_transaction({"to": address, "value": 1337}) + revm_env.execute_code(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..cbebe54fc9 100644 --- a/tests/functional/codegen/features/test_assert.py +++ b/tests/functional/codegen/features/test_assert.py @@ -8,25 +8,24 @@ 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(revm_env, get_contract_with_gas_estimation, tx_failed): code = """ @external def foo(): raise """ c = get_contract_with_gas_estimation(code) - a0 = w3.eth.accounts[0] + revm_env.set_balance(revm_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(transact={"gas": gas_sent, "gasPrice": 10}) + + result = revm_env.evm.result + assert result.gas_used < gas_sent, "Gas refund not received" + assert not result.is_success and not result.is_halt -def test_assert_reason(w3, get_contract_with_gas_estimation, tx_failed, memory_mocker): +def test_assert_reason(revm_env, get_contract_with_gas_estimation, tx_failed, memory_mocker): code = """ err: String[32] @@ -146,7 +145,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, revm_env, tx_failed, memory_mocker): foreign_code = """ state: uint256 @external @@ -159,14 +158,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 +209,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(revm_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..33afcb9ee6 100644 --- a/tests/functional/codegen/features/test_assert_unreachable.py +++ b/tests/functional/codegen/features/test_assert_unreachable.py @@ -1,4 +1,12 @@ -def test_unreachable_refund(w3, get_contract): +import pytest + + +@pytest.fixture(scope="module") +def initial_balance(): + return 10**20 + + +def test_unreachable_refund(revm_env, get_contract, tx_failed): code = """ @external def foo(): @@ -6,16 +14,17 @@ def foo(): """ c = get_contract(code) - a0 = w3.eth.accounts[0] + a0 = revm_env.deployer 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(transact={"from": a0, "gas": gas_sent, "gasPrice": 10}) - assert tx_receipt["status"] == 0 - assert tx_receipt["gasUsed"] == gas_sent # Drains all gains sent + result = revm_env.evm.result + assert result.gas_used == gas_sent # Drains all gains sent + assert not result.is_success and result.is_halt -def test_basic_unreachable(w3, get_contract, tx_failed): +def test_basic_unreachable(revm_env, get_contract, tx_failed): code = """ @external def foo(val: int128) -> bool: @@ -28,15 +37,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="InvalidFEOpcode"): c.foo(1) - with tx_failed(exc_text="Invalid opcode 0xfe"): + with tx_failed(exc_text="InvalidFEOpcode"): c.foo(-1) - with tx_failed(exc_text="Invalid opcode 0xfe"): + with tx_failed(exc_text="InvalidFEOpcode"): c.foo(-2) -def test_basic_call_unreachable(w3, get_contract, tx_failed): +def test_basic_call_unreachable(revm_env, get_contract, tx_failed): code = """ @view @@ -54,13 +63,13 @@ def foo(val: int128) -> int128: assert c.foo(33) == -123 - with tx_failed(exc_text="Invalid opcode 0xfe"): + with tx_failed(exc_text="InvalidFEOpcode"): c.foo(1) - with tx_failed(exc_text="Invalid opcode 0xfe"): + with tx_failed(exc_text="InvalidFEOpcode"): c.foo(-1) -def test_raise_unreachable(w3, get_contract, tx_failed): +def test_raise_unreachable(revm_env, get_contract, tx_failed): code = """ @external def foo(): @@ -69,5 +78,5 @@ def foo(): c = get_contract(code) - with tx_failed(exc_text="Invalid opcode 0xfe"): + with tx_failed(exc_text="InvalidFEOpcode"): c.foo() diff --git a/tests/functional/codegen/features/test_assignment.py b/tests/functional/codegen/features/test_assignment.py index 8f3270e4bc..39b4ce3cb3 100644 --- a/tests/functional/codegen/features/test_assignment.py +++ b/tests/functional/codegen/features/test_assignment.py @@ -249,7 +249,7 @@ def get(i: int128) -> int128: return self.test_map2[idx].c """ c = get_contract_with_gas_estimation(code) - assert c.set(transact={}) + c.set(transact={}) assert c.get(1) == 111 @@ -275,7 +275,7 @@ 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.set(transact={}) assert c.get() == 111 diff --git a/tests/functional/codegen/features/test_bytes_map_keys.py b/tests/functional/codegen/features/test_bytes_map_keys.py index c70ffb26ce..b9a308694c 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(revm_env, get_contract): code = """ mapped_bytes: HashMap[Bytes[5], int128] diff --git a/tests/functional/codegen/features/test_clampers.py b/tests/functional/codegen/features/test_clampers.py index 578413a8f4..7455c6f296 100644 --- a/tests/functional/codegen/features/test_clampers.py +++ b/tests/functional/codegen/features/test_clampers.py @@ -7,18 +7,18 @@ from vyper.utils import int_bounds -def _make_tx(w3, address, signature, values): +def _make_tx(revm_env, address, signature, values): # helper function to broadcast transactions that fail clamping check 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}"}) + revm_env.execute_code(address, data=f"0x{sig}{data}") -def _make_abi_encode_tx(w3, address, signature, input_types, values): +def _make_abi_encode_tx(revm_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}"}) + revm_env.execute_code(address, data=f"0x{sig}{data}") def _make_dynarray_data(offset, length, values): @@ -27,9 +27,9 @@ def _make_dynarray_data(offset, length, values): return data -def _make_invalid_dynarray_tx(w3, address, signature, data): +def _make_invalid_dynarray_tx(revm_env, address, signature, data): sig = keccak(signature.encode()).hex()[:8] - w3.eth.send_transaction({"to": address, "data": f"0x{sig}{data}"}) + revm_env.execute_code(address, data=f"0x{sig}{data}") def test_bytes_clamper(tx_failed, get_contract_with_gas_estimation): @@ -83,7 +83,7 @@ def get_foo() -> Bytes[3]: @pytest.mark.parametrize("n", list(range(1, 33))) -def test_bytes_m_clamper_passing(w3, get_contract, n): +def test_bytes_m_clamper_passing(revm_env, get_contract, n): values = [b"\xff" * (i + 1) for i in range(n)] code = f""" @@ -99,7 +99,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(revm_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,11 +120,11 @@ def foo(s: bytes{n}) -> bytes{n}: # munge for `_make_tx` with tx_failed(): int_value = int.from_bytes(v, byteorder="big") - _make_tx(w3, c.address, f"foo(bytes{n})", [int_value]) + _make_tx(revm_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(revm_env, get_contract, n): bits = 8 * (n + 1) lo, hi = int_bounds(True, bits) values = [-1, 0, 1, lo, hi] @@ -140,7 +140,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(revm_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] @@ -153,11 +153,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(revm_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(revm_env, get_contract, value): code = """ @external def foo(s: bool) -> bool: @@ -169,7 +169,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(revm_env, tx_failed, get_contract, value): code = """ @external def foo(s: bool) -> bool: @@ -178,11 +178,11 @@ def foo(s: bool) -> bool: c = get_contract(code) with tx_failed(): - _make_tx(w3, c.address, "foo(bool)", [value]) + _make_tx(revm_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(revm_env, get_contract, value): code = """ flag Roles: USER @@ -201,7 +201,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(revm_env, tx_failed, get_contract, value): code = """ flag Roles: USER @@ -217,11 +217,11 @@ def foo(s: Roles) -> Roles: c = get_contract(code) with tx_failed(): - _make_tx(w3, c.address, "foo(uint256)", [value]) + _make_tx(revm_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(revm_env, get_contract, n): bits = 8 * (n + 1) values = [0, 1, 2**bits - 1] code = f""" @@ -236,7 +236,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(revm_env, tx_failed, get_contract, n): bits = 8 * (n + 1) values = [-1, -(2**255), 2**bits] code = f""" @@ -247,7 +247,7 @@ 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(revm_env, c.address, f"foo(uint{bits})", [v]) @pytest.mark.parametrize( @@ -264,7 +264,7 @@ def foo(s: uint{bits}) -> uint{bits}: ), ], ) -def test_address_clamper_passing(w3, get_contract, value, expected): +def test_address_clamper_passing(revm_env, get_contract, value, expected): code = """ @external def foo(s: address) -> address: @@ -276,7 +276,7 @@ def foo(s: 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(revm_env, tx_failed, get_contract, value): code = """ @external def foo(s: address) -> address: @@ -285,7 +285,7 @@ def foo(s: address) -> address: c = get_contract(code) with tx_failed(): - _make_tx(w3, c.address, "foo(address)", [value]) + _make_tx(revm_env, c.address, "foo(address)", [value]) @pytest.mark.parametrize( @@ -328,7 +328,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(revm_env, tx_failed, get_contract, value): code = """ @external def foo(s: decimal) -> decimal: @@ -338,11 +338,11 @@ def foo(s: decimal) -> decimal: c = get_contract(code) with tx_failed(): - _make_tx(w3, c.address, "foo(fixed168x10)", [value]) + _make_tx(revm_env, c.address, "foo(fixed168x10)", [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(revm_env, get_contract, value): code = """ @external def foo(a: uint256, b: int128[5], c: uint256) -> int128[5]: @@ -358,7 +358,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(revm_env, tx_failed, get_contract, bad_value, idx): # ensure the invalid value is detected at all locations in the array code = """ @external @@ -371,11 +371,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(revm_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(revm_env, get_contract, value): # when an array is > 5 items, the arg clamper runs in a loop to reduce bytecode size code = """ @external @@ -390,7 +390,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(revm_env, tx_failed, get_contract, bad_value, idx): code = """ @external def foo(b: int128[10]) -> int128[10]: @@ -402,11 +402,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(revm_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(revm_env, get_contract, value): code = """ @external def foo(a: uint256, b: int128[6][3][1][8], c: uint256) -> int128[6][3][1][8]: @@ -421,7 +421,7 @@ def foo(a: uint256, b: int128[6][3][1][8], c: uint256) -> int128[6][3][1][8]: @pytest.mark.parametrize("bad_value", [2**127, -(2**127) - 1, 2**255 - 1, -(2**255)]) @pytest.mark.parametrize("idx", range(12)) -def test_multidimension_array_clamper_failing(w3, tx_failed, get_contract, bad_value, idx): +def test_multidimension_array_clamper_failing(revm_env, tx_failed, get_contract, bad_value, idx): code = """ @external def foo(b: int128[6][1][2]) -> int128[6][1][2]: @@ -433,11 +433,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(revm_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(revm_env, get_contract, value): code = """ @external def foo(a: uint256, b: DynArray[int128, 5], c: uint256) -> DynArray[int128, 5]: @@ -453,7 +453,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(revm_env, tx_failed, get_contract, bad_value, idx): # ensure the invalid value is detected at all locations in the array code = """ @external @@ -469,11 +469,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(revm_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(revm_env, get_contract, value): # when an array is > 5 items, the arg clamper runs in a loop to reduce bytecode size code = """ @external @@ -487,7 +487,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(revm_env, tx_failed, get_contract, bad_value, idx): code = """ @external def foo(b: DynArray[int128, 10]) -> DynArray[int128, 10]: @@ -502,11 +502,11 @@ 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(revm_env, c.address, signature, data) @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) -def test_multidimension_dynarray_clamper_passing(w3, get_contract, value): +def test_multidimension_dynarray_clamper_passing(revm_env, get_contract, value): code = """ @external def foo( @@ -524,7 +524,7 @@ def foo( @pytest.mark.parametrize("bad_value", [2**127, -(2**127) - 1, 2**255 - 1, -(2**255)]) @pytest.mark.parametrize("idx", range(4)) -def test_multidimension_dynarray_clamper_failing(w3, tx_failed, get_contract, bad_value, idx): +def test_multidimension_dynarray_clamper_failing(revm_env, tx_failed, get_contract, bad_value, idx): code = """ @external def foo(b: DynArray[DynArray[int128, 2], 2]) -> DynArray[DynArray[int128, 2], 2]: @@ -545,11 +545,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(revm_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(revm_env, get_contract, value): code = """ @external def foo( @@ -566,7 +566,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(revm_env, tx_failed, get_contract, bad_value, idx): # ensure the invalid value is detected at all locations in the array code = """ @external @@ -585,4 +585,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(revm_env, c.address, signature, data) diff --git a/tests/functional/codegen/features/test_constructor.py b/tests/functional/codegen/features/test_constructor.py index 9146ace8a6..0f7abf05da 100644 --- a/tests/functional/codegen/features/test_constructor.py +++ b/tests/functional/codegen/features/test_constructor.py @@ -1,5 +1,5 @@ import pytest -from web3.exceptions import ValidationError +from eth.codecs.abi.exceptions import EncodeError def test_init_argument_test(get_contract_with_gas_estimation): @@ -84,11 +84,11 @@ def foo(x: int128) -> int128: c.foo(1274124) c.foo(2**120) - with pytest.raises(ValidationError): + with pytest.raises(EncodeError): c.foo(2**130) -def test_large_input_code_2(w3, get_contract_with_gas_estimation): +def test_large_input_code_2(revm_env, get_contract_with_gas_estimation): large_input_code_2 = """ @deploy def __init__(x: int128): @@ -101,7 +101,7 @@ def foo() -> int128: get_contract_with_gas_estimation(large_input_code_2, *[17]) - with pytest.raises(TypeError): + with pytest.raises(EncodeError): get_contract_with_gas_estimation(large_input_code_2, *[2**130]) print("Passed invalid input tests") @@ -147,7 +147,7 @@ def check_foo(a: uint64) -> int16: 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(revm_env, get_contract_with_gas_estimation): code = """ foo: uint256 @@ -163,7 +163,7 @@ def get_foo() -> uint256: 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(revm_env, get_contract_with_gas_estimation): code = """ foo: int128 @@ -188,7 +188,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(revm_env, get_contract_with_gas_estimation): code = """ foo: DynArray[DynArray[uint256, 3], 3] @@ -208,7 +208,7 @@ def get_foo() -> DynArray[DynArray[uint256, 3], 3]: 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(revm_env, get_contract_with_gas_estimation): code = """ foo: DynArray[DynArray[DynArray[int128, 3], 3], 3] diff --git a/tests/functional/codegen/features/test_immutable.py b/tests/functional/codegen/features/test_immutable.py index 49ff54b353..0506e458ea 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): diff --git a/tests/functional/codegen/features/test_internal_call.py b/tests/functional/codegen/features/test_internal_call.py index eec740aa1b..76264d2228 100644 --- a/tests/functional/codegen/features/test_internal_call.py +++ b/tests/functional/codegen/features/test_internal_call.py @@ -69,7 +69,7 @@ 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): @@ -351,7 +351,7 @@ 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("66.77")] + assert c.bar() == (66, Decimal("66.77")) def test_internal_function_multiple_lists_as_args(get_contract_with_gas_estimation): @@ -403,7 +403,7 @@ 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("66.77"), 44] + assert c.bar() == (b"hello world", Decimal("66.77"), 44) FAILING_CONTRACTS_CALL_VIOLATION = [ @@ -560,7 +560,7 @@ def test() -> (int128, String[{ln}], Bytes[{ln}]): c = get_contract_with_gas_estimation(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): @@ -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 cf64d271a9..035797bc2e 100644 --- a/tests/functional/codegen/features/test_logging.py +++ b/tests/functional/codegen/features/test_logging.py @@ -2,6 +2,7 @@ import pytest from eth.codecs import abi +from eth_utils import to_text from vyper import compile_code from vyper.exceptions import ( @@ -18,7 +19,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(revm_env, keccak, get_contract_with_gas_estimation): loggy_code = """ event MyLog: pass @@ -28,25 +29,25 @@ def foo(): """ c = get_contract_with_gas_estimation(loggy_code) - tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c.foo(transact={}) event_id = keccak(bytes("MyLog()", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.hex() + (log,) = revm_env.evm.result.logs + assert log.topics[0] == event_id.hex() # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "name": "MyLog", "inputs": [], "anonymous": False, "type": "event", } # Event is decoded correctly - assert hasattr(c._classic_contract.events, "MyLog") + assert c.parse_log(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(revm_env, keccak, get_logs, get_contract_with_gas_estimation): loggy_code = """ a: Bytes[3] @@ -61,14 +62,14 @@ def foo(): """ c = get_contract_with_gas_estimation(loggy_code) - tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c.foo(transact={}) event_id = keccak(bytes("MyLog(bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.hex() + (log,) = revm_env.evm.result.logs + assert log.topics[0] == event_id.hex() # 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, @@ -77,7 +78,7 @@ def foo(): def test_event_logging_with_multiple_topics( - w3, tester, keccak, get_logs, get_contract_with_gas_estimation + revm_env, keccak, get_logs, get_contract_with_gas_estimation ): loggy_code = """ event MyLog: @@ -92,13 +93,13 @@ def foo(): c = get_contract_with_gas_estimation(loggy_code) tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) event_id = keccak(bytes("MyLog(int128,bool,address)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.hex() + (log,) = revm_env.evm.result.logs + assert log.topics[0] == event_id.hex() # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "name": "MyLog", "inputs": [ {"type": "int128", "name": "arg1", "indexed": True}, @@ -113,11 +114,11 @@ def foo(): 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 + assert logs[0].args.arg3 == c.address def test_event_logging_with_multiple_topics_var_and_store( - tester, get_contract_with_gas_estimation, get_logs + get_contract_with_gas_estimation, get_logs ): code = """ event MyLog: @@ -146,7 +147,7 @@ def foo(arg1: int128): def test_logging_the_same_event_multiple_times_with_topics( - w3, tester, keccak, get_logs, get_contract_with_gas_estimation + revm_env, keccak, get_logs, get_contract_with_gas_estimation ): loggy_code = """ event MyLog: @@ -165,17 +166,18 @@ def bar(): """ 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.foo(transact={}) + logs_tx1 = revm_env.evm.result.logs + log1, _ = logs_tx1 + c.bar(transact={}) + log2, _ = revm_env.evm.result.logs event_id = keccak(bytes("MyLog(int128,address)", "utf-8")) # Event id is always the first topic - assert receipt1["logs"][0]["topics"][0] == event_id.hex() - assert receipt2["logs"][0]["topics"][0] == event_id.hex() + assert log1.topics[0] == event_id.hex() + assert log2.topics[0] == event_id.hex() # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "name": "MyLog", "inputs": [ {"type": "int128", "name": "arg1", "indexed": True}, @@ -186,11 +188,11 @@ 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 + logs_tx1 = [c.parse_log(log) for log in logs_tx1] + assert logs_tx1[0].args.arg1 == 1 + assert logs_tx1[0].args.arg2 == c.address + assert logs_tx1[1].args.arg1 == 1 + assert logs_tx1[1].args.arg2 == c.address def test_event_logging_cannot_have_more_than_three_topics( @@ -208,7 +210,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(revm_env, keccak, get_logs, get_contract_with_gas_estimation): loggy_code = """ event MyLog: arg1: int128 @@ -220,13 +222,13 @@ def foo(): c = get_contract_with_gas_estimation(loggy_code) tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) event_id = keccak(bytes("MyLog(int128)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.hex() + (log,) = revm_env.evm.result.logs + assert log.topics[0] == event_id.hex() # 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, @@ -239,7 +241,7 @@ def foo(): def test_event_logging_with_fixed_array_data( - w3, tester, keccak, get_logs, get_contract_with_gas_estimation + revm_env, keccak, get_logs, get_contract_with_gas_estimation ): loggy_code = """ event MyLog: @@ -256,14 +258,14 @@ def foo(): c = get_contract_with_gas_estimation(loggy_code) tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) 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] == event_id.hex() + log, _ = revm_env.evm.result.logs + assert log.topics[0] == event_id.hex() # 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}, @@ -275,7 +277,7 @@ def foo(): } # Event is decoded correctly - timestamp = w3.eth.get_block(w3.eth.block_number).timestamp + timestamp = revm_env.get_block(revm_env.block_number).timestamp logs = get_logs(tx_hash, c, "MyLog") assert logs[0].args.arg1 == [1, 2] @@ -284,7 +286,7 @@ def foo(): def test_logging_with_input_bytes_1( - w3, tester, keccak, get_logs, bytes_helper, get_contract_with_gas_estimation + revm_env, keccak, get_logs, bytes_helper, get_contract_with_gas_estimation ): loggy_code = """ event MyLog: @@ -299,13 +301,13 @@ def foo(arg1: Bytes[29], arg2: Bytes[31]): 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()) event_id = keccak(bytes("MyLog(bytes,bytes,bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.hex() + (log,) = revm_env.evm.result.logs + assert log.topics[0] == event_id.hex() # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "name": "MyLog", "inputs": [ {"type": "bytes", "name": "arg1", "indexed": False}, @@ -324,7 +326,7 @@ def foo(arg1: Bytes[29], arg2: Bytes[31]): def test_event_logging_with_bytes_input_2( - w3, tester, keccak, get_logs, get_contract_with_gas_estimation + revm_env, keccak, get_logs, get_contract_with_gas_estimation ): loggy_code = """ event MyLog: @@ -336,25 +338,24 @@ def foo(_arg1: Bytes[20]): """ c = get_contract_with_gas_estimation(loggy_code) - tx_hash = c.foo(b"hello", transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c.foo(b"hello", transact={}) event_id = keccak(bytes("MyLog(bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.hex() + (log,) = revm_env.evm.result.logs + assert log.topics[0] == event_id.hex() # 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 c.parse_log(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(revm_env, keccak, get_logs, get_contract): loggy_code = """ event MyLog: arg1: Bytes[5] @@ -366,13 +367,13 @@ 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()) event_id = keccak(bytes("MyLog(bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.hex() + (log,) = revm_env.evm.result.logs + assert log.topics[0] == event_id.hex() # 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", @@ -384,7 +385,7 @@ def foo(_arg1: Bytes[5]): def test_event_logging_with_data_with_different_types( - w3, tester, keccak, get_logs, get_contract_with_gas_estimation + revm_env, keccak, get_logs, get_contract_with_gas_estimation ): loggy_code = """ event MyLog: @@ -402,13 +403,13 @@ def foo(): c = get_contract_with_gas_estimation(loggy_code) tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) 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] == event_id.hex() + (log,) = revm_env.evm.result.logs + assert log.topics[0] == event_id.hex() # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "name": "MyLog", "inputs": [ {"type": "int128", "name": "arg1", "indexed": False}, @@ -423,7 +424,7 @@ def foo(): } # Event is decoded correctly - timestamp = w3.eth.get_block(w3.eth.block_number).timestamp + timestamp = revm_env.get_block(revm_env.block_number).timestamp logs = get_logs(tx_hash, c, "MyLog") args = logs[0].args assert args.arg1 == 123 @@ -435,7 +436,7 @@ def foo(): def test_event_logging_with_topics_and_data_1( - w3, tester, keccak, get_logs, get_contract_with_gas_estimation + revm_env, keccak, get_logs, get_contract_with_gas_estimation ): loggy_code = """ event MyLog: @@ -449,13 +450,13 @@ def foo(): c = get_contract_with_gas_estimation(loggy_code) tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) event_id = keccak(bytes("MyLog(int128,bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.hex() + (log,) = revm_env.evm.result.logs + assert log.topics[0] == event_id.hex() # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "anonymous": False, "inputs": [ {"indexed": True, "name": "arg1", "type": "int128"}, @@ -468,11 +469,11 @@ def foo(): logs = get_logs(tx_hash, c, "MyLog") args = logs[0].args assert args.arg1 == 1 - assert args.arg2 == b"bar" + assert args.arg2.removesuffix(b"\0") == b"bar" def test_event_logging_with_multiple_logs_topics_and_data( - w3, tester, keccak, get_logs, get_contract_with_gas_estimation + revm_env, keccak, get_logs, get_contract_with_gas_estimation ): loggy_code = """ struct SmallStruct: @@ -498,18 +499,16 @@ def foo(): c = get_contract_with_gas_estimation(loggy_code) tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) - logs1 = receipt["logs"][0] - logs2 = receipt["logs"][1] + log1, log2 = revm_env.evm.result.logs event_id1 = keccak(bytes("MyLog(int128,bytes)", "utf-8")) event_id2 = keccak(bytes("YourLog(address,(uint256,bytes,(string,fixed168x10)))", "utf-8")) # Event id is always the first topic - assert logs1["topics"][0] == event_id1.hex() - assert logs2["topics"][0] == event_id2.hex() + assert log1.topics[0] == event_id1.hex() + assert log2.topics[0] == event_id2.hex() # Event abi is created correctly - assert c._classic_contract.abi[0] == { + assert c.abi[0] == { "name": "MyLog", "inputs": [ {"type": "int128", "name": "arg1", "indexed": True}, @@ -518,7 +517,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}, @@ -552,7 +551,7 @@ def foo(): 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("13.5")}} + assert args.arg2 == (1, b"abc", ("house", Decimal("13.5000000000"))) def test_fails_when_input_is_the_wrong_type(tx_failed, get_contract_with_gas_estimation): @@ -740,7 +739,7 @@ def foo(): get_contract_with_gas_estimation(loggy_code) -def test_loggy_code(w3, tester, get_contract_with_gas_estimation): +def test_loggy_code(revm_env, get_contract_with_gas_estimation): loggy_code = """ s: Bytes[100] @@ -764,33 +763,30 @@ def ioo(inp: Bytes[100]): c = get_contract_with_gas_estimation(loggy_code) - tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) - logs = receipt["logs"] - - 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" + c.foo(transact={}) + (log,) = revm_env.evm.result.logs + + assert to_text(log.data[1]) == "moo" + c.goo(transact={}) + (log,) = revm_env.evm.result.logs + + assert to_text(log.data[1]) == "moo2" assert ( - logs[0]["topics"][0] == "0x1234567812345678123456781234567812345678123456781234567812345678" + log.topics[0] == "0x1234567812345678123456781234567812345678123456781234567812345678" ) # noqa: E501 - 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(transact={}) + (log,) = revm_env.evm.result.logs + assert to_text(log.data[1]) == "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", transact={}) + (log,) = revm_env.evm.result.logs + assert to_text(log.data[1]) == "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(revm_env, get_contract_with_gas_estimation): code = """ b: uint256 @@ -804,13 +800,12 @@ def foo(): 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.foo(transact={}) + logs = revm_env.evm.result.logs + assert logs[0].data[1] == (1234).to_bytes(32, "big") + assert logs[1].data[1] == (4321).to_bytes(32, "big") + assert logs[2].data[1] == b"testmessage".ljust(32, b"\0") + assert logs[3].data[1] == keccak256(b"") def test_variable_list_packing(get_logs, get_contract_with_gas_estimation): @@ -1050,20 +1045,20 @@ def set_list(): 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] + 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] + 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): +def test_hashed_indexed_topics_calldata(keccak, get_contract, revm_env): loggy_code = """ event MyLog: arg1: indexed(Bytes[36]) @@ -1076,24 +1071,27 @@ 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", transact={}) # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - assert receipt["logs"][0]["topics"][0] == event_id.hex() + (log,) = revm_env.evm.result.logs + assert log.topics[0] == event_id.hex() topic1 = f"0x{keccak256(b'bar').hex()}" - assert receipt["logs"][0]["topics"][1] == topic1 + (log,) = revm_env.evm.result.logs + assert log.topics[1] == topic1 topic2 = f"0x{abi.encode('int128', 1).hex()}" - assert receipt["logs"][0]["topics"][2] == topic2 + (log,) = revm_env.evm.result.logs + assert log.topics[2] == topic2 topic3 = f"0x{keccak256(b'weird').hex()}" - assert receipt["logs"][0]["topics"][3] == topic3 + (log,) = revm_env.evm.result.logs + assert log.topics[3] == 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}, @@ -1105,7 +1103,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(keccak, get_contract, revm_env): loggy_code = """ event MyLog: arg1: indexed(Bytes[10]) @@ -1121,24 +1119,27 @@ def foo(): """ c = get_contract(loggy_code) - tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c.foo(transact={}) # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - assert receipt["logs"][0]["topics"][0] == event_id.hex() + (log,) = revm_env.evm.result.logs + assert log.topics[0] == event_id.hex() topic1 = f"0x{keccak256(b'potato').hex()}" - assert receipt["logs"][0]["topics"][1] == topic1 + (log,) = revm_env.evm.result.logs + assert log.topics[1] == topic1 topic2 = f"0x{abi.encode('int128', -777).hex()}" - assert receipt["logs"][0]["topics"][2] == topic2 + (log,) = revm_env.evm.result.logs + assert log.topics[2] == topic2 topic3 = f"0x{keccak256(b'why hello, neighbor! how are you today?').hex()}" - assert receipt["logs"][0]["topics"][3] == topic3 + (log,) = revm_env.evm.result.logs + assert log.topics[3] == 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}, @@ -1150,7 +1151,7 @@ def foo(): } -def test_hashed_indexed_topics_storage(tester, keccak, get_contract): +def test_hashed_indexed_topics_storage(keccak, get_contract, revm_env): loggy_code = """ event MyLog: arg1: indexed(Bytes[32]) @@ -1175,24 +1176,27 @@ 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.foo(transact={}) # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - assert receipt["logs"][0]["topics"][0] == event_id.hex() + (log,) = revm_env.evm.result.logs + assert log.topics[0] == event_id.hex() topic1 = f"0x{keccak256(b'zonk').hex()}" - assert receipt["logs"][0]["topics"][1] == topic1 + (log,) = revm_env.evm.result.logs + assert log.topics[1] == topic1 topic2 = f"0x{abi.encode('int128', -2109).hex()}" - assert receipt["logs"][0]["topics"][2] == topic2 + (log,) = revm_env.evm.result.logs + assert log.topics[2] == topic2 topic3 = f"0x{keccak256(b'yessir').hex()}" - assert receipt["logs"][0]["topics"][3] == topic3 + (log,) = revm_env.evm.result.logs + assert log.topics[3] == 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}, @@ -1204,7 +1208,7 @@ def foo(): } -def test_hashed_indexed_topics_storxxage(tester, keccak, get_contract): +def test_hashed_indexed_topics_storxxage(keccak, get_contract, revm_env): loggy_code = """ event MyLog: arg1: indexed(Bytes[64]) @@ -1217,21 +1221,24 @@ def foo(): """ c = get_contract(loggy_code) - tx_hash = c.foo(transact={}) - receipt = tester.get_transaction_receipt(tx_hash.hex()) + c.foo(transact={}) # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - assert receipt["logs"][0]["topics"][0] == event_id.hex() + (log,) = revm_env.evm.result.logs + assert log.topics[0] == event_id.hex() topic1 = f"0x{keccak256(b'wow').hex()}" - assert receipt["logs"][0]["topics"][1] == topic1 + (log,) = revm_env.evm.result.logs + assert log.topics[1] == topic1 topic2 = f"0x{abi.encode('int128', 666).hex()}" - assert receipt["logs"][0]["topics"][2] == topic2 + (log,) = revm_env.evm.result.logs + assert log.topics[2] == topic2 topic3 = f"0x{keccak256(b'madness!').hex()}" - assert receipt["logs"][0]["topics"][3] == topic3 + (log,) = revm_env.evm.result.logs + assert log.topics[3] == topic3 fail_list = [ diff --git a/tests/functional/codegen/features/test_logging_from_call.py b/tests/functional/codegen/features/test_logging_from_call.py index 7b4ee4f67d..222cd1dff8 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_with_gas_estimation): code = """ event TestLog: testData1: bytes32 @@ -37,17 +38,17 @@ def test_func(_value: uint256): logs = get_logs(tx_hash, c, "TestLog") log = logs[0].args - assert w3.to_int(log.testData1) == 123 - assert w3.to_int(log.testData2[:32]) == 123 + assert to_int(log.testData1) == 123 + assert 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.testData3) == 123 assert logs[0].args == logs[1].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 @@ -77,18 +78,16 @@ def test_func(_value: uint256,input: Bytes[133]): # 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") 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 @@ -114,11 +113,11 @@ def test_func(_value: uint256,input: Bytes[133]): tx_hash = c.test_func(1234444, b"x" * 129, transact={}) logs = get_logs(tx_hash, c, "TestLog") - assert w3.to_int(logs[0].args.testData1) == 1234444 + assert to_int(logs[0].args.testData1) == 1234444 assert logs[0].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 = """ @@ -154,17 +153,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) - assert w3.to_int(logs[0].args.testData1) == 333 + assert to_int(logs[0].args.testData1) == 333 - assert w3.to_int(logs[0].args.testData2[0:8]) == 333 - assert w3.to_int(logs[0].args.testData2[8:16]) == 333 + assert to_int(logs[0].args.testData2[0:8]) == 333 + assert 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(logs[0].args.testData3) == 333 assert logs[0].args == logs[1].args diff --git a/tests/functional/codegen/features/test_reverting.py b/tests/functional/codegen/features/test_reverting.py index f24886ce96..9007a91eab 100644 --- a/tests/functional/codegen/features/test_reverting.py +++ b/tests/functional/codegen/features/test_reverting.py @@ -7,7 +7,7 @@ pytestmark = pytest.mark.usefixtures("memory_mocker") -def test_revert_reason(w3, tx_failed, get_contract_with_gas_estimation): +def test_revert_reason(revm_env, tx_failed, get_contract_with_gas_estimation): reverty_code = """ @external def foo(): @@ -17,11 +17,11 @@ def foo(): revert_bytes = method_id("NoFives()") - with tx_failed(TransactionFailed, exc_text=f"execution reverted: {revert_bytes}"): + with tx_failed(TransactionFailed, exc_text=revert_bytes.hex()): get_contract_with_gas_estimation(reverty_code).foo(transact={}) -def test_revert_reason_typed(w3, tx_failed, get_contract_with_gas_estimation): +def test_revert_reason_typed(revm_env, tx_failed, get_contract_with_gas_estimation): reverty_code = """ @external def foo(): @@ -32,11 +32,11 @@ def foo(): revert_bytes = method_id("NoFives(uint256)") + abi.encode("(uint256)", (5,)) - with tx_failed(TransactionFailed, exc_text=f"execution reverted: {revert_bytes}"): + with tx_failed(TransactionFailed, exc_text=revert_bytes.hex()): get_contract_with_gas_estimation(reverty_code).foo(transact={}) -def test_revert_reason_typed_no_variable(w3, tx_failed, get_contract_with_gas_estimation): +def test_revert_reason_typed_no_variable(revm_env, tx_failed, get_contract_with_gas_estimation): reverty_code = """ @external def foo(): @@ -46,5 +46,5 @@ def foo(): revert_bytes = method_id("NoFives(uint256)") + abi.encode("(uint256)", (5,)) - with tx_failed(TransactionFailed, exc_text=f"execution reverted: {revert_bytes}"): + with tx_failed(TransactionFailed, exc_text=revert_bytes.hex()): get_contract_with_gas_estimation(reverty_code).foo(transact={}) diff --git a/tests/functional/codegen/features/test_short_circuiting.py b/tests/functional/codegen/features/test_short_circuiting.py index 5e464dd389..d3e8bcb388 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(revm_env, get_contract): code = """ called_left: public(bool) @@ -31,7 +31,7 @@ def foo() -> bool: assert not c.called_right() -def test_short_circuit_and_left_is_true(w3, get_contract): +def test_short_circuit_and_left_is_true(revm_env, get_contract): code = """ called_left: public(bool) @@ -59,7 +59,7 @@ def foo() -> bool: assert c.called_right() -def test_short_circuit_or_left_is_true(w3, get_contract): +def test_short_circuit_or_left_is_true(revm_env, get_contract): code = """ called_left: public(bool) @@ -87,7 +87,7 @@ def foo() -> bool: assert not c.called_right() -def test_short_circuit_or_left_is_false(w3, get_contract): +def test_short_circuit_or_left_is_false(revm_env, get_contract): code = """ called_left: public(bool) @@ -117,7 +117,7 @@ def foo() -> bool: @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(revm_env, 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(revm_env, 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(revm_env, 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(revm_env, 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..330145880d 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]) diff --git a/tests/functional/codegen/integration/test_crowdfund.py b/tests/functional/codegen/integration/test_crowdfund.py index b07ce5dc22..fac93e556a 100644 --- a/tests/functional/codegen/integration/test_crowdfund.py +++ b/tests/functional/codegen/integration/test_crowdfund.py @@ -1,5 +1,5 @@ # 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(w3, tester, get_contract_pyevm): crowdfund = """ struct Funder: @@ -64,7 +64,7 @@ def refund(): """ a0, a1, a2, a3, a4, a5, a6 = w3.eth.accounts[:7] - c = get_contract_with_gas_estimation_for_constants(crowdfund, *[a1, 50, 60]) + c = get_contract_pyevm(crowdfund, *[a1, 50, 60]) start_timestamp = w3.eth.get_block(w3.eth.block_number).timestamp c.participate(transact={"value": 5}) @@ -81,7 +81,7 @@ def refund(): post_bal = w3.eth.get_balance(a1) assert post_bal - pre_bal == 54 - c = get_contract_with_gas_estimation_for_constants(crowdfund, *[a1, 50, 60]) + c = get_contract_pyevm(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}) @@ -95,7 +95,7 @@ def refund(): 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(w3, tester, get_contract_pyevm): crowdfund2 = """ struct Funder: sender: address @@ -157,7 +157,7 @@ def refund(): """ a0, a1, a2, a3, a4, a5, a6 = w3.eth.accounts[:7] - c = get_contract_with_gas_estimation_for_constants(crowdfund2, *[a1, 50, 60]) + c = get_contract_pyevm(crowdfund2, *[a1, 50, 60]) c.participate(transact={"value": 5}) assert c.timelimit() == 60 @@ -173,7 +173,7 @@ def refund(): post_bal = w3.eth.get_balance(a1) assert post_bal - pre_bal == 54 - c = get_contract_with_gas_estimation_for_constants(crowdfund2, *[a1, 50, 60]) + c = get_contract_pyevm(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}) diff --git a/tests/functional/codegen/integration/test_escrow.py b/tests/functional/codegen/integration/test_escrow.py index f86b4aa516..f8c72ff839 100644 --- a/tests/functional/codegen/integration/test_escrow.py +++ b/tests/functional/codegen/integration/test_escrow.py @@ -1,7 +1,12 @@ -# from ethereum.tools import tester +import pytest -def test_arbitration_code(w3, get_contract_with_gas_estimation, tx_failed): +@pytest.fixture(scope="module") +def initial_balance(): + return 10**20 + + +def test_arbitration_code(revm_env, get_contract_with_gas_estimation, tx_failed): arbitration_code = """ buyer: address seller: address @@ -25,7 +30,7 @@ def refund(): send(self.buyer, self.balance) """ - a0, a1, a2 = w3.eth.accounts[:3] + a0, a1, a2 = revm_env.accounts[:3] c = get_contract_with_gas_estimation(arbitration_code, value=1) c.setup(a1, a2, transact={}) with tx_failed(): @@ -35,7 +40,7 @@ def refund(): print("Passed escrow test") -def test_arbitration_code_with_init(w3, tx_failed, get_contract_with_gas_estimation): +def test_arbitration_code_with_init(revm_env, tx_failed, get_contract_with_gas_estimation): arbitration_code_with_init = """ buyer: address seller: address @@ -59,7 +64,7 @@ def refund(): assert msg.sender == self.seller or msg.sender == self.arbitrator send(self.buyer, self.balance) """ - a0, a1, a2 = w3.eth.accounts[:3] + a0, a1, a2 = revm_env.accounts[:3] c = get_contract_with_gas_estimation(arbitration_code_with_init, *[a1, a2], value=1) with tx_failed(): c.finalize(transact={"from": a1}) diff --git a/tests/functional/codegen/modules/test_stateless_functions.py b/tests/functional/codegen/modules/test_stateless_functions.py index 33d8b3186c..27643dbd11 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, w3, revm_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() == revm_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,) diff --git a/tests/functional/codegen/storage_variables/test_getters.py b/tests/functional/codegen/storage_variables/test_getters.py index 9e72bed075..cc27006e52 100644 --- a/tests/functional/codegen/storage_variables/test_getters.py +++ b/tests/functional/codegen/storage_variables/test_getters.py @@ -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/test_interfaces.py b/tests/functional/codegen/test_interfaces.py index e93cd5142b..d8a7829697 100644 --- a/tests/functional/codegen/test_interfaces.py +++ b/tests/functional/codegen/test_interfaces.py @@ -2,6 +2,7 @@ from decimal import Decimal import pytest +from eth_utils import to_wei from vyper.compiler import compile_code from vyper.exceptions import ( @@ -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(revm_env, get_contract, make_input_bundle): token_interface = """ @view @external @@ -232,7 +233,7 @@ def test(): test_c = get_contract(code, *[token.address], input_bundle=input_bundle) - sender = w3.eth.accounts[0] + sender = revm_env.deployer assert token.balanceOf(sender) == 0 test_c.test(transact={}) @@ -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(revm_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 = revm_env.deployer assert erc20.balanceOf(sender) == 0 test_c.test(transact={}) assert erc20.balanceOf(sender) == 1000 -def test_address_member(w3, get_contract): +def test_address_member(revm_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 revm_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(revm_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(revm_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..733ca5678d 100644 --- a/tests/functional/codegen/test_selector_table.py +++ b/tests/functional/codegen/test_selector_table.py @@ -512,7 +512,9 @@ 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, revm_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) @@ -597,9 +599,8 @@ def __default__(): 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) + revm_env.execute_code(c.address, data=hexstr, value=1) # now do calldatasize check # strip some bytes @@ -610,15 +611,15 @@ def __default__(): # no args, hit default function if default_fn_mutability == "": with tx_failed(): - w3.eth.send_transaction(tx_params) + revm_env.execute_code(**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) + tx = revm_env.execute_code(**tx_params) logs = get_logs(tx, c, "CalledDefault") assert len(logs) == 1 else: - tx = w3.eth.send_transaction(tx_params) + tx = revm_env.execute_code(**tx_params) # note: can't emit logs from view/pure functions, # so the logging is not tested. @@ -629,9 +630,9 @@ def __default__(): # check default function reverts tx_params["value"] = 1 with tx_failed(): - w3.eth.send_transaction(tx_params) + revm_env.execute_code(**tx_params) else: with tx_failed(): - w3.eth.send_transaction(tx_params) + revm_env.execute_code(**tx_params) _test() diff --git a/tests/functional/codegen/types/numbers/test_constants.py b/tests/functional/codegen/types/numbers/test_constants.py index af871983ab..a97efefdd5 100644 --- a/tests/functional/codegen/types/numbers/test_constants.py +++ b/tests/functional/codegen/types/numbers/test_constants.py @@ -55,19 +55,19 @@ def test_arithmetic(a: int128) -> int128: assert c.test_zaddress("0x0000000000000000000000000000000000000000") 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("18707220957835557353007165858768422651595.9365500927")) == [ + assert c.test_decimal(Decimal("18707220957835557353007165858768422651595.9365500927")) == ( True, False, - ] - assert c.test_decimal(Decimal("-18707220957835557353007165858768422651595.9365500928")) == [ + ) + assert c.test_decimal(Decimal("-18707220957835557353007165858768422651595.9365500928")) == ( False, True, - ] - assert c.test_decimal(Decimal("0.1")) == [False, False] + ) + assert c.test_decimal(Decimal("0.1")) == (False, False) assert c.test_uint256(2**256 - 1) is True diff --git a/tests/functional/codegen/types/numbers/test_decimals.py b/tests/functional/codegen/types/numbers/test_decimals.py index 425440fd4b..35b494e52a 100644 --- a/tests/functional/codegen/types/numbers/test_decimals.py +++ b/tests/functional/codegen/types/numbers/test_decimals.py @@ -251,8 +251,8 @@ def minimum(): """ c = get_contract_with_gas_estimation(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): diff --git a/tests/functional/codegen/types/numbers/test_isqrt.py b/tests/functional/codegen/types/numbers/test_isqrt.py index b734323a6e..db4ba21f58 100644 --- a/tests/functional/codegen/types/numbers/test_isqrt.py +++ b/tests/functional/codegen/types/numbers/test_isqrt.py @@ -103,7 +103,7 @@ def test(a: uint256) -> (uint256, uint256, uint256, uint256, uint256, String[100 c = get_contract_with_gas_estimation(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 465426cd1d..e5c2e7eab0 100644 --- a/tests/functional/codegen/types/numbers/test_modulo.py +++ b/tests/functional/codegen/types/numbers/test_modulo.py @@ -57,7 +57,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_sqrt.py b/tests/functional/codegen/types/numbers/test_sqrt.py index 020a79e7ef..e91ea92c06 100644 --- a/tests/functional/codegen/types/numbers/test_sqrt.py +++ b/tests/functional/codegen/types/numbers/test_sqrt.py @@ -94,14 +94,14 @@ def test(a: decimal) -> (decimal, decimal, decimal, decimal, decimal, String[100 c = get_contract_with_gas_estimation(code) val = Decimal("2.1") - assert c.test(val) == [ + assert c.test(val) == ( val, Decimal("1"), Decimal("2"), Decimal("3"), decimal_sqrt(val), "hello world", - ] + ) @pytest.mark.parametrize("value", DECIMAL_RANGE) diff --git a/tests/functional/codegen/types/test_dynamic_array.py b/tests/functional/codegen/types/test_dynamic_array.py index b55f07639b..7364ef745f 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 @@ -880,7 +881,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): @@ -901,7 +902,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): @@ -936,7 +937,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): @@ -959,7 +960,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 = [ @@ -1011,7 +1012,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. ( @@ -1023,7 +1024,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 ( @@ -1196,7 +1197,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 @@ -1226,7 +1227,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), ), ( """ @@ -1236,7 +1237,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, []), ), ( """ @@ -1310,7 +1311,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..33c874e431 100644 --- a/tests/functional/codegen/types/test_flag.py +++ b/tests/functional/codegen/types/test_flag.py @@ -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, revm_env, tx_failed): code = """ flag Roles: ADMIN @@ -186,8 +186,8 @@ def checkMinter(minter: address): c = get_contract(code) # check admin - admin_address = w3.eth.accounts[0] - minter_address = w3.eth.accounts[1] + admin_address = revm_env.deployer + minter_address = revm_env.accounts[1] # add minter c.addMinter(minter_address, transact={}) diff --git a/tests/functional/codegen/types/test_lists.py b/tests/functional/codegen/types/test_lists.py index ee287064e8..14acdaaf28 100644 --- a/tests/functional/codegen/types/test_lists.py +++ b/tests/functional/codegen/types/test_lists.py @@ -423,7 +423,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): @@ -438,7 +438,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): @@ -473,7 +473,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): @@ -493,7 +493,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): @@ -514,7 +514,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..c34065b862 100644 --- a/tests/functional/codegen/types/test_string.py +++ b/tests/functional/codegen/types/test_string.py @@ -151,8 +151,8 @@ def test(addr: address) -> (int128, address, String[10]): c1 = get_contract_with_gas_estimation(contract_1) c2 = get_contract_with_gas_estimation(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): 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/builtins/conftest.py b/tests/functional/conftest.py similarity index 55% rename from tests/functional/builtins/conftest.py rename to tests/functional/conftest.py index 2616a458c8..0689b04ce4 100644 --- a/tests/functional/builtins/conftest.py +++ b/tests/functional/conftest.py @@ -14,3 +14,13 @@ def deploy_blueprint_for(deploy_blueprint_revm): @pytest.fixture(scope="module") def get_logs(get_logs_revm): return get_logs_revm + + +@pytest.fixture(scope="module") +def get_contract_with_gas_estimation(get_revm_contract): + return get_revm_contract + + +@pytest.fixture(scope="module") +def get_contract_with_gas_estimation_for_constants(get_revm_contract): + return get_revm_contract diff --git a/tests/functional/examples/tokens/test_erc1155.py b/tests/functional/examples/tokens/test_erc1155.py index 5dc314c037..b9d7438144 100644 --- a/tests/functional/examples/tokens/test_erc1155.py +++ b/tests/functional/examples/tokens/test_erc1155.py @@ -281,7 +281,7 @@ def test_safeBatchTransferFrom_balanceOf_batch(erc1155, w3, tx_failed): # test_ with tx_failed(): erc1155.balanceOfBatch([a2, a2, a2], [21, 22], transact={"from": owner}) - assert erc1155.balanceOfBatch([a2, a2, a2], [21, 22, 23]) == [1, 1, 1] + assert erc1155.balanceOfBatch([a2, a2, a2], [21, 22, 23]) == (1, 1, 1) assert erc1155.balanceOf(a1, 21) == 0 @@ -316,7 +316,7 @@ def test_mint_batch_burn_batch(erc1155, w3, tx_failed): # mint NFTs 11-20 # check the balance - assert erc1155.balanceOfBatch([a3, a3, a3], [11, 12, 13]) == [1, 1, 1] + assert erc1155.balanceOfBatch([a3, a3, a3], [11, 12, 13]) == (1, 1, 1) # try and burn a batch we don't control with tx_failed(): @@ -337,13 +337,13 @@ def test_mint_batch_burn_batch(erc1155, w3, tx_failed): # burn existing erc1155.burnBatch([11, 12], [1, 1], transact={"from": a3}) - assert erc1155.balanceOfBatch([a3, a3, a3], [11, 12, 13]) == [0, 0, 1] + 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}) - assert erc1155.balanceOfBatch([a3, a3, a3], [1, 2, 3]) == [0, 0, 0] + assert erc1155.balanceOfBatch([a3, a3, a3], [1, 2, 3]) == (0, 0, 0) def test_approval_functions(erc1155, w3, tx_failed): # test_mint_batch diff --git a/tests/functional/grammar/conftest.py b/tests/functional/grammar/conftest.py deleted file mode 100644 index 2616a458c8..0000000000 --- a/tests/functional/grammar/conftest.py +++ /dev/null @@ -1,16 +0,0 @@ -import pytest - - -@pytest.fixture(scope="module") -def get_contract(get_revm_contract): - return get_revm_contract - - -@pytest.fixture(scope="module") -def deploy_blueprint_for(deploy_blueprint_revm): - return deploy_blueprint_revm - - -@pytest.fixture(scope="module") -def get_logs(get_logs_revm): - return get_logs_revm diff --git a/tests/functional/syntax/conftest.py b/tests/functional/syntax/conftest.py deleted file mode 100644 index 2616a458c8..0000000000 --- a/tests/functional/syntax/conftest.py +++ /dev/null @@ -1,16 +0,0 @@ -import pytest - - -@pytest.fixture(scope="module") -def get_contract(get_revm_contract): - return get_revm_contract - - -@pytest.fixture(scope="module") -def deploy_blueprint_for(deploy_blueprint_revm): - return deploy_blueprint_revm - - -@pytest.fixture(scope="module") -def get_logs(get_logs_revm): - return get_logs_revm diff --git a/tests/functional/syntax/test_msg_data.py b/tests/functional/syntax/test_msg_data.py index dfeb9cea00..3c43c78d82 100644 --- a/tests/functional/syntax/test_msg_data.py +++ b/tests/functional/syntax/test_msg_data.py @@ -73,7 +73,7 @@ def foo() -> (uint256, Bytes[4], uint256): """ contract = get_contract(code) - assert contract.foo() == [2**256 - 1, bytes(keccak(text="foo()")[:4]), 2**256 - 1] + assert contract.foo() == (2**256 - 1, bytes(keccak(text="foo()")[:4]), 2**256 - 1) def test_assignment_to_storage(w3, get_contract, keccak): diff --git a/tests/functional/syntax/test_return_tuple.py b/tests/functional/syntax/test_return_tuple.py index 52640b883e..71d6b92dfe 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): @@ -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/revm/abi.py b/tests/revm/abi.py index 15eb849a2e..2a87c03ef8 100644 --- a/tests/revm/abi.py +++ b/tests/revm/abi.py @@ -2,7 +2,6 @@ from decimal import Decimal from typing import Any -from eth.codecs.abi import nodes from eth.codecs.abi.decoder import Decoder from eth.codecs.abi.encoder import Encoder from eth.codecs.abi.exceptions import ABIError @@ -21,11 +20,6 @@ def visit_AddressNode( address = super().visit_AddressNode(node, value, checksum, **kwargs) return address if address != "0x0000000000000000000000000000000000000000" else None - @classmethod - def visit_TupleNode(cls, node: nodes.TupleNode, value: bytes, **kwargs) -> list: - tup = super().visit_TupleNode(node, value, **kwargs) - return list(tup) - class _Encoder(Encoder): """ diff --git a/tests/revm/abi_contract.py b/tests/revm/abi_contract.py index d096c8b948..c7367d67dd 100644 --- a/tests/revm/abi_contract.py +++ b/tests/revm/abi_contract.py @@ -1,8 +1,8 @@ -from collections import defaultdict, namedtuple -from dataclasses import dataclass +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, Type, Union +from typing import TYPE_CHECKING, Any, Optional, Union from warnings import warn from eth_typing import ChecksumAddress, HexAddress @@ -46,16 +46,28 @@ def topic_id(self) -> bytes: 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 argument_types(self) -> list: - return [_abi_from_json(i) for i in self._abi["inputs"]] + 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.argument_types)})" + return f"({_format_abi_type(self.indexed_types + self.unindexed_types)})" def __repr__(self) -> str: - return f"ABI {self._contract_name}.{self.signature} (0x{self.topic_id.hex()})" + return f"ABITopic {self._contract_name}.{self.signature} (0x{self.topic_id.hex()})" def __str__(self) -> str: return repr(self) @@ -67,14 +79,26 @@ def parse(self, log: Log) -> ABILog: event=self.name, ) - @property - def data_type(self) -> Type[tuple]: - return namedtuple(self.name, [item["name"] for item in self._abi["inputs"]]) + @cached_property + def data_type(self) -> type: + names = [ + (item["name"], item["type"]) for item in self.indexed_inputs + self.unindexed_inputs + ] + return make_dataclass(self.name, names) def _parse_args(self, log: Log) -> tuple: - _, data = log.data - decoded = abi_decode(self.signature, data) - return self.data_type(*decoded) + 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): + return typ in ("bytes", "string", "tuple") or typ.endswith("[]") class ABIFunction: @@ -144,6 +168,11 @@ def is_encodable(self, *args, **kwargs) -> bool: 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.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: @@ -158,7 +187,7 @@ def _merge_kwargs(self, *args, **kwargs) -> list: error = f"Missing keyword argument {e} for `{self.signature}`. Passed {args} {kwargs}" raise TypeError(error) - def __call__(self, *args, value=0, gas=None, sender=None, transact=None, **kwargs): + def __call__(self, *args, value=0, gas=None, sender=None, transact=None, call=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.") @@ -166,16 +195,15 @@ def __call__(self, *args, value=0, gas=None, sender=None, transact=None, **kwarg if sender is None: sender = self.contract.env.deployer - args = self._merge_kwargs(*args, **kwargs) computation = self.contract.env.execute_code( to_address=self.contract.address, sender=sender, - data=self.method_id + abi_encode(self.signature, args), + data=self.prepare_calldata(*args, **kwargs), value=value, gas=gas, is_modifying=self.is_mutable, contract=self.contract, - transact=transact, + transact={**(transact or {}), **(call or {})}, ) match self.contract.marshal_to_python(computation, self.return_type): @@ -184,7 +212,6 @@ def __call__(self, *args, value=0, gas=None, sender=None, transact=None, **kwarg case (single,): return single case multiple: - # this should return a tuple, but for backwards compatibility we return a list return multiple @@ -327,7 +354,7 @@ def __repr__(self): warn_str = "" if self._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: Log): + def parse_log(self, log: Log) -> ABILog: """ Parse a log entry into an ABILog object. :param log: the log entry to parse @@ -384,10 +411,8 @@ def _abi_from_json(abi: dict) -> str: """ if "components" in abi: components = ",".join([_abi_from_json(item) for item in abi["components"]]) - if abi["type"] == "tuple": - return f"({components})" - if abi["type"] == "tuple[]": - return f"({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"] diff --git a/tests/revm/revm_env.py b/tests/revm/revm_env.py index 1bee815b81..45c3d2ce56 100644 --- a/tests/revm/revm_env.py +++ b/tests/revm/revm_env.py @@ -1,4 +1,6 @@ import json +import re +from contextlib import contextmanager from typing import Callable, Tuple from eth_keys.datatypes import PrivateKey @@ -7,29 +9,47 @@ from eth_typing import HexAddress from eth_utils import to_checksum_address from hexbytes import HexBytes -from pyrevm import EVM +from pyrevm import EVM, BlockEnv, Env -from tests.revm.abi import abi_encode +from tests.revm.abi import abi_decode, abi_encode from tests.revm.abi_contract import ABIContract, ABIContractFactory, ABIFunction from vyper.ast.grammar import parse_vyper_source from vyper.compiler import CompilerData, Settings, compile_code from vyper.compiler.settings import OptimizationLevel -from vyper.utils import ERC5202_PREFIX +from vyper.utils import ERC5202_PREFIX, method_id class RevmEnv: - def __init__(self, gas_limit: int, tracing=False) -> None: - self.evm = EVM(gas_limit=gas_limit, tracing=tracing) + def __init__(self, gas_limit: int, tracing=False, block_number=1) -> None: + self.gas_limit = gas_limit + self.evm = EVM( + gas_limit=gas_limit, + tracing=tracing, + spec_id="Shanghai", + env=Env( + block=BlockEnv(number=block_number), + ), + ) self.contracts: dict[HexAddress, ABIContract] = {} self._keys: list[PrivateKey] = get_default_account_keys() + self.deployer = self._keys[0].public_key.to_checksum_address() - @property - def accounts(self) -> list[HexAddress]: - return [k.public_key.to_checksum_address() for k in self._keys] - - @property - def deployer(self) -> HexAddress: - return self._keys[0].public_key.to_checksum_address() + @contextmanager + def anchor(self): + snapshot_id = self.evm.snapshot() + try: + yield + finally: + self.evm.revert(snapshot_id) + + @contextmanager + def sender(self, address: HexAddress): + original_deployer = self.deployer + self.deployer = address + try: + yield + finally: + self.deployer = original_deployer def get_balance(self, address: HexAddress) -> int: return self.evm.get_balance(address) @@ -37,33 +57,53 @@ def get_balance(self, address: HexAddress) -> int: def set_balance(self, address: HexAddress, value: int): self.evm.set_balance(address, value) + @property + def accounts(self) -> list[HexAddress]: + return [key.public_key.to_checksum_address() for key in self._keys] + + @property + def block_number(self) -> int: + return self.evm.env.block.number + + def get_block(self, _=None) -> BlockEnv: + return self.evm.env.block + def contract(self, abi, bytecode) -> "ABIContract": return ABIContractFactory.from_abi_dict(abi).at(self, bytecode) def execute_code( self, to_address: HexAddress, - sender: HexAddress, - data: bytes | None, + sender: HexAddress | None = None, + data: bytes | str = b"", value: int | None = None, - gas: int = 0, + gas: int | None = None, is_modifying: bool = True, # TODO: Remove the following. They are not used. transact: dict | None = None, contract=None, ): - gas = transact.get("gas", gas) if transact else gas + transact = transact or {} + data = data if isinstance(data, bytes) else bytes.fromhex(data.removeprefix("0x")) try: output = self.evm.message_call( to=to_address, - caller=sender, + caller=transact.get("from", sender) or self.deployer, calldata=data, - value=value, - gas=gas, + value=transact.get("value", value), + gas=transact.get("gas", gas) or self.gas_limit, + gas_price=transact.get("gasPrice"), is_static=not is_modifying, ) return bytes(output) except RuntimeError as e: + 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) + # Check EIP838 error, with ABI Error(string) + if output_bytes[:4] == method_id("Error(string)"): + (msg,) = abi_decode("(string)", output_bytes[4:]) + raise TransactionFailed(msg, gas_used) from e raise TransactionFailed(*e.args) from e def get_code(self, address: HexAddress): From 3fee741141e1d04dde15e644e9f8d68d5e86551d Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 26 Mar 2024 17:03:40 +0100 Subject: [PATCH 18/87] Linting --- tests/functional/codegen/calling_convention/test_return.py | 3 +-- tests/functional/codegen/features/test_logging.py | 7 +------ tests/revm/abi_contract.py | 4 +--- tests/revm/revm_env.py | 4 +--- 4 files changed, 4 insertions(+), 14 deletions(-) diff --git a/tests/functional/codegen/calling_convention/test_return.py b/tests/functional/codegen/calling_convention/test_return.py index 614e919fd9..5bd875bec9 100644 --- a/tests/functional/codegen/calling_convention/test_return.py +++ b/tests/functional/codegen/calling_convention/test_return.py @@ -19,8 +19,7 @@ def hardtest(arg1: Bytes[64], arg2: Bytes[64]) -> Bytes[128]: # Make sure underlying struct is correctly right padded res = revm_env.execute_code( - to_address=c.address, - data=c.hardtest.prepare_calldata(b"hello" * 5, b"hello" * 10), + to_address=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 diff --git a/tests/functional/codegen/features/test_logging.py b/tests/functional/codegen/features/test_logging.py index 035797bc2e..9876087038 100644 --- a/tests/functional/codegen/features/test_logging.py +++ b/tests/functional/codegen/features/test_logging.py @@ -37,12 +37,7 @@ def foo(): (log,) = revm_env.evm.result.logs assert log.topics[0] == event_id.hex() # Event abi is created correctly - assert c.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 c.parse_log(log).event == "MyLog" diff --git a/tests/revm/abi_contract.py b/tests/revm/abi_contract.py index c7367d67dd..32f36244f2 100644 --- a/tests/revm/abi_contract.py +++ b/tests/revm/abi_contract.py @@ -74,9 +74,7 @@ def __str__(self) -> str: def parse(self, log: Log) -> ABILog: return ABILog( - address=to_checksum_address(log.address), - args=self._parse_args(log), - event=self.name, + address=to_checksum_address(log.address), args=self._parse_args(log), event=self.name ) @cached_property diff --git a/tests/revm/revm_env.py b/tests/revm/revm_env.py index 45c3d2ce56..383856ce0a 100644 --- a/tests/revm/revm_env.py +++ b/tests/revm/revm_env.py @@ -26,9 +26,7 @@ def __init__(self, gas_limit: int, tracing=False, block_number=1) -> None: gas_limit=gas_limit, tracing=tracing, spec_id="Shanghai", - env=Env( - block=BlockEnv(number=block_number), - ), + env=Env(block=BlockEnv(number=block_number)), ) self.contracts: dict[HexAddress, ABIContract] = {} self._keys: list[PrivateKey] = get_default_account_keys() From 0b1a63010553d5a4b9c3885f19cf049ced6ba2ad Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 27 Mar 2024 15:41:53 +0100 Subject: [PATCH 19/87] Fix tests --- .../codegen/calling_convention/test_return.py | 2 +- .../functional/codegen/test_selector_table.py | 1 + .../examples/auctions/test_blind_auction.py | 98 ++++++++++--------- .../auctions/test_simple_open_auction.py | 44 +++++---- .../examples/company/test_company.py | 37 +++---- tests/functional/examples/conftest.py | 5 + .../crowdfund/test_crowdfund_example.py | 37 +++---- .../examples/factory/test_factory.py | 8 +- .../test_on_chain_market_maker.py | 73 +++++++------- .../name_registry/test_name_registry.py | 4 +- .../test_safe_remote_purchase.py | 55 ++++++----- .../examples/storage/test_advanced_storage.py | 23 +++-- .../examples/storage/test_storage.py | 6 +- .../examples/tokens/test_erc1155.py | 64 ++++++------ .../functional/examples/tokens/test_erc20.py | 66 ++++++------- .../examples/tokens/test_erc4626.py | 8 +- .../functional/examples/tokens/test_erc721.py | 70 ++++++------- .../functional/examples/voting/test_ballot.py | 32 +++--- .../functional/examples/wallet/test_wallet.py | 35 ++++--- tests/functional/syntax/test_return_tuple.py | 4 +- tests/functional/syntax/test_self_balance.py | 7 +- tests/revm/abi_contract.py | 5 +- tests/revm/revm_env.py | 22 ++++- 23 files changed, 378 insertions(+), 328 deletions(-) diff --git a/tests/functional/codegen/calling_convention/test_return.py b/tests/functional/codegen/calling_convention/test_return.py index 5bd875bec9..cd5d40798f 100644 --- a/tests/functional/codegen/calling_convention/test_return.py +++ b/tests/functional/codegen/calling_convention/test_return.py @@ -19,7 +19,7 @@ def hardtest(arg1: Bytes[64], arg2: Bytes[64]) -> Bytes[128]: # Make sure underlying struct is correctly right padded res = revm_env.execute_code( - to_address=c.address, data=c.hardtest.prepare_calldata(b"hello" * 5, b"hello" * 10) + 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 diff --git a/tests/functional/codegen/test_selector_table.py b/tests/functional/codegen/test_selector_table.py index 733ca5678d..7c8509edd4 100644 --- a/tests/functional/codegen/test_selector_table.py +++ b/tests/functional/codegen/test_selector_table.py @@ -576,6 +576,7 @@ def __default__(): """ c = get_contract(code, override_opt_level=opt_level) + revm_env.set_balance(revm_env.deployer, 10**18) for func_id, mutability, n_calldata_words, n_strip_bytes, n_default_args in methods: funcname = f"foo{func_id}" diff --git a/tests/functional/examples/auctions/test_blind_auction.py b/tests/functional/examples/auctions/test_blind_auction.py index dcd4e0bf8b..9efea61b5f 100644 --- a/tests/functional/examples/auctions/test_blind_auction.py +++ b/tests/functional/examples/auctions/test_blind_auction.py @@ -8,21 +8,21 @@ @pytest.fixture -def auction_contract(w3, get_contract): +def auction_contract(revm_env, get_contract, initial_balance): 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 revm_env.accounts[1:4]: + revm_env.set_balance(acc, initial_balance) -def test_initial_state(w3, tester, auction_contract): + return get_contract(contract_code, *[revm_env.deployer, BIDDING_TIME, REVEAL_TIME]) + + +def test_initial_state(revm_env, auction_contract): # Check beneficiary is correct - assert auction_contract.beneficiary() == w3.eth.accounts[0] + assert auction_contract.beneficiary() == revm_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() == revm_env.get_block("latest").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 @@ -33,16 +33,16 @@ def test_initial_state(w3, tester, auction_contract): assert auction_contract.highestBidder() is None -def test_late_bid(w3, auction_contract, tx_failed): - k1 = w3.eth.accounts[1] +def test_late_bid(revm_env, auction_contract, tx_failed, keccak): + k1 = revm_env.accounts[1] # Move time forward past bidding end - w3.testing.mine(BIDDING_TIME + TEST_INCREMENT) + revm_env.mine(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"), @@ -55,13 +55,13 @@ def test_late_bid(w3, auction_contract, tx_failed): ) -def test_too_many_bids(w3, auction_contract, tx_failed): - k1 = w3.eth.accounts[1] +def test_too_many_bids(revm_env, auction_contract, tx_failed, keccak): + k1 = revm_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"), @@ -76,7 +76,7 @@ def test_too_many_bids(w3, auction_contract, tx_failed): # 129th bid should fail with tx_failed(): auction_contract.bid( - w3.keccak( + keccak( b"".join( [ (128).to_bytes(32, byteorder="big"), @@ -89,12 +89,12 @@ def test_too_many_bids(w3, auction_contract, tx_failed): ) -def test_early_reval(w3, auction_contract, tx_failed): - k1 = w3.eth.accounts[1] +def test_early_reval(revm_env, auction_contract, tx_failed, keccak): + k1 = revm_env.accounts[1] # k1 places 1 real bid auction_contract.bid( - w3.keccak( + keccak( b"".join( [ (100).to_bytes(32, byteorder="big"), @@ -107,7 +107,7 @@ def test_early_reval(w3, auction_contract, tx_failed): ) # Move time slightly forward (still before bidding has ended) - w3.testing.mine(TEST_INCREMENT) + revm_env.mine(TEST_INCREMENT) # Try to reveal early _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -128,12 +128,12 @@ def test_early_reval(w3, auction_contract, tx_failed): assert auction_contract.highestBid() == 0 -def test_late_reveal(w3, auction_contract, tx_failed): - k1 = w3.eth.accounts[1] +def test_late_reveal(revm_env, auction_contract, tx_failed, keccak): + k1 = revm_env.accounts[1] # k1 places 1 real bid auction_contract.bid( - w3.keccak( + keccak( b"".join( [ (100).to_bytes(32, byteorder="big"), @@ -146,7 +146,7 @@ def test_late_reveal(w3, auction_contract, tx_failed): ) # Move time forward past bidding _and_ reveal time - w3.testing.mine(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) + revm_env.mine(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) # Try to reveal late _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -167,19 +167,19 @@ def test_late_reveal(w3, auction_contract, tx_failed): assert auction_contract.highestBid() == 0 -def test_early_end(w3, auction_contract, tx_failed): - k0 = w3.eth.accounts[0] +def test_early_end(revm_env, auction_contract, tx_failed): + k0 = revm_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}) -def test_double_end(w3, auction_contract, tx_failed): - k0 = w3.eth.accounts[0] +def test_double_end(revm_env, auction_contract, tx_failed): + k0 = revm_env.deployer # Move time forward past bidding and reveal end - w3.testing.mine(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) + revm_env.mine(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) # First auction end should succeed auction_contract.auctionEnd(transact={"value": 0, "from": k0}) @@ -189,8 +189,10 @@ def test_double_end(w3, auction_contract, tx_failed): auction_contract.auctionEnd(transact={"value": 0, "from": k0}) -def test_blind_auction(w3, auction_contract): - k0, k1, k2, k3 = w3.eth.accounts[0:4] +def test_blind_auction(revm_env, initial_balance, auction_contract, keccak): + k0, k1, k2, k3 = revm_env.accounts[0:4] + for acc in revm_env.accounts[1:4]: + revm_env.set_balance(acc, initial_balance) ################################################################### # Place bids # @@ -198,7 +200,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"), @@ -212,7 +214,7 @@ def test_blind_auction(w3, auction_contract): # k2 places 1 real bid (highest) and 2 fake auction_contract.bid( - w3.keccak( + keccak( b"".join( [ (150).to_bytes(32, byteorder="big"), @@ -224,7 +226,7 @@ def test_blind_auction(w3, auction_contract): transact={"value": 150, "from": k2}, ) auction_contract.bid( - w3.keccak( + keccak( b"".join( [ (200).to_bytes(32, byteorder="big"), @@ -236,7 +238,7 @@ def test_blind_auction(w3, auction_contract): transact={"value": 250, "from": k2}, ) auction_contract.bid( - w3.keccak( + keccak( b"".join( [ (300).to_bytes(32, byteorder="big"), @@ -250,7 +252,7 @@ def test_blind_auction(w3, auction_contract): # k3 places 2 fake bids auction_contract.bid( - w3.keccak( + keccak( b"".join( [ (175).to_bytes(32, byteorder="big"), @@ -262,7 +264,7 @@ def test_blind_auction(w3, auction_contract): transact={"value": 175, "from": k3}, ) auction_contract.bid( - w3.keccak( + keccak( b"".join( [ (275).to_bytes(32, byteorder="big"), @@ -279,7 +281,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) + revm_env.mine(BIDDING_TIME + TEST_INCREMENT) # Reveal k1 bids _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -308,9 +310,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) + balance_before_reveal = revm_env.get_balance(k2) auction_contract.reveal(3, _values, _fakes, _secrets, transact={"value": 0, "from": k2}) - balance_after_reveal = w3.eth.get_balance(k2) + balance_after_reveal = revm_env.get_balance(k2) #: Check that highest bidder and highest bid have updated assert auction_contract.highestBid() == 200 @@ -329,9 +331,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) + balance_before_reveal = revm_env.get_balance(k3) auction_contract.reveal(2, _values, _fakes, _secrets, transact={"value": 0, "from": k3}) - balance_after_reveal = w3.eth.get_balance(k3) + balance_after_reveal = revm_env.get_balance(k3) #: Check that highest bidder and highest bid have NOT updated assert auction_contract.highestBidder() == k2 @@ -345,12 +347,12 @@ def test_blind_auction(w3, auction_contract): ################################################################### # Move time forward past bidding and reveal end - w3.testing.mine(REVEAL_TIME) + revm_env.mine(REVEAL_TIME) # End the auction - balance_before_end = w3.eth.get_balance(k0) + balance_before_end = revm_env.get_balance(k0) auction_contract.auctionEnd(transact={"value": 0, "from": k0}) - balance_after_end = w3.eth.get_balance(k0) + balance_after_end = revm_env.get_balance(k0) # Check that auction indeed ended assert auction_contract.ended() is True @@ -359,7 +361,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) + balance_before_withdraw = revm_env.get_balance(k1) auction_contract.withdraw(transact={"value": 0, "from": k1}) - balance_after_withdraw = w3.eth.get_balance(k1) + balance_after_withdraw = revm_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..7059c42473 100644 --- a/tests/functional/examples/auctions/test_simple_open_auction.py +++ b/tests/functional/examples/auctions/test_simple_open_auction.py @@ -4,21 +4,24 @@ @pytest.fixture -def auction_start(w3): - return w3.eth.get_block("latest").timestamp + 1 +def auction_start(revm_env): + return revm_env.get_block("latest").timestamp + 1 @pytest.fixture -def auction_contract(w3, get_contract, auction_start): +def auction_contract(revm_env, get_contract, auction_start, initial_balance): 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 revm_env.accounts[1:5]: + revm_env.set_balance(acc, initial_balance) -def test_initial_state(w3, tester, auction_contract, auction_start): + return get_contract(contract_code, *[revm_env.accounts[0], auction_start, EXPIRY]) + + +def test_initial_state(revm_env, auction_contract, auction_start): # Check beneficiary is correct - assert auction_contract.beneficiary() == w3.eth.accounts[0] + assert auction_contract.beneficiary() == revm_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 @@ -30,14 +33,17 @@ def test_initial_state(w3, tester, auction_contract, auction_start): # 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() >= revm_env.get_block("latest").timestamp -def test_bid(w3, tester, auction_contract, tx_failed): - k1, k2, k3, k4, k5 = w3.eth.accounts[:5] +def test_bid(revm_env, auction_contract, tx_failed): + k1, k2, k3, k4, k5 = revm_env.accounts[:5] + revm_env.mine(1) # make sure auction has started + # Bidder cannot bid 0 with tx_failed(): auction_contract.bid(transact={"value": 0, "from": k1}) + # Bidder can bid auction_contract.bid(transact={"value": 1, "from": k1}) # Check that highest bidder and highest bid have changed accordingly @@ -65,27 +71,31 @@ def test_bid(w3, tester, auction_contract, tx_failed): # 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) + balance_before_withdrawal = revm_env.get_balance(k1) auction_contract.withdraw(transact={"from": k1}) - balance_after_withdrawal = w3.eth.get_balance(k1) + balance_after_withdrawal = revm_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(revm_env, auction_contract, tx_failed): + k1, k2, k3, k4, k5 = revm_env.accounts[:5] + + revm_env.mine(1) # make sure auction has started + # 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}) # 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) + revm_env.mine(EXPIRY) + balance_before_end = revm_env.get_balance(k1) auction_contract.endAuction(transact={"from": k2}) - balance_after_end = w3.eth.get_balance(k1) + balance_after_end = revm_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 diff --git a/tests/functional/examples/company/test_company.py b/tests/functional/examples/company/test_company.py index 5933a14e86..eb8b4ab17e 100644 --- a/tests/functional/examples/company/test_company.py +++ b/tests/functional/examples/company/test_company.py @@ -2,16 +2,19 @@ @pytest.fixture -def c(w3, get_contract): +def c(revm_env, initial_balance, 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 revm_env.accounts[1:5]: + revm_env.set_balance(acc, initial_balance) -def test_overbuy(w3, c, tx_failed): + return get_contract(contract_code, *[revm_env.accounts[0], 1000, 10**6]) + + +def test_overbuy(revm_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 = revm_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}) @@ -25,8 +28,8 @@ def test_overbuy(w3, c, tx_failed): c.buyStock(transact={"from": a2, "value": one_stock}) -def test_sell_without_stock(w3, c, tx_failed): - a1, a2 = w3.eth.accounts[1:3] +def test_sell_without_stock(revm_env, c, tx_failed): + a1, a2 = revm_env.accounts[1:3] # If you don't have any stock, you can't sell with tx_failed(): c.sellStock(1, transact={"from": a1}) @@ -43,8 +46,8 @@ def test_sell_without_stock(w3, c, tx_failed): c.sellStock(1, transact={"from": a1}) -def test_oversell(w3, c, tx_failed): - a0, a1, a2 = w3.eth.accounts[:3] +def test_oversell(revm_env, c, tx_failed): + a0, a1, a2 = revm_env.accounts[:3] # You can't sell more than you own test_shares = int(c.totalShares()) test_value = int(test_shares * c.price()) @@ -53,9 +56,9 @@ def test_oversell(w3, c, tx_failed): c.sellStock(test_shares + 1, transact={"from": a1}) -def test_transfer(w3, c, tx_failed): +def test_transfer(revm_env, c, tx_failed): # If you don't have any stock, you can't transfer - a1, a2 = w3.eth.accounts[1:3] + a1, a2 = revm_env.accounts[1:3] with tx_failed(): c.transferStock(a2, 1, transact={"from": a1}) with tx_failed(): @@ -72,8 +75,8 @@ def test_transfer(w3, c, tx_failed): c.sellStock(test_shares, transact={"from": a2}) -def test_paybill(w3, c, tx_failed): - a0, a1, a2, a3 = w3.eth.accounts[:4] +def test_paybill(revm_env, c, tx_failed): + a0, a1, a2, a3 = revm_env.accounts[:4] # Only the company can authorize payments with tx_failed(): c.payBill(a2, 1, transact={"from": a1}) @@ -92,8 +95,8 @@ def test_paybill(w3, c, tx_failed): c.sellStock(1, transact={"from": a1}) -def test_valuation(w3, c): - a1 = w3.eth.accounts[1] +def test_valuation(revm_env, c): + a1 = revm_env.accounts[1] # Valuation is number of shares held times price assert c.debt() == 0 test_value = int(c.totalShares() * c.price()) @@ -101,8 +104,8 @@ def test_valuation(w3, c): assert c.debt() == test_value -def test_logs(w3, c, get_logs): - a0, a1, a2, a3 = w3.eth.accounts[:4] +def test_logs(revm_env, c, get_logs): + a0, a1, a2, a3 = revm_env.accounts[:4] # Buy is logged logs = get_logs(c.buyStock(transact={"from": a1, "value": 7 * c.price()}), c, "Buy") assert len(logs) == 1 diff --git a/tests/functional/examples/conftest.py b/tests/functional/examples/conftest.py index 5c3a98e84b..5a781ac83a 100644 --- a/tests/functional/examples/conftest.py +++ b/tests/functional/examples/conftest.py @@ -4,3 +4,8 @@ @pytest.fixture(autouse=True) def setup(memory_mocker): pass + + +@pytest.fixture(scope="module") +def initial_balance(): + return 10**20 diff --git a/tests/functional/examples/crowdfund/test_crowdfund_example.py b/tests/functional/examples/crowdfund/test_crowdfund_example.py index e75a88bf48..df251dd7d5 100644 --- a/tests/functional/examples/crowdfund/test_crowdfund_example.py +++ b/tests/functional/examples/crowdfund/test_crowdfund_example.py @@ -2,43 +2,46 @@ @pytest.fixture -def c(w3, get_contract): +def c(revm_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, *[revm_env.accounts[1], 50, 60]) -def test_crowdfund_example(c, w3): - a0, a1, a2, a3, a4, a5, a6 = w3.eth.accounts[:7] +def test_crowdfund_example(c, revm_env): + a0, a1, a2, a3, a4, a5, a6 = revm_env.accounts[:7] c.participate(transact={"value": 5}) + revm_env.mine(1) 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 + assert c.deadline() - revm_env.get_block("latest").timestamp == 59 + assert revm_env.get_block("latest").timestamp < c.deadline() # expired + assert revm_env.get_balance(c.address) < c.goal() # not reached c.participate(transact={"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 + pre_bal = revm_env.get_balance(a1) + revm_env.mine(100) + assert revm_env.get_block("latest").timestamp > c.deadline() # expired c.finalize(transact={}) - post_bal = w3.eth.get_balance(a1) + post_bal = revm_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] +def test_crowdfund_example2(c, revm_env, tx_failed): + a0, a1, a2, a3, a4, a5, a6 = revm_env.accounts[:7] + for i, a in enumerate(revm_env.accounts[3:7]): + revm_env.set_balance(a, i + 1) + 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}) assert c.timelimit() == 60 - w3.testing.mine(100) + revm_env.mine(100) # assert c.expired() # assert not c.reached() - pre_bals = [w3.eth.get_balance(x) for x in [a3, a4, a5, a6]] + pre_bals = [revm_env.get_balance(x) for x in [a3, a4, a5, a6]] with tx_failed(): c.refund(transact={"from": a0}) c.refund(transact={"from": a3}) @@ -47,5 +50,5 @@ def test_crowdfund_example2(c, w3, tx_failed): 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]] + post_bals = [revm_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 0c5cf61b04..6022154264 100644 --- a/tests/functional/examples/factory/test_factory.py +++ b/tests/functional/examples/factory/test_factory.py @@ -17,14 +17,14 @@ def create_token(): @pytest.fixture -def create_exchange(w3, get_contract): +def create_exchange(revm_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(transact={"from": revm_env.accounts[0]}) return exchange return create_exchange @@ -47,8 +47,8 @@ def factory(get_contract, optimize): 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(revm_env, factory, create_token, create_exchange): + a = revm_env.accounts[0] token1 = create_token() exchange1 = create_exchange(token1, factory) token2 = create_token() 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..dd18587ea4 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,5 @@ import pytest +from eth_utils import to_wei @pytest.fixture @@ -31,9 +32,9 @@ def test_initial_state(market_maker): assert market_maker.owner() is None -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") +def test_initiate(revm_env, market_maker, erc20, tx_failed): + a0 = revm_env.accounts[0] + ether, ethers = to_wei(1, "ether"), to_wei(2, "ether") erc20.approve(market_maker.address, ethers, transact={}) market_maker.initiate(erc20.address, ether, transact={"value": ethers}) assert market_maker.totalEthQty() == ethers @@ -48,17 +49,16 @@ def test_initiate(w3, market_maker, erc20, tx_failed): market_maker.initiate(erc20.address, ether, transact={"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(revm_env, market_maker, erc20): + a1 = revm_env.accounts[1] + erc20.approve(market_maker.address, to_wei(2, "ether"), transact={}) + market_maker.initiate(erc20.address, to_wei(1, "ether"), transact={"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") + revm_env.set_balance(a1, 100) market_maker.ethToTokens(transact={"value": 100, "from": a1}) assert erc20.balanceOf(market_maker.address) == 999999999999999950 assert erc20.balanceOf(a1) == 50 @@ -66,48 +66,47 @@ def test_eth_to_tokens(w3, market_maker, erc20): 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(revm_env, market_maker, erc20): + a1 = revm_env.accounts[1] + a1_balance_before = to_wei(2, "ether") + revm_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}) + erc20.transfer(a1, to_wei(2, "ether"), transact={}) + erc20.approve(market_maker.address, 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} + erc20.address, to_wei(1, "ether"), transact={"value": to_wei(2, "ether"), "from": a1} ) - assert w3.eth.get_balance(market_maker.address) == w3.to_wei(2, "ether") + assert revm_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 revm_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"), transact={"from": a1}) + market_maker.tokensToEth(to_wei(1, "ether"), transact={"from": a1}) # 1 eth less in market. - assert w3.eth.get_balance(market_maker.address) == w3.to_wei(1, "ether") + assert revm_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 revm_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(revm_env, market_maker, erc20, tx_failed): + a0, a1 = revm_env.accounts[:2] + a0_balance_before = revm_env.get_balance(a0) # Approve 2 eth transfers. - erc20.approve(market_maker.address, w3.to_wei(2, "ether"), transact={}) + erc20.approve(market_maker.address, to_wei(2, "ether"), transact={}) # 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"), transact={"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 revm_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. + assert revm_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..331e30bd4b 100644 --- a/tests/functional/examples/name_registry/test_name_registry.py +++ b/tests/functional/examples/name_registry/test_name_registry.py @@ -1,5 +1,5 @@ -def test_name_registry(w3, get_contract, tx_failed): - a0, a1 = w3.eth.accounts[:2] +def test_name_registry(revm_env, get_contract, tx_failed): + a0, a1 = revm_env.accounts[:2] with open("examples/name_registry/name_registry.vy") as f: code = f.read() c = get_contract(code) 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..af84d24c65 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,16 +23,16 @@ def contract_code(get_contract): @pytest.fixture -def get_balance(w3): +def get_balance(revm_env): def get_balance(): - a0, a1 = w3.eth.accounts[:2] + a0, a1 = revm_env.accounts[:2] # balance of a1 = seller, a2 = buyer - return w3.eth.get_balance(a0), w3.eth.get_balance(a1) + return revm_env.get_balance(a0), revm_env.get_balance(a1) return get_balance -def test_initial_state(w3, tx_failed, get_contract, get_balance, contract_code): +def test_initial_state(revm_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) @@ -39,21 +40,23 @@ def test_initial_state(w3, tx_failed, get_contract, get_balance, contract_code): a0_pre_bal, a1_pre_bal = get_balance() c = get_contract(contract_code, value_in_eth=2) # Check that the seller is set correctly - assert c.seller() == w3.eth.accounts[0] + assert c.seller() == revm_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(revm_env, tx_failed, get_balance, get_contract, contract_code): + a0, a1, a2 = revm_env.accounts[:3] + revm_env.set_balance(a1, 10**18) + revm_env.set_balance(a2, 10**18) 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}) @@ -67,8 +70,11 @@ def test_abort(w3, tx_failed, get_balance, get_contract, contract_code): c.abort(transact={"from": a0}) -def test_purchase(w3, get_contract, tx_failed, get_balance, contract_code): - a0, a1, a2, a3 = w3.eth.accounts[:4] +def test_purchase(revm_env, get_contract, tx_failed, get_balance, contract_code): + a0, a1, a2, a3 = revm_env.accounts[:4] + revm_env.set_balance(a0, 10**18) + revm_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 @@ -89,8 +95,10 @@ def test_purchase(w3, get_contract, tx_failed, get_balance, contract_code): c.purchase(transact={"value": 2, "from": a3}) -def test_received(w3, get_contract, tx_failed, get_balance, contract_code): - a0, a1 = w3.eth.accounts[:2] +def test_received(revm_env, get_contract, tx_failed, get_balance, contract_code): + a0, a1 = revm_env.accounts[:2] + revm_env.set_balance(a0, 10**18) + revm_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 @@ -107,7 +115,7 @@ def test_received(w3, get_contract, tx_failed, get_balance, contract_code): 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(revm_env, get_contract, tx_failed, get_balance, contract_code): buyer_contract_code = """ interface PurchaseContract: @@ -142,24 +150,27 @@ def __default__(): """ - a0 = w3.eth.accounts[0] + a0, a1 = revm_env.accounts[:2] + revm_env.set_balance(a1, 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), + revm_env.get_balance(a0), + revm_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(transact={"value": 4, "from": 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(transact={"from": 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 revm_env.get_balance(a0), revm_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..880c073bde 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(revm_env, get_contract): with open("examples/storage/advanced_storage.vy") as f: contract_code = f.read() # Pass constructor variables directly to the contract @@ -18,8 +18,9 @@ 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(revm_env, adv_storage_contract, tx_failed): + k1 = revm_env.accounts[1] + revm_env.set_balance(k1, 10**18) # Try to set the storage to a negative amount with tx_failed(): @@ -36,24 +37,22 @@ def test_failed_transactions(w3, adv_storage_contract, tx_failed): assert adv_storage_contract.storedData() == 10 # Assert a different exception (ValidationError for non-matching argument type) - with tx_failed(ValidationError): + with tx_failed(EncodeError): adv_storage_contract.set("foo", transact={"from": k1}) # Assert a different exception that contains specific text - with tx_failed(ValidationError, "invocation failed due to improper number of arguments"): + with tx_failed(TypeError, "invocation failed due to improper number of arguments"): adv_storage_contract.set(1, 2, transact={"from": k1}) -def test_events(w3, adv_storage_contract, get_logs): - k1, k2 = w3.eth.accounts[:2] +def test_events(revm_env, adv_storage_contract, get_logs): + k1, k2 = revm_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") + tx2 = adv_storage_contract.set(20, transact={"from": k2}) logs2 = get_logs(tx2, adv_storage_contract, "DataChange") + tx3 = adv_storage_contract.reset(transact={"from": k1}) logs3 = get_logs(tx3, adv_storage_contract, "DataChange") # Check log contents diff --git a/tests/functional/examples/storage/test_storage.py b/tests/functional/examples/storage/test_storage.py index ee12f59cba..bcb3f6a665 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(revm_env, get_contract): with open("examples/storage/storage.vy") as f: contract_code = f.read() # Pass constructor variables directly to the contract @@ -17,8 +17,8 @@ def test_initial_state(storage_contract): assert storage_contract.storedData() == INITIAL_VALUE -def test_set(w3, storage_contract): - k0 = w3.eth.accounts[0] +def test_set(revm_env, storage_contract): + k0 = revm_env.accounts[0] # Let k0 try to set the value to 10 storage_contract.set(10, transact={"from": k0}) diff --git a/tests/functional/examples/tokens/test_erc1155.py b/tests/functional/examples/tokens/test_erc1155.py index b9d7438144..cf1d926653 100644 --- a/tests/functional/examples/tokens/test_erc1155.py +++ b/tests/functional/examples/tokens/test_erc1155.py @@ -29,8 +29,8 @@ @pytest.fixture -def erc1155(get_contract, w3, tx_failed): - owner, a1, a2, a3, a4, a5 = w3.eth.accounts[0:6] +def erc1155(get_contract, revm_env, tx_failed): + owner, a1, a2, a3, a4, a5 = revm_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]) @@ -82,9 +82,9 @@ 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, revm_env, tx_failed): + owner, a1, a2, a3, a4, a5 = revm_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() @@ -146,8 +146,8 @@ 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, revm_env, tx_failed): + owner, a1, a2, a3, a4, a5 = revm_env.accounts[0:6] # change contract URI and restore. assert erc1155.contractURI() == CONTRACT_METADATA_URI with tx_failed(): @@ -163,8 +163,8 @@ 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, revm_env, tx_failed): + owner, a1, a2, a3, a4, a5 = revm_env.accounts[0:6] # change contract URI and restore. assert erc1155.uri(0) == CONTRACT_URI erc1155.setURI(NEW_CONTRACT_URI, transact={"from": owner}) @@ -183,8 +183,8 @@ def test_URI(erc1155, w3, tx_failed): 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, revm_env, tx_failed): + owner, a1, a2, a3, a4, a5 = revm_env.accounts[0:6] assert erc1155.balanceOf(a1, 24) == 1 # transfer by non-owner with tx_failed(): @@ -217,16 +217,16 @@ def test_safeTransferFrom_balanceOf_single(erc1155, w3, tx_failed): # 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, revm_env, tx_failed): # test_mint_batch + owner, a1, a2, a3, a4, a5 = revm_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, revm_env, tx_failed): # test_mint_batch + owner, a1, a2, a3, a4, a5 = revm_env.accounts[0:6] # check a1 balances for NFTs 21-24 assert erc1155.balanceOf(a1, 21) == 1 @@ -269,7 +269,7 @@ def test_safeBatchTransferFrom_balanceOf_batch(erc1155, w3, tx_failed): # test_ erc1155.safeBatchTransferFrom( a1, a2, [21, 22, 500], [1, 1, 1], DUMMY_BYTES32_DATA, transact={"from": a1} ) - assert erc1155.safeBatchTransferFrom( + erc1155.safeBatchTransferFrom( a1, a2, [21, 22, 23], [1, 1, 1], DUMMY_BYTES32_DATA, transact={"from": a1} ) @@ -281,12 +281,12 @@ def test_safeBatchTransferFrom_balanceOf_batch(erc1155, w3, tx_failed): # test_ with tx_failed(): erc1155.balanceOfBatch([a2, a2, a2], [21, 22], transact={"from": owner}) - assert erc1155.balanceOfBatch([a2, a2, a2], [21, 22, 23]) == (1, 1, 1) + assert erc1155.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, revm_env, tx_failed): + owner, a1, a2, a3, a4, a5 = revm_env.accounts[0:6] # check the balance from an owner and non-owner account erc1155.mint(owner, 25, 1, transact={"from": owner}) @@ -311,12 +311,12 @@ def test_mint_one_burn_one(erc1155, w3, tx_failed): 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, revm_env, tx_failed): + owner, a1, a2, a3, a4, a5 = revm_env.accounts[0:6] # mint NFTs 11-20 # check the balance - assert erc1155.balanceOfBatch([a3, a3, a3], [11, 12, 13]) == (1, 1, 1) + assert erc1155.balanceOfBatch([a3, a3, a3], [11, 12, 13]) == [1, 1, 1] # try and burn a batch we don't control with tx_failed(): @@ -337,17 +337,17 @@ def test_mint_batch_burn_batch(erc1155, w3, tx_failed): # burn existing erc1155.burnBatch([11, 12], [1, 1], transact={"from": a3}) - assert erc1155.balanceOfBatch([a3, a3, a3], [11, 12, 13]) == (0, 0, 1) + 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}) - assert erc1155.balanceOfBatch([a3, a3, a3], [1, 2, 3]) == (0, 0, 0) + 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, revm_env, tx_failed): # test_mint_batch + owner, a1, a2, a3, a4, a5 = revm_env.accounts[0:6] # self-approval by the owner with tx_failed(): erc1155.setApprovalForAll(a5, a5, True, transact={"from": a5}) @@ -366,8 +366,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, revm_env, tx_failed): + owner, a1, a2, a3, a4, a5 = revm_env.accounts[0:6] TOTAL_BAD_BATCH = 200 ids = [] amounts = [] @@ -382,8 +382,8 @@ def test_max_batch_size_violation(erc1155, w3, tx_failed): # 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, revm_env, tx_failed): + owner, a1, a2, a3, a4, a5 = revm_env.accounts[0:6] print(owner, a1, a2) print("___owner___", erc1155.owner()) # change owner from account 0 to account 1 and back @@ -405,8 +405,8 @@ def test_ownership_functions(erc1155, w3, tx_failed, tester): 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, revm_env, tx_failed): + owner, a1, a2, a3, a4, a5 = revm_env.accounts[0:6] assert erc1155.owner() == owner # try to transfer ownership from non-owner account with tx_failed(): diff --git a/tests/functional/examples/tokens/test_erc20.py b/tests/functional/examples/tokens/test_erc20.py index ce507f75f8..2c0a9dca97 100644 --- a/tests/functional/examples/tokens/test_erc20.py +++ b/tests/functional/examples/tokens/test_erc20.py @@ -2,7 +2,7 @@ # 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 ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" MAX_UINT256 = (2**256) - 1 # Max uint256 value @@ -13,23 +13,21 @@ @pytest.fixture -def c(get_contract, w3): +def c(get_contract, revm_env): 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, revm_env): # 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 + return get_contract(bad_code, *[TOKEN_NAME, TOKEN_SYMBOL, TOKEN_DECIMALS, TOKEN_INITIAL_SUPPLY]) @pytest.fixture @@ -43,8 +41,8 @@ def get_log_args(tx_hash, c, event_name): return get_log_args -def test_initial_state(c, w3): - a1, a2, a3 = w3.eth.accounts[1:4] +def test_initial_state(c, revm_env): + a1, a2, a3 = revm_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,8 +59,8 @@ 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, revm_env, tx_failed): + minter, a1, a2 = revm_env.accounts[0:3] # Test scenario were mints 2 to a1, burns twice (check balance consistency) assert c.balanceOf(a1) == 0 @@ -93,9 +91,9 @@ def test_mint_and_burn(c, w3, tx_failed): c.mint(ZERO_ADDRESS, 1, transact={"from": minter}) -def test_totalSupply(c, w3, tx_failed): +def test_totalSupply(c, revm_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 = revm_env.accounts[0:2] assert c.totalSupply() == 0 c.mint(a1, 2, transact={"from": minter}) assert c.totalSupply() == 2 @@ -111,8 +109,8 @@ def test_totalSupply(c, w3, tx_failed): assert c.totalSupply() == 0 -def test_transfer(c, w3, tx_failed): - minter, a1, a2 = w3.eth.accounts[0:3] +def test_transfer(c, revm_env, tx_failed): + minter, a1, a2 = revm_env.accounts[0:3] with tx_failed(): c.burn(1, transact={"from": a2}) c.mint(a1, 2, transact={"from": minter}) @@ -130,8 +128,8 @@ def test_transfer(c, w3, tx_failed): c.transfer(a1, 0, transact={"from": a2}) -def test_maxInts(c, w3, tx_failed): - minter, a1, a2 = w3.eth.accounts[0:3] +def test_maxInts(c, revm_env, tx_failed): + minter, a1, a2 = revm_env.accounts[0:3] c.mint(a1, MAX_UINT256, transact={"from": minter}) assert c.balanceOf(a1) == MAX_UINT256 with tx_failed(): @@ -153,7 +151,7 @@ def test_maxInts(c, w3, tx_failed): assert c.balanceOf(a2) == MAX_UINT256 assert c.balanceOf(a1) == 0 # [ next line should never work in EVM ] - with pytest.raises(ValidationError): + with pytest.raises(EncodeError): c.transfer(a1, MAX_UINT256 + 1, transact={"from": a2}) # Check approve/allowance w max possible token values assert c.balanceOf(a2) == MAX_UINT256 @@ -166,8 +164,8 @@ def test_maxInts(c, w3, tx_failed): 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, revm_env, tx_failed): + minter, a1, a2, a3 = revm_env.accounts[0:4] with tx_failed(): c.burn(1, transact={"from": a2}) c.mint(a1, 1, transact={"from": minter}) @@ -219,8 +217,8 @@ def test_transferFrom_and_Allowance(c, w3, tx_failed): 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, revm_env, tx_failed): + minter, a1, a2, a3 = revm_env.accounts[0:4] with tx_failed(): c.burn(1, transact={"from": a2}) c.mint(a1, 1, transact={"from": minter}) @@ -275,29 +273,29 @@ def test_burnFrom_and_Allowance(c, w3, tx_failed): c.burnFrom(ZERO_ADDRESS, 0, transact={"from": a1}) -def test_raw_logs(c, w3, get_log_args): - minter, a1, a2, a3 = w3.eth.accounts[0:4] +def test_raw_logs(c, revm_env, get_log_args): + minter, a1, a2, a3 = revm_env.accounts[0:4] # Check that mint appropriately emits Transfer event args = get_log_args(c.mint(a1, 2, transact={"from": minter}), c, "Transfer") - assert args.sender == ZERO_ADDRESS + assert args.sender in (ZERO_ADDRESS, None) assert args.receiver == a1 assert args.value == 2 args = get_log_args(c.mint(a1, 0, transact={"from": minter}), c, "Transfer") - assert args.sender == ZERO_ADDRESS + assert args.sender in (ZERO_ADDRESS, None) 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") assert args.sender == a1 - assert args.receiver == ZERO_ADDRESS + assert args.receiver in (ZERO_ADDRESS, None) assert args.value == 1 args = get_log_args(c.burn(0, transact={"from": a1}), c, "Transfer") assert args.sender == a1 - assert args.receiver == ZERO_ADDRESS + assert args.receiver in (ZERO_ADDRESS, None) assert args.value == 0 # Check that transfer appropriately emits Transfer event @@ -334,9 +332,9 @@ def test_raw_logs(c, w3, get_log_args): assert args.value == 0 -def test_bad_transfer(c_bad, w3, tx_failed): +def test_bad_transfer(c_bad, revm_env, tx_failed): # Ensure transfer fails if it would otherwise overflow balance when totalSupply is corrupted - minter, a1, a2 = w3.eth.accounts[0:3] + minter, a1, a2 = revm_env.accounts[0:3] c_bad.mint(a1, MAX_UINT256, transact={"from": minter}) c_bad.mint(a2, 1, transact={"from": minter}) with tx_failed(): @@ -346,9 +344,9 @@ def test_bad_transfer(c_bad, w3, tx_failed): assert c_bad.balanceOf(a2) == MAX_UINT256 -def test_bad_burn(c_bad, w3, tx_failed): +def test_bad_burn(c_bad, revm_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 = revm_env.accounts[0:2] assert c_bad.balanceOf(a1) == 0 c_bad.mint(a1, 2, transact={"from": minter}) assert c_bad.balanceOf(a1) == 2 @@ -356,9 +354,9 @@ def test_bad_burn(c_bad, w3, tx_failed): c_bad.burn(3, transact={"from": a1}) -def test_bad_transferFrom(c_bad, w3, tx_failed): +def test_bad_transferFrom(c_bad, revm_env, tx_failed): # Ensure transferFrom fails if it would otherwise overflow balance when totalSupply is corrupted - minter, a1, a2 = w3.eth.accounts[0:3] + minter, a1, a2 = revm_env.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}) diff --git a/tests/functional/examples/tokens/test_erc4626.py b/tests/functional/examples/tokens/test_erc4626.py index 2469a7abd0..b8fd7be819 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(revm_env, vault): + a = revm_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(revm_env, token, vault): + a = revm_env.accounts[0] assert vault.totalAssets() == 0 assert vault.convertToAssets(10**18) == 0 # no assets diff --git a/tests/functional/examples/tokens/test_erc721.py b/tests/functional/examples/tokens/test_erc721.py index 4f55807ed3..81abb0cfab 100644 --- a/tests/functional/examples/tokens/test_erc721.py +++ b/tests/functional/examples/tokens/test_erc721.py @@ -11,11 +11,11 @@ @pytest.fixture -def c(get_contract, w3): +def c(get_contract, revm_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 = revm_env.accounts[:3] # someone owns 3 tokens for i in SOMEONE_TOKEN_IDS: c.mint(someone, i, transact={"from": minter}) @@ -24,7 +24,7 @@ def c(get_contract, w3): return c -def test_erc165(w3, c): +def test_erc165(revm_env, c): # From EIP-165: # The source contract makes a STATICCALL to the destination address with input data: # 0x01ffc9a701ffc9a700000000000000000000000000000000000000000000000000000000 @@ -40,22 +40,22 @@ 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, revm_env, tx_failed): + someone = revm_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, revm_env, tx_failed): + someone = revm_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, revm_env): + someone, operator = revm_env.accounts[1:3] assert c.getApproved(SOMEONE_TOKEN_IDS[0]) is None @@ -64,8 +64,8 @@ def test_getApproved(c, w3): assert c.getApproved(SOMEONE_TOKEN_IDS[0]) == operator -def test_isApprovedForAll(c, w3): - someone, operator = w3.eth.accounts[1:3] +def test_isApprovedForAll(c, revm_env): + someone, operator = revm_env.accounts[1:3] assert c.isApprovedForAll(someone, operator) == 0 @@ -74,8 +74,8 @@ def test_isApprovedForAll(c, w3): 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, revm_env, tx_failed, get_logs): + someone, operator = revm_env.accounts[1:3] # transfer from zero address with tx_failed(): @@ -108,8 +108,8 @@ def test_transferFrom_by_owner(c, w3, tx_failed, get_logs): 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, revm_env, get_logs): + someone, operator = revm_env.accounts[1:3] # transfer by approved c.approve(operator, SOMEONE_TOKEN_IDS[1], transact={"from": someone}) @@ -127,8 +127,8 @@ def test_transferFrom_by_approved(c, w3, get_logs): 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, revm_env, get_logs): + someone, operator = revm_env.accounts[1:3] # transfer by operator c.setApprovalForAll(operator, True, transact={"from": someone}) @@ -146,8 +146,8 @@ def test_transferFrom_by_operator(c, w3, get_logs): 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, revm_env, tx_failed, get_logs): + someone, operator = revm_env.accounts[1:3] # transfer from zero address with tx_failed(): @@ -182,8 +182,8 @@ def test_safeTransferFrom_by_owner(c, w3, tx_failed, get_logs): 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, revm_env, get_logs): + someone, operator = revm_env.accounts[1:3] # transfer by approved c.approve(operator, SOMEONE_TOKEN_IDS[1], transact={"from": someone}) @@ -203,8 +203,8 @@ 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, revm_env, get_logs): + someone, operator = revm_env.accounts[1:3] # transfer by operator c.setApprovalForAll(operator, True, transact={"from": someone}) @@ -224,8 +224,8 @@ def test_safeTransferFrom_by_operator(c, w3, get_logs): 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, revm_env, tx_failed, get_logs, get_contract): + someone = revm_env.accounts[1] # Can't transfer to a contract that doesn't implement the receiver code with tx_failed(): @@ -260,8 +260,8 @@ def onERC721Received( 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, revm_env, tx_failed, get_logs): + someone, operator = revm_env.accounts[1:3] # approve myself with tx_failed(): @@ -285,8 +285,8 @@ def test_approve(c, w3, tx_failed, get_logs): assert 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, revm_env, tx_failed, get_logs): + someone, operator = revm_env.accounts[1:3] approved = True # setApprovalForAll myself @@ -303,8 +303,8 @@ def test_setApprovalForAll(c, w3, tx_failed, get_logs): assert args.approved == approved -def test_mint(c, w3, tx_failed, get_logs): - minter, someone = w3.eth.accounts[:2] +def test_mint(c, revm_env, tx_failed, get_logs): + minter, someone = revm_env.accounts[:2] # mint by non-minter with tx_failed(): @@ -320,15 +320,15 @@ def test_mint(c, w3, tx_failed, get_logs): assert len(logs) > 0 args = logs[0].args - assert args.sender == ZERO_ADDRESS + assert args.sender in (ZERO_ADDRESS, None) assert args.receiver == someone assert args.token_id == NEW_TOKEN_ID assert c.ownerOf(NEW_TOKEN_ID) == someone 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, revm_env, tx_failed, get_logs): + someone, operator = revm_env.accounts[1:3] # burn token without ownership with tx_failed(): @@ -341,7 +341,7 @@ def test_burn(c, w3, tx_failed, get_logs): assert len(logs) > 0 args = logs[0].args assert args.sender == someone - assert args.receiver == ZERO_ADDRESS + assert args.receiver in (ZERO_ADDRESS, None) assert args.token_id == SOMEONE_TOKEN_IDS[0] with tx_failed(): c.ownerOf(SOMEONE_TOKEN_IDS[0]) diff --git a/tests/functional/examples/voting/test_ballot.py b/tests/functional/examples/voting/test_ballot.py index 9c3a09fc83..326e3ef7c0 100644 --- a/tests/functional/examples/voting/test_ballot.py +++ b/tests/functional/examples/voting/test_ballot.py @@ -14,8 +14,8 @@ def c(get_contract): z0 = "0x0000000000000000000000000000000000000000" -def test_initial_state(w3, c): - a0 = w3.eth.accounts[0] +def test_initial_state(revm_env, c): + a0 = revm_env.accounts[0] # Check chairperson is msg.sender assert c.chairperson() == a0 # Check propsal names are correct @@ -33,8 +33,8 @@ def test_initial_state(w3, c): assert c.voters(z0)[0] == 0 # Voter.weight -def test_give_the_right_to_vote(w3, c, tx_failed): - a0, a1, a2, a3, a4, a5 = w3.eth.accounts[:6] +def test_give_the_right_to_vote(revm_env, c, tx_failed): + a0, a1, a2, a3, a4, a5 = revm_env.accounts[:6] c.giveRightToVote(a1, transact={}) # Check voter given right has weight of 1 assert c.voters(a1)[0] == 1 # Voter.weight @@ -62,8 +62,8 @@ def test_give_the_right_to_vote(w3, c, tx_failed): 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] +def test_forward_weight(revm_env, c): + a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = revm_env.accounts[:10] c.giveRightToVote(a0, transact={}) c.giveRightToVote(a1, transact={}) c.giveRightToVote(a2, transact={}) @@ -128,8 +128,8 @@ def test_forward_weight(w3, c): 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] +def test_block_short_cycle(revm_env, c, tx_failed): + a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = revm_env.accounts[:10] c.giveRightToVote(a0, transact={}) c.giveRightToVote(a1, transact={}) c.giveRightToVote(a2, transact={}) @@ -152,8 +152,8 @@ def test_block_short_cycle(w3, c, tx_failed): # 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] +def test_delegate(revm_env, c, tx_failed): + a0, a1, a2, a3, a4, a5, a6 = revm_env.accounts[:7] c.giveRightToVote(a0, transact={}) c.giveRightToVote(a1, transact={}) c.giveRightToVote(a2, transact={}) @@ -184,8 +184,8 @@ def test_delegate(w3, c, tx_failed): 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] +def test_vote(revm_env, c, tx_failed): + a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = revm_env.accounts[:10] c.giveRightToVote(a0, transact={}) c.giveRightToVote(a1, transact={}) c.giveRightToVote(a2, transact={}) @@ -217,8 +217,8 @@ def test_vote(w3, c, tx_failed): c.vote(2, transact={"from": a7}) -def test_winning_proposal(w3, c): - a0, a1, a2 = w3.eth.accounts[:3] +def test_winning_proposal(revm_env, c): + a0, a1, a2 = revm_env.accounts[:3] c.giveRightToVote(a0, transact={}) c.giveRightToVote(a1, transact={}) c.giveRightToVote(a2, transact={}) @@ -233,8 +233,8 @@ def test_winning_proposal(w3, c): assert c.winningProposal() == 1 -def test_winner_namer(w3, c): - a0, a1, a2 = w3.eth.accounts[:3] +def test_winner_namer(revm_env, c): + a0, a1, a2 = revm_env.accounts[:3] c.giveRightToVote(a0, transact={}) c.giveRightToVote(a1, transact={}) c.giveRightToVote(a2, transact={}) diff --git a/tests/functional/examples/wallet/test_wallet.py b/tests/functional/examples/wallet/test_wallet.py index b9db5acee3..4be6bf3624 100644 --- a/tests/functional/examples/wallet/test_wallet.py +++ b/tests/functional/examples/wallet/test_wallet.py @@ -2,17 +2,17 @@ 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 @pytest.fixture -def c(w3, get_contract): - a0, a1, a2, a3, a4, a5, a6 = w3.eth.accounts[:7] +def c(revm_env, get_contract): + a0, a1, a2, a3, a4, a5, a6 = revm_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}) + revm_env.execute_code(c.address, value=10**17) return c @@ -29,12 +29,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(revm_env, c, tx_failed, sign): + a0, a1, a2, a3, a4, a5, a6 = revm_env.accounts[:7] + k0, k1, k2, k3, k4, k5, k6, k7 = revm_env._keys[:8] + revm_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] @@ -67,8 +68,8 @@ def pack_and_sign(seq, *args): print("Basic tests passed") -def test_javascript_signatures(w3, get_contract): - a3 = w3.eth.accounts[2] +def test_javascript_signatures(revm_env, get_contract, keccak): + a3 = revm_env.accounts[2] # The zero address will cause `approve` to default to valid signatures zero_address = "0x0000000000000000000000000000000000000000" accounts = [ @@ -85,14 +86,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 +105,13 @@ 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}) + revm_env.execute_code(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") diff --git a/tests/functional/syntax/test_return_tuple.py b/tests/functional/syntax/test_return_tuple.py index 71d6b92dfe..5364cc9206 100644 --- a/tests/functional/syntax/test_return_tuple.py +++ b/tests/functional/syntax/test_return_tuple.py @@ -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): diff --git a/tests/functional/syntax/test_self_balance.py b/tests/functional/syntax/test_self_balance.py index 4f844088f6..39dfa55ce0 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(revm_env, get_contract_with_gas_estimation): code = """ @external @view @@ -18,6 +18,9 @@ def __default__(): assert "SELFBALANCE" in opcodes c = get_contract_with_gas_estimation(code) - w3.eth.send_transaction({"to": c.address, "value": 1337}) + revm_env.set_balance(revm_env.deployer, 1337) + revm_env.execute_code(**{"to": c.address, "value": 1337}) assert c.get_balance() == 1337 + assert revm_env.get_balance(c.address) == 1337 + assert revm_env.get_balance(revm_env.deployer) == 0 diff --git a/tests/revm/abi_contract.py b/tests/revm/abi_contract.py index 32f36244f2..33204457d5 100644 --- a/tests/revm/abi_contract.py +++ b/tests/revm/abi_contract.py @@ -175,7 +175,8 @@ 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( - f"Bad args to `{repr(self)}` (expected {self.argument_count} " + "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: @@ -194,7 +195,7 @@ def __call__(self, *args, value=0, gas=None, sender=None, transact=None, call=No sender = self.contract.env.deployer computation = self.contract.env.execute_code( - to_address=self.contract.address, + to=self.contract.address, sender=sender, data=self.prepare_calldata(*args, **kwargs), value=value, diff --git a/tests/revm/revm_env.py b/tests/revm/revm_env.py index 383856ce0a..3582ea1de2 100644 --- a/tests/revm/revm_env.py +++ b/tests/revm/revm_env.py @@ -71,7 +71,7 @@ def contract(self, abi, bytecode) -> "ABIContract": def execute_code( self, - to_address: HexAddress, + to: HexAddress, sender: HexAddress | None = None, data: bytes | str = b"", value: int | None = None, @@ -85,7 +85,7 @@ def execute_code( data = data if isinstance(data, bytes) else bytes.fromhex(data.removeprefix("0x")) try: output = self.evm.message_call( - to=to_address, + to=to, caller=transact.get("from", sender) or self.deployer, calldata=data, value=transact.get("value", value), @@ -101,7 +101,7 @@ def execute_code( # Check EIP838 error, with ABI Error(string) if output_bytes[:4] == method_id("Error(string)"): (msg,) = abi_decode("(string)", output_bytes[4:]) - raise TransactionFailed(msg, gas_used) from e + raise TransactionFailed(f"execution reverted: {msg}", gas_used) from e raise TransactionFailed(*e.args) from e def get_code(self, address: HexAddress): @@ -193,3 +193,19 @@ def deploy(self, abi: list[dict], bytecode: bytes, value=0, *args, **kwargs): address = to_checksum_address(deployed_at) return factory.at(self, address) + + def mine(self, num_blocks=1, time_delta: int | None = None) -> None: + if time_delta is None: + time_delta = num_blocks + self.evm.set_block_env( + BlockEnv( + number=self.evm.env.block.number + num_blocks, + coinbase=self.evm.env.block.coinbase, + timestamp=self.evm.env.block.timestamp + time_delta, + difficulty=self.evm.env.block.difficulty, + prevrandao=self.evm.env.block.prevrandao, + basefee=self.evm.env.block.basefee, + gas_limit=self.evm.env.block.gas_limit, + excess_blob_gas=self.evm.env.block.excess_blob_gas, + ) + ) From 2e1f52e5bc394885ec251e17083c591a69423bd6 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 27 Mar 2024 16:24:37 +0100 Subject: [PATCH 20/87] Use default_chain_id --- tests/functional/syntax/test_chainid.py | 4 ++-- tests/revm/revm_env.py | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/functional/syntax/test_chainid.py b/tests/functional/syntax/test_chainid.py index 3ff540f212..e0281395ba 100644 --- a/tests/functional/syntax/test_chainid.py +++ b/tests/functional/syntax/test_chainid.py @@ -81,7 +81,7 @@ 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_with_gas_estimation, revm_env): code = """ @external @view @@ -89,4 +89,4 @@ 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 + assert c.get_chain_id() == revm_env.default_chain_id diff --git a/tests/revm/revm_env.py b/tests/revm/revm_env.py index 3582ea1de2..4817c48e60 100644 --- a/tests/revm/revm_env.py +++ b/tests/revm/revm_env.py @@ -20,6 +20,8 @@ class RevmEnv: + default_chain_id = 1 + def __init__(self, gas_limit: int, tracing=False, block_number=1) -> None: self.gas_limit = gas_limit self.evm = EVM( From 12ef64f84668387240663375f80d322fad816183 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 27 Mar 2024 16:37:31 +0100 Subject: [PATCH 21/87] Convert unit tests, save bytecode --- tests/revm/abi_contract.py | 23 ++++++++++++----- tests/revm/revm_env.py | 2 +- tests/unit/compiler/test_bytecode_runtime.py | 8 +++--- tests/unit/conftest.py | 26 ++++++++++++++++++++ 4 files changed, 47 insertions(+), 12 deletions(-) create mode 100644 tests/unit/conftest.py diff --git a/tests/revm/abi_contract.py b/tests/revm/abi_contract.py index 33204457d5..0e07461728 100644 --- a/tests/revm/abi_contract.py +++ b/tests/revm/abi_contract.py @@ -301,6 +301,7 @@ def __init__( abi: dict, functions: list[ABIFunction], log_topics: list[ABILogTopic], + bytecode: Optional[bytes], address: HexAddress, filename: Optional[str] = None, ): @@ -311,8 +312,9 @@ def __init__( self._name = name self._functions = functions self.log_topics = log_topics - self._bytecode = self.env.get_code(address) - if not self._bytecode: + 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) @@ -350,7 +352,7 @@ def deployer(self) -> "ABIContractFactory": def __repr__(self): file_str = f" (file {self.filename})" if self.filename else "" - warn_str = "" if self._bytecode else " (WARNING: no bytecode at this address!)" + 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: Log) -> ABILog: @@ -377,26 +379,35 @@ def __init__( abi: dict, functions: list[ABIFunction], log_topics: list[ABILogTopic], + bytecode: Optional[bytes] = None, filename: Optional[str] = None, ): self._name = name self._abi = abi self._functions = functions self._log_topics = log_topics + self._bytecode = bytecode self._filename = filename @classmethod - def from_abi_dict(cls, abi, name=""): + 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, filename=name) + return cls(basename(name), abi, functions, log_topics, bytecode, filename=name) def at(self, env, address: HexAddress) -> ABIContract: """ Create an ABI contract object for a deployed contract at `address`. """ contract = ABIContract( - env, self._name, self._abi, self._functions, self._log_topics, address, self._filename + env, + self._name, + self._abi, + self._functions, + self._log_topics, + self._bytecode, + address, + self._filename, ) env.register_contract(address, contract) return contract diff --git a/tests/revm/revm_env.py b/tests/revm/revm_env.py index 4817c48e60..9fe82bcd39 100644 --- a/tests/revm/revm_env.py +++ b/tests/revm/revm_env.py @@ -178,7 +178,7 @@ def factory(address): return deployer, factory def deploy(self, abi: list[dict], bytecode: bytes, value=0, *args, **kwargs): - factory = ABIContractFactory.from_abi_dict(abi=abi) + factory = ABIContractFactory.from_abi_dict(abi, bytecode=bytecode) initcode = bytecode if args or kwargs: diff --git a/tests/unit/compiler/test_bytecode_runtime.py b/tests/unit/compiler/test_bytecode_runtime.py index 64cee3a75c..7d0a302fab 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, revm_env): c = get_contract(code) - deployed_code = w3.eth.get_code(c.address) + deployed_code = revm_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/conftest.py b/tests/unit/conftest.py new file mode 100644 index 0000000000..0689b04ce4 --- /dev/null +++ b/tests/unit/conftest.py @@ -0,0 +1,26 @@ +import pytest + + +@pytest.fixture(scope="module") +def get_contract(get_revm_contract): + return get_revm_contract + + +@pytest.fixture(scope="module") +def deploy_blueprint_for(deploy_blueprint_revm): + return deploy_blueprint_revm + + +@pytest.fixture(scope="module") +def get_logs(get_logs_revm): + return get_logs_revm + + +@pytest.fixture(scope="module") +def get_contract_with_gas_estimation(get_revm_contract): + return get_revm_contract + + +@pytest.fixture(scope="module") +def get_contract_with_gas_estimation_for_constants(get_revm_contract): + return get_revm_contract From 85affe68defbdf27d72441afc065374e44870605 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 27 Mar 2024 17:19:00 +0100 Subject: [PATCH 22/87] Use evm-version --- .github/workflows/test.yml | 5 ++++- tests/conftest.py | 12 ++++++++++-- tests/revm/revm_env.py | 4 ++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8bd03de79b..bb4121b624 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -64,12 +64,14 @@ jobs: tests: runs-on: ubuntu-latest strategy: + fail-fast: false matrix: python-version: [["3.11", "311"]] opt-mode: ["gas", "none", "codesize"] evm-version: [shanghai] debug: [true, 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: @@ -113,7 +115,7 @@ jobs: debug: false evm-version: shanghai - name: py${{ matrix.python-version[1] }}-opt-${{ matrix.opt-mode }}${{ matrix.debug && '-debug' || '' }}${{ matrix.memorymock && '-memorymock' || '' }}-${{ matrix.evm-version }} + name: py${{ matrix.python-version[1] }}-opt-${{ matrix.opt-mode }}${{ matrix.debug && '-debug' || '' }}${{ matrix.memorymock && '-memorymock' || '' }}-${{ matrix.evm-version }}-${{ matrix.evm-backend }} steps: - uses: actions/checkout@v4 @@ -139,6 +141,7 @@ jobs: -m "not fuzzing" \ --optimize ${{ matrix.opt-mode }} \ --evm-version ${{ matrix.evm-version }} \ + --evm-backend ${{ matrix.evm-backend }} \ ${{ matrix.debug && '--enable-compiler-debug-mode' || '' }} \ ${{ matrix.memorymock && '--memorymock' || '' }} \ --cov-branch \ diff --git a/tests/conftest.py b/tests/conftest.py index 607ca40137..41e9a8f691 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -69,6 +69,13 @@ def pytest_addoption(parser): help="set evm version", ) + parser.addoption( + "--evm-backend", + choices=["py-evm", "revm"], + default="py-evm", + help="set evm backend", + ) + @pytest.fixture(scope="module") def output_formats(): @@ -101,6 +108,7 @@ def evm_version(pytestconfig): # this should get overridden by anchor_evm_version, # but set it anyway evm.active_evm_version = evm.EVM_VERSIONS[evm_version_str] + return evm_version_str @pytest.fixture @@ -190,8 +198,8 @@ def tester(gas_limit): @pytest.fixture(scope="module") -def revm_env(gas_limit, initial_balance): - revm = RevmEnv(gas_limit, tracing=False, block_number=1) +def revm_env(gas_limit, initial_balance, evm_version): + revm = RevmEnv(gas_limit, tracing=False, block_number=1, evm_version=evm_version) revm.set_balance(revm.deployer, initial_balance) return revm diff --git a/tests/revm/revm_env.py b/tests/revm/revm_env.py index 9fe82bcd39..b684a83e05 100644 --- a/tests/revm/revm_env.py +++ b/tests/revm/revm_env.py @@ -22,12 +22,12 @@ class RevmEnv: default_chain_id = 1 - def __init__(self, gas_limit: int, tracing=False, block_number=1) -> None: + def __init__(self, gas_limit: int, tracing=False, block_number=1, evm_version="latest") -> None: self.gas_limit = gas_limit self.evm = EVM( gas_limit=gas_limit, tracing=tracing, - spec_id="Shanghai", + spec_id=evm_version, env=Env(block=BlockEnv(number=block_number)), ) self.contracts: dict[HexAddress, ABIContract] = {} From d083710c7ef8426e9d38f33a20a5d3e432d3ca12 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 2 Apr 2024 09:32:25 +0200 Subject: [PATCH 23/87] Lint and test args --- .github/workflows/test.yml | 9 +++++++++ tests/conftest.py | 5 +---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bb4121b624..d8f59cc8d9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -80,21 +80,26 @@ jobs: debug: false opt-mode: gas evm-version: london + evm-backend: revm + - python-version: ["3.11", "311"] debug: false opt-mode: gas evm-version: paris + evm-backend: revm # redundant rule, for clarity - python-version: ["3.11", "311"] debug: false opt-mode: gas evm-version: shanghai + evm-backend: revm - python-version: ["3.11", "311"] debug: false opt-mode: gas evm-version: cancun + evm-backend: revm # run with `--memorymock`, but only need to do it one configuration # TODO: consider removing the memorymock tests @@ -103,6 +108,7 @@ jobs: debug: false evm-version: shanghai memorymock: true + evm-backend: revm # run across other python versions. we don't really need to run all # modes across all python versions - one is enough @@ -110,10 +116,13 @@ jobs: opt-mode: gas debug: false evm-version: shanghai + evm-backend: revm + - python-version: ["3.12", "312"] opt-mode: gas debug: false evm-version: shanghai + evm-backend: revm name: py${{ matrix.python-version[1] }}-opt-${{ matrix.opt-mode }}${{ matrix.debug && '-debug' || '' }}${{ matrix.memorymock && '-memorymock' || '' }}-${{ matrix.evm-version }}-${{ matrix.evm-backend }} diff --git a/tests/conftest.py b/tests/conftest.py index 41e9a8f691..f300fec52d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -70,10 +70,7 @@ def pytest_addoption(parser): ) parser.addoption( - "--evm-backend", - choices=["py-evm", "revm"], - default="py-evm", - help="set evm backend", + "--evm-backend", choices=["py-evm", "revm"], default="py-evm", help="set evm backend" ) From ebfa8f9054bd304501fc463f3373a7b3d433e250 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 2 Apr 2024 09:55:24 +0200 Subject: [PATCH 24/87] Get rid of w3 --- tests/functional/builtins/codegen/test_raw_call.py | 4 ++-- .../codegen/environment_variables/test_blockhash.py | 8 +++----- .../codegen/modules/test_stateless_functions.py | 2 +- tests/functional/codegen/types/test_string.py | 2 +- tests/functional/syntax/test_msg_data.py | 11 +++++------ 5 files changed, 12 insertions(+), 15 deletions(-) diff --git a/tests/functional/builtins/codegen/test_raw_call.py b/tests/functional/builtins/codegen/test_raw_call.py index 4228c98187..6afd0306ff 100644 --- a/tests/functional/builtins/codegen/test_raw_call.py +++ b/tests/functional/builtins/codegen/test_raw_call.py @@ -233,7 +233,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, revm_env, keccak): target_source = """ @external def foo() -> uint256: @@ -259,7 +259,7 @@ def __default__(): # manually construct msg.data for `caller` contract sig = keccak("foo()".encode()).hex()[:10] - w3.eth.send_transaction({"to": caller.address, "data": sig}) + assert revm_env.execute_code(caller.address, data=sig) == b"" # check max_outsize=0 does same thing as not setting max_outsize. diff --git a/tests/functional/codegen/environment_variables/test_blockhash.py b/tests/functional/codegen/environment_variables/test_blockhash.py index 68db053b12..a57ec46c15 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_with_gas_estimation): block_number_code = """ @external def prev() -> bytes32: @@ -23,8 +21,8 @@ def foo() -> bytes32: assert_compile_failed(lambda: get_contract_with_gas_estimation(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_with_gas_estimation, revm_env): + revm_env.mine(257) code = """ @external def get_50_blockhash() -> bytes32: diff --git a/tests/functional/codegen/modules/test_stateless_functions.py b/tests/functional/codegen/modules/test_stateless_functions.py index 27643dbd11..4ed8d89a6e 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, revm_env): +def test_simple_library(get_contract, make_input_bundle, revm_env): library_source = """ @internal def foo() -> uint256: diff --git a/tests/functional/codegen/types/test_string.py b/tests/functional/codegen/types/test_string.py index c34065b862..6f0ca718a5 100644 --- a/tests/functional/codegen/types/test_string.py +++ b/tests/functional/codegen/types/test_string.py @@ -41,7 +41,7 @@ def testa(inp: String[10]) -> String[160]: 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] diff --git a/tests/functional/syntax/test_msg_data.py b/tests/functional/syntax/test_msg_data.py index 3c43c78d82..d54bb27575 100644 --- a/tests/functional/syntax/test_msg_data.py +++ b/tests/functional/syntax/test_msg_data.py @@ -1,5 +1,6 @@ import pytest from eth_tester.exceptions import TransactionFailed +from eth_utils import to_bytes from vyper import compiler from vyper.exceptions import StructureException, TypeMismatch @@ -31,7 +32,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, keccak): code = """ @external def foo(bar: uint256) -> Bytes[36]: @@ -42,7 +43,7 @@ def foo(bar: uint256) -> Bytes[36]: # 2fbebd38000000000000000000000000000000000000000000000000000000000000002a method_id = keccak(text="foo(uint256)").hex()[2:10] # 2fbebd38 - encoded_42 = w3.to_bytes(42).hex() # 2a + encoded_42 = to_bytes(42).hex() # 2a expected_result = method_id + "00" * 31 + encoded_42 assert contract.foo(42).hex() == expected_result @@ -76,7 +77,7 @@ def foo() -> (uint256, Bytes[4], uint256): assert contract.foo() == (2**256 - 1, bytes(keccak(text="foo()")[:4]), 2**256 - 1) -def test_assignment_to_storage(w3, get_contract, keccak): +def test_assignment_to_storage(revm_env, get_contract, keccak): code = """ cache: public(Bytes[4]) @@ -84,10 +85,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(transact={}) assert contract.cache() == bytes(keccak(text="foo()")[:4]) From 60ba06349d79666aac61005f3d22b3b8b1735430 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 2 Apr 2024 21:26:28 +0200 Subject: [PATCH 25/87] Update hexbytes version and tests --- setup.py | 1 + .../builtins/codegen/test_keccak256.py | 10 +++--- .../test_external_contract_calls.py | 4 +-- .../codegen/features/test_logging.py | 36 +++++++++---------- tests/functional/syntax/test_msg_data.py | 2 +- 5 files changed, 27 insertions(+), 26 deletions(-) diff --git a/setup.py b/setup.py index 933e8bfa4b..4e81b80b07 100644 --- a/setup.py +++ b/setup.py @@ -16,6 +16,7 @@ "eth-tester[py-evm]>=0.10.0b4,<0.11", "eth_abi>=4.0.0,<5.0.0", "py-evm>=0.10.0b4,<0.11", + "hexbytes>1.0,<2.0", "web3==6.0.0", "lark==1.1.9", "hypothesis[lark]>=6.0,<7.0", diff --git a/tests/functional/builtins/codegen/test_keccak256.py b/tests/functional/builtins/codegen/test_keccak256.py index 3b0b9f2018..8b5d14495e 100644 --- a/tests/functional/builtins/codegen/test_keccak256.py +++ b/tests/functional/builtins/codegen/test_keccak256.py @@ -18,10 +18,10 @@ def bar() -> bytes32: c = get_contract_with_gas_estimation(hash_code) for inp in (b"", b"cow", b"s" * 31, b"\xff" * 32, b"\n" * 33, b"g" * 64, b"h" * 65): - assert "0x" + c.foo(inp).hex() == keccak(inp).hex() + assert c.foo(inp).hex() == keccak(inp).hex() - assert "0x" + c.bar().hex() == keccak(b"inp").hex() - assert "0x" + c.foob().hex() == keccak(b"inp").hex() + assert c.bar().hex() == keccak(b"inp").hex() + assert c.foob().hex() == keccak(b"inp").hex() def test_hash_code2(get_contract_with_gas_estimation): @@ -96,7 +96,7 @@ def foo() -> bytes32: return x """ c = get_contract_with_gas_estimation(code) - assert "0x" + c.foo().hex() == keccak(hex_to_int(hex_val).to_bytes(32, "big")).hex() + assert c.foo().hex() == keccak(hex_to_int(hex_val).to_bytes(32, "big")).hex() def test_hash_constant_string(get_contract_with_gas_estimation, keccak): @@ -110,4 +110,4 @@ def foo() -> bytes32: return x """ c = get_contract_with_gas_estimation(code) - assert "0x" + c.foo().hex() == keccak(str_val.encode()).hex() + assert c.foo().hex() == keccak(str_val.encode()).hex() 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 0f5f915a48..0108c7cf42 100644 --- a/tests/functional/codegen/calling_convention/test_external_contract_calls.py +++ b/tests/functional/codegen/calling_convention/test_external_contract_calls.py @@ -2503,7 +2503,7 @@ def foo(a: {typ}): pass """ c1 = get_contract(code) - sig = keccak(f"foo({typ})".encode()).hex()[:10] + sig = keccak(f"foo({typ})".encode()).to_0x_hex()[:10] encoded = abi.encode(f"({typ})", (val,)).hex() data = f"{sig}{encoded}" @@ -2528,7 +2528,7 @@ def foo(a: DynArray[{typ}, 3], b: String[5]): """ c1 = get_contract(code) - sig = keccak(f"foo({typ}[],string)".encode()).hex()[:10] + sig = keccak(f"foo({typ}[],string)".encode()).to_0x_hex()[:10] encoded = abi.encode(f"({typ}[],string)", val).hex() data = f"{sig}{encoded}" diff --git a/tests/functional/codegen/features/test_logging.py b/tests/functional/codegen/features/test_logging.py index cf64d271a9..55ab408081 100644 --- a/tests/functional/codegen/features/test_logging.py +++ b/tests/functional/codegen/features/test_logging.py @@ -34,7 +34,7 @@ def foo(): event_id = keccak(bytes("MyLog()", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.hex() + assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "name": "MyLog", @@ -66,7 +66,7 @@ def foo(): event_id = keccak(bytes("MyLog(bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.hex() + assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "name": "MyLog", @@ -96,7 +96,7 @@ def foo(): event_id = keccak(bytes("MyLog(int128,bool,address)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.hex() + assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "name": "MyLog", @@ -172,8 +172,8 @@ def bar(): event_id = keccak(bytes("MyLog(int128,address)", "utf-8")) # Event id is always the first topic - assert receipt1["logs"][0]["topics"][0] == event_id.hex() - assert receipt2["logs"][0]["topics"][0] == event_id.hex() + assert receipt1["logs"][0]["topics"][0] == event_id.to_0x_hex() + assert receipt2["logs"][0]["topics"][0] == event_id.to_0x_hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "name": "MyLog", @@ -224,7 +224,7 @@ def foo(): event_id = keccak(bytes("MyLog(int128)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.hex() + assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "name": "MyLog", @@ -260,7 +260,7 @@ def 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] == event_id.hex() + assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { @@ -303,7 +303,7 @@ def foo(arg1: Bytes[29], arg2: Bytes[31]): event_id = keccak(bytes("MyLog(bytes,bytes,bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.hex() + assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "name": "MyLog", @@ -341,7 +341,7 @@ def foo(_arg1: Bytes[20]): event_id = keccak(bytes("MyLog(bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.hex() + assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "anonymous": False, @@ -370,7 +370,7 @@ def foo(_arg1: Bytes[5]): event_id = keccak(bytes("MyLog(bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.hex() + assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "anonymous": False, @@ -406,7 +406,7 @@ def 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] == event_id.hex() + assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "name": "MyLog", @@ -453,7 +453,7 @@ def foo(): event_id = keccak(bytes("MyLog(int128,bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.hex() + assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "anonymous": False, @@ -506,8 +506,8 @@ def foo(): event_id2 = keccak(bytes("YourLog(address,(uint256,bytes,(string,fixed168x10)))", "utf-8")) # Event id is always the first topic - assert logs1["topics"][0] == event_id1.hex() - assert logs2["topics"][0] == event_id2.hex() + assert logs1["topics"][0] == event_id1.to_0x_hex() + assert logs2["topics"][0] == event_id2.to_0x_hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "name": "MyLog", @@ -1081,7 +1081,7 @@ def foo(a: Bytes[36], b: int128, c: String[7]): # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - assert receipt["logs"][0]["topics"][0] == event_id.hex() + assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() topic1 = f"0x{keccak256(b'bar').hex()}" assert receipt["logs"][0]["topics"][1] == topic1 @@ -1126,7 +1126,7 @@ def foo(): # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - assert receipt["logs"][0]["topics"][0] == event_id.hex() + assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() topic1 = f"0x{keccak256(b'potato').hex()}" assert receipt["logs"][0]["topics"][1] == topic1 @@ -1180,7 +1180,7 @@ def foo(): # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - assert receipt["logs"][0]["topics"][0] == event_id.hex() + assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() topic1 = f"0x{keccak256(b'zonk').hex()}" assert receipt["logs"][0]["topics"][1] == topic1 @@ -1222,7 +1222,7 @@ def foo(): # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - assert receipt["logs"][0]["topics"][0] == event_id.hex() + assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() topic1 = f"0x{keccak256(b'wow').hex()}" assert receipt["logs"][0]["topics"][1] == topic1 diff --git a/tests/functional/syntax/test_msg_data.py b/tests/functional/syntax/test_msg_data.py index dfeb9cea00..40e636eefc 100644 --- a/tests/functional/syntax/test_msg_data.py +++ b/tests/functional/syntax/test_msg_data.py @@ -41,7 +41,7 @@ def foo(bar: uint256) -> Bytes[36]: contract = get_contract(code) # 2fbebd38000000000000000000000000000000000000000000000000000000000000002a - method_id = keccak(text="foo(uint256)").hex()[2:10] # 2fbebd38 + method_id = keccak(text="foo(uint256)").hex()[:8] # 2fbebd38 encoded_42 = w3.to_bytes(42).hex() # 2a expected_result = method_id + "00" * 31 + encoded_42 From 9e67463d0915ff46f063163eb4b3e43e4b00ee7a Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 2 Apr 2024 21:33:10 +0200 Subject: [PATCH 26/87] Double dependency merge conflict --- setup.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 4e81b80b07..1bcba53107 100644 --- a/setup.py +++ b/setup.py @@ -16,13 +16,12 @@ "eth-tester[py-evm]>=0.10.0b4,<0.11", "eth_abi>=4.0.0,<5.0.0", "py-evm>=0.10.0b4,<0.11", - "hexbytes>1.0,<2.0", "web3==6.0.0", "lark==1.1.9", "hypothesis[lark]>=6.0,<7.0", "eth-stdlib==0.2.7", "setuptools", - "hexbytes<1.0", + "hexbytes>1.0,<2.0", "typing_extensions", # we can remove this once dependencies upgrade to eth-rlp>=2.0 ], "lint": [ From 76c91aa259c0f19b6997044622643559db61c688 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 2 Apr 2024 21:43:52 +0200 Subject: [PATCH 27/87] Use vyper.utils.keccak256 --- tests/conftest.py | 4 +-- .../test_external_contract_calls.py | 8 ++--- .../codegen/features/test_logging.py | 36 +++++++++---------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index d0681cdf42..dc336ee789 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -23,7 +23,7 @@ from vyper.compiler.input_bundle import FilesystemInputBundle, InputBundle from vyper.compiler.settings import OptimizationLevel, Settings, _set_debug_mode from vyper.ir import compile_ir, optimizer -from vyper.utils import ERC5202_PREFIX +from vyper.utils import ERC5202_PREFIX, keccak256 # Import the base fixtures pytest_plugins = ["tests.fixtures.memorymock"] @@ -144,7 +144,7 @@ def chdir_tmp_path(tmp_path): # CMC 2024-03-01 this doesn't need to be a fixture @pytest.fixture def keccak(): - return Web3.keccak + return keccak256 @pytest.fixture 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 0108c7cf42..f92e07e681 100644 --- a/tests/functional/codegen/calling_convention/test_external_contract_calls.py +++ b/tests/functional/codegen/calling_convention/test_external_contract_calls.py @@ -2503,9 +2503,9 @@ def foo(a: {typ}): pass """ c1 = get_contract(code) - sig = keccak(f"foo({typ})".encode()).to_0x_hex()[:10] + sig = keccak(f"foo({typ})".encode()).hex()[:8] encoded = abi.encode(f"({typ})", (val,)).hex() - data = f"{sig}{encoded}" + data = f"0x{sig}{encoded}" # Static size is short by 1 byte malformed = data[:-2] @@ -2528,9 +2528,9 @@ def foo(a: DynArray[{typ}, 3], b: String[5]): """ c1 = get_contract(code) - sig = keccak(f"foo({typ}[],string)".encode()).to_0x_hex()[:10] + sig = keccak(f"foo({typ}[],string)".encode()).hex()[:8] encoded = abi.encode(f"({typ}[],string)", val).hex() - data = f"{sig}{encoded}" + data = f"0x{sig}{encoded}" # Dynamic size is short by 1 byte malformed = data[:264] diff --git a/tests/functional/codegen/features/test_logging.py b/tests/functional/codegen/features/test_logging.py index 55ab408081..40f163d837 100644 --- a/tests/functional/codegen/features/test_logging.py +++ b/tests/functional/codegen/features/test_logging.py @@ -34,7 +34,7 @@ def foo(): event_id = keccak(bytes("MyLog()", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() + assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "name": "MyLog", @@ -66,7 +66,7 @@ def foo(): event_id = keccak(bytes("MyLog(bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() + assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "name": "MyLog", @@ -96,7 +96,7 @@ def foo(): event_id = keccak(bytes("MyLog(int128,bool,address)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() + assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "name": "MyLog", @@ -172,8 +172,8 @@ def bar(): event_id = keccak(bytes("MyLog(int128,address)", "utf-8")) # Event id is always the first topic - assert receipt1["logs"][0]["topics"][0] == event_id.to_0x_hex() - assert receipt2["logs"][0]["topics"][0] == event_id.to_0x_hex() + assert receipt1["logs"][0]["topics"][0] == "0x" + event_id.hex() + assert receipt2["logs"][0]["topics"][0] == "0x" + event_id.hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "name": "MyLog", @@ -224,7 +224,7 @@ def foo(): event_id = keccak(bytes("MyLog(int128)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() + assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "name": "MyLog", @@ -260,7 +260,7 @@ def 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] == event_id.to_0x_hex() + assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { @@ -303,7 +303,7 @@ def foo(arg1: Bytes[29], arg2: Bytes[31]): event_id = keccak(bytes("MyLog(bytes,bytes,bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() + assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "name": "MyLog", @@ -341,7 +341,7 @@ def foo(_arg1: Bytes[20]): event_id = keccak(bytes("MyLog(bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() + assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "anonymous": False, @@ -370,7 +370,7 @@ def foo(_arg1: Bytes[5]): event_id = keccak(bytes("MyLog(bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() + assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "anonymous": False, @@ -406,7 +406,7 @@ def 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] == event_id.to_0x_hex() + assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "name": "MyLog", @@ -453,7 +453,7 @@ def foo(): event_id = keccak(bytes("MyLog(int128,bytes)", "utf-8")) # Event id is always the first topic - assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() + assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "anonymous": False, @@ -506,8 +506,8 @@ def foo(): event_id2 = keccak(bytes("YourLog(address,(uint256,bytes,(string,fixed168x10)))", "utf-8")) # Event id is always the first topic - assert logs1["topics"][0] == event_id1.to_0x_hex() - assert logs2["topics"][0] == event_id2.to_0x_hex() + assert logs1["topics"][0] == "0x" + event_id1.hex() + assert logs2["topics"][0] == "0x" + event_id2.hex() # Event abi is created correctly assert c._classic_contract.abi[0] == { "name": "MyLog", @@ -1081,7 +1081,7 @@ def foo(a: Bytes[36], b: int128, c: String[7]): # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() + assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() topic1 = f"0x{keccak256(b'bar').hex()}" assert receipt["logs"][0]["topics"][1] == topic1 @@ -1126,7 +1126,7 @@ def foo(): # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() + assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() topic1 = f"0x{keccak256(b'potato').hex()}" assert receipt["logs"][0]["topics"][1] == topic1 @@ -1180,7 +1180,7 @@ def foo(): # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() + assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() topic1 = f"0x{keccak256(b'zonk').hex()}" assert receipt["logs"][0]["topics"][1] == topic1 @@ -1222,7 +1222,7 @@ def foo(): # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - assert receipt["logs"][0]["topics"][0] == event_id.to_0x_hex() + assert receipt["logs"][0]["topics"][0] == "0x" + event_id.hex() topic1 = f"0x{keccak256(b'wow').hex()}" assert receipt["logs"][0]["topics"][1] == topic1 From cf1ef521e04b446e5401f33e535f06eb09ececdb Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 2 Apr 2024 21:55:26 +0200 Subject: [PATCH 28/87] hexbytes>=1.2 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 1bcba53107..2379f59379 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ "hypothesis[lark]>=6.0,<7.0", "eth-stdlib==0.2.7", "setuptools", - "hexbytes>1.0,<2.0", + "hexbytes>=1.2", "typing_extensions", # we can remove this once dependencies upgrade to eth-rlp>=2.0 ], "lint": [ From 96eaadbe4efa63ce3ab4b671972ba87fa36bd2ef Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 2 Apr 2024 22:21:27 +0200 Subject: [PATCH 29/87] Update arg --- tests/functional/syntax/test_msg_data.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/functional/syntax/test_msg_data.py b/tests/functional/syntax/test_msg_data.py index 40e636eefc..48443965ac 100644 --- a/tests/functional/syntax/test_msg_data.py +++ b/tests/functional/syntax/test_msg_data.py @@ -15,7 +15,7 @@ def foo() -> Bytes[4]: contract = get_contract(code) - assert contract.foo() == bytes(keccak(text="foo()")[:4]) + assert contract.foo() == bytes(keccak(b"foo()")[:4]) def test_slicing_start_index_other_than_zero(get_contract): @@ -41,7 +41,7 @@ def foo(bar: uint256) -> Bytes[36]: contract = get_contract(code) # 2fbebd38000000000000000000000000000000000000000000000000000000000000002a - method_id = keccak(text="foo(uint256)").hex()[:8] # 2fbebd38 + method_id = keccak(b"foo(uint256)").hex()[:8] # 2fbebd38 encoded_42 = w3.to_bytes(42).hex() # 2a expected_result = method_id + "00" * 31 + encoded_42 @@ -73,7 +73,7 @@ def foo() -> (uint256, Bytes[4], uint256): """ contract = get_contract(code) - assert contract.foo() == [2**256 - 1, bytes(keccak(text="foo()")[:4]), 2**256 - 1] + assert contract.foo() == [2**256 - 1, bytes(keccak(b"foo()")[:4]), 2**256 - 1] def test_assignment_to_storage(w3, get_contract, keccak): @@ -88,7 +88,7 @@ def foo(): contract = get_contract(code) contract.foo(transact={"from": acct}) - assert contract.cache() == bytes(keccak(text="foo()")[:4]) + assert contract.cache() == bytes(keccak(b"foo()")[:4]) def test_get_len(get_contract): From 6cd3819cdf8765383fb7a98a2a9237f8120879bf Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 3 Apr 2024 10:17:55 +0200 Subject: [PATCH 30/87] Missing parameter --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ae30eadda3..5791db78ff 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -108,6 +108,7 @@ jobs: debug: false evm-version: shanghai experimental-codegen: true + evm-backend: revm # TODO: test experimental_codegen + -Ocodesize # run with `--memorymock`, but only need to do it one configuration From 4d04bb7ed706e25a8a25050740ca365f169627ad Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 3 Apr 2024 11:31:14 +0200 Subject: [PATCH 31/87] Convert last test to pyrevm --- tests/conftest.py | 13 +++++- .../codegen/integration/test_crowdfund.py | 45 ++++++++++--------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 5f61b58b81..b6e7d4f1f3 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -129,11 +129,15 @@ def _xfail(*args, **kwargs): @pytest.fixture(scope="session", autouse=True) -def evm_version(pytestconfig): +def evm_version(pytestconfig, evm_backend): + evm_version_str = pytestconfig.getoption("evm_version") + if evm_backend != "py-evm": + # revm uses this fixture to set the evm version + return evm_version_str + # note: we configure the evm version that we emit code for, # but eth-tester is only configured with the latest mainnet # version. - evm_version_str = pytestconfig.getoption("evm_version") evm.DEFAULT_EVM_VERSION = evm_version_str # this should get overridden by anchor_evm_version, # but set it anyway @@ -141,6 +145,11 @@ def evm_version(pytestconfig): return evm_version_str +@pytest.fixture(scope="session", autouse=True) +def evm_backend(pytestconfig): + return pytestconfig.getoption("evm_backend") + + @pytest.fixture def chdir_tmp_path(tmp_path): # this is useful for when you want imports to have relpaths diff --git a/tests/functional/codegen/integration/test_crowdfund.py b/tests/functional/codegen/integration/test_crowdfund.py index fac93e556a..b679aa4641 100644 --- a/tests/functional/codegen/integration/test_crowdfund.py +++ b/tests/functional/codegen/integration/test_crowdfund.py @@ -1,5 +1,5 @@ # TODO: check, this is probably redundant with examples/test_crowdfund.py -def test_crowdfund(w3, tester, get_contract_pyevm): +def test_crowdfund(revm_env, tester, get_contract): crowdfund = """ struct Funder: @@ -62,10 +62,12 @@ def refund(): self.refundIndex = ind + 30 """ - a0, a1, a2, a3, a4, a5, a6 = w3.eth.accounts[:7] + a0, a1, a2, a3, a4, a5, a6 = revm_env.accounts[:7] + for a in revm_env.accounts[:7]: + revm_env.set_balance(a, 10**10) - c = get_contract_pyevm(crowdfund, *[a1, 50, 60]) - start_timestamp = w3.eth.get_block(w3.eth.block_number).timestamp + c = get_contract(crowdfund, *[a1, 50, 60]) + start_timestamp = revm_env.get_block(revm_env.block_number).timestamp c.participate(transact={"value": 5}) assert c.timelimit() == 60 @@ -74,28 +76,28 @@ def refund(): assert not c.reached() c.participate(transact={"value": 49}) assert c.reached() - pre_bal = w3.eth.get_balance(a1) - w3.testing.mine(100) + pre_bal = revm_env.get_balance(a1) + revm_env.mine(100) assert c.expired() c.finalize(transact={}) - post_bal = w3.eth.get_balance(a1) + post_bal = revm_env.get_balance(a1) assert post_bal - pre_bal == 54 - c = get_contract_pyevm(crowdfund, *[a1, 50, 60]) + c = get_contract(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) + revm_env.mine(100) assert c.expired() assert not c.reached() - pre_bals = [w3.eth.get_balance(x) for x in [a3, a4, a5, a6]] + pre_bals = [revm_env.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]] + post_bals = [revm_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_pyevm): +def test_crowdfund2(revm_env, tester, get_contract): crowdfund2 = """ struct Funder: sender: address @@ -156,32 +158,33 @@ def refund(): self.refundIndex = ind + 30 """ - a0, a1, a2, a3, a4, a5, a6 = w3.eth.accounts[:7] - c = get_contract_pyevm(crowdfund2, *[a1, 50, 60]) + a0, a1, a2, a3, a4, a5, a6 = revm_env.accounts[:7] + c = get_contract(crowdfund2, *[a1, 50, 60]) c.participate(transact={"value": 5}) + revm_env.mine(1) assert c.timelimit() == 60 assert c.deadline() - c.block_timestamp() == 59 assert not c.expired() assert not c.reached() c.participate(transact={"value": 49}) assert c.reached() - pre_bal = w3.eth.get_balance(a1) - w3.testing.mine(100) + pre_bal = revm_env.get_balance(a1) + revm_env.mine(100) assert c.expired() c.finalize(transact={}) - post_bal = w3.eth.get_balance(a1) + post_bal = revm_env.get_balance(a1) assert post_bal - pre_bal == 54 - c = get_contract_pyevm(crowdfund2, *[a1, 50, 60]) + c = get_contract(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) + revm_env.mine(100) assert c.expired() assert not c.reached() - pre_bals = [w3.eth.get_balance(x) for x in [a3, a4, a5, a6]] + pre_bals = [revm_env.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]] + post_bals = [revm_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] From 933e66eaf12c81e7465e87661f05ac15df392fff Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 3 Apr 2024 14:25:48 +0200 Subject: [PATCH 32/87] Rename revm_env to env, make _evm private --- tests/conftest.py | 47 ++-- .../builtins/codegen/test_create_functions.py | 85 ++++--- .../builtins/codegen/test_is_contract.py | 4 +- .../builtins/codegen/test_raw_call.py | 22 +- .../functional/builtins/codegen/test_send.py | 24 +- .../test_default_function.py | 42 ++-- .../test_default_parameters.py | 6 +- .../calling_convention/test_erc20_abi.py | 32 +-- .../test_external_contract_calls.py | 38 +-- .../codegen/calling_convention/test_return.py | 4 +- .../test_self_call_struct.py | 6 +- .../test_block_number.py | 9 +- .../environment_variables/test_blockhash.py | 4 +- .../codegen/environment_variables/test_tx.py | 4 +- .../features/decorators/test_nonreentrant.py | 14 +- .../features/decorators/test_payable.py | 20 +- .../features/decorators/test_private.py | 27 +- .../features/iteration/test_range_in.py | 4 +- .../codegen/features/test_address_balance.py | 4 +- .../codegen/features/test_assert.py | 15 +- .../features/test_assert_unreachable.py | 16 +- .../codegen/features/test_bytes_map_keys.py | 2 +- .../codegen/features/test_clampers.py | 82 +++--- .../codegen/features/test_constructor.py | 10 +- .../codegen/features/test_logging.py | 235 ++++++++---------- .../codegen/features/test_reverting.py | 6 +- .../codegen/features/test_short_circuiting.py | 16 +- .../codegen/integration/test_crowdfund.py | 40 +-- .../codegen/integration/test_escrow.py | 8 +- .../modules/test_stateless_functions.py | 4 +- tests/functional/codegen/test_interfaces.py | 16 +- .../functional/codegen/test_selector_table.py | 18 +- tests/functional/codegen/types/test_flag.py | 6 +- .../examples/auctions/test_blind_auction.py | 74 +++--- .../auctions/test_simple_open_auction.py | 40 +-- .../examples/company/test_company.py | 36 +-- .../crowdfund/test_crowdfund_example.py | 38 +-- .../examples/factory/test_factory.py | 8 +- .../test_on_chain_market_maker.py | 34 +-- .../name_registry/test_name_registry.py | 4 +- .../test_safe_remote_purchase.py | 46 ++-- .../examples/storage/test_advanced_storage.py | 12 +- .../examples/storage/test_storage.py | 6 +- .../examples/tokens/test_erc1155.py | 52 ++-- .../functional/examples/tokens/test_erc20.py | 48 ++-- .../examples/tokens/test_erc4626.py | 8 +- .../functional/examples/tokens/test_erc721.py | 66 ++--- .../functional/examples/voting/test_ballot.py | 32 +-- .../functional/examples/wallet/test_wallet.py | 20 +- tests/functional/syntax/test_address_code.py | 4 +- tests/functional/syntax/test_chainid.py | 4 +- tests/functional/syntax/test_msg_data.py | 2 +- tests/functional/syntax/test_self_balance.py | 10 +- tests/revm/abi_contract.py | 9 +- tests/revm/revm_env.py | 51 ++-- tests/unit/compiler/test_bytecode_runtime.py | 4 +- 56 files changed, 728 insertions(+), 750 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index b6e7d4f1f3..a5c1ef2fa8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -15,7 +15,7 @@ from web3.contract import Contract from web3.providers.eth_tester import EthereumTesterProvider -import vyper.evm.opcodes as evm +import vyper.evm.opcodes as evm_opcodes from tests.revm.abi_contract import ABIContract from tests.revm.revm_env import RevmEnv from tests.utils import working_directory @@ -65,13 +65,13 @@ def pytest_addoption(parser): parser.addoption( "--evm-version", - choices=list(evm.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="py-evm", help="set evm backend" + "--evm-backend", choices=["py-evm", "revm"], default="revm", help="set evm backend" ) @@ -131,23 +131,24 @@ def _xfail(*args, **kwargs): @pytest.fixture(scope="session", autouse=True) def evm_version(pytestconfig, evm_backend): evm_version_str = pytestconfig.getoption("evm_version") - if evm_backend != "py-evm": + if evm_backend != "PyevmEnv": # revm uses this fixture to set the evm version return evm_version_str # note: we configure the evm version that we emit code for, # but eth-tester is only configured with the latest mainnet # version. - evm.DEFAULT_EVM_VERSION = evm_version_str + evm_opcodes.DEFAULT_EVM_VERSION = evm_version_str # this should get overridden by anchor_evm_version, # but set it anyway - evm.active_evm_version = evm.EVM_VERSIONS[evm_version_str] + evm_opcodes.active_evm_version = evm_opcodes.EVM_VERSIONS[evm_version_str] return evm_version_str @pytest.fixture(scope="session", autouse=True) def evm_backend(pytestconfig): - return pytestconfig.getoption("evm_backend") + backend_str = pytestconfig.getoption("evm_backend") + return {"py-evm": "PyevmEnv", "revm": RevmEnv}[backend_str] @pytest.fixture @@ -238,10 +239,10 @@ def tester(gas_limit): @pytest.fixture(scope="module") -def revm_env(gas_limit, initial_balance, evm_version): - revm = RevmEnv(gas_limit, tracing=False, block_number=1, evm_version=evm_version) - revm.set_balance(revm.deployer, initial_balance) - return revm +def env(gas_limit, initial_balance, evm_version, evm_backend): + env = evm_backend(gas_limit, tracing=False, block_number=1, evm_version=evm_version) + env.set_balance(env.deployer, initial_balance) + return env def zero_gas_price_strategy(web3, transaction_params=None): @@ -436,9 +437,9 @@ def get_contract(get_contract_pyevm): @pytest.fixture(scope="module") -def get_revm_contract(revm_env, optimize, output_formats): +def get_revm_contract(env, optimize, output_formats): def fn(source_code, *args, **kwargs): - return revm_env.deploy_source(source_code, optimize, output_formats, *args, **kwargs) + return env.deploy_source(source_code, optimize, output_formats, *args, **kwargs) return fn @@ -547,19 +548,25 @@ def deploy_blueprint_for(source_code, *args, **kwargs): @pytest.fixture(scope="module") -def deploy_blueprint_revm(revm_env, optimize, output_formats): +def deploy_blueprint_revm(env, optimize, output_formats): def deploy_blueprint_revm(source_code, *args, **kwargs): - return revm_env.deploy_blueprint(source_code, optimize, output_formats, *args, **kwargs) + return env.deploy_blueprint(source_code, optimize, output_formats, *args, **kwargs) return deploy_blueprint_revm @pytest.fixture(scope="module") -def get_logs_revm(revm_env): - def get_logs(tx_result, c: ABIContract, event_name): - logs = revm_env.evm.result.logs - parsed_logs = [c.parse_log(log) for log in logs if c.address == log.address] - return [log for log in parsed_logs if log.event == event_name] +def get_logs_revm(env): + def get_logs(tx_result, c: ABIContract, event_name: str = None, raw=False): + logs = [log for log in env.last_result["logs"] if c.address == log.address] + if raw: + return [log.data for log in logs] + + parsed_logs = [c.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 return get_logs diff --git a/tests/functional/builtins/codegen/test_create_functions.py b/tests/functional/builtins/codegen/test_create_functions.py index 43274d8038..df9fb43a3b 100644 --- a/tests/functional/builtins/codegen/test_create_functions.py +++ b/tests/functional/builtins/codegen/test_create_functions.py @@ -70,7 +70,7 @@ def test2() -> Bytes[100]: assert c.test2() == b"hello world!" -def test_minimal_proxy_exception(revm_env, get_contract, tx_failed): +def test_minimal_proxy_exception(env, get_contract, tx_failed): code = """ interface SubContract: def hello(a: uint256) -> Bytes[100]: view @@ -105,9 +105,8 @@ def test2(a: uint256) -> Bytes[100]: with tx_failed(): c.test2(0, transact={"gas": GAS_SENT}) - receipt = revm_env.evm.result - assert receipt.is_success is False - assert receipt.gas_used < GAS_SENT + assert env.last_result["is_success"] is False + assert env.last_result["gas_used"] < GAS_SENT def test_create_minimal_proxy_to_create2(get_contract, create2_address_of, keccak, tx_failed): @@ -137,7 +136,7 @@ def test(_salt: bytes32) -> address: def test_create_from_blueprint( get_contract, deploy_blueprint_for, - revm_env, + env, keccak, create2_address_of, tx_failed, @@ -171,7 +170,7 @@ def test2(target: address, salt: bytes32): d.test(f.address) test = FooContract(d.created_address()) - assert revm_env.get_code(test.address) == revm_env.get_code(foo_contract.address) + assert env.get_code(test.address) == env.get_code(foo_contract.address) assert test.foo() == 123 # extcodesize check @@ -184,11 +183,11 @@ def test2(target: address, salt: bytes32): d.test2(f.address, salt, transact={}) test = FooContract(d.created_address()) - assert revm_env.get_code(test.address) == revm_env.get_code(foo_contract.address) + assert env.get_code(test.address) == env.get_code(foo_contract.address) assert test.foo() == 123 # check if the create2 address matches our offchain calculation - initcode = revm_env.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) @@ -200,7 +199,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, revm_env, keccak, create2_address_of, tx_failed + get_contract, deploy_blueprint_for, env, keccak, create2_address_of, tx_failed ): code = """ @external @@ -222,7 +221,7 @@ 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 = revm_env.get_code(foo_contract.address) + expected_runtime_code = env.get_code(foo_contract.address) f, FooContract = deploy_blueprint_for(code) @@ -231,7 +230,7 @@ def test2(target: address, salt: bytes32): d.test(f.address, transact={}) test = FooContract(d.created_address()) - assert revm_env.get_code(test.address) == expected_runtime_code + assert env.get_code(test.address) == expected_runtime_code assert test.foo() == 123 # extcodesize check @@ -244,11 +243,11 @@ def test2(target: address, salt: bytes32): d.test2(f.address, salt, transact={}) test = FooContract(d.created_address()) - assert revm_env.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 = revm_env.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) @@ -258,7 +257,7 @@ def test2(target: address, salt: bytes32): def test_create_from_blueprint_bad_code_offset( - get_contract, get_contract_from_ir, deploy_blueprint_for, revm_env, tx_failed + get_contract, get_contract_from_ir, deploy_blueprint_for, env, tx_failed ): deployer_code = """ BLUEPRINT: immutable(address) @@ -282,7 +281,7 @@ def test(code_ofst: uint256) -> address: compile_ir.compile_to_assembly(ir, optimize=OptimizationLevel.NONE) ) # manually deploy the bytecode - c = revm_env.deploy(abi=[], bytecode=bytecode) + c = env.deploy(abi=[], bytecode=bytecode) blueprint_address = c.address d = get_contract(deployer_code, blueprint_address) @@ -304,7 +303,7 @@ def test(code_ofst: uint256) -> address: # test create_from_blueprint with args def test_create_from_blueprint_args( - get_contract, deploy_blueprint_for, revm_env, keccak, create2_address_of, tx_failed + get_contract, deploy_blueprint_for, env, keccak, create2_address_of, tx_failed ): code = """ struct Bar: @@ -358,18 +357,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 = revm_env.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 = revm_env.get_code(f.address)[3:] + initcode = env.get_code(f.address)[3:] d.test(f.address, FOO, BAR, transact={}) test = FooContract(d.created_address()) - assert revm_env.get_code(test.address) == expected_runtime_code + assert env.get_code(test.address) == expected_runtime_code assert test.foo() == FOO assert test.bar() == BAR @@ -382,7 +381,7 @@ def should_fail(target: address, arg1: String[129], arg2: Bar): d.test2(f.address, FOO, BAR, salt, transact={}) test = FooContract(d.created_address()) - assert revm_env.get_code(test.address) == expected_runtime_code + assert env.get_code(test.address) == expected_runtime_code assert test.foo() == FOO assert test.bar() == BAR @@ -391,13 +390,13 @@ def should_fail(target: address, arg1: String[129], arg2: Bar): d.test3(f.address, encoded_args, transact={}) test = FooContract(d.created_address()) - assert revm_env.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={}) test = FooContract(d.created_address()) - assert revm_env.get_code(test.address) == expected_runtime_code + assert env.get_code(test.address) == expected_runtime_code assert test.foo() == FOO assert test.bar() == BAR @@ -421,10 +420,10 @@ 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(): - revm_env.execute_code(d.address, revm_env.deployer, HexBytes(f"{sig}{encoded}")) + env.execute_code(d.address, env.deployer, HexBytes(f"{sig}{encoded}")) -def test_create_copy_of(get_contract, revm_env, keccak, create2_address_of, tx_failed): +def test_create_copy_of(get_contract, env, keccak, create2_address_of, tx_failed): code = """ created_address: public(address) @internal @@ -451,11 +450,11 @@ def test2(target: address, salt: bytes32) -> address: """ c = get_contract(code) - bytecode = revm_env.get_code(c.address) + bytecode = env.get_code(c.address) c.test(c.address, transact={}) test1 = c.created_address() - assert revm_env.get_code(test1) == bytecode + assert env.get_code(test1) == bytecode # extcodesize check with tx_failed(): @@ -467,7 +466,7 @@ def test2(target: address, salt: bytes32) -> address: salt = keccak(b"vyper") c.test2(c.address, salt, transact={}) test2 = c.created_address() - assert revm_env.get_code(test2) == bytecode + assert env.get_code(test2) == bytecode assert HexBytes(test2) == create2_address_of(c.address, salt, vyper_initcode(bytecode)) @@ -488,7 +487,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, revm_env, blueprint_prefix + get_contract, deploy_blueprint_for, env, blueprint_prefix ): # check msize allocator does not get trampled by value= kwarg code = """ @@ -530,23 +529,23 @@ def test(target: address): """ foo_contract = get_contract(code, 12) - expected_runtime_code = revm_env.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) - revm_env.set_balance(revm_env.deployer, 3) + env.set_balance(env.deployer, 3) d.test(f.address, value=3) test = FooContract(d.created_address()) - assert revm_env.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, revm_env, blueprint_prefix + get_contract, deploy_blueprint_for, env, blueprint_prefix ): # test msize allocator does not get trampled by salt= kwarg code = """ @@ -589,7 +588,7 @@ def test(target: address): """ foo_contract = get_contract(code, 12) - expected_runtime_code = revm_env.get_code(foo_contract.address) + expected_runtime_code = env.get_code(foo_contract.address) f, FooContract = deploy_blueprint_for(code, initcode_prefix=blueprint_prefix) @@ -598,13 +597,13 @@ def test(target: address): d.test(f.address, transact={}) test = FooContract(d.created_address()) - assert revm_env.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, revm_env, blueprint_prefix + get_contract, deploy_blueprint_for, env, blueprint_prefix ): # test msize allocator does not get trampled by salt= kwarg code = """ @@ -637,7 +636,7 @@ def test(target: address): """ foo_contract = get_contract(code) - expected_runtime_code = revm_env.get_code(foo_contract.address) + expected_runtime_code = env.get_code(foo_contract.address) f, FooContract = deploy_blueprint_for(code, initcode_prefix=blueprint_prefix) @@ -646,11 +645,11 @@ def test(target: address): d.test(f.address, transact={}) test = FooContract(d.created_address()) - assert revm_env.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, revm_env): +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) @@ -666,10 +665,10 @@ def test(target: address) -> address: """ c = get_contract(complex_salt) - bytecode = revm_env.get_code(c.address) + bytecode = env.get_code(c.address) c.test(c.address, transact={}) test1 = c.address - assert bytecode and revm_env.get_code(test1) == bytecode + assert bytecode and env.get_code(test1) == bytecode # test msize allocator does not get trampled by value= kwarg complex_value = """ @@ -685,9 +684,9 @@ def test(target: address) -> address: """ c = get_contract(complex_value) - bytecode = revm_env.get_code(c.address) - revm_env.set_balance(revm_env.deployer, 2) + bytecode = env.get_code(c.address) + env.set_balance(env.deployer, 2) c.test(c.address, value=2) test1 = c.address - assert revm_env.get_code(test1) == bytecode + assert env.get_code(test1) == bytecode diff --git a/tests/functional/builtins/codegen/test_is_contract.py b/tests/functional/builtins/codegen/test_is_contract.py index d35053a8d4..47a5709a84 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(revm_env, get_contract_with_gas_estimation): +def test_is_contract(env, get_contract_with_gas_estimation): contract_1 = """ @external def foo(arg1: address) -> bool: @@ -11,7 +11,7 @@ def foo(arg1: address) -> bool: def foo(arg1: address) -> bool: return arg1.is_contract """ - a0, a1 = revm_env.accounts[:2] + a0, a1 = env.accounts[:2] c1 = get_contract_with_gas_estimation(contract_1) c2 = get_contract_with_gas_estimation(contract_2) diff --git a/tests/functional/builtins/codegen/test_raw_call.py b/tests/functional/builtins/codegen/test_raw_call.py index 6afd0306ff..c3f8cd161f 100644 --- a/tests/functional/builtins/codegen/test_raw_call.py +++ b/tests/functional/builtins/codegen/test_raw_call.py @@ -50,7 +50,7 @@ def foo() -> Bytes[5]: assert c.foo() == b"moose" -def test_multiple_levels(revm_env, get_contract_with_gas_estimation): +def test_multiple_levels(env, get_contract_with_gas_estimation): inner_code = """ @external def returnten() -> int128: @@ -81,7 +81,7 @@ def create_and_return_proxy(inp: address) -> address: c3 = c2.create_and_return_proxy(c.address) c2.create_and_return_proxy(c.address, transact={}) - c3_contract_code = revm_env.get_code(c3) + c3_contract_code = env.get_code(c3) assert c3_contract_code[:10] == HexBytes(preamble) assert c3_contract_code[-15:] == HexBytes(callcode) @@ -120,7 +120,7 @@ def create_and_return_proxy(inp: address) -> address: print("Passed minimal proxy exception test") -def test_delegate_call(revm_env, get_contract): +def test_delegate_call(env, get_contract): inner_code = """ a: address # this is required for storage alignment... owners: public(address[5]) @@ -155,7 +155,7 @@ def set(i: int128, owner: address): ) """ - a0, a1, a2 = revm_env.accounts[:3] + a0, a1, a2 = env.accounts[:3] outer_contract = get_contract(outer_code, inner_contract.address) # Test setting on inners contract's state setting works. @@ -171,7 +171,7 @@ def set(i: int128, owner: address): assert outer_contract.owners(1) == a1 -def test_gas(get_contract, tx_failed, revm_env): +def test_gas(get_contract, tx_failed, env): inner_code = """ bar: bytes32 @@ -233,7 +233,7 @@ def foo(_addr: address) -> int128: assert caller.foo(target.address) == 42 -def test_forward_calldata(get_contract, revm_env, keccak): +def test_forward_calldata(get_contract, env, keccak): target_source = """ @external def foo() -> uint256: @@ -259,7 +259,7 @@ def __default__(): # manually construct msg.data for `caller` contract sig = keccak("foo()".encode()).hex()[:10] - assert revm_env.execute_code(caller.address, data=sig) == b"" + assert env.execute_code(caller.address, data=sig) == b"" # check max_outsize=0 does same thing as not setting max_outsize. @@ -516,7 +516,7 @@ def foo() -> String[32]: assert c.foo() == "goo" -def test_raw_call_clean_mem_kwargs_value(get_contract, revm_env): +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 = """ @@ -543,7 +543,7 @@ def bar(f: uint256) -> Bytes[100]: ) return self.buf """ - revm_env.set_balance(revm_env.deployer, 1) + env.set_balance(env.deployer, 1) c = get_contract(code, value=1) assert ( @@ -552,7 +552,7 @@ def bar(f: uint256) -> Bytes[100]: ) -def test_raw_call_clean_mem_kwargs_gas(get_contract, revm_env): +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,7 +579,7 @@ def bar(f: uint256) -> Bytes[100]: ) return self.buf """ - revm_env.set_balance(revm_env.deployer, 1) + env.set_balance(env.deployer, 1) c = get_contract(code, value=1) assert ( diff --git a/tests/functional/builtins/codegen/test_send.py b/tests/functional/builtins/codegen/test_send.py index a3f203b321..a16dcd0068 100644 --- a/tests/functional/builtins/codegen/test_send.py +++ b/tests/functional/builtins/codegen/test_send.py @@ -1,4 +1,4 @@ -def test_send(tx_failed, get_contract, revm_env): +def test_send(tx_failed, get_contract, env): send_test = """ @external def foo(): @@ -8,7 +8,7 @@ def foo(): def fop(): send(msg.sender, 10) """ - revm_env.set_balance(revm_env.deployer, 1000) + env.set_balance(env.deployer, 1000) c = get_contract(send_test, value=10) with tx_failed(): c.foo(transact={}) @@ -17,7 +17,7 @@ def fop(): c.fop(transact={}) -def test_default_gas(get_contract, revm_env, tx_failed): +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. @@ -43,7 +43,7 @@ def __default__(): self.last_sender = msg.sender """ - revm_env.set_balance(revm_env.deployer, 100000 * 3) + env.set_balance(env.deployer, 100000 * 3) sender = get_contract(sender_code, value=1) receiver = get_contract(receiver_code) @@ -52,18 +52,18 @@ def __default__(): # no value transfer happened, variable was not changed assert receiver.last_sender() is None - assert revm_env.get_balance(sender.address) == 1 - assert revm_env.get_balance(receiver.address) == 0 + assert env.get_balance(sender.address) == 1 + assert env.get_balance(receiver.address) == 0 sender.test_call(receiver.address, transact={"gas": 100000}) # value transfer happened, variable was changed assert receiver.last_sender() == sender.address - assert revm_env.get_balance(sender.address) == 0 - assert revm_env.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, revm_env): +def test_send_gas_stipend(get_contract, env): """ Tests to verify that adding gas stipend to send() will send sufficient gas """ @@ -86,7 +86,7 @@ def __default__(): self.last_sender = msg.sender """ - revm_env.set_balance(revm_env.deployer, 100000 * 3) + env.set_balance(env.deployer, 100000 * 3) sender = get_contract(sender_code, value=1) receiver = get_contract(receiver_code) @@ -94,5 +94,5 @@ def __default__(): # value transfer happened, variable was changed assert receiver.last_sender() == sender.address - assert revm_env.get_balance(sender.address) == 0 - assert revm_env.get_balance(receiver.address) == 1 + assert env.get_balance(sender.address) == 0 + assert env.get_balance(receiver.address) == 1 diff --git a/tests/functional/codegen/calling_convention/test_default_function.py b/tests/functional/codegen/calling_convention/test_default_function.py index 0fd4a3510d..d7589c3047 100644 --- a/tests/functional/codegen/calling_convention/test_default_function.py +++ b/tests/functional/codegen/calling_convention/test_default_function.py @@ -1,7 +1,7 @@ from eth_utils import to_wei -def test_throw_on_sending(revm_env, tx_failed, get_contract_with_gas_estimation): +def test_throw_on_sending(env, tx_failed, get_contract_with_gas_estimation): code = """ x: public(int128) @@ -12,13 +12,13 @@ def __init__(): c = get_contract_with_gas_estimation(code) assert c.x() == 123 - assert revm_env.get_balance(c.address) == 0 + assert env.get_balance(c.address) == 0 with tx_failed(): - revm_env.execute_code(c.address, value=to_wei(0.1, "ether")) - assert revm_env.get_balance(c.address) == 0 + env.execute_code(c.address, value=to_wei(0.1, "ether")) + assert env.get_balance(c.address) == 0 -def test_basic_default(revm_env, get_logs, get_contract_with_gas_estimation): +def test_basic_default(env, get_logs, get_contract_with_gas_estimation): code = """ event Sent: sender: indexed(address) @@ -29,13 +29,13 @@ def __default__(): log Sent(msg.sender) """ c = get_contract_with_gas_estimation(code) - revm_env.set_balance(revm_env.deployer, 10**18) - (log,) = get_logs(revm_env.execute_code(c.address, value=10**17), c, "Sent") - assert revm_env.deployer == log.args.sender - assert revm_env.get_balance(c.address) == to_wei(0.1, "ether") + env.set_balance(env.deployer, 10**18) + (log,) = get_logs(env.execute_code(c.address, value=10**17), 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(revm_env, get_logs, get_contract_with_gas_estimation): +def test_basic_default_default_param_function(env, get_logs, get_contract_with_gas_estimation): code = """ event Sent: sender: indexed(address) @@ -53,12 +53,12 @@ def __default__(): """ c = get_contract_with_gas_estimation(code) - (log,) = get_logs(revm_env.execute_code(c.address, value=10**17), c, "Sent") - assert revm_env.deployer == log.args.sender - assert revm_env.get_balance(c.address) == to_wei(0.1, "ether") + (log,) = get_logs(env.execute_code(c.address, value=10**17), 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(revm_env, tx_failed, get_contract_with_gas_estimation): +def test_basic_default_not_payable(env, tx_failed, get_contract_with_gas_estimation): code = """ event Sent: sender: indexed(address) @@ -70,7 +70,7 @@ def __default__(): c = get_contract_with_gas_estimation(code) with tx_failed(): - revm_env.execute_code(c.address, value=10**17) + env.execute_code(c.address, value=10**17) def test_multi_arg_default(assert_compile_failed, get_contract_with_gas_estimation): @@ -103,7 +103,7 @@ def __default__(): assert_compile_failed(lambda: get_contract_with_gas_estimation(code)) -def test_zero_method_id(revm_env, 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 = """ @@ -128,7 +128,7 @@ def __default__(): def _call_with_bytes(hexstr): # call our special contract and return the logged value data = bytes.fromhex(hexstr.removeprefix("0x")) - result = revm_env.execute_code(c.address, value=0, data=data) + result = env.execute_code(c.address, value=0, data=data) (log,) = get_logs(result, c, "Sent") return log.args.sig @@ -150,7 +150,7 @@ def _call_with_bytes(hexstr): _call_with_bytes(f"0x{'00' * i}") -def test_another_zero_method_id(revm_env, 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: @@ -174,7 +174,7 @@ def __default__(): def _call_with_bytes(hexstr): # call our special contract and return the logged value data = bytes.fromhex(hexstr.removeprefix("0x")) - result = revm_env.execute_code(c.address, value=0, data=data, gas=10**6) + result = env.execute_code(c.address, value=0, data=data, gas=10**6) (log,) = get_logs(result, c, "Sent") return log.args.sig @@ -191,7 +191,7 @@ def _call_with_bytes(hexstr): assert 1 == _call_with_bytes("0x" + "00" * i) -def test_partial_selector_match_trailing_zeroes(revm_env, get_logs, get_contract): +def test_partial_selector_match_trailing_zeroes(env, get_logs, get_contract): code = """ event Sent: sig: uint256 @@ -215,7 +215,7 @@ def __default__(): def _call_with_bytes(hexstr): # call our special contract and return the logged value data = bytes.fromhex(hexstr.removeprefix("0x")) - result = revm_env.execute_code(c.address, value=0, data=data) + result = env.execute_code(c.address, value=0, data=data) (log,) = get_logs(result, c, "Sent") return log.args.sig diff --git a/tests/functional/codegen/calling_convention/test_default_parameters.py b/tests/functional/codegen/calling_convention/test_default_parameters.py index c9aaa5368d..05aeab7bd4 100644 --- a/tests/functional/codegen/calling_convention/test_default_parameters.py +++ b/tests/functional/codegen/calling_convention/test_default_parameters.py @@ -231,7 +231,7 @@ def callMeMaybe() -> (Bytes[100], uint256, Bytes[20]): assert c.callMeMaybe() == (b"here is my number", 555123456, b"baby") -def test_environment_vars_as_default(get_contract, revm_env): +def test_environment_vars_as_default(get_contract, env): code = """ xx: uint256 @@ -250,13 +250,13 @@ def get_balance() -> uint256: return self.balance """ c = get_contract(code) - revm_env.set_balance(revm_env.deployer, 31337 + 9001) + env.set_balance(env.deployer, 31337 + 9001) c.foo(transact={"value": 31337}) assert c.bar() == 31337 c.foo(666, transact={"value": 9001}) assert c.bar() == 31337 + 666 assert c.get_balance() == 31337 + 9001 - assert revm_env.get_balance(revm_env.deployer) == 0 + 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 8cd5b5926f..381a9d88e0 100644 --- a/tests/functional/codegen/calling_convention/test_erc20_abi.py +++ b/tests/functional/codegen/calling_convention/test_erc20_abi.py @@ -72,47 +72,47 @@ def allowance(_owner: address, _spender: address) -> uint256: return get_contract(erc20_caller_code, *[erc20.address]) -def test_initial_state(revm_env, erc20_caller): +def test_initial_state(env, erc20_caller): assert erc20_caller.totalSupply() == TOKEN_TOTAL_SUPPLY - assert erc20_caller.balanceOf(revm_env.deployer) == TOKEN_TOTAL_SUPPLY - assert erc20_caller.balanceOf(revm_env.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(revm_env, erc20, erc20_caller, tx_failed): +def test_call_transfer(env, erc20, erc20_caller, tx_failed): # Basic transfer. erc20.transfer(erc20_caller.address, 10, transact={}) assert erc20.balanceOf(erc20_caller.address) == 10 - erc20_caller.transfer(revm_env.accounts[1], 10, transact={}) + erc20_caller.transfer(env.accounts[1], 10, transact={}) assert erc20.balanceOf(erc20_caller.address) == 0 - assert erc20.balanceOf(revm_env.accounts[1]) == 10 + assert erc20.balanceOf(env.accounts[1]) == 10 # more than allowed with tx_failed(): - erc20_caller.transfer(revm_env.accounts[1], TOKEN_TOTAL_SUPPLY) + erc20_caller.transfer(env.accounts[1], TOKEN_TOTAL_SUPPLY) # Negative transfer value. with tx_failed(EncodeError): - erc20_caller.transfer(revm_env.accounts[1], -1) + erc20_caller.transfer(env.accounts[1], -1) -def test_caller_approve_allowance(revm_env, 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(revm_env.deployer, erc20_caller.address) == 10 + assert erc20_caller.allowance(env.deployer, erc20_caller.address) == 10 -def test_caller_tranfer_from(revm_env, 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(revm_env.deployer, 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(revm_env.deployer, erc20_caller.address, 5, transact={}) + erc20_caller.transferFrom(env.deployer, erc20_caller.address, 5, transact={}) assert erc20.balanceOf(erc20_caller.address) == 5 - assert erc20_caller.allowance(revm_env.deployer, erc20_caller.address) == 5 - erc20_caller.transferFrom(revm_env.deployer, erc20_caller.address, 3, transact={}) + assert erc20_caller.allowance(env.deployer, erc20_caller.address) == 5 + erc20_caller.transferFrom(env.deployer, erc20_caller.address, 3, transact={}) assert erc20.balanceOf(erc20_caller.address) == 8 - assert erc20_caller.allowance(revm_env.deployer, 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 f3ced6aaf4..b31638e265 100644 --- a/tests/functional/codegen/calling_convention/test_external_contract_calls.py +++ b/tests/functional/codegen/calling_convention/test_external_contract_calls.py @@ -1119,7 +1119,7 @@ def _expr(x: address) -> int128: assert c2._expr(c2.address) == 1 -def test_invalid_nonexistent_contract_call(revm_env, tx_failed, get_contract): +def test_invalid_nonexistent_contract_call(env, tx_failed, get_contract): contract_1 = """ @external def bar() -> int128: @@ -1140,9 +1140,9 @@ def foo(x: address) -> int128: assert c2.foo(c1.address) == 1 with tx_failed(): - c2.foo(revm_env.deployer) + c2.foo(env.deployer) with tx_failed(): - c2.foo(revm_env.accounts[3]) + c2.foo(env.accounts[3]) def test_invalid_contract_reference_declaration(tx_failed, get_contract): @@ -1351,7 +1351,7 @@ def foo(contract_address: address) -> int128: get_contract(contract_1) -def test_external_with_payable_value(revm_env, get_contract_with_gas_estimation): +def test_external_with_payable_value(env, get_contract_with_gas_estimation): contract_1 = """ @payable @external @@ -1392,26 +1392,26 @@ def get_lucky(amount_to_send: uint256) -> int128: c2.set_contract(c1.address, transact={}) # Send some eth - revm_env.set_balance(revm_env.deployer, 10000) - with revm_env.anchor(): + env.set_balance(env.deployer, 10000) + with env.anchor(): assert c2.get_lucky(0, transact={"value": 500}) == 1 c2.get_lucky(0, transact={"value": 500}) # Contract 1 received money. assert c1.get_balance() == 500 - assert revm_env.get_balance(c1.address) == 500 - assert revm_env.get_balance(c2.address) == 0 + assert env.get_balance(c1.address) == 500 + assert env.get_balance(c2.address) == 0 # Send subset of amount - with revm_env.anchor(): + with env.anchor(): assert c2.get_lucky(250, transact={"value": 500}) == 1 c2.get_lucky(250, transact={"value": 500}) # Contract 1 received more money. assert c1.get_balance() == 750 - assert revm_env.get_balance(c1.address) == 750 - assert revm_env.get_balance(c2.address) == 250 - assert revm_env.get_balance(revm_env.deployer) == 9000 + 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): @@ -2500,7 +2500,7 @@ def do_stuff(f: Foo) -> uint256: @pytest.mark.parametrize("typ,val", [("address", TEST_ADDR)]) -def test_calldata_clamp(revm_env, get_contract, tx_failed, keccak, typ, val): +def test_calldata_clamp(env, get_contract, tx_failed, keccak, typ, val): code = f""" @external def foo(a: {typ}): @@ -2514,17 +2514,17 @@ def foo(a: {typ}): # Static size is short by 1 byte malformed = data[:-2] with tx_failed(): - revm_env.execute_code(c1.address, data=malformed) + env.execute_code(c1.address, data=malformed) # Static size is exact - revm_env.execute_code(c1.address, data=data) + env.execute_code(c1.address, data=data) # Static size exceeds by 1 byte, ok - revm_env.execute_code(c1.address, data=data + "ff") + env.execute_code(c1.address, data=data + "ff") @pytest.mark.parametrize("typ,val", [("address", ([TEST_ADDR] * 3, "vyper"))]) -def test_dynamic_calldata_clamp(revm_env, get_contract, tx_failed, keccak, typ, val): +def test_dynamic_calldata_clamp(env, get_contract, tx_failed, keccak, typ, val): code = f""" @external def foo(a: DynArray[{typ}, 3], b: String[5]): @@ -2539,8 +2539,8 @@ def foo(a: DynArray[{typ}, 3], b: String[5]): # Dynamic size is short by 1 byte malformed = data[:264] with tx_failed(): - revm_env.execute_code(c1.address, data=malformed) + env.execute_code(c1.address, data=malformed) # Dynamic size is at least minimum (132 bytes * 2 + 2 (for 0x) = 266) valid = data[:266] - revm_env.execute_code(c1.address, data=valid) + env.execute_code(c1.address, data=valid) diff --git a/tests/functional/codegen/calling_convention/test_return.py b/tests/functional/codegen/calling_convention/test_return.py index cd5d40798f..f7f7515388 100644 --- a/tests/functional/codegen/calling_convention/test_return.py +++ b/tests/functional/codegen/calling_convention/test_return.py @@ -6,7 +6,7 @@ pytestmark = pytest.mark.usefixtures("memory_mocker") -def test_correct_abi_right_padding(revm_env, get_contract_with_gas_estimation): +def test_correct_abi_right_padding(env, get_contract_with_gas_estimation): selfcall_code_6 = """ @external def hardtest(arg1: Bytes[64], arg2: Bytes[64]) -> Bytes[128]: @@ -18,7 +18,7 @@ def hardtest(arg1: Bytes[64], arg2: Bytes[64]) -> Bytes[128]: assert c.hardtest(b"hello" * 5, b"hello" * 10) == b"hello" * 15 # Make sure underlying struct is correctly right padded - res = revm_env.execute_code( + res = env.execute_code( to=c.address, data=c.hardtest.prepare_calldata(b"hello" * 5, b"hello" * 10) ) static_offset = int.from_bytes(res[:32], "big") 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 b7dda7a823..a479665b59 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 decimal import Decimal -def test_call_to_self_struct(revm_env, 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("0.1")) == ( Decimal("0.1"), - revm_env.get_block().timestamp, + env.get_block().timestamp, ) assert c.wrap_get_my_struct_BROKEN(Decimal("0.1")) == ( Decimal("0.1"), - revm_env.get_block().timestamp, + env.get_block().timestamp, ) diff --git a/tests/functional/codegen/environment_variables/test_block_number.py b/tests/functional/codegen/environment_variables/test_block_number.py index 8ed72043c4..f91da1889a 100644 --- a/tests/functional/codegen/environment_variables/test_block_number.py +++ b/tests/functional/codegen/environment_variables/test_block_number.py @@ -1,7 +1,4 @@ -from pyrevm import EVM, BlockEnv, Env - - -def test_block_number(get_contract_with_gas_estimation, revm_env, optimize, output_formats): +def test_block_number(get_contract_with_gas_estimation, env, optimize, output_formats): block_number_code = """ @external def block_number() -> uint256: @@ -10,6 +7,6 @@ def block_number() -> uint256: c = get_contract_with_gas_estimation(block_number_code) assert c.block_number() == 1 - revm_env.evm = EVM(env=Env(block=BlockEnv(number=2))) - c = revm_env.deploy_source(block_number_code, optimize, output_formats) + env.mine() + c = env.deploy_source(block_number_code, optimize, output_formats) 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 a57ec46c15..6a6bb2358d 100644 --- a/tests/functional/codegen/environment_variables/test_blockhash.py +++ b/tests/functional/codegen/environment_variables/test_blockhash.py @@ -21,8 +21,8 @@ def foo() -> bytes32: assert_compile_failed(lambda: get_contract_with_gas_estimation(code)) -def test_too_old_blockhash(tx_failed, get_contract_with_gas_estimation, revm_env): - revm_env.mine(257) +def test_too_old_blockhash(tx_failed, get_contract_with_gas_estimation, env): + env.mine(257) code = """ @external def get_50_blockhash() -> bytes32: diff --git a/tests/functional/codegen/environment_variables/test_tx.py b/tests/functional/codegen/environment_variables/test_tx.py index 0170cb83c3..d9a23e69cb 100644 --- a/tests/functional/codegen/environment_variables/test_tx.py +++ b/tests/functional/codegen/environment_variables/test_tx.py @@ -1,10 +1,10 @@ -def test_tx_gasprice(get_contract, revm_env): +def test_tx_gasprice(get_contract, env): code = """ @external def tx_gasprice() -> uint256: return tx.gasprice """ - revm_env.set_balance(revm_env.deployer, 10**20) + 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 diff --git a/tests/functional/codegen/features/decorators/test_nonreentrant.py b/tests/functional/codegen/features/decorators/test_nonreentrant.py index 4b290e6119..4e3c0402da 100644 --- a/tests/functional/codegen/features/decorators/test_nonreentrant.py +++ b/tests/functional/codegen/features/decorators/test_nonreentrant.py @@ -193,7 +193,7 @@ def __default__(): contract.protected_function3("zzz value", True, transact={}) -def test_nonreentrant_decorator_for_default(revm_env, get_contract, tx_failed): +def test_nonreentrant_decorator_for_default(env, get_contract, tx_failed): calling_contract_code = """ @external def send_funds(_amount: uint256): @@ -262,20 +262,20 @@ def __default__(): # Test unprotected function without callback. reentrant_contract.unprotected_function("some value", False, transact={"value": 1000}) assert reentrant_contract.special_value() == "some value" - assert revm_env.get_balance(reentrant_contract.address) == 0 - assert revm_env.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}) assert reentrant_contract.special_value() == "another value" - assert revm_env.get_balance(reentrant_contract.address) == 1000 - assert revm_env.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}) assert reentrant_contract.special_value() == "surprise!" - assert revm_env.get_balance(reentrant_contract.address) == 1000 - assert revm_env.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(): diff --git a/tests/functional/codegen/features/decorators/test_payable.py b/tests/functional/codegen/features/decorators/test_payable.py index 696c1d02e2..c70fba15e9 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(revm_env, 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}) sig = keccak("foo()".encode()).hex()[:10] with tx_failed(): - revm_env.execute_code(c.address, data=sig, value=10**18) + env.execute_code(c.address, data=sig, value=10**18) payable_code = [ @@ -341,7 +341,7 @@ def test_payable_runtime_assertion(get_contract, code): c.foo(transact={"value": 0}) -def test_payable_default_func_invalid_calldata(get_contract, revm_env): +def test_payable_default_func_invalid_calldata(get_contract, env): code = """ @external def foo() -> bool: @@ -354,10 +354,10 @@ def __default__(): """ c = get_contract(code) - revm_env.execute_code(c.address, value=100, data="0x12345678") + env.execute_code(c.address, value=100, data="0x12345678") -def test_nonpayable_default_func_invalid_calldata(get_contract, revm_env, 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) - revm_env.execute_code(c.address, value=0, data="0x12345678") + env.execute_code(c.address, value=0, data="0x12345678") with tx_failed(): - revm_env.execute_code(c.address, value=100, data="0x12345678") + env.execute_code(c.address, value=100, data="0x12345678") -def test_batch_nonpayable(get_contract, revm_env, 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) - revm_env.execute_code(c.address, value=0, data="0x12345678") + env.execute_code(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(): - revm_env.execute_code(c.address, value=100, data=calldata) + env.execute_code(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 59d49322c2..e612d1f3c5 100644 --- a/tests/functional/codegen/features/decorators/test_private.py +++ b/tests/functional/codegen/features/decorators/test_private.py @@ -1,5 +1,5 @@ import pytest -from eth_utils import to_checksum_address, to_wei +from eth_utils import to_wei def test_private_test(get_contract_with_gas_estimation): @@ -390,7 +390,7 @@ def test() -> int128[4]: assert c.test() == [0, 1, 0, 1] -def test_private_payable(revm_env, get_contract_with_gas_estimation): +def test_private_payable(env, get_contract_with_gas_estimation): code = """ @internal def _send_it(a: address, _value: uint256): @@ -409,16 +409,16 @@ def __default__(): c = get_contract_with_gas_estimation(code) - revm_env.execute_code(c.address, value=to_wei(1, "ether")) - assert revm_env.get_balance(c.address) == to_wei(1, "ether") - a3 = revm_env.accounts[2] - revm_env.set_balance(a3, to_wei(1000000, "ether")) + env.execute_code(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"), transact={}) - assert revm_env.get_balance(a3) == to_wei(1000000.05, "ether") - assert revm_env.get_balance(c.address) == to_wei(0.95, "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, revm_env): +def test_private_msg_sender(get_contract, env, get_logs): code = """ event Addr: addr: address @@ -443,11 +443,10 @@ def whoami() -> address: c = get_contract(code) assert c.i_am_me() - addr = revm_env.accounts[1] - c.whoami(transact={"from": addr}) - (log,) = revm_env.evm.result.logs - _, data = log.data - assert to_checksum_address(data[-20:]) == addr, "oh no" + addr = env.accounts[1] + result = c.whoami(transact={"from": addr}) + (log,) = get_logs(result, c) + assert log.args.addr == addr def test_nested_static_params_only(get_contract, tx_failed): diff --git a/tests/functional/codegen/features/iteration/test_range_in.py b/tests/functional/codegen/features/iteration/test_range_in.py index adee33b657..564b14d524 100644 --- a/tests/functional/codegen/features/iteration/test_range_in.py +++ b/tests/functional/codegen/features/iteration/test_range_in.py @@ -110,7 +110,7 @@ def testin() -> bool: assert_compile_failed(lambda: get_contract_with_gas_estimation(code), TypeMismatch) -def test_ownership(revm_env, tx_failed, get_contract_with_gas_estimation): +def test_ownership(env, tx_failed, get_contract_with_gas_estimation): code = """ owners: address[2] @@ -128,7 +128,7 @@ def set_owner(i: int128, new_owner: address): def is_owner() -> bool: return msg.sender in self.owners """ - a1 = revm_env.accounts[1] + a1 = env.accounts[1] c = get_contract_with_gas_estimation(code) assert c.is_owner() is True # contract creator is owner. diff --git a/tests/functional/codegen/features/test_address_balance.py b/tests/functional/codegen/features/test_address_balance.py index a016d48c70..50d55abbf4 100644 --- a/tests/functional/codegen/features/test_address_balance.py +++ b/tests/functional/codegen/features/test_address_balance.py @@ -6,7 +6,7 @@ def initial_balance(): return 10**5 -def test_constant_address_balance(revm_env, get_contract_with_gas_estimation): +def test_constant_address_balance(env, get_contract_with_gas_estimation): code = """ a: constant(address) = 0x776Ba14735FF84789320718cf0aa43e91F7A8Ce1 @@ -21,6 +21,6 @@ def foo() -> uint256: assert c.foo() == 0 - revm_env.execute_code(address, value=1337) + env.execute_code(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 cbebe54fc9..939fdc5c75 100644 --- a/tests/functional/codegen/features/test_assert.py +++ b/tests/functional/codegen/features/test_assert.py @@ -8,24 +8,23 @@ def _fixup_err_str(s): return s.replace("execution reverted: ", "") -def test_assert_refund(revm_env, get_contract_with_gas_estimation, tx_failed): +def test_assert_refund(env, get_contract_with_gas_estimation, tx_failed): code = """ @external def foo(): raise """ c = get_contract_with_gas_estimation(code) - revm_env.set_balance(revm_env.deployer, 10**7) + env.set_balance(env.deployer, 10**7) gas_sent = 10**6 with tx_failed(): c.foo(transact={"gas": gas_sent, "gasPrice": 10}) - result = revm_env.evm.result - assert result.gas_used < gas_sent, "Gas refund not received" - assert not result.is_success and not result.is_halt + assert env.last_result["gas_used"] < gas_sent, "Gas refund not received" + assert not env.last_result["is_success"] and not env.last_result["is_halt"] -def test_assert_reason(revm_env, get_contract_with_gas_estimation, tx_failed, memory_mocker): +def test_assert_reason(env, get_contract_with_gas_estimation, tx_failed, memory_mocker): code = """ err: String[32] @@ -145,7 +144,7 @@ def test_valid_assertions(get_contract, code): get_contract(code) -def test_assert_staticcall(get_contract, revm_env, tx_failed, memory_mocker): +def test_assert_staticcall(get_contract, env, tx_failed, memory_mocker): foreign_code = """ state: uint256 @external @@ -209,7 +208,7 @@ def test(x: uint256[3]) -> bool: c.test([1, 3, 5]) -def test_assert_reason_revert_length(revm_env, 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 33afcb9ee6..e3ec4946b4 100644 --- a/tests/functional/codegen/features/test_assert_unreachable.py +++ b/tests/functional/codegen/features/test_assert_unreachable.py @@ -6,7 +6,7 @@ def initial_balance(): return 10**20 -def test_unreachable_refund(revm_env, get_contract, tx_failed): +def test_unreachable_refund(env, get_contract, tx_failed): code = """ @external def foo(): @@ -14,17 +14,15 @@ def foo(): """ c = get_contract(code) - a0 = revm_env.deployer gas_sent = 10**6 with tx_failed(): - c.foo(transact={"from": a0, "gas": gas_sent, "gasPrice": 10}) + c.foo(transact={"gas": gas_sent, "gasPrice": 10}) - result = revm_env.evm.result - assert result.gas_used == gas_sent # Drains all gains sent - assert not result.is_success and result.is_halt + assert env.last_result["gas_used"] == gas_sent # Drains all gains sent + assert not env.last_result["is_success"] and env.last_result["is_halt"] -def test_basic_unreachable(revm_env, get_contract, tx_failed): +def test_basic_unreachable(env, get_contract, tx_failed): code = """ @external def foo(val: int128) -> bool: @@ -45,7 +43,7 @@ def foo(val: int128) -> bool: c.foo(-2) -def test_basic_call_unreachable(revm_env, get_contract, tx_failed): +def test_basic_call_unreachable(env, get_contract, tx_failed): code = """ @view @@ -69,7 +67,7 @@ def foo(val: int128) -> int128: c.foo(-1) -def test_raise_unreachable(revm_env, get_contract, tx_failed): +def test_raise_unreachable(env, get_contract, tx_failed): code = """ @external def foo(): diff --git a/tests/functional/codegen/features/test_bytes_map_keys.py b/tests/functional/codegen/features/test_bytes_map_keys.py index b9a308694c..aa6fa22bac 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(revm_env, get_contract): +def test_basic_bytes_keys(env, get_contract): code = """ mapped_bytes: HashMap[Bytes[5], int128] diff --git a/tests/functional/codegen/features/test_clampers.py b/tests/functional/codegen/features/test_clampers.py index a12a19b453..7fbc0186db 100644 --- a/tests/functional/codegen/features/test_clampers.py +++ b/tests/functional/codegen/features/test_clampers.py @@ -84,7 +84,7 @@ def get_foo() -> Bytes[3]: @pytest.mark.parametrize("n", list(range(1, 33))) -def test_bytes_m_clamper_passing(revm_env, 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""" @@ -100,7 +100,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(revm_env, 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 @@ -121,11 +121,11 @@ def foo(s: bytes{n}) -> bytes{n}: # munge for `_make_tx` with tx_failed(): int_value = int.from_bytes(v, byteorder="big") - _make_tx(revm_env, 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(revm_env, 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] @@ -141,7 +141,7 @@ def foo(s: int{bits}) -> int{bits}: @pytest.mark.parametrize("n", list(range(31))) # int256 does not clamp -def test_sint_clamper_failing(revm_env, 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] @@ -154,11 +154,11 @@ def foo(s: int{bits}) -> int{bits}: c = get_contract(code) for v in values: with tx_failed(): - _make_tx(revm_env, 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(revm_env, get_contract, value): +def test_bool_clamper_passing(env, get_contract, value): code = """ @external def foo(s: bool) -> bool: @@ -170,7 +170,7 @@ def foo(s: bool) -> bool: @pytest.mark.parametrize("value", [2, 3, 4, 8, 16, 2**256 - 1]) -def test_bool_clamper_failing(revm_env, tx_failed, get_contract, value): +def test_bool_clamper_failing(env, tx_failed, get_contract, value): code = """ @external def foo(s: bool) -> bool: @@ -179,11 +179,11 @@ def foo(s: bool) -> bool: c = get_contract(code) with tx_failed(): - _make_tx(revm_env, 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(revm_env, get_contract, value): +def test_flag_clamper_passing(env, get_contract, value): code = """ flag Roles: USER @@ -202,7 +202,7 @@ def foo(s: Roles) -> Roles: @pytest.mark.parametrize("value", [2**i for i in range(5, 256)]) -def test_flag_clamper_failing(revm_env, tx_failed, get_contract, value): +def test_flag_clamper_failing(env, tx_failed, get_contract, value): code = """ flag Roles: USER @@ -218,11 +218,11 @@ def foo(s: Roles) -> Roles: c = get_contract(code) with tx_failed(): - _make_tx(revm_env, 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(revm_env, get_contract, n): +def test_uint_clamper_passing(env, get_contract, n): bits = 8 * (n + 1) values = [0, 1, 2**bits - 1] code = f""" @@ -237,7 +237,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(revm_env, 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""" @@ -248,7 +248,7 @@ def foo(s: uint{bits}) -> uint{bits}: c = get_contract(code) for v in values: with tx_failed(): - _make_tx(revm_env, c.address, f"foo(uint{bits})", [v]) + _make_tx(env, c.address, f"foo(uint{bits})", [v]) @pytest.mark.parametrize( @@ -265,7 +265,7 @@ def foo(s: uint{bits}) -> uint{bits}: ), ], ) -def test_address_clamper_passing(revm_env, get_contract, value, expected): +def test_address_clamper_passing(env, get_contract, value, expected): code = """ @external def foo(s: address) -> address: @@ -277,7 +277,7 @@ def foo(s: address) -> address: @pytest.mark.parametrize("value", [2**160, 2**256 - 1]) -def test_address_clamper_failing(revm_env, tx_failed, get_contract, value): +def test_address_clamper_failing(env, tx_failed, get_contract, value): code = """ @external def foo(s: address) -> address: @@ -286,7 +286,7 @@ def foo(s: address) -> address: c = get_contract(code) with tx_failed(): - _make_tx(revm_env, c.address, "foo(address)", [value]) + _make_tx(env, c.address, "foo(address)", [value]) @pytest.mark.parametrize( @@ -329,7 +329,7 @@ def foo(s: decimal) -> decimal: -187072209578355573530071658587684226515959365500929, # - (2 ** 127 - 1e-10) ], ) -def test_decimal_clamper_failing(revm_env, tx_failed, get_contract, value): +def test_decimal_clamper_failing(env, tx_failed, get_contract, value): code = """ @external def foo(s: decimal) -> decimal: @@ -339,11 +339,11 @@ def foo(s: decimal) -> decimal: c = get_contract(code) with tx_failed(): - _make_tx(revm_env, c.address, "foo(fixed168x10)", [value]) + _make_tx(env, c.address, "foo(fixed168x10)", [value]) @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) -def test_int128_array_clamper_passing(revm_env, get_contract, value): +def test_int128_array_clamper_passing(env, get_contract, value): code = """ @external def foo(a: uint256, b: int128[5], c: uint256) -> int128[5]: @@ -359,7 +359,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(revm_env, 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 @@ -372,11 +372,11 @@ def foo(b: int128[5]) -> int128[5]: c = get_contract(code) with tx_failed(): - _make_tx(revm_env, 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(revm_env, get_contract, value): +def test_int128_array_looped_clamper_passing(env, get_contract, value): # when an array is > 5 items, the arg clamper runs in a loop to reduce bytecode size code = """ @external @@ -391,7 +391,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(revm_env, 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]: @@ -403,11 +403,11 @@ def foo(b: int128[10]) -> int128[10]: c = get_contract(code) with tx_failed(): - _make_tx(revm_env, 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(revm_env, get_contract, value): +def test_multidimension_array_clamper_passing(env, get_contract, value): code = """ @external def foo(a: uint256, b: int128[6][3][1][8], c: uint256) -> int128[6][3][1][8]: @@ -422,7 +422,7 @@ def foo(a: uint256, b: int128[6][3][1][8], c: uint256) -> int128[6][3][1][8]: @pytest.mark.parametrize("bad_value", [2**127, -(2**127) - 1, 2**255 - 1, -(2**255)]) @pytest.mark.parametrize("idx", range(12)) -def test_multidimension_array_clamper_failing(revm_env, 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]: @@ -434,11 +434,11 @@ def foo(b: int128[6][1][2]) -> int128[6][1][2]: c = get_contract(code) with tx_failed(): - _make_tx(revm_env, 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(revm_env, get_contract, value): +def test_int128_dynarray_clamper_passing(env, get_contract, value): code = """ @external def foo(a: uint256, b: DynArray[int128, 5], c: uint256) -> DynArray[int128, 5]: @@ -454,7 +454,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(revm_env, 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 @@ -470,11 +470,11 @@ def foo(b: int128[5]) -> int128[5]: data = _make_dynarray_data(32, 5, values) with tx_failed(): - _make_invalid_dynarray_tx(revm_env, 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(revm_env, get_contract, value): +def test_int128_dynarray_looped_clamper_passing(env, get_contract, value): # when an array is > 5 items, the arg clamper runs in a loop to reduce bytecode size code = """ @external @@ -488,7 +488,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(revm_env, 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]: @@ -503,12 +503,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(revm_env, 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(revm_env, get_contract, value): +def test_multidimension_dynarray_clamper_passing(env, get_contract, value): code = """ @external def foo( @@ -526,7 +526,7 @@ def foo( @pytest.mark.parametrize("bad_value", [2**127, -(2**127) - 1, 2**255 - 1, -(2**255)]) @pytest.mark.parametrize("idx", range(4)) -def test_multidimension_dynarray_clamper_failing(revm_env, 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]: @@ -547,11 +547,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(revm_env, 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(revm_env, get_contract, value): +def test_dynarray_list_clamper_passing(env, get_contract, value): code = """ @external def foo( @@ -568,7 +568,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(revm_env, 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 @@ -587,4 +587,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(revm_env, c.address, signature, data) + _make_invalid_dynarray_tx(env, c.address, signature, data) diff --git a/tests/functional/codegen/features/test_constructor.py b/tests/functional/codegen/features/test_constructor.py index 0bc51b5a89..b0f2f17960 100644 --- a/tests/functional/codegen/features/test_constructor.py +++ b/tests/functional/codegen/features/test_constructor.py @@ -90,7 +90,7 @@ def foo(x: int128) -> int128: c.foo(2**130) -def test_large_input_code_2(revm_env, get_contract_with_gas_estimation): +def test_large_input_code_2(env, get_contract_with_gas_estimation): large_input_code_2 = """ @deploy def __init__(x: int128): @@ -149,7 +149,7 @@ def check_foo(a: uint64) -> int16: assert c.check_foo(3) == -2 -def test_nested_dynamic_array_constructor_arg(revm_env, get_contract_with_gas_estimation): +def test_nested_dynamic_array_constructor_arg(env, get_contract_with_gas_estimation): code = """ foo: uint256 @@ -166,7 +166,7 @@ def get_foo() -> uint256: @pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") -def test_nested_dynamic_array_constructor_arg_2(revm_env, get_contract_with_gas_estimation): +def test_nested_dynamic_array_constructor_arg_2(env, get_contract_with_gas_estimation): code = """ foo: int128 @@ -191,7 +191,7 @@ def get_foo() -> int128: assert c.get_foo() == 9580 -def test_initialise_nested_dynamic_array(revm_env, get_contract_with_gas_estimation): +def test_initialise_nested_dynamic_array(env, get_contract_with_gas_estimation): code = """ foo: DynArray[DynArray[uint256, 3], 3] @@ -212,7 +212,7 @@ def get_foo() -> DynArray[DynArray[uint256, 3], 3]: @pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") -def test_initialise_nested_dynamic_array_2(revm_env, get_contract_with_gas_estimation): +def test_initialise_nested_dynamic_array_2(env, get_contract_with_gas_estimation): code = """ foo: DynArray[DynArray[DynArray[int128, 3], 3], 3] diff --git a/tests/functional/codegen/features/test_logging.py b/tests/functional/codegen/features/test_logging.py index 611aad61e1..6e65ec9ebe 100644 --- a/tests/functional/codegen/features/test_logging.py +++ b/tests/functional/codegen/features/test_logging.py @@ -19,7 +19,7 @@ pytestmark = pytest.mark.usefixtures("memory_mocker") -def test_empty_event_logging(revm_env, keccak, get_contract_with_gas_estimation): +def test_empty_event_logging(get_logs, keccak, get_contract_with_gas_estimation): loggy_code = """ event MyLog: pass @@ -29,20 +29,20 @@ def foo(): """ c = get_contract_with_gas_estimation(loggy_code) - c.foo(transact={}) + tx = c.foo(transact={}) event_id = keccak(bytes("MyLog()", "utf-8")) # Event id is always the first topic - (log,) = revm_env.evm.result.logs - assert log.topics[0] == "0x" + event_id.hex() + (log,) = get_logs(tx, c) + assert log.topics == [event_id] # Event abi is created correctly assert c.abi[0] == {"name": "MyLog", "inputs": [], "anonymous": False, "type": "event"} # Event is decoded correctly - assert c.parse_log(log).event == "MyLog" + assert log.event == "MyLog" -def test_event_logging_with_topics(revm_env, keccak, get_logs, get_contract_with_gas_estimation): +def test_event_logging_with_topics(get_logs, keccak, get_contract_with_gas_estimation): loggy_code = """ a: Bytes[3] @@ -57,12 +57,12 @@ def foo(): """ c = get_contract_with_gas_estimation(loggy_code) - c.foo(transact={}) + tx_hash = c.foo(transact={}) event_id = keccak(bytes("MyLog(bytes)", "utf-8")) # Event id is always the first topic - (log,) = revm_env.evm.result.logs - assert log.topics[0] == "0x" + event_id.hex() + (log,) = get_logs(tx_hash, c) + assert log.topics[0] == event_id # Event abi is created correctly assert c.abi[0] == { "name": "MyLog", @@ -73,7 +73,7 @@ def foo(): def test_event_logging_with_multiple_topics( - revm_env, keccak, get_logs, get_contract_with_gas_estimation + env, keccak, get_logs, get_contract_with_gas_estimation ): loggy_code = """ event MyLog: @@ -91,8 +91,8 @@ def foo(): event_id = keccak(bytes("MyLog(int128,bool,address)", "utf-8")) # Event id is always the first topic - (log,) = revm_env.evm.result.logs - assert log.topics[0] == "0x" + event_id.hex() + (log,) = get_logs(tx_hash, c) + assert log.topics[0] == event_id # Event abi is created correctly assert c.abi[0] == { "name": "MyLog", @@ -142,7 +142,7 @@ def foo(arg1: int128): def test_logging_the_same_event_multiple_times_with_topics( - revm_env, keccak, get_logs, get_contract_with_gas_estimation + env, keccak, get_logs, get_contract_with_gas_estimation ): loggy_code = """ event MyLog: @@ -161,16 +161,16 @@ def bar(): """ c = get_contract_with_gas_estimation(loggy_code) - c.foo(transact={}) - logs_tx1 = revm_env.evm.result.logs + tx_hash1 = c.foo(transact={}) + logs_tx1 = get_logs(tx_hash1, c) log1, _ = logs_tx1 - c.bar(transact={}) - log2, _ = revm_env.evm.result.logs + tx_hash2 = c.bar(transact={}) + log2, _ = get_logs(tx_hash2, c) event_id = keccak(bytes("MyLog(int128,address)", "utf-8")) # Event id is always the first topic - assert log1.topics[0] == "0x" + event_id.hex() - assert log2.topics[0] == "0x" + event_id.hex() + assert log1.topics[0] == event_id + assert log2.topics[0] == event_id # Event abi is created correctly assert c.abi[0] == { "name": "MyLog", @@ -183,7 +183,7 @@ def bar(): } # Event is decoded correctly - logs_tx1 = [c.parse_log(log) for log in logs_tx1] + logs_tx1 = [log for log in logs_tx1] assert logs_tx1[0].args.arg1 == 1 assert logs_tx1[0].args.arg2 == c.address assert logs_tx1[1].args.arg1 == 1 @@ -205,7 +205,7 @@ def test_event_logging_cannot_have_more_than_three_topics( compile_code(loggy_code) -def test_event_logging_with_data(revm_env, keccak, get_logs, get_contract_with_gas_estimation): +def test_event_logging_with_data(get_logs, keccak, get_contract_with_gas_estimation): loggy_code = """ event MyLog: arg1: int128 @@ -220,8 +220,8 @@ def foo(): event_id = keccak(bytes("MyLog(int128)", "utf-8")) # Event id is always the first topic - (log,) = revm_env.evm.result.logs - assert log.topics[0] == "0x" + event_id.hex() + (log,) = get_logs(tx_hash, c) + assert log.topics == [event_id] # Event abi is created correctly assert c.abi[0] == { "name": "MyLog", @@ -236,7 +236,7 @@ def foo(): def test_event_logging_with_fixed_array_data( - revm_env, keccak, get_logs, get_contract_with_gas_estimation + env, keccak, get_logs, get_contract_with_gas_estimation ): loggy_code = """ event MyLog: @@ -256,8 +256,8 @@ def foo(): event_id = keccak(bytes("MyLog(int128[2],uint256[3],int128[2][2])", "utf-8")) # Event id is always the first topic - log, _ = revm_env.evm.result.logs - assert log.topics[0] == "0x" + event_id.hex() + log, _ = get_logs(tx_hash, c) + assert log.topics == [event_id] # Event abi is created correctly assert c.abi[0] == { @@ -272,7 +272,7 @@ def foo(): } # Event is decoded correctly - timestamp = revm_env.get_block(revm_env.block_number).timestamp + timestamp = env.get_block(env.block_number).timestamp logs = get_logs(tx_hash, c, "MyLog") assert logs[0].args.arg1 == [1, 2] @@ -281,7 +281,7 @@ def foo(): def test_logging_with_input_bytes_1( - revm_env, keccak, get_logs, bytes_helper, get_contract_with_gas_estimation + env, keccak, get_logs, bytes_helper, get_contract_with_gas_estimation ): loggy_code = """ event MyLog: @@ -299,8 +299,8 @@ def foo(arg1: Bytes[29], arg2: Bytes[31]): event_id = keccak(bytes("MyLog(bytes,bytes,bytes)", "utf-8")) # Event id is always the first topic - (log,) = revm_env.evm.result.logs - assert log.topics[0] == "0x" + event_id.hex() + (log,) = get_logs(tx_hash, c) + assert log.topics[0] == event_id # Event abi is created correctly assert c.abi[0] == { "name": "MyLog", @@ -320,9 +320,7 @@ def foo(arg1: Bytes[29], arg2: Bytes[31]): assert logs[0].args.arg3 == b"foo" -def test_event_logging_with_bytes_input_2( - revm_env, keccak, get_logs, get_contract_with_gas_estimation -): +def test_event_logging_with_bytes_input_2(env, keccak, get_logs, get_contract_with_gas_estimation): loggy_code = """ event MyLog: arg1: Bytes[20] @@ -333,12 +331,12 @@ def foo(_arg1: Bytes[20]): """ c = get_contract_with_gas_estimation(loggy_code) - c.foo(b"hello", transact={}) + tx_hash = c.foo(b"hello", transact={}) event_id = keccak(bytes("MyLog(bytes)", "utf-8")) # Event id is always the first topic - (log,) = revm_env.evm.result.logs - assert log.topics[0] == "0x" + event_id.hex() + (log,) = get_logs(tx_hash, c) + assert log.topics[0] == event_id # Event abi is created correctly assert c.abi[0] == { "anonymous": False, @@ -347,10 +345,10 @@ def foo(_arg1: Bytes[20]): "type": "event", } # Event is decoded correctly - assert c.parse_log(log).args.arg1 == b"hello" + assert log.args.arg1 == b"hello" -def test_event_logging_with_bytes_input_3(revm_env, 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] @@ -365,8 +363,8 @@ def foo(_arg1: Bytes[5]): event_id = keccak(bytes("MyLog(bytes)", "utf-8")) # Event id is always the first topic - (log,) = revm_env.evm.result.logs - assert log.topics[0] == "0x" + event_id.hex() + (log,) = get_logs(tx_hash, c) + assert log.topics == [event_id] # Event abi is created correctly assert c.abi[0] == { "anonymous": False, @@ -380,7 +378,7 @@ def foo(_arg1: Bytes[5]): def test_event_logging_with_data_with_different_types( - revm_env, keccak, get_logs, get_contract_with_gas_estimation + env, keccak, get_logs, get_contract_with_gas_estimation ): loggy_code = """ event MyLog: @@ -401,8 +399,8 @@ def foo(): event_id = keccak(bytes("MyLog(int128,bytes,bytes,address,address,uint256)", "utf-8")) # Event id is always the first topic - (log,) = revm_env.evm.result.logs - assert log.topics[0] == "0x" + event_id.hex() + (log,) = get_logs(tx_hash, c) + assert log.topics == [event_id] # Event abi is created correctly assert c.abi[0] == { "name": "MyLog", @@ -419,7 +417,7 @@ def foo(): } # Event is decoded correctly - timestamp = revm_env.get_block(revm_env.block_number).timestamp + timestamp = env.get_block(env.block_number).timestamp logs = get_logs(tx_hash, c, "MyLog") args = logs[0].args assert args.arg1 == 123 @@ -431,7 +429,7 @@ def foo(): def test_event_logging_with_topics_and_data_1( - revm_env, keccak, get_logs, get_contract_with_gas_estimation + env, keccak, get_logs, get_contract_with_gas_estimation ): loggy_code = """ event MyLog: @@ -448,8 +446,8 @@ def foo(): event_id = keccak(bytes("MyLog(int128,bytes)", "utf-8")) # Event id is always the first topic - (log,) = revm_env.evm.result.logs - assert log.topics[0] == "0x" + event_id.hex() + (log,) = get_logs(tx_hash, c) + assert log.topics[0] == event_id # Event abi is created correctly assert c.abi[0] == { "anonymous": False, @@ -468,7 +466,7 @@ def foo(): def test_event_logging_with_multiple_logs_topics_and_data( - revm_env, keccak, get_logs, get_contract_with_gas_estimation + env, keccak, get_logs, get_contract_with_gas_estimation ): loggy_code = """ struct SmallStruct: @@ -495,13 +493,13 @@ def foo(): c = get_contract_with_gas_estimation(loggy_code) tx_hash = c.foo(transact={}) - log1, log2 = revm_env.evm.result.logs + log1, log2 = get_logs(tx_hash, c) event_id1 = keccak(bytes("MyLog(int128,bytes)", "utf-8")) event_id2 = keccak(bytes("YourLog(address,(uint256,bytes,(string,fixed168x10)))", "utf-8")) # Event id is always the first topic - assert log1.topics[0] == "0x" + event_id1.hex() - assert log2.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.abi[0] == { "name": "MyLog", @@ -734,7 +732,7 @@ def foo(): get_contract_with_gas_estimation(loggy_code) -def test_loggy_code(revm_env, get_contract_with_gas_estimation): +def test_loggy_code(get_logs, get_contract_with_gas_estimation): loggy_code = """ s: Bytes[100] @@ -758,30 +756,30 @@ def ioo(inp: Bytes[100]): c = get_contract_with_gas_estimation(loggy_code) - c.foo(transact={}) - (log,) = revm_env.evm.result.logs + tx_hash = c.foo(transact={}) + ((topics, data),) = get_logs(tx_hash, c, raw=True) - assert to_text(log.data[1]) == "moo" - c.goo(transact={}) - (log,) = revm_env.evm.result.logs + assert to_text(data) == "moo" + tx_hash = c.goo(transact={}) + ((topics, data),) = get_logs(tx_hash, c, raw=True) - assert to_text(log.data[1]) == "moo2" - assert ( - log.topics[0] == "0x1234567812345678123456781234567812345678123456781234567812345678" - ) # noqa: E501 + assert to_text(data) == "moo2" + assert topics[0] == bytes.fromhex( + "1234567812345678123456781234567812345678123456781234567812345678" + ) - c.hoo(transact={}) - (log,) = revm_env.evm.result.logs - assert to_text(log.data[1]) == "moo3" + tx_hash = c.hoo(transact={}) + ((topics, data),) = get_logs(tx_hash, c, raw=True) + assert to_text(data) == "moo3" - c.ioo(b"moo4", transact={}) - (log,) = revm_env.evm.result.logs - assert to_text(log.data[1]) == "moo4" + tx_hash = c.ioo(b"moo4", transact={}) + ((topics, data),) = get_logs(tx_hash, c, raw=True) + assert to_text(data) == "moo4" print("Passed raw log tests") -def test_raw_call_bytes32_data(revm_env, get_contract_with_gas_estimation): +def test_raw_call_bytes32_data(get_logs, get_contract_with_gas_estimation): code = """ b: uint256 @@ -795,12 +793,12 @@ def foo(): raw_log([], keccak256(b"")) """ c = get_contract_with_gas_estimation(code) - c.foo(transact={}) - logs = revm_env.evm.result.logs - assert logs[0].data[1] == (1234).to_bytes(32, "big") - assert logs[1].data[1] == (4321).to_bytes(32, "big") - assert logs[2].data[1] == b"testmessage".ljust(32, b"\0") - assert logs[3].data[1] == keccak256(b"") + tx_hash = c.foo(transact={}) + logs = get_logs(tx_hash, 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): @@ -1053,7 +1051,7 @@ def set_list(): assert log.args.arg5 == [1024, 2048] -def test_hashed_indexed_topics_calldata(keccak, get_contract, revm_env): +def test_hashed_indexed_topics_calldata(get_logs, keccak, get_contract): loggy_code = """ event MyLog: arg1: indexed(Bytes[36]) @@ -1066,24 +1064,16 @@ def foo(a: Bytes[36], b: int128, c: String[7]): """ c = get_contract(loggy_code) - c.foo(b"bar", 1, "weird", transact={}) + tx_hash = c.foo(b"bar", 1, "weird", transact={}) # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - (log,) = revm_env.evm.result.logs - assert log.topics[0] == "0x" + event_id.hex() + topic1 = keccak256(b"bar") + topic2 = abi.encode("int128", 1) + topic3 = keccak256(b"weird") - topic1 = f"0x{keccak256(b'bar').hex()}" - (log,) = revm_env.evm.result.logs - assert log.topics[1] == topic1 - - topic2 = f"0x{abi.encode('int128', 1).hex()}" - (log,) = revm_env.evm.result.logs - assert log.topics[2] == topic2 - - topic3 = f"0x{keccak256(b'weird').hex()}" - (log,) = revm_env.evm.result.logs - assert log.topics[3] == topic3 + (log,) = get_logs(tx_hash, c) + assert log.topics == [event_id, topic1, topic2, topic3] # Event abi is created correctly assert c.abi[0] == { @@ -1098,7 +1088,7 @@ def foo(a: Bytes[36], b: int128, c: String[7]): } -def test_hashed_indexed_topics_memory(keccak, get_contract, revm_env): +def test_hashed_indexed_topics_memory(get_logs, keccak, get_contract): loggy_code = """ event MyLog: arg1: indexed(Bytes[10]) @@ -1114,24 +1104,15 @@ def foo(): """ c = get_contract(loggy_code) - c.foo(transact={}) + tx_hash = c.foo(transact={}) # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - (log,) = revm_env.evm.result.logs - assert log.topics[0] == "0x" + event_id.hex() - - topic1 = f"0x{keccak256(b'potato').hex()}" - (log,) = revm_env.evm.result.logs - assert log.topics[1] == topic1 - - topic2 = f"0x{abi.encode('int128', -777).hex()}" - (log,) = revm_env.evm.result.logs - assert log.topics[2] == topic2 - - topic3 = f"0x{keccak256(b'why hello, neighbor! how are you today?').hex()}" - (log,) = revm_env.evm.result.logs - assert log.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(tx_hash, c) + assert log.topics == [event_id, topic1, topic2, topic3] # Event abi is created correctly assert c.abi[0] == { @@ -1146,7 +1127,7 @@ def foo(): } -def test_hashed_indexed_topics_storage(keccak, get_contract, revm_env): +def test_hashed_indexed_topics_storage(get_logs, keccak, get_contract): loggy_code = """ event MyLog: arg1: indexed(Bytes[32]) @@ -1171,24 +1152,16 @@ def foo(): c = get_contract(loggy_code) c.setter(b"zonk", -2109, "yessir", transact={}) - c.foo(transact={}) + tx_hash = c.foo(transact={}) # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - (log,) = revm_env.evm.result.logs - assert log.topics[0] == "0x" + event_id.hex() - - topic1 = f"0x{keccak256(b'zonk').hex()}" - (log,) = revm_env.evm.result.logs - assert log.topics[1] == topic1 + topic1 = keccak256(b"zonk") + topic2 = abi.encode("int128", -2109) + topic3 = keccak256(b"yessir") - topic2 = f"0x{abi.encode('int128', -2109).hex()}" - (log,) = revm_env.evm.result.logs - assert log.topics[2] == topic2 - - topic3 = f"0x{keccak256(b'yessir').hex()}" - (log,) = revm_env.evm.result.logs - assert log.topics[3] == topic3 + (log,) = get_logs(tx_hash, c) + assert log.topics == [event_id, topic1, topic2, topic3] # Event abi is created correctly assert c.abi[0] == { @@ -1203,7 +1176,7 @@ def foo(): } -def test_hashed_indexed_topics_storxxage(keccak, get_contract, revm_env): +def test_hashed_indexed_topics_storxxage(get_logs, keccak, get_contract): loggy_code = """ event MyLog: arg1: indexed(Bytes[64]) @@ -1216,24 +1189,16 @@ def foo(): """ c = get_contract(loggy_code) - c.foo(transact={}) + tx_hash = c.foo(transact={}) # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") - (log,) = revm_env.evm.result.logs - assert log.topics[0] == "0x" + event_id.hex() - - topic1 = f"0x{keccak256(b'wow').hex()}" - (log,) = revm_env.evm.result.logs - assert log.topics[1] == topic1 - - topic2 = f"0x{abi.encode('int128', 666).hex()}" - (log,) = revm_env.evm.result.logs - assert log.topics[2] == topic2 + topic1 = keccak256(b"wow") + topic2 = abi.encode("int128", 666) + topic3 = keccak256(b"madness!") - topic3 = f"0x{keccak256(b'madness!').hex()}" - (log,) = revm_env.evm.result.logs - assert log.topics[3] == topic3 + (log,) = get_logs(tx_hash, c) + assert log.topics == [event_id, topic1, topic2, topic3] fail_list = [ diff --git a/tests/functional/codegen/features/test_reverting.py b/tests/functional/codegen/features/test_reverting.py index 9007a91eab..b39f4ac2c1 100644 --- a/tests/functional/codegen/features/test_reverting.py +++ b/tests/functional/codegen/features/test_reverting.py @@ -7,7 +7,7 @@ pytestmark = pytest.mark.usefixtures("memory_mocker") -def test_revert_reason(revm_env, tx_failed, get_contract_with_gas_estimation): +def test_revert_reason(env, tx_failed, get_contract_with_gas_estimation): reverty_code = """ @external def foo(): @@ -21,7 +21,7 @@ def foo(): get_contract_with_gas_estimation(reverty_code).foo(transact={}) -def test_revert_reason_typed(revm_env, tx_failed, get_contract_with_gas_estimation): +def test_revert_reason_typed(env, tx_failed, get_contract_with_gas_estimation): reverty_code = """ @external def foo(): @@ -36,7 +36,7 @@ def foo(): get_contract_with_gas_estimation(reverty_code).foo(transact={}) -def test_revert_reason_typed_no_variable(revm_env, tx_failed, get_contract_with_gas_estimation): +def test_revert_reason_typed_no_variable(env, tx_failed, get_contract_with_gas_estimation): reverty_code = """ @external def foo(): diff --git a/tests/functional/codegen/features/test_short_circuiting.py b/tests/functional/codegen/features/test_short_circuiting.py index d3e8bcb388..d35f9145f5 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(revm_env, get_contract): +def test_short_circuit_and_left_is_false(env, get_contract): code = """ called_left: public(bool) @@ -31,7 +31,7 @@ def foo() -> bool: assert not c.called_right() -def test_short_circuit_and_left_is_true(revm_env, get_contract): +def test_short_circuit_and_left_is_true(env, get_contract): code = """ called_left: public(bool) @@ -59,7 +59,7 @@ def foo() -> bool: assert c.called_right() -def test_short_circuit_or_left_is_true(revm_env, get_contract): +def test_short_circuit_or_left_is_true(env, get_contract): code = """ called_left: public(bool) @@ -87,7 +87,7 @@ def foo() -> bool: assert not c.called_right() -def test_short_circuit_or_left_is_false(revm_env, get_contract): +def test_short_circuit_or_left_is_false(env, get_contract): code = """ called_left: public(bool) @@ -117,7 +117,7 @@ def foo() -> bool: @pytest.mark.parametrize("op", ["and", "or"]) @pytest.mark.parametrize("a, b", itertools.product([True, False], repeat=2)) -def test_from_memory(revm_env, get_contract, a, b, op): +def test_from_memory(env, 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(revm_env, get_contract, a, b, op): +def test_from_storage(env, 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(revm_env, get_contract, a, b, op): +def test_from_calldata(env, 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(revm_env, get_contract, a, b, c, d, ops): +def test_complex_combination(env, 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/integration/test_crowdfund.py b/tests/functional/codegen/integration/test_crowdfund.py index b679aa4641..1c05bd32c4 100644 --- a/tests/functional/codegen/integration/test_crowdfund.py +++ b/tests/functional/codegen/integration/test_crowdfund.py @@ -1,5 +1,5 @@ # TODO: check, this is probably redundant with examples/test_crowdfund.py -def test_crowdfund(revm_env, tester, get_contract): +def test_crowdfund(env, tester, get_contract): crowdfund = """ struct Funder: @@ -62,12 +62,12 @@ def refund(): self.refundIndex = ind + 30 """ - a0, a1, a2, a3, a4, a5, a6 = revm_env.accounts[:7] - for a in revm_env.accounts[:7]: - revm_env.set_balance(a, 10**10) + a0, a1, a2, a3, a4, a5, a6 = env.accounts[:7] + for a in env.accounts[:7]: + env.set_balance(a, 10**10) c = get_contract(crowdfund, *[a1, 50, 60]) - start_timestamp = revm_env.get_block(revm_env.block_number).timestamp + start_timestamp = env.get_block(env.block_number).timestamp c.participate(transact={"value": 5}) assert c.timelimit() == 60 @@ -76,11 +76,11 @@ def refund(): assert not c.reached() c.participate(transact={"value": 49}) assert c.reached() - pre_bal = revm_env.get_balance(a1) - revm_env.mine(100) + pre_bal = env.get_balance(a1) + env.mine(100) assert c.expired() c.finalize(transact={}) - post_bal = revm_env.get_balance(a1) + post_bal = env.get_balance(a1) assert post_bal - pre_bal == 54 c = get_contract(crowdfund, *[a1, 50, 60]) @@ -88,16 +88,16 @@ def refund(): c.participate(transact={"value": 2, "from": a4}) c.participate(transact={"value": 3, "from": a5}) c.participate(transact={"value": 4, "from": a6}) - revm_env.mine(100) + env.mine(100) assert c.expired() assert not c.reached() - pre_bals = [revm_env.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(transact={}) - post_bals = [revm_env.get_balance(x) for x in [a3, a4, a5, 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] -def test_crowdfund2(revm_env, tester, get_contract): +def test_crowdfund2(env, tester, get_contract): crowdfund2 = """ struct Funder: sender: address @@ -158,22 +158,22 @@ def refund(): self.refundIndex = ind + 30 """ - a0, a1, a2, a3, a4, a5, a6 = revm_env.accounts[:7] + a0, a1, a2, a3, a4, a5, a6 = env.accounts[:7] c = get_contract(crowdfund2, *[a1, 50, 60]) c.participate(transact={"value": 5}) - revm_env.mine(1) + env.mine() # 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}) assert c.reached() - pre_bal = revm_env.get_balance(a1) - revm_env.mine(100) + pre_bal = env.get_balance(a1) + env.mine(100) assert c.expired() c.finalize(transact={}) - post_bal = revm_env.get_balance(a1) + post_bal = env.get_balance(a1) assert post_bal - pre_bal == 54 c = get_contract(crowdfund2, *[a1, 50, 60]) @@ -181,10 +181,10 @@ def refund(): c.participate(transact={"value": 2, "from": a4}) c.participate(transact={"value": 3, "from": a5}) c.participate(transact={"value": 4, "from": a6}) - revm_env.mine(100) + env.mine(100) assert c.expired() assert not c.reached() - pre_bals = [revm_env.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(transact={}) - post_bals = [revm_env.get_balance(x) for x in [a3, a4, a5, 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/codegen/integration/test_escrow.py b/tests/functional/codegen/integration/test_escrow.py index f8c72ff839..c3b1fd800d 100644 --- a/tests/functional/codegen/integration/test_escrow.py +++ b/tests/functional/codegen/integration/test_escrow.py @@ -6,7 +6,7 @@ def initial_balance(): return 10**20 -def test_arbitration_code(revm_env, get_contract_with_gas_estimation, tx_failed): +def test_arbitration_code(env, get_contract_with_gas_estimation, tx_failed): arbitration_code = """ buyer: address seller: address @@ -30,7 +30,7 @@ def refund(): send(self.buyer, self.balance) """ - a0, a1, a2 = revm_env.accounts[:3] + a0, a1, a2 = env.accounts[:3] c = get_contract_with_gas_estimation(arbitration_code, value=1) c.setup(a1, a2, transact={}) with tx_failed(): @@ -40,7 +40,7 @@ def refund(): print("Passed escrow test") -def test_arbitration_code_with_init(revm_env, tx_failed, get_contract_with_gas_estimation): +def test_arbitration_code_with_init(env, tx_failed, get_contract_with_gas_estimation): arbitration_code_with_init = """ buyer: address seller: address @@ -64,7 +64,7 @@ def refund(): assert msg.sender == self.seller or msg.sender == self.arbitrator send(self.buyer, self.balance) """ - a0, a1, a2 = revm_env.accounts[:3] + a0, a1, a2 = env.accounts[:3] c = get_contract_with_gas_estimation(arbitration_code_with_init, *[a1, a2], value=1) with tx_failed(): c.finalize(transact={"from": a1}) diff --git a/tests/functional/codegen/modules/test_stateless_functions.py b/tests/functional/codegen/modules/test_stateless_functions.py index 4ed8d89a6e..ced1c58380 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, revm_env): +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() == revm_env.block_number + assert c.bar() == env.block_number # is this the best place for this? diff --git a/tests/functional/codegen/test_interfaces.py b/tests/functional/codegen/test_interfaces.py index d8a7829697..76b307bf4b 100644 --- a/tests/functional/codegen/test_interfaces.py +++ b/tests/functional/codegen/test_interfaces.py @@ -186,7 +186,7 @@ def test_extract_file_interface_imports_raises( compile_code(code, input_bundle=input_bundle) -def test_external_call_to_interface(revm_env, get_contract, make_input_bundle): +def test_external_call_to_interface(env, get_contract, make_input_bundle): token_interface = """ @view @external @@ -233,7 +233,7 @@ def test(): test_c = get_contract(code, *[token.address], input_bundle=input_bundle) - sender = revm_env.deployer + sender = env.deployer assert token.balanceOf(sender) == 0 test_c.test(transact={}) @@ -285,7 +285,7 @@ def bar(a_address: address) -> {typ}: assert contract_b.bar(contract_a.address) == expected -def test_external_call_to_builtin_interface(revm_env, get_contract): +def test_external_call_to_builtin_interface(env, get_contract): token_code = """ balanceOf: public(HashMap[address, uint256]) @@ -312,14 +312,14 @@ def test(): erc20 = get_contract(token_code) test_c = get_contract(code, *[erc20.address]) - sender = revm_env.deployer + sender = env.deployer assert erc20.balanceOf(sender) == 0 test_c.test(transact={}) assert erc20.balanceOf(sender) == 1000 -def test_address_member(revm_env, get_contract): +def test_address_member(env, get_contract): code = """ interface Foo: def foo(): payable @@ -332,7 +332,7 @@ def test(addr: address): assert self.f.address == addr """ c = get_contract(code) - for address in revm_env.accounts: + for address in env.accounts: c.test(address) @@ -504,7 +504,7 @@ def test_fail3() -> Bytes[3]: c.test_fail3() -def test_units_interface(revm_env, get_contract, make_input_bundle): +def test_units_interface(env, get_contract, make_input_bundle): code = """ import balanceof as BalanceOf @@ -527,7 +527,7 @@ def balanceOf(owner: address) -> uint256: c = get_contract(code, input_bundle=input_bundle) - assert c.balanceOf(revm_env.deployer) == 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 7c8509edd4..e11a4b3405 100644 --- a/tests/functional/codegen/test_selector_table.py +++ b/tests/functional/codegen/test_selector_table.py @@ -512,9 +512,7 @@ def generate_methods(draw, max_calldata_bytes): # dense selector table packing boundaries at 256 and 65336 @pytest.mark.parametrize("max_calldata_bytes", [255, 256, 65336]) @pytest.mark.fuzzing -def test_selector_table_fuzz( - max_calldata_bytes, opt_level, revm_env, 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) @@ -576,7 +574,7 @@ def __default__(): """ c = get_contract(code, override_opt_level=opt_level) - revm_env.set_balance(revm_env.deployer, 10**18) + 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}" @@ -601,7 +599,7 @@ def __default__(): else: hexstr = (method_id + argsdata).hex() with tx_failed(): - revm_env.execute_code(c.address, data=hexstr, value=1) + env.execute_code(c.address, data=hexstr, value=1) # now do calldatasize check # strip some bytes @@ -612,15 +610,15 @@ def __default__(): # no args, hit default function if default_fn_mutability == "": with tx_failed(): - revm_env.execute_code(**tx_params) + env.execute_code(**tx_params) elif default_fn_mutability == "@payable": # we should be able to send eth to it tx_params["value"] = 1 - tx = revm_env.execute_code(**tx_params) + tx = env.execute_code(**tx_params) logs = get_logs(tx, c, "CalledDefault") assert len(logs) == 1 else: - tx = revm_env.execute_code(**tx_params) + tx = env.execute_code(**tx_params) # note: can't emit logs from view/pure functions, # so the logging is not tested. @@ -631,9 +629,9 @@ def __default__(): # check default function reverts tx_params["value"] = 1 with tx_failed(): - revm_env.execute_code(**tx_params) + env.execute_code(**tx_params) else: with tx_failed(): - revm_env.execute_code(**tx_params) + env.execute_code(**tx_params) _test() diff --git a/tests/functional/codegen/types/test_flag.py b/tests/functional/codegen/types/test_flag.py index 33c874e431..0024b17df3 100644 --- a/tests/functional/codegen/types/test_flag.py +++ b/tests/functional/codegen/types/test_flag.py @@ -152,7 +152,7 @@ def binv_arg(a: Roles) -> Roles: c.bxor_arg(3, 32) -def test_augassign_storage(get_contract, revm_env, tx_failed): +def test_augassign_storage(get_contract, env, tx_failed): code = """ flag Roles: ADMIN @@ -186,8 +186,8 @@ def checkMinter(minter: address): c = get_contract(code) # check admin - admin_address = revm_env.deployer - minter_address = revm_env.accounts[1] + admin_address = env.deployer + minter_address = env.accounts[1] # add minter c.addMinter(minter_address, transact={}) diff --git a/tests/functional/examples/auctions/test_blind_auction.py b/tests/functional/examples/auctions/test_blind_auction.py index 9efea61b5f..1f482adea0 100644 --- a/tests/functional/examples/auctions/test_blind_auction.py +++ b/tests/functional/examples/auctions/test_blind_auction.py @@ -8,21 +8,21 @@ @pytest.fixture -def auction_contract(revm_env, get_contract, initial_balance): +def auction_contract(env, get_contract, initial_balance): with open("examples/auctions/blind_auction.vy") as f: contract_code = f.read() - for acc in revm_env.accounts[1:4]: - revm_env.set_balance(acc, initial_balance) + for acc in env.accounts[1:4]: + env.set_balance(acc, initial_balance) - return get_contract(contract_code, *[revm_env.deployer, BIDDING_TIME, REVEAL_TIME]) + return get_contract(contract_code, *[env.deployer, BIDDING_TIME, REVEAL_TIME]) -def test_initial_state(revm_env, auction_contract): +def test_initial_state(env, auction_contract): # Check beneficiary is correct - assert auction_contract.beneficiary() == revm_env.deployer + assert auction_contract.beneficiary() == env.deployer # Check that bidding end time is correct - assert auction_contract.biddingEnd() == revm_env.get_block("latest").timestamp + BIDDING_TIME + assert auction_contract.biddingEnd() == env.get_block("latest").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 @@ -33,11 +33,11 @@ def test_initial_state(revm_env, auction_contract): assert auction_contract.highestBidder() is None -def test_late_bid(revm_env, auction_contract, tx_failed, keccak): - k1 = revm_env.accounts[1] +def test_late_bid(env, auction_contract, tx_failed, keccak): + k1 = env.accounts[1] # Move time forward past bidding end - revm_env.mine(BIDDING_TIME + TEST_INCREMENT) + env.mine(BIDDING_TIME + TEST_INCREMENT) # Try to bid after bidding has ended with tx_failed(): @@ -55,8 +55,8 @@ def test_late_bid(revm_env, auction_contract, tx_failed, keccak): ) -def test_too_many_bids(revm_env, auction_contract, tx_failed, keccak): - k1 = revm_env.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): @@ -89,8 +89,8 @@ def test_too_many_bids(revm_env, auction_contract, tx_failed, keccak): ) -def test_early_reval(revm_env, auction_contract, tx_failed, keccak): - k1 = revm_env.accounts[1] +def test_early_reval(env, auction_contract, tx_failed, keccak): + k1 = env.accounts[1] # k1 places 1 real bid auction_contract.bid( @@ -107,7 +107,7 @@ def test_early_reval(revm_env, auction_contract, tx_failed, keccak): ) # Move time slightly forward (still before bidding has ended) - revm_env.mine(TEST_INCREMENT) + env.mine(TEST_INCREMENT) # Try to reveal early _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -128,8 +128,8 @@ def test_early_reval(revm_env, auction_contract, tx_failed, keccak): assert auction_contract.highestBid() == 0 -def test_late_reveal(revm_env, auction_contract, tx_failed, keccak): - k1 = revm_env.accounts[1] +def test_late_reveal(env, auction_contract, tx_failed, keccak): + k1 = env.accounts[1] # k1 places 1 real bid auction_contract.bid( @@ -146,7 +146,7 @@ def test_late_reveal(revm_env, auction_contract, tx_failed, keccak): ) # Move time forward past bidding _and_ reveal time - revm_env.mine(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) + env.mine(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) # Try to reveal late _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -167,19 +167,19 @@ def test_late_reveal(revm_env, auction_contract, tx_failed, keccak): assert auction_contract.highestBid() == 0 -def test_early_end(revm_env, auction_contract, tx_failed): - k0 = revm_env.deployer +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}) -def test_double_end(revm_env, auction_contract, tx_failed): - k0 = revm_env.deployer +def test_double_end(env, auction_contract, tx_failed): + k0 = env.deployer # Move time forward past bidding and reveal end - revm_env.mine(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) + env.mine(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) # First auction end should succeed auction_contract.auctionEnd(transact={"value": 0, "from": k0}) @@ -189,10 +189,10 @@ def test_double_end(revm_env, auction_contract, tx_failed): auction_contract.auctionEnd(transact={"value": 0, "from": k0}) -def test_blind_auction(revm_env, initial_balance, auction_contract, keccak): - k0, k1, k2, k3 = revm_env.accounts[0:4] - for acc in revm_env.accounts[1:4]: - revm_env.set_balance(acc, initial_balance) +def test_blind_auction(env, initial_balance, auction_contract, keccak): + k0, k1, k2, k3 = env.accounts[0:4] + for acc in env.accounts[1:4]: + env.set_balance(acc, initial_balance) ################################################################### # Place bids # @@ -281,7 +281,7 @@ def test_blind_auction(revm_env, initial_balance, auction_contract, keccak): ################################################################### # Move time forward past bidding end (still within reveal end) - revm_env.mine(BIDDING_TIME + TEST_INCREMENT) + env.mine(BIDDING_TIME + TEST_INCREMENT) # Reveal k1 bids _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -310,9 +310,9 @@ def test_blind_auction(revm_env, initial_balance, auction_contract, keccak): _values[2] = 300 _fakes[2] = True _secrets[2] = (1234567).to_bytes(32, byteorder="big") - balance_before_reveal = revm_env.get_balance(k2) + balance_before_reveal = env.get_balance(k2) auction_contract.reveal(3, _values, _fakes, _secrets, transact={"value": 0, "from": k2}) - balance_after_reveal = revm_env.get_balance(k2) + balance_after_reveal = env.get_balance(k2) #: Check that highest bidder and highest bid have updated assert auction_contract.highestBid() == 200 @@ -331,9 +331,9 @@ def test_blind_auction(revm_env, initial_balance, auction_contract, keccak): _values[1] = 275 _fakes[1] = True _secrets[1] = (9876543).to_bytes(32, byteorder="big") - balance_before_reveal = revm_env.get_balance(k3) + balance_before_reveal = env.get_balance(k3) auction_contract.reveal(2, _values, _fakes, _secrets, transact={"value": 0, "from": k3}) - balance_after_reveal = revm_env.get_balance(k3) + balance_after_reveal = env.get_balance(k3) #: Check that highest bidder and highest bid have NOT updated assert auction_contract.highestBidder() == k2 @@ -347,12 +347,12 @@ def test_blind_auction(revm_env, initial_balance, auction_contract, keccak): ################################################################### # Move time forward past bidding and reveal end - revm_env.mine(REVEAL_TIME) + env.mine(REVEAL_TIME) # End the auction - balance_before_end = revm_env.get_balance(k0) + balance_before_end = env.get_balance(k0) auction_contract.auctionEnd(transact={"value": 0, "from": k0}) - balance_after_end = revm_env.get_balance(k0) + balance_after_end = env.get_balance(k0) # Check that auction indeed ended assert auction_contract.ended() is True @@ -361,7 +361,7 @@ def test_blind_auction(revm_env, initial_balance, auction_contract, keccak): assert balance_after_end == (balance_before_end + 200) # Check that k1 is able to withdraw their outbid bid - balance_before_withdraw = revm_env.get_balance(k1) + balance_before_withdraw = env.get_balance(k1) auction_contract.withdraw(transact={"value": 0, "from": k1}) - balance_after_withdraw = revm_env.get_balance(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 7059c42473..9bf79cdae2 100644 --- a/tests/functional/examples/auctions/test_simple_open_auction.py +++ b/tests/functional/examples/auctions/test_simple_open_auction.py @@ -4,24 +4,24 @@ @pytest.fixture -def auction_start(revm_env): - return revm_env.get_block("latest").timestamp + 1 +def auction_start(env): + return env.get_block("latest").timestamp + 1 @pytest.fixture -def auction_contract(revm_env, get_contract, auction_start, initial_balance): +def auction_contract(env, get_contract, auction_start, initial_balance): with open("examples/auctions/simple_open_auction.vy") as f: contract_code = f.read() - for acc in revm_env.accounts[1:5]: - revm_env.set_balance(acc, initial_balance) + for acc in env.accounts[1:5]: + env.set_balance(acc, initial_balance) - return get_contract(contract_code, *[revm_env.accounts[0], auction_start, EXPIRY]) + return get_contract(contract_code, *[env.accounts[0], auction_start, EXPIRY]) -def test_initial_state(revm_env, auction_contract, auction_start): +def test_initial_state(env, auction_contract, auction_start): # Check beneficiary is correct - assert auction_contract.beneficiary() == revm_env.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 @@ -33,12 +33,12 @@ def test_initial_state(revm_env, auction_contract, auction_start): # Check highest bid is 0 assert auction_contract.highestBid() == 0 # Check end time is more than current block timestamp - assert auction_contract.auctionEnd() >= revm_env.get_block("latest").timestamp + assert auction_contract.auctionEnd() >= env.get_block("latest").timestamp -def test_bid(revm_env, auction_contract, tx_failed): - k1, k2, k3, k4, k5 = revm_env.accounts[:5] - revm_env.mine(1) # make sure auction has started +def test_bid(env, auction_contract, tx_failed): + k1, k2, k3, k4, k5 = env.accounts[:5] + env.mine() # make sure auction has started # Bidder cannot bid 0 with tx_failed(): @@ -71,19 +71,19 @@ def test_bid(revm_env, auction_contract, tx_failed): # Account has a greater pending return balance after being outbid assert pending_return_after_outbid > pending_return_before_outbid - balance_before_withdrawal = revm_env.get_balance(k1) + balance_before_withdrawal = env.get_balance(k1) auction_contract.withdraw(transact={"from": k1}) - balance_after_withdrawal = revm_env.get_balance(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(revm_env, auction_contract, tx_failed): - k1, k2, k3, k4, k5 = revm_env.accounts[:5] +def test_end_auction(env, auction_contract, tx_failed): + k1, k2, k3, k4, k5 = env.accounts[:5] - revm_env.mine(1) # make sure auction has started + env.mine() # make sure auction has started # Fails if auction end time has not been reached with tx_failed(): @@ -92,10 +92,10 @@ def test_end_auction(revm_env, auction_contract, tx_failed): auction_contract.bid(transact={"value": 1 * 10**10, "from": k2}) # Move block timestamp forward to reach auction end time # tester.time_travel(tester.get_block_by_number('latest')['timestamp'] + EXPIRY) - revm_env.mine(EXPIRY) - balance_before_end = revm_env.get_balance(k1) + env.mine(EXPIRY) + balance_before_end = env.get_balance(k1) auction_contract.endAuction(transact={"from": k2}) - balance_after_end = revm_env.get_balance(k1) + 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 diff --git a/tests/functional/examples/company/test_company.py b/tests/functional/examples/company/test_company.py index eb8b4ab17e..7c034ad22f 100644 --- a/tests/functional/examples/company/test_company.py +++ b/tests/functional/examples/company/test_company.py @@ -2,19 +2,19 @@ @pytest.fixture -def c(revm_env, initial_balance, get_contract): +def c(env, initial_balance, get_contract): with open("examples/stock/company.vy") as f: contract_code = f.read() - for acc in revm_env.accounts[1:5]: - revm_env.set_balance(acc, initial_balance) + for acc in env.accounts[1:5]: + env.set_balance(acc, initial_balance) - return get_contract(contract_code, *[revm_env.accounts[0], 1000, 10**6]) + return get_contract(contract_code, *[env.accounts[0], 1000, 10**6]) -def test_overbuy(revm_env, c, tx_failed): +def test_overbuy(env, c, tx_failed): # If all the stock has been bought, no one can buy more - a1, a2 = revm_env.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}) @@ -28,8 +28,8 @@ def test_overbuy(revm_env, c, tx_failed): c.buyStock(transact={"from": a2, "value": one_stock}) -def test_sell_without_stock(revm_env, c, tx_failed): - a1, a2 = revm_env.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}) @@ -46,8 +46,8 @@ def test_sell_without_stock(revm_env, c, tx_failed): c.sellStock(1, transact={"from": a1}) -def test_oversell(revm_env, c, tx_failed): - a0, a1, a2 = revm_env.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()) @@ -56,9 +56,9 @@ def test_oversell(revm_env, c, tx_failed): c.sellStock(test_shares + 1, transact={"from": a1}) -def test_transfer(revm_env, c, tx_failed): +def test_transfer(env, c, tx_failed): # If you don't have any stock, you can't transfer - a1, a2 = revm_env.accounts[1:3] + a1, a2 = env.accounts[1:3] with tx_failed(): c.transferStock(a2, 1, transact={"from": a1}) with tx_failed(): @@ -75,8 +75,8 @@ def test_transfer(revm_env, c, tx_failed): c.sellStock(test_shares, transact={"from": a2}) -def test_paybill(revm_env, c, tx_failed): - a0, a1, a2, a3 = revm_env.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}) @@ -95,8 +95,8 @@ def test_paybill(revm_env, c, tx_failed): c.sellStock(1, transact={"from": a1}) -def test_valuation(revm_env, c): - a1 = revm_env.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()) @@ -104,8 +104,8 @@ def test_valuation(revm_env, c): assert c.debt() == test_value -def test_logs(revm_env, c, get_logs): - a0, a1, a2, a3 = revm_env.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 diff --git a/tests/functional/examples/crowdfund/test_crowdfund_example.py b/tests/functional/examples/crowdfund/test_crowdfund_example.py index df251dd7d5..3855174679 100644 --- a/tests/functional/examples/crowdfund/test_crowdfund_example.py +++ b/tests/functional/examples/crowdfund/test_crowdfund_example.py @@ -2,35 +2,35 @@ @pytest.fixture -def c(revm_env, get_contract): +def c(env, get_contract): with open("examples/crowdfund.vy") as f: contract_code = f.read() - return get_contract(contract_code, *[revm_env.accounts[1], 50, 60]) + return get_contract(contract_code, *[env.accounts[1], 50, 60]) -def test_crowdfund_example(c, revm_env): - a0, a1, a2, a3, a4, a5, a6 = revm_env.accounts[:7] +def test_crowdfund_example(c, env): + a0, a1, a2, a3, a4, a5, a6 = env.accounts[:7] c.participate(transact={"value": 5}) - revm_env.mine(1) + env.mine() # make sure auction has started assert c.timelimit() == 60 - assert c.deadline() - revm_env.get_block("latest").timestamp == 59 - assert revm_env.get_block("latest").timestamp < c.deadline() # expired - assert revm_env.get_balance(c.address) < c.goal() # not reached + assert c.deadline() - env.get_block("latest").timestamp == 59 + assert env.get_block("latest").timestamp < c.deadline() # expired + assert env.get_balance(c.address) < c.goal() # not reached c.participate(transact={"value": 49}) # assert c.reached() - pre_bal = revm_env.get_balance(a1) - revm_env.mine(100) - assert revm_env.get_block("latest").timestamp > c.deadline() # expired + pre_bal = env.get_balance(a1) + env.mine(100) + assert env.get_block("latest").timestamp > c.deadline() # expired c.finalize(transact={}) - post_bal = revm_env.get_balance(a1) + post_bal = env.get_balance(a1) assert post_bal - pre_bal == 54 -def test_crowdfund_example2(c, revm_env, tx_failed): - a0, a1, a2, a3, a4, a5, a6 = revm_env.accounts[:7] - for i, a in enumerate(revm_env.accounts[3:7]): - revm_env.set_balance(a, i + 1) +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(transact={"value": 1, "from": a3}) c.participate(transact={"value": 2, "from": a4}) @@ -38,10 +38,10 @@ def test_crowdfund_example2(c, revm_env, tx_failed): c.participate(transact={"value": 4, "from": a6}) assert c.timelimit() == 60 - revm_env.mine(100) + env.mine(100) # assert c.expired() # assert not c.reached() - pre_bals = [revm_env.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}) @@ -50,5 +50,5 @@ def test_crowdfund_example2(c, revm_env, tx_failed): c.refund(transact={"from": a4}) c.refund(transact={"from": a5}) c.refund(transact={"from": a6}) - post_bals = [revm_env.get_balance(x) for x in [a3, a4, a5, 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 7fbbcf68d8..c9c995b462 100644 --- a/tests/functional/examples/factory/test_factory.py +++ b/tests/functional/examples/factory/test_factory.py @@ -17,14 +17,14 @@ def create_token(): @pytest.fixture -def create_exchange(revm_env, 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": revm_env.accounts[0]}) + exchange.initialize(transact={"from": env.accounts[0]}) return exchange return create_exchange @@ -49,8 +49,8 @@ def factory(get_contract, optimize, experimental_codegen): return get_contract(code, keccak(hexstr=exchange_deployed_bytecode)) -def test_exchange(revm_env, factory, create_token, create_exchange): - a = revm_env.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() 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 dd18587ea4..9dfab7a79a 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 @@ -32,8 +32,8 @@ def test_initial_state(market_maker): assert market_maker.owner() is None -def test_initiate(revm_env, market_maker, erc20, tx_failed): - a0 = revm_env.accounts[0] +def test_initiate(env, market_maker, erc20, tx_failed): + a0 = env.accounts[0] ether, ethers = to_wei(1, "ether"), to_wei(2, "ether") erc20.approve(market_maker.address, ethers, transact={}) market_maker.initiate(erc20.address, ether, transact={"value": ethers}) @@ -49,8 +49,8 @@ def test_initiate(revm_env, market_maker, erc20, tx_failed): market_maker.initiate(erc20.address, ether, transact={"value": ethers}) -def test_eth_to_tokens(revm_env, market_maker, erc20): - a1 = revm_env.accounts[1] +def test_eth_to_tokens(env, market_maker, erc20): + a1 = env.accounts[1] erc20.approve(market_maker.address, to_wei(2, "ether"), transact={}) market_maker.initiate(erc20.address, to_wei(1, "ether"), transact={"value": to_wei(2, "ether")}) assert erc20.balanceOf(market_maker.address) == to_wei(1, "ether") @@ -58,7 +58,7 @@ def test_eth_to_tokens(revm_env, market_maker, erc20): assert market_maker.totalTokenQty() == to_wei(1, "ether") assert market_maker.totalEthQty() == to_wei(2, "ether") - revm_env.set_balance(a1, 100) + env.set_balance(a1, 100) market_maker.ethToTokens(transact={"value": 100, "from": a1}) assert erc20.balanceOf(market_maker.address) == 999999999999999950 assert erc20.balanceOf(a1) == 50 @@ -66,41 +66,41 @@ def test_eth_to_tokens(revm_env, market_maker, erc20): assert market_maker.totalEthQty() == 2000000000000000100 -def test_tokens_to_eth(revm_env, market_maker, erc20): - a1 = revm_env.accounts[1] +def test_tokens_to_eth(env, market_maker, erc20): + a1 = env.accounts[1] a1_balance_before = to_wei(2, "ether") - revm_env.set_balance(a1, a1_balance_before) + env.set_balance(a1, a1_balance_before) erc20.transfer(a1, to_wei(2, "ether"), transact={}) erc20.approve(market_maker.address, to_wei(2, "ether"), transact={"from": a1}) market_maker.initiate( erc20.address, to_wei(1, "ether"), transact={"value": to_wei(2, "ether"), "from": a1} ) - assert revm_env.get_balance(market_maker.address) == to_wei(2, "ether") + assert env.get_balance(market_maker.address) == to_wei(2, "ether") # sent 2 eth, with initiate. - assert revm_env.get_balance(a1) == a1_balance_before - to_wei(2, "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, to_wei(1, "ether"), transact={"from": a1}) market_maker.tokensToEth(to_wei(1, "ether"), transact={"from": a1}) # 1 eth less in market. - assert revm_env.get_balance(market_maker.address) == to_wei(1, "ether") + assert env.get_balance(market_maker.address) == to_wei(1, "ether") # got 1 eth back, for trade. - assert revm_env.get_balance(a1) == a1_balance_before - to_wei(1, "ether") + assert env.get_balance(a1) == a1_balance_before - to_wei(1, "ether") # Tokens increased by 1 assert market_maker.totalTokenQty() == to_wei(2, "ether") assert market_maker.totalEthQty() == to_wei(1, "ether") -def test_owner_withdraw(revm_env, market_maker, erc20, tx_failed): - a0, a1 = revm_env.accounts[:2] - a0_balance_before = revm_env.get_balance(a0) +def test_owner_withdraw(env, market_maker, erc20, tx_failed): + a0, a1 = env.accounts[:2] + a0_balance_before = env.get_balance(a0) # Approve 2 eth transfers. erc20.approve(market_maker.address, to_wei(2, "ether"), transact={}) # Initiate market with 2 eth value. market_maker.initiate(erc20.address, to_wei(1, "ether"), transact={"value": to_wei(2, "ether")}) # 2 eth was sent to market_maker contract. - assert revm_env.get_balance(a0) == a0_balance_before - 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 - to_wei(1, "ether") @@ -108,5 +108,5 @@ def test_owner_withdraw(revm_env, market_maker, erc20, tx_failed): with tx_failed(): market_maker.ownerWithdraw(transact={"from": a1}) market_maker.ownerWithdraw(transact={}) - assert revm_env.get_balance(a0) == a0_balance_before # Eth balance restored. + 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 331e30bd4b..97cf6058df 100644 --- a/tests/functional/examples/name_registry/test_name_registry.py +++ b/tests/functional/examples/name_registry/test_name_registry.py @@ -1,5 +1,5 @@ -def test_name_registry(revm_env, get_contract, tx_failed): - a0, a1 = revm_env.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) 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 af84d24c65..6fe78c27ac 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 @@ -23,16 +23,16 @@ def contract_code(get_contract): @pytest.fixture -def get_balance(revm_env): +def get_balance(env): def get_balance(): - a0, a1 = revm_env.accounts[:2] + a0, a1 = env.accounts[:2] # balance of a1 = seller, a2 = buyer - return revm_env.get_balance(a0), revm_env.get_balance(a1) + return env.get_balance(a0), env.get_balance(a1) return get_balance -def test_initial_state(revm_env, 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) @@ -40,7 +40,7 @@ def test_initial_state(revm_env, tx_failed, get_contract, get_balance, contract_ a0_pre_bal, a1_pre_bal = get_balance() c = get_contract(contract_code, value_in_eth=2) # Check that the seller is set correctly - assert c.seller() == revm_env.accounts[0] + assert c.seller() == env.accounts[0] # Check if item value is set correctly (Half of deposit) assert c.value() == to_wei(1, "ether") # Check if unlocked() works correctly after initialization @@ -49,10 +49,10 @@ def test_initial_state(revm_env, tx_failed, get_contract, get_balance, contract_ assert get_balance() == ((a0_pre_bal - to_wei(2, "ether")), a1_pre_bal) -def test_abort(revm_env, tx_failed, get_balance, get_contract, contract_code): - a0, a1, a2 = revm_env.accounts[:3] - revm_env.set_balance(a1, 10**18) - revm_env.set_balance(a2, 10**18) +def test_abort(env, tx_failed, get_balance, get_contract, contract_code): + a0, a1, a2 = env.accounts[:3] + env.set_balance(a1, 10**18) + env.set_balance(a2, 10**18) a0_pre_bal, a1_pre_bal = get_balance() c = get_contract(contract_code, value=to_wei(2, "ether")) @@ -70,10 +70,10 @@ def test_abort(revm_env, tx_failed, get_balance, get_contract, contract_code): c.abort(transact={"from": a0}) -def test_purchase(revm_env, get_contract, tx_failed, get_balance, contract_code): - a0, a1, a2, a3 = revm_env.accounts[:4] - revm_env.set_balance(a0, 10**18) - revm_env.set_balance(a1, 10**18) +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) @@ -95,10 +95,10 @@ def test_purchase(revm_env, get_contract, tx_failed, get_balance, contract_code) c.purchase(transact={"value": 2, "from": a3}) -def test_received(revm_env, get_contract, tx_failed, get_balance, contract_code): - a0, a1 = revm_env.accounts[:2] - revm_env.set_balance(a0, 10**18) - revm_env.set_balance(a1, 10**18) +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 @@ -115,7 +115,7 @@ def test_received(revm_env, get_contract, tx_failed, get_balance, contract_code) assert get_balance() == (init_bal_a0 + 1, init_bal_a1 - 1) -def test_received_reentrancy(revm_env, 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: @@ -150,15 +150,15 @@ def __default__(): """ - a0, a1 = revm_env.accounts[:2] - revm_env.set_balance(a1, 10**18) + a0, a1 = env.accounts[:2] + env.set_balance(a1, 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 = ( - revm_env.get_balance(a0), - revm_env.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": a1, "gas": 100000}) @@ -170,7 +170,7 @@ def __default__(): buyer_contract.start_received(transact={"from": a1, "gas": 100000}) # Final check if everything worked. 1 value has been transferred - assert revm_env.get_balance(a0), revm_env.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 880c073bde..8815aeb2d7 100644 --- a/tests/functional/examples/storage/test_advanced_storage.py +++ b/tests/functional/examples/storage/test_advanced_storage.py @@ -5,7 +5,7 @@ @pytest.fixture -def adv_storage_contract(revm_env, get_contract): +def adv_storage_contract(env, get_contract): with open("examples/storage/advanced_storage.vy") as f: contract_code = f.read() # Pass constructor variables directly to the contract @@ -18,9 +18,9 @@ def test_initial_state(adv_storage_contract): assert adv_storage_contract.storedData() == INITIAL_VALUE -def test_failed_transactions(revm_env, adv_storage_contract, tx_failed): - k1 = revm_env.accounts[1] - revm_env.set_balance(k1, 10**18) +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(): @@ -45,8 +45,8 @@ def test_failed_transactions(revm_env, adv_storage_contract, tx_failed): adv_storage_contract.set(1, 2, transact={"from": k1}) -def test_events(revm_env, adv_storage_contract, get_logs): - k1, k2 = revm_env.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}) logs1 = get_logs(tx1, adv_storage_contract, "DataChange") diff --git a/tests/functional/examples/storage/test_storage.py b/tests/functional/examples/storage/test_storage.py index bcb3f6a665..d891eea3c1 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(revm_env, get_contract): +def storage_contract(env, get_contract): with open("examples/storage/storage.vy") as f: contract_code = f.read() # Pass constructor variables directly to the contract @@ -17,8 +17,8 @@ def test_initial_state(storage_contract): assert storage_contract.storedData() == INITIAL_VALUE -def test_set(revm_env, storage_contract): - k0 = revm_env.accounts[0] +def test_set(env, storage_contract): + k0 = env.accounts[0] # Let k0 try to set the value to 10 storage_contract.set(10, transact={"from": k0}) diff --git a/tests/functional/examples/tokens/test_erc1155.py b/tests/functional/examples/tokens/test_erc1155.py index cf1d926653..71236de914 100644 --- a/tests/functional/examples/tokens/test_erc1155.py +++ b/tests/functional/examples/tokens/test_erc1155.py @@ -29,8 +29,8 @@ @pytest.fixture -def erc1155(get_contract, revm_env, tx_failed): - owner, a1, a2, a3, a4, a5 = revm_env.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]) @@ -82,8 +82,8 @@ def test_initial_state(erc1155): assert erc1155.supportsInterface(ERC1155_INTERFACE_ID_METADATA) -def test_pause(erc1155, revm_env, tx_failed): - owner, a1, a2, a3, a4, a5 = revm_env.accounts[0:6] +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() @@ -146,8 +146,8 @@ def test_pause(erc1155, revm_env, tx_failed): erc1155.unpause() -def test_contractURI(erc1155, revm_env, tx_failed): - owner, a1, a2, a3, a4, a5 = revm_env.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(): @@ -163,8 +163,8 @@ def test_contractURI(erc1155, revm_env, tx_failed): erc1155.setContractURI(CONTRACT_METADATA_URI) -def test_URI(erc1155, revm_env, tx_failed): - owner, a1, a2, a3, a4, a5 = revm_env.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}) @@ -183,8 +183,8 @@ def test_URI(erc1155, revm_env, tx_failed): assert erc1155.uri(0) == CONTRACT_DYNURI + str(0) + ".json" -def test_safeTransferFrom_balanceOf_single(erc1155, revm_env, tx_failed): - owner, a1, a2, a3, a4, a5 = revm_env.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(): @@ -217,16 +217,16 @@ def test_safeTransferFrom_balanceOf_single(erc1155, revm_env, tx_failed): # TODO: mint 20 NFTs [1:20] and check the balance for each -def test_mintBatch_balanceOf(erc1155, revm_env, tx_failed): # test_mint_batch - owner, a1, a2, a3, a4, a5 = revm_env.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, revm_env, tx_failed): # test_mint_batch - owner, a1, a2, a3, a4, a5 = revm_env.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 @@ -285,8 +285,8 @@ def test_safeBatchTransferFrom_balanceOf_batch(erc1155, revm_env, tx_failed): # assert erc1155.balanceOf(a1, 21) == 0 -def test_mint_one_burn_one(erc1155, revm_env, tx_failed): - owner, a1, a2, a3, a4, a5 = revm_env.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}) @@ -311,8 +311,8 @@ def test_mint_one_burn_one(erc1155, revm_env, tx_failed): assert erc1155.balanceOf(owner, 25) == 0 -def test_mint_batch_burn_batch(erc1155, revm_env, tx_failed): - owner, a1, a2, a3, a4, a5 = revm_env.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 @@ -346,8 +346,8 @@ def test_mint_batch_burn_batch(erc1155, revm_env, tx_failed): assert erc1155.balanceOfBatch([a3, a3, a3], [1, 2, 3]) == [0, 0, 0] -def test_approval_functions(erc1155, revm_env, tx_failed): # test_mint_batch - owner, a1, a2, a3, a4, a5 = revm_env.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}) @@ -366,8 +366,8 @@ def test_approval_functions(erc1155, revm_env, tx_failed): # test_mint_batch erc1155.setApprovalForAll(owner, a5, False) -def test_max_batch_size_violation(erc1155, revm_env, tx_failed): - owner, a1, a2, a3, a4, a5 = revm_env.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 = [] @@ -382,8 +382,8 @@ def test_max_batch_size_violation(erc1155, revm_env, tx_failed): # Transferring back and forth -def test_ownership_functions(erc1155, revm_env, tx_failed): - owner, a1, a2, a3, a4, a5 = revm_env.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 @@ -405,8 +405,8 @@ def test_ownership_functions(erc1155, revm_env, tx_failed): assert erc1155.owner() == a1 -def test_renounce_ownership(erc1155, revm_env, tx_failed): - owner, a1, a2, a3, a4, a5 = revm_env.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(): diff --git a/tests/functional/examples/tokens/test_erc20.py b/tests/functional/examples/tokens/test_erc20.py index 2c0a9dca97..3dcae2538e 100644 --- a/tests/functional/examples/tokens/test_erc20.py +++ b/tests/functional/examples/tokens/test_erc20.py @@ -13,14 +13,14 @@ @pytest.fixture -def c(get_contract, revm_env): +def c(get_contract, env): with open("examples/tokens/ERC20.vy") as f: code = f.read() return get_contract(code, *[TOKEN_NAME, TOKEN_SYMBOL, TOKEN_DECIMALS, TOKEN_INITIAL_SUPPLY]) @pytest.fixture -def c_bad(get_contract, revm_env): +def c_bad(get_contract, env): # Bad contract is used for overflow checks on totalSupply corrupted with open("examples/tokens/ERC20.vy") as f: code = f.read() @@ -41,8 +41,8 @@ def get_log_args(tx_hash, c, event_name): return get_log_args -def test_initial_state(c, revm_env): - a1, a2, a3 = revm_env.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 @@ -59,8 +59,8 @@ def test_initial_state(c, revm_env): assert c.allowance(a2, a3) == 0 -def test_mint_and_burn(c, revm_env, tx_failed): - minter, a1, a2 = revm_env.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 @@ -91,9 +91,9 @@ def test_mint_and_burn(c, revm_env, tx_failed): c.mint(ZERO_ADDRESS, 1, transact={"from": minter}) -def test_totalSupply(c, revm_env, tx_failed): +def test_totalSupply(c, env, tx_failed): # Test total supply initially, after mint, between two burns, and after failed burn - minter, a1 = revm_env.accounts[0:2] + minter, a1 = env.accounts[0:2] assert c.totalSupply() == 0 c.mint(a1, 2, transact={"from": minter}) assert c.totalSupply() == 2 @@ -109,8 +109,8 @@ def test_totalSupply(c, revm_env, tx_failed): assert c.totalSupply() == 0 -def test_transfer(c, revm_env, tx_failed): - minter, a1, a2 = revm_env.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}) @@ -128,8 +128,8 @@ def test_transfer(c, revm_env, tx_failed): c.transfer(a1, 0, transact={"from": a2}) -def test_maxInts(c, revm_env, tx_failed): - minter, a1, a2 = revm_env.accounts[0:3] +def test_maxInts(c, env, tx_failed): + minter, a1, a2 = env.accounts[0:3] c.mint(a1, MAX_UINT256, transact={"from": minter}) assert c.balanceOf(a1) == MAX_UINT256 with tx_failed(): @@ -164,8 +164,8 @@ def test_maxInts(c, revm_env, tx_failed): assert c.balanceOf(a1) == 0 -def test_transferFrom_and_Allowance(c, revm_env, tx_failed): - minter, a1, a2, a3 = revm_env.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}) @@ -217,8 +217,8 @@ def test_transferFrom_and_Allowance(c, revm_env, tx_failed): assert c.allowance(a2, a1) == 5 -def test_burnFrom_and_Allowance(c, revm_env, tx_failed): - minter, a1, a2, a3 = revm_env.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}) @@ -273,8 +273,8 @@ def test_burnFrom_and_Allowance(c, revm_env, tx_failed): c.burnFrom(ZERO_ADDRESS, 0, transact={"from": a1}) -def test_raw_logs(c, revm_env, get_log_args): - minter, a1, a2, a3 = revm_env.accounts[0:4] +def test_raw_logs(c, env, get_log_args): + minter, a1, a2, a3 = env.accounts[0:4] # Check that mint appropriately emits Transfer event args = get_log_args(c.mint(a1, 2, transact={"from": minter}), c, "Transfer") @@ -332,9 +332,9 @@ def test_raw_logs(c, revm_env, get_log_args): assert args.value == 0 -def test_bad_transfer(c_bad, revm_env, 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 = revm_env.accounts[0:3] + minter, a1, a2 = env.accounts[0:3] c_bad.mint(a1, MAX_UINT256, transact={"from": minter}) c_bad.mint(a2, 1, transact={"from": minter}) with tx_failed(): @@ -344,9 +344,9 @@ def test_bad_transfer(c_bad, revm_env, tx_failed): assert c_bad.balanceOf(a2) == MAX_UINT256 -def test_bad_burn(c_bad, revm_env, 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 = revm_env.accounts[0:2] + minter, a1 = env.accounts[0:2] assert c_bad.balanceOf(a1) == 0 c_bad.mint(a1, 2, transact={"from": minter}) assert c_bad.balanceOf(a1) == 2 @@ -354,9 +354,9 @@ def test_bad_burn(c_bad, revm_env, tx_failed): c_bad.burn(3, transact={"from": a1}) -def test_bad_transferFrom(c_bad, revm_env, 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 = revm_env.accounts[0:3] + minter, a1, a2 = env.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}) diff --git a/tests/functional/examples/tokens/test_erc4626.py b/tests/functional/examples/tokens/test_erc4626.py index b8fd7be819..ae4991f33e 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(revm_env, vault): - a = revm_env.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(revm_env, vault): assert vault.maxRedeem(a) == 2**256 - 1 -def test_preview_methods(revm_env, token, vault): - a = revm_env.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 diff --git a/tests/functional/examples/tokens/test_erc721.py b/tests/functional/examples/tokens/test_erc721.py index 81abb0cfab..8d44f31a7a 100644 --- a/tests/functional/examples/tokens/test_erc721.py +++ b/tests/functional/examples/tokens/test_erc721.py @@ -11,11 +11,11 @@ @pytest.fixture -def c(get_contract, revm_env): +def c(get_contract, env): with open("examples/tokens/ERC721.vy") as f: code = f.read() c = get_contract(code) - minter, someone, operator = revm_env.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}) @@ -24,7 +24,7 @@ def c(get_contract, revm_env): return c -def test_erc165(revm_env, c): +def test_erc165(env, c): # From EIP-165: # The source contract makes a STATICCALL to the destination address with input data: # 0x01ffc9a701ffc9a700000000000000000000000000000000000000000000000000000000 @@ -40,22 +40,22 @@ def test_erc165(revm_env, c): assert c.supportsInterface(ERC721_SIG) -def test_balanceOf(c, revm_env, tx_failed): - someone = revm_env.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, revm_env, tx_failed): - someone = revm_env.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, revm_env): - someone, operator = revm_env.accounts[1:3] +def test_getApproved(c, env): + someone, operator = env.accounts[1:3] assert c.getApproved(SOMEONE_TOKEN_IDS[0]) is None @@ -64,8 +64,8 @@ def test_getApproved(c, revm_env): assert c.getApproved(SOMEONE_TOKEN_IDS[0]) == operator -def test_isApprovedForAll(c, revm_env): - someone, operator = revm_env.accounts[1:3] +def test_isApprovedForAll(c, env): + someone, operator = env.accounts[1:3] assert c.isApprovedForAll(someone, operator) == 0 @@ -74,8 +74,8 @@ def test_isApprovedForAll(c, revm_env): assert c.isApprovedForAll(someone, operator) == 1 -def test_transferFrom_by_owner(c, revm_env, tx_failed, get_logs): - someone, operator = revm_env.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(): @@ -108,8 +108,8 @@ def test_transferFrom_by_owner(c, revm_env, tx_failed, get_logs): assert c.balanceOf(operator) == 2 -def test_transferFrom_by_approved(c, revm_env, get_logs): - someone, operator = revm_env.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}) @@ -127,8 +127,8 @@ def test_transferFrom_by_approved(c, revm_env, get_logs): assert c.balanceOf(operator) == 2 -def test_transferFrom_by_operator(c, revm_env, get_logs): - someone, operator = revm_env.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}) @@ -146,8 +146,8 @@ def test_transferFrom_by_operator(c, revm_env, get_logs): assert c.balanceOf(operator) == 2 -def test_safeTransferFrom_by_owner(c, revm_env, tx_failed, get_logs): - someone, operator = revm_env.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(): @@ -182,8 +182,8 @@ def test_safeTransferFrom_by_owner(c, revm_env, tx_failed, get_logs): assert c.balanceOf(operator) == 2 -def test_safeTransferFrom_by_approved(c, revm_env, get_logs): - someone, operator = revm_env.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}) @@ -203,8 +203,8 @@ def test_safeTransferFrom_by_approved(c, revm_env, get_logs): assert c.balanceOf(operator) == 2 -def test_safeTransferFrom_by_operator(c, revm_env, get_logs): - someone, operator = revm_env.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}) @@ -224,8 +224,8 @@ def test_safeTransferFrom_by_operator(c, revm_env, get_logs): assert c.balanceOf(operator) == 2 -def test_safeTransferFrom_to_contract(c, revm_env, tx_failed, get_logs, get_contract): - someone = revm_env.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(): @@ -260,8 +260,8 @@ def onERC721Received( assert c.balanceOf(receiver.address) == 1 -def test_approve(c, revm_env, tx_failed, get_logs): - someone, operator = revm_env.accounts[1:3] +def test_approve(c, env, tx_failed, get_logs): + someone, operator = env.accounts[1:3] # approve myself with tx_failed(): @@ -285,8 +285,8 @@ def test_approve(c, revm_env, tx_failed, get_logs): assert args.token_id == SOMEONE_TOKEN_IDS[0] -def test_setApprovalForAll(c, revm_env, tx_failed, get_logs): - someone, operator = revm_env.accounts[1:3] +def test_setApprovalForAll(c, env, tx_failed, get_logs): + someone, operator = env.accounts[1:3] approved = True # setApprovalForAll myself @@ -303,8 +303,8 @@ def test_setApprovalForAll(c, revm_env, tx_failed, get_logs): assert args.approved == approved -def test_mint(c, revm_env, tx_failed, get_logs): - minter, someone = revm_env.accounts[:2] +def test_mint(c, env, tx_failed, get_logs): + minter, someone = env.accounts[:2] # mint by non-minter with tx_failed(): @@ -327,8 +327,8 @@ def test_mint(c, revm_env, tx_failed, get_logs): assert c.balanceOf(someone) == 4 -def test_burn(c, revm_env, tx_failed, get_logs): - someone, operator = revm_env.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(): diff --git a/tests/functional/examples/voting/test_ballot.py b/tests/functional/examples/voting/test_ballot.py index 326e3ef7c0..4776d76184 100644 --- a/tests/functional/examples/voting/test_ballot.py +++ b/tests/functional/examples/voting/test_ballot.py @@ -14,8 +14,8 @@ def c(get_contract): z0 = "0x0000000000000000000000000000000000000000" -def test_initial_state(revm_env, c): - a0 = revm_env.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 @@ -33,8 +33,8 @@ def test_initial_state(revm_env, c): assert c.voters(z0)[0] == 0 # Voter.weight -def test_give_the_right_to_vote(revm_env, c, tx_failed): - a0, a1, a2, a3, a4, a5 = revm_env.accounts[:6] +def test_give_the_right_to_vote(env, c, tx_failed): + a0, a1, a2, a3, a4, a5 = env.accounts[:6] c.giveRightToVote(a1, transact={}) # Check voter given right has weight of 1 assert c.voters(a1)[0] == 1 # Voter.weight @@ -62,8 +62,8 @@ def test_give_the_right_to_vote(revm_env, c, tx_failed): assert c.voters(a5)[0] == 1 # Voter.weight -def test_forward_weight(revm_env, c): - a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = revm_env.accounts[:10] +def test_forward_weight(env, c): + a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = env.accounts[:10] c.giveRightToVote(a0, transact={}) c.giveRightToVote(a1, transact={}) c.giveRightToVote(a2, transact={}) @@ -128,8 +128,8 @@ def test_forward_weight(revm_env, c): assert c.voters(a9)[0] == 10 # Voter.weight -def test_block_short_cycle(revm_env, c, tx_failed): - a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = revm_env.accounts[:10] +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, transact={}) c.giveRightToVote(a1, transact={}) c.giveRightToVote(a2, transact={}) @@ -152,8 +152,8 @@ def test_block_short_cycle(revm_env, c, tx_failed): # but this is something the frontend should prevent for user friendliness -def test_delegate(revm_env, c, tx_failed): - a0, a1, a2, a3, a4, a5, a6 = revm_env.accounts[:7] +def test_delegate(env, c, tx_failed): + a0, a1, a2, a3, a4, a5, a6 = env.accounts[:7] c.giveRightToVote(a0, transact={}) c.giveRightToVote(a1, transact={}) c.giveRightToVote(a2, transact={}) @@ -184,8 +184,8 @@ def test_delegate(revm_env, c, tx_failed): assert c.voters(a0)[0] == 3 # Voter.weight -def test_vote(revm_env, c, tx_failed): - a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = revm_env.accounts[:10] +def test_vote(env, c, tx_failed): + a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = env.accounts[:10] c.giveRightToVote(a0, transact={}) c.giveRightToVote(a1, transact={}) c.giveRightToVote(a2, transact={}) @@ -217,8 +217,8 @@ def test_vote(revm_env, c, tx_failed): c.vote(2, transact={"from": a7}) -def test_winning_proposal(revm_env, c): - a0, a1, a2 = revm_env.accounts[:3] +def test_winning_proposal(env, c): + a0, a1, a2 = env.accounts[:3] c.giveRightToVote(a0, transact={}) c.giveRightToVote(a1, transact={}) c.giveRightToVote(a2, transact={}) @@ -233,8 +233,8 @@ def test_winning_proposal(revm_env, c): assert c.winningProposal() == 1 -def test_winner_namer(revm_env, c): - a0, a1, a2 = revm_env.accounts[:3] +def test_winner_namer(env, c): + a0, a1, a2 = env.accounts[:3] c.giveRightToVote(a0, transact={}) c.giveRightToVote(a1, transact={}) c.giveRightToVote(a2, transact={}) diff --git a/tests/functional/examples/wallet/test_wallet.py b/tests/functional/examples/wallet/test_wallet.py index 4be6bf3624..d58aae66d2 100644 --- a/tests/functional/examples/wallet/test_wallet.py +++ b/tests/functional/examples/wallet/test_wallet.py @@ -6,13 +6,13 @@ @pytest.fixture -def c(revm_env, get_contract): - a0, a1, a2, a3, a4, a5, a6 = revm_env.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]) - revm_env.execute_code(c.address, value=10**17) + env.execute_code(c.address, value=10**17) return c @@ -29,10 +29,10 @@ def _sign(seq, to, value, data, key): return _sign -def test_approve(revm_env, c, tx_failed, sign): - a0, a1, a2, a3, a4, a5, a6 = revm_env.accounts[:7] - k0, k1, k2, k3, k4, k5, k6, k7 = revm_env._keys[:8] - revm_env.set_balance(a1, 10**18) +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 = to_checksum_address(to) @@ -68,8 +68,8 @@ def pack_and_sign(seq, *args): print("Basic tests passed") -def test_javascript_signatures(revm_env, get_contract, keccak): - a3 = revm_env.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 = [ @@ -108,7 +108,7 @@ def test_javascript_signatures(revm_env, get_contract, keccak): owners = [to_checksum_address(x) for x in accounts + [a3, zero_address, zero_address]] x2 = get_contract(f.read(), *[owners, 2]) - revm_env.execute_code(x2.address, value=10**17) + env.execute_code(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 diff --git a/tests/functional/syntax/test_address_code.py b/tests/functional/syntax/test_address_code.py index fb6ac78eaa..b726d54824 100644 --- a/tests/functional/syntax/test_address_code.py +++ b/tests/functional/syntax/test_address_code.py @@ -17,8 +17,8 @@ @pytest.fixture -def deploy_precompiled_contract(revm_env): - return lambda: revm_env.deploy(json.loads(PRECOMPILED_ABI), HexBytes(PRECOMPILED_BYTECODE)) +def deploy_precompiled_contract(env): + return lambda: env.deploy(json.loads(PRECOMPILED_ABI), HexBytes(PRECOMPILED_BYTECODE)) @pytest.mark.parametrize( diff --git a/tests/functional/syntax/test_chainid.py b/tests/functional/syntax/test_chainid.py index e0281395ba..258712bda6 100644 --- a/tests/functional/syntax/test_chainid.py +++ b/tests/functional/syntax/test_chainid.py @@ -81,7 +81,7 @@ def test_chain_success(good_code): assert compiler.compile_code(good_code) is not None -def test_chainid_operation(get_contract_with_gas_estimation, revm_env): +def test_chainid_operation(get_contract_with_gas_estimation, env): code = """ @external @view @@ -89,4 +89,4 @@ def get_chain_id() -> uint256: return chain.id """ c = get_contract_with_gas_estimation(code) - assert c.get_chain_id() == revm_env.default_chain_id + assert c.get_chain_id() == env.default_chain_id diff --git a/tests/functional/syntax/test_msg_data.py b/tests/functional/syntax/test_msg_data.py index 8ddf9b3e19..c935bdd4c5 100644 --- a/tests/functional/syntax/test_msg_data.py +++ b/tests/functional/syntax/test_msg_data.py @@ -77,7 +77,7 @@ def foo() -> (uint256, Bytes[4], uint256): assert contract.foo() == (2**256 - 1, bytes(keccak(b"foo()")[:4]), 2**256 - 1) -def test_assignment_to_storage(revm_env, get_contract, keccak): +def test_assignment_to_storage(env, get_contract, keccak): code = """ cache: public(Bytes[4]) diff --git a/tests/functional/syntax/test_self_balance.py b/tests/functional/syntax/test_self_balance.py index 39dfa55ce0..2f0e144fc4 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(revm_env, get_contract_with_gas_estimation): +def test_self_balance(env, get_contract_with_gas_estimation): code = """ @external @view @@ -18,9 +18,9 @@ def __default__(): assert "SELFBALANCE" in opcodes c = get_contract_with_gas_estimation(code) - revm_env.set_balance(revm_env.deployer, 1337) - revm_env.execute_code(**{"to": c.address, "value": 1337}) + env.set_balance(env.deployer, 1337) + env.execute_code(**{"to": c.address, "value": 1337}) assert c.get_balance() == 1337 - assert revm_env.get_balance(c.address) == 1337 - assert revm_env.get_balance(revm_env.deployer) == 0 + assert env.get_balance(c.address) == 1337 + assert env.get_balance(env.deployer) == 0 diff --git a/tests/revm/abi_contract.py b/tests/revm/abi_contract.py index 0e07461728..73a060db9f 100644 --- a/tests/revm/abi_contract.py +++ b/tests/revm/abi_contract.py @@ -26,6 +26,8 @@ class ABILog: address: ChecksumAddress args: tuple event: str + topics: list[str] + raw_data: bytes class ABILogTopic: @@ -73,8 +75,13 @@ def __str__(self) -> str: return repr(self) def parse(self, log: Log) -> ABILog: + topics, raw_data = log.data return ABILog( - address=to_checksum_address(log.address), args=self._parse_args(log), event=self.name + address=to_checksum_address(log.address), + args=self._parse_args(log), + event=self.name, + topics=topics, + raw_data=raw_data, ) @cached_property diff --git a/tests/revm/revm_env.py b/tests/revm/revm_env.py index b684a83e05..e55203a99f 100644 --- a/tests/revm/revm_env.py +++ b/tests/revm/revm_env.py @@ -24,7 +24,7 @@ class RevmEnv: def __init__(self, gas_limit: int, tracing=False, block_number=1, evm_version="latest") -> None: self.gas_limit = gas_limit - self.evm = EVM( + self._evm = EVM( gas_limit=gas_limit, tracing=tracing, spec_id=evm_version, @@ -36,11 +36,11 @@ def __init__(self, gas_limit: int, tracing=False, block_number=1, evm_version="l @contextmanager def anchor(self): - snapshot_id = self.evm.snapshot() + snapshot_id = self._evm.snapshot() try: yield finally: - self.evm.revert(snapshot_id) + self._evm.revert(snapshot_id) @contextmanager def sender(self, address: HexAddress): @@ -52,10 +52,10 @@ def sender(self, address: HexAddress): self.deployer = original_deployer def get_balance(self, address: HexAddress) -> int: - return self.evm.get_balance(address) + return self._evm.get_balance(address) def set_balance(self, address: HexAddress, value: int): - self.evm.set_balance(address, value) + self._evm.set_balance(address, value) @property def accounts(self) -> list[HexAddress]: @@ -63,14 +63,25 @@ def accounts(self) -> list[HexAddress]: @property def block_number(self) -> int: - return self.evm.env.block.number + return self._evm.env.block.number def get_block(self, _=None) -> BlockEnv: - return self.evm.env.block + return self._evm.env.block def contract(self, abi, bytecode) -> "ABIContract": return ABIContractFactory.from_abi_dict(abi).at(self, bytecode) + @property + def last_result(self) -> dict: + result = self._evm.result + return { + "gas_refunded": result.gas_refunded, + "gas_used": result.gas_used, + "is_halt": result.is_halt, + "is_success": result.is_success, + "logs": result.logs, + } + def execute_code( self, to: HexAddress, @@ -86,7 +97,7 @@ def execute_code( transact = transact or {} data = data if isinstance(data, bytes) else bytes.fromhex(data.removeprefix("0x")) try: - output = self.evm.message_call( + output = self._evm.message_call( to=to, caller=transact.get("from", sender) or self.deployer, calldata=data, @@ -107,7 +118,7 @@ def execute_code( raise TransactionFailed(*e.args) from e def get_code(self, address: HexAddress): - return HexBytes(self.evm.basic(address).code.rstrip(b"\0")) + return HexBytes(self._evm.basic(address).code.rstrip(b"\0")) def register_contract(self, address: HexAddress, contract: "ABIContract"): self.contracts[address] = contract @@ -187,9 +198,7 @@ def deploy(self, abi: list[dict], bytecode: bytes, value=0, *args, **kwargs): initcode += abi_encode(ctor.signature, ctor._merge_kwargs(*args, **kwargs)) try: - deployed_at = self.evm.deploy( - deployer=self.deployer, code=initcode, value=value, _abi=json.dumps(abi) - ) + deployed_at = self._evm.deploy(deployer=self.deployer, code=initcode, value=value) except RuntimeError as e: raise TransactionFailed(*e.args) from e @@ -199,15 +208,15 @@ def deploy(self, abi: list[dict], bytecode: bytes, value=0, *args, **kwargs): def mine(self, num_blocks=1, time_delta: int | None = None) -> None: if time_delta is None: time_delta = num_blocks - self.evm.set_block_env( + self._evm.set_block_env( BlockEnv( - number=self.evm.env.block.number + num_blocks, - coinbase=self.evm.env.block.coinbase, - timestamp=self.evm.env.block.timestamp + time_delta, - difficulty=self.evm.env.block.difficulty, - prevrandao=self.evm.env.block.prevrandao, - basefee=self.evm.env.block.basefee, - gas_limit=self.evm.env.block.gas_limit, - excess_blob_gas=self.evm.env.block.excess_blob_gas, + number=self._evm.env.block.number + num_blocks, + coinbase=self._evm.env.block.coinbase, + timestamp=self._evm.env.block.timestamp + time_delta, + difficulty=self._evm.env.block.difficulty, + prevrandao=self._evm.env.block.prevrandao, + basefee=self._evm.env.block.basefee, + gas_limit=self._evm.env.block.gas_limit, + excess_blob_gas=self._evm.env.block.excess_blob_gas, ) ) diff --git a/tests/unit/compiler/test_bytecode_runtime.py b/tests/unit/compiler/test_bytecode_runtime.py index 7d0a302fab..213adce017 100644 --- a/tests/unit/compiler/test_bytecode_runtime.py +++ b/tests/unit/compiler/test_bytecode_runtime.py @@ -124,9 +124,9 @@ 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, revm_env): +def test_bytecode_signature_deployed(code, get_contract, env): c = get_contract(code) - deployed_code = revm_env.get_code(c.address) + deployed_code = env.get_code(c.address) metadata = _parse_cbor_metadata(c.bytecode) runtime_len, data_section_lengths, immutables_len, compiler = metadata From 883e1004b50a7c7069797cfca13e4e5866c02e12 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 3 Apr 2024 14:28:42 +0200 Subject: [PATCH 33/87] Rename package --- tests/conftest.py | 4 ++-- tests/{revm => evm_backends}/__init__.py | 0 tests/{revm => evm_backends}/abi.py | 0 tests/{revm => evm_backends}/abi_contract.py | 2 +- tests/{revm => evm_backends}/revm_env.py | 4 ++-- 5 files changed, 5 insertions(+), 5 deletions(-) rename tests/{revm => evm_backends}/__init__.py (100%) rename tests/{revm => evm_backends}/abi.py (100%) rename tests/{revm => evm_backends}/abi_contract.py (99%) rename tests/{revm => evm_backends}/revm_env.py (98%) diff --git a/tests/conftest.py b/tests/conftest.py index a5c1ef2fa8..1513dc1a7d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -16,8 +16,8 @@ from web3.providers.eth_tester import EthereumTesterProvider import vyper.evm.opcodes as evm_opcodes -from tests.revm.abi_contract import ABIContract -from tests.revm.revm_env import RevmEnv +from tests.evm_backends.abi_contract import ABIContract +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 diff --git a/tests/revm/__init__.py b/tests/evm_backends/__init__.py similarity index 100% rename from tests/revm/__init__.py rename to tests/evm_backends/__init__.py diff --git a/tests/revm/abi.py b/tests/evm_backends/abi.py similarity index 100% rename from tests/revm/abi.py rename to tests/evm_backends/abi.py diff --git a/tests/revm/abi_contract.py b/tests/evm_backends/abi_contract.py similarity index 99% rename from tests/revm/abi_contract.py rename to tests/evm_backends/abi_contract.py index 73a060db9f..3348feb8d6 100644 --- a/tests/revm/abi_contract.py +++ b/tests/evm_backends/abi_contract.py @@ -16,7 +16,7 @@ from .abi import abi_decode, abi_encode, is_abi_encodable if TYPE_CHECKING: - from tests.revm.revm_env import RevmEnv + from tests.evm_backends.revm_env import RevmEnv @dataclass diff --git a/tests/revm/revm_env.py b/tests/evm_backends/revm_env.py similarity index 98% rename from tests/revm/revm_env.py rename to tests/evm_backends/revm_env.py index e55203a99f..0a426880dd 100644 --- a/tests/revm/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -11,8 +11,8 @@ from hexbytes import HexBytes from pyrevm import EVM, BlockEnv, Env -from tests.revm.abi import abi_decode, abi_encode -from tests.revm.abi_contract import ABIContract, ABIContractFactory, ABIFunction +from tests.evm_backends.abi import abi_decode, abi_encode +from tests.evm_backends.abi_contract import ABIContract, ABIContractFactory, ABIFunction from vyper.ast.grammar import parse_vyper_source from vyper.compiler import CompilerData, Settings, compile_code from vyper.compiler.settings import OptimizationLevel From 34073363568eee906db7d639f66f3e66e66abd5c Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 3 Apr 2024 20:58:46 +0200 Subject: [PATCH 34/87] Implement tests with py-evm --- .github/workflows/test.yml | 4 +- tests/conftest.py | 21 +- tests/evm_backends/abi_contract.py | 7 +- tests/evm_backends/base_env.py | 116 +++++++++++ tests/evm_backends/pyevm_env.py | 188 ++++++++++++++++++ tests/evm_backends/revm_env.py | 174 ++++------------ .../builtins/codegen/test_create_functions.py | 8 +- .../test_self_call_struct.py | 10 +- .../test_block_number.py | 2 +- .../environment_variables/test_blockhash.py | 2 +- .../codegen/features/test_assert.py | 28 ++- .../features/test_assert_unreachable.py | 14 +- .../codegen/features/test_logging.py | 5 +- .../codegen/integration/test_crowdfund.py | 16 +- .../codegen/integration/test_eth_tester.py | 0 .../examples/auctions/test_blind_auction.py | 14 +- .../auctions/test_simple_open_auction.py | 10 +- .../crowdfund/test_crowdfund_example.py | 12 +- 18 files changed, 416 insertions(+), 215 deletions(-) create mode 100644 tests/evm_backends/base_env.py create mode 100644 tests/evm_backends/pyevm_env.py create mode 100644 tests/functional/codegen/integration/test_eth_tester.py diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5791db78ff..b318fc7aaa 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -72,7 +72,7 @@ jobs: evm-version: [shanghai] experimental-codegen: [false] memorymock: [false] - evm-backend: [revm] + evm-backend: [revm, py-evm] # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#expanding-or-adding-matrix-configurations include: @@ -81,7 +81,7 @@ jobs: debug: false opt-mode: gas evm-version: london - evm-backend: revm + evm-backend: [revm, py-evm] - python-version: ["3.11", "311"] debug: false diff --git a/tests/conftest.py b/tests/conftest.py index 1513dc1a7d..5b313f2672 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,6 +7,7 @@ import pytest import web3.exceptions from eth_tester import EthereumTester, PyEVMBackend +from eth_tester.backends.pyevm.main import get_default_account_keys from eth_tester.exceptions import TransactionFailed from eth_utils import setup_DEBUG2_logging from eth_utils.toolz import compose @@ -17,6 +18,7 @@ import vyper.evm.opcodes as evm_opcodes from tests.evm_backends.abi_contract import ABIContract +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 @@ -131,7 +133,7 @@ def _xfail(*args, **kwargs): @pytest.fixture(scope="session", autouse=True) def evm_version(pytestconfig, evm_backend): evm_version_str = pytestconfig.getoption("evm_version") - if evm_backend != "PyevmEnv": + if evm_backend != PyEvmEnv: # revm uses this fixture to set the evm version return evm_version_str @@ -148,7 +150,7 @@ def evm_version(pytestconfig, evm_backend): @pytest.fixture(scope="session", autouse=True) def evm_backend(pytestconfig): backend_str = pytestconfig.getoption("evm_backend") - return {"py-evm": "PyevmEnv", "revm": RevmEnv}[backend_str] + return {"py-evm": PyEvmEnv, "revm": RevmEnv}[backend_str] @pytest.fixture @@ -227,7 +229,12 @@ def gas_limit(): @pytest.fixture(scope="module") def initial_balance(): - return 0 + return 0 # default balance for the deployer account + + +@pytest.fixture(scope="module") +def get_initial_accounts(): + return @pytest.fixture(scope="module") @@ -240,7 +247,13 @@ def tester(gas_limit): @pytest.fixture(scope="module") def env(gas_limit, initial_balance, evm_version, evm_backend): - env = evm_backend(gas_limit, tracing=False, block_number=1, evm_version=evm_version) + env = evm_backend( + gas_limit=gas_limit, + tracing=False, + block_number=1, + evm_version=evm_version, + account_keys=get_default_account_keys(), + ) env.set_balance(env.deployer, initial_balance) return env diff --git a/tests/evm_backends/abi_contract.py b/tests/evm_backends/abi_contract.py index 3348feb8d6..1d9fa1c707 100644 --- a/tests/evm_backends/abi_contract.py +++ b/tests/evm_backends/abi_contract.py @@ -26,7 +26,7 @@ class ABILog: address: ChecksumAddress args: tuple event: str - topics: list[str] + topics: list[bytes] raw_data: bytes @@ -208,7 +208,6 @@ def __call__(self, *args, value=0, gas=None, sender=None, transact=None, call=No value=value, gas=gas, is_modifying=self.is_mutable, - contract=self.contract, transact={**(transact or {}), **(call or {})}, ) @@ -406,7 +405,7 @@ def at(self, env, address: HexAddress) -> ABIContract: """ Create an ABI contract object for a deployed contract at `address`. """ - contract = ABIContract( + return ABIContract( env, self._name, self._abi, @@ -416,8 +415,6 @@ def at(self, env, address: HexAddress) -> ABIContract: address, self._filename, ) - env.register_contract(address, contract) - return contract def _abi_from_json(abi: dict) -> str: diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py new file mode 100644 index 0000000000..bccaddee22 --- /dev/null +++ b/tests/evm_backends/base_env.py @@ -0,0 +1,116 @@ +import json +from typing import Callable, Tuple + +from eth_keys.datatypes import PrivateKey +from eth_tester.exceptions import TransactionFailed +from eth_utils import to_checksum_address + +from tests.evm_backends.abi import abi_decode, abi_encode +from tests.evm_backends.abi_contract import ABIContract, ABIContractFactory, ABIFunction +from vyper.ast.grammar import parse_vyper_source +from vyper.compiler import CompilerData, Settings, compile_code +from vyper.compiler.settings import OptimizationLevel +from vyper.utils import ERC5202_PREFIX, method_id + + +class BaseEnv: + 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, initcode: bytes, value: int, gas: int = None) -> str: + raise NotImplementedError + + def deploy(self, abi: list[dict], bytecode: bytes, value=0, *args, **kwargs): + 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 += abi_encode(ctor.signature, ctor._merge_kwargs(*args, **kwargs)) + + try: + deployed_at = self._deploy(initcode, value) + except RuntimeError as e: + raise TransactionFailed(*e.args) from e + + address = to_checksum_address(deployed_at) + return factory.at(self, address) + + def deploy_source( + self, + source_code: str, + optimize: OptimizationLevel, + output_formats: dict[str, Callable[[CompilerData], str]], + *args, + override_opt_level=None, + input_bundle=None, + evm_version=None, + **kwargs, + ) -> ABIContract: + abi, bytecode = self._compile( + source_code, optimize, output_formats, override_opt_level, input_bundle, evm_version + ) + value = ( + kwargs.pop("value", 0) or kwargs.pop("value_in_eth", 0) * 10**18 + ) # Handle deploying with an eth value. + + return self.deploy(abi, bytecode, value, *args, **kwargs) + + def _compile( + self, source_code, optimize, output_formats, override_opt_level, input_bundle, evm_version + ) -> Tuple[list[dict], bytes]: + out = compile_code( + source_code, + # test that all output formats can get generated + output_formats=output_formats, + settings=Settings(evm_version=evm_version, optimize=override_opt_level or optimize), + 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")) + + def deploy_blueprint( + self, + source_code, + optimize, + output_formats, + *args, + override_opt_level=None, + input_bundle=None, + evm_version=None, + initcode_prefix=ERC5202_PREFIX, + ): + abi, bytecode = self._compile( + source_code, optimize, output_formats, override_opt_level, input_bundle, evm_version + ) + bytecode = bytes.fromhex(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 = [] # just a constructor + value = 0 + deployer = self.deploy(deployer_abi, deploy_bytecode, value, *args) + + def factory(address): + return ABIContractFactory.from_abi_dict(abi).at(self, address) + + return deployer, factory + + def _parse_revert(self, output_bytes, error, gas_used): + # Check EIP838 error, with ABI Error(string) + prefix = "execution reverted" + if output_bytes[:4] == method_id("Error(string)"): + (msg,) = abi_decode("(string)", output_bytes[4:]) + raise TransactionFailed(f"{prefix}: {msg}", gas_used) from error + + raise TransactionFailed(f"{prefix}: 0x{output_bytes.hex()}", gas_used) from error diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py new file mode 100644 index 0000000000..de9279993b --- /dev/null +++ b/tests/evm_backends/pyevm_env.py @@ -0,0 +1,188 @@ +from collections import namedtuple +from contextlib import contextmanager +from typing import cast + +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 +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_tester.exceptions import TransactionFailed +from eth_tester.utils.address import generate_contract_address +from eth_typing import Address +from eth_utils import to_checksum_address + +from tests.evm_backends.base_env import BaseEnv + + +class PyEvmEnv(BaseEnv): + default_chain_id = 1 + INVALID_OPCODE_ERROR = "Invalid opcode" + + def __init__( + self, + gas_limit: int, + account_keys: list[PrivateKey], + tracing=False, + block_number=1, + evm_version="mainnet", + ) -> None: + super().__init__(gas_limit, account_keys) + + 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 = None + + @cached_property + def _state(self) -> StateAPI: + return self._vm.state + + @cached_property + def _vm(self): + return self._chain.get_vm() + + @contextmanager + def anchor(self): + snapshot_id = self._state.snapshot() + try: + yield + finally: + self._state.revert(snapshot_id) + + @contextmanager + def sender(self, address: str): + original_deployer = self.deployer + self.deployer = address + try: + yield + finally: + self.deployer = original_deployer + + 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 accounts(self) -> list[str]: + return [key.public_key.to_checksum_address() for key in self._keys] + + @property + def block_number(self) -> int: + return self._state.block_number + + @property + def timestamp(self) -> int | None: + return self._state.timestamp + + @property + def last_result(self) -> dict | None: + result = self._last_computation + return result and { + "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 execute_code( + self, + to: str, + sender: str | None = None, + data: bytes | str = b"", + value: int | None = None, + gas: int | None = None, + is_modifying: bool = True, + transact: dict | None = None, + ): + transact = transact or {} + data = data if isinstance(data, bytes) else bytes.fromhex(data.removeprefix("0x")) + sender = _addr(transact.get("from", sender) or self.deployer) + 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=transact.get("value", value) or 0, + gas=transact.get("gas", gas) or self.gas_limit, + is_static=not is_modifying, + ), + transaction_context=BaseTransactionContext( + origin=sender, gas_price=transact.get("gasPrice", 0) + ), + ) + self._check_computation(computation) + return computation.output + + def _check_computation(self, computation): + self._last_computation = computation + if computation.is_error: + if isinstance(computation.error, Revert): + (output,) = computation.error.args + self._parse_revert( + output, computation.error, gas_used=self._last_computation.get_gas_used() + ) + + raise TransactionFailed(*computation.error.args) from computation.error + + def get_code(self, address: str): + return self._state.get_code(_addr(address)) + + def time_travel(self, num_blocks=1, time_delta: int | None = None) -> None: + if time_delta is None: + time_delta = num_blocks + context = cast(ExecutionContext, self._state.execution_context) + context._block_number += num_blocks + context._timestamp += time_delta + + def _deploy(self, initcode: bytes, value: int, gas: int = None) -> str: + sender = _addr(self.deployer) + target_address = self._generate_address(sender) + + 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=initcode, + data=b"", + gas=gas or self.gas_limit, + create_address=target_address, + ), + transaction_context=BaseTransactionContext(origin=sender, gas_price=0), + ) + self._check_computation(computation) + return "0x" + target_address.hex() + + def _generate_address(self, sender: Address) -> bytes: + nonce = self._state.get_nonce(sender) + self._state.increment_nonce(sender) + return generate_contract_address(sender, nonce) + + +Log = namedtuple("Log", ["address", "topics", "data"]) + + +def _parse_log_entries(result): + for address, topics, data in result.get_log_entries(): + topics = [t.to_bytes(32, "big") for t in topics] + yield Log(to_checksum_address(address), topics, (topics, data)) + + +def _addr(address: str) -> Address: + return Address(bytes.fromhex(address.removeprefix("0x"))) diff --git a/tests/evm_backends/revm_env.py b/tests/evm_backends/revm_env.py index 0a426880dd..37b685d254 100644 --- a/tests/evm_backends/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -1,38 +1,31 @@ -import json import re from contextlib import contextmanager -from typing import Callable, Tuple from eth_keys.datatypes import PrivateKey -from eth_tester.backends.pyevm.main import get_default_account_keys from eth_tester.exceptions import TransactionFailed -from eth_typing import HexAddress -from eth_utils import to_checksum_address -from hexbytes import HexBytes from pyrevm import EVM, BlockEnv, Env -from tests.evm_backends.abi import abi_decode, abi_encode -from tests.evm_backends.abi_contract import ABIContract, ABIContractFactory, ABIFunction -from vyper.ast.grammar import parse_vyper_source -from vyper.compiler import CompilerData, Settings, compile_code -from vyper.compiler.settings import OptimizationLevel -from vyper.utils import ERC5202_PREFIX, method_id +from tests.evm_backends.base_env import BaseEnv -class RevmEnv: - default_chain_id = 1 +class RevmEnv(BaseEnv): + INVALID_OPCODE_ERROR = "InvalidFEOpcode" - def __init__(self, gas_limit: int, tracing=False, block_number=1, evm_version="latest") -> None: - self.gas_limit = gas_limit + def __init__( + self, + gas_limit: int, + account_keys: list[PrivateKey], + tracing=False, + block_number=1, + evm_version="latest", + ) -> 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)), ) - self.contracts: dict[HexAddress, ABIContract] = {} - self._keys: list[PrivateKey] = get_default_account_keys() - self.deployer = self._keys[0].public_key.to_checksum_address() @contextmanager def anchor(self): @@ -43,7 +36,7 @@ def anchor(self): self._evm.revert(snapshot_id) @contextmanager - def sender(self, address: HexAddress): + def sender(self, address: str): original_deployer = self.deployer self.deployer = address try: @@ -51,48 +44,43 @@ def sender(self, address: HexAddress): finally: self.deployer = original_deployer - def get_balance(self, address: HexAddress) -> int: + def get_balance(self, address: str) -> int: return self._evm.get_balance(address) - def set_balance(self, address: HexAddress, value: int): + def set_balance(self, address: str, value: int): self._evm.set_balance(address, value) @property - def accounts(self) -> list[HexAddress]: + def accounts(self) -> list[str]: return [key.public_key.to_checksum_address() for key in self._keys] @property def block_number(self) -> int: return self._evm.env.block.number - def get_block(self, _=None) -> BlockEnv: - return self._evm.env.block - - def contract(self, abi, bytecode) -> "ABIContract": - return ABIContractFactory.from_abi_dict(abi).at(self, bytecode) + @property + def timestamp(self) -> int | None: + return self._evm.env.block.timestamp @property - def last_result(self) -> dict: + def last_result(self) -> dict | None: result = self._evm.result - return { + return result and { "gas_refunded": result.gas_refunded, "gas_used": result.gas_used, - "is_halt": result.is_halt, "is_success": result.is_success, "logs": result.logs, } def execute_code( self, - to: HexAddress, - sender: HexAddress | None = None, + to: str, + sender: str | None = None, data: bytes | str = b"", value: int | None = None, gas: int | None = None, is_modifying: bool = True, - # TODO: Remove the following. They are not used. transact: dict | None = None, - contract=None, ): transact = transact or {} data = data if isinstance(data, bytes) else bytes.fromhex(data.removeprefix("0x")) @@ -111,112 +99,28 @@ def execute_code( 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) - # Check EIP838 error, with ABI Error(string) - if output_bytes[:4] == method_id("Error(string)"): - (msg,) = abi_decode("(string)", output_bytes[4:]) - raise TransactionFailed(f"execution reverted: {msg}", gas_used) from e + self._parse_revert(output_bytes, e, gas_used) raise TransactionFailed(*e.args) from e - def get_code(self, address: HexAddress): - return HexBytes(self._evm.basic(address).code.rstrip(b"\0")) - - def register_contract(self, address: HexAddress, contract: "ABIContract"): - self.contracts[address] = contract - - def deploy_source( - self, - source_code: str, - optimize: OptimizationLevel, - output_formats: dict[str, Callable[[CompilerData], str]], - *args, - override_opt_level=None, - input_bundle=None, - evm_version=None, - **kwargs, - ) -> ABIContract: - abi, bytecode = self._compile( - source_code, optimize, output_formats, override_opt_level, input_bundle, evm_version - ) - value = ( - kwargs.pop("value", 0) or kwargs.pop("value_in_eth", 0) * 10**18 - ) # Handle deploying with an eth value. - - return self.deploy(abi, bytecode, value, *args, **kwargs) - - def _compile( - self, source_code, optimize, output_formats, override_opt_level, input_bundle, evm_version - ) -> Tuple[list[dict], HexBytes]: - out = compile_code( - source_code, - # test that all output formats can get generated - output_formats=output_formats, - settings=Settings(evm_version=evm_version, optimize=override_opt_level or optimize), - 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"], HexBytes(out["bytecode"]) - - def deploy_blueprint( - self, - source_code, - optimize, - output_formats, - *args, - override_opt_level=None, - input_bundle=None, - evm_version=None, - initcode_prefix=ERC5202_PREFIX, - ): - abi, bytecode = self._compile( - source_code, optimize, output_formats, override_opt_level, input_bundle, evm_version - ) - bytecode = HexBytes(initcode_prefix + 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 = deploy_preamble + bytecode + def get_code(self, address: str): + return self._evm.basic(address).code.rstrip(b"\0") - deployer_abi = [] # just a constructor - value = 0 - deployer = self.deploy(deployer_abi, deploy_bytecode, value, *args) - - def factory(address): - return ABIContractFactory.from_abi_dict(abi).at(self, address) - - return deployer, factory - - def deploy(self, abi: list[dict], bytecode: bytes, value=0, *args, **kwargs): - 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 += abi_encode(ctor.signature, ctor._merge_kwargs(*args, **kwargs)) - - try: - deployed_at = self._evm.deploy(deployer=self.deployer, code=initcode, value=value) - except RuntimeError as e: - raise TransactionFailed(*e.args) from e - - address = to_checksum_address(deployed_at) - return factory.at(self, address) - - def mine(self, num_blocks=1, time_delta: int | None = None) -> None: + def time_travel(self, num_blocks=1, time_delta: int | None = None) -> None: if time_delta is None: time_delta = num_blocks + block = self._evm.env.block self._evm.set_block_env( BlockEnv( - number=self._evm.env.block.number + num_blocks, - coinbase=self._evm.env.block.coinbase, - timestamp=self._evm.env.block.timestamp + time_delta, - difficulty=self._evm.env.block.difficulty, - prevrandao=self._evm.env.block.prevrandao, - basefee=self._evm.env.block.basefee, - gas_limit=self._evm.env.block.gas_limit, - excess_blob_gas=self._evm.env.block.excess_blob_gas, + number=block.number + num_blocks, + coinbase=block.coinbase, + timestamp=block.timestamp + time_delta, + difficulty=block.difficulty, + prevrandao=block.prevrandao, + basefee=block.basefee, + gas_limit=block.gas_limit, + excess_blob_gas=block.excess_blob_gas, ) ) + + def _deploy(self, initcode: bytes, value: int, gas: int = None) -> str: + return self._evm.deploy(deployer=self.deployer, code=initcode, value=value, gas=gas) diff --git a/tests/functional/builtins/codegen/test_create_functions.py b/tests/functional/builtins/codegen/test_create_functions.py index df9fb43a3b..5a13fc961f 100644 --- a/tests/functional/builtins/codegen/test_create_functions.py +++ b/tests/functional/builtins/codegen/test_create_functions.py @@ -134,13 +134,7 @@ def test(_salt: bytes32) -> address: # contract, and 0xfe7100 is ERC5202 magic @pytest.mark.parametrize("blueprint_prefix", [b"", b"\xfe", ERC5202_PREFIX]) def test_create_from_blueprint( - get_contract, - deploy_blueprint_for, - env, - keccak, - create2_address_of, - tx_failed, - blueprint_prefix, + get_contract, deploy_blueprint_for, env, keccak, create2_address_of, tx_failed, blueprint_prefix ): code = """ @external 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 a479665b59..167809916a 100644 --- a/tests/functional/codegen/calling_convention/test_self_call_struct.py +++ b/tests/functional/codegen/calling_convention/test_self_call_struct.py @@ -24,14 +24,8 @@ def wrap_get_my_struct_BROKEN(_e1: decimal) -> MyStruct: return self.get_my_struct(_e1, block.timestamp) """ c = get_contract(code) - assert c.wrap_get_my_struct_WORKING(Decimal("0.1")) == ( - Decimal("0.1"), - env.get_block().timestamp, - ) - assert c.wrap_get_my_struct_BROKEN(Decimal("0.1")) == ( - Decimal("0.1"), - env.get_block().timestamp, - ) + assert c.wrap_get_my_struct_WORKING(Decimal("0.1")) == (Decimal("0.1"), env.timestamp) + assert c.wrap_get_my_struct_BROKEN(Decimal("0.1")) == (Decimal("0.1"), env.timestamp) def test_call_to_self_struct_2(get_contract): diff --git a/tests/functional/codegen/environment_variables/test_block_number.py b/tests/functional/codegen/environment_variables/test_block_number.py index f91da1889a..277800b321 100644 --- a/tests/functional/codegen/environment_variables/test_block_number.py +++ b/tests/functional/codegen/environment_variables/test_block_number.py @@ -7,6 +7,6 @@ def block_number() -> uint256: c = get_contract_with_gas_estimation(block_number_code) assert c.block_number() == 1 - env.mine() + env.time_travel() c = env.deploy_source(block_number_code, optimize, output_formats) 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 6a6bb2358d..475a28fddd 100644 --- a/tests/functional/codegen/environment_variables/test_blockhash.py +++ b/tests/functional/codegen/environment_variables/test_blockhash.py @@ -22,7 +22,7 @@ def foo() -> bytes32: def test_too_old_blockhash(tx_failed, get_contract_with_gas_estimation, env): - env.mine(257) + env.time_travel(257) code = """ @external def get_50_blockhash() -> bytes32: diff --git a/tests/functional/codegen/features/test_assert.py b/tests/functional/codegen/features/test_assert.py index 939fdc5c75..ee90fda9f7 100644 --- a/tests/functional/codegen/features/test_assert.py +++ b/tests/functional/codegen/features/test_assert.py @@ -1,11 +1,10 @@ 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 _fixup_err_str(e_info): + return e_info.value.args[0].replace("execution reverted: ", "") def test_assert_refund(env, get_contract_with_gas_estimation, tx_failed): @@ -21,7 +20,7 @@ def foo(): c.foo(transact={"gas": gas_sent, "gasPrice": 10}) assert env.last_result["gas_used"] < gas_sent, "Gas refund not received" - assert not env.last_result["is_success"] and not env.last_result["is_halt"] + assert env.last_result["is_success"] is False def test_assert_reason(env, get_contract_with_gas_estimation, tx_failed, memory_mocker): @@ -58,33 +57,30 @@ def test5(reason_str: String[32]): c = get_contract_with_gas_estimation(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 = [ diff --git a/tests/functional/codegen/features/test_assert_unreachable.py b/tests/functional/codegen/features/test_assert_unreachable.py index e3ec4946b4..2706cd04b1 100644 --- a/tests/functional/codegen/features/test_assert_unreachable.py +++ b/tests/functional/codegen/features/test_assert_unreachable.py @@ -19,7 +19,7 @@ def foo(): c.foo(transact={"gas": gas_sent, "gasPrice": 10}) assert env.last_result["gas_used"] == gas_sent # Drains all gains sent - assert not env.last_result["is_success"] and env.last_result["is_halt"] + assert env.last_result["is_success"] is False def test_basic_unreachable(env, get_contract, tx_failed): @@ -35,11 +35,11 @@ def foo(val: int128) -> bool: assert c.foo(2) is True - with tx_failed(exc_text="InvalidFEOpcode"): + with tx_failed(exc_text=(env.INVALID_OPCODE_ERROR)): c.foo(1) - with tx_failed(exc_text="InvalidFEOpcode"): + with tx_failed(exc_text=(env.INVALID_OPCODE_ERROR)): c.foo(-1) - with tx_failed(exc_text="InvalidFEOpcode"): + with tx_failed(exc_text=(env.INVALID_OPCODE_ERROR)): c.foo(-2) @@ -61,9 +61,9 @@ def foo(val: int128) -> int128: assert c.foo(33) == -123 - with tx_failed(exc_text="InvalidFEOpcode"): + with tx_failed(exc_text=env.INVALID_OPCODE_ERROR): c.foo(1) - with tx_failed(exc_text="InvalidFEOpcode"): + with tx_failed(exc_text=env.INVALID_OPCODE_ERROR): c.foo(-1) @@ -76,5 +76,5 @@ def foo(): c = get_contract(code) - with tx_failed(exc_text="InvalidFEOpcode"): + with tx_failed(exc_text=env.INVALID_OPCODE_ERROR): c.foo() diff --git a/tests/functional/codegen/features/test_logging.py b/tests/functional/codegen/features/test_logging.py index 6e65ec9ebe..65d8b506bd 100644 --- a/tests/functional/codegen/features/test_logging.py +++ b/tests/functional/codegen/features/test_logging.py @@ -272,7 +272,7 @@ def foo(): } # Event is decoded correctly - timestamp = env.get_block(env.block_number).timestamp + timestamp = env.timestamp logs = get_logs(tx_hash, c, "MyLog") assert logs[0].args.arg1 == [1, 2] @@ -417,7 +417,6 @@ def foo(): } # Event is decoded correctly - timestamp = env.get_block(env.block_number).timestamp logs = get_logs(tx_hash, c, "MyLog") args = logs[0].args assert args.arg1 == 123 @@ -425,7 +424,7 @@ def foo(): 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( diff --git a/tests/functional/codegen/integration/test_crowdfund.py b/tests/functional/codegen/integration/test_crowdfund.py index 1c05bd32c4..a010e7310c 100644 --- a/tests/functional/codegen/integration/test_crowdfund.py +++ b/tests/functional/codegen/integration/test_crowdfund.py @@ -1,5 +1,5 @@ # TODO: check, this is probably redundant with examples/test_crowdfund.py -def test_crowdfund(env, tester, get_contract): +def test_crowdfund(env, get_contract): crowdfund = """ struct Funder: @@ -67,7 +67,7 @@ def refund(): env.set_balance(a, 10**10) c = get_contract(crowdfund, *[a1, 50, 60]) - start_timestamp = env.get_block(env.block_number).timestamp + start_timestamp = env.timestamp c.participate(transact={"value": 5}) assert c.timelimit() == 60 @@ -77,7 +77,7 @@ def refund(): c.participate(transact={"value": 49}) assert c.reached() pre_bal = env.get_balance(a1) - env.mine(100) + env.time_travel(100) assert c.expired() c.finalize(transact={}) post_bal = env.get_balance(a1) @@ -88,7 +88,7 @@ def refund(): c.participate(transact={"value": 2, "from": a4}) c.participate(transact={"value": 3, "from": a5}) c.participate(transact={"value": 4, "from": a6}) - env.mine(100) + env.time_travel(100) assert c.expired() assert not c.reached() pre_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] @@ -97,7 +97,7 @@ def refund(): assert [y - x for x, y in zip(pre_bals, post_bals)] == [1, 2, 3, 4] -def test_crowdfund2(env, tester, get_contract): +def test_crowdfund2(env, get_contract): crowdfund2 = """ struct Funder: sender: address @@ -162,7 +162,7 @@ def refund(): c = get_contract(crowdfund2, *[a1, 50, 60]) c.participate(transact={"value": 5}) - env.mine() # make sure auction has started + env.time_travel() # make sure auction has started assert c.timelimit() == 60 assert c.deadline() - c.block_timestamp() == 59 assert not c.expired() @@ -170,7 +170,7 @@ def refund(): c.participate(transact={"value": 49}) assert c.reached() pre_bal = env.get_balance(a1) - env.mine(100) + env.time_travel(100) assert c.expired() c.finalize(transact={}) post_bal = env.get_balance(a1) @@ -181,7 +181,7 @@ def refund(): c.participate(transact={"value": 2, "from": a4}) c.participate(transact={"value": 3, "from": a5}) c.participate(transact={"value": 4, "from": a6}) - env.mine(100) + env.time_travel(100) assert c.expired() assert not c.reached() pre_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] diff --git a/tests/functional/codegen/integration/test_eth_tester.py b/tests/functional/codegen/integration/test_eth_tester.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/functional/examples/auctions/test_blind_auction.py b/tests/functional/examples/auctions/test_blind_auction.py index 1f482adea0..5fc339ee35 100644 --- a/tests/functional/examples/auctions/test_blind_auction.py +++ b/tests/functional/examples/auctions/test_blind_auction.py @@ -22,7 +22,7 @@ def test_initial_state(env, auction_contract): # Check beneficiary is correct assert auction_contract.beneficiary() == env.deployer # Check that bidding end time is correct - assert auction_contract.biddingEnd() == env.get_block("latest").timestamp + BIDDING_TIME + 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 @@ -37,7 +37,7 @@ def test_late_bid(env, auction_contract, tx_failed, keccak): k1 = env.accounts[1] # Move time forward past bidding end - env.mine(BIDDING_TIME + TEST_INCREMENT) + env.time_travel(BIDDING_TIME + TEST_INCREMENT) # Try to bid after bidding has ended with tx_failed(): @@ -107,7 +107,7 @@ def test_early_reval(env, auction_contract, tx_failed, keccak): ) # Move time slightly forward (still before bidding has ended) - env.mine(TEST_INCREMENT) + env.time_travel(TEST_INCREMENT) # Try to reveal early _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -146,7 +146,7 @@ def test_late_reveal(env, auction_contract, tx_failed, keccak): ) # Move time forward past bidding _and_ reveal time - env.mine(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) + env.time_travel(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) # Try to reveal late _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -179,7 +179,7 @@ def test_double_end(env, auction_contract, tx_failed): k0 = env.deployer # Move time forward past bidding and reveal end - env.mine(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) + env.time_travel(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) # First auction end should succeed auction_contract.auctionEnd(transact={"value": 0, "from": k0}) @@ -281,7 +281,7 @@ def test_blind_auction(env, initial_balance, auction_contract, keccak): ################################################################### # Move time forward past bidding end (still within reveal end) - env.mine(BIDDING_TIME + TEST_INCREMENT) + env.time_travel(BIDDING_TIME + TEST_INCREMENT) # Reveal k1 bids _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -347,7 +347,7 @@ def test_blind_auction(env, initial_balance, auction_contract, keccak): ################################################################### # Move time forward past bidding and reveal end - env.mine(REVEAL_TIME) + env.time_travel(REVEAL_TIME) # End the auction balance_before_end = env.get_balance(k0) diff --git a/tests/functional/examples/auctions/test_simple_open_auction.py b/tests/functional/examples/auctions/test_simple_open_auction.py index 9bf79cdae2..92fa2efed3 100644 --- a/tests/functional/examples/auctions/test_simple_open_auction.py +++ b/tests/functional/examples/auctions/test_simple_open_auction.py @@ -5,7 +5,7 @@ @pytest.fixture def auction_start(env): - return env.get_block("latest").timestamp + 1 + return env.timestamp + 1 @pytest.fixture @@ -33,12 +33,12 @@ def test_initial_state(env, auction_contract, auction_start): # Check highest bid is 0 assert auction_contract.highestBid() == 0 # Check end time is more than current block timestamp - assert auction_contract.auctionEnd() >= env.get_block("latest").timestamp + assert auction_contract.auctionEnd() >= env.timestamp def test_bid(env, auction_contract, tx_failed): k1, k2, k3, k4, k5 = env.accounts[:5] - env.mine() # make sure auction has started + env.time_travel() # make sure auction has started # Bidder cannot bid 0 with tx_failed(): @@ -83,7 +83,7 @@ def test_bid(env, auction_contract, tx_failed): def test_end_auction(env, auction_contract, tx_failed): k1, k2, k3, k4, k5 = env.accounts[:5] - env.mine() # make sure auction has started + env.time_travel() # make sure auction has started # Fails if auction end time has not been reached with tx_failed(): @@ -92,7 +92,7 @@ def test_end_auction(env, auction_contract, tx_failed): auction_contract.bid(transact={"value": 1 * 10**10, "from": k2}) # Move block timestamp forward to reach auction end time # tester.time_travel(tester.get_block_by_number('latest')['timestamp'] + EXPIRY) - env.mine(EXPIRY) + env.time_travel(EXPIRY) balance_before_end = env.get_balance(k1) auction_contract.endAuction(transact={"from": k2}) balance_after_end = env.get_balance(k1) diff --git a/tests/functional/examples/crowdfund/test_crowdfund_example.py b/tests/functional/examples/crowdfund/test_crowdfund_example.py index 3855174679..0cd3c08b98 100644 --- a/tests/functional/examples/crowdfund/test_crowdfund_example.py +++ b/tests/functional/examples/crowdfund/test_crowdfund_example.py @@ -11,17 +11,17 @@ def c(env, get_contract): def test_crowdfund_example(c, env): a0, a1, a2, a3, a4, a5, a6 = env.accounts[:7] c.participate(transact={"value": 5}) - env.mine() # make sure auction has started + env.time_travel() # make sure auction has started assert c.timelimit() == 60 - assert c.deadline() - env.get_block("latest").timestamp == 59 - assert env.get_block("latest").timestamp < c.deadline() # expired + assert c.deadline() - env.timestamp == 59 + assert env.timestamp < c.deadline() # expired assert env.get_balance(c.address) < c.goal() # not reached c.participate(transact={"value": 49}) # assert c.reached() pre_bal = env.get_balance(a1) - env.mine(100) - assert env.get_block("latest").timestamp > c.deadline() # expired + env.time_travel(100) + assert env.timestamp > c.deadline() # expired c.finalize(transact={}) post_bal = env.get_balance(a1) assert post_bal - pre_bal == 54 @@ -38,7 +38,7 @@ def test_crowdfund_example2(c, env, tx_failed): c.participate(transact={"value": 4, "from": a6}) assert c.timelimit() == 60 - env.mine(100) + env.time_travel(100) # assert c.expired() # assert not c.reached() pre_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] From ac58bcd4076aad78da0493b5cd6509865253ea04 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Thu, 4 Apr 2024 08:37:39 +0200 Subject: [PATCH 35/87] Fix blueprint + InsufficientFunds --- .github/workflows/test.yml | 1 - tests/evm_backends/base_env.py | 2 +- tests/evm_backends/pyevm_env.py | 65 ++++++++++++++++++--------------- 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b318fc7aaa..f226a190f9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -81,7 +81,6 @@ jobs: debug: false opt-mode: gas evm-version: london - evm-backend: [revm, py-evm] - python-version: ["3.11", "311"] debug: false diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index bccaddee22..e7b9084f58 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -90,7 +90,7 @@ def deploy_blueprint( abi, bytecode = self._compile( source_code, optimize, output_formats, override_opt_level, input_bundle, evm_version ) - bytecode = bytes.fromhex(initcode_prefix + bytecode) + bytecode = initcode_prefix + bytecode bytecode_len = len(bytecode) bytecode_len_hex = hex(bytecode_len)[2:].rjust(4, "0") # prepend a quick deploy preamble diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index de9279993b..69ef003422 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -7,7 +7,7 @@ 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 +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 @@ -110,21 +110,25 @@ def execute_code( transact = transact or {} data = data if isinstance(data, bytes) else bytes.fromhex(data.removeprefix("0x")) sender = _addr(transact.get("from", sender) or self.deployer) - 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=transact.get("value", value) or 0, - gas=transact.get("gas", gas) or self.gas_limit, - is_static=not is_modifying, - ), - transaction_context=BaseTransactionContext( - origin=sender, gas_price=transact.get("gasPrice", 0) - ), - ) + 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=transact.get("value", value) or 0, + gas=transact.get("gas", gas) or self.gas_limit, + is_static=not is_modifying, + ), + transaction_context=BaseTransactionContext( + origin=sender, gas_price=transact.get("gasPrice", 0) + ), + ) + except VMError as e: + raise TransactionFailed(*e.args) from e + self._check_computation(computation) return computation.output @@ -153,19 +157,22 @@ def _deploy(self, initcode: bytes, value: int, gas: int = None) -> str: sender = _addr(self.deployer) target_address = self._generate_address(sender) - 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=initcode, - data=b"", - gas=gas or self.gas_limit, - create_address=target_address, - ), - transaction_context=BaseTransactionContext(origin=sender, gas_price=0), - ) + 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=initcode, + data=b"", + gas=gas or self.gas_limit, + create_address=target_address, + ), + transaction_context=BaseTransactionContext(origin=sender, gas_price=0), + ) + except VMError as e: + raise TransactionFailed(*e.args) from e self._check_computation(computation) return "0x" + target_address.hex() From c145c93e82e51d0e4ce6e224b40c156f668c06eb Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Thu, 4 Apr 2024 09:04:38 +0200 Subject: [PATCH 36/87] Delete some xfail for passing tests --- .github/workflows/test.yml | 1 + tests/functional/builtins/codegen/test_abi_decode.py | 4 +--- tests/functional/codegen/features/test_clampers.py | 2 -- tests/functional/codegen/features/test_constructor.py | 4 ---- tests/functional/codegen/features/test_immutable.py | 2 -- tests/functional/codegen/types/test_dynamic_array.py | 7 ------- tests/functional/examples/factory/test_factory.py | 9 ++++++--- 7 files changed, 8 insertions(+), 21 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f226a190f9..aee31beebb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -81,6 +81,7 @@ jobs: debug: false opt-mode: gas evm-version: london + evm-backend: revm - python-version: ["3.11", "311"] debug: false diff --git a/tests/functional/builtins/codegen/test_abi_decode.py b/tests/functional/builtins/codegen/test_abi_decode.py index e37ed32d5a..e276e03944 100644 --- a/tests/functional/builtins/codegen/test_abi_decode.py +++ b/tests/functional/builtins/codegen/test_abi_decode.py @@ -3,7 +3,7 @@ import pytest from eth.codecs import abi -from vyper.exceptions import ArgumentException, StackTooDeep, StructureException +from vyper.exceptions import ArgumentException, StructureException TEST_ADDR = "0x" + b"".join(chr(i).encode("utf-8") for i in range(20)).hex() @@ -194,7 +194,6 @@ def abi_decode(x: Bytes[{len}]) -> DynArray[DynArray[uint256, 3], 3]: @pytest.mark.parametrize("args", nested_3d_array_args) @pytest.mark.parametrize("unwrap_tuple", (True, False)) -@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_abi_decode_nested_dynarray2(get_contract, args, unwrap_tuple): if unwrap_tuple is True: encoded = abi.encode("(uint256[][][])", (args,)) @@ -272,7 +271,6 @@ def foo(bs: Bytes[160]) -> (uint256, DynArray[uint256, 3]): assert c.foo(encoded) == (2**256 - 1, bs) -@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_abi_decode_private_nested_dynarray(get_contract): code = """ bytez: DynArray[DynArray[DynArray[uint256, 3], 3], 3] diff --git a/tests/functional/codegen/features/test_clampers.py b/tests/functional/codegen/features/test_clampers.py index 7fbc0186db..630cc43d55 100644 --- a/tests/functional/codegen/features/test_clampers.py +++ b/tests/functional/codegen/features/test_clampers.py @@ -4,7 +4,6 @@ from eth.codecs import abi from eth_utils import keccak -from vyper.exceptions import StackTooDeep from vyper.utils import int_bounds @@ -507,7 +506,6 @@ def foo(b: DynArray[int128, 10]) -> DynArray[int128, 10]: @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(env, get_contract, value): code = """ @external diff --git a/tests/functional/codegen/features/test_constructor.py b/tests/functional/codegen/features/test_constructor.py index b0f2f17960..17ae5d1c48 100644 --- a/tests/functional/codegen/features/test_constructor.py +++ b/tests/functional/codegen/features/test_constructor.py @@ -1,8 +1,6 @@ import pytest from eth.codecs.abi.exceptions import EncodeError -from vyper.exceptions import StackTooDeep - def test_init_argument_test(get_contract_with_gas_estimation): init_argument_test = """ @@ -165,7 +163,6 @@ def get_foo() -> uint256: assert c.get_foo() == 39 -@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_nested_dynamic_array_constructor_arg_2(env, get_contract_with_gas_estimation): code = """ foo: int128 @@ -211,7 +208,6 @@ def get_foo() -> DynArray[DynArray[uint256, 3], 3]: assert c.get_foo() == [[37, 41, 73], [37041, 41073, 73037], [146, 123, 148]] -@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_initialise_nested_dynamic_array_2(env, get_contract_with_gas_estimation): code = """ foo: DynArray[DynArray[DynArray[int128, 3], 3], 3] diff --git a/tests/functional/codegen/features/test_immutable.py b/tests/functional/codegen/features/test_immutable.py index 91378db8bc..0506e458ea 100644 --- a/tests/functional/codegen/features/test_immutable.py +++ b/tests/functional/codegen/features/test_immutable.py @@ -1,7 +1,6 @@ import pytest from vyper.compiler.settings import OptimizationLevel -from vyper.exceptions import StackTooDeep @pytest.mark.parametrize( @@ -199,7 +198,6 @@ def get_idx_two() -> uint256: assert c.get_idx_two() == expected_values[2][2] -@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_nested_dynarray_immutable(get_contract): code = """ my_list: immutable(DynArray[DynArray[DynArray[int128, 3], 3], 3]) diff --git a/tests/functional/codegen/types/test_dynamic_array.py b/tests/functional/codegen/types/test_dynamic_array.py index fb5614c31a..fe5cd787e7 100644 --- a/tests/functional/codegen/types/test_dynamic_array.py +++ b/tests/functional/codegen/types/test_dynamic_array.py @@ -9,7 +9,6 @@ ArrayIndexException, ImmutableViolation, OverflowException, - StackTooDeep, StateAccessViolation, TypeMismatch, ) @@ -62,7 +61,6 @@ def loo(x: DynArray[DynArray[int128, 2], 2]) -> int128: print("Passed list tests") -@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_string_list(get_contract): code = """ @external @@ -735,7 +733,6 @@ def test_array_decimal_return3() -> DynArray[DynArray[decimal, 2], 2]: assert c.test_array_decimal_return3() == [[1.0, 2.0], [3.0]] -@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_mult_list(get_contract_with_gas_estimation): code = """ nest3: DynArray[DynArray[DynArray[uint256, 2], 2], 2] @@ -1482,7 +1479,6 @@ def foo(x: int128) -> int128: assert c.foo(7) == 392 -@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_struct_of_lists(get_contract): code = """ struct Foo: @@ -1571,7 +1567,6 @@ def bar(x: int128) -> DynArray[int128, 3]: assert c.bar(7) == [7, 14] -@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_nested_struct_of_lists(get_contract, assert_compile_failed, optimize): code = """ struct nestedFoo: @@ -1702,8 +1697,6 @@ def __init__(): ], ) def test_empty_nested_dynarray(get_contract, typ, val, venom_xfail): - if val == [[[], []], []]: - venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") code = f""" @external def foo() -> {typ}: diff --git a/tests/functional/examples/factory/test_factory.py b/tests/functional/examples/factory/test_factory.py index c9c995b462..ca0b0f6f60 100644 --- a/tests/functional/examples/factory/test_factory.py +++ b/tests/functional/examples/factory/test_factory.py @@ -1,8 +1,8 @@ import pytest -from eth_utils import keccak import vyper from vyper.compiler.settings import Settings +from vyper.utils import keccak256 @pytest.fixture @@ -23,6 +23,7 @@ def create_exchange(env, get_contract): def create_exchange(token, factory): exchange = get_contract(code, *[token.address, factory.address]) + assert keccak256(env.get_code(exchange.address)).hex() == factory.exchange_codehash().hex() # NOTE: Must initialize exchange to register it with factory exchange.initialize(transact={"from": env.accounts[0]}) return exchange @@ -40,13 +41,15 @@ def factory(get_contract, optimize, experimental_codegen): output_formats=["bytecode_runtime"], settings=Settings(optimize=optimize, experimental_codegen=experimental_codegen), ) - exchange_deployed_bytecode = exchange_interface["bytecode_runtime"] + bytecode_runtime = exchange_interface["bytecode_runtime"] + exchange_deployed_bytecode = bytes.fromhex(bytecode_runtime.removeprefix("0x")) with open("examples/factory/Factory.vy") as f: code = f.read() # NOTE: We deploy the factory with the hash of the exchange's expected deployment bytecode - return get_contract(code, keccak(hexstr=exchange_deployed_bytecode)) + deployed = keccak256(exchange_deployed_bytecode) + return get_contract(code, deployed) def test_exchange(env, factory, create_token, create_exchange): From 9a4c5adea2c48fce64b48accefabd7213c2e24ce Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Thu, 4 Apr 2024 09:41:06 +0200 Subject: [PATCH 37/87] Cleanup conftest and eth_tester --- tests/conftest.py | 414 ++---------------- tests/evm_backends/pyevm_env.py | 18 +- tests/evm_backends/revm_env.py | 7 +- .../builtins/codegen/test_abi_encode.py | 1 - .../codegen/features/test_logging.py | 10 +- .../codegen/integration/test_eth_tester.py | 219 +++++++++ .../codegen/types/test_bytes_zero_padding.py | 3 +- tests/functional/conftest.py | 26 -- tests/unit/conftest.py | 26 -- 9 files changed, 291 insertions(+), 433 deletions(-) delete mode 100644 tests/functional/conftest.py delete mode 100644 tests/unit/conftest.py diff --git a/tests/conftest.py b/tests/conftest.py index 5b313f2672..b6c19ffa67 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,20 +1,10 @@ -import json -import logging from contextlib import contextmanager -from functools import wraps import hypothesis import pytest -import web3.exceptions -from eth_tester import EthereumTester, PyEVMBackend from eth_tester.backends.pyevm.main import get_default_account_keys from eth_tester.exceptions import TransactionFailed -from eth_utils import setup_DEBUG2_logging -from eth_utils.toolz import compose from hexbytes import HexBytes -from web3 import Web3 -from web3.contract import Contract -from web3.providers.eth_tester import EthereumTesterProvider import vyper.evm.opcodes as evm_opcodes from tests.evm_backends.abi_contract import ABIContract @@ -22,12 +12,11 @@ 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, _set_debug_mode +from vyper.compiler.settings import OptimizationLevel, _set_debug_mode 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"] @@ -42,19 +31,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", @@ -64,6 +40,7 @@ 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", @@ -132,19 +109,13 @@ def _xfail(*args, **kwargs): @pytest.fixture(scope="session", autouse=True) def evm_version(pytestconfig, evm_backend): - evm_version_str = pytestconfig.getoption("evm_version") - if evm_backend != PyEvmEnv: - # revm uses this fixture to set the evm version - return evm_version_str - - # note: we configure the evm version that we emit code for, - # but eth-tester is only configured with the latest mainnet - # version. - evm_opcodes.DEFAULT_EVM_VERSION = evm_version_str - # this should get overridden by anchor_evm_version, - # but set it anyway - evm_opcodes.active_evm_version = evm_opcodes.EVM_VERSIONS[evm_version_str] - return evm_version_str + version = pytestconfig.getoption("evm_version") + # note: configure the evm version that we emit code for. + # The env will read this fixture and apply the evm version there. + evm_opcodes.DEFAULT_EVM_VERSION = version + # This should get overridden by anchor_evm_version, but set it anyway + evm_opcodes.active_evm_version = evm_opcodes.EVM_VERSIONS[version] + return version @pytest.fixture(scope="session", autouse=True) @@ -153,6 +124,11 @@ def evm_backend(pytestconfig): return {"py-evm": PyEvmEnv, "revm": RevmEnv}[backend_str] +@pytest.fixture(scope="session", autouse=True) +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,26 +176,6 @@ 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 gas_limit(): # set absurdly high gas limit so that london basefee never adjusts @@ -233,23 +189,10 @@ def initial_balance(): @pytest.fixture(scope="module") -def get_initial_accounts(): - return - - -@pytest.fixture(scope="module") -def tester(gas_limit): - custom_genesis = PyEVMBackend._generate_genesis_params(overrides={"gas_limit": gas_limit}) - custom_genesis["base_fee_per_gas"] = 0 - backend = PyEVMBackend(genesis_parameters=custom_genesis) - return EthereumTester(backend=backend) - - -@pytest.fixture(scope="module") -def env(gas_limit, initial_balance, evm_version, evm_backend): +def env(gas_limit, initial_balance, evm_version, evm_backend, tracing): env = evm_backend( gas_limit=gas_limit, - tracing=False, + tracing=tracing, block_number=1, evm_version=evm_version, account_keys=get_default_account_keys(), @@ -258,319 +201,59 @@ def env(gas_limit, initial_balance, evm_version, evm_backend): return env -def zero_gas_price_strategy(web3, transaction_params=None): - return 0 # zero gas price makes testing simpler. - - -@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) - - 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 -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 = 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 - ) - 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) - - @pytest.fixture(scope="module") -def get_contract_pyevm(w3, optimize, experimental_codegen, output_formats): +def get_contract(env, optimize, output_formats): def fn(source_code, *args, **kwargs): - return _get_contract( - w3, source_code, optimize, experimental_codegen, output_formats, *args, **kwargs - ) + return env.deploy_source(source_code, optimize, output_formats, *args, **kwargs) return fn +# todo: this should be removed and replaced with get_contract @pytest.fixture(scope="module") -def get_contract(get_contract_pyevm): - return get_contract_pyevm +def get_contract_with_gas_estimation(get_contract): + return get_contract +# todo: this should be removed and replaced with get_contract @pytest.fixture(scope="module") -def get_revm_contract(env, optimize, output_formats): - def fn(source_code, *args, **kwargs): - return env.deploy_source(source_code, optimize, 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 +def get_contract_module(get_contract): + return get_contract +# todo: this should be removed and replaced with get_contract @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 - ) - - return w3.eth.contract(address, bytecode=deploy_bytecode), factory +def get_contract_with_gas_estimation_for_constants(get_contract): + return get_contract @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 - - -@pytest.fixture(scope="module") -def deploy_blueprint_revm(env, optimize, output_formats): - def deploy_blueprint_revm(source_code, *args, **kwargs): +def deploy_blueprint_for(env, optimize, output_formats): + def fn(source_code, *args, **kwargs): return env.deploy_blueprint(source_code, optimize, output_formats, *args, **kwargs) - return deploy_blueprint_revm + return fn @pytest.fixture(scope="module") -def get_logs_revm(env): - def get_logs(tx_result, c: ABIContract, event_name: str = None, raw=False): +def get_logs(env): + def fn(tx_result, c: ABIContract, event_name: str = None, raw=False): logs = [log for log in env.last_result["logs"] if c.address == log.address] if raw: return [log.data for log in logs] @@ -581,7 +264,7 @@ def get_logs(tx_result, c: ABIContract, event_name: str = None, raw=False): return parsed_logs - return get_logs + return fn # TODO: this should not be a fixture. @@ -641,23 +324,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 - - @pytest.fixture(scope="module") -def tx_failed(tester): +def tx_failed(env): + # todo: use custom exception, we don't use eth_tester anymore @contextmanager def fn(exception=TransactionFailed, exc_text=None): - snapshot_id = tester.take_snapshot() - with pytest.raises(exception) as excinfo: + with env.anchor(), pytest.raises(exception) as excinfo: yield excinfo - tester.revert_to_snapshot(snapshot_id) + if exc_text: # TODO test equality assert exc_text in str(excinfo.value), (exc_text, excinfo.value) diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index 69ef003422..2b0d727ca7 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -1,3 +1,4 @@ +import logging from collections import namedtuple from contextlib import contextmanager from typing import cast @@ -17,8 +18,9 @@ from eth_tester.exceptions import TransactionFailed from eth_tester.utils.address import generate_contract_address from eth_typing import Address -from eth_utils import to_checksum_address +from eth_utils import setup_DEBUG2_logging, to_checksum_address +import vyper.evm.opcodes as evm_opcodes from tests.evm_backends.base_env import BaseEnv @@ -36,6 +38,20 @@ def __init__( ) -> None: super().__init__(gas_limit, account_keys) + # note: we configure the evm version that we emit code for, + # but eth-tester is only configured with the latest mainnet + # version. + evm_opcodes.DEFAULT_EVM_VERSION = evm_version + # this should get overridden by anchor_evm_version, but set it anyway + evm_opcodes.active_evm_version = evm_opcodes.EVM_VERSIONS[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(), diff --git a/tests/evm_backends/revm_env.py b/tests/evm_backends/revm_env.py index 37b685d254..e4993a9242 100644 --- a/tests/evm_backends/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -33,7 +33,12 @@ def anchor(self): try: yield finally: - self._evm.revert(snapshot_id) + 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 @contextmanager def sender(self, address: str): diff --git a/tests/functional/builtins/codegen/test_abi_encode.py b/tests/functional/builtins/codegen/test_abi_encode.py index f1b290d394..824cb7dcc4 100644 --- a/tests/functional/builtins/codegen/test_abi_encode.py +++ b/tests/functional/builtins/codegen/test_abi_encode.py @@ -228,7 +228,6 @@ def abi_encode( @pytest.mark.parametrize("args", nested_3d_array_args) -@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_abi_encode_nested_dynarray_2(get_contract, args): code = """ @external diff --git a/tests/functional/codegen/features/test_logging.py b/tests/functional/codegen/features/test_logging.py index 65d8b506bd..4acfc79987 100644 --- a/tests/functional/codegen/features/test_logging.py +++ b/tests/functional/codegen/features/test_logging.py @@ -280,9 +280,7 @@ def foo(): assert logs[0].args.arg3 == [[1, 2], [1, 2]] -def test_logging_with_input_bytes_1( - env, keccak, get_logs, bytes_helper, get_contract_with_gas_estimation -): +def test_logging_with_input_bytes_1(env, keccak, get_logs, get_contract_with_gas_estimation): loggy_code = """ event MyLog: arg1: Bytes[4] @@ -833,7 +831,7 @@ def foo(): assert logs[0].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_with_gas_estimation): code = """ event Bar: _value: int128[4] @@ -896,7 +894,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_with_gas_estimation): code = """ event MyLog: arg1: Bytes[29] @@ -922,7 +920,7 @@ def setbytez(): assert logs[0].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_with_gas_estimation): code = """ event Bar: _value: decimal[4] diff --git a/tests/functional/codegen/integration/test_eth_tester.py b/tests/functional/codegen/integration/test_eth_tester.py index e69de29bb2..6369f63709 100644 --- a/tests/functional/codegen/integration/test_eth_tester.py +++ b/tests/functional/codegen/integration/test_eth_tester.py @@ -0,0 +1,219 @@ +import json +from functools import wraps + +import pytest +import web3.exceptions +from eth_tester import EthereumTester, PyEVMBackend +from eth_utils.toolz import compose +from web3 import Web3 +from web3.contract import Contract +from web3.providers.eth_tester import EthereumTesterProvider + +from vyper import compiler +from vyper.ast.grammar import parse_vyper_source +from vyper.compiler.settings import Settings + + +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,) + + +def zero_gas_price_strategy(web3, transaction_params=None): + return 0 # zero gas price makes testing simpler. + + +@pytest.fixture(scope="module") +def tester(gas_limit): + custom_genesis = PyEVMBackend._generate_genesis_params(overrides={"gas_limit": gas_limit}) + custom_genesis["base_fee_per_gas"] = 0 + backend = PyEVMBackend(genesis_parameters=custom_genesis) + return EthereumTester(backend=backend) + + +@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) + + 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)) + + +def _get_contract( + w3, + source_code, + optimize, + experimental_codegen, + output_formats, + *args, + override_opt_level=None, + input_bundle=None, + **kwargs, +): + settings = 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 + ) + 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) + + +@pytest.fixture(scope="module") +def get_contract(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 test_slice_storage_bytes32(get_contract): + code = """ +bytez: bytes32 +@external +def dice() -> Bytes[1]: + self.bytez = convert(65, bytes32) + c: Bytes[1] = slice(self.bytez, 31, 1) + return c + """ + + c = get_contract(code) + assert c.dice() == b"A" diff --git a/tests/functional/codegen/types/test_bytes_zero_padding.py b/tests/functional/codegen/types/test_bytes_zero_padding.py index 40bd1de6fc..909eb2f0b9 100644 --- a/tests/functional/codegen/types/test_bytes_zero_padding.py +++ b/tests/functional/codegen/types/test_bytes_zero_padding.py @@ -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_module(code) @pytest.mark.fuzzing diff --git a/tests/functional/conftest.py b/tests/functional/conftest.py deleted file mode 100644 index 0689b04ce4..0000000000 --- a/tests/functional/conftest.py +++ /dev/null @@ -1,26 +0,0 @@ -import pytest - - -@pytest.fixture(scope="module") -def get_contract(get_revm_contract): - return get_revm_contract - - -@pytest.fixture(scope="module") -def deploy_blueprint_for(deploy_blueprint_revm): - return deploy_blueprint_revm - - -@pytest.fixture(scope="module") -def get_logs(get_logs_revm): - return get_logs_revm - - -@pytest.fixture(scope="module") -def get_contract_with_gas_estimation(get_revm_contract): - return get_revm_contract - - -@pytest.fixture(scope="module") -def get_contract_with_gas_estimation_for_constants(get_revm_contract): - return get_revm_contract diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py deleted file mode 100644 index 0689b04ce4..0000000000 --- a/tests/unit/conftest.py +++ /dev/null @@ -1,26 +0,0 @@ -import pytest - - -@pytest.fixture(scope="module") -def get_contract(get_revm_contract): - return get_revm_contract - - -@pytest.fixture(scope="module") -def deploy_blueprint_for(deploy_blueprint_revm): - return deploy_blueprint_revm - - -@pytest.fixture(scope="module") -def get_logs(get_logs_revm): - return get_logs_revm - - -@pytest.fixture(scope="module") -def get_contract_with_gas_estimation(get_revm_contract): - return get_revm_contract - - -@pytest.fixture(scope="module") -def get_contract_with_gas_estimation_for_constants(get_revm_contract): - return get_revm_contract From 10326099083b863686af5668596d660bdd7b2d2f Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Thu, 4 Apr 2024 10:32:26 +0200 Subject: [PATCH 38/87] Self-review --- tests/evm_backends/abi_contract.py | 21 +++++--- tests/evm_backends/base_env.py | 53 +++++++++++-------- tests/evm_backends/pyevm_env.py | 31 ++++++----- tests/evm_backends/revm_env.py | 9 ++-- .../builtins/codegen/test_abi_encode.py | 3 -- .../functional/builtins/codegen/test_send.py | 4 +- tests/functional/builtins/folding/__init__.py | 0 .../features/test_assert_unreachable.py | 6 +-- .../codegen/features/test_logging.py | 2 +- tests/functional/syntax/test_address_code.py | 12 ++--- tests/functional/syntax/test_chainid.py | 2 +- tests/functional/syntax/test_msg_data.py | 15 +++--- 12 files changed, 90 insertions(+), 68 deletions(-) delete mode 100644 tests/functional/builtins/folding/__init__.py diff --git a/tests/evm_backends/abi_contract.py b/tests/evm_backends/abi_contract.py index 1d9fa1c707..b07e01d851 100644 --- a/tests/evm_backends/abi_contract.py +++ b/tests/evm_backends/abi_contract.py @@ -7,7 +7,6 @@ from eth_typing import ChecksumAddress, HexAddress from eth_utils import to_checksum_address -from hexbytes import HexBytes from pyrevm import Log from vyper.semantics.analysis.base import FunctionVisibility, StateMutability @@ -86,12 +85,15 @@ def parse(self, log: Log) -> ABILog: @cached_property def data_type(self) -> type: - names = [ - (item["name"], item["type"]) for item in self.indexed_inputs + self.unindexed_inputs - ] - return make_dataclass(self.name, names) + """ + 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: Log) -> tuple: + def _parse_args(self, log: Log) -> 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 = [ @@ -103,6 +105,7 @@ def _parse_args(self, log: Log) -> tuple: @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("[]") @@ -366,10 +369,12 @@ def parse_log(self, log: Log) -> 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 any(topic.topic_id == HexBytes(t) for t in log.topics): + if topic.topic_id == topic_id: return topic.parse(log) - raise KeyError(f"Could not find event for log {log.topics}. Found {self.log_topics}") + raise KeyError(f"Could not find event for log {topic_id_str}. Found {self.log_topics}") class ABIContractFactory: diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index e7b9084f58..5ba6209917 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -14,17 +14,20 @@ class BaseEnv: - default_chain_id = 1 + """ + Base class for EVM backends. + It provides a common interface for deploying contracts and interacting with them. + """ + + 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, initcode: bytes, value: int, gas: int = None) -> str: - raise NotImplementedError - 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 @@ -52,6 +55,7 @@ def deploy_source( evm_version=None, **kwargs, ) -> ABIContract: + """Compile and deploy a contract from source code.""" abi, bytecode = self._compile( source_code, optimize, output_formats, override_opt_level, input_bundle, evm_version ) @@ -61,21 +65,6 @@ def deploy_source( return self.deploy(abi, bytecode, value, *args, **kwargs) - def _compile( - self, source_code, optimize, output_formats, override_opt_level, input_bundle, evm_version - ) -> Tuple[list[dict], bytes]: - out = compile_code( - source_code, - # test that all output formats can get generated - output_formats=output_formats, - settings=Settings(evm_version=evm_version, optimize=override_opt_level or optimize), - 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")) - def deploy_blueprint( self, source_code, @@ -87,6 +76,7 @@ def deploy_blueprint( evm_version=None, initcode_prefix=ERC5202_PREFIX, ): + """Deploy a contract with a blueprint pattern.""" abi, bytecode = self._compile( source_code, optimize, output_formats, override_opt_level, input_bundle, evm_version ) @@ -106,8 +96,29 @@ def factory(address): return deployer, factory - def _parse_revert(self, output_bytes, error, gas_used): - # Check EIP838 error, with ABI Error(string) + def _deploy(self, code: bytes, value: int, gas: int = None) -> str: + raise NotImplementedError # must be implemented by subclasses + + def _compile( + self, source_code, optimize, output_formats, override_opt_level, input_bundle, evm_version + ) -> Tuple[list[dict], bytes]: + out = compile_code( + source_code, + # test that all output formats can get generated + output_formats=output_formats, + settings=Settings(evm_version=evm_version, optimize=override_opt_level or optimize), + 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")) + + @staticmethod + def _parse_revert(output_bytes: bytes, error: Exception, gas_used: int): + """ + Tries to parse the EIP-838 revert reason from the output bytes. + """ prefix = "execution reverted" if output_bytes[:4] == method_id("Error(string)"): (msg,) = abi_decode("(string)", output_bytes[4:]) diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index 2b0d727ca7..02d34c544d 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -25,7 +25,8 @@ class PyEvmEnv(BaseEnv): - default_chain_id = 1 + """EVM backend environment using the Py-EVM library.""" + INVALID_OPCODE_ERROR = "Invalid opcode" def __init__( @@ -153,9 +154,8 @@ def _check_computation(self, computation): if computation.is_error: if isinstance(computation.error, Revert): (output,) = computation.error.args - self._parse_revert( - output, computation.error, gas_used=self._last_computation.get_gas_used() - ) + gas_used = computation.get_gas_used() + self._parse_revert(output, computation.error, gas_used) raise TransactionFailed(*computation.error.args) from computation.error @@ -163,15 +163,16 @@ def get_code(self, address: str): return self._state.get_code(_addr(address)) def time_travel(self, num_blocks=1, time_delta: int | None = None) -> None: - if time_delta is None: - time_delta = num_blocks + """ + Move the block number forward by `num_blocks` and the timestamp forward by `time_delta`. + """ context = cast(ExecutionContext, self._state.execution_context) context._block_number += num_blocks - context._timestamp += time_delta + context._timestamp += num_blocks if time_delta is None else time_delta - def _deploy(self, initcode: bytes, value: int, gas: int = None) -> str: + def _deploy(self, code: bytes, value: int, gas: int = None) -> str: sender = _addr(self.deployer) - target_address = self._generate_address(sender) + target_address = self._generate_contract_address(sender) try: computation = self._state.computation_class.apply_create_message( @@ -180,7 +181,7 @@ def _deploy(self, initcode: bytes, value: int, gas: int = None) -> str: to=CREATE_CONTRACT_ADDRESS, # i.e., b"" sender=sender, value=value, - code=initcode, + code=code, data=b"", gas=gas or self.gas_limit, create_address=target_address, @@ -192,20 +193,26 @@ def _deploy(self, initcode: bytes, value: int, gas: int = None) -> str: self._check_computation(computation) return "0x" + target_address.hex() - def _generate_address(self, sender: Address) -> bytes: + def _generate_contract_address(self, sender: Address) -> Address: nonce = self._state.get_nonce(sender) self._state.increment_nonce(sender) return generate_contract_address(sender, nonce) +# a very simple log representation for the raw log entries Log = namedtuple("Log", ["address", "topics", "data"]) -def _parse_log_entries(result): +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(): topics = [t.to_bytes(32, "big") for t in topics] yield Log(to_checksum_address(address), topics, (topics, 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 index e4993a9242..72e27ef880 100644 --- a/tests/evm_backends/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -104,13 +104,16 @@ def execute_code( 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) - self._parse_revert(output_bytes, e, gas_used) + self._parse_revert(output_bytes, e, int(gas_used)) raise TransactionFailed(*e.args) from e def get_code(self, address: str): return self._evm.basic(address).code.rstrip(b"\0") def time_travel(self, num_blocks=1, time_delta: int | None = None) -> None: + """ + Move the block number forward by `num_blocks` and the timestamp forward by `time_delta`. + """ if time_delta is None: time_delta = num_blocks block = self._evm.env.block @@ -127,5 +130,5 @@ def time_travel(self, num_blocks=1, time_delta: int | None = None) -> None: ) ) - def _deploy(self, initcode: bytes, value: int, gas: int = None) -> str: - return self._evm.deploy(deployer=self.deployer, code=initcode, value=value, gas=gas) + def _deploy(self, code: bytes, value: int, gas: int = None) -> str: + return self._evm.deploy(self.deployer, code, value, gas) diff --git a/tests/functional/builtins/codegen/test_abi_encode.py b/tests/functional/builtins/codegen/test_abi_encode.py index 824cb7dcc4..9ab6efbd65 100644 --- a/tests/functional/builtins/codegen/test_abi_encode.py +++ b/tests/functional/builtins/codegen/test_abi_encode.py @@ -3,8 +3,6 @@ import pytest from eth.codecs import abi -from vyper.exceptions import StackTooDeep - # @pytest.mark.parametrize("string", ["a", "abc", "abcde", "potato"]) def test_abi_encode(get_contract): @@ -332,7 +330,6 @@ def foo(bs: DynArray[uint256, 3]) -> (uint256, Bytes[160]): assert c.foo(bs) == (2**256 - 1, abi.encode("(uint256[])", (bs,))) -@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_abi_encode_private_nested_dynarray(get_contract): code = """ bytez: Bytes[1696] diff --git a/tests/functional/builtins/codegen/test_send.py b/tests/functional/builtins/codegen/test_send.py index a16dcd0068..4a50892d0d 100644 --- a/tests/functional/builtins/codegen/test_send.py +++ b/tests/functional/builtins/codegen/test_send.py @@ -43,7 +43,7 @@ def __default__(): self.last_sender = msg.sender """ - env.set_balance(env.deployer, 100000 * 3) + env.set_balance(env.deployer, 300000) sender = get_contract(sender_code, value=1) receiver = get_contract(receiver_code) @@ -86,7 +86,7 @@ def __default__(): self.last_sender = msg.sender """ - env.set_balance(env.deployer, 100000 * 3) + env.set_balance(env.deployer, 300000) sender = get_contract(sender_code, value=1) receiver = get_contract(receiver_code) diff --git a/tests/functional/builtins/folding/__init__.py b/tests/functional/builtins/folding/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/functional/codegen/features/test_assert_unreachable.py b/tests/functional/codegen/features/test_assert_unreachable.py index 2706cd04b1..58aef15240 100644 --- a/tests/functional/codegen/features/test_assert_unreachable.py +++ b/tests/functional/codegen/features/test_assert_unreachable.py @@ -35,11 +35,11 @@ def foo(val: int128) -> bool: assert c.foo(2) is True - with tx_failed(exc_text=(env.INVALID_OPCODE_ERROR)): + with tx_failed(exc_text=env.INVALID_OPCODE_ERROR): c.foo(1) - with tx_failed(exc_text=(env.INVALID_OPCODE_ERROR)): + with tx_failed(exc_text=env.INVALID_OPCODE_ERROR): c.foo(-1) - with tx_failed(exc_text=(env.INVALID_OPCODE_ERROR)): + with tx_failed(exc_text=env.INVALID_OPCODE_ERROR): c.foo(-2) diff --git a/tests/functional/codegen/features/test_logging.py b/tests/functional/codegen/features/test_logging.py index 4acfc79987..7390b80469 100644 --- a/tests/functional/codegen/features/test_logging.py +++ b/tests/functional/codegen/features/test_logging.py @@ -541,7 +541,7 @@ def foo(): logs = get_logs(tx_hash, c, "YourLog") args = logs[0].args assert args.arg1 == c.address - assert args.arg2 == (1, b"abc", ("house", Decimal("13.5000000000"))) + assert args.arg2 == (1, b"abc", ("house", Decimal("13.5"))) def test_fails_when_input_is_the_wrong_type(tx_failed, get_contract_with_gas_estimation): diff --git a/tests/functional/syntax/test_address_code.py b/tests/functional/syntax/test_address_code.py index b726d54824..53ddf439e3 100644 --- a/tests/functional/syntax/test_address_code.py +++ b/tests/functional/syntax/test_address_code.py @@ -3,7 +3,6 @@ import pytest from eth_tester.exceptions import TransactionFailed -from hexbytes import HexBytes from vyper import compiler from vyper.compiler.settings import Settings @@ -17,15 +16,16 @@ @pytest.fixture -def deploy_precompiled_contract(env): - return lambda: env.deploy(json.loads(PRECOMPILED_ABI), HexBytes(PRECOMPILED_BYTECODE)) +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, deploy_precompiled_contract, get_contract + start: int, length: int, expected: bytes, precompiled_contract, get_contract ): code = f""" @external @@ -33,12 +33,11 @@ def code_slice(x: address) -> Bytes[{length}]: return slice(x.code, {start}, {length}) """ contract = get_contract(code) - precompiled_contract = deploy_precompiled_contract() actual = contract.code_slice(precompiled_contract.address) assert actual == expected -def test_address_code_runtime_error_slice_too_long(deploy_precompiled_contract, get_contract): +def test_address_code_runtime_error_slice_too_long(precompiled_contract, get_contract): start = len(PRECOMPILED) - 5 length = 10 code = f""" @@ -47,7 +46,6 @@ def code_slice(x: address) -> Bytes[{length}]: return slice(x.code, {start}, {length}) """ contract = get_contract(code) - precompiled_contract = deploy_precompiled_contract() with pytest.raises(TransactionFailed): contract.code_slice(precompiled_contract.address) diff --git a/tests/functional/syntax/test_chainid.py b/tests/functional/syntax/test_chainid.py index 258712bda6..54a3f706e6 100644 --- a/tests/functional/syntax/test_chainid.py +++ b/tests/functional/syntax/test_chainid.py @@ -89,4 +89,4 @@ def get_chain_id() -> uint256: return chain.id """ c = get_contract_with_gas_estimation(code) - assert c.get_chain_id() == env.default_chain_id + assert c.get_chain_id() == env.DEFAULT_CHAIN_ID diff --git a/tests/functional/syntax/test_msg_data.py b/tests/functional/syntax/test_msg_data.py index c935bdd4c5..0e3a25b760 100644 --- a/tests/functional/syntax/test_msg_data.py +++ b/tests/functional/syntax/test_msg_data.py @@ -4,9 +4,10 @@ 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]: @@ -16,7 +17,7 @@ def foo() -> Bytes[4]: contract = get_contract(code) - assert contract.foo() == bytes(keccak(b"foo()")[:4]) + assert contract.foo() == method_id("foo()") def test_slicing_start_index_other_than_zero(get_contract): @@ -32,7 +33,7 @@ def foo(_value: uint256) -> uint256: assert contract.foo(42) == 42 -def test_get_full_calldata(get_contract, keccak): +def test_get_full_calldata(get_contract): code = """ @external def foo(bar: uint256) -> Bytes[36]: @@ -42,9 +43,9 @@ def foo(bar: uint256) -> Bytes[36]: contract = get_contract(code) # 2fbebd38000000000000000000000000000000000000000000000000000000000000002a - method_id = keccak(b"foo(uint256)").hex()[:8] # 2fbebd38 + foo_method_id = method_id("foo(uint256)").hex() # 2fbebd38 encoded_42 = to_bytes(42).hex() # 2a - expected_result = method_id + "00" * 31 + encoded_42 + expected_result = foo_method_id + "00" * 31 + encoded_42 assert contract.foo(42).hex() == expected_result @@ -74,7 +75,7 @@ def foo() -> (uint256, Bytes[4], uint256): """ contract = get_contract(code) - assert contract.foo() == (2**256 - 1, bytes(keccak(b"foo()")[:4]), 2**256 - 1) + assert contract.foo() == (2**256 - 1, method_id("foo()"), 2**256 - 1) def test_assignment_to_storage(env, get_contract, keccak): @@ -87,7 +88,7 @@ def foo(): """ contract = get_contract(code) contract.foo(transact={}) - assert contract.cache() == bytes(keccak(b"foo()")[:4]) + assert contract.cache() == method_id("foo()") def test_get_len(get_contract): From f02376aa03a935aab8c2907fdc1e1bb4b1e2ab99 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Thu, 4 Apr 2024 10:51:36 +0200 Subject: [PATCH 39/87] Topic IDs as str --- tests/evm_backends/pyevm_env.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index 02d34c544d..f25a0ddd0a 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -209,8 +209,9 @@ def _parse_log_entries(result: ComputationAPI): usable format similar to the revm backend. """ for address, topics, data in result.get_log_entries(): - topics = [t.to_bytes(32, "big") for t in topics] - yield Log(to_checksum_address(address), topics, (topics, data)) + topic_bytes = [t.to_bytes(32, "big") for t in topics] + topic_ids = ["0x" + t.hex() for t in topic_bytes] + yield Log(to_checksum_address(address), topic_ids, (topic_bytes, data)) def _addr(address: str) -> Address: From 2a487b325cb21208346e5bc952fcbd15c6cbd678 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Thu, 4 Apr 2024 11:53:35 +0200 Subject: [PATCH 40/87] Pass evm_version to compiler --- tests/functional/examples/factory/test_factory.py | 7 ++++--- tests/functional/syntax/test_address_code.py | 9 ++++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/functional/examples/factory/test_factory.py b/tests/functional/examples/factory/test_factory.py index ca0b0f6f60..19f68d634f 100644 --- a/tests/functional/examples/factory/test_factory.py +++ b/tests/functional/examples/factory/test_factory.py @@ -23,7 +23,6 @@ def create_exchange(env, get_contract): def create_exchange(token, factory): exchange = get_contract(code, *[token.address, factory.address]) - assert keccak256(env.get_code(exchange.address)).hex() == factory.exchange_codehash().hex() # NOTE: Must initialize exchange to register it with factory exchange.initialize(transact={"from": env.accounts[0]}) return exchange @@ -32,14 +31,16 @@ def create_exchange(token, factory): @pytest.fixture -def factory(get_contract, optimize, experimental_codegen): +def factory(get_contract, optimize, experimental_codegen, evm_version): 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), + settings=Settings( + evm_version=evm_version, optimize=optimize, experimental_codegen=experimental_codegen + ), ) bytecode_runtime = exchange_interface["bytecode_runtime"] exchange_deployed_bytecode = bytes.fromhex(bytecode_runtime.removeprefix("0x")) diff --git a/tests/functional/syntax/test_address_code.py b/tests/functional/syntax/test_address_code.py index 53ddf439e3..3d62797af2 100644 --- a/tests/functional/syntax/test_address_code.py +++ b/tests/functional/syntax/test_address_code.py @@ -159,7 +159,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, optimize, experimental_codegen, evm_version): code = """ code_deployment: public(Bytes[32]) @@ -172,9 +172,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, + output_formats=["bytecode", "bytecode_runtime"], + settings=Settings( + evm_version=evm_version, optimize=optimize, experimental_codegen=experimental_codegen + ), ) assert contract.code_deployment() == bytes.fromhex(code_compiled["bytecode"][2:])[:32] assert contract.code_runtime() == bytes.fromhex(code_compiled["bytecode_runtime"][2:])[:32] From ceaf5e8c7ef40f1ce2dc0aaca6aa614439e8109a Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Thu, 4 Apr 2024 15:03:32 +0200 Subject: [PATCH 41/87] Extract compiler_settings fixture --- tests/conftest.py | 27 +++++++++++++++---- tests/evm_backends/base_env.py | 21 +++++---------- .../test_block_number.py | 4 +-- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index b6c19ffa67..3fc528c58f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -14,7 +14,7 @@ from vyper import compiler from vyper.codegen.ir_node import IRnode from vyper.compiler.input_bundle import FilesystemInputBundle, InputBundle -from vyper.compiler.settings import OptimizationLevel, _set_debug_mode +from vyper.compiler.settings import OptimizationLevel, Settings, _set_debug_mode from vyper.ir import compile_ir, optimizer from vyper.utils import keccak256 @@ -218,9 +218,21 @@ def ir_compiler(ir, *args, **kwargs): @pytest.fixture(scope="module") -def get_contract(env, optimize, output_formats): +def compiler_settings(optimize, experimental_codegen, evm_version): + return Settings( + optimize=optimize, evm_version=evm_version, experimental_codegen=experimental_codegen + ) + + +@pytest.fixture(scope="module") +def get_contract(env, optimize, output_formats, compiler_settings): def fn(source_code, *args, **kwargs): - return env.deploy_source(source_code, optimize, output_formats, *args, **kwargs) + settings = kwargs.pop("compiler_settings", compiler_settings) + if "override_opt_level" in kwargs: + settings = Settings( + **dict(settings.__dict__, optimize=kwargs.pop("override_opt_level")) + ) + return env.deploy_source(source_code, output_formats, settings, *args, **kwargs) return fn @@ -244,9 +256,14 @@ def get_contract_with_gas_estimation_for_constants(get_contract): @pytest.fixture(scope="module") -def deploy_blueprint_for(env, optimize, output_formats): +def deploy_blueprint_for(env, compiler_settings, output_formats): def fn(source_code, *args, **kwargs): - return env.deploy_blueprint(source_code, optimize, output_formats, *args, **kwargs) + settings = kwargs.pop("compiler_settings", compiler_settings) + if "override_opt_level" in kwargs: + settings = Settings( + **dict(settings.__dict__, optimize=kwargs.pop("override_opt_level")) + ) + return env.deploy_blueprint(source_code, output_formats, settings, *args, **kwargs) return fn diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index 5ba6209917..05326c2d76 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -9,7 +9,6 @@ from tests.evm_backends.abi_contract import ABIContract, ABIContractFactory, ABIFunction from vyper.ast.grammar import parse_vyper_source from vyper.compiler import CompilerData, Settings, compile_code -from vyper.compiler.settings import OptimizationLevel from vyper.utils import ERC5202_PREFIX, method_id @@ -47,18 +46,14 @@ def deploy(self, abi: list[dict], bytecode: bytes, value=0, *args, **kwargs): def deploy_source( self, source_code: str, - optimize: OptimizationLevel, output_formats: dict[str, Callable[[CompilerData], str]], + compiler_settings: Settings, *args, - override_opt_level=None, input_bundle=None, - evm_version=None, **kwargs, ) -> ABIContract: """Compile and deploy a contract from source code.""" - abi, bytecode = self._compile( - source_code, optimize, output_formats, override_opt_level, input_bundle, evm_version - ) + abi, bytecode = self._compile(source_code, output_formats, compiler_settings, input_bundle) value = ( kwargs.pop("value", 0) or kwargs.pop("value_in_eth", 0) * 10**18 ) # Handle deploying with an eth value. @@ -68,18 +63,14 @@ def deploy_source( def deploy_blueprint( self, source_code, - optimize, output_formats, + compiler_settings: Settings, *args, - override_opt_level=None, input_bundle=None, - evm_version=None, initcode_prefix=ERC5202_PREFIX, ): """Deploy a contract with a blueprint pattern.""" - abi, bytecode = self._compile( - source_code, optimize, output_formats, override_opt_level, input_bundle, evm_version - ) + abi, bytecode = self._compile(source_code, output_formats, compiler_settings, input_bundle) bytecode = initcode_prefix + bytecode bytecode_len = len(bytecode) bytecode_len_hex = hex(bytecode_len)[2:].rjust(4, "0") @@ -100,13 +91,13 @@ def _deploy(self, code: bytes, value: int, gas: int = None) -> str: raise NotImplementedError # must be implemented by subclasses def _compile( - self, source_code, optimize, output_formats, override_opt_level, input_bundle, evm_version + self, source_code, output_formats, settings, input_bundle ) -> Tuple[list[dict], bytes]: out = compile_code( source_code, # test that all output formats can get generated output_formats=output_formats, - settings=Settings(evm_version=evm_version, optimize=override_opt_level or optimize), + settings=settings, input_bundle=input_bundle, show_gas_estimates=True, # Enable gas estimates for testing ) diff --git a/tests/functional/codegen/environment_variables/test_block_number.py b/tests/functional/codegen/environment_variables/test_block_number.py index 277800b321..5c4ba3677b 100644 --- a/tests/functional/codegen/environment_variables/test_block_number.py +++ b/tests/functional/codegen/environment_variables/test_block_number.py @@ -1,4 +1,4 @@ -def test_block_number(get_contract_with_gas_estimation, env, optimize, output_formats): +def test_block_number(get_contract_with_gas_estimation, env, compiler_settings, output_formats): block_number_code = """ @external def block_number() -> uint256: @@ -8,5 +8,5 @@ def block_number() -> uint256: assert c.block_number() == 1 env.time_travel() - c = env.deploy_source(block_number_code, optimize, output_formats) + c = env.deploy_source(block_number_code, output_formats, compiler_settings) assert c.block_number() == 2 From 6342422e3f6edb657edfcf89be81d2afb55d736e Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Thu, 4 Apr 2024 20:18:23 +0200 Subject: [PATCH 42/87] Revert "Delete some xfail for passing tests" This reverts commit c145c93e82e51d0e4ce6e224b40c156f668c06eb. --- .github/workflows/test.yml | 1 - tests/functional/builtins/codegen/test_abi_decode.py | 4 +++- tests/functional/builtins/codegen/test_abi_encode.py | 3 +++ tests/functional/codegen/features/test_clampers.py | 2 ++ tests/functional/codegen/features/test_constructor.py | 4 ++++ tests/functional/codegen/features/test_immutable.py | 2 ++ tests/functional/codegen/types/test_dynamic_array.py | 7 +++++++ tests/functional/examples/factory/test_factory.py | 8 +++----- 8 files changed, 24 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index aee31beebb..f226a190f9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -81,7 +81,6 @@ jobs: debug: false opt-mode: gas evm-version: london - evm-backend: revm - python-version: ["3.11", "311"] debug: false diff --git a/tests/functional/builtins/codegen/test_abi_decode.py b/tests/functional/builtins/codegen/test_abi_decode.py index e276e03944..e37ed32d5a 100644 --- a/tests/functional/builtins/codegen/test_abi_decode.py +++ b/tests/functional/builtins/codegen/test_abi_decode.py @@ -3,7 +3,7 @@ import pytest from eth.codecs import abi -from vyper.exceptions import ArgumentException, StructureException +from vyper.exceptions import ArgumentException, StackTooDeep, StructureException TEST_ADDR = "0x" + b"".join(chr(i).encode("utf-8") for i in range(20)).hex() @@ -194,6 +194,7 @@ def abi_decode(x: Bytes[{len}]) -> DynArray[DynArray[uint256, 3], 3]: @pytest.mark.parametrize("args", nested_3d_array_args) @pytest.mark.parametrize("unwrap_tuple", (True, False)) +@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_abi_decode_nested_dynarray2(get_contract, args, unwrap_tuple): if unwrap_tuple is True: encoded = abi.encode("(uint256[][][])", (args,)) @@ -271,6 +272,7 @@ def foo(bs: Bytes[160]) -> (uint256, DynArray[uint256, 3]): assert c.foo(encoded) == (2**256 - 1, bs) +@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_abi_decode_private_nested_dynarray(get_contract): code = """ bytez: DynArray[DynArray[DynArray[uint256, 3], 3], 3] diff --git a/tests/functional/builtins/codegen/test_abi_encode.py b/tests/functional/builtins/codegen/test_abi_encode.py index 9ab6efbd65..552d36c959 100644 --- a/tests/functional/builtins/codegen/test_abi_encode.py +++ b/tests/functional/builtins/codegen/test_abi_encode.py @@ -3,6 +3,8 @@ import pytest from eth.codecs import abi +from vyper.exceptions import StackTooDeep + # @pytest.mark.parametrize("string", ["a", "abc", "abcde", "potato"]) def test_abi_encode(get_contract): @@ -225,6 +227,7 @@ def abi_encode( ] +@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") @pytest.mark.parametrize("args", nested_3d_array_args) def test_abi_encode_nested_dynarray_2(get_contract, args): code = """ diff --git a/tests/functional/codegen/features/test_clampers.py b/tests/functional/codegen/features/test_clampers.py index 630cc43d55..7fbc0186db 100644 --- a/tests/functional/codegen/features/test_clampers.py +++ b/tests/functional/codegen/features/test_clampers.py @@ -4,6 +4,7 @@ from eth.codecs import abi from eth_utils import keccak +from vyper.exceptions import StackTooDeep from vyper.utils import int_bounds @@ -506,6 +507,7 @@ def foo(b: DynArray[int128, 10]) -> DynArray[int128, 10]: @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(env, get_contract, value): code = """ @external diff --git a/tests/functional/codegen/features/test_constructor.py b/tests/functional/codegen/features/test_constructor.py index 17ae5d1c48..b0f2f17960 100644 --- a/tests/functional/codegen/features/test_constructor.py +++ b/tests/functional/codegen/features/test_constructor.py @@ -1,6 +1,8 @@ import pytest from eth.codecs.abi.exceptions import EncodeError +from vyper.exceptions import StackTooDeep + def test_init_argument_test(get_contract_with_gas_estimation): init_argument_test = """ @@ -163,6 +165,7 @@ def get_foo() -> uint256: assert c.get_foo() == 39 +@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_nested_dynamic_array_constructor_arg_2(env, get_contract_with_gas_estimation): code = """ foo: int128 @@ -208,6 +211,7 @@ def get_foo() -> DynArray[DynArray[uint256, 3], 3]: assert c.get_foo() == [[37, 41, 73], [37041, 41073, 73037], [146, 123, 148]] +@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_initialise_nested_dynamic_array_2(env, get_contract_with_gas_estimation): code = """ foo: DynArray[DynArray[DynArray[int128, 3], 3], 3] diff --git a/tests/functional/codegen/features/test_immutable.py b/tests/functional/codegen/features/test_immutable.py index 0506e458ea..91378db8bc 100644 --- a/tests/functional/codegen/features/test_immutable.py +++ b/tests/functional/codegen/features/test_immutable.py @@ -1,6 +1,7 @@ import pytest from vyper.compiler.settings import OptimizationLevel +from vyper.exceptions import StackTooDeep @pytest.mark.parametrize( @@ -198,6 +199,7 @@ def get_idx_two() -> uint256: assert c.get_idx_two() == expected_values[2][2] +@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_nested_dynarray_immutable(get_contract): code = """ my_list: immutable(DynArray[DynArray[DynArray[int128, 3], 3], 3]) diff --git a/tests/functional/codegen/types/test_dynamic_array.py b/tests/functional/codegen/types/test_dynamic_array.py index fe5cd787e7..fb5614c31a 100644 --- a/tests/functional/codegen/types/test_dynamic_array.py +++ b/tests/functional/codegen/types/test_dynamic_array.py @@ -9,6 +9,7 @@ ArrayIndexException, ImmutableViolation, OverflowException, + StackTooDeep, StateAccessViolation, TypeMismatch, ) @@ -61,6 +62,7 @@ def loo(x: DynArray[DynArray[int128, 2], 2]) -> int128: print("Passed list tests") +@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_string_list(get_contract): code = """ @external @@ -733,6 +735,7 @@ def test_array_decimal_return3() -> DynArray[DynArray[decimal, 2], 2]: assert c.test_array_decimal_return3() == [[1.0, 2.0], [3.0]] +@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_mult_list(get_contract_with_gas_estimation): code = """ nest3: DynArray[DynArray[DynArray[uint256, 2], 2], 2] @@ -1479,6 +1482,7 @@ def foo(x: int128) -> int128: assert c.foo(7) == 392 +@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_struct_of_lists(get_contract): code = """ struct Foo: @@ -1567,6 +1571,7 @@ def bar(x: int128) -> DynArray[int128, 3]: assert c.bar(7) == [7, 14] +@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_nested_struct_of_lists(get_contract, assert_compile_failed, optimize): code = """ struct nestedFoo: @@ -1697,6 +1702,8 @@ def __init__(): ], ) def test_empty_nested_dynarray(get_contract, typ, val, venom_xfail): + if val == [[[], []], []]: + venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") code = f""" @external def foo() -> {typ}: diff --git a/tests/functional/examples/factory/test_factory.py b/tests/functional/examples/factory/test_factory.py index 19f68d634f..88826c0a5d 100644 --- a/tests/functional/examples/factory/test_factory.py +++ b/tests/functional/examples/factory/test_factory.py @@ -1,8 +1,8 @@ import pytest +from eth_utils import keccak import vyper from vyper.compiler.settings import Settings -from vyper.utils import keccak256 @pytest.fixture @@ -42,15 +42,13 @@ def factory(get_contract, optimize, experimental_codegen, evm_version): evm_version=evm_version, optimize=optimize, experimental_codegen=experimental_codegen ), ) - bytecode_runtime = exchange_interface["bytecode_runtime"] - exchange_deployed_bytecode = bytes.fromhex(bytecode_runtime.removeprefix("0x")) + exchange_deployed_bytecode = exchange_interface["bytecode_runtime"] with open("examples/factory/Factory.vy") as f: code = f.read() # NOTE: We deploy the factory with the hash of the exchange's expected deployment bytecode - deployed = keccak256(exchange_deployed_bytecode) - return get_contract(code, deployed) + return get_contract(code, keccak(hexstr=exchange_deployed_bytecode)) def test_exchange(env, factory, create_token, create_exchange): From 19a2837db687755aeb47b743fdcddec1f790c00a Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Thu, 4 Apr 2024 20:47:25 +0200 Subject: [PATCH 43/87] revm reset_transient_storage --- tests/conftest.py | 3 +-- tests/evm_backends/revm_env.py | 10 +++++++++- tests/functional/codegen/features/test_transient.py | 8 ++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index e889f7c881..543e22fda7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -15,7 +15,6 @@ from vyper.codegen.ir_node import IRnode from vyper.compiler.input_bundle import FilesystemInputBundle, InputBundle from vyper.compiler.settings import OptimizationLevel, Settings, _set_debug_mode -from vyper.evm.opcodes import version_check from vyper.exceptions import EvmVersionException from vyper.ir import compile_ir, optimizer from vyper.utils import keccak256 @@ -363,7 +362,7 @@ def pytest_runtest_call(item): 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) ) diff --git a/tests/evm_backends/revm_env.py b/tests/evm_backends/revm_env.py index 72e27ef880..274ea454c6 100644 --- a/tests/evm_backends/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -106,6 +106,11 @@ def execute_code( output_bytes = bytes.fromhex(output_str) self._parse_revert(output_bytes, e, int(gas_used)) raise TransactionFailed(*e.args) from e + finally: + self.reset_transient_storage() + + def reset_transient_storage(self): + self._evm.reset_transient_storage() def get_code(self, address: str): return self._evm.basic(address).code.rstrip(b"\0") @@ -131,4 +136,7 @@ def time_travel(self, num_blocks=1, time_delta: int | None = None) -> None: ) def _deploy(self, code: bytes, value: int, gas: int = None) -> str: - return self._evm.deploy(self.deployer, code, value, gas) + try: + return self._evm.deploy(self.deployer, code, value, gas) + finally: + self.reset_transient_storage() diff --git a/tests/functional/codegen/features/test_transient.py b/tests/functional/codegen/features/test_transient.py index 8dc221fc0d..63502b46ce 100644 --- a/tests/functional/codegen/features/test_transient.py +++ b/tests/functional/codegen/features/test_transient.py @@ -124,11 +124,11 @@ 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 assert c.a() == 0 assert c.b() is None assert c.c() == "" - assert c.foo(*values) == list(values) + assert c.foo(*values) == values def test_struct_transient(get_contract): @@ -496,7 +496,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 +537,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) From 44cadd8706da7402e7f00f6106d9fde07ca25a37 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Thu, 4 Apr 2024 21:09:12 +0200 Subject: [PATCH 44/87] Fix merge conflicts, reset transient for pyevm, optional evm-backend --- .github/workflows/test.yml | 11 +++-------- tests/evm_backends/pyevm_env.py | 4 ++++ tests/evm_backends/revm_env.py | 7 ++----- .../codegen/features/test_logging.py | 18 +++++++++--------- tests/functional/syntax/test_msg_data.py | 6 +++--- 5 files changed, 21 insertions(+), 25 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f226a190f9..387f5e748d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -81,25 +81,24 @@ jobs: debug: false opt-mode: gas evm-version: london + evm-backend: [revm, py-evm] - python-version: ["3.11", "311"] debug: false opt-mode: gas evm-version: paris - evm-backend: revm # redundant rule, for clarity - python-version: ["3.11", "311"] debug: false opt-mode: gas evm-version: shanghai - evm-backend: revm - python-version: ["3.11", "311"] debug: false opt-mode: gas evm-version: cancun - evm-backend: revm + evm-backend: [revm, py-evm] # test experimental pipeline - python-version: ["3.11", "311"] @@ -107,7 +106,6 @@ jobs: debug: false evm-version: shanghai experimental-codegen: true - evm-backend: revm # TODO: test experimental_codegen + -Ocodesize # run with `--memorymock`, but only need to do it one configuration @@ -117,7 +115,6 @@ jobs: debug: false evm-version: shanghai memorymock: true - evm-backend: revm # run across other python versions. we don't really need to run all # modes across all python versions - one is enough @@ -125,13 +122,11 @@ jobs: opt-mode: gas debug: false evm-version: shanghai - evm-backend: revm - python-version: ["3.12", "312"] opt-mode: gas debug: false evm-version: shanghai - evm-backend: revm 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 }} @@ -160,7 +155,7 @@ jobs: -m "not fuzzing" \ --optimize ${{ matrix.opt-mode }} \ --evm-version ${{ matrix.evm-version }} \ - --evm-backend ${{ matrix.evm-backend }} \ + ${{ matrix.evm-backend && '--evm-backend ${{ matrix.evm-backend }}' || '' }} \ ${{ matrix.debug && '--enable-compiler-debug-mode' || '' }} \ ${{ matrix.memorymock && '--memorymock' || '' }} \ ${{ matrix.experimental-codegen && '--experimental-codegen' || '' }} \ diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index f25a0ddd0a..694f0b339f 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -145,6 +145,8 @@ def execute_code( ) except VMError as e: raise TransactionFailed(*e.args) from e + finally: + self._state.clear_transient_storage() self._check_computation(computation) return computation.output @@ -190,6 +192,8 @@ def _deploy(self, code: bytes, value: int, gas: int = None) -> str: ) except VMError as e: raise TransactionFailed(*e.args) from e + finally: + self._state.clear_transient_storage() self._check_computation(computation) return "0x" + target_address.hex() diff --git a/tests/evm_backends/revm_env.py b/tests/evm_backends/revm_env.py index 274ea454c6..47621c8860 100644 --- a/tests/evm_backends/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -107,10 +107,7 @@ def execute_code( self._parse_revert(output_bytes, e, int(gas_used)) raise TransactionFailed(*e.args) from e finally: - self.reset_transient_storage() - - def reset_transient_storage(self): - self._evm.reset_transient_storage() + self._evm.reset_transient_storage() def get_code(self, address: str): return self._evm.basic(address).code.rstrip(b"\0") @@ -139,4 +136,4 @@ def _deploy(self, code: bytes, value: int, gas: int = None) -> str: try: return self._evm.deploy(self.deployer, code, value, gas) finally: - self.reset_transient_storage() + self._evm.reset_transient_storage() diff --git a/tests/functional/codegen/features/test_logging.py b/tests/functional/codegen/features/test_logging.py index 1edcc0e4e3..7390b80469 100644 --- a/tests/functional/codegen/features/test_logging.py +++ b/tests/functional/codegen/features/test_logging.py @@ -62,7 +62,7 @@ def foo(): # Event id is always the first topic (log,) = get_logs(tx_hash, c) - assert log.topics[0] == "0x" + event_id + assert log.topics[0] == event_id # Event abi is created correctly assert c.abi[0] == { "name": "MyLog", @@ -92,7 +92,7 @@ def foo(): event_id = keccak(bytes("MyLog(int128,bool,address)", "utf-8")) # Event id is always the first topic (log,) = get_logs(tx_hash, c) - assert log.topics[0] == "0x" + event_id + assert log.topics[0] == event_id # Event abi is created correctly assert c.abi[0] == { "name": "MyLog", @@ -169,8 +169,8 @@ def bar(): event_id = keccak(bytes("MyLog(int128,address)", "utf-8")) # Event id is always the first topic - assert log1.topics[0] == "0x" + event_id - assert log2.topics[0] == "0x" + event_id + assert log1.topics[0] == event_id + assert log2.topics[0] == event_id # Event abi is created correctly assert c.abi[0] == { "name": "MyLog", @@ -298,7 +298,7 @@ def foo(arg1: Bytes[29], arg2: Bytes[31]): event_id = keccak(bytes("MyLog(bytes,bytes,bytes)", "utf-8")) # Event id is always the first topic (log,) = get_logs(tx_hash, c) - assert log.topics[0] == "0x" + event_id + assert log.topics[0] == event_id # Event abi is created correctly assert c.abi[0] == { "name": "MyLog", @@ -334,7 +334,7 @@ def foo(_arg1: Bytes[20]): event_id = keccak(bytes("MyLog(bytes)", "utf-8")) # Event id is always the first topic (log,) = get_logs(tx_hash, c) - assert log.topics[0] == "0x" + event_id + assert log.topics[0] == event_id # Event abi is created correctly assert c.abi[0] == { "anonymous": False, @@ -444,7 +444,7 @@ def foo(): event_id = keccak(bytes("MyLog(int128,bytes)", "utf-8")) # Event id is always the first topic (log,) = get_logs(tx_hash, c) - assert log.topics[0] == "0x" + event_id + assert log.topics[0] == event_id # Event abi is created correctly assert c.abi[0] == { "anonymous": False, @@ -495,8 +495,8 @@ def foo(): event_id2 = keccak(bytes("YourLog(address,(uint256,bytes,(string,fixed168x10)))", "utf-8")) # Event id is always the first topic - assert log1.topics[0] == "0x" + event_id1 - assert log2.topics[0] == "0x" + event_id2 + assert log1.topics[0] == event_id1 + assert log2.topics[0] == event_id2 # Event abi is created correctly assert c.abi[0] == { "name": "MyLog", diff --git a/tests/functional/syntax/test_msg_data.py b/tests/functional/syntax/test_msg_data.py index a06c3e02ab..3803bd53af 100644 --- a/tests/functional/syntax/test_msg_data.py +++ b/tests/functional/syntax/test_msg_data.py @@ -42,9 +42,9 @@ def foo(bar: uint256) -> Bytes[36]: contract = get_contract(code) # 2fbebd38000000000000000000000000000000000000000000000000000000000000002a - foo_method_id = method_id("foo(uint256)").hex() # 2fbebd38 - encoded_42 = to_bytes(42).hex() # 2a - expected_result = foo_method_id + "00" * 31 + 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 From b1119433c38cecf7c326e8986c405296614ac2ff Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Thu, 4 Apr 2024 21:20:13 +0200 Subject: [PATCH 45/87] Run all combinations of pyevm and revm --- .github/workflows/test.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 387f5e748d..69079d2dd8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -81,7 +81,6 @@ jobs: debug: false opt-mode: gas evm-version: london - evm-backend: [revm, py-evm] - python-version: ["3.11", "311"] debug: false @@ -98,7 +97,6 @@ jobs: debug: false opt-mode: gas evm-version: cancun - evm-backend: [revm, py-evm] # test experimental pipeline - python-version: ["3.11", "311"] @@ -128,8 +126,14 @@ 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 }}-${{ matrix.evm-backend }} + 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 @@ -155,7 +159,7 @@ jobs: -m "not fuzzing" \ --optimize ${{ matrix.opt-mode }} \ --evm-version ${{ matrix.evm-version }} \ - ${{ matrix.evm-backend && '--evm-backend ${{ matrix.evm-backend }}' || '' }} \ + ${{ matrix.evm-backend && format('--evm-backend {0}', matrix.evm-backend) || '' }} \ ${{ matrix.debug && '--enable-compiler-debug-mode' || '' }} \ ${{ matrix.memorymock && '--memorymock' || '' }} \ ${{ matrix.experimental-codegen && '--experimental-codegen' || '' }} \ From cbb07c3fde351f447063d6691264925a9f0510f3 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Thu, 4 Apr 2024 21:45:03 +0200 Subject: [PATCH 46/87] Py-evm and experimental fixes --- .github/workflows/test.yml | 15 +++++++-------- tests/evm_backends/pyevm_env.py | 10 ++++++++-- .../builtins/codegen/test_abi_encode.py | 3 ++- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 69079d2dd8..bf9e35a62d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -126,14 +126,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 }} - ${{ matrix.evm-backend && format('-{0}', matrix.evm-backend) || '' }} + 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 diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index 694f0b339f..35a77c0642 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -146,11 +146,17 @@ def execute_code( except VMError as e: raise TransactionFailed(*e.args) from e finally: - self._state.clear_transient_storage() + self._clear_transient_storage() self._check_computation(computation) return computation.output + def _clear_transient_storage(self): + 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: @@ -193,7 +199,7 @@ def _deploy(self, code: bytes, value: int, gas: int = None) -> str: except VMError as e: raise TransactionFailed(*e.args) from e finally: - self._state.clear_transient_storage() + self._clear_transient_storage() self._check_computation(computation) return "0x" + target_address.hex() diff --git a/tests/functional/builtins/codegen/test_abi_encode.py b/tests/functional/builtins/codegen/test_abi_encode.py index 552d36c959..f1b290d394 100644 --- a/tests/functional/builtins/codegen/test_abi_encode.py +++ b/tests/functional/builtins/codegen/test_abi_encode.py @@ -227,8 +227,8 @@ def abi_encode( ] -@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") @pytest.mark.parametrize("args", nested_3d_array_args) +@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_abi_encode_nested_dynarray_2(get_contract, args): code = """ @external @@ -333,6 +333,7 @@ def foo(bs: DynArray[uint256, 3]) -> (uint256, Bytes[160]): assert c.foo(bs) == (2**256 - 1, abi.encode("(uint256[])", (bs,))) +@pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") def test_abi_encode_private_nested_dynarray(get_contract): code = """ bytez: Bytes[1696] From a39a347c3180ee995bc8a2fbae54dc8e3cdc6219 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 5 Apr 2024 09:36:21 +0200 Subject: [PATCH 47/87] Review comments --- .github/workflows/test.yml | 16 +- tests/conftest.py | 31 +-- tests/evm_backends/abi.py | 11 +- .../builtins/codegen/test_addmod.py | 12 +- .../builtins/codegen/test_as_wei_value.py | 4 +- .../builtins/codegen/test_bitwise.py | 12 +- .../functional/builtins/codegen/test_ceil.py | 12 +- .../builtins/codegen/test_concat.py | 28 +-- .../builtins/codegen/test_convert.py | 40 ++-- tests/functional/builtins/codegen/test_ec.py | 24 +-- .../builtins/codegen/test_ecrecover.py | 9 +- .../functional/builtins/codegen/test_empty.py | 54 +++--- .../builtins/codegen/test_extract32.py | 8 +- .../functional/builtins/codegen/test_floor.py | 12 +- .../builtins/codegen/test_is_contract.py | 6 +- .../builtins/codegen/test_keccak256.py | 20 +- .../builtins/codegen/test_length.py | 8 +- .../builtins/codegen/test_method_id.py | 4 +- .../builtins/codegen/test_minmax.py | 42 ++--- .../builtins/codegen/test_mulmod.py | 16 +- .../builtins/codegen/test_raw_call.py | 21 +-- .../functional/builtins/codegen/test_send.py | 5 +- .../builtins/codegen/test_sha256.py | 28 +-- .../functional/builtins/codegen/test_slice.py | 8 +- .../builtins/codegen/test_uint2str.py | 4 +- .../test_default_function.py | 28 +-- .../test_default_parameters.py | 5 +- .../test_external_contract_calls.py | 178 ++++++++---------- .../codegen/calling_convention/test_return.py | 43 ++--- .../test_block_number.py | 4 +- .../environment_variables/test_blockhash.py | 16 +- .../codegen/features/decorators/conftest.py | 6 +- .../features/decorators/test_private.py | 52 ++--- .../features/decorators/test_public.py | 16 +- .../codegen/features/decorators/test_view.py | 12 +- .../codegen/features/iteration/test_break.py | 16 +- .../features/iteration/test_continue.py | 20 +- .../features/iteration/test_for_in_list.py | 24 +-- .../features/iteration/test_for_range.py | 24 +-- .../features/iteration/test_range_in.py | 32 ++-- .../codegen/features/test_address_balance.py | 13 +- .../codegen/features/test_assert.py | 8 +- .../features/test_assert_unreachable.py | 9 +- .../codegen/features/test_assignment.py | 62 +++--- .../codegen/features/test_clampers.py | 33 ++-- .../codegen/features/test_comments.py | 4 +- .../codegen/features/test_conditionals.py | 12 +- .../codegen/features/test_constructor.py | 50 ++--- tests/functional/codegen/features/test_gas.py | 4 +- .../codegen/features/test_internal_call.py | 68 +++---- .../codegen/features/test_logging.py | 176 ++++++++--------- .../features/test_logging_bytes_extended.py | 20 +- .../features/test_logging_from_call.py | 4 +- .../codegen/features/test_packing.py | 4 +- .../codegen/features/test_reverting.py | 12 +- .../codegen/integration/test_basics.py | 8 +- .../codegen/integration/test_escrow.py | 14 +- .../codegen/storage_variables/test_getters.py | 8 +- .../codegen/storage_variables/test_setters.py | 16 +- .../test_storage_variable.py | 4 +- .../codegen/types/numbers/test_constants.py | 13 +- .../codegen/types/numbers/test_decimals.py | 20 +- .../codegen/types/numbers/test_isqrt.py | 28 +-- .../codegen/types/numbers/test_modulo.py | 8 +- .../codegen/types/numbers/test_signed_ints.py | 8 +- .../codegen/types/numbers/test_sqrt.py | 20 +- tests/functional/codegen/types/test_bytes.py | 28 +-- .../codegen/types/test_bytes_literal.py | 8 +- .../codegen/types/test_bytes_zero_padding.py | 4 +- .../codegen/types/test_dynamic_array.py | 120 ++++++------ tests/functional/codegen/types/test_flag.py | 12 +- tests/functional/codegen/types/test_lists.py | 68 +++---- tests/functional/codegen/types/test_string.py | 34 ++-- .../codegen/types/test_string_literal.py | 12 +- .../examples/auctions/test_blind_auction.py | 16 +- .../auctions/test_simple_open_auction.py | 10 +- .../examples/company/test_company.py | 6 +- tests/functional/examples/conftest.py | 6 +- .../test_on_chain_market_maker.py | 4 +- .../examples/tokens/test_erc1155.py | 5 +- .../functional/examples/tokens/test_erc20.py | 5 +- .../functional/examples/tokens/test_erc721.py | 5 +- .../functional/examples/voting/test_ballot.py | 11 +- .../functional/examples/wallet/test_wallet.py | 5 +- tests/functional/syntax/test_as_wei_value.py | 4 +- tests/functional/syntax/test_bool.py | 8 +- tests/functional/syntax/test_bool_ops.py | 4 +- tests/functional/syntax/test_chainid.py | 4 +- tests/functional/syntax/test_concat.py | 4 +- tests/functional/syntax/test_extract32.py | 8 +- tests/functional/syntax/test_no_none.py | 24 +-- tests/functional/syntax/test_self_balance.py | 4 +- tests/functional/syntax/test_string.py | 4 +- tests/utils.py | 2 + 94 files changed, 930 insertions(+), 1032 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bf9e35a62d..a05c72c6e6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -64,7 +64,6 @@ jobs: tests: runs-on: ubuntu-latest strategy: - fail-fast: false matrix: python-version: [["3.11", "311"]] opt-mode: ["gas", "none", "codesize"] @@ -72,7 +71,7 @@ jobs: evm-version: [shanghai] experimental-codegen: [false] memorymock: [false] - evm-backend: [revm, py-evm] + evm-backend: [revm] # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs#expanding-or-adding-matrix-configurations include: @@ -98,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 diff --git a/tests/conftest.py b/tests/conftest.py index 543e22fda7..f9e65a80de 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -109,7 +109,7 @@ def _xfail(*args, **kwargs): @pytest.fixture(scope="session", autouse=True) -def evm_version(pytestconfig, evm_backend): +def evm_version(pytestconfig): version = pytestconfig.getoption("evm_version") # note: configure the evm version that we emit code for. # The env will read this fixture and apply the evm version there. @@ -185,21 +185,14 @@ def gas_limit(): @pytest.fixture(scope="module") -def initial_balance(): - return 0 # default balance for the deployer account - - -@pytest.fixture(scope="module") -def env(gas_limit, initial_balance, evm_version, evm_backend, tracing): - env = evm_backend( +def env(gas_limit, evm_version, evm_backend, tracing) -> PyEvmEnv | RevmEnv: + return evm_backend( gas_limit=gas_limit, tracing=tracing, block_number=1, evm_version=evm_version, account_keys=get_default_account_keys(), ) - env.set_balance(env.deployer, initial_balance) - return env @pytest.fixture @@ -238,24 +231,6 @@ def fn(source_code, *args, **kwargs): return fn -# todo: this should be removed and replaced with get_contract -@pytest.fixture(scope="module") -def get_contract_with_gas_estimation(get_contract): - return get_contract - - -# todo: this should be removed and replaced with get_contract -@pytest.fixture(scope="module") -def get_contract_module(get_contract): - return get_contract - - -# todo: this should be removed and replaced with get_contract -@pytest.fixture -def get_contract_with_gas_estimation_for_constants(get_contract): - return get_contract - - @pytest.fixture(scope="module") def deploy_blueprint_for(env, compiler_settings, output_formats): def fn(source_code, *args, **kwargs): diff --git a/tests/evm_backends/abi.py b/tests/evm_backends/abi.py index 2a87c03ef8..f1a29af197 100644 --- a/tests/evm_backends/abi.py +++ b/tests/evm_backends/abi.py @@ -12,15 +12,6 @@ _parsers: dict[str, ABITypeNode] = {} -class _Decoder(Decoder): - @classmethod - def visit_AddressNode( - cls, node: AddressNode, value: bytes, checksum: bool = True, **kwargs: Any - ) -> str | None: - address = super().visit_AddressNode(node, value, checksum, **kwargs) - return address if address != "0x0000000000000000000000000000000000000000" else None - - class _Encoder(Encoder): """ Custom encoder that converts some types to the expected format. @@ -61,7 +52,7 @@ def abi_encode(schema: str, data: Any) -> bytes: def abi_decode(schema: str, data: bytes) -> Any: - return _Decoder.decode(_get_parser(schema), data) + return Decoder.decode(_get_parser(schema), data) def is_abi_encodable(abi_type: str, data: Any) -> bool: diff --git a/tests/functional/builtins/codegen/test_addmod.py b/tests/functional/builtins/codegen/test_addmod.py index 595d7d588f..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 @@ -32,7 +32,7 @@ def foo(f: Foo) -> uint256: 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: @@ -51,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 @@ -81,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 278a114fe8..d9a06d6220 100644 --- a/tests/functional/builtins/codegen/test_as_wei_value.py +++ b/tests/functional/builtins/codegen/test_as_wei_value.py @@ -113,7 +113,7 @@ def foo(a: Foo) -> uint256: assert_side_effects_invoked(c1, lambda: c2.foo(c1.address)) -def test_internal_call(get_contract_with_gas_estimation): +def test_internal_call(get_contract): code = """ @external def foo() -> uint256: @@ -123,5 +123,5 @@ def foo() -> uint256: def bar() -> uint8: return 7 """ - c = get_contract_with_gas_estimation(code) + 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 0bf387cebf..0e57185d8d 100644 --- a/tests/functional/builtins/codegen/test_ceil.py +++ b/tests/functional/builtins/codegen/test_ceil.py @@ -2,7 +2,7 @@ from decimal import Decimal -def test_ceil(get_contract_with_gas_estimation): +def test_ceil(get_contract): code = """ x: decimal @@ -38,7 +38,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 @@ -49,7 +49,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 @@ -93,7 +93,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 @@ -124,7 +124,7 @@ def foo(a: Foo) -> int256: 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: @@ -135,6 +135,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 27a3d0d519..cda1c8888f 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 @@ -422,9 +420,7 @@ 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 @@ -449,9 +445,9 @@ def test_convert() -> {o_typ}: skip_c1 = True if c1_exception is not None: - assert_compile_failed(lambda: get_contract_with_gas_estimation(contract_1), c1_exception) + assert_compile_failed(lambda: get_contract(contract_1), c1_exception) elif not skip_c1: - c1 = get_contract_with_gas_estimation(contract_1) + c1 = get_contract(contract_1) assert c1.test_convert() == expected_val contract_2 = f""" @@ -460,7 +456,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(val) == expected_val contract_3 = f""" @@ -472,7 +468,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""" @@ -482,13 +478,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(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: @@ -503,18 +499,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 @@ -526,7 +520,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 @@ -534,7 +528,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 @@ -662,9 +656,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). @@ -695,7 +687,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 @@ -704,7 +696,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() @@ -714,6 +706,6 @@ 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) with tx_failed(): c3.foo(val) diff --git a/tests/functional/builtins/codegen/test_ec.py b/tests/functional/builtins/codegen/test_ec.py index fdc864866a..65fb846021 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,7 +55,7 @@ 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 @@ -76,7 +76,7 @@ def foo(a: Foo) -> uint256[2]: assert_side_effects_invoked(c1, lambda: c2.foo(c1.address, transact={})) -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,7 +137,7 @@ 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 @@ -158,7 +158,7 @@ def foo(a: Foo) -> uint256[2]: assert_side_effects_invoked(c1, lambda: c2.foo(c1.address, transact={})) -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 6f630aed18..db2d32c7e8 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,7 +497,7 @@ 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 @@ -506,7 +506,7 @@ def e() -> X: 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,7 +523,7 @@ 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) @@ -535,7 +535,7 @@ def delete(key: bytes32): 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,7 +552,7 @@ 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) @@ -565,7 +565,7 @@ def delete(key1: bytes32, key2: bytes32): 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,7 +586,7 @@ 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={}) 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 1f394c28fe..e90ea63470 100644 --- a/tests/functional/builtins/codegen/test_floor.py +++ b/tests/functional/builtins/codegen/test_floor.py @@ -2,7 +2,7 @@ from decimal import Decimal -def test_floor(get_contract_with_gas_estimation): +def test_floor(get_contract): code = """ x: decimal @@ -41,7 +41,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 @@ -51,7 +51,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 @@ -97,7 +97,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 @@ -128,7 +128,7 @@ def foo(a: Foo) -> int256: assert_side_effects_invoked(c1, lambda: c2.foo(c1.address, transact={})) -def test_floor_internal_call(get_contract_with_gas_estimation): +def test_floor_internal_call(get_contract): code = """ @external def foo() -> int256: @@ -139,6 +139,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 47a5709a84..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(env, get_contract_with_gas_estimation): +def test_is_contract(env, get_contract): contract_1 = """ @external def foo(arg1: address) -> bool: @@ -12,8 +12,8 @@ def foo(arg1: address) -> bool: return arg1.is_contract """ a0, a1 = env.accounts[:2] - 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(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..7f9f7436ba 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,7 +61,7 @@ def try32(inp: bytes32) -> bool: return keccak256(inp) == keccak256(self.test) """ - c = get_contract_with_gas_estimation(hash_code3) + c = get_contract(hash_code3) c.set_test(b"", transact={}) assert c.tryy(b"") is True assert c.tryy_str("") is True @@ -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 f86504522f..eeaa8e6005 100644 --- a/tests/functional/builtins/codegen/test_minmax.py +++ b/tests/functional/builtins/codegen/test_minmax.py @@ -5,7 +5,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: @@ -16,7 +16,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("58223.123") assert c.goo() == 83 @@ -24,7 +24,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. @@ -60,7 +60,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 @@ -69,7 +69,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. @@ -103,7 +103,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 @@ -111,7 +111,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. @@ -145,7 +145,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 @@ -153,7 +153,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. @@ -167,7 +167,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 @@ -176,7 +176,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 @@ -185,7 +185,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 @@ -194,12 +194,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 = """ @@ -208,7 +206,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 @@ -216,10 +214,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: @@ -238,14 +236,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: @@ -264,7 +262,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 4f97af5c39..07369d7bdc 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,7 +27,7 @@ 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 @@ -50,7 +50,7 @@ def foo(f: Foo) -> uint256: assert_side_effects_invoked(c1, lambda: c2.foo(c1.address, transact={})) -def test_uint256_mulmod_internal_call(get_contract_with_gas_estimation): +def test_uint256_mulmod_internal_call(get_contract): code = """ @external def foo() -> uint256: @@ -69,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 @@ -99,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 c3f8cd161f..df56568e4b 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(env, 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,7 +73,7 @@ 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={}) @@ -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) @@ -164,7 +165,7 @@ def set(i: int128, owner: address): # 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. outer_contract.set(1, a1) @@ -635,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 4a50892d0d..763771f64f 100644 --- a/tests/functional/builtins/codegen/test_send.py +++ b/tests/functional/builtins/codegen/test_send.py @@ -1,3 +1,6 @@ +from tests.utils import ZERO_ADDRESS + + def test_send(tx_failed, get_contract, env): send_test = """ @external @@ -51,7 +54,7 @@ def __default__(): sender.test_send(receiver.address, transact={"gas": 100000}) # no value transfer happened, variable was not changed - assert receiver.last_sender() is None + assert receiver.last_sender() == ZERO_ADDRESS assert env.get_balance(sender.address) == 1 assert env.get_balance(receiver.address) == 0 diff --git a/tests/functional/builtins/codegen/test_sha256.py b/tests/functional/builtins/codegen/test_sha256.py index 17e3dbc307..048de3ccd5 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) -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,7 +73,7 @@ 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={}) @@ -81,7 +81,7 @@ def bar() -> bytes32: 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 df824a67f9..f6487bd515 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 @@ -261,7 +261,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) @@ -273,7 +273,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 d7589c3047..9035258127 100644 --- a/tests/functional/codegen/calling_convention/test_default_function.py +++ b/tests/functional/codegen/calling_convention/test_default_function.py @@ -1,7 +1,7 @@ from eth_utils import to_wei -def test_throw_on_sending(env, tx_failed, get_contract_with_gas_estimation): +def test_throw_on_sending(env, tx_failed, get_contract): code = """ x: public(int128) @@ -9,7 +9,7 @@ def test_throw_on_sending(env, 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 env.get_balance(c.address) == 0 @@ -18,7 +18,7 @@ def __init__(): assert env.get_balance(c.address) == 0 -def test_basic_default(env, get_logs, get_contract_with_gas_estimation): +def test_basic_default(env, get_logs, get_contract): code = """ event Sent: sender: indexed(address) @@ -28,14 +28,14 @@ def test_basic_default(env, get_logs, get_contract_with_gas_estimation): def __default__(): log Sent(msg.sender) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) env.set_balance(env.deployer, 10**18) (log,) = get_logs(env.execute_code(c.address, value=10**17), 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(env, 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) @@ -51,14 +51,14 @@ def fooBar(a: int128 = 12345) -> int128: def __default__(): log Sent(msg.sender) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) (log,) = get_logs(env.execute_code(c.address, value=10**17), 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(env, tx_failed, get_contract_with_gas_estimation): +def test_basic_default_not_payable(env, tx_failed, get_contract): code = """ event Sent: sender: indexed(address) @@ -67,32 +67,32 @@ def test_basic_default_not_payable(env, tx_failed, get_contract_with_gas_estimat def __default__(): log Sent(msg.sender) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) with tx_failed(): env.execute_code(c.address, value=10**17) -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) @@ -100,7 +100,7 @@ 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(env, get_logs, get_contract, tx_failed): diff --git a/tests/functional/codegen/calling_convention/test_default_parameters.py b/tests/functional/codegen/calling_convention/test_default_parameters.py index 05aeab7bd4..8dff6371c7 100644 --- a/tests/functional/codegen/calling_convention/test_default_parameters.py +++ b/tests/functional/codegen/calling_convention/test_default_parameters.py @@ -1,6 +1,7 @@ import pytest from eth.codecs.abi.exceptions import EncodeError +from tests.utils import ZERO_ADDRESS from vyper.compiler import compile_code from vyper.exceptions import ( InvalidLiteral, @@ -138,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 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 5c5d8ecc26..e0ea71441c 100644 --- a/tests/functional/codegen/calling_convention/test_external_contract_calls.py +++ b/tests/functional/codegen/calling_convention/test_external_contract_calls.py @@ -15,14 +15,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: @@ -38,7 +38,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) @@ -56,7 +56,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: @@ -1251,7 +1251,7 @@ def get_lucky(contract_address: address) -> int128: 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,9 +1280,9 @@ 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={}) @@ -1352,7 +1352,7 @@ def foo(contract_address: address) -> int128: get_contract(contract_1) -def test_external_with_payable_value(env, get_contract_with_gas_estimation): +def test_external_with_payable_value(env, get_contract): contract_1 = """ @payable @external @@ -1383,8 +1383,8 @@ 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 @@ -1415,7 +1415,7 @@ def get_lucky(amount_to_send: uint256) -> int128: 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: @@ -1438,8 +1438,8 @@ 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) + c1 = get_contract(contract_1) + c2 = get_contract(contract_2) c2.set_contract(c1.address, transact={}) assert c2.get_lucky(1000) == 656598 @@ -1447,7 +1447,7 @@ def get_lucky(gas_amount: uint256) -> int128: 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 @@ -1470,13 +1470,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 @@ -1489,10 +1489,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 @@ -1500,7 +1500,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 = [ @@ -1543,11 +1543,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: @@ -1589,7 +1589,7 @@ def test(addr: address) -> (int128, address, Bytes[10]): 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 @@ -1612,15 +1612,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) == 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 @@ -1645,14 +1645,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) == 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 @@ -1673,14 +1673,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 @@ -1706,17 +1706,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) == 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 @@ -1744,14 +1742,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) == 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 @@ -1775,14 +1773,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 @@ -1804,17 +1802,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 @@ -1838,14 +1834,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 @@ -1867,14 +1863,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 @@ -1908,17 +1904,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) == 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 @@ -1955,14 +1949,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) == 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 @@ -2004,16 +1998,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) == 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 @@ -2039,17 +2031,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 @@ -2078,16 +2068,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 @@ -2127,8 +2115,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 @@ -2137,7 +2125,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 @@ -2162,14 +2150,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 @@ -2194,14 +2182,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]: @@ -2222,14 +2210,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]: @@ -2250,21 +2238,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: diff --git a/tests/functional/codegen/calling_convention/test_return.py b/tests/functional/codegen/calling_convention/test_return.py index f7f7515388..059cfdbf1a 100644 --- a/tests/functional/codegen/calling_convention/test_return.py +++ b/tests/functional/codegen/calling_convention/test_return.py @@ -1,19 +1,20 @@ 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(env, 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 @@ -35,7 +36,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 = """ @@ -84,10 +85,10 @@ 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_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") @@ -101,14 +102,14 @@ def out_very_long_bytes() -> (int128, Bytes[1024], int128, address): ) -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) + c = get_contract(code) assert c.abi[0]["outputs"] == [ {"type": "int128", "name": ""}, {"type": "address", "name": ""}, @@ -116,7 +117,7 @@ def out_literals() -> (int128, address, Bytes[6]): ] -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]): @@ -135,12 +136,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 @@ -173,7 +174,7 @@ 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") @@ -226,7 +227,7 @@ def test_values(a: address) -> (Bytes[6], uint256): 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): @@ -236,7 +237,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 @@ -253,12 +254,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 @@ -275,12 +276,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 @@ -329,7 +330,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) @@ -339,7 +340,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 @@ -386,7 +387,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/environment_variables/test_block_number.py b/tests/functional/codegen/environment_variables/test_block_number.py index 5c4ba3677b..fdb2277c0e 100644 --- a/tests/functional/codegen/environment_variables/test_block_number.py +++ b/tests/functional/codegen/environment_variables/test_block_number.py @@ -1,10 +1,10 @@ -def test_block_number(get_contract_with_gas_estimation, env, compiler_settings, output_formats): +def test_block_number(get_contract, env, compiler_settings, output_formats): 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 env.time_travel() diff --git a/tests/functional/codegen/environment_variables/test_blockhash.py b/tests/functional/codegen/environment_variables/test_blockhash.py index 475a28fddd..a7de637851 100644 --- a/tests/functional/codegen/environment_variables/test_blockhash.py +++ b/tests/functional/codegen/environment_variables/test_blockhash.py @@ -1,4 +1,4 @@ -def test_blockhash(get_contract_with_gas_estimation): +def test_blockhash(get_contract): block_number_code = """ @external def prev() -> bytes32: @@ -8,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, env): +def test_too_old_blockhash(tx_failed, get_contract, env): env.time_travel(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/features/decorators/conftest.py b/tests/functional/codegen/features/decorators/conftest.py index 1e98c3b24c..1765e5d928 100644 --- a/tests/functional/codegen/features/decorators/conftest.py +++ b/tests/functional/codegen/features/decorators/conftest.py @@ -1,6 +1,6 @@ import pytest -@pytest.fixture(scope="module") -def initial_balance(): - return 10**20 +@pytest.fixture(autouse=True) +def set_initial_balance(env): + env.set_balance(env.deployer, 10**20) diff --git a/tests/functional/codegen/features/decorators/test_private.py b/tests/functional/codegen/features/decorators/test_private.py index e612d1f3c5..16b444913e 100644 --- a/tests/functional/codegen/features/decorators/test_private.py +++ b/tests/functional/codegen/features/decorators/test_private.py @@ -2,7 +2,7 @@ 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: @@ -13,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 @@ -42,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: @@ -68,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: @@ -88,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: @@ -113,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]) @@ -135,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]) @@ -176,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={}) 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: @@ -207,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] @@ -260,7 +260,7 @@ 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 @@ -269,7 +269,7 @@ def test4() -> (Bytes[100]): 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]): @@ -288,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): @@ -315,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) -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]): @@ -362,7 +362,7 @@ 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") @@ -370,7 +370,7 @@ def test4(a: Bytes[40]) -> (int128, Bytes[100], Bytes[100]): 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]: @@ -385,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(env, get_contract_with_gas_estimation): +def test_private_payable(env, get_contract): code = """ @internal def _send_it(a: address, _value: uint256): @@ -407,7 +407,7 @@ def __default__(): pass """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) env.execute_code(c.address, value=to_wei(1, "ether")) assert env.get_balance(c.address) == to_wei(1, "ether") 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 4abde9c617..88aa48de3d 100644 --- a/tests/functional/codegen/features/iteration/test_break.py +++ b/tests/functional/codegen/features/iteration/test_break.py @@ -5,7 +5,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: @@ -19,7 +19,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("1")) == 0 assert c.foo(Decimal("2")) == 3 @@ -29,7 +29,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: @@ -48,7 +48,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("1")) == 0 assert c.foo(Decimal("2")) == 3 assert c.foo(Decimal("10")) == 10 @@ -57,7 +57,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: @@ -76,7 +76,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 @@ -119,5 +119,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 cbf7c5c36c..3f586f67cf 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={}) 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,7 +205,7 @@ 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 @@ -214,7 +214,7 @@ def data() -> int128: 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,7 +236,7 @@ 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={}) @@ -245,7 +245,7 @@ def iterate_return_second() -> address: 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,7 +267,7 @@ 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("0.0001"), transact={}) c.set(1, Decimal("1.1"), transact={}) @@ -278,7 +278,7 @@ def i_return(break_count: int128) -> decimal: assert c.ret(0) == c.i_return(0) == Decimal("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 e64a35811d..6b7db17c08 100644 --- a/tests/functional/codegen/features/iteration/test_for_range.py +++ b/tests/functional/codegen/features/iteration/test_for_range.py @@ -1,7 +1,7 @@ import pytest -def test_basic_repeater(get_contract_with_gas_estimation): +def test_basic_repeater(get_contract): basic_repeater = """ @external def repeat(z: int128) -> int128: @@ -10,7 +10,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 @@ -128,7 +128,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: @@ -144,11 +144,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: @@ -160,12 +160,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}: @@ -175,12 +175,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}: @@ -192,12 +192,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: @@ -210,7 +210,7 @@ def foo() -> bool: return True """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() is True diff --git a/tests/functional/codegen/features/iteration/test_range_in.py b/tests/functional/codegen/features/iteration/test_range_in.py index 564b14d524..e07fc58f8a 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(env, tx_failed, get_contract_with_gas_estimation): +def test_ownership(env, tx_failed, get_contract): code = """ owners: address[2] @@ -129,7 +129,7 @@ def is_owner() -> bool: return msg.sender in self.owners """ a1 = env.accounts[1] - c = get_contract_with_gas_estimation(code) + 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. @@ -146,7 +146,7 @@ def is_owner() -> bool: assert c.is_owner() is False -def test_in_fails_when_types_dont_match(get_contract_with_gas_estimation, 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 50d55abbf4..75cd6578fc 100644 --- a/tests/functional/codegen/features/test_address_balance.py +++ b/tests/functional/codegen/features/test_address_balance.py @@ -1,12 +1,4 @@ -import pytest - - -@pytest.fixture(scope="module") -def initial_balance(): - return 10**5 - - -def test_constant_address_balance(env, get_contract_with_gas_estimation): +def test_constant_address_balance(env, get_contract): code = """ a: constant(address) = 0x776Ba14735FF84789320718cf0aa43e91F7A8Ce1 @@ -17,10 +9,11 @@ def foo() -> uint256: """ address = "0x776Ba14735FF84789320718cf0aa43e91F7A8Ce1" - c = get_contract_with_gas_estimation(code) + c = get_contract(code) assert c.foo() == 0 + env.set_balance(env.deployer, 1337) env.execute_code(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 ee90fda9f7..a2a74fa818 100644 --- a/tests/functional/codegen/features/test_assert.py +++ b/tests/functional/codegen/features/test_assert.py @@ -7,13 +7,13 @@ def _fixup_err_str(e_info): return e_info.value.args[0].replace("execution reverted: ", "") -def test_assert_refund(env, 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) + c = get_contract(code) env.set_balance(env.deployer, 10**7) gas_sent = 10**6 with tx_failed(): @@ -23,7 +23,7 @@ def foo(): assert env.last_result["is_success"] is False -def test_assert_reason(env, get_contract_with_gas_estimation, tx_failed, memory_mocker): +def test_assert_reason(env, get_contract, tx_failed, memory_mocker): code = """ err: String[32] @@ -54,7 +54,7 @@ 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 tx_failed(exc_text="larger than one please"): diff --git a/tests/functional/codegen/features/test_assert_unreachable.py b/tests/functional/codegen/features/test_assert_unreachable.py index 58aef15240..35bc7420ae 100644 --- a/tests/functional/codegen/features/test_assert_unreachable.py +++ b/tests/functional/codegen/features/test_assert_unreachable.py @@ -1,17 +1,10 @@ -import pytest - - -@pytest.fixture(scope="module") -def initial_balance(): - return 10**20 - - 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) gas_sent = 10**6 diff --git a/tests/functional/codegen/features/test_assignment.py b/tests/functional/codegen/features/test_assignment.py index 39b4ce3cb3..adc2bfb122 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) + c = get_contract(code) c.set(transact={}) 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,7 +274,7 @@ def set(): def get() -> int128: return self.test_map2[self.test_map1[1].a].c """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) c.set(transact={}) 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_clampers.py b/tests/functional/codegen/features/test_clampers.py index 7fbc0186db..bee9ee4f9d 100644 --- a/tests/functional/codegen/features/test_clampers.py +++ b/tests/functional/codegen/features/test_clampers.py @@ -4,6 +4,7 @@ from eth.codecs import abi from eth_utils import keccak +from tests.utils import ZERO_ADDRESS from vyper.exceptions import StackTooDeep from vyper.utils import int_bounds @@ -33,21 +34,21 @@ def _make_invalid_dynarray_tx(revm_env, address, signature, data): revm_env.execute_code(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]: @@ -55,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 @@ -63,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] @@ -76,11 +77,11 @@ 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))) @@ -252,20 +253,14 @@ def foo(s: uint{bits}) -> uint{bits}: @pytest.mark.parametrize( - "value,expected", + "address", [ - ("0x0000000000000000000000000000000000000000", None), - ( - "0x0000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000001", - ), - ( - "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF", - "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF", - ), + ZERO_ADDRESS, + "0x0000000000000000000000000000000000000001", + "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF", ], ) -def test_address_clamper_passing(env, get_contract, value, expected): +def test_address_clamper_passing(env, get_contract, address): code = """ @external def foo(s: address) -> address: @@ -273,7 +268,7 @@ 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]) 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 b0f2f17960..0534a62896 100644 --- a/tests/functional/codegen/features/test_constructor.py +++ b/tests/functional/codegen/features/test_constructor.py @@ -4,7 +4,7 @@ from vyper.exceptions import StackTooDeep -def test_init_argument_test(get_contract_with_gas_estimation): +def test_init_argument_test(get_contract): init_argument_test = """ moose: int128 @@ -17,12 +17,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] @@ -38,11 +38,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 @@ -54,11 +54,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 @@ -70,19 +70,19 @@ 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(get_contract): large_input_code = """ @external def foo(x: int128) -> int128: return 3 """ - c = get_contract_with_gas_estimation(large_input_code) + c = get_contract(large_input_code) c.foo(1274124) c.foo(2**120) @@ -90,7 +90,7 @@ def foo(x: int128) -> int128: c.foo(2**130) -def test_large_input_code_2(env, get_contract_with_gas_estimation): +def test_large_input_code_2(env, get_contract): large_input_code_2 = """ @deploy def __init__(x: int128): @@ -101,15 +101,15 @@ def foo() -> int128: return 5 """ - get_contract_with_gas_estimation(large_input_code_2, *[17]) + get_contract(large_input_code_2, *[17]) with pytest.raises(EncodeError): - get_contract_with_gas_estimation(large_input_code_2, *[2**130]) + get_contract(large_input_code_2, *[2**130]) print("Passed invalid input tests") -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 @@ -125,11 +125,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 @@ -145,11 +145,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(env, get_contract_with_gas_estimation): +def test_nested_dynamic_array_constructor_arg(env, get_contract): code = """ foo: uint256 @@ -161,12 +161,12 @@ 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 @pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") -def test_nested_dynamic_array_constructor_arg_2(env, get_contract_with_gas_estimation): +def test_nested_dynamic_array_constructor_arg_2(env, get_contract): code = """ foo: int128 @@ -178,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, *[ [ @@ -191,7 +191,7 @@ def get_foo() -> int128: assert c.get_foo() == 9580 -def test_initialise_nested_dynamic_array(env, get_contract_with_gas_estimation): +def test_initialise_nested_dynamic_array(env, get_contract): code = """ foo: DynArray[DynArray[uint256, 3], 3] @@ -207,12 +207,12 @@ 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]] @pytest.mark.venom_xfail(raises=StackTooDeep, reason="stack scheduler regression") -def test_initialise_nested_dynamic_array_2(env, get_contract_with_gas_estimation): +def test_initialise_nested_dynamic_array_2(env, get_contract): code = """ foo: DynArray[DynArray[DynArray[int128, 3], 3], 3] @@ -236,7 +236,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..525d3e8e92 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 diff --git a/tests/functional/codegen/features/test_internal_call.py b/tests/functional/codegen/features/test_internal_call.py index 76264d2228..01cb34d941 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) @@ -72,7 +72,7 @@ def foo() -> (uint256, uint256): 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 = get_contract(code) c.set(transact={}) 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("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) + c = get_contract(code) assert c.bar() == (66, Decimal("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,7 +402,7 @@ 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) + c = get_contract(code) assert c.bar() == (b"hello world", Decimal("66.77"), 44) @@ -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")) -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" diff --git a/tests/functional/codegen/features/test_logging.py b/tests/functional/codegen/features/test_logging.py index 7390b80469..745d746737 100644 --- a/tests/functional/codegen/features/test_logging.py +++ b/tests/functional/codegen/features/test_logging.py @@ -19,7 +19,7 @@ pytestmark = pytest.mark.usefixtures("memory_mocker") -def test_empty_event_logging(get_logs, keccak, get_contract_with_gas_estimation): +def test_empty_event_logging(get_logs, keccak, get_contract): loggy_code = """ event MyLog: pass @@ -28,7 +28,7 @@ def foo(): log MyLog() """ - c = get_contract_with_gas_estimation(loggy_code) + c = get_contract(loggy_code) tx = c.foo(transact={}) event_id = keccak(bytes("MyLog()", "utf-8")) @@ -42,7 +42,7 @@ def foo(): assert log.event == "MyLog" -def test_event_logging_with_topics(get_logs, keccak, get_contract_with_gas_estimation): +def test_event_logging_with_topics(get_logs, keccak, get_contract): loggy_code = """ a: Bytes[3] @@ -56,7 +56,7 @@ def foo(): log MyLog(self.a) """ - c = get_contract_with_gas_estimation(loggy_code) + c = get_contract(loggy_code) tx_hash = c.foo(transact={}) event_id = keccak(bytes("MyLog(bytes)", "utf-8")) @@ -72,9 +72,7 @@ def foo(): } -def test_event_logging_with_multiple_topics( - env, 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) @@ -86,7 +84,7 @@ def foo(): log MyLog(-2, True, self) """ - c = get_contract_with_gas_estimation(loggy_code) + c = get_contract(loggy_code) tx_hash = c.foo(transact={}) event_id = keccak(bytes("MyLog(int128,bool,address)", "utf-8")) @@ -112,9 +110,7 @@ def foo(): assert logs[0].args.arg3 == c.address -def test_event_logging_with_multiple_topics_var_and_store( - 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) @@ -130,7 +126,7 @@ def foo(arg1: int128): log MyLog(arg1, a, self.b) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) tx_hash = c.foo(31337, transact={}) # Event is decoded correctly @@ -141,9 +137,7 @@ def foo(arg1: int128): assert log.args.arg3 == c.address -def test_logging_the_same_event_multiple_times_with_topics( - env, 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) @@ -160,7 +154,7 @@ def bar(): log MyLog(1, self) """ - c = get_contract_with_gas_estimation(loggy_code) + c = get_contract(loggy_code) tx_hash1 = c.foo(transact={}) logs_tx1 = get_logs(tx_hash1, c) log1, _ = logs_tx1 @@ -190,9 +184,7 @@ def bar(): assert logs_tx1[1].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]) @@ -205,7 +197,7 @@ def test_event_logging_cannot_have_more_than_three_topics( compile_code(loggy_code) -def test_event_logging_with_data(get_logs, keccak, get_contract_with_gas_estimation): +def test_event_logging_with_data(get_logs, keccak, get_contract): loggy_code = """ event MyLog: arg1: int128 @@ -215,7 +207,7 @@ def foo(): log MyLog(123) """ - c = get_contract_with_gas_estimation(loggy_code) + c = get_contract(loggy_code) tx_hash = c.foo(transact={}) event_id = keccak(bytes("MyLog(int128)", "utf-8")) @@ -235,9 +227,7 @@ def foo(): assert logs[0].args.arg1 == 123 -def test_event_logging_with_fixed_array_data( - env, 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] @@ -251,7 +241,7 @@ 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) + c = get_contract(loggy_code) tx_hash = c.foo(transact={}) event_id = keccak(bytes("MyLog(int128[2],uint256[3],int128[2][2])", "utf-8")) @@ -280,7 +270,7 @@ def foo(): assert logs[0].args.arg3 == [[1, 2], [1, 2]] -def test_logging_with_input_bytes_1(env, keccak, get_logs, 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] @@ -292,7 +282,7 @@ def foo(arg1: Bytes[29], arg2: Bytes[31]): log MyLog(b'bar', arg1, arg2) """ - c = get_contract_with_gas_estimation(loggy_code) + c = get_contract(loggy_code) tx_hash = c.foo(b"bar", b"foo", transact={}) event_id = keccak(bytes("MyLog(bytes,bytes,bytes)", "utf-8")) @@ -318,7 +308,7 @@ def foo(arg1: Bytes[29], arg2: Bytes[31]): assert logs[0].args.arg3 == b"foo" -def test_event_logging_with_bytes_input_2(env, 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] @@ -328,7 +318,7 @@ def foo(_arg1: Bytes[20]): log MyLog(_arg1) """ - c = get_contract_with_gas_estimation(loggy_code) + c = get_contract(loggy_code) tx_hash = c.foo(b"hello", transact={}) event_id = keccak(bytes("MyLog(bytes)", "utf-8")) @@ -375,9 +365,7 @@ def foo(_arg1: Bytes[5]): assert logs[0].args.arg1 == b"hello" -def test_event_logging_with_data_with_different_types( - env, 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 @@ -392,7 +380,7 @@ def foo(): log MyLog(123, b'home', b'bar', 0xc305c901078781C232A2a521C2aF7980f8385ee9, self, block.timestamp) # noqa: E501 """ - c = get_contract_with_gas_estimation(loggy_code) + c = get_contract(loggy_code) tx_hash = c.foo(transact={}) event_id = keccak(bytes("MyLog(int128,bytes,bytes,address,address,uint256)", "utf-8")) @@ -425,9 +413,7 @@ def foo(): assert args.arg6 == env.timestamp -def test_event_logging_with_topics_and_data_1( - env, 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) @@ -438,7 +424,7 @@ def foo(): log MyLog(1, b'bar') """ - c = get_contract_with_gas_estimation(loggy_code) + c = get_contract(loggy_code) tx_hash = c.foo(transact={}) event_id = keccak(bytes("MyLog(int128,bytes)", "utf-8")) @@ -462,9 +448,7 @@ def foo(): assert args.arg2.removesuffix(b"\0") == b"bar" -def test_event_logging_with_multiple_logs_topics_and_data( - env, 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] @@ -487,7 +471,7 @@ 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) + c = get_contract(loggy_code) tx_hash = c.foo(transact={}) log1, log2 = get_logs(tx_hash, c) @@ -544,7 +528,7 @@ def foo(): assert args.arg2 == (1, b"abc", ("house", Decimal("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) @@ -555,10 +539,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]) @@ -570,10 +554,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]) @@ -584,10 +568,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] @@ -598,10 +582,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] @@ -612,10 +596,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]) @@ -624,10 +608,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) @@ -641,10 +625,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 @@ -655,10 +639,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 @@ -667,10 +651,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) @@ -681,10 +665,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] @@ -695,11 +679,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: @@ -710,12 +694,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 @@ -726,10 +708,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(get_logs, get_contract_with_gas_estimation): +def test_loggy_code(get_logs, get_contract): loggy_code = """ s: Bytes[100] @@ -751,7 +733,7 @@ def ioo(inp: Bytes[100]): raw_log([], inp) """ - c = get_contract_with_gas_estimation(loggy_code) + c = get_contract(loggy_code) tx_hash = c.foo(transact={}) ((topics, data),) = get_logs(tx_hash, c, raw=True) @@ -776,7 +758,7 @@ def ioo(inp: Bytes[100]): print("Passed raw log tests") -def test_raw_call_bytes32_data(get_logs, get_contract_with_gas_estimation): +def test_raw_call_bytes32_data(get_logs, get_contract): code = """ b: uint256 @@ -789,7 +771,7 @@ def foo(): raw_log([], convert(b"testmessage", bytes32)) raw_log([], keccak256(b"")) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) tx_hash = c.foo(transact={}) logs = get_logs(tx_hash, c, raw=True) assert logs[0][1] == (1234).to_bytes(32, "big") @@ -798,7 +780,7 @@ def foo(): 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] @@ -808,14 +790,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] -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] @@ -824,14 +806,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] -def test_storage_list_packing(get_logs, get_contract_with_gas_estimation): +def test_storage_list_packing(get_logs, get_contract): code = """ event Bar: _value: int128[4] @@ -846,7 +828,7 @@ 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") @@ -857,7 +839,7 @@ def set_list(): assert logs[0].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] @@ -866,14 +848,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] -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] @@ -882,7 +864,7 @@ 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") @@ -894,7 +876,7 @@ def foo(): ] -def test_storage_byte_packing(get_logs, get_contract_with_gas_estimation): +def test_storage_byte_packing(get_logs, get_contract): code = """ event MyLog: arg1: Bytes[29] @@ -910,7 +892,7 @@ def setbytez(): self.x = b'hello' """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) tx_hash = c.foo(0, transact={}) logs = get_logs(tx_hash, c, "MyLog") assert logs[0].args.arg1 == b"" @@ -920,7 +902,7 @@ def setbytez(): assert logs[0].args.arg1 == b"hello" -def test_storage_decimal_list_packing(get_logs, get_contract_with_gas_estimation): +def test_storage_decimal_list_packing(get_logs, get_contract): code = """ event Bar: _value: decimal[4] @@ -935,7 +917,7 @@ def foo(): def set_list(): self.x = [1.33, 2.33, 3.33, 4.33] """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) tx_hash = c.foo(transact={}) logs = get_logs(tx_hash, c, "Bar") @@ -951,7 +933,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]) @@ -961,10 +943,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 @@ -975,13 +957,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] -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 @@ -997,7 +979,7 @@ 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] @@ -1006,7 +988,7 @@ def set_list(): assert get_logs(tx_hash, 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 @@ -1031,7 +1013,7 @@ 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={}) log = get_logs(tx_hash, c, "Bar")[0] @@ -1245,5 +1227,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..ed3ed5256b 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,7 +10,7 @@ def foo(): log MyLog(667788, b'hellohellohellohellohellohellohellohellohello', 334455) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) log = get_logs(c.foo(transact={}), c, "MyLog") assert log[0].args.arg1 == 667788 @@ -18,7 +18,7 @@ def foo(): assert log[0].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,7 +33,7 @@ def foo(): log MyLog(a, b, b'hello') """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) log = get_logs(c.foo(transact={}), c, "MyLog") assert log[0].args.arg1 == b"hello" * 9 @@ -41,7 +41,7 @@ def foo(): assert log[0].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,7 +53,7 @@ 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") @@ -62,7 +62,7 @@ def foo(a: int128, b: Bytes[64], c: int128): 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,7 +84,7 @@ 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") @@ -101,7 +101,7 @@ def set(x: int128, y: Bytes[64], z: int128): 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,7 +119,7 @@ def foo(): ) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) log = get_logs(c.foo(transact={}), c, "MyLog")[0] assert log.args.arg1 == [[24, 26], [12, 10]] diff --git a/tests/functional/codegen/features/test_logging_from_call.py b/tests/functional/codegen/features/test_logging_from_call.py index 222cd1dff8..86ee4c6bfb 100644 --- a/tests/functional/codegen/features/test_logging_from_call.py +++ b/tests/functional/codegen/features/test_logging_from_call.py @@ -4,7 +4,7 @@ pytestmark = pytest.mark.usefixtures("memory_mocker") -def test_log_dynamic_static_combo(get_logs, get_contract_with_gas_estimation): +def test_log_dynamic_static_combo(get_logs, get_contract): code = """ event TestLog: testData1: bytes32 @@ -31,7 +31,7 @@ def test_func(_value: uint256): log TestLog(loggedValue, data2, loggedValue2) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) tx_hash = c.test_func(123, transact={}) 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 b39f4ac2c1..932f9fe826 100644 --- a/tests/functional/codegen/features/test_reverting.py +++ b/tests/functional/codegen/features/test_reverting.py @@ -7,7 +7,7 @@ pytestmark = pytest.mark.usefixtures("memory_mocker") -def test_revert_reason(env, tx_failed, get_contract_with_gas_estimation): +def test_revert_reason(env, tx_failed, get_contract): reverty_code = """ @external def foo(): @@ -18,10 +18,10 @@ def foo(): revert_bytes = method_id("NoFives()") with tx_failed(TransactionFailed, exc_text=revert_bytes.hex()): - get_contract_with_gas_estimation(reverty_code).foo(transact={}) + get_contract(reverty_code).foo(transact={}) -def test_revert_reason_typed(env, tx_failed, get_contract_with_gas_estimation): +def test_revert_reason_typed(env, tx_failed, get_contract): reverty_code = """ @external def foo(): @@ -33,10 +33,10 @@ def foo(): revert_bytes = method_id("NoFives(uint256)") + abi.encode("(uint256)", (5,)) with tx_failed(TransactionFailed, exc_text=revert_bytes.hex()): - get_contract_with_gas_estimation(reverty_code).foo(transact={}) + get_contract(reverty_code).foo(transact={}) -def test_revert_reason_typed_no_variable(env, tx_failed, get_contract_with_gas_estimation): +def test_revert_reason_typed_no_variable(env, tx_failed, get_contract): reverty_code = """ @external def foo(): @@ -47,4 +47,4 @@ def foo(): revert_bytes = method_id("NoFives(uint256)") + abi.encode("(uint256)", (5,)) with tx_failed(TransactionFailed, exc_text=revert_bytes.hex()): - get_contract_with_gas_estimation(reverty_code).foo(transact={}) + get_contract(reverty_code).foo(transact={}) 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_escrow.py b/tests/functional/codegen/integration/test_escrow.py index c3b1fd800d..7883f18233 100644 --- a/tests/functional/codegen/integration/test_escrow.py +++ b/tests/functional/codegen/integration/test_escrow.py @@ -1,12 +1,12 @@ import pytest -@pytest.fixture(scope="module") -def initial_balance(): - return 10**20 +@pytest.fixture(autouse=True) +def set_initial_balance(env): + env.set_balance(env.deployer, 10**20) -def test_arbitration_code(env, get_contract_with_gas_estimation, tx_failed): +def test_arbitration_code(env, get_contract, tx_failed): arbitration_code = """ buyer: address seller: address @@ -31,7 +31,7 @@ def refund(): """ a0, a1, a2 = env.accounts[:3] - c = get_contract_with_gas_estimation(arbitration_code, value=1) + c = get_contract(arbitration_code, value=1) c.setup(a1, a2, transact={}) with tx_failed(): c.finalize(transact={"from": a1}) @@ -40,7 +40,7 @@ def refund(): print("Passed escrow test") -def test_arbitration_code_with_init(env, 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 @@ -65,7 +65,7 @@ def refund(): send(self.buyer, self.balance) """ a0, a1, a2 = env.accounts[:3] - c = get_contract_with_gas_estimation(arbitration_code_with_init, *[a1, a2], value=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}) diff --git a/tests/functional/codegen/storage_variables/test_getters.py b/tests/functional/codegen/storage_variables/test_getters.py index cc27006e52..73be3a40b3 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 = get_contract(state_accessor) c.oo(transact={}) 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" diff --git a/tests/functional/codegen/storage_variables/test_setters.py b/tests/functional/codegen/storage_variables/test_setters.py index cf4138b939..5710fe5a35 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,7 +54,7 @@ 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={}) assert c.fop() == 654321 @@ -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/types/numbers/test_constants.py b/tests/functional/codegen/types/numbers/test_constants.py index a97efefdd5..030d338dea 100644 --- a/tests/functional/codegen/types/numbers/test_constants.py +++ b/tests/functional/codegen/types/numbers/test_constants.py @@ -3,6 +3,7 @@ import pytest +from tests.utils import ZERO_ADDRESS from vyper.compiler import compile_code from vyper.exceptions import TypeMismatch from vyper.utils import MemoryPositions @@ -15,7 +16,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,12 +48,12 @@ 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) @@ -74,7 +75,7 @@ def test_arithmetic(a: int128) -> int128: 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: @@ -112,14 +113,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() == Decimal(2**167 - 1) / 10**10 assert c.loo() == Decimal(-(2**167)) / 10**10 diff --git a/tests/functional/codegen/types/numbers/test_decimals.py b/tests/functional/codegen/types/numbers/test_decimals.py index 30a5b5367f..a64425d6fc 100644 --- a/tests/functional/codegen/types/numbers/test_decimals.py +++ b/tests/functional/codegen/types/numbers/test_decimals.py @@ -51,7 +51,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: @@ -99,7 +99,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 @@ -116,7 +116,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: @@ -148,7 +148,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("1.2")) == Decimal("20736.0") assert c.phooey(Decimal("-1.2")) == Decimal("20736.0") assert c.arg(Decimal("-3.7")) == Decimal("-3.7") @@ -160,7 +160,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 @@ -169,7 +169,7 @@ def _num_mul(x: decimal, y: decimal) -> decimal: """ - c = get_contract_with_gas_estimation(mul_code) + c = get_contract(mul_code) x = Decimal("85070591730234615865843651857942052864") y = Decimal("136112946768375385385349842973") @@ -236,7 +236,7 @@ def foo(x: decimal, y: decimal) -> decimal: assert c.foo(x, 1 + DECIMAL_EPSILON) == quantize(x / (1 + DECIMAL_EPSILON)) -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(): @@ -245,13 +245,13 @@ def maximum(): def minimum(): a: decimal = -18707220957835557353007165858768422651595.9365500928 """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) 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: @@ -261,7 +261,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("1e-10") # Smallest possible decimal assert c.bar(Decimal("1e37")) == Decimal("-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 db4ba21f58..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,7 +100,7 @@ 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") diff --git a/tests/functional/codegen/types/numbers/test_modulo.py b/tests/functional/codegen/types/numbers/test_modulo.py index e5c2e7eab0..3ac2f6ce96 100644 --- a/tests/functional/codegen/types/numbers/test_modulo.py +++ b/tests/functional/codegen/types/numbers/test_modulo.py @@ -5,7 +5,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: @@ -24,20 +24,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(".18") assert c.decimal_modulo_num() == Decimal(".5") assert c.num_modulo_decimal() == Decimal(".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("1"), Decimal("0")) diff --git a/tests/functional/codegen/types/numbers/test_signed_ints.py b/tests/functional/codegen/types/numbers/test_signed_ints.py index e063f981ec..87c48709e3 100644 --- a/tests/functional/codegen/types/numbers/test_signed_ints.py +++ b/tests/functional/codegen/types/numbers/test_signed_ints.py @@ -134,7 +134,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}: @@ -150,14 +150,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""" @@ -186,7 +186,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 e91ea92c06..c8b41e9779 100644 --- a/tests/functional/codegen/types/numbers/test_sqrt.py +++ b/tests/functional/codegen/types/numbers/test_sqrt.py @@ -22,17 +22,17 @@ def decimal_sqrt(val): return 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")) -def test_sqrt_variable(get_contract_with_gas_estimation): +def test_sqrt_variable(get_contract): code = """ @external def test(a: decimal) -> decimal: @@ -44,7 +44,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(val) == decimal_sqrt(val) @@ -56,7 +56,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 @@ -71,7 +71,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(val) == decimal_sqrt(val + 1) val = Decimal("100.01") @@ -79,7 +79,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]): @@ -91,7 +91,7 @@ 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(val) == ( @@ -120,13 +120,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 diff --git a/tests/functional/codegen/types/test_bytes.py b/tests/functional/codegen/types/test_bytes.py index f8ae65cc54..cea71d5e56 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,7 +79,7 @@ def get_xy() -> int128: return self.x * self.y """ - c = get_contract_with_gas_estimation(test_bytes3) + c = get_contract(test_bytes3) c.set_maa(b"pig", transact={}) assert c.get_maa() == b"pig" assert c.get_maa2() == b"pig" @@ -96,7 +96,7 @@ def get_xy() -> int128: 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,7 +159,7 @@ def quz(inp1: Bytes[40], inp2: Bytes[45]): self.g.b = h.b """ - c = get_contract_with_gas_estimation(test_bytes5) + c = get_contract(test_bytes5) c.foo(b"cow", b"horse", transact={}) assert c.check1() == b"cow" assert c.check2() == b"horse" @@ -172,7 +172,7 @@ def quz(inp1: Bytes[40], inp2: Bytes[45]): 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 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 909eb2f0b9..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,7 +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) """ - return get_contract_module(code) + 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 fb5614c31a..12ee0288a6 100644 --- a/tests/functional/codegen/types/test_dynamic_array.py +++ b/tests/functional/codegen/types/test_dynamic_array.py @@ -15,7 +15,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 +52,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 @@ -103,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 @@ -204,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] @@ -229,7 +229,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: @@ -241,12 +241,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: @@ -258,12 +258,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: @@ -280,11 +280,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: @@ -313,11 +313,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 @@ -344,9 +344,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 @@ -359,9 +357,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 @@ -380,8 +376,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 = """ @@ -416,10 +411,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( @@ -445,21 +437,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: @@ -473,7 +465,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 @@ -486,7 +478,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: @@ -498,7 +490,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 @@ -508,7 +500,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: @@ -538,7 +530,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 @@ -548,7 +540,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: @@ -578,7 +570,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 @@ -588,7 +580,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: @@ -597,11 +589,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: @@ -620,11 +612,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 @@ -638,11 +630,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 @@ -660,11 +652,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 @@ -679,11 +671,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 @@ -702,11 +694,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]: @@ -728,7 +720,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() == [[1.0], [3.0, 4.0]] assert c.test_array_decimal_return2() == [[1.0, 2.0]] @@ -736,7 +728,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] @@ -768,7 +760,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 @@ -778,13 +770,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) @@ -801,37 +793,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(): @@ -840,14 +832,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 @@ -855,17 +847,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): diff --git a/tests/functional/codegen/types/test_flag.py b/tests/functional/codegen/types/test_flag.py index 0024b17df3..2eb490f1ad 100644 --- a/tests/functional/codegen/types/test_flag.py +++ b/tests/functional/codegen/types/test_flag.py @@ -224,7 +224,7 @@ def checkMinter(minter: address): 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 14acdaaf28..de3178b793 100644 --- a/tests/functional/codegen/types/test_lists.py +++ b/tests/functional/codegen/types/test_lists.py @@ -5,7 +5,7 @@ from vyper.exceptions import ArrayIndexException, OverflowException, TypeMismatch -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] @@ -42,7 +42,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 @@ -52,7 +52,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] @@ -107,7 +107,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] @@ -123,7 +123,7 @@ def roo(inp: decimal[2]) -> decimal[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: @@ -135,12 +135,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: @@ -152,12 +152,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: @@ -174,11 +174,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: @@ -207,11 +207,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: @@ -223,9 +223,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 @@ -238,9 +236,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 @@ -259,8 +255,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 = """ @@ -295,13 +290,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]: @@ -323,14 +315,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() == [[1.0, 2.0], [3.0, 4.0]] assert c.test_array_decimal_return2() == [[1.0, 2.0], [3.0, 4.0]] assert c.test_array_decimal_return3() == [[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]: @@ -343,7 +335,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() == [ @@ -353,14 +345,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(): @@ -368,14 +360,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(): @@ -384,31 +376,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): diff --git a/tests/functional/codegen/types/test_string.py b/tests/functional/codegen/types/test_string.py index 6f0ca718a5..5e9d8abf45 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,7 +35,7 @@ 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" @@ -61,14 +61,14 @@ def get(k: String[34]) -> int128: 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,7 +121,7 @@ def foo(): log MyLog(667788, 'hellohellohellohellohellohellohellohellohello', 334455) """ - c = get_contract_with_gas_estimation(code) + c = get_contract(code) log = get_logs(c.foo(transact={}), c, "MyLog") assert log[0].args.arg1 == 667788 @@ -129,7 +129,7 @@ def foo(): assert log[0].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 +148,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") -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 +165,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 +189,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 +332,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/examples/auctions/test_blind_auction.py b/tests/functional/examples/auctions/test_blind_auction.py index 5fc339ee35..8c8da4ac25 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,12 +10,12 @@ @pytest.fixture -def auction_contract(env, get_contract, initial_balance): +def auction_contract(env, get_contract): with open("examples/auctions/blind_auction.vy") as f: contract_code = f.read() for acc in env.accounts[1:4]: - env.set_balance(acc, initial_balance) + env.set_balance(acc, 10**20) return get_contract(contract_code, *[env.deployer, BIDDING_TIME, REVEAL_TIME]) @@ -30,7 +32,7 @@ def test_initial_state(env, 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(env, auction_contract, tx_failed, keccak): @@ -123,7 +125,7 @@ def test_early_reval(env, auction_contract, tx_failed, keccak): ) # 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 @@ -162,7 +164,7 @@ def test_late_reveal(env, auction_contract, tx_failed, keccak): ) # 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 @@ -189,10 +191,10 @@ def test_double_end(env, auction_contract, tx_failed): auction_contract.auctionEnd(transact={"value": 0, "from": k0}) -def test_blind_auction(env, initial_balance, auction_contract, keccak): +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, initial_balance) + env.set_balance(acc, 10**20) ################################################################### # Place bids # diff --git a/tests/functional/examples/auctions/test_simple_open_auction.py b/tests/functional/examples/auctions/test_simple_open_auction.py index 92fa2efed3..54023286a4 100644 --- a/tests/functional/examples/auctions/test_simple_open_auction.py +++ b/tests/functional/examples/auctions/test_simple_open_auction.py @@ -1,5 +1,7 @@ import pytest +from tests.utils import ZERO_ADDRESS + EXPIRY = 16 @@ -9,12 +11,12 @@ def auction_start(env): @pytest.fixture -def auction_contract(env, get_contract, auction_start, initial_balance): +def auction_contract(env, get_contract, auction_start): with open("examples/auctions/simple_open_auction.vy") as f: contract_code = f.read() - for acc in env.accounts[1:5]: - env.set_balance(acc, initial_balance) + for acc in env.accounts[:5]: + env.set_balance(acc, 10**20) return get_contract(contract_code, *[env.accounts[0], auction_start, EXPIRY]) @@ -29,7 +31,7 @@ def test_initial_state(env, 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 diff --git a/tests/functional/examples/company/test_company.py b/tests/functional/examples/company/test_company.py index 7c034ad22f..193a983eef 100644 --- a/tests/functional/examples/company/test_company.py +++ b/tests/functional/examples/company/test_company.py @@ -2,12 +2,12 @@ @pytest.fixture -def c(env, initial_balance, get_contract): +def c(env, get_contract): with open("examples/stock/company.vy") as f: contract_code = f.read() - for acc in env.accounts[1:5]: - env.set_balance(acc, initial_balance) + for acc in env.accounts[:5]: + env.set_balance(acc, 10**20) return get_contract(contract_code, *[env.accounts[0], 1000, 10**6]) diff --git a/tests/functional/examples/conftest.py b/tests/functional/examples/conftest.py index 5a781ac83a..ec2a92afaf 100644 --- a/tests/functional/examples/conftest.py +++ b/tests/functional/examples/conftest.py @@ -6,6 +6,6 @@ def setup(memory_mocker): pass -@pytest.fixture(scope="module") -def initial_balance(): - return 10**20 +@pytest.fixture(autouse=True) +def set_initial_balance(env): + env.set_balance(env.deployer, 10**20) 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 9dfab7a79a..ec75a7ba29 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,6 +1,8 @@ import pytest from eth_utils import to_wei +from tests.utils import ZERO_ADDRESS + @pytest.fixture def market_maker(get_contract): @@ -29,7 +31,7 @@ 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(env, market_maker, erc20, tx_failed): diff --git a/tests/functional/examples/tokens/test_erc1155.py b/tests/functional/examples/tokens/test_erc1155.py index 71236de914..659e98a4b4 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 @@ -397,7 +398,7 @@ def test_ownership_functions(erc1155, env, 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}) diff --git a/tests/functional/examples/tokens/test_erc20.py b/tests/functional/examples/tokens/test_erc20.py index 3dcae2538e..52f8133c13 100644 --- a/tests/functional/examples/tokens/test_erc20.py +++ b/tests/functional/examples/tokens/test_erc20.py @@ -4,7 +4,8 @@ import pytest from eth.codecs.abi.exceptions import EncodeError -ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" +from tests.utils import ZERO_ADDRESS + MAX_UINT256 = (2**256) - 1 # Max uint256 value TOKEN_NAME = "Vypercoin" TOKEN_SYMBOL = "FANG" @@ -20,7 +21,7 @@ def c(get_contract, env): @pytest.fixture -def c_bad(get_contract, env): +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() diff --git a/tests/functional/examples/tokens/test_erc721.py b/tests/functional/examples/tokens/test_erc721.py index 8d44f31a7a..128e2d040c 100644 --- a/tests/functional/examples/tokens/test_erc721.py +++ b/tests/functional/examples/tokens/test_erc721.py @@ -1,10 +1,11 @@ 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" @@ -57,7 +58,7 @@ def test_ownerOf(c, env, tx_failed): 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}) diff --git a/tests/functional/examples/voting/test_ballot.py b/tests/functional/examples/voting/test_ballot.py index 4776d76184..0adafc8de4 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,7 +13,7 @@ def c(get_contract): return get_contract(contract_code, *[[PROPOSAL_1_NAME, PROPOSAL_2_NAME]]) -z0 = "0x0000000000000000000000000000000000000000" +z0 = ZERO_ADDRESS def test_initial_state(env, c): @@ -27,10 +29,7 @@ def test_initial_state(env, 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(env, c, tx_failed): @@ -39,7 +38,7 @@ def test_give_the_right_to_vote(env, c, tx_failed): # 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 diff --git a/tests/functional/examples/wallet/test_wallet.py b/tests/functional/examples/wallet/test_wallet.py index d58aae66d2..ae7f811203 100644 --- a/tests/functional/examples/wallet/test_wallet.py +++ b/tests/functional/examples/wallet/test_wallet.py @@ -4,6 +4,8 @@ from eth_keys import KeyAPI from eth_utils import is_same_address, to_bytes, to_checksum_address, to_int +from tests.utils import ZERO_ADDRESS + @pytest.fixture def c(env, get_contract): @@ -71,7 +73,6 @@ def pack_and_sign(seq, *args): 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", @@ -105,7 +106,7 @@ def test_javascript_signatures(env, get_contract, keccak): # Set the owners to zero addresses with open("examples/wallet/wallet.vy") as f: - owners = [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]) env.execute_code(x2.address, value=10**17) 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 54a3f706e6..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, env): +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) + c = get_contract(code) assert c.get_chain_id() == env.DEFAULT_CHAIN_ID 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_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_self_balance.py b/tests/functional/syntax/test_self_balance.py index 2f0e144fc4..906f078593 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(env, get_contract_with_gas_estimation): +def test_self_balance(env, get_contract): code = """ @external @view @@ -17,7 +17,7 @@ def __default__(): opcodes = compiler.compile_code(code, output_formats=["opcodes"])["opcodes"] assert "SELFBALANCE" in opcodes - c = get_contract_with_gas_estimation(code) + c = get_contract(code) env.set_balance(env.deployer, 1337) env.execute_code(**{"to": c.address, "value": 1337}) 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/utils.py b/tests/utils.py index 25dad818ca..4005eb50c8 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -4,6 +4,8 @@ from vyper import ast as vy_ast from vyper.semantics.analysis.constant_folding import constant_fold +ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" + @contextlib.contextmanager def working_directory(directory): From dea863a7154a0c25d9c3a937662d633b57e0525b Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 5 Apr 2024 10:12:04 +0200 Subject: [PATCH 48/87] Unused parameters --- tests/conftest.py | 2 +- .../builtins/codegen/test_convert.py | 10 +- .../builtins/codegen/test_create_functions.py | 32 +-- tests/functional/builtins/codegen/test_ec.py | 4 +- .../functional/builtins/codegen/test_empty.py | 15 +- .../functional/builtins/codegen/test_floor.py | 2 +- .../builtins/codegen/test_keccak256.py | 8 +- .../builtins/codegen/test_mulmod.py | 2 +- .../builtins/codegen/test_raw_call.py | 6 +- .../functional/builtins/codegen/test_send.py | 6 +- .../builtins/codegen/test_sha256.py | 2 +- .../test_default_function.py | 18 +- .../calling_convention/test_erc20_abi.py | 12 +- .../test_external_contract_calls.py | 20 +- ...test_modifiable_external_contract_calls.py | 18 +- .../features/decorators/test_nonreentrant.py | 18 +- .../features/decorators/test_private.py | 12 +- .../features/iteration/test_for_in_list.py | 16 +- .../features/iteration/test_for_range.py | 2 +- .../features/iteration/test_range_in.py | 4 +- .../codegen/features/test_assignment.py | 4 +- .../codegen/features/test_bytes_map_keys.py | 4 +- .../codegen/features/test_immutable.py | 4 +- .../codegen/features/test_internal_call.py | 2 +- .../codegen/features/test_logging.py | 267 ++++++++---------- .../features/test_logging_bytes_extended.py | 33 ++- .../features/test_logging_from_call.py | 51 ++-- .../codegen/features/test_reverting.py | 6 +- .../codegen/features/test_short_circuiting.py | 8 +- .../codegen/features/test_ternary.py | 2 +- .../codegen/features/test_transient.py | 11 +- .../codegen/integration/test_crowdfund.py | 8 +- .../codegen/integration/test_escrow.py | 4 +- .../functional/codegen/modules/test_events.py | 17 +- .../codegen/modules/test_module_variables.py | 10 +- .../modules/test_stateless_functions.py | 2 +- .../codegen/storage_variables/test_getters.py | 2 +- .../codegen/storage_variables/test_setters.py | 4 +- tests/functional/codegen/test_interfaces.py | 4 +- .../functional/codegen/test_selector_table.py | 8 +- .../codegen/types/test_array_indexing.py | 16 +- tests/functional/codegen/types/test_bytes.py | 18 +- tests/functional/codegen/types/test_flag.py | 12 +- tests/functional/codegen/types/test_string.py | 9 +- .../examples/company/test_company.py | 26 +- .../crowdfund/test_crowdfund_example.py | 2 +- .../test_on_chain_market_maker.py | 10 +- .../name_registry/test_name_registry.py | 2 +- .../examples/storage/test_advanced_storage.py | 22 +- .../functional/examples/tokens/test_erc20.py | 7 +- .../functional/examples/tokens/test_erc721.py | 122 +++----- .../functional/examples/voting/test_ballot.py | 92 +++--- tests/functional/syntax/test_msg_data.py | 2 +- 53 files changed, 472 insertions(+), 528 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index f9e65a80de..008a711c31 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -246,7 +246,7 @@ def fn(source_code, *args, **kwargs): @pytest.fixture(scope="module") def get_logs(env): - def fn(tx_result, c: ABIContract, event_name: str = None, raw=False): + def fn(c: ABIContract, event_name: str = None, raw=False): logs = [log for log in env.last_result["logs"] if c.address == log.address] if raw: return [log.data for log in logs] diff --git a/tests/functional/builtins/codegen/test_convert.py b/tests/functional/builtins/codegen/test_convert.py index cda1c8888f..7ab56bca00 100644 --- a/tests/functional/builtins/codegen/test_convert.py +++ b/tests/functional/builtins/codegen/test_convert.py @@ -422,9 +422,6 @@ def _vyper_literal(val, typ): @pytest.mark.fuzzing 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 contract_1 = f""" @external @@ -432,7 +429,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. @@ -444,9 +440,7 @@ 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(contract_1), c1_exception) - elif not skip_c1: + if not skip_c1: c1 = get_contract(contract_1) assert c1.test_convert() == expected_val @@ -628,7 +622,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}]" diff --git a/tests/functional/builtins/codegen/test_create_functions.py b/tests/functional/builtins/codegen/test_create_functions.py index 5a13fc961f..cf220e1083 100644 --- a/tests/functional/builtins/codegen/test_create_functions.py +++ b/tests/functional/builtins/codegen/test_create_functions.py @@ -66,7 +66,7 @@ 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!" @@ -95,7 +95,7 @@ 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(): @@ -174,7 +174,7 @@ 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 env.get_code(test.address) == env.get_code(foo_contract.address) @@ -221,7 +221,7 @@ def test2(target: address, salt: bytes32): d = get_contract(deployer_code) - d.test(f.address, transact={}) + d.test(f.address) test = FooContract(d.created_address()) assert env.get_code(test.address) == expected_runtime_code @@ -234,7 +234,7 @@ 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 env.get_code(test.address) == expected_runtime_code @@ -359,7 +359,7 @@ def should_fail(target: address, arg1: String[129], arg2: Bar): 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 env.get_code(test.address) == expected_runtime_code @@ -372,7 +372,7 @@ 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 env.get_code(test.address) == expected_runtime_code @@ -382,13 +382,13 @@ def should_fail(target: address, arg1: String[129], arg2: 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 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 env.get_code(test.address) == expected_runtime_code assert test.foo() == FOO @@ -403,7 +403,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 @@ -446,7 +446,7 @@ def test2(target: address, salt: bytes32) -> address: c = get_contract(code) bytecode = env.get_code(c.address) - c.test(c.address, transact={}) + c.test(c.address) test1 = c.created_address() assert env.get_code(test1) == bytecode @@ -458,7 +458,7 @@ def test2(target: address, salt: bytes32) -> address: # assert revm_env.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 env.get_code(test2) == bytecode @@ -466,7 +466,7 @@ def test2(target: address, salt: bytes32) -> address: # can't create2 where contract already exists with tx_failed(): - c.test2(c.address, salt, transact={}) + c.test2(c.address, salt) # test single byte contract # test2 = c.test2(b"\x01", salt) @@ -588,7 +588,7 @@ def test(target: address): d = get_contract(deployer_code) - d.test(f.address, transact={}) + d.test(f.address) test = FooContract(d.created_address()) assert env.get_code(test.address) == expected_runtime_code @@ -636,7 +636,7 @@ def test(target: address): d = get_contract(deployer_code) - d.test(f.address, transact={}) + d.test(f.address) test = FooContract(d.created_address()) assert env.get_code(test.address) == expected_runtime_code @@ -660,7 +660,7 @@ def test(target: address) -> address: c = get_contract(complex_salt) bytecode = env.get_code(c.address) - c.test(c.address, transact={}) + c.test(c.address) test1 = c.address assert bytecode and env.get_code(test1) == bytecode diff --git a/tests/functional/builtins/codegen/test_ec.py b/tests/functional/builtins/codegen/test_ec.py index 65fb846021..e81b8c2faf 100644 --- a/tests/functional/builtins/codegen/test_ec.py +++ b/tests/functional/builtins/codegen/test_ec.py @@ -73,7 +73,7 @@ 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): @@ -155,7 +155,7 @@ 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): diff --git a/tests/functional/builtins/codegen/test_empty.py b/tests/functional/builtins/codegen/test_empty.py index db2d32c7e8..c8e6fc374e 100644 --- a/tests/functional/builtins/codegen/test_empty.py +++ b/tests/functional/builtins/codegen/test_empty.py @@ -529,9 +529,9 @@ def delete(key: bytes32): 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 @@ -559,9 +559,9 @@ def delete(key1: bytes32, key2: bytes32): 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 @@ -589,9 +589,9 @@ def delete(): c = get_contract(code) assert c.get() == (0, 0) - c.set(transact={}) + c.set() assert c.get() == (333, 444) - c.delete(transact={}) + c.delete() assert c.get() == (0, 0) @@ -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_floor.py b/tests/functional/builtins/codegen/test_floor.py index e90ea63470..cbd4d7e542 100644 --- a/tests/functional/builtins/codegen/test_floor.py +++ b/tests/functional/builtins/codegen/test_floor.py @@ -125,7 +125,7 @@ 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): diff --git a/tests/functional/builtins/codegen/test_keccak256.py b/tests/functional/builtins/codegen/test_keccak256.py index 7f9f7436ba..ac5da75d2e 100644 --- a/tests/functional/builtins/codegen/test_keccak256.py +++ b/tests/functional/builtins/codegen/test_keccak256.py @@ -62,21 +62,21 @@ def try32(inp: bytes32) -> bool: """ c = get_contract(hash_code3) - c.set_test(b"", transact={}) + 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 diff --git a/tests/functional/builtins/codegen/test_mulmod.py b/tests/functional/builtins/codegen/test_mulmod.py index 07369d7bdc..1bb66ae598 100644 --- a/tests/functional/builtins/codegen/test_mulmod.py +++ b/tests/functional/builtins/codegen/test_mulmod.py @@ -47,7 +47,7 @@ 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): diff --git a/tests/functional/builtins/codegen/test_raw_call.py b/tests/functional/builtins/codegen/test_raw_call.py index df56568e4b..fcb99f93ec 100644 --- a/tests/functional/builtins/codegen/test_raw_call.py +++ b/tests/functional/builtins/codegen/test_raw_call.py @@ -75,12 +75,12 @@ def create_and_return_proxy(inp: address) -> address: 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) - c2.create_and_return_proxy(c.address, transact={}) + c2.create_and_return_proxy(c.address) c3_contract_code = env.get_code(c3) @@ -256,7 +256,7 @@ 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] diff --git a/tests/functional/builtins/codegen/test_send.py b/tests/functional/builtins/codegen/test_send.py index 763771f64f..4199c28b36 100644 --- a/tests/functional/builtins/codegen/test_send.py +++ b/tests/functional/builtins/codegen/test_send.py @@ -14,10 +14,10 @@ def fop(): env.set_balance(env.deployer, 1000) c = get_contract(send_test, value=10) with tx_failed(): - c.foo(transact={}) - c.fop(transact={}) + c.foo() + c.fop() with tx_failed(): - c.fop(transact={}) + c.fop() def test_default_gas(get_contract, env, tx_failed): diff --git a/tests/functional/builtins/codegen/test_sha256.py b/tests/functional/builtins/codegen/test_sha256.py index 048de3ccd5..137d3e6205 100644 --- a/tests/functional/builtins/codegen/test_sha256.py +++ b/tests/functional/builtins/codegen/test_sha256.py @@ -76,7 +76,7 @@ def bar() -> bytes32: 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() diff --git a/tests/functional/codegen/calling_convention/test_default_function.py b/tests/functional/codegen/calling_convention/test_default_function.py index 9035258127..54d17acf06 100644 --- a/tests/functional/codegen/calling_convention/test_default_function.py +++ b/tests/functional/codegen/calling_convention/test_default_function.py @@ -30,7 +30,8 @@ def __default__(): """ c = get_contract(code) env.set_balance(env.deployer, 10**18) - (log,) = get_logs(env.execute_code(c.address, value=10**17), c, "Sent") + env.execute_code(c.address, value=10**17) + (log,) = get_logs(c, "Sent") assert env.deployer == log.args.sender assert env.get_balance(c.address) == to_wei(0.1, "ether") @@ -53,7 +54,8 @@ def __default__(): """ c = get_contract(code) - (log,) = get_logs(env.execute_code(c.address, value=10**17), c, "Sent") + env.execute_code(c.address, value=10**17) + (log,) = get_logs(c, "Sent") assert env.deployer == log.args.sender assert env.get_balance(c.address) == to_wei(0.1, "ether") @@ -128,8 +130,8 @@ def __default__(): def _call_with_bytes(hexstr): # call our special contract and return the logged value data = bytes.fromhex(hexstr.removeprefix("0x")) - result = env.execute_code(c.address, value=0, data=data) - (log,) = get_logs(result, c, "Sent") + env.execute_code(c.address, value=0, data=data) + (log,) = get_logs(c, "Sent") return log.args.sig assert 1 == _call_with_bytes("0x") @@ -174,8 +176,8 @@ def __default__(): def _call_with_bytes(hexstr): # call our special contract and return the logged value data = bytes.fromhex(hexstr.removeprefix("0x")) - result = env.execute_code(c.address, value=0, data=data, gas=10**6) - (log,) = get_logs(result, c, "Sent") + env.execute_code(c.address, value=0, data=data, gas=10**6) + (log,) = get_logs(c, "Sent") return log.args.sig assert 1 == _call_with_bytes("0x") @@ -215,8 +217,8 @@ def __default__(): def _call_with_bytes(hexstr): # call our special contract and return the logged value data = bytes.fromhex(hexstr.removeprefix("0x")) - result = env.execute_code(c.address, value=0, data=data) - (log,) = get_logs(result, c, "Sent") + env.execute_code(c.address, value=0, data=data) + (log,) = get_logs(c, "Sent") return log.args.sig # check we can call default function diff --git a/tests/functional/codegen/calling_convention/test_erc20_abi.py b/tests/functional/codegen/calling_convention/test_erc20_abi.py index 381a9d88e0..a09a94a63e 100644 --- a/tests/functional/codegen/calling_convention/test_erc20_abi.py +++ b/tests/functional/codegen/calling_convention/test_erc20_abi.py @@ -83,9 +83,9 @@ def test_initial_state(env, erc20_caller): 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(env.accounts[1], 10, transact={}) + erc20_caller.transfer(env.accounts[1], 10) assert erc20.balanceOf(erc20_caller.address) == 0 assert erc20.balanceOf(env.accounts[1]) == 10 @@ -100,7 +100,7 @@ def test_call_transfer(env, erc20, erc20_caller, tx_failed): 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.approve(erc20_caller.address, 10) assert erc20_caller.allowance(env.deployer, erc20_caller.address) == 10 @@ -109,10 +109,10 @@ def test_caller_tranfer_from(env, erc20, erc20_caller, tx_failed): with tx_failed(): 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(env.deployer, 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(env.deployer, erc20_caller.address) == 5 - erc20_caller.transferFrom(env.deployer, erc20_caller.address, 3, transact={}) + erc20_caller.transferFrom(env.deployer, erc20_caller.address, 3) assert erc20.balanceOf(erc20_caller.address) == 8 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 e0ea71441c..e53a4be33b 100644 --- a/tests/functional/codegen/calling_convention/test_external_contract_calls.py +++ b/tests/functional/codegen/calling_convention/test_external_contract_calls.py @@ -895,7 +895,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 +961,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( @@ -1243,10 +1243,10 @@ 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 @@ -1285,9 +1285,9 @@ def get_lucky() -> int128: 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 +1313,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 @@ -1390,7 +1390,7 @@ def get_lucky(amount_to_send: uint256) -> int128: assert c1.get_lucky() == 1 assert c1.get_balance() == 0 - c2.set_contract(c1.address, transact={}) + c2.set_contract(c1.address) # Send some eth env.set_balance(env.deployer, 10000) @@ -1440,7 +1440,7 @@ def get_lucky(gas_amount: uint256) -> int128: c1 = get_contract(contract_1) c2 = get_contract(contract_2) - c2.set_contract(c1.address, transact={}) + c2.set_contract(c1.address) assert c2.get_lucky(1000) == 656598 with tx_failed(): 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/features/decorators/test_nonreentrant.py b/tests/functional/codegen/features/decorators/test_nonreentrant.py index 4e3c0402da..bfad00fe1e 100644 --- a/tests/functional/codegen/features/decorators/test_nonreentrant.py +++ b/tests/functional/codegen/features/decorators/test_nonreentrant.py @@ -165,32 +165,32 @@ 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(env, get_contract, tx_failed): @@ -256,7 +256,7 @@ 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. diff --git a/tests/functional/codegen/features/decorators/test_private.py b/tests/functional/codegen/features/decorators/test_private.py index 16b444913e..415e7a2541 100644 --- a/tests/functional/codegen/features/decorators/test_private.py +++ b/tests/functional/codegen/features/decorators/test_private.py @@ -179,7 +179,7 @@ def hithere(name: Bytes[20]) -> Bytes[40]: 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" @@ -265,7 +265,7 @@ def test4() -> (Bytes[100]): 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" @@ -413,7 +413,7 @@ def __default__(): 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"), transact={}) + 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") @@ -444,8 +444,8 @@ def whoami() -> address: assert c.i_am_me() addr = env.accounts[1] - result = c.whoami(transact={"from": addr}) - (log,) = get_logs(result, c) + c.whoami(transact={"from": addr}) + (log,) = get_logs(c) assert log.args.addr == addr @@ -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 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 3f586f67cf..8e636ad9a6 100644 --- a/tests/functional/codegen/features/iteration/test_for_in_list.py +++ b/tests/functional/codegen/features/iteration/test_for_in_list.py @@ -185,7 +185,7 @@ def data() -> int128: c = get_contract(code) assert c.data() == -1 - c.set(transact={}) + c.set() assert c.data() == 7 @@ -210,7 +210,7 @@ def data() -> int128: 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) @@ -238,9 +238,9 @@ def iterate_return_second() -> address: 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" @@ -269,9 +269,9 @@ def i_return(break_count: int128) -> decimal: c = get_contract(code) - c.set(0, Decimal("0.0001"), transact={}) - c.set(1, Decimal("1.1"), transact={}) - c.set(2, Decimal("2.2"), transact={}) + c.set(0, Decimal("0.0001")) + c.set(1, Decimal("1.1")) + c.set(2, Decimal("2.2")) assert c.ret(2) == c.i_return(2) == Decimal("2.2") assert c.ret(1) == c.i_return(1) == Decimal("1.1") diff --git a/tests/functional/codegen/features/iteration/test_for_range.py b/tests/functional/codegen/features/iteration/test_for_range.py index 6b7db17c08..dfc74837c3 100644 --- a/tests/functional/codegen/features/iteration/test_for_range.py +++ b/tests/functional/codegen/features/iteration/test_for_range.py @@ -376,7 +376,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 e07fc58f8a..e7e9fa85a4 100644 --- a/tests/functional/codegen/features/iteration/test_range_in.py +++ b/tests/functional/codegen/features/iteration/test_range_in.py @@ -138,11 +138,11 @@ def is_owner() -> bool: with tx_failed(): c.set_owner(1, a1, call={"from": a1}) - c.set_owner(1, a1, transact={}) + c.set_owner(1, a1) assert c.is_owner(call={"from": 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 diff --git a/tests/functional/codegen/features/test_assignment.py b/tests/functional/codegen/features/test_assignment.py index adc2bfb122..eaafb527c1 100644 --- a/tests/functional/codegen/features/test_assignment.py +++ b/tests/functional/codegen/features/test_assignment.py @@ -249,7 +249,7 @@ def get(i: int128) -> int128: return self.test_map2[idx].c """ c = get_contract(code) - c.set(transact={}) + c.set() assert c.get(1) == 111 @@ -275,7 +275,7 @@ def get() -> int128: return self.test_map2[self.test_map1[1].a].c """ c = get_contract(code) - c.set(transact={}) + c.set() assert c.get() == 111 diff --git a/tests/functional/codegen/features/test_bytes_map_keys.py b/tests/functional/codegen/features/test_bytes_map_keys.py index aa6fa22bac..1bbb7d002d 100644 --- a/tests/functional/codegen/features/test_bytes_map_keys.py +++ b/tests/functional/codegen/features/test_bytes_map_keys.py @@ -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 diff --git a/tests/functional/codegen/features/test_immutable.py b/tests/functional/codegen/features/test_immutable.py index 91378db8bc..9792acb7d8 100644 --- a/tests/functional/codegen/features/test_immutable.py +++ b/tests/functional/codegen/features/test_immutable.py @@ -395,11 +395,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 01cb34d941..7dae6007c3 100644 --- a/tests/functional/codegen/features/test_internal_call.py +++ b/tests/functional/codegen/features/test_internal_call.py @@ -254,7 +254,7 @@ def bar1() -> int128: """ c = get_contract(code) - c.set(transact={}) + c.set() assert c.bar0() == 88 assert c.bar1() == 99 diff --git a/tests/functional/codegen/features/test_logging.py b/tests/functional/codegen/features/test_logging.py index 745d746737..b53d370947 100644 --- a/tests/functional/codegen/features/test_logging.py +++ b/tests/functional/codegen/features/test_logging.py @@ -29,12 +29,12 @@ def foo(): """ c = get_contract(loggy_code) - tx = c.foo(transact={}) + c.foo() + (log,) = get_logs(c) event_id = keccak(bytes("MyLog()", "utf-8")) # Event id is always the first topic - (log,) = get_logs(tx, c) assert log.topics == [event_id] # Event abi is created correctly assert c.abi[0] == {"name": "MyLog", "inputs": [], "anonymous": False, "type": "event"} @@ -57,11 +57,11 @@ def foo(): """ c = get_contract(loggy_code) - tx_hash = c.foo(transact={}) + c.foo() event_id = keccak(bytes("MyLog(bytes)", "utf-8")) # Event id is always the first topic - (log,) = get_logs(tx_hash, c) + (log,) = get_logs(c) assert log.topics[0] == event_id # Event abi is created correctly assert c.abi[0] == { @@ -85,11 +85,11 @@ def foo(): """ c = get_contract(loggy_code) - tx_hash = c.foo(transact={}) + c.foo() event_id = keccak(bytes("MyLog(int128,bool,address)", "utf-8")) # Event id is always the first topic - (log,) = get_logs(tx_hash, c) + (log,) = get_logs(c) assert log.topics[0] == event_id # Event abi is created correctly assert c.abi[0] == { @@ -103,11 +103,11 @@ 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.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(get_contract, get_logs): @@ -127,11 +127,10 @@ def foo(arg1: int128): """ c = get_contract(code) - tx_hash = c.foo(31337, transact={}) + 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 @@ -155,16 +154,15 @@ def bar(): """ c = get_contract(loggy_code) - tx_hash1 = c.foo(transact={}) - logs_tx1 = get_logs(tx_hash1, c) - log1, _ = logs_tx1 - tx_hash2 = c.bar(transact={}) - log2, _ = get_logs(tx_hash2, c) + 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 log1.topics[0] == event_id - assert log2.topics[0] == event_id + assert log3.topics[0] == event_id # Event abi is created correctly assert c.abi[0] == { "name": "MyLog", @@ -177,11 +175,10 @@ def bar(): } # Event is decoded correctly - logs_tx1 = [log for log in logs_tx1] - assert logs_tx1[0].args.arg1 == 1 - assert logs_tx1[0].args.arg2 == c.address - assert logs_tx1[1].args.arg1 == 1 - assert logs_tx1[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): @@ -208,11 +205,11 @@ def foo(): """ c = get_contract(loggy_code) - tx_hash = c.foo(transact={}) + c.foo() event_id = keccak(bytes("MyLog(int128)", "utf-8")) # Event id is always the first topic - (log,) = get_logs(tx_hash, c) + (log,) = get_logs(c) assert log.topics == [event_id] # Event abi is created correctly assert c.abi[0] == { @@ -223,8 +220,8 @@ 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(env, keccak, get_logs, get_contract): @@ -242,11 +239,11 @@ def foo(): """ c = get_contract(loggy_code) - tx_hash = c.foo(transact={}) + c.foo() event_id = keccak(bytes("MyLog(int128[2],uint256[3],int128[2][2])", "utf-8")) # Event id is always the first topic - log, _ = get_logs(tx_hash, c) + log, _ = get_logs(c) assert log.topics == [event_id] # Event abi is created correctly @@ -263,11 +260,9 @@ def foo(): # Event is decoded correctly timestamp = env.timestamp - logs = get_logs(tx_hash, c, "MyLog") - - 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]] + assert log.args.arg1 == [1, 2] + assert log.args.arg2 == [timestamp, timestamp + 1, timestamp + 2] + assert log.args.arg3 == [[1, 2], [1, 2]] def test_logging_with_input_bytes_1(env, keccak, get_logs, get_contract): @@ -283,11 +278,11 @@ def foo(arg1: Bytes[29], arg2: Bytes[31]): """ c = get_contract(loggy_code) - tx_hash = c.foo(b"bar", b"foo", transact={}) + c.foo(b"bar", b"foo") event_id = keccak(bytes("MyLog(bytes,bytes,bytes)", "utf-8")) # Event id is always the first topic - (log,) = get_logs(tx_hash, c) + (log,) = get_logs(c) assert log.topics[0] == event_id # Event abi is created correctly assert c.abi[0] == { @@ -301,11 +296,11 @@ 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(env, keccak, get_logs, get_contract): @@ -319,11 +314,11 @@ def foo(_arg1: Bytes[20]): """ c = get_contract(loggy_code) - tx_hash = c.foo(b"hello", transact={}) + c.foo(b"hello") event_id = keccak(bytes("MyLog(bytes)", "utf-8")) # Event id is always the first topic - (log,) = get_logs(tx_hash, c) + (log,) = get_logs(c) assert log.topics[0] == event_id # Event abi is created correctly assert c.abi[0] == { @@ -347,11 +342,11 @@ def foo(_arg1: Bytes[5]): """ c = get_contract(loggy_code) - tx_hash = c.foo(b"hello", transact={}) + c.foo(b"hello") event_id = keccak(bytes("MyLog(bytes)", "utf-8")) # Event id is always the first topic - (log,) = get_logs(tx_hash, c) + (log,) = get_logs(c) assert log.topics == [event_id] # Event abi is created correctly assert c.abi[0] == { @@ -361,8 +356,8 @@ def foo(_arg1: Bytes[5]): "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(env, keccak, get_logs, get_contract): @@ -381,11 +376,11 @@ def foo(): """ c = get_contract(loggy_code) - tx_hash = c.foo(transact={}) + c.foo() event_id = keccak(bytes("MyLog(int128,bytes,bytes,address,address,uint256)", "utf-8")) # Event id is always the first topic - (log,) = get_logs(tx_hash, c) + (log,) = get_logs(c) assert log.topics == [event_id] # Event abi is created correctly assert c.abi[0] == { @@ -403,8 +398,7 @@ def foo(): } # Event is decoded correctly - 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" @@ -425,11 +419,11 @@ def foo(): """ c = get_contract(loggy_code) - tx_hash = c.foo(transact={}) + c.foo() event_id = keccak(bytes("MyLog(int128,bytes)", "utf-8")) # Event id is always the first topic - (log,) = get_logs(tx_hash, c) + (log,) = get_logs(c) assert log.topics[0] == event_id # Event abi is created correctly assert c.abi[0] == { @@ -442,10 +436,9 @@ 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.removesuffix(b"\0") == b"bar" + (log,) = get_logs(c, "MyLog") + assert log.args.arg1 == 1 + assert log.args.arg2.removesuffix(b"\0") == b"bar" def test_event_logging_with_multiple_logs_topics_and_data(env, keccak, get_logs, get_contract): @@ -472,9 +465,9 @@ def foo(): """ c = get_contract(loggy_code) - tx_hash = c.foo(transact={}) + c.foo() - log1, log2 = get_logs(tx_hash, c) + log1, log2 = get_logs(c) event_id1 = keccak(bytes("MyLog(int128,bytes)", "utf-8")) event_id2 = keccak(bytes("YourLog(address,(uint256,bytes,(string,fixed168x10)))", "utf-8")) @@ -518,14 +511,13 @@ 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 == (1, b"abc", ("house", Decimal("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("13.5"))) def test_fails_when_input_is_the_wrong_type(tx_failed, get_contract): @@ -735,24 +727,24 @@ def ioo(inp: Bytes[100]): c = get_contract(loggy_code) - tx_hash = c.foo(transact={}) - ((topics, data),) = get_logs(tx_hash, c, raw=True) + c.foo() + ((topics, data),) = get_logs(c, raw=True) assert to_text(data) == "moo" - tx_hash = c.goo(transact={}) - ((topics, data),) = get_logs(tx_hash, c, raw=True) + c.goo() + ((topics, data),) = get_logs(c, raw=True) assert to_text(data) == "moo2" assert topics[0] == bytes.fromhex( "1234567812345678123456781234567812345678123456781234567812345678" ) - tx_hash = c.hoo(transact={}) - ((topics, data),) = get_logs(tx_hash, c, raw=True) + c.hoo() + ((topics, data),) = get_logs(c, raw=True) assert to_text(data) == "moo3" - tx_hash = c.ioo(b"moo4", transact={}) - ((topics, data),) = get_logs(tx_hash, c, raw=True) + c.ioo(b"moo4") + ((topics, data),) = get_logs(c, raw=True) assert to_text(data) == "moo4" print("Passed raw log tests") @@ -772,8 +764,8 @@ def foo(): raw_log([], keccak256(b"")) """ c = get_contract(code) - tx_hash = c.foo(transact={}) - logs = get_logs(tx_hash, c, raw=True) + 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") @@ -792,9 +784,9 @@ def foo(): """ 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): @@ -808,9 +800,9 @@ def foo(): """ 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, get_contract): @@ -830,13 +822,13 @@ def set_list(): """ 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): @@ -850,9 +842,9 @@ def foo(barbaric: int128[4]): """ 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): @@ -866,14 +858,9 @@ def foo(): """ c = get_contract(code) - tx_hash = c.foo(transact={}) - logs = get_logs(tx_hash, c, "Bar") - assert logs[0].args._value == [ - Decimal("1.11"), - Decimal("2.22"), - Decimal("3.33"), - Decimal("4.44"), - ] + c.foo() + (log,) = get_logs(c, "Bar") + assert log.args._value == [Decimal("1.11"), Decimal("2.22"), Decimal("3.33"), Decimal("4.44")] def test_storage_byte_packing(get_logs, get_contract): @@ -893,13 +880,13 @@ def setbytez(): """ c = get_contract(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.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, get_contract): @@ -919,18 +906,13 @@ def set_list(): """ c = get_contract(code) - tx_hash = c.foo(transact={}) - logs = get_logs(tx_hash, c, "Bar") - assert logs[0].args._value == [Decimal("0"), Decimal("0"), Decimal("0"), Decimal("0")] - c.set_list(transact={}) - tx_hash = c.foo(transact={}) - logs = get_logs(tx_hash, c, "Bar") - assert logs[0].args._value == [ - Decimal("1.33"), - Decimal("2.33"), - Decimal("3.33"), - Decimal("4.33"), - ] + c.foo() + (log,) = get_logs(c, "Bar") + assert log.args._value == [Decimal("0"), Decimal("0"), Decimal("0"), Decimal("0")] + c.set_list() + c.foo() + (log,) = get_logs(c, "Bar") + assert log.args._value == [Decimal("1.33"), Decimal("2.33"), Decimal("3.33"), Decimal("4.33")] def test_logging_fails_when_input_is_too_big(tx_failed, get_contract): @@ -959,8 +941,8 @@ def foo(): """ 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): @@ -981,11 +963,11 @@ def set_list(): """ 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): @@ -1015,15 +997,16 @@ def set_list(): """ c = get_contract(code) - tx_hash = c.foo(transact={}) - log = get_logs(tx_hash, c, "Bar")[0] + 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(transact={}) - tx_hash = c.foo(transact={}) - log = get_logs(tx_hash, c, "Bar")[0] + + 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] @@ -1043,7 +1026,7 @@ def foo(a: Bytes[36], b: int128, c: String[7]): """ c = get_contract(loggy_code) - tx_hash = c.foo(b"bar", 1, "weird", transact={}) + c.foo(b"bar", 1, "weird") # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") @@ -1051,7 +1034,7 @@ def foo(a: Bytes[36], b: int128, c: String[7]): topic2 = abi.encode("int128", 1) topic3 = keccak256(b"weird") - (log,) = get_logs(tx_hash, c) + (log,) = get_logs(c) assert log.topics == [event_id, topic1, topic2, topic3] # Event abi is created correctly @@ -1083,14 +1066,14 @@ def foo(): """ c = get_contract(loggy_code) - tx_hash = c.foo(transact={}) + c.foo() # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") topic1 = keccak256(b"potato") topic2 = abi.encode("int128", -777) topic3 = keccak256(b"why hello, neighbor! how are you today?") - (log,) = get_logs(tx_hash, c) + (log,) = get_logs(c) assert log.topics == [event_id, topic1, topic2, topic3] # Event abi is created correctly @@ -1130,8 +1113,8 @@ def foo(): """ c = get_contract(loggy_code) - c.setter(b"zonk", -2109, "yessir", transact={}) - tx_hash = c.foo(transact={}) + c.setter(b"zonk", -2109, "yessir") + c.foo() # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") @@ -1139,7 +1122,7 @@ def foo(): topic2 = abi.encode("int128", -2109) topic3 = keccak256(b"yessir") - (log,) = get_logs(tx_hash, c) + (log,) = get_logs(c) assert log.topics == [event_id, topic1, topic2, topic3] # Event abi is created correctly @@ -1168,7 +1151,7 @@ def foo(): """ c = get_contract(loggy_code) - tx_hash = c.foo(transact={}) + c.foo() # Event id is always the first topic event_id = keccak(b"MyLog(bytes,int128,string)") @@ -1176,7 +1159,7 @@ def foo(): topic2 = abi.encode("int128", 666) topic3 = keccak256(b"madness!") - (log,) = get_logs(tx_hash, c) + (log,) = get_logs(c) assert log.topics == [event_id, topic1, topic2, topic3] diff --git a/tests/functional/codegen/features/test_logging_bytes_extended.py b/tests/functional/codegen/features/test_logging_bytes_extended.py index ed3ed5256b..6b84cdd23a 100644 --- a/tests/functional/codegen/features/test_logging_bytes_extended.py +++ b/tests/functional/codegen/features/test_logging_bytes_extended.py @@ -11,11 +11,12 @@ def foo(): """ c = get_contract(code) - log = get_logs(c.foo(transact={}), c, "MyLog") + 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, get_logs): @@ -34,11 +35,11 @@ def foo(): """ c = get_contract(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.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, get_logs): @@ -55,7 +56,8 @@ def foo(a: int128, b: Bytes[64], c: int128): 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 @@ -86,16 +88,16 @@ def set(x: int128, y: Bytes[64], z: int128): 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 @@ -120,7 +122,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 == [[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 86ee4c6bfb..1bedfe050e 100644 --- a/tests/functional/codegen/features/test_logging_from_call.py +++ b/tests/functional/codegen/features/test_logging_from_call.py @@ -33,19 +33,17 @@ def test_func(_value: uint256): c = get_contract(code) - tx_hash = c.test_func(123, transact={}) + c.test_func(123) + log, log2 = get_logs(c, "TestLog") - logs = get_logs(tx_hash, c, "TestLog") + 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 - log = logs[0].args - assert to_int(log.testData1) == 123 - assert 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 to_int(log.testData3) == 123 - - assert logs[0].args == logs[1].args + assert log.args == log2.args def test_log_dynamic_static_combo2(get_logs, get_contract): @@ -77,8 +75,8 @@ 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={}) - logs = get_logs(tx_hash, c, "TestLog") + c.test_func(1234444, b"x" * 129) + logs = get_logs(c, "TestLog") print(logs[0].args) @@ -110,11 +108,11 @@ 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 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): @@ -152,16 +150,15 @@ def test_func(_value: uint256,input: Bytes[2048]): c = get_contract(code) - tx_hash = c.test_func(333, b"x" * 132, transact={}) - 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 to_int(logs[0].args.testData1) == 333 + print(log1.args) - assert to_int(logs[0].args.testData2[0:8]) == 333 - assert to_int(logs[0].args.testData2[8:16]) == 333 - assert logs[0].args.testData2[16:] == b"x" * 132 - assert 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_reverting.py b/tests/functional/codegen/features/test_reverting.py index 932f9fe826..bbb1d48b4f 100644 --- a/tests/functional/codegen/features/test_reverting.py +++ b/tests/functional/codegen/features/test_reverting.py @@ -18,7 +18,7 @@ def foo(): revert_bytes = method_id("NoFives()") with tx_failed(TransactionFailed, exc_text=revert_bytes.hex()): - get_contract(reverty_code).foo(transact={}) + get_contract(reverty_code).foo() def test_revert_reason_typed(env, tx_failed, get_contract): @@ -33,7 +33,7 @@ def foo(): revert_bytes = method_id("NoFives(uint256)") + abi.encode("(uint256)", (5,)) with tx_failed(TransactionFailed, exc_text=revert_bytes.hex()): - get_contract(reverty_code).foo(transact={}) + get_contract(reverty_code).foo() def test_revert_reason_typed_no_variable(env, tx_failed, get_contract): @@ -47,4 +47,4 @@ def foo(): revert_bytes = method_id("NoFives(uint256)") + abi.encode("(uint256)", (5,)) with tx_failed(TransactionFailed, exc_text=revert_bytes.hex()): - get_contract(reverty_code).foo(transact={}) + 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 d35f9145f5..4627b9c885 100644 --- a/tests/functional/codegen/features/test_short_circuiting.py +++ b/tests/functional/codegen/features/test_short_circuiting.py @@ -26,7 +26,7 @@ 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() @@ -54,7 +54,7 @@ def foo() -> bool: c = get_contract(code) assert c.foo() - c.foo(transact={}) + c.foo() assert c.called_left() assert c.called_right() @@ -82,7 +82,7 @@ def foo() -> bool: c = get_contract(code) assert c.foo() - c.foo(transact={}) + c.foo() assert c.called_left() assert not c.called_right() @@ -110,7 +110,7 @@ def foo() -> bool: c = get_contract(code) assert not c.foo() - c.foo(transact={}) + c.foo() assert c.called_left() assert c.called_right() diff --git a/tests/functional/codegen/features/test_ternary.py b/tests/functional/codegen/features/test_ternary.py index 330145880d..ab6f50f97f 100644 --- a/tests/functional/codegen/features/test_ternary.py +++ b/tests/functional/codegen/features/test_ternary.py @@ -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 63502b46ce..d12db9e262 100644 --- a/tests/functional/codegen/features/test_transient.py +++ b/tests/functional/codegen/features/test_transient.py @@ -1,5 +1,6 @@ import pytest +from tests.utils import ZERO_ADDRESS from vyper.compiler import compile_code from vyper.exceptions import EvmVersionException, VyperException @@ -52,7 +53,7 @@ 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", ""), @@ -126,7 +127,7 @@ def foo(_a: uint256, _b: address, _c: String[64]) -> (uint256, address, String[6 c = get_contract(code) assert c.foo(*values) == values assert c.a() == 0 - assert c.b() is None + assert c.b() == ZERO_ADDRESS assert c.c() == "" assert c.foo(*values) == values @@ -155,7 +156,7 @@ 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) + assert c.my_struct() == (0, 0, ZERO_ADDRESS, 0) assert c.foo(*values) == values @@ -184,7 +185,7 @@ 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, ([],), []) + assert c.my_struct() == (ZERO_ADDRESS, ([],), []) assert c.foo(*values) == values @@ -266,7 +267,7 @@ 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 diff --git a/tests/functional/codegen/integration/test_crowdfund.py b/tests/functional/codegen/integration/test_crowdfund.py index a010e7310c..2741dcd247 100644 --- a/tests/functional/codegen/integration/test_crowdfund.py +++ b/tests/functional/codegen/integration/test_crowdfund.py @@ -79,7 +79,7 @@ def refund(): pre_bal = env.get_balance(a1) env.time_travel(100) assert c.expired() - c.finalize(transact={}) + c.finalize() post_bal = env.get_balance(a1) assert post_bal - pre_bal == 54 @@ -92,7 +92,7 @@ def refund(): assert c.expired() assert not c.reached() pre_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] - c.refund(transact={}) + 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] @@ -172,7 +172,7 @@ def refund(): pre_bal = env.get_balance(a1) env.time_travel(100) assert c.expired() - c.finalize(transact={}) + c.finalize() post_bal = env.get_balance(a1) assert post_bal - pre_bal == 54 @@ -185,6 +185,6 @@ def refund(): assert c.expired() assert not c.reached() pre_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] - c.refund(transact={}) + 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 7883f18233..55b8ea2314 100644 --- a/tests/functional/codegen/integration/test_escrow.py +++ b/tests/functional/codegen/integration/test_escrow.py @@ -32,10 +32,10 @@ def refund(): """ a0, a1, a2 = env.accounts[:3] c = get_contract(arbitration_code, value=1) - c.setup(a1, a2, transact={}) + c.setup(a1, a2) with tx_failed(): c.finalize(transact={"from": a1}) - c.finalize(transact={}) + c.finalize() print("Passed escrow test") 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_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 ced1c58380..3f618bf0ea 100644 --- a/tests/functional/codegen/modules/test_stateless_functions.py +++ b/tests/functional/codegen/modules/test_stateless_functions.py @@ -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 73be3a40b3..5169bd300d 100644 --- a/tests/functional/codegen/storage_variables/test_getters.py +++ b/tests/functional/codegen/storage_variables/test_getters.py @@ -13,7 +13,7 @@ def foo() -> int128: """ c = get_contract(state_accessor) - c.oo(transact={}) + c.oo() assert c.foo() == 5 diff --git a/tests/functional/codegen/storage_variables/test_setters.py b/tests/functional/codegen/storage_variables/test_setters.py index 5710fe5a35..c562ef1614 100644 --- a/tests/functional/codegen/storage_variables/test_setters.py +++ b/tests/functional/codegen/storage_variables/test_setters.py @@ -56,9 +56,9 @@ def jop() -> int128: 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 diff --git a/tests/functional/codegen/test_interfaces.py b/tests/functional/codegen/test_interfaces.py index 76b307bf4b..2d19704a79 100644 --- a/tests/functional/codegen/test_interfaces.py +++ b/tests/functional/codegen/test_interfaces.py @@ -236,7 +236,7 @@ def test(): sender = env.deployer assert token.balanceOf(sender) == 0 - test_c.test(transact={}) + test_c.test() assert token.balanceOf(sender) == 1000 @@ -315,7 +315,7 @@ def test(): sender = env.deployer assert erc20.balanceOf(sender) == 0 - test_c.test(transact={}) + test_c.test() assert erc20.balanceOf(sender) == 1000 diff --git a/tests/functional/codegen/test_selector_table.py b/tests/functional/codegen/test_selector_table.py index e11a4b3405..917d909792 100644 --- a/tests/functional/codegen/test_selector_table.py +++ b/tests/functional/codegen/test_selector_table.py @@ -593,8 +593,8 @@ def __default__(): # do payable check if mutability == "@payable": - tx = func(*args, transact={"value": 1}) - (event,) = get_logs(tx, c, "_Return") + func(*args, transact={"value": 1}) + (event,) = get_logs(c, "_Return") assert event.args.val == func_id else: hexstr = (method_id + argsdata).hex() @@ -618,12 +618,12 @@ def __default__(): logs = get_logs(tx, c, "CalledDefault") assert len(logs) == 1 else: - tx = env.execute_code(**tx_params) + env.execute_code(**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 diff --git a/tests/functional/codegen/types/test_array_indexing.py b/tests/functional/codegen/types/test_array_indexing.py index 321f6e620c..acb1cf7db3 100644 --- a/tests/functional/codegen/types/test_array_indexing.py +++ b/tests/functional/codegen/types/test_array_indexing.py @@ -56,8 +56,8 @@ def set2(idx: uint256): c = get_contract(code) with pytest.raises(TransactionFailed): - c.set2(2**256 - 1, transact={}) - c.set2(2**256 - 2, transact={}) + c.set2(2**256 - 1) + c.set2(2**256 - 2) def test_boundary_access_to_arr(get_contract): @@ -79,14 +79,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 +106,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 +124,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 cea71d5e56..a5b119f143 100644 --- a/tests/functional/codegen/types/test_bytes.py +++ b/tests/functional/codegen/types/test_bytes.py @@ -80,16 +80,16 @@ def get_xy() -> int128: """ c = get_contract(test_bytes3) - c.set_maa(b"pig", transact={}) + 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 @@ -160,12 +160,12 @@ def quz(inp1: Bytes[40], inp2: Bytes[45]): """ c = get_contract(test_bytes5) - c.foo(b"cow", b"horse", transact={}) + 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" @@ -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_flag.py b/tests/functional/codegen/types/test_flag.py index 2eb490f1ad..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 @@ -190,7 +190,7 @@ def checkMinter(minter: address): 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,25 +200,25 @@ 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) diff --git a/tests/functional/codegen/types/test_string.py b/tests/functional/codegen/types/test_string.py index 5e9d8abf45..b1b8e19411 100644 --- a/tests/functional/codegen/types/test_string.py +++ b/tests/functional/codegen/types/test_string.py @@ -122,11 +122,12 @@ def foo(): """ c = get_contract(code) - log = get_logs(c.foo(transact={}), c, "MyLog") + 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): diff --git a/tests/functional/examples/company/test_company.py b/tests/functional/examples/company/test_company.py index 193a983eef..0704dfbd11 100644 --- a/tests/functional/examples/company/test_company.py +++ b/tests/functional/examples/company/test_company.py @@ -107,23 +107,23 @@ def test_valuation(env, c): 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(transact={"from": a1, "value": 7 * c.price()}) + (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, transact={"from": 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, transact={"from": 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 0cd3c08b98..89f5d17278 100644 --- a/tests/functional/examples/crowdfund/test_crowdfund_example.py +++ b/tests/functional/examples/crowdfund/test_crowdfund_example.py @@ -22,7 +22,7 @@ def test_crowdfund_example(c, env): pre_bal = env.get_balance(a1) env.time_travel(100) assert env.timestamp > c.deadline() # expired - c.finalize(transact={}) + c.finalize() post_bal = env.get_balance(a1) assert post_bal - pre_bal == 54 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 ec75a7ba29..d6f92c9488 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 @@ -37,7 +37,7 @@ def test_initial_state(market_maker): def test_initiate(env, market_maker, erc20, tx_failed): a0 = env.accounts[0] ether, ethers = to_wei(1, "ether"), to_wei(2, "ether") - erc20.approve(market_maker.address, ethers, transact={}) + erc20.approve(market_maker.address, ethers) market_maker.initiate(erc20.address, ether, transact={"value": ethers}) assert market_maker.totalEthQty() == ethers assert market_maker.totalTokenQty() == ether @@ -53,7 +53,7 @@ def test_initiate(env, market_maker, erc20, tx_failed): def test_eth_to_tokens(env, market_maker, erc20): a1 = env.accounts[1] - erc20.approve(market_maker.address, to_wei(2, "ether"), transact={}) + erc20.approve(market_maker.address, to_wei(2, "ether")) market_maker.initiate(erc20.address, to_wei(1, "ether"), transact={"value": to_wei(2, "ether")}) assert erc20.balanceOf(market_maker.address) == to_wei(1, "ether") assert erc20.balanceOf(a1) == 0 @@ -73,7 +73,7 @@ def test_tokens_to_eth(env, market_maker, erc20): a1_balance_before = to_wei(2, "ether") env.set_balance(a1, a1_balance_before) - erc20.transfer(a1, to_wei(2, "ether"), transact={}) + erc20.transfer(a1, to_wei(2, "ether")) erc20.approve(market_maker.address, to_wei(2, "ether"), transact={"from": a1}) market_maker.initiate( erc20.address, to_wei(1, "ether"), transact={"value": to_wei(2, "ether"), "from": a1} @@ -98,7 +98,7 @@ def test_owner_withdraw(env, market_maker, erc20, tx_failed): a0, a1 = env.accounts[:2] a0_balance_before = env.get_balance(a0) # Approve 2 eth transfers. - erc20.approve(market_maker.address, 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, to_wei(1, "ether"), transact={"value": to_wei(2, "ether")}) # 2 eth was sent to market_maker contract. @@ -109,6 +109,6 @@ def test_owner_withdraw(env, market_maker, erc20, tx_failed): # Only owner can call ownerWithdraw with tx_failed(): market_maker.ownerWithdraw(transact={"from": a1}) - market_maker.ownerWithdraw(transact={}) + 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 97cf6058df..7437b29de7 100644 --- a/tests/functional/examples/name_registry/test_name_registry.py +++ b/tests/functional/examples/name_registry/test_name_registry.py @@ -3,7 +3,7 @@ def test_name_registry(env, get_contract, tx_failed): 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/storage/test_advanced_storage.py b/tests/functional/examples/storage/test_advanced_storage.py index 8815aeb2d7..29749e9ae5 100644 --- a/tests/functional/examples/storage/test_advanced_storage.py +++ b/tests/functional/examples/storage/test_advanced_storage.py @@ -48,18 +48,14 @@ def test_failed_transactions(env, adv_storage_contract, tx_failed): def test_events(env, adv_storage_contract, get_logs): k1, k2 = env.accounts[:2] - tx1 = adv_storage_contract.set(10, transact={"from": k1}) - logs1 = get_logs(tx1, adv_storage_contract, "DataChange") - tx2 = adv_storage_contract.set(20, transact={"from": k2}) - logs2 = get_logs(tx2, adv_storage_contract, "DataChange") - tx3 = adv_storage_contract.reset(transact={"from": k1}) - logs3 = get_logs(tx3, adv_storage_contract, "DataChange") + adv_storage_contract.set(10, transact={"from": k1}) + (log1,) = get_logs(adv_storage_contract, "DataChange") + adv_storage_contract.set(20, transact={"from": k2}) + (log2,) = get_logs(adv_storage_contract, "DataChange") + adv_storage_contract.reset(transact={"from": 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/tokens/test_erc20.py b/tests/functional/examples/tokens/test_erc20.py index 52f8133c13..e6da4bd46c 100644 --- a/tests/functional/examples/tokens/test_erc20.py +++ b/tests/functional/examples/tokens/test_erc20.py @@ -33,11 +33,8 @@ def c_bad(get_contract): @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 + def get_log_args(_, c, event_name): + return get_logs(c, event_name)[0].args return get_log_args diff --git a/tests/functional/examples/tokens/test_erc721.py b/tests/functional/examples/tokens/test_erc721.py index 128e2d040c..ad858f0720 100644 --- a/tests/functional/examples/tokens/test_erc721.py +++ b/tests/functional/examples/tokens/test_erc721.py @@ -95,15 +95,12 @@ def test_transferFrom_by_owner(c, env, tx_failed, get_logs): c.transferFrom(someone, operator, INVALID_TOKEN_ID, transact={"from": someone}) # transfer by owner - tx_hash = c.transferFrom(someone, operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) + c.transferFrom(someone, operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) - 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[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 @@ -114,15 +111,12 @@ def test_transferFrom_by_approved(c, env, get_logs): # 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}) + c.transferFrom(someone, operator, SOMEONE_TOKEN_IDS[1], transact={"from": 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[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 @@ -133,15 +127,12 @@ def test_transferFrom_by_operator(c, env, get_logs): # transfer by operator c.setApprovalForAll(operator, True, transact={"from": someone}) - tx_hash = c.transferFrom(someone, operator, SOMEONE_TOKEN_IDS[2], transact={"from": operator}) + c.transferFrom(someone, operator, SOMEONE_TOKEN_IDS[2], transact={"from": 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 @@ -167,17 +158,12 @@ def test_safeTransferFrom_by_owner(c, env, tx_failed, get_logs): c.safeTransferFrom(someone, operator, INVALID_TOKEN_ID, transact={"from": someone}) # transfer by owner - tx_hash = c.safeTransferFrom( - someone, operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone} - ) + c.safeTransferFrom(someone, operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) - 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[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 @@ -188,14 +174,10 @@ def test_safeTransferFrom_by_approved(c, env, get_logs): # 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.safeTransferFrom(someone, operator, SOMEONE_TOKEN_IDS[1], transact={"from": 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] @@ -209,17 +191,12 @@ def test_safeTransferFrom_by_operator(c, env, get_logs): # transfer by operator c.setApprovalForAll(operator, True, transact={"from": someone}) - tx_hash = c.safeTransferFrom( - someone, operator, SOMEONE_TOKEN_IDS[2], transact={"from": operator} - ) - - logs = get_logs(tx_hash, c, "Transfer") + c.safeTransferFrom(someone, operator, SOMEONE_TOKEN_IDS[2], transact={"from": 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 @@ -245,17 +222,12 @@ 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} - ) - - logs = get_logs(tx_hash, c, "Transfer") + c.safeTransferFrom(someone, receiver.address, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) - 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 @@ -276,14 +248,12 @@ def test_approve(c, env, tx_failed, get_logs): with tx_failed(): c.approve(operator, INVALID_TOKEN_ID, transact={"from": someone}) - tx_hash = c.approve(operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) - logs = get_logs(tx_hash, c, "Approval") + c.approve(operator, SOMEONE_TOKEN_IDS[0], transact={"from": 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, env, tx_failed, get_logs): @@ -294,11 +264,9 @@ def test_setApprovalForAll(c, env, tx_failed, get_logs): with tx_failed(): c.setApprovalForAll(someone, approved, transact={"from": someone}) - tx_hash = c.setApprovalForAll(operator, approved, transact={"from": someone}) - logs = get_logs(tx_hash, c, "ApprovalForAll") - - assert len(logs) > 0 - args = logs[0].args + c.setApprovalForAll(operator, approved, transact={"from": someone}) + (log,) = get_logs(c, "ApprovalForAll") + args = log.args assert args.owner == someone assert args.operator == operator assert args.approved == approved @@ -316,8 +284,8 @@ def test_mint(c, env, tx_failed, get_logs): c.mint(ZERO_ADDRESS, SOMEONE_TOKEN_IDS[0], transact={"from": minter}) # mint by minter - tx_hash = c.mint(someone, NEW_TOKEN_ID, transact={"from": minter}) - logs = get_logs(tx_hash, c, "Transfer") + c.mint(someone, NEW_TOKEN_ID, transact={"from": minter}) + logs = get_logs(c, "Transfer") assert len(logs) > 0 args = logs[0].args @@ -336,8 +304,8 @@ def test_burn(c, env, tx_failed, get_logs): c.burn(SOMEONE_TOKEN_IDS[0], transact={"from": 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], transact={"from": 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 0adafc8de4..76a753f004 100644 --- a/tests/functional/examples/voting/test_ballot.py +++ b/tests/functional/examples/voting/test_ballot.py @@ -34,7 +34,7 @@ def test_initial_state(env, c): def test_give_the_right_to_vote(env, c, tx_failed): a0, a1, a2, a3, a4, a5 = env.accounts[:6] - c.giveRightToVote(a1, transact={}) + 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 @@ -42,37 +42,37 @@ def test_give_the_right_to_vote(env, c, tx_failed): 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(env, c): a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = env.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={}) + 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 @@ -107,7 +107,7 @@ def test_forward_weight(env, 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 @@ -121,7 +121,7 @@ def test_forward_weight(env, 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 @@ -129,12 +129,12 @@ def test_forward_weight(env, c): 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, transact={}) - c.giveRightToVote(a1, transact={}) - c.giveRightToVote(a2, transact={}) - c.giveRightToVote(a3, transact={}) - c.giveRightToVote(a4, transact={}) - c.giveRightToVote(a5, transact={}) + 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}) @@ -153,10 +153,10 @@ def test_block_short_cycle(env, c, tx_failed): def test_delegate(env, c, tx_failed): a0, a1, a2, a3, a4, a5, a6 = env.accounts[:7] - c.giveRightToVote(a0, transact={}) - c.giveRightToVote(a1, transact={}) - c.giveRightToVote(a2, transact={}) - c.giveRightToVote(a3, transact={}) + 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 @@ -185,18 +185,18 @@ def test_delegate(env, c, tx_failed): def test_vote(env, c, tx_failed): a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = env.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(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, transact={"from": a1}) c.delegate(a1, transact={"from": 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 @@ -218,10 +218,10 @@ def test_vote(env, c, tx_failed): def test_winning_proposal(env, c): a0, a1, a2 = env.accounts[:3] - c.giveRightToVote(a0, transact={}) - c.giveRightToVote(a1, transact={}) - c.giveRightToVote(a2, transact={}) - c.vote(0, transact={}) + 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}) @@ -234,11 +234,11 @@ def test_winning_proposal(env, c): def test_winner_namer(env, c): a0, a1, a2 = env.accounts[:3] - c.giveRightToVote(a0, transact={}) - c.giveRightToVote(a1, transact={}) - c.giveRightToVote(a2, transact={}) + c.giveRightToVote(a0) + c.giveRightToVote(a1) + c.giveRightToVote(a2) c.delegate(a1, transact={"from": a2}) - c.vote(0, transact={}) + c.vote(0) # Proposal 0 is now winning assert c.winnerName()[:7] == b"Clinton" c.vote(1, transact={"from": a1}) diff --git a/tests/functional/syntax/test_msg_data.py b/tests/functional/syntax/test_msg_data.py index 3803bd53af..6dd687da29 100644 --- a/tests/functional/syntax/test_msg_data.py +++ b/tests/functional/syntax/test_msg_data.py @@ -86,7 +86,7 @@ def foo(): self.cache = slice(msg.data, 0, 4) """ contract = get_contract(code) - contract.foo(transact={}) + contract.foo() assert contract.cache() == method_id("foo()") From b7e2a3770b372dd30b32742de5a8ac78fcea590e Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 5 Apr 2024 11:17:00 +0200 Subject: [PATCH 49/87] Self-review and exception type --- tests/conftest.py | 4 +-- tests/evm_backends/base_env.py | 11 +++++--- tests/evm_backends/pyevm_env.py | 9 +++---- tests/evm_backends/revm_env.py | 5 ++-- .../builtins/codegen/test_raw_call.py | 2 +- .../codegen/features/decorators/conftest.py | 1 + .../codegen/features/test_clampers.py | 16 ++++++------ .../codegen/features/test_reverting.py | 7 +++-- .../codegen/features/test_short_circuiting.py | 16 ++++++------ .../codegen/integration/test_escrow.py | 1 + .../functional/codegen/test_selector_table.py | 4 +-- .../codegen/types/numbers/test_sqrt.py | 5 ++-- .../codegen/types/test_array_indexing.py | 21 ++++++++------- tests/functional/examples/conftest.py | 1 + .../examples/factory/test_factory.py | 9 ++----- .../examples/storage/test_advanced_storage.py | 2 +- .../examples/storage/test_storage.py | 12 +++------ .../functional/examples/tokens/test_erc20.py | 8 +++--- .../functional/examples/tokens/test_erc721.py | 4 +-- .../functional/examples/wallet/test_wallet.py | 2 +- tests/functional/syntax/test_address_code.py | 26 +++++++------------ tests/functional/syntax/test_msg_data.py | 8 +++--- tests/functional/syntax/test_self_balance.py | 2 +- 23 files changed, 82 insertions(+), 94 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 008a711c31..85dc14531f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -3,11 +3,11 @@ import hypothesis import pytest from eth_tester.backends.pyevm.main import get_default_account_keys -from eth_tester.exceptions import TransactionFailed from hexbytes import HexBytes import vyper.evm.opcodes as evm_opcodes from tests.evm_backends.abi_contract import ABIContract +from tests.evm_backends.base_env import EvmError from tests.evm_backends.pyevm_env import PyEvmEnv from tests.evm_backends.revm_env import RevmEnv from tests.utils import working_directory @@ -321,7 +321,7 @@ def assert_side_effects_invoked(side_effects_contract, side_effects_trigger, n=1 def tx_failed(env): # todo: use custom exception, we don't use eth_tester anymore @contextmanager - def fn(exception=TransactionFailed, exc_text=None): + def fn(exception=EvmError, exc_text=None): with env.anchor(), pytest.raises(exception) as excinfo: yield excinfo diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index 05326c2d76..dc36912b9c 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -2,7 +2,6 @@ from typing import Callable, Tuple from eth_keys.datatypes import PrivateKey -from eth_tester.exceptions import TransactionFailed from eth_utils import to_checksum_address from tests.evm_backends.abi import abi_decode, abi_encode @@ -38,7 +37,7 @@ def deploy(self, abi: list[dict], bytecode: bytes, value=0, *args, **kwargs): try: deployed_at = self._deploy(initcode, value) except RuntimeError as e: - raise TransactionFailed(*e.args) from e + raise EvmError(*e.args) from e address = to_checksum_address(deployed_at) return factory.at(self, address) @@ -113,6 +112,10 @@ def _parse_revert(output_bytes: bytes, error: Exception, gas_used: int): prefix = "execution reverted" if output_bytes[:4] == method_id("Error(string)"): (msg,) = abi_decode("(string)", output_bytes[4:]) - raise TransactionFailed(f"{prefix}: {msg}", gas_used) from error + raise EvmError(f"{prefix}: {msg}", gas_used) from error - raise TransactionFailed(f"{prefix}: 0x{output_bytes.hex()}", gas_used) from error + raise EvmError(f"{prefix}: 0x{output_bytes.hex()}", gas_used) from error + + +class EvmError(RuntimeError): + """Exception raised when a transaction reverts.""" diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index 35a77c0642..b9303602b9 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -15,13 +15,12 @@ from eth.vm.message import Message from eth.vm.transaction_context import BaseTransactionContext from eth_keys.datatypes import PrivateKey -from eth_tester.exceptions import TransactionFailed from eth_tester.utils.address import generate_contract_address from eth_typing import Address from eth_utils import setup_DEBUG2_logging, to_checksum_address import vyper.evm.opcodes as evm_opcodes -from tests.evm_backends.base_env import BaseEnv +from tests.evm_backends.base_env import BaseEnv, EvmError class PyEvmEnv(BaseEnv): @@ -144,7 +143,7 @@ def execute_code( ), ) except VMError as e: - raise TransactionFailed(*e.args) from e + raise EvmError(*e.args) from e finally: self._clear_transient_storage() @@ -165,7 +164,7 @@ def _check_computation(self, computation): gas_used = computation.get_gas_used() self._parse_revert(output, computation.error, gas_used) - raise TransactionFailed(*computation.error.args) from computation.error + raise EvmError(*computation.error.args) from computation.error def get_code(self, address: str): return self._state.get_code(_addr(address)) @@ -197,7 +196,7 @@ def _deploy(self, code: bytes, value: int, gas: int = None) -> str: transaction_context=BaseTransactionContext(origin=sender, gas_price=0), ) except VMError as e: - raise TransactionFailed(*e.args) from e + raise EvmError(*e.args) from e finally: self._clear_transient_storage() self._check_computation(computation) diff --git a/tests/evm_backends/revm_env.py b/tests/evm_backends/revm_env.py index 47621c8860..9580740bcc 100644 --- a/tests/evm_backends/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -2,10 +2,9 @@ from contextlib import contextmanager from eth_keys.datatypes import PrivateKey -from eth_tester.exceptions import TransactionFailed from pyrevm import EVM, BlockEnv, Env -from tests.evm_backends.base_env import BaseEnv +from tests.evm_backends.base_env import BaseEnv, EvmError class RevmEnv(BaseEnv): @@ -105,7 +104,7 @@ def execute_code( gas_used, output_str = match.groups() output_bytes = bytes.fromhex(output_str) self._parse_revert(output_bytes, e, int(gas_used)) - raise TransactionFailed(*e.args) from e + raise EvmError(*e.args) from e finally: self._evm.reset_transient_storage() diff --git a/tests/functional/builtins/codegen/test_raw_call.py b/tests/functional/builtins/codegen/test_raw_call.py index fcb99f93ec..5fa71fa7e8 100644 --- a/tests/functional/builtins/codegen/test_raw_call.py +++ b/tests/functional/builtins/codegen/test_raw_call.py @@ -172,7 +172,7 @@ def set(i: int128, owner: address): assert outer_contract.owners(1) == a1 -def test_gas(get_contract, tx_failed, env): +def test_gas(get_contract, tx_failed): inner_code = """ bar: bytes32 diff --git a/tests/functional/codegen/features/decorators/conftest.py b/tests/functional/codegen/features/decorators/conftest.py index 1765e5d928..99d1ada3c9 100644 --- a/tests/functional/codegen/features/decorators/conftest.py +++ b/tests/functional/codegen/features/decorators/conftest.py @@ -3,4 +3,5 @@ @pytest.fixture(autouse=True) def set_initial_balance(env): + # set the balance of the deployer so the tests can transfer funds env.set_balance(env.deployer, 10**20) diff --git a/tests/functional/codegen/features/test_clampers.py b/tests/functional/codegen/features/test_clampers.py index bee9ee4f9d..bcf767e1a4 100644 --- a/tests/functional/codegen/features/test_clampers.py +++ b/tests/functional/codegen/features/test_clampers.py @@ -260,7 +260,7 @@ def foo(s: uint{bits}) -> uint{bits}: "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF", ], ) -def test_address_clamper_passing(env, get_contract, address): +def test_address_clamper_passing(get_contract, address): code = """ @external def foo(s: address) -> address: @@ -338,7 +338,7 @@ def foo(s: decimal) -> decimal: @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) -def test_int128_array_clamper_passing(env, 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]: @@ -371,7 +371,7 @@ def foo(b: int128[5]) -> int128[5]: @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) -def test_int128_array_looped_clamper_passing(env, 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 @@ -402,7 +402,7 @@ def foo(b: int128[10]) -> int128[10]: @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) -def test_multidimension_array_clamper_passing(env, 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]: @@ -433,7 +433,7 @@ def foo(b: int128[6][1][2]) -> int128[6][1][2]: @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) -def test_int128_dynarray_clamper_passing(env, 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]: @@ -469,7 +469,7 @@ def foo(b: int128[5]) -> int128[5]: @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) -def test_int128_dynarray_looped_clamper_passing(env, 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 @@ -503,7 +503,7 @@ def foo(b: DynArray[int128, 10]) -> DynArray[int128, 10]: @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(env, get_contract, value): +def test_multidimension_dynarray_clamper_passing(get_contract, value): code = """ @external def foo( @@ -546,7 +546,7 @@ def foo(b: DynArray[DynArray[int128, 2], 2]) -> DynArray[DynArray[int128, 2], 2] @pytest.mark.parametrize("value", [0, 1, -1, 2**127 - 1, -(2**127)]) -def test_dynarray_list_clamper_passing(env, get_contract, value): +def test_dynarray_list_clamper_passing(get_contract, value): code = """ @external def foo( diff --git a/tests/functional/codegen/features/test_reverting.py b/tests/functional/codegen/features/test_reverting.py index bbb1d48b4f..d69e5ec722 100644 --- a/tests/functional/codegen/features/test_reverting.py +++ b/tests/functional/codegen/features/test_reverting.py @@ -1,6 +1,5 @@ import pytest from eth.codecs import abi -from eth_tester.exceptions import TransactionFailed from vyper.utils import method_id @@ -17,7 +16,7 @@ def foo(): revert_bytes = method_id("NoFives()") - with tx_failed(TransactionFailed, exc_text=revert_bytes.hex()): + with tx_failed(exc_text=revert_bytes.hex()): get_contract(reverty_code).foo() @@ -32,7 +31,7 @@ def foo(): revert_bytes = method_id("NoFives(uint256)") + abi.encode("(uint256)", (5,)) - with tx_failed(TransactionFailed, exc_text=revert_bytes.hex()): + with tx_failed(exc_text=revert_bytes.hex()): get_contract(reverty_code).foo() @@ -46,5 +45,5 @@ def foo(): revert_bytes = method_id("NoFives(uint256)") + abi.encode("(uint256)", (5,)) - with tx_failed(TransactionFailed, exc_text=revert_bytes.hex()): + 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 4627b9c885..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(env, get_contract): +def test_short_circuit_and_left_is_false(get_contract): code = """ called_left: public(bool) @@ -31,7 +31,7 @@ def foo() -> bool: assert not c.called_right() -def test_short_circuit_and_left_is_true(env, get_contract): +def test_short_circuit_and_left_is_true(get_contract): code = """ called_left: public(bool) @@ -59,7 +59,7 @@ def foo() -> bool: assert c.called_right() -def test_short_circuit_or_left_is_true(env, get_contract): +def test_short_circuit_or_left_is_true(get_contract): code = """ called_left: public(bool) @@ -87,7 +87,7 @@ def foo() -> bool: assert not c.called_right() -def test_short_circuit_or_left_is_false(env, get_contract): +def test_short_circuit_or_left_is_false(get_contract): code = """ called_left: public(bool) @@ -117,7 +117,7 @@ def foo() -> bool: @pytest.mark.parametrize("op", ["and", "or"]) @pytest.mark.parametrize("a, b", itertools.product([True, False], repeat=2)) -def test_from_memory(env, 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(env, 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(env, 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(env, 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/integration/test_escrow.py b/tests/functional/codegen/integration/test_escrow.py index 55b8ea2314..b843dd1a26 100644 --- a/tests/functional/codegen/integration/test_escrow.py +++ b/tests/functional/codegen/integration/test_escrow.py @@ -3,6 +3,7 @@ @pytest.fixture(autouse=True) def set_initial_balance(env): + # set the balance of the deployer so the tests can transfer funds env.set_balance(env.deployer, 10**20) diff --git a/tests/functional/codegen/test_selector_table.py b/tests/functional/codegen/test_selector_table.py index 917d909792..69b0427252 100644 --- a/tests/functional/codegen/test_selector_table.py +++ b/tests/functional/codegen/test_selector_table.py @@ -614,8 +614,8 @@ def __default__(): elif default_fn_mutability == "@payable": # we should be able to send eth to it tx_params["value"] = 1 - tx = env.execute_code(**tx_params) - logs = get_logs(tx, c, "CalledDefault") + env.execute_code(**tx_params) + logs = get_logs(c, "CalledDefault") assert len(logs) == 1 else: env.execute_code(**tx_params) diff --git a/tests/functional/codegen/types/numbers/test_sqrt.py b/tests/functional/codegen/types/numbers/test_sqrt.py index c8b41e9779..3f29773d4c 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 vyper.utils import SizeLimits @@ -159,6 +158,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(value) diff --git a/tests/functional/codegen/types/test_array_indexing.py b/tests/functional/codegen/types/test_array_indexing.py index acb1cf7db3..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,8 +57,9 @@ def set2(idx: uint256): """ c = get_contract(code) - with pytest.raises(TransactionFailed): + with tx_failed(): c.set2(2**256 - 1) + with tx_failed(): c.set2(2**256 - 2) diff --git a/tests/functional/examples/conftest.py b/tests/functional/examples/conftest.py index ec2a92afaf..506548f6e0 100644 --- a/tests/functional/examples/conftest.py +++ b/tests/functional/examples/conftest.py @@ -8,4 +8,5 @@ def setup(memory_mocker): @pytest.fixture(autouse=True) def set_initial_balance(env): + # set the balance of the deployer so the tests can transfer funds env.set_balance(env.deployer, 10**20) diff --git a/tests/functional/examples/factory/test_factory.py b/tests/functional/examples/factory/test_factory.py index 88826c0a5d..1c5bd9d0e9 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 @@ -31,16 +30,12 @@ def create_exchange(token, factory): @pytest.fixture -def factory(get_contract, optimize, experimental_codegen, evm_version): +def factory(get_contract, compiler_settings): with open("examples/factory/Exchange.vy") as f: code = f.read() exchange_interface = vyper.compile_code( - code, - output_formats=["bytecode_runtime"], - settings=Settings( - evm_version=evm_version, optimize=optimize, experimental_codegen=experimental_codegen - ), + code, output_formats=["bytecode_runtime"], settings=compiler_settings ) exchange_deployed_bytecode = exchange_interface["bytecode_runtime"] diff --git a/tests/functional/examples/storage/test_advanced_storage.py b/tests/functional/examples/storage/test_advanced_storage.py index 29749e9ae5..25555a69f6 100644 --- a/tests/functional/examples/storage/test_advanced_storage.py +++ b/tests/functional/examples/storage/test_advanced_storage.py @@ -5,7 +5,7 @@ @pytest.fixture -def adv_storage_contract(env, 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 diff --git a/tests/functional/examples/storage/test_storage.py b/tests/functional/examples/storage/test_storage.py index d891eea3c1..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(env, 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(env, storage_contract): - k0 = env.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_erc20.py b/tests/functional/examples/tokens/test_erc20.py index e6da4bd46c..c4e00840ec 100644 --- a/tests/functional/examples/tokens/test_erc20.py +++ b/tests/functional/examples/tokens/test_erc20.py @@ -276,24 +276,24 @@ def test_raw_logs(c, env, get_log_args): # Check that mint appropriately emits Transfer event args = get_log_args(c.mint(a1, 2, transact={"from": minter}), c, "Transfer") - assert args.sender in (ZERO_ADDRESS, None) + 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") - assert args.sender in (ZERO_ADDRESS, None) + 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") assert args.sender == a1 - assert args.receiver in (ZERO_ADDRESS, None) + assert args.receiver == ZERO_ADDRESS assert args.value == 1 args = get_log_args(c.burn(0, transact={"from": a1}), c, "Transfer") assert args.sender == a1 - assert args.receiver in (ZERO_ADDRESS, None) + assert args.receiver == ZERO_ADDRESS assert args.value == 0 # Check that transfer appropriately emits Transfer event diff --git a/tests/functional/examples/tokens/test_erc721.py b/tests/functional/examples/tokens/test_erc721.py index ad858f0720..5cc93af4c0 100644 --- a/tests/functional/examples/tokens/test_erc721.py +++ b/tests/functional/examples/tokens/test_erc721.py @@ -289,7 +289,7 @@ def test_mint(c, env, tx_failed, get_logs): assert len(logs) > 0 args = logs[0].args - assert args.sender in (ZERO_ADDRESS, None) + assert args.sender == ZERO_ADDRESS assert args.receiver == someone assert args.token_id == NEW_TOKEN_ID assert c.ownerOf(NEW_TOKEN_ID) == someone @@ -310,7 +310,7 @@ def test_burn(c, env, tx_failed, get_logs): assert len(logs) > 0 args = logs[0].args assert args.sender == someone - assert args.receiver in (ZERO_ADDRESS, None) + assert args.receiver == ZERO_ADDRESS assert args.token_id == SOMEONE_TOKEN_IDS[0] with tx_failed(): c.ownerOf(SOMEONE_TOKEN_IDS[0]) diff --git a/tests/functional/examples/wallet/test_wallet.py b/tests/functional/examples/wallet/test_wallet.py index ae7f811203..0efda5002a 100644 --- a/tests/functional/examples/wallet/test_wallet.py +++ b/tests/functional/examples/wallet/test_wallet.py @@ -106,7 +106,7 @@ def test_javascript_signatures(env, get_contract, keccak): # Set the owners to zero addresses with open("examples/wallet/wallet.vy") as f: - owners = [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]) env.execute_code(x2.address, value=10**17) diff --git a/tests/functional/syntax/test_address_code.py b/tests/functional/syntax/test_address_code.py index 3d62797af2..65b56bd906 100644 --- a/tests/functional/syntax/test_address_code.py +++ b/tests/functional/syntax/test_address_code.py @@ -2,10 +2,8 @@ from typing import Type import pytest -from eth_tester.exceptions import TransactionFailed 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 @@ -37,7 +35,7 @@ def code_slice(x: address) -> Bytes[{length}]: assert actual == expected -def test_address_code_runtime_error_slice_too_long(precompiled_contract, 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""" @@ -46,18 +44,18 @@ def code_slice(x: address) -> Bytes[{length}]: return slice(x.code, {start}, {length}) """ contract = get_contract(code) - 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) @@ -159,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, evm_version): +def test_address_code_self_success(get_contract, compiler_settings): code = """ code_deployment: public(Bytes[32]) @@ -173,17 +171,13 @@ def code_runtime() -> Bytes[32]: """ contract = get_contract(code) code_compiled = compiler.compile_code( - code, - output_formats=["bytecode", "bytecode_runtime"], - settings=Settings( - evm_version=evm_version, optimize=optimize, experimental_codegen=experimental_codegen - ), + code, output_formats=["bytecode", "bytecode_runtime"], settings=compiler_settings ) 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]) @@ -191,16 +185,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_msg_data.py b/tests/functional/syntax/test_msg_data.py index 6dd687da29..a2cf022f21 100644 --- a/tests/functional/syntax/test_msg_data.py +++ b/tests/functional/syntax/test_msg_data.py @@ -1,5 +1,4 @@ import pytest -from eth_tester.exceptions import TransactionFailed from eth_utils import to_bytes from vyper import compiler @@ -77,7 +76,7 @@ def foo() -> (uint256, Bytes[4], uint256): assert contract.foo() == (2**256 - 1, method_id("foo()"), 2**256 - 1) -def test_assignment_to_storage(env, get_contract, keccak): +def test_assignment_to_storage(get_contract, keccak): code = """ cache: public(Bytes[4]) @@ -157,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: @@ -166,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_self_balance.py b/tests/functional/syntax/test_self_balance.py index 906f078593..91af631d2b 100644 --- a/tests/functional/syntax/test_self_balance.py +++ b/tests/functional/syntax/test_self_balance.py @@ -19,7 +19,7 @@ def __default__(): c = get_contract(code) env.set_balance(env.deployer, 1337) - env.execute_code(**{"to": c.address, "value": 1337}) + env.execute_code(c.address, value=1337) assert c.get_balance() == 1337 assert env.get_balance(c.address) == 1337 From 95f3fe535e94f426e5858582f54445029049b00c Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Fri, 5 Apr 2024 09:07:28 -0400 Subject: [PATCH 50/87] review --- tests/conftest.py | 1 + tests/evm_backends/abi_contract.py | 6 +++++- .../calling_convention/test_external_contract_calls.py | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 85dc14531f..82f3381d6a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -185,6 +185,7 @@ def gas_limit(): @pytest.fixture(scope="module") +# REVIEW: just return type BaseEnv? def env(gas_limit, evm_version, evm_backend, tracing) -> PyEvmEnv | RevmEnv: return evm_backend( gas_limit=gas_limit, diff --git a/tests/evm_backends/abi_contract.py b/tests/evm_backends/abi_contract.py index b07e01d851..3f8b5e5a3c 100644 --- a/tests/evm_backends/abi_contract.py +++ b/tests/evm_backends/abi_contract.py @@ -15,6 +15,7 @@ from .abi import abi_decode, abi_encode, is_abi_encodable if TYPE_CHECKING: + # REVIEW: bad import -- see below comment about BaseEnv from tests.evm_backends.revm_env import RevmEnv @@ -39,6 +40,8 @@ def __init__(self, event_abi: dict, contract_name: str): @cached_property def topic_id(self) -> bytes: """The keccak256 hash of the event signature.""" + # REVIEW: what does truthy represent here? i would prefer an `is not None` + # or more explicit `if "anonymous" in self._abi`. if self._abi.get("anonymous"): return b"" return keccak256((self.name + self.signature).encode()) @@ -211,6 +214,7 @@ def __call__(self, *args, value=0, gas=None, sender=None, transact=None, call=No value=value, gas=gas, is_modifying=self.is_mutable, + # REVIEW: let's kill the transact and call dicts transact={**(transact or {}), **(call or {})}, ) @@ -305,7 +309,7 @@ def address(self) -> HexAddress: def __init__( self, - env: "RevmEnv", + env: "RevmEnv", # REVIEW: should be "BaseEnv" name: str, abi: dict, functions: list[ABIFunction], 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 e53a4be33b..a12f5c60f3 100644 --- a/tests/functional/codegen/calling_convention/test_external_contract_calls.py +++ b/tests/functional/codegen/calling_convention/test_external_contract_calls.py @@ -1394,6 +1394,7 @@ def get_lucky(amount_to_send: uint256) -> int128: # Send some eth env.set_balance(env.deployer, 10000) + # REVIEW: why is anchor needed here? with env.anchor(): assert c2.get_lucky(0, transact={"value": 500}) == 1 @@ -1404,6 +1405,7 @@ def get_lucky(amount_to_send: uint256) -> int128: assert env.get_balance(c2.address) == 0 # Send subset of amount + # REVIEW: why is anchor needed here? with env.anchor(): assert c2.get_lucky(250, transact={"value": 500}) == 1 c2.get_lucky(250, transact={"value": 500}) From 81b49da05f5c5faf195e190e3e9cc8db45181d4d Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 5 Apr 2024 16:11:47 +0200 Subject: [PATCH 51/87] Review comments --- tests/conftest.py | 5 +- tests/evm_backends/abi_contract.py | 13 +- tests/evm_backends/base_env.py | 51 ++++- tests/evm_backends/pyevm_env.py | 15 +- tests/evm_backends/revm_env.py | 13 +- .../builtins/codegen/test_create_functions.py | 2 +- .../functional/builtins/codegen/test_send.py | 6 +- .../test_default_parameters.py | 4 +- .../test_external_contract_calls.py | 8 +- .../codegen/environment_variables/test_tx.py | 2 +- .../features/decorators/test_nonreentrant.py | 8 +- .../features/decorators/test_payable.py | 6 +- .../features/decorators/test_private.py | 2 +- .../features/iteration/test_range_in.py | 6 +- .../codegen/features/test_assert.py | 2 +- .../features/test_assert_unreachable.py | 2 +- .../codegen/features/test_bytes_map_keys.py | 2 +- .../codegen/features/test_clampers.py | 4 +- tests/functional/codegen/features/test_gas.py | 4 +- .../features/test_logging_from_call.py | 2 +- .../codegen/integration/test_crowdfund.py | 24 +-- .../codegen/integration/test_escrow.py | 6 +- .../functional/codegen/test_selector_table.py | 2 +- tests/functional/codegen/types/test_string.py | 2 +- .../examples/auctions/test_blind_auction.py | 57 ++--- .../auctions/test_simple_open_auction.py | 26 +-- .../examples/company/test_company.py | 54 ++--- .../crowdfund/test_crowdfund_example.py | 24 +-- .../examples/factory/test_factory.py | 10 +- .../test_on_chain_market_maker.py | 22 +- .../test_safe_remote_purchase.py | 28 +-- .../examples/storage/test_advanced_storage.py | 20 +- .../examples/tokens/test_erc1155.py | 120 +++++------ .../functional/examples/tokens/test_erc20.py | 200 +++++++++--------- .../examples/tokens/test_erc4626.py | 12 +- .../functional/examples/tokens/test_erc721.py | 70 +++--- .../functional/examples/voting/test_ballot.py | 66 +++--- .../functional/examples/wallet/test_wallet.py | 16 +- 38 files changed, 477 insertions(+), 439 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 82f3381d6a..f02ca10433 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,7 +7,7 @@ import vyper.evm.opcodes as evm_opcodes from tests.evm_backends.abi_contract import ABIContract -from tests.evm_backends.base_env import EvmError +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 @@ -185,8 +185,7 @@ def gas_limit(): @pytest.fixture(scope="module") -# REVIEW: just return type BaseEnv? -def env(gas_limit, evm_version, evm_backend, tracing) -> PyEvmEnv | RevmEnv: +def env(gas_limit, evm_version, evm_backend, tracing) -> BaseEnv: return evm_backend( gas_limit=gas_limit, tracing=tracing, diff --git a/tests/evm_backends/abi_contract.py b/tests/evm_backends/abi_contract.py index 3f8b5e5a3c..8e66df9bd5 100644 --- a/tests/evm_backends/abi_contract.py +++ b/tests/evm_backends/abi_contract.py @@ -15,8 +15,7 @@ from .abi import abi_decode, abi_encode, is_abi_encodable if TYPE_CHECKING: - # REVIEW: bad import -- see below comment about BaseEnv - from tests.evm_backends.revm_env import RevmEnv + from tests.evm_backends.base_env import BaseEnv @dataclass @@ -40,9 +39,7 @@ def __init__(self, event_abi: dict, contract_name: str): @cached_property def topic_id(self) -> bytes: """The keccak256 hash of the event signature.""" - # REVIEW: what does truthy represent here? i would prefer an `is not None` - # or more explicit `if "anonymous" in self._abi`. - if self._abi.get("anonymous"): + if self._abi.get("anonymous") is True: return b"" return keccak256((self.name + self.signature).encode()) @@ -199,7 +196,7 @@ def _merge_kwargs(self, *args, **kwargs) -> list: error = f"Missing keyword argument {e} for `{self.signature}`. Passed {args} {kwargs}" raise TypeError(error) - def __call__(self, *args, value=0, gas=None, sender=None, transact=None, call=None, **kwargs): + def __call__(self, *args, value=0, gas=None, 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.") @@ -214,8 +211,6 @@ def __call__(self, *args, value=0, gas=None, sender=None, transact=None, call=No value=value, gas=gas, is_modifying=self.is_mutable, - # REVIEW: let's kill the transact and call dicts - transact={**(transact or {}), **(call or {})}, ) match self.contract.marshal_to_python(computation, self.return_type): @@ -309,7 +304,7 @@ def address(self) -> HexAddress: def __init__( self, - env: "RevmEnv", # REVIEW: should be "BaseEnv" + env: "BaseEnv", name: str, abi: dict, functions: list[ABIFunction], diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index dc36912b9c..0f93423d7f 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -1,4 +1,5 @@ import json +from contextlib import contextmanager from typing import Callable, Tuple from eth_keys.datatypes import PrivateKey @@ -77,7 +78,7 @@ def deploy_blueprint( deploy_preamble = bytes.fromhex("61" + bytecode_len_hex + "3d81600a3d39f3") deploy_bytecode = deploy_preamble + bytecode - deployer_abi = [] # just a constructor + deployer_abi: list[dict] = [] # just a constructor value = 0 deployer = self.deploy(deployer_abi, deploy_bytecode, value, *args) @@ -86,6 +87,54 @@ def factory(address): return deployer, factory + @contextmanager + def anchor(self): + raise NotImplementedError # must be implemented by subclasses + + @contextmanager + def sender(self, address: str): + 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 accounts(self) -> list[str]: + raise NotImplementedError # must be implemented by subclasses + + @property + def block_number(self) -> int: + raise NotImplementedError # must be implemented by subclasses + + @property + def timestamp(self) -> int | None: + raise NotImplementedError # must be implemented by subclasses + + @property + def last_result(self) -> dict | None: + raise NotImplementedError # must be implemented by subclasses + + def execute_code( + 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, + ) -> bytes: + raise NotImplementedError # must be implemented by subclasses + + def get_code(self, address: str) -> bytes: + raise NotImplementedError # must be implemented by subclasses + + def time_travel(self, num_blocks=1, time_delta: int | None = None) -> None: + raise NotImplementedError # must be implemented by subclasses + def _deploy(self, code: bytes, value: int, gas: int = None) -> str: raise NotImplementedError # must be implemented by subclasses diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index b9303602b9..5cb69fdd6f 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -118,14 +118,13 @@ def execute_code( to: str, sender: str | None = None, data: bytes | str = b"", - value: int | None = None, + value: int = 0, gas: int | None = None, + gas_price: int = 0, is_modifying: bool = True, - transact: dict | None = None, ): - transact = transact or {} data = data if isinstance(data, bytes) else bytes.fromhex(data.removeprefix("0x")) - sender = _addr(transact.get("from", sender) or self.deployer) + sender = _addr(sender or self.deployer) try: computation = self._state.computation_class.apply_message( state=self._state, @@ -134,13 +133,11 @@ def execute_code( sender=sender, data=data, code=self.get_code(to), - value=transact.get("value", value) or 0, - gas=transact.get("gas", gas) or self.gas_limit, + value=value, + gas=self.gas_limit if gas is None else gas, is_static=not is_modifying, ), - transaction_context=BaseTransactionContext( - origin=sender, gas_price=transact.get("gasPrice", 0) - ), + transaction_context=BaseTransactionContext(origin=sender, gas_price=gas_price), ) except VMError as e: raise EvmError(*e.args) from e diff --git a/tests/evm_backends/revm_env.py b/tests/evm_backends/revm_env.py index 9580740bcc..dda6812ff8 100644 --- a/tests/evm_backends/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -81,21 +81,20 @@ def execute_code( to: str, sender: str | None = None, data: bytes | str = b"", - value: int | None = None, + value: int = 0, gas: int | None = None, + gas_price: int = 0, is_modifying: bool = True, - transact: dict | None = None, ): - transact = transact or {} data = data if isinstance(data, bytes) else bytes.fromhex(data.removeprefix("0x")) try: output = self._evm.message_call( to=to, - caller=transact.get("from", sender) or self.deployer, + caller=sender or self.deployer, calldata=data, - value=transact.get("value", value), - gas=transact.get("gas", gas) or self.gas_limit, - gas_price=transact.get("gasPrice"), + value=value, + gas=self.gas_limit if gas is None else gas, + gas_price=gas_price, is_static=not is_modifying, ) return bytes(output) diff --git a/tests/functional/builtins/codegen/test_create_functions.py b/tests/functional/builtins/codegen/test_create_functions.py index cf220e1083..29d2f3c6b0 100644 --- a/tests/functional/builtins/codegen/test_create_functions.py +++ b/tests/functional/builtins/codegen/test_create_functions.py @@ -103,7 +103,7 @@ def test2(a: uint256) -> Bytes[100]: GAS_SENT = 30000 with tx_failed(): - c.test2(0, transact={"gas": GAS_SENT}) + c.test2(0, gas=GAS_SENT) assert env.last_result["is_success"] is False assert env.last_result["gas_used"] < GAS_SENT diff --git a/tests/functional/builtins/codegen/test_send.py b/tests/functional/builtins/codegen/test_send.py index 4199c28b36..a563bf4e7d 100644 --- a/tests/functional/builtins/codegen/test_send.py +++ b/tests/functional/builtins/codegen/test_send.py @@ -51,14 +51,14 @@ def __default__(): receiver = get_contract(receiver_code) with tx_failed(): - sender.test_send(receiver.address, transact={"gas": 100000}) + sender.test_send(receiver.address, gas=100000) # no value transfer happened, variable was not changed 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 @@ -93,7 +93,7 @@ def __default__(): 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 diff --git a/tests/functional/codegen/calling_convention/test_default_parameters.py b/tests/functional/codegen/calling_convention/test_default_parameters.py index 8dff6371c7..2976a6eed5 100644 --- a/tests/functional/codegen/calling_convention/test_default_parameters.py +++ b/tests/functional/codegen/calling_convention/test_default_parameters.py @@ -252,9 +252,9 @@ def get_balance() -> uint256: """ c = get_contract(code) env.set_balance(env.deployer, 31337 + 9001) - c.foo(transact={"value": 31337}) + 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 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 a12f5c60f3..bb78753726 100644 --- a/tests/functional/codegen/calling_convention/test_external_contract_calls.py +++ b/tests/functional/codegen/calling_convention/test_external_contract_calls.py @@ -1396,9 +1396,9 @@ def get_lucky(amount_to_send: uint256) -> int128: env.set_balance(env.deployer, 10000) # REVIEW: why is anchor needed here? with env.anchor(): - assert c2.get_lucky(0, transact={"value": 500}) == 1 + assert c2.get_lucky(0, value=500) == 1 - c2.get_lucky(0, transact={"value": 500}) + c2.get_lucky(0, value=500) # Contract 1 received money. assert c1.get_balance() == 500 assert env.get_balance(c1.address) == 500 @@ -1407,8 +1407,8 @@ def get_lucky(amount_to_send: uint256) -> int128: # Send subset of amount # REVIEW: why is anchor needed here? with env.anchor(): - assert c2.get_lucky(250, transact={"value": 500}) == 1 - c2.get_lucky(250, transact={"value": 500}) + assert c2.get_lucky(250, value=500) == 1 + c2.get_lucky(250, value=500) # Contract 1 received more money. assert c1.get_balance() == 750 diff --git a/tests/functional/codegen/environment_variables/test_tx.py b/tests/functional/codegen/environment_variables/test_tx.py index d9a23e69cb..efdde8a919 100644 --- a/tests/functional/codegen/environment_variables/test_tx.py +++ b/tests/functional/codegen/environment_variables/test_tx.py @@ -7,4 +7,4 @@ def tx_gasprice() -> uint256: 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 bfad00fe1e..55b4d81027 100644 --- a/tests/functional/codegen/features/decorators/test_nonreentrant.py +++ b/tests/functional/codegen/features/decorators/test_nonreentrant.py @@ -260,26 +260,26 @@ def __default__(): assert reentrant_contract.callback() == calling_contract.address # Test unprotected function without callback. - reentrant_contract.unprotected_function("some value", False, transact={"value": 1000}) + reentrant_contract.unprotected_function("some value", False, value=1000) assert reentrant_contract.special_value() == "some value" 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 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 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 c70fba15e9..2c4c621273 100644 --- a/tests/functional/codegen/features/decorators/test_payable.py +++ b/tests/functional/codegen/features/decorators/test_payable.py @@ -183,7 +183,7 @@ def baz() -> bool: 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(): env.execute_code(c.address, data=sig, value=10**18) @@ -337,8 +337,8 @@ def bar() -> bool: def test_payable_runtime_assertion(get_contract, code): c = get_contract(code) - c.foo(transact={"value": 10**18}) - c.foo(transact={"value": 0}) + c.foo(value=10**18) + c.foo(value=0) def test_payable_default_func_invalid_calldata(get_contract, env): diff --git a/tests/functional/codegen/features/decorators/test_private.py b/tests/functional/codegen/features/decorators/test_private.py index 415e7a2541..f6bb110d9f 100644 --- a/tests/functional/codegen/features/decorators/test_private.py +++ b/tests/functional/codegen/features/decorators/test_private.py @@ -444,7 +444,7 @@ def whoami() -> address: assert c.i_am_me() addr = env.accounts[1] - c.whoami(transact={"from": addr}) + c.whoami(sender=addr) (log,) = get_logs(c) assert log.args.addr == addr diff --git a/tests/functional/codegen/features/iteration/test_range_in.py b/tests/functional/codegen/features/iteration/test_range_in.py index e7e9fa85a4..6870bc3d48 100644 --- a/tests/functional/codegen/features/iteration/test_range_in.py +++ b/tests/functional/codegen/features/iteration/test_range_in.py @@ -132,14 +132,14 @@ def is_owner() -> bool: 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) - assert c.is_owner(call={"from": a1}) is True + assert c.is_owner(sender=a1) is True # Owner in place 0 can be replaced. c.set_owner(0, a1) diff --git a/tests/functional/codegen/features/test_assert.py b/tests/functional/codegen/features/test_assert.py index a2a74fa818..09cd7c8aee 100644 --- a/tests/functional/codegen/features/test_assert.py +++ b/tests/functional/codegen/features/test_assert.py @@ -17,7 +17,7 @@ def foo(): env.set_balance(env.deployer, 10**7) gas_sent = 10**6 with tx_failed(): - c.foo(transact={"gas": gas_sent, "gasPrice": 10}) + c.foo(gas=gas_sent, gas_price=10) assert env.last_result["gas_used"] < gas_sent, "Gas refund not received" assert env.last_result["is_success"] is False diff --git a/tests/functional/codegen/features/test_assert_unreachable.py b/tests/functional/codegen/features/test_assert_unreachable.py index 35bc7420ae..6c286d90c9 100644 --- a/tests/functional/codegen/features/test_assert_unreachable.py +++ b/tests/functional/codegen/features/test_assert_unreachable.py @@ -9,7 +9,7 @@ def foo(): c = get_contract(code) gas_sent = 10**6 with tx_failed(): - c.foo(transact={"gas": gas_sent, "gasPrice": 10}) + c.foo(gas=gas_sent, gas_price=10) assert env.last_result["gas_used"] == gas_sent # Drains all gains sent assert env.last_result["is_success"] is False diff --git a/tests/functional/codegen/features/test_bytes_map_keys.py b/tests/functional/codegen/features/test_bytes_map_keys.py index 1bbb7d002d..dfb775015b 100644 --- a/tests/functional/codegen/features/test_bytes_map_keys.py +++ b/tests/functional/codegen/features/test_bytes_map_keys.py @@ -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 bcf767e1a4..2e4dc88ae2 100644 --- a/tests/functional/codegen/features/test_clampers.py +++ b/tests/functional/codegen/features/test_clampers.py @@ -412,7 +412,7 @@ 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)]) @@ -516,7 +516,7 @@ 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)]) diff --git a/tests/functional/codegen/features/test_gas.py b/tests/functional/codegen/features/test_gas.py index 525d3e8e92..b8bc3a5063 100644 --- a/tests/functional/codegen/features/test_gas.py +++ b/tests/functional/codegen/features/test_gas.py @@ -7,5 +7,5 @@ def foo() -> uint256: 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_logging_from_call.py b/tests/functional/codegen/features/test_logging_from_call.py index 1bedfe050e..6c9d803c3e 100644 --- a/tests/functional/codegen/features/test_logging_from_call.py +++ b/tests/functional/codegen/features/test_logging_from_call.py @@ -74,7 +74,7 @@ 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 + # assert c.test_func(2**255, b'x' * 129) == b'x' * 129 c.test_func(1234444, b"x" * 129) logs = get_logs(c, "TestLog") diff --git a/tests/functional/codegen/integration/test_crowdfund.py b/tests/functional/codegen/integration/test_crowdfund.py index 2741dcd247..d51de0fd6d 100644 --- a/tests/functional/codegen/integration/test_crowdfund.py +++ b/tests/functional/codegen/integration/test_crowdfund.py @@ -69,12 +69,12 @@ def refund(): 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 = env.get_balance(a1) env.time_travel(100) @@ -84,10 +84,10 @@ def refund(): assert post_bal - pre_bal == 54 c = get_contract(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}) + 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.time_travel(100) assert c.expired() assert not c.reached() @@ -161,13 +161,13 @@ def refund(): 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.time_travel() # 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 = env.get_balance(a1) env.time_travel(100) @@ -177,10 +177,10 @@ def refund(): assert post_bal - pre_bal == 54 c = get_contract(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}) + 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.time_travel(100) assert c.expired() assert not c.reached() diff --git a/tests/functional/codegen/integration/test_escrow.py b/tests/functional/codegen/integration/test_escrow.py index b843dd1a26..98c7306a8d 100644 --- a/tests/functional/codegen/integration/test_escrow.py +++ b/tests/functional/codegen/integration/test_escrow.py @@ -35,7 +35,7 @@ def refund(): c = get_contract(arbitration_code, value=1) c.setup(a1, a2) with tx_failed(): - c.finalize(transact={"from": a1}) + c.finalize(sender=a1) c.finalize() print("Passed escrow test") @@ -68,7 +68,7 @@ def refund(): a0, a1, a2 = env.accounts[:3] 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/test_selector_table.py b/tests/functional/codegen/test_selector_table.py index 69b0427252..438f5f5344 100644 --- a/tests/functional/codegen/test_selector_table.py +++ b/tests/functional/codegen/test_selector_table.py @@ -593,7 +593,7 @@ def __default__(): # do payable check if mutability == "@payable": - func(*args, transact={"value": 1}) + func(*args, value=1) (event,) = get_logs(c, "_Return") assert event.args.val == func_id else: diff --git a/tests/functional/codegen/types/test_string.py b/tests/functional/codegen/types/test_string.py index b1b8e19411..a573df47c2 100644 --- a/tests/functional/codegen/types/test_string.py +++ b/tests/functional/codegen/types/test_string.py @@ -56,7 +56,7 @@ 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 diff --git a/tests/functional/examples/auctions/test_blind_auction.py b/tests/functional/examples/auctions/test_blind_auction.py index 8c8da4ac25..072fbd49fd 100644 --- a/tests/functional/examples/auctions/test_blind_auction.py +++ b/tests/functional/examples/auctions/test_blind_auction.py @@ -53,7 +53,8 @@ def test_late_bid(env, auction_contract, tx_failed, keccak): ] ) ), - transact={"value": 200, "from": k1}, + value=200, + sender=k1, ) @@ -72,7 +73,8 @@ def test_too_many_bids(env, auction_contract, tx_failed, keccak): ] ) ), - transact={"value": i, "from": k1}, + value=i, + sender=k1, ) # 129th bid should fail @@ -87,7 +89,8 @@ def test_too_many_bids(env, auction_contract, tx_failed, keccak): ] ) ), - transact={"value": 128, "from": k1}, + value=128, + sender=k1, ) @@ -105,7 +108,8 @@ def test_early_reval(env, auction_contract, tx_failed, keccak): ] ) ), - transact={"value": 100, "from": k1}, + value=100, + sender=k1, ) # Move time slightly forward (still before bidding has ended) @@ -120,9 +124,7 @@ def test_early_reval(env, auction_contract, tx_failed, keccak): _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() == ZERO_ADDRESS @@ -144,7 +146,8 @@ def test_late_reveal(env, auction_contract, tx_failed, keccak): ] ) ), - transact={"value": 100, "from": k1}, + value=100, + sender=k1, ) # Move time forward past bidding _and_ reveal time @@ -159,9 +162,7 @@ def test_late_reveal(env, auction_contract, tx_failed, keccak): _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() == ZERO_ADDRESS @@ -174,7 +175,7 @@ def test_early_end(env, auction_contract, tx_failed): # 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(env, auction_contract, tx_failed): @@ -184,11 +185,11 @@ def test_double_end(env, auction_contract, tx_failed): env.time_travel(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(env, auction_contract, keccak): @@ -211,7 +212,8 @@ def test_blind_auction(env, auction_contract, keccak): ] ) ), - transact={"value": 100, "from": k1}, + value=100, + sender=k1, ) # k2 places 1 real bid (highest) and 2 fake @@ -225,7 +227,8 @@ def test_blind_auction(env, auction_contract, keccak): ] ) ), - transact={"value": 150, "from": k2}, + value=150, + sender=k2, ) auction_contract.bid( keccak( @@ -237,7 +240,8 @@ def test_blind_auction(env, auction_contract, keccak): ] ) ), - transact={"value": 250, "from": k2}, + value=250, + sender=k2, ) auction_contract.bid( keccak( @@ -249,7 +253,8 @@ def test_blind_auction(env, auction_contract, keccak): ] ) ), - transact={"value": 300, "from": k2}, + value=300, + sender=k2, ) # k3 places 2 fake bids @@ -263,7 +268,8 @@ def test_blind_auction(env, auction_contract, keccak): ] ) ), - transact={"value": 175, "from": k3}, + value=175, + sender=k3, ) auction_contract.bid( keccak( @@ -275,7 +281,8 @@ def test_blind_auction(env, auction_contract, keccak): ] ) ), - transact={"value": 275, "from": k3}, + value=275, + sender=k3, ) ################################################################### @@ -293,7 +300,7 @@ def test_blind_auction(env, auction_contract, keccak): _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 @@ -313,7 +320,7 @@ def test_blind_auction(env, auction_contract, keccak): _fakes[2] = True _secrets[2] = (1234567).to_bytes(32, byteorder="big") balance_before_reveal = env.get_balance(k2) - auction_contract.reveal(3, _values, _fakes, _secrets, transact={"value": 0, "from": 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 @@ -334,7 +341,7 @@ def test_blind_auction(env, auction_contract, keccak): _fakes[1] = True _secrets[1] = (9876543).to_bytes(32, byteorder="big") balance_before_reveal = env.get_balance(k3) - auction_contract.reveal(2, _values, _fakes, _secrets, transact={"value": 0, "from": 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 @@ -353,7 +360,7 @@ def test_blind_auction(env, auction_contract, keccak): # End the auction balance_before_end = env.get_balance(k0) - auction_contract.auctionEnd(transact={"value": 0, "from": k0}) + auction_contract.auctionEnd(value=0, sender=k0) balance_after_end = env.get_balance(k0) # Check that auction indeed ended @@ -364,6 +371,6 @@ def test_blind_auction(env, auction_contract, keccak): # Check that k1 is able to withdraw their outbid bid balance_before_withdraw = env.get_balance(k1) - auction_contract.withdraw(transact={"value": 0, "from": 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 54023286a4..4f2e0a9eb3 100644 --- a/tests/functional/examples/auctions/test_simple_open_auction.py +++ b/tests/functional/examples/auctions/test_simple_open_auction.py @@ -44,37 +44,37 @@ def test_bid(env, auction_contract, tx_failed): # 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 = env.get_balance(k1) - auction_contract.withdraw(transact={"from": k1}) + auction_contract.withdraw(sender=k1) balance_after_withdrawal = env.get_balance(k1) # Balance increases after withdrawal assert balance_after_withdrawal > balance_before_withdrawal @@ -91,18 +91,18 @@ def test_end_auction(env, auction_contract, tx_failed): 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) env.time_travel(EXPIRY) balance_before_end = env.get_balance(k1) - auction_contract.endAuction(transact={"from": k2}) + 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 0704dfbd11..35b4951471 100644 --- a/tests/functional/examples/company/test_company.py +++ b/tests/functional/examples/company/test_company.py @@ -17,33 +17,33 @@ def test_overbuy(env, c, tx_failed): 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(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(env, c, tx_failed): @@ -51,48 +51,48 @@ def test_oversell(env, c, tx_failed): # 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(env, c, tx_failed): # If you don't have any stock, you can't transfer 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(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(env, c): @@ -100,24 +100,24 @@ def test_valuation(env, c): # 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(env, c, get_logs): a0, a1, a2, a3 = env.accounts[:4] # Buy is logged - c.buyStock(transact={"from": a1, "value": 7 * c.price()}) + c.buyStock(value=7 * c.price(), sender=a1) (log,) = get_logs(c, "Buy") assert log.args.buy_order == 7 # Sell is logged - c.sellStock(3, transact={"from": a1}) + c.sellStock(3, sender=a1) (log,) = get_logs(c, "Sell") assert log.args.sell_order == 3 # Transfer is logged - c.transferStock(a2, 4, transact={"from": a1}) + c.transferStock(a2, 4, sender=a1) (log,) = get_logs(c, "Transfer") assert log.event == "Transfer" assert log.args.value == 4 diff --git a/tests/functional/examples/crowdfund/test_crowdfund_example.py b/tests/functional/examples/crowdfund/test_crowdfund_example.py index 89f5d17278..ad56778e04 100644 --- a/tests/functional/examples/crowdfund/test_crowdfund_example.py +++ b/tests/functional/examples/crowdfund/test_crowdfund_example.py @@ -10,14 +10,14 @@ def c(env, get_contract): def test_crowdfund_example(c, env): a0, a1, a2, a3, a4, a5, a6 = env.accounts[:7] - c.participate(transact={"value": 5}) + c.participate(value=5) env.time_travel() # make sure auction has started assert c.timelimit() == 60 assert c.deadline() - env.timestamp == 59 assert env.timestamp < c.deadline() # expired assert env.get_balance(c.address) < c.goal() # not reached - c.participate(transact={"value": 49}) + c.participate(value=49) # assert c.reached() pre_bal = env.get_balance(a1) env.time_travel(100) @@ -32,10 +32,10 @@ def test_crowdfund_example2(c, env, tx_failed): for i, a in enumerate(env.accounts[3:7]): env.set_balance(a, i + 1) - 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}) + 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 env.time_travel(100) @@ -43,12 +43,12 @@ def test_crowdfund_example2(c, env, tx_failed): # assert not c.reached() 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}) + 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 1c5bd9d0e9..7947a4b464 100644 --- a/tests/functional/examples/factory/test_factory.py +++ b/tests/functional/examples/factory/test_factory.py @@ -23,7 +23,7 @@ def create_exchange(env, get_contract): 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": env.accounts[0]}) + exchange.initialize(sender=env.accounts[0]) return exchange return create_exchange @@ -54,15 +54,15 @@ def test_exchange(env, factory, create_token, create_exchange): 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 d6f92c9488..3645bc1bf8 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 @@ -38,7 +38,7 @@ def test_initiate(env, market_maker, erc20, tx_failed): a0 = env.accounts[0] ether, ethers = to_wei(1, "ether"), to_wei(2, "ether") erc20.approve(market_maker.address, ethers) - market_maker.initiate(erc20.address, ether, transact={"value": 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 @@ -48,20 +48,20 @@ def test_initiate(env, 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(env, market_maker, erc20): a1 = env.accounts[1] erc20.approve(market_maker.address, to_wei(2, "ether")) - market_maker.initiate(erc20.address, to_wei(1, "ether"), transact={"value": 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() == to_wei(1, "ether") assert market_maker.totalEthQty() == to_wei(2, "ether") env.set_balance(a1, 100) - market_maker.ethToTokens(transact={"value": 100, "from": a1}) + market_maker.ethToTokens(value=100, sender=a1) assert erc20.balanceOf(market_maker.address) == 999999999999999950 assert erc20.balanceOf(a1) == 50 assert market_maker.totalTokenQty() == 999999999999999950 @@ -74,17 +74,15 @@ def test_tokens_to_eth(env, market_maker, erc20): env.set_balance(a1, a1_balance_before) erc20.transfer(a1, to_wei(2, "ether")) - erc20.approve(market_maker.address, to_wei(2, "ether"), transact={"from": a1}) - market_maker.initiate( - erc20.address, to_wei(1, "ether"), transact={"value": to_wei(2, "ether"), "from": a1} - ) + 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 env.get_balance(a1) == a1_balance_before - to_wei(2, "ether") assert market_maker.totalTokenQty() == to_wei(1, "ether") - erc20.approve(market_maker.address, to_wei(1, "ether"), transact={"from": a1}) - market_maker.tokensToEth(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 env.get_balance(market_maker.address) == to_wei(1, "ether") # got 1 eth back, for trade. @@ -100,7 +98,7 @@ def test_owner_withdraw(env, market_maker, erc20, tx_failed): # Approve 2 eth transfers. erc20.approve(market_maker.address, to_wei(2, "ether")) # Initiate market with 2 eth value. - market_maker.initiate(erc20.address, to_wei(1, "ether"), transact={"value": 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 env.get_balance(a0) == a0_balance_before - to_wei(2, "ether") # a0's balance is locked up in market_maker contract. @@ -108,7 +106,7 @@ def test_owner_withdraw(env, market_maker, erc20, tx_failed): # Only owner can call ownerWithdraw with tx_failed(): - market_maker.ownerWithdraw(transact={"from": a1}) + 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/safe_remote_purchase/test_safe_remote_purchase.py b/tests/functional/examples/safe_remote_purchase/test_safe_remote_purchase.py index 6fe78c27ac..d67ac5e72a 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 @@ -59,15 +59,15 @@ def test_abort(env, tx_failed, get_balance, get_contract, contract_code): 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(env, get_contract, tx_failed, get_balance, contract_code): @@ -79,11 +79,11 @@ def test_purchase(env, get_contract, tx_failed, get_balance, contract_code): 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 @@ -92,7 +92,7 @@ def test_purchase(env, 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(env, get_contract, tx_failed, get_balance, contract_code): @@ -103,14 +103,14 @@ def test_received(env, get_contract, tx_failed, get_balance, contract_code): 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) @@ -161,13 +161,13 @@ def __default__(): env.get_balance(buyer_contract_address), ) # Start purchase - buyer_contract.start_purchase(transact={"value": 4, "from": a1, "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" with tx_failed(): - buyer_contract.start_received(transact={"from": a1, "gas": 100000}) + buyer_contract.start_received(sender=a1, gas=100000) # Final check if everything worked. 1 value has been transferred assert env.get_balance(a0), env.get_balance(buyer_contract_address) == ( diff --git a/tests/functional/examples/storage/test_advanced_storage.py b/tests/functional/examples/storage/test_advanced_storage.py index 25555a69f6..51e5a1729e 100644 --- a/tests/functional/examples/storage/test_advanced_storage.py +++ b/tests/functional/examples/storage/test_advanced_storage.py @@ -24,35 +24,35 @@ def test_failed_transactions(env, adv_storage_contract, tx_failed): # 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(EncodeError): - adv_storage_contract.set("foo", transact={"from": k1}) + adv_storage_contract.set("foo", sender=k1) # Assert a different exception that contains specific text with tx_failed(TypeError, "invocation failed due to improper number of arguments"): - adv_storage_contract.set(1, 2, transact={"from": k1}) + adv_storage_contract.set(1, 2, sender=k1) def test_events(env, adv_storage_contract, get_logs): k1, k2 = env.accounts[:2] - adv_storage_contract.set(10, transact={"from": k1}) + adv_storage_contract.set(10, sender=k1) (log1,) = get_logs(adv_storage_contract, "DataChange") - adv_storage_contract.set(20, transact={"from": k2}) + adv_storage_contract.set(20, sender=k2) (log2,) = get_logs(adv_storage_contract, "DataChange") - adv_storage_contract.reset(transact={"from": k1}) + adv_storage_contract.reset(sender=k1) logs3 = get_logs(adv_storage_contract, "DataChange") # Check log contents diff --git a/tests/functional/examples/tokens/test_erc1155.py b/tests/functional/examples/tokens/test_erc1155.py index 659e98a4b4..771ed328ca 100644 --- a/tests/functional/examples/tokens/test_erc1155.py +++ b/tests/functional/examples/tokens/test_erc1155.py @@ -36,26 +36,26 @@ def erc1155(get_contract, env, tx_failed): 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 @@ -91,10 +91,10 @@ def test_pause(erc1155, env, tx_failed): # 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 @@ -113,16 +113,16 @@ def test_pause(erc1155, env, 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 @@ -137,9 +137,9 @@ def test_pause(erc1155, env, 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 @@ -152,11 +152,11 @@ def test_contractURI(erc1155, env, tx_failed): # 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 @@ -168,10 +168,10 @@ 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 @@ -179,8 +179,8 @@ def test_URI(erc1155, env, 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" @@ -189,31 +189,31 @@ def test_safeTransferFrom_balanceOf_single(erc1155, env, tx_failed): 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 @@ -238,49 +238,45 @@ def test_safeBatchTransferFrom_balanceOf_batch(erc1155, env, 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 ) - 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 @@ -290,24 +286,24 @@ 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 @@ -325,24 +321,24 @@ def test_mint_batch_burn_batch(erc1155, env, 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] @@ -351,11 +347,11 @@ 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) @@ -377,7 +373,7 @@ def test_max_batch_size_violation(erc1155, env, 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 @@ -391,7 +387,7 @@ def test_ownership_functions(erc1155, env, tx_failed): 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(): @@ -401,7 +397,7 @@ def test_ownership_functions(erc1155, env, tx_failed): 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 @@ -411,8 +407,8 @@ def test_renounce_ownership(erc1155, env, tx_failed): 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 c4e00840ec..60fe5267a0 100644 --- a/tests/functional/examples/tokens/test_erc20.py +++ b/tests/functional/examples/tokens/test_erc20.py @@ -62,269 +62,269 @@ def test_mint_and_burn(c, env, tx_failed): # 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, env, tx_failed): # Test total supply initially, after mint, between two burns, and after failed burn 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, 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, env, tx_failed): minter, a1, a2 = env.accounts[0:3] - c.mint(a1, MAX_UINT256, transact={"from": minter}) + 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(EncodeError): - c.transfer(a1, MAX_UINT256 + 1, transact={"from": a2}) + 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, 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, 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_log_args): minter, a1, a2, a3 = env.accounts[0:4] # 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 @@ -333,11 +333,11 @@ def test_raw_logs(c, env, get_log_args): 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 = env.accounts[0:3] - c_bad.mint(a1, MAX_UINT256, transact={"from": minter}) - c_bad.mint(a2, 1, transact={"from": minter}) + 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 @@ -346,21 +346,21 @@ def test_bad_burn(c_bad, env, tx_failed): # Ensure burn fails if it would otherwise underflow balance when totalSupply is corrupted 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, env, tx_failed): # Ensure transferFrom fails if it would otherwise overflow balance when totalSupply is corrupted minter, a1, a2 = env.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}) + 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 ae4991f33e..f0fb79efae 100644 --- a/tests/functional/examples/tokens/test_erc4626.py +++ b/tests/functional/examples/tokens/test_erc4626.py @@ -45,9 +45,9 @@ def test_preview_methods(env, 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(env, 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(env, 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(env, 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 5cc93af4c0..1ed26f64dc 100644 --- a/tests/functional/examples/tokens/test_erc721.py +++ b/tests/functional/examples/tokens/test_erc721.py @@ -19,9 +19,9 @@ def c(get_contract, env): 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 @@ -60,7 +60,7 @@ def test_getApproved(c, env): 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 @@ -70,7 +70,7 @@ def test_isApprovedForAll(c, env): 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 @@ -80,22 +80,22 @@ def test_transferFrom_by_owner(c, env, tx_failed, get_logs): # 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 - c.transferFrom(someone, operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) + c.transferFrom(someone, operator, SOMEONE_TOKEN_IDS[0], sender=someone) (log,) = get_logs(c, "Transfer") assert log.args.sender == someone @@ -110,8 +110,8 @@ 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}) - c.transferFrom(someone, operator, SOMEONE_TOKEN_IDS[1], transact={"from": operator}) + c.approve(operator, SOMEONE_TOKEN_IDS[1], sender=someone) + c.transferFrom(someone, operator, SOMEONE_TOKEN_IDS[1], sender=operator) (log,) = get_logs(c, "Transfer") assert log.args.sender == someone @@ -126,8 +126,8 @@ 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}) - c.transferFrom(someone, operator, SOMEONE_TOKEN_IDS[2], transact={"from": operator}) + c.setApprovalForAll(operator, True, sender=someone) + c.transferFrom(someone, operator, SOMEONE_TOKEN_IDS[2], sender=operator) (log,) = get_logs(c, "Transfer") assert log.args.sender == someone @@ -143,22 +143,22 @@ def test_safeTransferFrom_by_owner(c, env, tx_failed, get_logs): # 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 - c.safeTransferFrom(someone, operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) + c.safeTransferFrom(someone, operator, SOMEONE_TOKEN_IDS[0], sender=someone) (log,) = get_logs(c, "Transfer") assert log.args.sender == someone @@ -173,8 +173,8 @@ 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}) - c.safeTransferFrom(someone, operator, SOMEONE_TOKEN_IDS[1], transact={"from": operator}) + c.approve(operator, SOMEONE_TOKEN_IDS[1], sender=someone) + c.safeTransferFrom(someone, operator, SOMEONE_TOKEN_IDS[1], sender=operator) (log,) = get_logs(c, "Transfer") args = log.args @@ -190,8 +190,8 @@ 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}) - 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) (log,) = get_logs(c, "Transfer") assert log.args.sender == someone @@ -207,7 +207,7 @@ def test_safeTransferFrom_to_contract(c, env, tx_failed, get_logs, get_contract) # 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( @@ -222,7 +222,7 @@ def onERC721Received( return method_id("onERC721Received(address,address,uint256,bytes)", output_type=bytes4) """ ) - c.safeTransferFrom(someone, receiver.address, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) + c.safeTransferFrom(someone, receiver.address, SOMEONE_TOKEN_IDS[0], sender=someone) (log,) = get_logs(c, "Transfer") assert log.args.sender == someone @@ -238,17 +238,17 @@ def test_approve(c, env, tx_failed, get_logs): # 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) - c.approve(operator, SOMEONE_TOKEN_IDS[0], transact={"from": someone}) + c.approve(operator, SOMEONE_TOKEN_IDS[0], sender=someone) (log,) = get_logs(c, "Approval") assert log.args.owner == someone @@ -262,9 +262,9 @@ def test_setApprovalForAll(c, env, tx_failed, get_logs): # setApprovalForAll myself with tx_failed(): - c.setApprovalForAll(someone, approved, transact={"from": someone}) + c.setApprovalForAll(someone, approved, sender=someone) - c.setApprovalForAll(operator, approved, transact={"from": someone}) + c.setApprovalForAll(operator, approved, sender=someone) (log,) = get_logs(c, "ApprovalForAll") args = log.args assert args.owner == someone @@ -277,14 +277,14 @@ def test_mint(c, env, tx_failed, get_logs): # 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 - c.mint(someone, NEW_TOKEN_ID, transact={"from": minter}) + c.mint(someone, NEW_TOKEN_ID, sender=minter) logs = get_logs(c, "Transfer") assert len(logs) > 0 @@ -301,10 +301,10 @@ def test_burn(c, env, tx_failed, get_logs): # 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 - c.burn(SOMEONE_TOKEN_IDS[0], transact={"from": someone}) + c.burn(SOMEONE_TOKEN_IDS[0], sender=someone) logs = get_logs(c, "Transfer") assert len(logs) > 0 diff --git a/tests/functional/examples/voting/test_ballot.py b/tests/functional/examples/voting/test_ballot.py index 76a753f004..2135feff72 100644 --- a/tests/functional/examples/voting/test_ballot.py +++ b/tests/functional/examples/voting/test_ballot.py @@ -76,30 +76,30 @@ def test_forward_weight(env, c): # 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 @@ -113,7 +113,7 @@ def test_forward_weight(env, c): 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 @@ -136,17 +136,17 @@ def test_block_short_cycle(env, c, tx_failed): 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 @@ -160,7 +160,7 @@ def test_delegate(env, c, tx_failed): # 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 @@ -169,16 +169,16 @@ def test_delegate(env, 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 @@ -193,8 +193,8 @@ def test_vote(env, c, tx_failed): c.giveRightToVote(a5) c.giveRightToVote(a6) c.giveRightToVote(a7) - c.delegate(a0, transact={"from": a1}) - c.delegate(a1, transact={"from": a3}) + c.delegate(a0, sender=a1) + c.delegate(a1, sender=a3) # Voter can vote c.vote(0) # Vote count changes based on voters weight @@ -204,16 +204,16 @@ def test_vote(env, 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(env, c): @@ -224,10 +224,10 @@ def test_winning_proposal(env, c): 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 @@ -237,10 +237,10 @@ def test_winner_namer(env, c): c.giveRightToVote(a0) c.giveRightToVote(a1) c.giveRightToVote(a2) - c.delegate(a1, transact={"from": 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 0efda5002a..4f7e0b5be0 100644 --- a/tests/functional/examples/wallet/test_wallet.py +++ b/tests/functional/examples/wallet/test_wallet.py @@ -45,27 +45,27 @@ 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") @@ -113,6 +113,4 @@ def test_javascript_signatures(env, get_contract, keccak): # 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} - ) + x2.approve(0, recipient, 25, b"", sigs + [[0, 0, 0]] * 3, value=10**17) From 4a8ba2bf106e92e47c566b09b777d4b304937638 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 5 Apr 2024 16:25:47 +0200 Subject: [PATCH 52/87] Remove last transact --- tests/evm_backends/abi_contract.py | 3 +-- .../calling_convention/test_external_contract_calls.py | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/evm_backends/abi_contract.py b/tests/evm_backends/abi_contract.py index 8e66df9bd5..bb2c277924 100644 --- a/tests/evm_backends/abi_contract.py +++ b/tests/evm_backends/abi_contract.py @@ -258,7 +258,6 @@ def __call__( gas=None, sender=None, disambiguate_signature=None, - transact=None, **kwargs, ): """ @@ -268,7 +267,7 @@ def __call__( function = self._pick_overload( *args, disambiguate_signature=disambiguate_signature, **kwargs ) - return function(*args, value=value, gas=gas, sender=sender, transact=transact, **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.""" 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 bb78753726..e0ece0f58a 100644 --- a/tests/functional/codegen/calling_convention/test_external_contract_calls.py +++ b/tests/functional/codegen/calling_convention/test_external_contract_calls.py @@ -1395,7 +1395,7 @@ def get_lucky(amount_to_send: uint256) -> int128: # Send some eth env.set_balance(env.deployer, 10000) # REVIEW: why is anchor needed here? - with env.anchor(): + with env.anchor(): # anchor to check if the transaction is cancelled assert c2.get_lucky(0, value=500) == 1 c2.get_lucky(0, value=500) @@ -1405,8 +1405,7 @@ def get_lucky(amount_to_send: uint256) -> int128: assert env.get_balance(c2.address) == 0 # Send subset of amount - # REVIEW: why is anchor needed here? - with env.anchor(): + with env.anchor(): # anchor to check if the transaction is cancelled assert c2.get_lucky(250, value=500) == 1 c2.get_lucky(250, value=500) From 5f770921af3ebb8f36fd9771f17735cc9998b854 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 5 Apr 2024 20:56:34 +0200 Subject: [PATCH 53/87] fix gas_price --- tests/evm_backends/abi_contract.py | 11 +++-------- tests/evm_backends/pyevm_env.py | 2 +- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/tests/evm_backends/abi_contract.py b/tests/evm_backends/abi_contract.py index bb2c277924..aa8d918965 100644 --- a/tests/evm_backends/abi_contract.py +++ b/tests/evm_backends/abi_contract.py @@ -196,7 +196,7 @@ def _merge_kwargs(self, *args, **kwargs) -> list: error = f"Missing keyword argument {e} for `{self.signature}`. Passed {args} {kwargs}" raise TypeError(error) - def __call__(self, *args, value=0, gas=None, sender=None, **kwargs): + 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.") @@ -210,6 +210,7 @@ def __call__(self, *args, value=0, gas=None, sender=None, **kwargs): data=self.prepare_calldata(*args, **kwargs), value=value, gas=gas, + gas_price=gas_price, is_modifying=self.is_mutable, ) @@ -252,13 +253,7 @@ def name(self) -> str: return self.functions[0].name def __call__( - self, - *args, - value=0, - gas=None, - sender=None, - disambiguate_signature=None, - **kwargs, + self, *args, value=0, gas=None, sender=None, disambiguate_signature=None, **kwargs ): """ Call the function that matches the given arguments. diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index 5cb69fdd6f..26f5305ad8 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -190,7 +190,7 @@ def _deploy(self, code: bytes, value: int, gas: int = None) -> str: gas=gas or self.gas_limit, create_address=target_address, ), - transaction_context=BaseTransactionContext(origin=sender, gas_price=0), + transaction_context=BaseTransactionContext(origin=sender), ) except VMError as e: raise EvmError(*e.args) from e From 7e782579a3387d3a9304f1a6191350ab2c5541ea Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Sun, 7 Apr 2024 18:46:40 -0400 Subject: [PATCH 54/87] add some review comments --- tests/conftest.py | 18 ++++++++++++++++++ tests/evm_backends/abi.py | 1 + tests/evm_backends/abi_contract.py | 7 ++++++- tests/evm_backends/base_env.py | 4 +++- tests/evm_backends/pyevm_env.py | 10 ++++++++++ tests/evm_backends/revm_env.py | 1 + .../builtins/codegen/test_abi_decode.py | 1 + .../builtins/codegen/test_create_functions.py | 4 ++++ .../functional/codegen/features/test_assert.py | 1 + .../features/test_assert_unreachable.py | 1 + .../codegen/integration/test_eth_tester.py | 5 ++++- 11 files changed, 50 insertions(+), 3 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index f02ca10433..d0b06d2da9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,6 +2,20 @@ import hypothesis import pytest + +# REVIEW: let's get rid of get_default_account_keys and have our own keys generator. +# for reference, eth-tester implementation is just +#@to_tuple +#def get_default_account_keys(quantity=None): +# keys = KeyAPI() +# quantity = quantity or 10 +# for i in range(1, quantity + 1): +# pk_bytes = int_to_big_endian(i).rjust(32, b"\x00") +# private_key = keys.PrivateKey(pk_bytes) +# yield private_key +# we could do something like `(random.nextbytes() for _ in range(10))` (with a +# pre-defined seed like b"vyper"). + from eth_tester.backends.pyevm.main import get_default_account_keys from hexbytes import HexBytes @@ -199,6 +213,7 @@ def env(gas_limit, evm_version, evm_backend, tracing) -> BaseEnv: def get_contract_from_ir(env, optimize): def ir_compiler(ir, *args, **kwargs): ir = IRnode.from_list(ir) + # REVIEW: does kwargs.pop("optimize", optimize) match the previous behavior? if kwargs.pop("optimize", optimize) != OptimizationLevel.NONE: ir = optimizer.optimize(ir) @@ -247,6 +262,8 @@ def fn(source_code, *args, **kwargs): @pytest.fixture(scope="module") def get_logs(env): def fn(c: ABIContract, event_name: str = None, raw=False): + # REVIEW: maybe it would be slicker to have something like + # `env.get_logs()`? logs = [log for log in env.last_result["logs"] if c.address == log.address] if raw: return [log.data for log in logs] @@ -265,6 +282,7 @@ def fn(c: ABIContract, event_name: str = None, raw=False): @pytest.fixture def assert_compile_failed(): def assert_compile_failed(function_to_test, exception=Exception): + # REVIEW: should isolate the call to get_contract with pytest.raises(exception): function_to_test() diff --git a/tests/evm_backends/abi.py b/tests/evm_backends/abi.py index f1a29af197..c540468d44 100644 --- a/tests/evm_backends/abi.py +++ b/tests/evm_backends/abi.py @@ -26,6 +26,7 @@ def visit_BytesNode(cls, node: BytesNode, value: bytes | str) -> bytes: @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) diff --git a/tests/evm_backends/abi_contract.py b/tests/evm_backends/abi_contract.py index aa8d918965..abfad60f26 100644 --- a/tests/evm_backends/abi_contract.py +++ b/tests/evm_backends/abi_contract.py @@ -7,7 +7,7 @@ from eth_typing import ChecksumAddress, HexAddress from eth_utils import to_checksum_address -from pyrevm import Log +from pyrevm import Log # REVIEW: this leaks from pyrevm from vyper.semantics.analysis.base import FunctionVisibility, StateMutability from vyper.utils import keccak256, method_id @@ -70,9 +70,13 @@ def signature(self) -> str: def __repr__(self) -> str: return f"ABITopic {self._contract_name}.{self.signature} (0x{self.topic_id.hex()})" + # REVIEW: can be removed, repr is the default implementation for str def __str__(self) -> str: return repr(self) + # REVIEW: Log leaks information from pyrevm, i'd prefer this to be generic. + # can we have a LogEntry which both pyevmenv and revmenv need to parse + # log entries into. def parse(self, log: Log) -> ABILog: topics, raw_data = log.data return ABILog( @@ -136,6 +140,7 @@ def argument_types(self) -> list: def argument_count(self) -> int: return len(self.argument_types) + # REVIEW: why not `_signature`? @property def signature(self) -> str: return f"({_format_abi_type(self.argument_types)})" diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index 0f93423d7f..5caf91f2dd 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -138,9 +138,10 @@ def time_travel(self, num_blocks=1, time_delta: int | None = None) -> None: def _deploy(self, code: bytes, value: int, gas: int = None) -> str: raise NotImplementedError # must be implemented by subclasses + # REVIEW: is there a reason this needs to be a method? def _compile( self, source_code, output_formats, settings, input_bundle - ) -> Tuple[list[dict], bytes]: + ) -> Tuple[list[dict], bytes]: # REVIEW: tuple can be used in the signature out = compile_code( source_code, # test that all output formats can get generated @@ -158,6 +159,7 @@ def _parse_revert(output_bytes: bytes, error: Exception, gas_used: int): """ Tries to parse the EIP-838 revert reason from the output bytes. """ + #REVIEW: not sure the prefix is needed prefix = "execution reverted" if output_bytes[:4] == method_id("Error(string)"): (msg,) = abi_decode("(string)", output_bytes[4:]) diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index 26f5305ad8..317de23fe0 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -76,6 +76,8 @@ def anchor(self): finally: self._state.revert(snapshot_id) + # REVIEW: this can be a method on super since it is the same in + # all environments @contextmanager def sender(self, address: str): original_deployer = self.deployer @@ -139,9 +141,12 @@ def execute_code( ), transaction_context=BaseTransactionContext(origin=sender, gas_price=gas_price), ) + # REVIEW: why is VMError caught here, but check_computation is also + # required below? except VMError as e: raise EvmError(*e.args) from e finally: + # REVIEW: not sure why transient storage needs to be cleared here self._clear_transient_storage() self._check_computation(computation) @@ -170,6 +175,7 @@ def time_travel(self, num_blocks=1, time_delta: int | None = None) -> None: """ Move the block number forward by `num_blocks` and the timestamp forward by `time_delta`. """ + # REVIEW: is cast necessary? context = cast(ExecutionContext, self._state.execution_context) context._block_number += num_blocks context._timestamp += num_blocks if time_delta is None else time_delta @@ -192,9 +198,12 @@ def _deploy(self, code: bytes, value: int, gas: int = None) -> str: ), transaction_context=BaseTransactionContext(origin=sender), ) + # REVIEW: why is VMError caught here, but check_computation is also + # required below? except VMError as e: raise EvmError(*e.args) from e finally: + # REVIEW: not sure why transient storage needs to be cleared here self._clear_transient_storage() self._check_computation(computation) return "0x" + target_address.hex() @@ -206,6 +215,7 @@ def _generate_contract_address(self, sender: Address) -> Address: # a very simple log representation for the raw log entries +# REVIEW: maybe "LogEntry" is a better name Log = namedtuple("Log", ["address", "topics", "data"]) diff --git a/tests/evm_backends/revm_env.py b/tests/evm_backends/revm_env.py index dda6812ff8..7cdb360a7b 100644 --- a/tests/evm_backends/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -34,6 +34,7 @@ def anchor(self): finally: try: self._evm.revert(snapshot_id) + # REVIEW: why does this happen? except OverflowError: # snapshot_id is reverted by the transaction already. # revm updates are needed to make the journal more robust. diff --git a/tests/functional/builtins/codegen/test_abi_decode.py b/tests/functional/builtins/codegen/test_abi_decode.py index e37ed32d5a..d1c03ad9e6 100644 --- a/tests/functional/builtins/codegen/test_abi_decode.py +++ b/tests/functional/builtins/codegen/test_abi_decode.py @@ -60,6 +60,7 @@ def abi_decode_struct(x: Bytes[544]) -> Human: assert tuple(c.abi_decode(encoded)) == (TEST_ADDR, -1, True, Decimal("-123.4"), test_bytes32) test_bytes32 = b"".join(chr(i).encode("utf-8") for i in range(32)) + # REVIEW: why is this now a list instead of tuple? human_tuple = [ "foobar", ("vyper", TEST_ADDR, 123, True, Decimal("123.4"), [123, 456, 789], test_bytes32), diff --git a/tests/functional/builtins/codegen/test_create_functions.py b/tests/functional/builtins/codegen/test_create_functions.py index 29d2f3c6b0..1fa6214b5d 100644 --- a/tests/functional/builtins/codegen/test_create_functions.py +++ b/tests/functional/builtins/codegen/test_create_functions.py @@ -105,7 +105,10 @@ def test2(a: uint256) -> Bytes[100]: with tx_failed(): c.test2(0, gas=GAS_SENT) + # REVIEW: implied by tx_failed assert env.last_result["is_success"] is False + # REVIEW: add a comment maybe like "check the staticcall performed + # no sstore" (or reason string) assert env.last_result["gas_used"] < GAS_SENT @@ -414,6 +417,7 @@ 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(): + # REVIEW: why is HexBytes needed here? env.execute_code(d.address, env.deployer, HexBytes(f"{sig}{encoded}")) diff --git a/tests/functional/codegen/features/test_assert.py b/tests/functional/codegen/features/test_assert.py index 09cd7c8aee..bb5ff31a41 100644 --- a/tests/functional/codegen/features/test_assert.py +++ b/tests/functional/codegen/features/test_assert.py @@ -20,6 +20,7 @@ def foo(): c.foo(gas=gas_sent, gas_price=10) assert env.last_result["gas_used"] < gas_sent, "Gas refund not received" + # REVIEW: implied by tx_failed assert env.last_result["is_success"] is False diff --git a/tests/functional/codegen/features/test_assert_unreachable.py b/tests/functional/codegen/features/test_assert_unreachable.py index 6c286d90c9..f5a8ec5fd8 100644 --- a/tests/functional/codegen/features/test_assert_unreachable.py +++ b/tests/functional/codegen/features/test_assert_unreachable.py @@ -12,6 +12,7 @@ def foo(): c.foo(gas=gas_sent, gas_price=10) assert env.last_result["gas_used"] == gas_sent # Drains all gains sent + # REVIEW: i think this is implied by tx_failed()? assert env.last_result["is_success"] is False diff --git a/tests/functional/codegen/integration/test_eth_tester.py b/tests/functional/codegen/integration/test_eth_tester.py index 6369f63709..58a54f2124 100644 --- a/tests/functional/codegen/integration/test_eth_tester.py +++ b/tests/functional/codegen/integration/test_eth_tester.py @@ -204,7 +204,10 @@ def get_contract_module(source_code, *args, **kwargs): return get_contract_module - +# REVIEW: there is a lot in this module for just the single test. should we just +# delete it and re-add integration tests as a follow up? also, if we are going +# to keep it then maybe move it to +# tests/functional/integration/test_eth_tester.py def test_slice_storage_bytes32(get_contract): code = """ bytez: bytes32 From 28ed360a8d20732e487d7830ddcee7ba01a409c3 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 8 Apr 2024 13:06:23 +0200 Subject: [PATCH 55/87] Review comments --- tests/conftest.py | 49 +--- tests/evm_backends/abi_contract.py | 17 +- tests/evm_backends/base_env.py | 57 +++-- tests/evm_backends/pyevm_env.py | 60 ++--- tests/evm_backends/revm_env.py | 28 +-- .../builtins/codegen/test_abi_decode.py | 5 +- .../builtins/codegen/test_create_functions.py | 17 +- .../test_external_contract_calls.py | 1 - .../codegen/features/test_assert.py | 4 +- .../features/test_assert_unreachable.py | 4 +- .../codegen/integration/test_eth_tester.py | 222 ------------------ 11 files changed, 101 insertions(+), 363 deletions(-) delete mode 100644 tests/functional/codegen/integration/test_eth_tester.py diff --git a/tests/conftest.py b/tests/conftest.py index d0b06d2da9..ed951ad14e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,26 +1,12 @@ from contextlib import contextmanager +from random import Random import hypothesis import pytest - -# REVIEW: let's get rid of get_default_account_keys and have our own keys generator. -# for reference, eth-tester implementation is just -#@to_tuple -#def get_default_account_keys(quantity=None): -# keys = KeyAPI() -# quantity = quantity or 10 -# for i in range(1, quantity + 1): -# pk_bytes = int_to_big_endian(i).rjust(32, b"\x00") -# private_key = keys.PrivateKey(pk_bytes) -# yield private_key -# we could do something like `(random.nextbytes() for _ in range(10))` (with a -# pre-defined seed like b"vyper"). - -from eth_tester.backends.pyevm.main import get_default_account_keys +from eth_keys.datatypes import PrivateKey from hexbytes import HexBytes import vyper.evm.opcodes as evm_opcodes -from tests.evm_backends.abi_contract import ABIContract 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 @@ -199,13 +185,19 @@ def gas_limit(): @pytest.fixture(scope="module") -def env(gas_limit, evm_version, evm_backend, tracing) -> BaseEnv: +def account_keys(): + random = Random(b"vyper") + return [PrivateKey(random.randbytes(32)) for _ in range(10)] + + +@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=get_default_account_keys(), + account_keys=account_keys, ) @@ -213,7 +205,6 @@ def env(gas_limit, evm_version, evm_backend, tracing) -> BaseEnv: def get_contract_from_ir(env, optimize): def ir_compiler(ir, *args, **kwargs): ir = IRnode.from_list(ir) - # REVIEW: does kwargs.pop("optimize", optimize) match the previous behavior? if kwargs.pop("optimize", optimize) != OptimizationLevel.NONE: ir = optimizer.optimize(ir) @@ -261,29 +252,15 @@ def fn(source_code, *args, **kwargs): @pytest.fixture(scope="module") def get_logs(env): - def fn(c: ABIContract, event_name: str = None, raw=False): - # REVIEW: maybe it would be slicker to have something like - # `env.get_logs()`? - logs = [log for log in env.last_result["logs"] if c.address == log.address] - if raw: - return [log.data for log in logs] - - parsed_logs = [c.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 - - return fn + 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): - # REVIEW: should isolate the call to get_contract - with pytest.raises(exception): + with tx_failed(exception): function_to_test() return assert_compile_failed diff --git a/tests/evm_backends/abi_contract.py b/tests/evm_backends/abi_contract.py index abfad60f26..2692a9ab47 100644 --- a/tests/evm_backends/abi_contract.py +++ b/tests/evm_backends/abi_contract.py @@ -7,7 +7,6 @@ from eth_typing import ChecksumAddress, HexAddress from eth_utils import to_checksum_address -from pyrevm import Log # REVIEW: this leaks from pyrevm from vyper.semantics.analysis.base import FunctionVisibility, StateMutability from vyper.utils import keccak256, method_id @@ -15,7 +14,7 @@ from .abi import abi_decode, abi_encode, is_abi_encodable if TYPE_CHECKING: - from tests.evm_backends.base_env import BaseEnv + from tests.evm_backends.base_env import BaseEnv, LogEntry @dataclass @@ -70,14 +69,7 @@ def signature(self) -> str: def __repr__(self) -> str: return f"ABITopic {self._contract_name}.{self.signature} (0x{self.topic_id.hex()})" - # REVIEW: can be removed, repr is the default implementation for str - def __str__(self) -> str: - return repr(self) - - # REVIEW: Log leaks information from pyrevm, i'd prefer this to be generic. - # can we have a LogEntry which both pyevmenv and revmenv need to parse - # log entries into. - def parse(self, log: Log) -> ABILog: + def parse(self, log: "LogEntry") -> ABILog: topics, raw_data = log.data return ABILog( address=to_checksum_address(log.address), @@ -96,7 +88,7 @@ def data_type(self) -> type: fields = [(item["name"], item["type"]) for item in inputs] return make_dataclass(self.name, fields) - def _parse_args(self, log: Log) -> Any: + 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" @@ -140,7 +132,6 @@ def argument_types(self) -> list: def argument_count(self) -> int: return len(self.argument_types) - # REVIEW: why not `_signature`? @property def signature(self) -> str: return f"({_format_abi_type(self.argument_types)})" @@ -362,7 +353,7 @@ def __repr__(self): 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: Log) -> ABILog: + def parse_log(self, log: "LogEntry") -> ABILog: """ Parse a log entry into an ABILog object. :param log: the log entry to parse diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index 5caf91f2dd..25f2268794 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -1,6 +1,7 @@ import json +from collections import namedtuple from contextlib import contextmanager -from typing import Callable, Tuple +from typing import Callable from eth_keys.datatypes import PrivateKey from eth_utils import to_checksum_address @@ -11,6 +12,16 @@ from vyper.compiler import CompilerData, Settings, compile_code from vyper.utils import ERC5202_PREFIX, method_id +# a very simple log representation for the raw log entries +LogEntry = namedtuple("LogEntry", ["address", "topics", "data"]) + +# object returned by `last_result` property +ExecutionResult = namedtuple("ExecutionResult", ["is_success", "logs", "gas_refunded", "gas_used"]) + + +class EvmError(RuntimeError): + """Exception raised when a transaction reverts.""" + class BaseEnv: """ @@ -18,6 +29,7 @@ class BaseEnv: 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: @@ -25,6 +37,15 @@ def __init__(self, gas_limit: int, account_keys: list[PrivateKey]) -> None: self._keys = account_keys self.deployer: str = self._keys[0].public_key.to_checksum_address() + @contextmanager + def sender(self, address: str): + original_deployer = self.deployer + self.deployer = address + try: + yield + finally: + self.deployer = original_deployer + 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) @@ -87,12 +108,19 @@ def factory(address): return deployer, factory - @contextmanager - def anchor(self): - raise NotImplementedError # must be implemented by subclasses + 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 @contextmanager - def sender(self, address: str): + def anchor(self): raise NotImplementedError # must be implemented by subclasses def get_balance(self, address: str) -> int: @@ -114,7 +142,7 @@ def timestamp(self) -> int | None: raise NotImplementedError # must be implemented by subclasses @property - def last_result(self) -> dict | None: + def last_result(self) -> ExecutionResult: raise NotImplementedError # must be implemented by subclasses def execute_code( @@ -135,13 +163,16 @@ def get_code(self, address: str) -> bytes: def time_travel(self, num_blocks=1, time_delta: int | None = None) -> None: raise NotImplementedError # must be implemented by subclasses - def _deploy(self, code: bytes, value: int, gas: int = None) -> str: + def _deploy(self, code: bytes, value: int, gas: int | None = None) -> str: raise NotImplementedError # must be implemented by subclasses - # REVIEW: is there a reason this needs to be a method? def _compile( - self, source_code, output_formats, settings, input_bundle - ) -> Tuple[list[dict], bytes]: # REVIEW: tuple can be used in the signature + self, + source_code: str, + output_formats: dict[str, Callable[[CompilerData], str]], + settings: Settings, + input_bundle=None, + ) -> tuple[list[dict], bytes]: out = compile_code( source_code, # test that all output formats can get generated @@ -159,14 +190,10 @@ def _parse_revert(output_bytes: bytes, error: Exception, gas_used: int): """ Tries to parse the EIP-838 revert reason from the output bytes. """ - #REVIEW: not sure the prefix is needed + # REVIEW: not sure the prefix is needed prefix = "execution reverted" if output_bytes[:4] == method_id("Error(string)"): (msg,) = abi_decode("(string)", output_bytes[4:]) raise EvmError(f"{prefix}: {msg}", gas_used) from error raise EvmError(f"{prefix}: 0x{output_bytes.hex()}", gas_used) from error - - -class EvmError(RuntimeError): - """Exception raised when a transaction reverts.""" diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index 317de23fe0..2d5e323d8b 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -1,8 +1,8 @@ import logging -from collections import namedtuple from contextlib import contextmanager from typing import cast +import rlp from cached_property import cached_property from eth.abc import ChainAPI, ComputationAPI from eth.chains.mainnet import MainnetChain @@ -15,12 +15,12 @@ from eth.vm.message import Message from eth.vm.transaction_context import BaseTransactionContext from eth_keys.datatypes import PrivateKey -from eth_tester.utils.address import generate_contract_address from eth_typing import Address -from eth_utils import setup_DEBUG2_logging, to_checksum_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 +from tests.evm_backends.base_env import BaseEnv, EvmError, ExecutionResult, LogEntry +from vyper.utils import keccak256 class PyEvmEnv(BaseEnv): @@ -58,7 +58,7 @@ def __init__( genesis_params={"difficulty": GENESIS_DIFFICULTY, "gas_limit": gas_limit}, ) - self._last_computation: ComputationAPI | None = None + self._last_computation: ComputationAPI = None @cached_property def _state(self) -> StateAPI: @@ -76,17 +76,6 @@ def anchor(self): finally: self._state.revert(snapshot_id) - # REVIEW: this can be a method on super since it is the same in - # all environments - @contextmanager - def sender(self, address: str): - original_deployer = self.deployer - self.deployer = address - try: - yield - finally: - self.deployer = original_deployer - def get_balance(self, address: str) -> int: return self._state.get_balance(_addr(address)) @@ -106,14 +95,14 @@ def timestamp(self) -> int | None: return self._state.timestamp @property - def last_result(self) -> dict | None: + def last_result(self) -> ExecutionResult: result = self._last_computation - return result and { - "is_success": not result.is_error, - "logs": list(_parse_log_entries(result)), - "gas_refunded": result.get_gas_refund(), - "gas_used": result.get_gas_used(), - } + 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 execute_code( self, @@ -141,12 +130,11 @@ def execute_code( ), transaction_context=BaseTransactionContext(origin=sender, gas_price=gas_price), ) - # REVIEW: why is VMError caught here, but check_computation is also - # required below? 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 finally: - # REVIEW: not sure why transient storage needs to be cleared here + # clear transient storage after every call, since we are not committing anything self._clear_transient_storage() self._check_computation(computation) @@ -175,7 +163,8 @@ def time_travel(self, num_blocks=1, time_delta: int | None = None) -> None: """ Move the block number forward by `num_blocks` and the timestamp forward by `time_delta`. """ - # REVIEW: is cast necessary? + + # Cast since ExecutionContextAPI does not have the properties we need to change context = cast(ExecutionContext, self._state.execution_context) context._block_number += num_blocks context._timestamp += num_blocks if time_delta is None else time_delta @@ -196,14 +185,13 @@ def _deploy(self, code: bytes, value: int, gas: int = None) -> str: gas=gas or self.gas_limit, create_address=target_address, ), - transaction_context=BaseTransactionContext(origin=sender), + transaction_context=BaseTransactionContext(origin=sender, gas_price=0), ) - # REVIEW: why is VMError caught here, but check_computation is also - # required below? 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 finally: - # REVIEW: not sure why transient storage needs to be cleared here + # clear transient storage after every call, since we are not committing anything self._clear_transient_storage() self._check_computation(computation) return "0x" + target_address.hex() @@ -211,12 +199,8 @@ def _deploy(self, code: bytes, value: int, gas: int = None) -> str: def _generate_contract_address(self, sender: Address) -> Address: nonce = self._state.get_nonce(sender) self._state.increment_nonce(sender) - return generate_contract_address(sender, nonce) - - -# a very simple log representation for the raw log entries -# REVIEW: maybe "LogEntry" is a better name -Log = namedtuple("Log", ["address", "topics", "data"]) + next_account_hash = keccak256(rlp.encode([sender, nonce])) + return to_canonical_address(next_account_hash[-20:]) def _parse_log_entries(result: ComputationAPI): @@ -227,7 +211,7 @@ def _parse_log_entries(result: ComputationAPI): 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 Log(to_checksum_address(address), topic_ids, (topic_bytes, data)) + yield LogEntry(to_checksum_address(address), topic_ids, (topic_bytes, data)) def _addr(address: str) -> Address: diff --git a/tests/evm_backends/revm_env.py b/tests/evm_backends/revm_env.py index 7cdb360a7b..94a4b2a4d8 100644 --- a/tests/evm_backends/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -4,7 +4,7 @@ from eth_keys.datatypes import PrivateKey from pyrevm import EVM, BlockEnv, Env -from tests.evm_backends.base_env import BaseEnv, EvmError +from tests.evm_backends.base_env import BaseEnv, EvmError, ExecutionResult class RevmEnv(BaseEnv): @@ -34,21 +34,11 @@ def anchor(self): finally: try: self._evm.revert(snapshot_id) - # REVIEW: why does this happen? except OverflowError: # snapshot_id is reverted by the transaction already. # revm updates are needed to make the journal more robust. pass - @contextmanager - def sender(self, address: str): - original_deployer = self.deployer - self.deployer = address - try: - yield - finally: - self.deployer = original_deployer - def get_balance(self, address: str) -> int: return self._evm.get_balance(address) @@ -68,14 +58,14 @@ def timestamp(self) -> int | None: return self._evm.env.block.timestamp @property - def last_result(self) -> dict | None: + def last_result(self) -> ExecutionResult: result = self._evm.result - return result and { - "gas_refunded": result.gas_refunded, - "gas_used": result.gas_used, - "is_success": result.is_success, - "logs": result.logs, - } + return ExecutionResult( + gas_refunded=result.gas_refunded, + gas_used=result.gas_used, + is_success=result.is_success, + logs=result.logs, + ) def execute_code( self, @@ -106,6 +96,7 @@ def execute_code( self._parse_revert(output_bytes, e, int(gas_used)) raise EvmError(*e.args) from e finally: + # clear transient storage after every call, since we are not committing anything self._evm.reset_transient_storage() def get_code(self, address: str): @@ -135,4 +126,5 @@ def _deploy(self, code: bytes, value: int, gas: int = None) -> str: try: return self._evm.deploy(self.deployer, code, value, gas) finally: + # clear transient storage after every call, since we are not committing anything self._evm.reset_transient_storage() diff --git a/tests/functional/builtins/codegen/test_abi_decode.py b/tests/functional/builtins/codegen/test_abi_decode.py index d1c03ad9e6..57e199a6ce 100644 --- a/tests/functional/builtins/codegen/test_abi_decode.py +++ b/tests/functional/builtins/codegen/test_abi_decode.py @@ -60,11 +60,10 @@ def abi_decode_struct(x: Bytes[544]) -> Human: assert tuple(c.abi_decode(encoded)) == (TEST_ADDR, -1, True, Decimal("-123.4"), test_bytes32) test_bytes32 = b"".join(chr(i).encode("utf-8") for i in range(32)) - # REVIEW: why is this now a list instead of tuple? - human_tuple = [ + human_tuple = ( "foobar", ("vyper", TEST_ADDR, 123, True, Decimal("123.4"), [123, 456, 789], test_bytes32), - ] + ) human_t = "((string,(string,address,int128,bool,fixed168x10,uint256[3],bytes32)))" human_encoded = abi.encode(human_t, (human_tuple,)) diff --git a/tests/functional/builtins/codegen/test_create_functions.py b/tests/functional/builtins/codegen/test_create_functions.py index 1fa6214b5d..405a46d4cc 100644 --- a/tests/functional/builtins/codegen/test_create_functions.py +++ b/tests/functional/builtins/codegen/test_create_functions.py @@ -98,18 +98,14 @@ def test2(a: uint256) -> Bytes[100]: c.test() assert c.test2(1) == b"hello world!" - with tx_failed(): + with tx_failed(exc_text="invaliddddd"): c.test2(0) - GAS_SENT = 30000 - with tx_failed(): - c.test2(0, gas=GAS_SENT) + gas_sent = 30000 + with tx_failed(exc_text="invaliddddd"): + c.test2(0, gas=gas_sent) - # REVIEW: implied by tx_failed - assert env.last_result["is_success"] is False - # REVIEW: add a comment maybe like "check the staticcall performed - # no sstore" (or reason string) - assert env.last_result["gas_used"] < GAS_SENT + assert env.last_result.gas_used < gas_sent def test_create_minimal_proxy_to_create2(get_contract, create2_address_of, keccak, tx_failed): @@ -417,8 +413,7 @@ 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(): - # REVIEW: why is HexBytes needed here? - env.execute_code(d.address, env.deployer, HexBytes(f"{sig}{encoded}")) + env.execute_code(d.address, env.deployer, f"{sig}{encoded}") def test_create_copy_of(get_contract, env, keccak, create2_address_of, tx_failed): 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 e0ece0f58a..d565f6fc71 100644 --- a/tests/functional/codegen/calling_convention/test_external_contract_calls.py +++ b/tests/functional/codegen/calling_convention/test_external_contract_calls.py @@ -1394,7 +1394,6 @@ def get_lucky(amount_to_send: uint256) -> int128: # Send some eth env.set_balance(env.deployer, 10000) - # REVIEW: why is anchor needed here? with env.anchor(): # anchor to check if the transaction is cancelled assert c2.get_lucky(0, value=500) == 1 diff --git a/tests/functional/codegen/features/test_assert.py b/tests/functional/codegen/features/test_assert.py index bb5ff31a41..8c11cf4c76 100644 --- a/tests/functional/codegen/features/test_assert.py +++ b/tests/functional/codegen/features/test_assert.py @@ -19,9 +19,7 @@ def foo(): with tx_failed(): c.foo(gas=gas_sent, gas_price=10) - assert env.last_result["gas_used"] < gas_sent, "Gas refund not received" - # REVIEW: implied by tx_failed - assert env.last_result["is_success"] is False + assert env.last_result.gas_used < gas_sent, "Gas refund not received" def test_assert_reason(env, get_contract, tx_failed, memory_mocker): diff --git a/tests/functional/codegen/features/test_assert_unreachable.py b/tests/functional/codegen/features/test_assert_unreachable.py index f5a8ec5fd8..855fbc21f9 100644 --- a/tests/functional/codegen/features/test_assert_unreachable.py +++ b/tests/functional/codegen/features/test_assert_unreachable.py @@ -11,9 +11,7 @@ def foo(): with tx_failed(): c.foo(gas=gas_sent, gas_price=10) - assert env.last_result["gas_used"] == gas_sent # Drains all gains sent - # REVIEW: i think this is implied by tx_failed()? - assert env.last_result["is_success"] is False + assert env.last_result.gas_used == gas_sent # Drains all gains sent def test_basic_unreachable(env, get_contract, tx_failed): diff --git a/tests/functional/codegen/integration/test_eth_tester.py b/tests/functional/codegen/integration/test_eth_tester.py deleted file mode 100644 index 58a54f2124..0000000000 --- a/tests/functional/codegen/integration/test_eth_tester.py +++ /dev/null @@ -1,222 +0,0 @@ -import json -from functools import wraps - -import pytest -import web3.exceptions -from eth_tester import EthereumTester, PyEVMBackend -from eth_utils.toolz import compose -from web3 import Web3 -from web3.contract import Contract -from web3.providers.eth_tester import EthereumTesterProvider - -from vyper import compiler -from vyper.ast.grammar import parse_vyper_source -from vyper.compiler.settings import Settings - - -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,) - - -def zero_gas_price_strategy(web3, transaction_params=None): - return 0 # zero gas price makes testing simpler. - - -@pytest.fixture(scope="module") -def tester(gas_limit): - custom_genesis = PyEVMBackend._generate_genesis_params(overrides={"gas_limit": gas_limit}) - custom_genesis["base_fee_per_gas"] = 0 - backend = PyEVMBackend(genesis_parameters=custom_genesis) - return EthereumTester(backend=backend) - - -@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) - - 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)) - - -def _get_contract( - w3, - source_code, - optimize, - experimental_codegen, - output_formats, - *args, - override_opt_level=None, - input_bundle=None, - **kwargs, -): - settings = 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 - ) - 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) - - -@pytest.fixture(scope="module") -def get_contract(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 - -# REVIEW: there is a lot in this module for just the single test. should we just -# delete it and re-add integration tests as a follow up? also, if we are going -# to keep it then maybe move it to -# tests/functional/integration/test_eth_tester.py -def test_slice_storage_bytes32(get_contract): - code = """ -bytez: bytes32 -@external -def dice() -> Bytes[1]: - self.bytez = convert(65, bytes32) - c: Bytes[1] = slice(self.bytez, 31, 1) - return c - """ - - c = get_contract(code) - assert c.dice() == b"A" From 3ab187f00599db78d79b5a738974f5f43f6e079c Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 9 Apr 2024 13:42:29 +0200 Subject: [PATCH 56/87] Review comments --- tests/evm_backends/abi_contract.py | 18 +++++--- tests/evm_backends/base_env.py | 46 +++++++++---------- .../builtins/codegen/test_create_functions.py | 5 +- 3 files changed, 37 insertions(+), 32 deletions(-) diff --git a/tests/evm_backends/abi_contract.py b/tests/evm_backends/abi_contract.py index 2692a9ab47..790f176a06 100644 --- a/tests/evm_backends/abi_contract.py +++ b/tests/evm_backends/abi_contract.py @@ -133,7 +133,7 @@ def argument_count(self) -> int: return len(self.argument_types) @property - def signature(self) -> str: + def _args_signature(self) -> str: return f"({_format_abi_type(self.argument_types)})" @cached_property @@ -142,15 +142,17 @@ def return_type(self) -> list: @property def full_signature(self) -> str: - return f"{self.name}{self.signature}" + return f"{self.name}{self._args_signature}" @property def pretty_signature(self) -> str: - return f"{self.name}{self.signature} -> {self.return_type}" + return f"{self.name}{self._args_signature} -> {self.return_type}" @cached_property def method_id(self) -> bytes: - return method_id(self.name + self.signature) + 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}" @@ -175,7 +177,7 @@ def is_encodable(self, *args, **kwargs) -> bool: 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.signature, abi_args) + 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.""" @@ -189,7 +191,9 @@ def _merge_kwargs(self, *args, **kwargs) -> list: 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.signature}`. Passed {args} {kwargs}" + 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): @@ -279,7 +283,7 @@ def _pick_overload(self, *args, disambiguate_signature=None, **kwargs) -> ABIFun raise Exception( f"Ambiguous call to {self.name}. " f"Arguments can be encoded to multiple overloads: " - f"{', '.join(self.name + f.signature for f in multiple)}. " + f"{', '.join(self.name + f._args_signature for f in multiple)}. " f"(Hint: try using `disambiguate_signature=` to disambiguate)." ) diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index 25f2268794..c159c94fe2 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -6,7 +6,7 @@ from eth_keys.datatypes import PrivateKey from eth_utils import to_checksum_address -from tests.evm_backends.abi import abi_decode, abi_encode +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, Settings, compile_code @@ -54,7 +54,7 @@ def deploy(self, abi: list[dict], bytecode: bytes, value=0, *args, **kwargs): 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 += abi_encode(ctor.signature, ctor._merge_kwargs(*args, **kwargs)) + initcode += ctor.prepare_calldata(*args, **kwargs) try: deployed_at = self._deploy(initcode, value) @@ -74,7 +74,7 @@ def deploy_source( **kwargs, ) -> ABIContract: """Compile and deploy a contract from source code.""" - abi, bytecode = self._compile(source_code, output_formats, compiler_settings, input_bundle) + abi, bytecode = _compile(source_code, output_formats, compiler_settings, input_bundle) value = ( kwargs.pop("value", 0) or kwargs.pop("value_in_eth", 0) * 10**18 ) # Handle deploying with an eth value. @@ -91,7 +91,7 @@ def deploy_blueprint( initcode_prefix=ERC5202_PREFIX, ): """Deploy a contract with a blueprint pattern.""" - abi, bytecode = self._compile(source_code, output_formats, compiler_settings, input_bundle) + abi, bytecode = _compile(source_code, output_formats, compiler_settings, input_bundle) bytecode = initcode_prefix + bytecode bytecode_len = len(bytecode) bytecode_len_hex = hex(bytecode_len)[2:].rjust(4, "0") @@ -166,25 +166,6 @@ def time_travel(self, num_blocks=1, time_delta: int | None = None) -> None: def _deploy(self, code: bytes, value: int, gas: int | None = None) -> str: raise NotImplementedError # must be implemented by subclasses - def _compile( - self, - source_code: str, - output_formats: dict[str, Callable[[CompilerData], str]], - settings: Settings, - input_bundle=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")) - @staticmethod def _parse_revert(output_bytes: bytes, error: Exception, gas_used: int): """ @@ -197,3 +178,22 @@ def _parse_revert(output_bytes: bytes, error: Exception, gas_used: int): raise EvmError(f"{prefix}: {msg}", gas_used) from error raise EvmError(f"{prefix}: 0x{output_bytes.hex()}", gas_used) from error + + +def _compile( + source_code: str, + output_formats: dict[str, Callable[[CompilerData], str]], + settings: Settings, + input_bundle=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/functional/builtins/codegen/test_create_functions.py b/tests/functional/builtins/codegen/test_create_functions.py index 219d8082ce..22802a6906 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 @@ -130,7 +131,7 @@ def test(_salt: bytes32) -> address: # 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) @@ -490,7 +491,7 @@ def test2(target: address, salt: bytes32) -> address: # 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) From e01d1d47733492413c4fb5af667c1e157db8f671 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 9 Apr 2024 14:01:48 +0200 Subject: [PATCH 57/87] Manual clear_transient_storage --- tests/evm_backends/base_env.py | 3 ++ tests/evm_backends/pyevm_env.py | 9 +--- tests/evm_backends/revm_env.py | 12 ++--- .../codegen/features/test_transient.py | 47 +++++++++++++------ 4 files changed, 41 insertions(+), 30 deletions(-) diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index c159c94fe2..186341cc7e 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -157,6 +157,9 @@ def execute_code( ) -> 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 diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index 2d5e323d8b..294fe2f5cd 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -133,14 +133,11 @@ def execute_code( 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 - finally: - # clear transient storage after every call, since we are not committing anything - self._clear_transient_storage() self._check_computation(computation) return computation.output - def _clear_transient_storage(self): + def clear_transient_storage(self) -> None: try: self._state.clear_transient_storage() except AttributeError as e: @@ -190,9 +187,7 @@ def _deploy(self, code: bytes, value: int, gas: int = None) -> str: 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 - finally: - # clear transient storage after every call, since we are not committing anything - self._clear_transient_storage() + self._check_computation(computation) return "0x" + target_address.hex() diff --git a/tests/evm_backends/revm_env.py b/tests/evm_backends/revm_env.py index 94a4b2a4d8..44e0aab94a 100644 --- a/tests/evm_backends/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -95,9 +95,9 @@ def execute_code( output_bytes = bytes.fromhex(output_str) self._parse_revert(output_bytes, e, int(gas_used)) raise EvmError(*e.args) from e - finally: - # clear transient storage after every call, since we are not committing anything - self._evm.reset_transient_storage() + + 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") @@ -123,8 +123,4 @@ def time_travel(self, num_blocks=1, time_delta: int | None = None) -> None: ) def _deploy(self, code: bytes, value: int, gas: int = None) -> str: - try: - return self._evm.deploy(self.deployer, code, value, gas) - finally: - # clear transient storage after every call, since we are not committing anything - self._evm.reset_transient_storage() + return self._evm.deploy(self.deployer, code, value, gas) diff --git a/tests/functional/codegen/features/test_transient.py b/tests/functional/codegen/features/test_transient.py index d12db9e262..01f6ccfc3e 100644 --- a/tests/functional/codegen/features/test_transient.py +++ b/tests/functional/codegen/features/test_transient.py @@ -60,7 +60,7 @@ def setter(k: address, v: uint256): ("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})) @@ -73,13 +73,15 @@ 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) @@ -99,10 +101,11 @@ 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)) @@ -126,13 +129,14 @@ 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) == values + env.clear_transient_storage() assert c.a() == 0 assert c.b() == ZERO_ADDRESS assert c.c() == "" assert c.foo(*values) == values -def test_struct_transient(get_contract): +def test_struct_transient(get_contract, env): code = """ struct MyStruct: a: uint256 @@ -156,11 +160,12 @@ def foo(_a: uint256, _b: uint256, _c: address, _d: int256) -> MyStruct: c = get_contract(code) assert c.foo(*values) == values + 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 @@ -185,11 +190,12 @@ def foo(_a: address, _b: MyStruct2, _c: DynArray[DynArray[uint256, 3], 3]) -> My c = get_contract(code) assert c.foo(*values) == values + 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 @@ -208,11 +214,12 @@ 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])) @@ -225,12 +232,13 @@ 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])) @@ -243,10 +251,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 @@ -271,13 +280,13 @@ def 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])) @@ -295,9 +304,11 @@ 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) @@ -324,7 +335,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]], @@ -370,18 +381,21 @@ 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: @@ -401,11 +415,12 @@ 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)) @@ -427,10 +442,11 @@ 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) @@ -461,6 +477,7 @@ 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 From 81fe3549658368447890c23150e9b431b7cf2ae4 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 15 Apr 2024 14:23:09 +0200 Subject: [PATCH 58/87] New pyrevm repository --- setup.py | 2 +- tests/conftest.py | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index afca18877e..1cd7b8844b 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ "eth-stdlib==0.2.7", "setuptools", "hexbytes>=1.2", - "pyrevm @ git+https://github.com/DanielSchiavini/pyrevm.git@revm", + "pyrevm @ git+https://github.com/paradigmxyz/pyrevm.git@v0.3.0b1", ], "lint": [ "black==23.12.0", diff --git a/tests/conftest.py b/tests/conftest.py index dcb483b995..672f1cf098 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,7 +6,6 @@ from eth_keys.datatypes import PrivateKey from hexbytes import HexBytes -import vyper.compiler.settings as vyper_compiler_settings import vyper.evm.opcodes as evm_opcodes from tests.evm_backends.base_env import BaseEnv, EvmError from tests.evm_backends.pyevm_env import PyEvmEnv @@ -16,7 +15,6 @@ from vyper.codegen.ir_node import IRnode from vyper.compiler.input_bundle import FilesystemInputBundle, InputBundle from vyper.compiler.settings import OptimizationLevel, Settings, set_global_settings -from vyper.evm.opcodes import EVM_VERSIONS from vyper.exceptions import EvmVersionException from vyper.ir import compile_ir, optimizer from vyper.utils import keccak256 @@ -47,7 +45,7 @@ def pytest_addoption(parser): parser.addoption( "--evm-version", - choices=list(EVM_VERSIONS.keys()), + choices=list(evm_opcodes.EVM_VERSIONS.keys()), default="shanghai", help="set evm version", ) @@ -221,7 +219,7 @@ def ir_compiler(ir, *args, **kwargs): @pytest.fixture(scope="module", autouse=True) def compiler_settings(optimize, experimental_codegen, evm_version, debug): - vyper_compiler_settings.DEFAULT_ENABLE_DECIMALS = True + compiler.settings.DEFAULT_ENABLE_DECIMALS = True settings = Settings( optimize=optimize, evm_version=evm_version, From 78ca4676463bce2b17318978add433f0633fac41 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 15 Apr 2024 15:12:34 +0200 Subject: [PATCH 59/87] Update new test --- tests/functional/codegen/modules/test_exports.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/functional/codegen/modules/test_exports.py b/tests/functional/codegen/modules/test_exports.py index b02ed6ba9e..878fafa998 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.execute_code(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.execute_code(c.address) assert c.counter() == 6 From b0c3fa50bbda95aa16102f22d5ec76e8c9d0d3cb Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 15 Apr 2024 16:32:02 +0200 Subject: [PATCH 60/87] Test isolation --- tests/conftest.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/conftest.py b/tests/conftest.py index 672f1cf098..20df513845 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,6 @@ from contextlib import contextmanager from random import Random +from typing import Generator import hypothesis import pytest @@ -334,7 +335,8 @@ def fn(exception=EvmError, 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 @@ -343,3 +345,11 @@ def pytest_runtest_call(item): 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 From 4bd4bce5647d07a9e7a3dd9c8e713ffcc39b3cac Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Tue, 16 Apr 2024 13:33:43 +0200 Subject: [PATCH 61/87] Update balance --- .../calling_convention/test_default_function.py | 2 +- .../functional/codegen/integration/test_crowdfund.py | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/functional/codegen/calling_convention/test_default_function.py b/tests/functional/codegen/calling_convention/test_default_function.py index 54d17acf06..6ba0a2fe7a 100644 --- a/tests/functional/codegen/calling_convention/test_default_function.py +++ b/tests/functional/codegen/calling_convention/test_default_function.py @@ -53,7 +53,7 @@ def __default__(): log Sent(msg.sender) """ c = get_contract(code) - + env.set_balance(env.deployer, 10**18) env.execute_code(c.address, value=10**17) (log,) = get_logs(c, "Sent") assert env.deployer == log.args.sender diff --git a/tests/functional/codegen/integration/test_crowdfund.py b/tests/functional/codegen/integration/test_crowdfund.py index d51de0fd6d..f8b3f81df0 100644 --- a/tests/functional/codegen/integration/test_crowdfund.py +++ b/tests/functional/codegen/integration/test_crowdfund.py @@ -1,3 +1,12 @@ +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(env, get_contract): crowdfund = """ @@ -63,8 +72,6 @@ def refund(): """ a0, a1, a2, a3, a4, a5, a6 = env.accounts[:7] - for a in env.accounts[:7]: - env.set_balance(a, 10**10) c = get_contract(crowdfund, *[a1, 50, 60]) start_timestamp = env.timestamp From 4c05b289b14c88bf2076037625cbed2ff4f731c4 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 17 Apr 2024 16:20:48 +0200 Subject: [PATCH 62/87] Review comments --- tests/evm_backends/abi_contract.py | 5 +---- tests/evm_backends/base_env.py | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/tests/evm_backends/abi_contract.py b/tests/evm_backends/abi_contract.py index 790f176a06..bcbc96fbea 100644 --- a/tests/evm_backends/abi_contract.py +++ b/tests/evm_backends/abi_contract.py @@ -384,20 +384,18 @@ def __init__( functions: list[ABIFunction], log_topics: list[ABILogTopic], bytecode: Optional[bytes] = None, - filename: Optional[str] = None, ): self._name = name self._abi = abi self._functions = functions self._log_topics = log_topics self._bytecode = bytecode - self._filename = filename @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, filename=name) + return cls(basename(name), abi, functions, log_topics, bytecode) def at(self, env, address: HexAddress) -> ABIContract: """ @@ -411,7 +409,6 @@ def at(self, env, address: HexAddress) -> ABIContract: self._log_topics, self._bytecode, address, - self._filename, ) diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index 186341cc7e..2fa9a80f2e 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -1,6 +1,6 @@ import json -from collections import namedtuple from contextlib import contextmanager +from dataclasses import dataclass from typing import Callable from eth_keys.datatypes import PrivateKey @@ -12,11 +12,22 @@ from vyper.compiler import CompilerData, Settings, compile_code from vyper.utils import ERC5202_PREFIX, method_id + # a very simple log representation for the raw log entries -LogEntry = namedtuple("LogEntry", ["address", "topics", "data"]) +@dataclass +class LogEntry: + address: str + topics: list[str] + data: tuple[list[bytes], bytes] # (topic list, non-topic) + # object returned by `last_result` property -ExecutionResult = namedtuple("ExecutionResult", ["is_success", "logs", "gas_refunded", "gas_used"]) +@dataclass +class ExecutionResult: + is_success: bool + logs: list[LogEntry] + gas_refunded: int + gas_used: int class EvmError(RuntimeError): From 0acf8f5af63354481d35ce329ad83412d06fc939 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 17 Apr 2024 17:10:44 +0200 Subject: [PATCH 63/87] Unused parameter --- tests/evm_backends/base_env.py | 2 +- tests/evm_backends/pyevm_env.py | 6 ++---- tests/evm_backends/revm_env.py | 6 ++---- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index 2fa9a80f2e..9e7d031b2c 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -174,7 +174,7 @@ def clear_transient_storage(self) -> None: def get_code(self, address: str) -> bytes: raise NotImplementedError # must be implemented by subclasses - def time_travel(self, num_blocks=1, time_delta: int | None = None) -> None: + def time_travel(self, num_blocks=1) -> None: raise NotImplementedError # must be implemented by subclasses def _deploy(self, code: bytes, value: int, gas: int | None = None) -> str: diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index 294fe2f5cd..94be494758 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -42,8 +42,6 @@ def __init__( # but eth-tester is only configured with the latest mainnet # version. evm_opcodes.DEFAULT_EVM_VERSION = evm_version - # this should get overridden by anchor_evm_version, but set it anyway - evm_opcodes.active_evm_version = evm_opcodes.EVM_VERSIONS[evm_version] if tracing: logger = logging.getLogger("eth.vm.computation.BaseComputation") @@ -156,7 +154,7 @@ def _check_computation(self, computation): def get_code(self, address: str): return self._state.get_code(_addr(address)) - def time_travel(self, num_blocks=1, time_delta: int | None = None) -> None: + def time_travel(self, num_blocks=1) -> None: """ Move the block number forward by `num_blocks` and the timestamp forward by `time_delta`. """ @@ -164,7 +162,7 @@ def time_travel(self, num_blocks=1, time_delta: int | None = None) -> None: # Cast since ExecutionContextAPI does not have the properties we need to change context = cast(ExecutionContext, self._state.execution_context) context._block_number += num_blocks - context._timestamp += num_blocks if time_delta is None else time_delta + context._timestamp += num_blocks def _deploy(self, code: bytes, value: int, gas: int = None) -> str: sender = _addr(self.deployer) diff --git a/tests/evm_backends/revm_env.py b/tests/evm_backends/revm_env.py index 44e0aab94a..c1cbd015ba 100644 --- a/tests/evm_backends/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -102,18 +102,16 @@ def clear_transient_storage(self) -> None: def get_code(self, address: str): return self._evm.basic(address).code.rstrip(b"\0") - def time_travel(self, num_blocks=1, time_delta: int | None = None) -> None: + def time_travel(self, num_blocks=1) -> None: """ Move the block number forward by `num_blocks` and the timestamp forward by `time_delta`. """ - if time_delta is None: - time_delta = num_blocks block = self._evm.env.block self._evm.set_block_env( BlockEnv( number=block.number + num_blocks, coinbase=block.coinbase, - timestamp=block.timestamp + time_delta, + timestamp=block.timestamp + num_blocks, difficulty=block.difficulty, prevrandao=block.prevrandao, basefee=block.basefee, From 05bf9c61711aa4eeba370f60314f43ef33d06c00 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 19 Apr 2024 15:54:42 +0200 Subject: [PATCH 64/87] Update pyrevm --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 1cd7b8844b..70f80d75bd 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ "eth-stdlib==0.2.7", "setuptools", "hexbytes>=1.2", - "pyrevm @ git+https://github.com/paradigmxyz/pyrevm.git@v0.3.0b1", + "pyrevm>=0.3.1", ], "lint": [ "black==23.12.0", From 2b426377db2c17f7db6842687f046f9710a2543c Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 22 Apr 2024 09:50:45 +0200 Subject: [PATCH 65/87] Review comments --- tests/evm_backends/abi_contract.py | 8 +------- tests/evm_backends/base_env.py | 2 +- tests/evm_backends/pyevm_env.py | 7 +++---- tests/evm_backends/revm_env.py | 5 ++--- .../builtins/codegen/test_create_functions.py | 1 + tests/functional/builtins/codegen/test_send.py | 2 ++ .../calling_convention/test_default_function.py | 14 +++++++------- .../calling_convention/test_default_parameters.py | 9 ++++----- .../environment_variables/test_block_number.py | 3 +-- .../environment_variables/test_blockhash.py | 2 +- .../codegen/features/decorators/conftest.py | 7 ------- .../features/decorators/test_nonreentrant.py | 1 + .../codegen/features/decorators/test_payable.py | 6 +++--- .../codegen/features/decorators/test_private.py | 2 +- tests/functional/codegen/features/test_assert.py | 9 ++------- .../codegen/integration/test_crowdfund.py | 10 +++++----- .../functional/codegen/integration/test_escrow.py | 11 ++--------- .../examples/auctions/test_blind_auction.py | 12 ++++++------ .../examples/auctions/test_simple_open_auction.py | 6 +++--- tests/functional/examples/conftest.py | 6 ------ .../examples/crowdfund/test_crowdfund_example.py | 7 ++++--- .../market_maker/test_on_chain_market_maker.py | 7 +++++-- .../test_safe_remote_purchase.py | 8 +++++--- tests/functional/examples/wallet/test_wallet.py | 2 ++ 24 files changed, 62 insertions(+), 85 deletions(-) delete mode 100644 tests/functional/codegen/features/decorators/conftest.py diff --git a/tests/evm_backends/abi_contract.py b/tests/evm_backends/abi_contract.py index bcbc96fbea..c242e94e41 100644 --- a/tests/evm_backends/abi_contract.py +++ b/tests/evm_backends/abi_contract.py @@ -402,13 +402,7 @@ 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, + env, self._name, self._abi, self._functions, self._log_topics, self._bytecode, address ) diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index 9e7d031b2c..b69c572da4 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -174,7 +174,7 @@ def clear_transient_storage(self) -> None: def get_code(self, address: str) -> bytes: raise NotImplementedError # must be implemented by subclasses - def time_travel(self, num_blocks=1) -> None: + def fast_forward_blocks(self, num_blocks=1) -> None: raise NotImplementedError # must be implemented by subclasses def _deploy(self, code: bytes, value: int, gas: int | None = None) -> str: diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index 94be494758..4fb187458f 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -1,6 +1,5 @@ import logging from contextlib import contextmanager -from typing import cast import rlp from cached_property import cached_property @@ -154,15 +153,15 @@ def _check_computation(self, computation): def get_code(self, address: str): return self._state.get_code(_addr(address)) - def time_travel(self, num_blocks=1) -> None: + def fast_forward_blocks(self, num_blocks=1) -> None: """ Move the block number forward by `num_blocks` and the timestamp forward by `time_delta`. """ # Cast since ExecutionContextAPI does not have the properties we need to change - context = cast(ExecutionContext, self._state.execution_context) + context = self._state.execution_context + assert isinstance(context, ExecutionContext) context._block_number += num_blocks - context._timestamp += num_blocks def _deploy(self, code: bytes, value: int, gas: int = None) -> str: sender = _addr(self.deployer) diff --git a/tests/evm_backends/revm_env.py b/tests/evm_backends/revm_env.py index c1cbd015ba..5e8a49408d 100644 --- a/tests/evm_backends/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -79,7 +79,7 @@ def execute_code( ): data = data if isinstance(data, bytes) else bytes.fromhex(data.removeprefix("0x")) try: - output = self._evm.message_call( + return self._evm.message_call( to=to, caller=sender or self.deployer, calldata=data, @@ -88,7 +88,6 @@ def execute_code( gas_price=gas_price, is_static=not is_modifying, ) - return bytes(output) except RuntimeError as e: if match := re.match(r"Revert \{ gas_used: (\d+), output: 0x([0-9a-f]+) }", e.args[0]): gas_used, output_str = match.groups() @@ -102,7 +101,7 @@ def clear_transient_storage(self) -> None: def get_code(self, address: str): return self._evm.basic(address).code.rstrip(b"\0") - def time_travel(self, num_blocks=1) -> None: + def fast_forward_blocks(self, num_blocks=1) -> None: """ Move the block number forward by `num_blocks` and the timestamp forward by `time_delta`. """ diff --git a/tests/functional/builtins/codegen/test_create_functions.py b/tests/functional/builtins/codegen/test_create_functions.py index 22802a6906..fde0cdfa4e 100644 --- a/tests/functional/builtins/codegen/test_create_functions.py +++ b/tests/functional/builtins/codegen/test_create_functions.py @@ -106,6 +106,7 @@ def test2(a: uint256) -> Bytes[100]: with tx_failed(exc_text="invaliddddd"): c.test2(0, gas=gas_sent) + # check we issued `revert`, which does not consume all gas assert env.last_result.gas_used < gas_sent diff --git a/tests/functional/builtins/codegen/test_send.py b/tests/functional/builtins/codegen/test_send.py index a563bf4e7d..66c0dfb6ff 100644 --- a/tests/functional/builtins/codegen/test_send.py +++ b/tests/functional/builtins/codegen/test_send.py @@ -15,7 +15,9 @@ def fop(): c = get_contract(send_test, value=10) with tx_failed(): c.foo() + assert env.get_balance(c.address) == 10 c.fop() + assert env.get_balance(c.address) == 0 with tx_failed(): c.fop() diff --git a/tests/functional/codegen/calling_convention/test_default_function.py b/tests/functional/codegen/calling_convention/test_default_function.py index 6ba0a2fe7a..af2fdc8041 100644 --- a/tests/functional/codegen/calling_convention/test_default_function.py +++ b/tests/functional/codegen/calling_convention/test_default_function.py @@ -14,7 +14,7 @@ def __init__(): assert c.x() == 123 assert env.get_balance(c.address) == 0 with tx_failed(): - env.execute_code(c.address, value=to_wei(0.1, "ether")) + env.execute_code(c.address, value=to_wei(0.1, "ether")) # call default function assert env.get_balance(c.address) == 0 @@ -30,7 +30,7 @@ def __default__(): """ c = get_contract(code) env.set_balance(env.deployer, 10**18) - env.execute_code(c.address, value=10**17) + env.execute_code(c.address, value=10**17) # 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") @@ -54,7 +54,7 @@ def __default__(): """ c = get_contract(code) env.set_balance(env.deployer, 10**18) - env.execute_code(c.address, value=10**17) + env.execute_code(c.address, value=10**17) # 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") @@ -72,7 +72,7 @@ def __default__(): c = get_contract(code) with tx_failed(): - env.execute_code(c.address, value=10**17) + env.execute_code(c.address, value=10**17) # call default function def test_multi_arg_default(assert_compile_failed, get_contract): @@ -130,7 +130,7 @@ def __default__(): def _call_with_bytes(hexstr): # call our special contract and return the logged value data = bytes.fromhex(hexstr.removeprefix("0x")) - env.execute_code(c.address, value=0, data=data) + env.execute_code(c.address, value=0, data=data) # call default function (log,) = get_logs(c, "Sent") return log.args.sig @@ -176,7 +176,7 @@ def __default__(): def _call_with_bytes(hexstr): # call our special contract and return the logged value data = bytes.fromhex(hexstr.removeprefix("0x")) - env.execute_code(c.address, value=0, data=data, gas=10**6) + env.execute_code(c.address, value=0, data=data, gas=10**6) # call default function (log,) = get_logs(c, "Sent") return log.args.sig @@ -217,7 +217,7 @@ def __default__(): def _call_with_bytes(hexstr): # call our special contract and return the logged value data = bytes.fromhex(hexstr.removeprefix("0x")) - env.execute_code(c.address, value=0, data=data) + env.execute_code(c.address, value=0, data=data) # call default function (log,) = get_logs(c, "Sent") return log.args.sig diff --git a/tests/functional/codegen/calling_convention/test_default_parameters.py b/tests/functional/codegen/calling_convention/test_default_parameters.py index 2976a6eed5..b36df0e3a0 100644 --- a/tests/functional/codegen/calling_convention/test_default_parameters.py +++ b/tests/functional/codegen/calling_convention/test_default_parameters.py @@ -1,5 +1,4 @@ import pytest -from eth.codecs.abi.exceptions import EncodeError from tests.utils import ZERO_ADDRESS from vyper.compiler import compile_code @@ -196,13 +195,13 @@ def bar(a: int128, b: int128 = -1) -> (int128, int128): # noqa: E501 assert c.bar(-123) == (-123, -1) assert c.bar(100, 100) == (100, 100) - def validate_value(cls, value): - pass + def visit_int(node, value): + return value.to_bytes(32, "big", signed=node.is_signed) - monkeypatch.setattr("eth_abi.encoding.NumberEncoder.validate_value", validate_value) + monkeypatch.setattr("eth.codecs.abi.encoder.Encoder.visit_IntegerNode", visit_int) assert c.bar(200, 2**127 - 1) == (200, 2**127 - 1) - with tx_failed(EncodeError): + with tx_failed(): c.bar(200, 2**127, disambiguate_signature="bar(int128,int128)") diff --git a/tests/functional/codegen/environment_variables/test_block_number.py b/tests/functional/codegen/environment_variables/test_block_number.py index fdb2277c0e..4b16ec2208 100644 --- a/tests/functional/codegen/environment_variables/test_block_number.py +++ b/tests/functional/codegen/environment_variables/test_block_number.py @@ -7,6 +7,5 @@ def block_number() -> uint256: c = get_contract(block_number_code) assert c.block_number() == 1 - env.time_travel() - c = env.deploy_source(block_number_code, output_formats, compiler_settings) + env.fast_forward_blocks() 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 a7de637851..2bf85787dc 100644 --- a/tests/functional/codegen/environment_variables/test_blockhash.py +++ b/tests/functional/codegen/environment_variables/test_blockhash.py @@ -22,7 +22,7 @@ def foo() -> bytes32: def test_too_old_blockhash(tx_failed, get_contract, env): - env.time_travel(257) + env.fast_forward_blocks(257) code = """ @external def get_50_blockhash() -> bytes32: diff --git a/tests/functional/codegen/features/decorators/conftest.py b/tests/functional/codegen/features/decorators/conftest.py deleted file mode 100644 index 99d1ada3c9..0000000000 --- a/tests/functional/codegen/features/decorators/conftest.py +++ /dev/null @@ -1,7 +0,0 @@ -import pytest - - -@pytest.fixture(autouse=True) -def set_initial_balance(env): - # set the balance of the deployer so the tests can transfer funds - env.set_balance(env.deployer, 10**20) diff --git a/tests/functional/codegen/features/decorators/test_nonreentrant.py b/tests/functional/codegen/features/decorators/test_nonreentrant.py index 55b4d81027..5586acbe6d 100644 --- a/tests/functional/codegen/features/decorators/test_nonreentrant.py +++ b/tests/functional/codegen/features/decorators/test_nonreentrant.py @@ -260,6 +260,7 @@ def __default__(): assert reentrant_contract.callback() == calling_contract.address # Test unprotected function without callback. + env.set_balance(env.deployer, 10**6) reentrant_contract.unprotected_function("some value", False, value=1000) assert reentrant_contract.special_value() == "some value" assert env.get_balance(reentrant_contract.address) == 0 diff --git a/tests/functional/codegen/features/decorators/test_payable.py b/tests/functional/codegen/features/decorators/test_payable.py index 2c4c621273..aaf8b3af73 100644 --- a/tests/functional/codegen/features/decorators/test_payable.py +++ b/tests/functional/codegen/features/decorators/test_payable.py @@ -334,9 +334,9 @@ 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) @@ -352,8 +352,8 @@ def foo() -> bool: def __default__(): pass """ - c = get_contract(code) + env.set_balance(env.deployer, 100) env.execute_code(c.address, value=100, data="0x12345678") diff --git a/tests/functional/codegen/features/decorators/test_private.py b/tests/functional/codegen/features/decorators/test_private.py index f6bb110d9f..031a190560 100644 --- a/tests/functional/codegen/features/decorators/test_private.py +++ b/tests/functional/codegen/features/decorators/test_private.py @@ -408,7 +408,7 @@ def __default__(): """ c = get_contract(code) - + env.set_balance(env.deployer, to_wei(1, "ether")) env.execute_code(c.address, value=to_wei(1, "ether")) assert env.get_balance(c.address) == to_wei(1, "ether") a3 = env.accounts[2] diff --git a/tests/functional/codegen/features/test_assert.py b/tests/functional/codegen/features/test_assert.py index 8c11cf4c76..9604707916 100644 --- a/tests/functional/codegen/features/test_assert.py +++ b/tests/functional/codegen/features/test_assert.py @@ -1,12 +1,6 @@ import pytest -# web3 returns f"execution reverted: {err_str}" -# TODO move exception string parsing logic into tx_failed -def _fixup_err_str(e_info): - return e_info.value.args[0].replace("execution reverted: ", "") - - def test_assert_refund(env, get_contract, tx_failed): code = """ @external @@ -19,7 +13,8 @@ def foo(): with tx_failed(): c.foo(gas=gas_sent, gas_price=10) - assert env.last_result.gas_used < gas_sent, "Gas refund not received" + # check we issued `revert`, which does not consume all gas + assert env.last_result.gas_used < gas_sent def test_assert_reason(env, get_contract, tx_failed, memory_mocker): diff --git a/tests/functional/codegen/integration/test_crowdfund.py b/tests/functional/codegen/integration/test_crowdfund.py index f8b3f81df0..bc87fe4803 100644 --- a/tests/functional/codegen/integration/test_crowdfund.py +++ b/tests/functional/codegen/integration/test_crowdfund.py @@ -84,7 +84,7 @@ def refund(): c.participate(value=49) assert c.reached() pre_bal = env.get_balance(a1) - env.time_travel(100) + env.fast_forward_blocks(100) assert c.expired() c.finalize() post_bal = env.get_balance(a1) @@ -95,7 +95,7 @@ def refund(): c.participate(value=2, sender=a4) c.participate(value=3, sender=a5) c.participate(value=4, sender=a6) - env.time_travel(100) + env.fast_forward_blocks(100) assert c.expired() assert not c.reached() pre_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] @@ -169,7 +169,7 @@ def refund(): c = get_contract(crowdfund2, *[a1, 50, 60]) c.participate(value=5) - env.time_travel() # make sure auction has started + env.fast_forward_blocks() # make sure auction has started assert c.timelimit() == 60 assert c.deadline() - c.block_timestamp() == 59 assert not c.expired() @@ -177,7 +177,7 @@ def refund(): c.participate(value=49) assert c.reached() pre_bal = env.get_balance(a1) - env.time_travel(100) + env.fast_forward_blocks(100) assert c.expired() c.finalize() post_bal = env.get_balance(a1) @@ -188,7 +188,7 @@ def refund(): c.participate(value=2, sender=a4) c.participate(value=3, sender=a5) c.participate(value=4, sender=a6) - env.time_travel(100) + env.fast_forward_blocks(100) assert c.expired() assert not c.reached() pre_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] diff --git a/tests/functional/codegen/integration/test_escrow.py b/tests/functional/codegen/integration/test_escrow.py index 98c7306a8d..879affc719 100644 --- a/tests/functional/codegen/integration/test_escrow.py +++ b/tests/functional/codegen/integration/test_escrow.py @@ -1,12 +1,3 @@ -import pytest - - -@pytest.fixture(autouse=True) -def set_initial_balance(env): - # set the balance of the deployer so the tests can transfer funds - env.set_balance(env.deployer, 10**20) - - def test_arbitration_code(env, get_contract, tx_failed): arbitration_code = """ buyer: address @@ -32,6 +23,7 @@ def refund(): """ 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(): @@ -66,6 +58,7 @@ def refund(): send(self.buyer, self.balance) """ 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(sender=a1) diff --git a/tests/functional/examples/auctions/test_blind_auction.py b/tests/functional/examples/auctions/test_blind_auction.py index 072fbd49fd..9d74aa5725 100644 --- a/tests/functional/examples/auctions/test_blind_auction.py +++ b/tests/functional/examples/auctions/test_blind_auction.py @@ -39,7 +39,7 @@ def test_late_bid(env, auction_contract, tx_failed, keccak): k1 = env.accounts[1] # Move time forward past bidding end - env.time_travel(BIDDING_TIME + TEST_INCREMENT) + env.fast_forward_blocks(BIDDING_TIME + TEST_INCREMENT) # Try to bid after bidding has ended with tx_failed(): @@ -113,7 +113,7 @@ def test_early_reval(env, auction_contract, tx_failed, keccak): ) # Move time slightly forward (still before bidding has ended) - env.time_travel(TEST_INCREMENT) + env.fast_forward_blocks(TEST_INCREMENT) # Try to reveal early _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -151,7 +151,7 @@ def test_late_reveal(env, auction_contract, tx_failed, keccak): ) # Move time forward past bidding _and_ reveal time - env.time_travel(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) + env.fast_forward_blocks(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) # Try to reveal late _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -182,7 +182,7 @@ def test_double_end(env, auction_contract, tx_failed): k0 = env.deployer # Move time forward past bidding and reveal end - env.time_travel(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) + env.fast_forward_blocks(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) # First auction end should succeed auction_contract.auctionEnd(value=0, sender=k0) @@ -290,7 +290,7 @@ def test_blind_auction(env, auction_contract, keccak): ################################################################### # Move time forward past bidding end (still within reveal end) - env.time_travel(BIDDING_TIME + TEST_INCREMENT) + env.fast_forward_blocks(BIDDING_TIME + TEST_INCREMENT) # Reveal k1 bids _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -356,7 +356,7 @@ def test_blind_auction(env, auction_contract, keccak): ################################################################### # Move time forward past bidding and reveal end - env.time_travel(REVEAL_TIME) + env.fast_forward_blocks(REVEAL_TIME) # End the auction balance_before_end = env.get_balance(k0) diff --git a/tests/functional/examples/auctions/test_simple_open_auction.py b/tests/functional/examples/auctions/test_simple_open_auction.py index 4f2e0a9eb3..c3b0ef18de 100644 --- a/tests/functional/examples/auctions/test_simple_open_auction.py +++ b/tests/functional/examples/auctions/test_simple_open_auction.py @@ -40,7 +40,7 @@ def test_initial_state(env, auction_contract, auction_start): def test_bid(env, auction_contract, tx_failed): k1, k2, k3, k4, k5 = env.accounts[:5] - env.time_travel() # make sure auction has started + env.fast_forward_blocks() # make sure auction has started # Bidder cannot bid 0 with tx_failed(): @@ -85,7 +85,7 @@ def test_bid(env, auction_contract, tx_failed): def test_end_auction(env, auction_contract, tx_failed): k1, k2, k3, k4, k5 = env.accounts[:5] - env.time_travel() # make sure auction has started + env.fast_forward_blocks() # make sure auction has started # Fails if auction end time has not been reached with tx_failed(): @@ -94,7 +94,7 @@ def test_end_auction(env, auction_contract, tx_failed): 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) - env.time_travel(EXPIRY) + env.fast_forward_blocks(EXPIRY) balance_before_end = env.get_balance(k1) auction_contract.endAuction(sender=k2) balance_after_end = env.get_balance(k1) diff --git a/tests/functional/examples/conftest.py b/tests/functional/examples/conftest.py index 506548f6e0..5c3a98e84b 100644 --- a/tests/functional/examples/conftest.py +++ b/tests/functional/examples/conftest.py @@ -4,9 +4,3 @@ @pytest.fixture(autouse=True) def setup(memory_mocker): pass - - -@pytest.fixture(autouse=True) -def set_initial_balance(env): - # set the balance of the deployer so the tests can transfer funds - env.set_balance(env.deployer, 10**20) diff --git a/tests/functional/examples/crowdfund/test_crowdfund_example.py b/tests/functional/examples/crowdfund/test_crowdfund_example.py index ad56778e04..e57f9863cf 100644 --- a/tests/functional/examples/crowdfund/test_crowdfund_example.py +++ b/tests/functional/examples/crowdfund/test_crowdfund_example.py @@ -10,8 +10,9 @@ def c(env, get_contract): 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.time_travel() # make sure auction has started + env.fast_forward_blocks() # make sure auction has started assert c.timelimit() == 60 assert c.deadline() - env.timestamp == 59 @@ -20,7 +21,7 @@ def test_crowdfund_example(c, env): c.participate(value=49) # assert c.reached() pre_bal = env.get_balance(a1) - env.time_travel(100) + env.fast_forward_blocks(100) assert env.timestamp > c.deadline() # expired c.finalize() post_bal = env.get_balance(a1) @@ -38,7 +39,7 @@ def test_crowdfund_example2(c, env, tx_failed): c.participate(value=4, sender=a6) assert c.timelimit() == 60 - env.time_travel(100) + env.fast_forward_blocks(100) # assert c.expired() # assert not c.reached() pre_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] diff --git a/tests/functional/examples/market_maker/test_on_chain_market_maker.py b/tests/functional/examples/market_maker/test_on_chain_market_maker.py index 3645bc1bf8..1c99e8021a 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 @@ -36,6 +36,7 @@ def test_initial_state(market_maker): def test_initiate(env, market_maker, erc20, tx_failed): a0 = env.accounts[0] + env.set_balance(a0, to_wei(2, "ether")) ether, ethers = to_wei(1, "ether"), to_wei(2, "ether") erc20.approve(market_maker.address, ethers) market_maker.initiate(erc20.address, ether, value=ethers) @@ -52,7 +53,8 @@ def test_initiate(env, market_maker, erc20, tx_failed): def test_eth_to_tokens(env, market_maker, erc20): - a1 = env.accounts[1] + 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") @@ -94,7 +96,8 @@ def test_tokens_to_eth(env, market_maker, erc20): def test_owner_withdraw(env, market_maker, erc20, tx_failed): a0, a1 = env.accounts[:2] - a0_balance_before = env.get_balance(a0) + a0_balance_before = to_wei(10, "ether") + env.set_balance(a0, a0_balance_before) # Approve 2 eth transfers. erc20.approve(market_maker.address, to_wei(2, "ether")) # Initiate market with 2 eth value. 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 d67ac5e72a..88dab11aa5 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 @@ -36,6 +36,7 @@ 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) @@ -51,8 +52,8 @@ def test_initial_state(env, tx_failed, get_contract, get_balance, contract_code) def test_abort(env, tx_failed, get_balance, get_contract, contract_code): a0, a1, a2 = env.accounts[:3] - env.set_balance(a1, 10**18) - env.set_balance(a2, 10**18) + 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=to_wei(2, "ether")) @@ -151,7 +152,8 @@ def __default__(): """ a0, a1 = env.accounts[:2] - env.set_balance(a1, 10**18) + 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]) diff --git a/tests/functional/examples/wallet/test_wallet.py b/tests/functional/examples/wallet/test_wallet.py index 4f7e0b5be0..85176109ae 100644 --- a/tests/functional/examples/wallet/test_wallet.py +++ b/tests/functional/examples/wallet/test_wallet.py @@ -14,6 +14,7 @@ def c(env, get_contract): code = f.read() # Sends wei to the contract for future transactions gas costs c = get_contract(code, *[[a1, a2, a3, a4, a5], 3]) + env.set_balance(a0, 10**17) env.execute_code(c.address, value=10**17) return c @@ -109,6 +110,7 @@ def test_javascript_signatures(env, get_contract, keccak): owners = [to_checksum_address(x) for x in accounts + [a3, ZERO_ADDRESS, ZERO_ADDRESS]] x2 = get_contract(f.read(), *[owners, 2]) + env.set_balance(env.deployer, 10**18) env.execute_code(x2.address, value=10**17) # There's no need to pass in signatures because the owners are 0 addresses From 07c0a27921bf9c3f4dc10912ba243ea3d69e21c2 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 22 Apr 2024 10:37:44 +0200 Subject: [PATCH 66/87] Rename back to `time_travel` some crowdfund/auction tests relied on increased timestamps --- tests/evm_backends/base_env.py | 2 +- tests/evm_backends/pyevm_env.py | 3 ++- tests/evm_backends/revm_env.py | 2 +- .../environment_variables/test_block_number.py | 2 +- .../codegen/environment_variables/test_blockhash.py | 2 +- .../functional/codegen/integration/test_crowdfund.py | 10 +++++----- .../examples/auctions/test_blind_auction.py | 12 ++++++------ .../examples/auctions/test_simple_open_auction.py | 6 +++--- .../examples/crowdfund/test_crowdfund_example.py | 6 +++--- 9 files changed, 23 insertions(+), 22 deletions(-) diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index b69c572da4..9e7d031b2c 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -174,7 +174,7 @@ def clear_transient_storage(self) -> None: def get_code(self, address: str) -> bytes: raise NotImplementedError # must be implemented by subclasses - def fast_forward_blocks(self, num_blocks=1) -> None: + def time_travel(self, num_blocks=1) -> None: raise NotImplementedError # must be implemented by subclasses def _deploy(self, code: bytes, value: int, gas: int | None = None) -> str: diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index 4fb187458f..da1d7815b5 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -153,7 +153,7 @@ def _check_computation(self, computation): def get_code(self, address: str): return self._state.get_code(_addr(address)) - def fast_forward_blocks(self, num_blocks=1) -> None: + def time_travel(self, num_blocks=1) -> None: """ Move the block number forward by `num_blocks` and the timestamp forward by `time_delta`. """ @@ -162,6 +162,7 @@ def fast_forward_blocks(self, num_blocks=1) -> None: context = self._state.execution_context assert isinstance(context, ExecutionContext) context._block_number += num_blocks + context._timestamp += num_blocks def _deploy(self, code: bytes, value: int, gas: int = None) -> str: sender = _addr(self.deployer) diff --git a/tests/evm_backends/revm_env.py b/tests/evm_backends/revm_env.py index 5e8a49408d..0a3d9c9dc7 100644 --- a/tests/evm_backends/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -101,7 +101,7 @@ def clear_transient_storage(self) -> None: def get_code(self, address: str): return self._evm.basic(address).code.rstrip(b"\0") - def fast_forward_blocks(self, num_blocks=1) -> None: + def time_travel(self, num_blocks=1) -> None: """ Move the block number forward by `num_blocks` and the timestamp forward by `time_delta`. """ diff --git a/tests/functional/codegen/environment_variables/test_block_number.py b/tests/functional/codegen/environment_variables/test_block_number.py index 4b16ec2208..328a630d17 100644 --- a/tests/functional/codegen/environment_variables/test_block_number.py +++ b/tests/functional/codegen/environment_variables/test_block_number.py @@ -7,5 +7,5 @@ def block_number() -> uint256: c = get_contract(block_number_code) assert c.block_number() == 1 - env.fast_forward_blocks() + env.time_travel() 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 2bf85787dc..a7de637851 100644 --- a/tests/functional/codegen/environment_variables/test_blockhash.py +++ b/tests/functional/codegen/environment_variables/test_blockhash.py @@ -22,7 +22,7 @@ def foo() -> bytes32: def test_too_old_blockhash(tx_failed, get_contract, env): - env.fast_forward_blocks(257) + env.time_travel(257) code = """ @external def get_50_blockhash() -> bytes32: diff --git a/tests/functional/codegen/integration/test_crowdfund.py b/tests/functional/codegen/integration/test_crowdfund.py index bc87fe4803..f8b3f81df0 100644 --- a/tests/functional/codegen/integration/test_crowdfund.py +++ b/tests/functional/codegen/integration/test_crowdfund.py @@ -84,7 +84,7 @@ def refund(): c.participate(value=49) assert c.reached() pre_bal = env.get_balance(a1) - env.fast_forward_blocks(100) + env.time_travel(100) assert c.expired() c.finalize() post_bal = env.get_balance(a1) @@ -95,7 +95,7 @@ def refund(): c.participate(value=2, sender=a4) c.participate(value=3, sender=a5) c.participate(value=4, sender=a6) - env.fast_forward_blocks(100) + env.time_travel(100) assert c.expired() assert not c.reached() pre_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] @@ -169,7 +169,7 @@ def refund(): c = get_contract(crowdfund2, *[a1, 50, 60]) c.participate(value=5) - env.fast_forward_blocks() # make sure auction has started + env.time_travel() # make sure auction has started assert c.timelimit() == 60 assert c.deadline() - c.block_timestamp() == 59 assert not c.expired() @@ -177,7 +177,7 @@ def refund(): c.participate(value=49) assert c.reached() pre_bal = env.get_balance(a1) - env.fast_forward_blocks(100) + env.time_travel(100) assert c.expired() c.finalize() post_bal = env.get_balance(a1) @@ -188,7 +188,7 @@ def refund(): c.participate(value=2, sender=a4) c.participate(value=3, sender=a5) c.participate(value=4, sender=a6) - env.fast_forward_blocks(100) + env.time_travel(100) assert c.expired() assert not c.reached() pre_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] diff --git a/tests/functional/examples/auctions/test_blind_auction.py b/tests/functional/examples/auctions/test_blind_auction.py index 9d74aa5725..072fbd49fd 100644 --- a/tests/functional/examples/auctions/test_blind_auction.py +++ b/tests/functional/examples/auctions/test_blind_auction.py @@ -39,7 +39,7 @@ def test_late_bid(env, auction_contract, tx_failed, keccak): k1 = env.accounts[1] # Move time forward past bidding end - env.fast_forward_blocks(BIDDING_TIME + TEST_INCREMENT) + env.time_travel(BIDDING_TIME + TEST_INCREMENT) # Try to bid after bidding has ended with tx_failed(): @@ -113,7 +113,7 @@ def test_early_reval(env, auction_contract, tx_failed, keccak): ) # Move time slightly forward (still before bidding has ended) - env.fast_forward_blocks(TEST_INCREMENT) + env.time_travel(TEST_INCREMENT) # Try to reveal early _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -151,7 +151,7 @@ def test_late_reveal(env, auction_contract, tx_failed, keccak): ) # Move time forward past bidding _and_ reveal time - env.fast_forward_blocks(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) + env.time_travel(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) # Try to reveal late _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -182,7 +182,7 @@ def test_double_end(env, auction_contract, tx_failed): k0 = env.deployer # Move time forward past bidding and reveal end - env.fast_forward_blocks(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) + env.time_travel(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) # First auction end should succeed auction_contract.auctionEnd(value=0, sender=k0) @@ -290,7 +290,7 @@ def test_blind_auction(env, auction_contract, keccak): ################################################################### # Move time forward past bidding end (still within reveal end) - env.fast_forward_blocks(BIDDING_TIME + TEST_INCREMENT) + env.time_travel(BIDDING_TIME + TEST_INCREMENT) # Reveal k1 bids _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -356,7 +356,7 @@ def test_blind_auction(env, auction_contract, keccak): ################################################################### # Move time forward past bidding and reveal end - env.fast_forward_blocks(REVEAL_TIME) + env.time_travel(REVEAL_TIME) # End the auction balance_before_end = env.get_balance(k0) diff --git a/tests/functional/examples/auctions/test_simple_open_auction.py b/tests/functional/examples/auctions/test_simple_open_auction.py index c3b0ef18de..4f2e0a9eb3 100644 --- a/tests/functional/examples/auctions/test_simple_open_auction.py +++ b/tests/functional/examples/auctions/test_simple_open_auction.py @@ -40,7 +40,7 @@ def test_initial_state(env, auction_contract, auction_start): def test_bid(env, auction_contract, tx_failed): k1, k2, k3, k4, k5 = env.accounts[:5] - env.fast_forward_blocks() # make sure auction has started + env.time_travel() # make sure auction has started # Bidder cannot bid 0 with tx_failed(): @@ -85,7 +85,7 @@ def test_bid(env, auction_contract, tx_failed): def test_end_auction(env, auction_contract, tx_failed): k1, k2, k3, k4, k5 = env.accounts[:5] - env.fast_forward_blocks() # make sure auction has started + env.time_travel() # make sure auction has started # Fails if auction end time has not been reached with tx_failed(): @@ -94,7 +94,7 @@ def test_end_auction(env, auction_contract, tx_failed): 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) - env.fast_forward_blocks(EXPIRY) + env.time_travel(EXPIRY) balance_before_end = env.get_balance(k1) auction_contract.endAuction(sender=k2) balance_after_end = env.get_balance(k1) diff --git a/tests/functional/examples/crowdfund/test_crowdfund_example.py b/tests/functional/examples/crowdfund/test_crowdfund_example.py index e57f9863cf..ffcfe98669 100644 --- a/tests/functional/examples/crowdfund/test_crowdfund_example.py +++ b/tests/functional/examples/crowdfund/test_crowdfund_example.py @@ -12,7 +12,7 @@ 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.fast_forward_blocks() # make sure auction has started + env.time_travel() # make sure auction has started assert c.timelimit() == 60 assert c.deadline() - env.timestamp == 59 @@ -21,7 +21,7 @@ def test_crowdfund_example(c, env): c.participate(value=49) # assert c.reached() pre_bal = env.get_balance(a1) - env.fast_forward_blocks(100) + env.time_travel(100) assert env.timestamp > c.deadline() # expired c.finalize() post_bal = env.get_balance(a1) @@ -39,7 +39,7 @@ def test_crowdfund_example2(c, env, tx_failed): c.participate(value=4, sender=a6) assert c.timelimit() == 60 - env.fast_forward_blocks(100) + env.time_travel(100) # assert c.expired() # assert not c.reached() pre_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] From a59b2b26cd1c43bdf3b6843c70eeb8ac6f163beb Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Thu, 25 Apr 2024 09:13:12 +0200 Subject: [PATCH 67/87] Test blobbasefee without transaction - Uses new pyrevm version https://github.com/paradigmxyz/pyrevm/pull/16 --- setup.py | 2 +- tests/evm_backends/base_env.py | 17 ++++++- tests/evm_backends/pyevm_env.py | 20 ++++++-- tests/evm_backends/revm_env.py | 29 ++++++----- .../environment_variables/test_blobbasefee.py | 51 ++++++++----------- 5 files changed, 68 insertions(+), 51 deletions(-) diff --git a/setup.py b/setup.py index d785398481..4db454ebe4 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ "eth-stdlib==0.2.7", "setuptools", "hexbytes>=1.2", - "pyrevm>=0.3.1", + "pyrevm @ git+https://github.com/DanielSchiavini/pyrevm.git@725cbfc", ], "lint": [ "black==23.12.0", diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index 9e7d031b2c..f4caa83e67 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -1,8 +1,11 @@ import json from contextlib import contextmanager from dataclasses import dataclass -from typing import Callable +from typing import Callable, Optional +from ckzg import blob_to_kzg_commitment, load_trusted_setup +from eth.precompiles.point_evaluation import kzg_to_versioned_hash +from eth_account._utils.typed_transactions.base import TRUSTED_SETUP from eth_keys.datatypes import PrivateKey from eth_utils import to_checksum_address @@ -165,6 +168,7 @@ def execute_code( 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 @@ -177,6 +181,12 @@ def get_code(self, address: str) -> bytes: def time_travel(self, num_blocks=1) -> None: 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 @@ -211,3 +221,8 @@ def _compile( 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")) + + +def kzg_hash(blob: bytes) -> bytes: + commitment = blob_to_kzg_commitment(blob, load_trusted_setup(TRUSTED_SETUP)) + return kzg_to_versioned_hash(commitment) diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index da1d7815b5..b3379951d8 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -1,5 +1,6 @@ import logging from contextlib import contextmanager +from typing import Optional import rlp from cached_property import cached_property @@ -65,6 +66,12 @@ def _state(self) -> StateAPI: def _vm(self): return self._chain.get_vm() + @cached_property + def _context(self) -> ExecutionContext: + context = self._state.execution_context + assert isinstance(context, ExecutionContext) + return context + @contextmanager def anchor(self): snapshot_id = self._state.snapshot() @@ -110,6 +117,7 @@ def execute_code( gas: int | None = None, gas_price: int = 0, is_modifying: bool = True, + blob_hashes: Optional[list[bytes]] = None, # for blobbasefee >= Cancun ): data = data if isinstance(data, bytes) else bytes.fromhex(data.removeprefix("0x")) sender = _addr(sender or self.deployer) @@ -157,12 +165,14 @@ def time_travel(self, num_blocks=1) -> None: """ Move the block number forward by `num_blocks` and the timestamp forward by `time_delta`. """ + self._context._block_number += num_blocks + self._context._timestamp += num_blocks - # Cast since ExecutionContextAPI does not have the properties we need to change - context = self._state.execution_context - assert isinstance(context, ExecutionContext) - context._block_number += num_blocks - context._timestamp += num_blocks + 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) diff --git a/tests/evm_backends/revm_env.py b/tests/evm_backends/revm_env.py index 0a3d9c9dc7..95a615cc8e 100644 --- a/tests/evm_backends/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -1,5 +1,6 @@ import re from contextlib import contextmanager +from typing import Optional from eth_keys.datatypes import PrivateKey from pyrevm import EVM, BlockEnv, Env @@ -76,8 +77,12 @@ def execute_code( gas: int | None = None, gas_price: int = 0, is_modifying: bool = True, + blob_hashes: Optional[list[bytes]] = None, # for blobbasefee >= Cancun ): data = data if isinstance(data, bytes) else bytes.fromhex(data.removeprefix("0x")) + if blob_hashes is not None: + self._evm.env.tx.blob_hashes = blob_hashes + try: return self._evm.message_call( to=to, @@ -105,19 +110,17 @@ def time_travel(self, num_blocks=1) -> None: """ Move the block number forward by `num_blocks` and the timestamp forward by `time_delta`. """ - block = self._evm.env.block - self._evm.set_block_env( - BlockEnv( - number=block.number + num_blocks, - coinbase=block.coinbase, - timestamp=block.timestamp + num_blocks, - difficulty=block.difficulty, - prevrandao=block.prevrandao, - basefee=block.basefee, - gas_limit=block.gas_limit, - excess_blob_gas=block.excess_blob_gas, - ) - ) + self._evm.env.block.number += num_blocks + self._evm.env.block.timestamp += num_blocks + + 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: return self._evm.deploy(self.deployer, code, value, gas) diff --git a/tests/functional/codegen/environment_variables/test_blobbasefee.py b/tests/functional/codegen/environment_variables/test_blobbasefee.py index b92824491c..4440f665ac 100644 --- a/tests/functional/codegen/environment_variables/test_blobbasefee.py +++ b/tests/functional/codegen/environment_variables/test_blobbasefee.py @@ -2,49 +2,38 @@ from eth.vm.forks.cancun.constants import BLOB_BASE_FEE_UPDATE_FRACTION, MIN_BLOB_BASE_FEE from eth.vm.forks.cancun.state import fake_exponential +from tests.evm_backends.base_env import kzg_hash + @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") + env.set_balance(env.deployer, 10**20) + env.set_excess_blob_gas(10**6) 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 + blob_hashes = [kzg_hash(blob_data)] * 6 + + env.execute_code( + "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 From 27331902c8ac117ff4bfef8dd758df1a1973237f Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 26 Apr 2024 10:06:10 +0200 Subject: [PATCH 68/87] Review comments --- setup.py | 2 +- tests/conftest.py | 8 ++--- tests/evm_backends/base_env.py | 19 ++++++------ tests/evm_backends/pyevm_env.py | 21 +++++++------- tests/evm_backends/revm_env.py | 24 ++++++++++----- .../builtins/codegen/test_create_functions.py | 6 ++-- .../functional/builtins/codegen/test_slice.py | 3 ++ .../test_default_parameters.py | 14 ++++----- .../test_block_number.py | 2 +- .../environment_variables/test_blockhash.py | 2 +- .../features/test_assert_unreachable.py | 2 +- .../codegen/features/test_clampers.py | 16 +++++----- .../codegen/features/test_constructor.py | 29 ++++++++++--------- .../codegen/integration/test_crowdfund.py | 10 +++---- .../examples/auctions/test_blind_auction.py | 12 ++++---- .../auctions/test_simple_open_auction.py | 7 ++--- .../crowdfund/test_crowdfund_example.py | 6 ++-- .../test_safe_remote_purchase.py | 2 +- 18 files changed, 97 insertions(+), 88 deletions(-) diff --git a/setup.py b/setup.py index 4db454ebe4..7822675af1 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ "eth-stdlib==0.2.7", "setuptools", "hexbytes>=1.2", - "pyrevm @ git+https://github.com/DanielSchiavini/pyrevm.git@725cbfc", + "pyrevm @ git+https://github.com/DanielSchiavini/pyrevm.git@b1a6f63", ], "lint": [ "black==23.12.0", diff --git a/tests/conftest.py b/tests/conftest.py index 20df513845..fe905a0d90 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -111,13 +111,9 @@ def _xfail(*args, **kwargs): @pytest.fixture(scope="session", autouse=True) def evm_version(pytestconfig): - version = pytestconfig.getoption("evm_version") # note: configure the evm version that we emit code for. # The env will read this fixture and apply the evm version there. - evm_opcodes.DEFAULT_EVM_VERSION = version - # This should get overridden by anchor_evm_version, but set it anyway - evm_opcodes.active_evm_version = evm_opcodes.EVM_VERSIONS[version] - return version + return pytestconfig.getoption("evm_version") @pytest.fixture(scope="session", autouse=True) @@ -326,7 +322,7 @@ def tx_failed(env): @contextmanager def fn(exception=EvmError, exc_text=None): with env.anchor(), pytest.raises(exception) as excinfo: - yield excinfo + yield if exc_text: # TODO test equality diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index f4caa83e67..61aa12e7c0 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -85,14 +85,11 @@ def deploy_source( compiler_settings: Settings, *args, input_bundle=None, + value=0, **kwargs, ) -> ABIContract: """Compile and deploy a contract from source code.""" abi, bytecode = _compile(source_code, output_formats, compiler_settings, input_bundle) - value = ( - kwargs.pop("value", 0) or kwargs.pop("value_in_eth", 0) * 10**18 - ) # Handle deploying with an eth value. - return self.deploy(abi, bytecode, value, *args, **kwargs) def deploy_blueprint( @@ -114,8 +111,7 @@ def deploy_blueprint( deploy_bytecode = deploy_preamble + bytecode deployer_abi: list[dict] = [] # just a constructor - value = 0 - deployer = self.deploy(deployer_abi, deploy_bytecode, value, *args) + deployer = self.deploy(deployer_abi, deploy_bytecode, *args) def factory(address): return ABIContractFactory.from_abi_dict(abi).at(self, address) @@ -151,10 +147,18 @@ def accounts(self) -> list[str]: 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 @@ -178,9 +182,6 @@ def clear_transient_storage(self) -> None: def get_code(self, address: str) -> bytes: raise NotImplementedError # must be implemented by subclasses - def time_travel(self, num_blocks=1) -> None: - raise NotImplementedError # must be implemented by subclasses - def get_excess_blob_gas(self) -> Optional[int]: raise NotImplementedError # must be implemented by subclasses diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index b3379951d8..07f58a34c2 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -69,7 +69,7 @@ def _vm(self): @cached_property def _context(self) -> ExecutionContext: context = self._state.execution_context - assert isinstance(context, ExecutionContext) + assert isinstance(context, ExecutionContext) # help mypy return context @contextmanager @@ -92,11 +92,19 @@ def accounts(self) -> list[str]: @property def block_number(self) -> int: - return self._state.block_number + 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._state.timestamp + return self._context.timestamp + + @timestamp.setter + def timestamp(self, value: int): + self._context._timestamp = value @property def last_result(self) -> ExecutionResult: @@ -161,13 +169,6 @@ def _check_computation(self, computation): def get_code(self, address: str): return self._state.get_code(_addr(address)) - def time_travel(self, num_blocks=1) -> None: - """ - Move the block number forward by `num_blocks` and the timestamp forward by `time_delta`. - """ - self._context._block_number += num_blocks - self._context._timestamp += num_blocks - def get_excess_blob_gas(self) -> Optional[int]: return self._context.excess_blob_gas diff --git a/tests/evm_backends/revm_env.py b/tests/evm_backends/revm_env.py index 95a615cc8e..a6327828ca 100644 --- a/tests/evm_backends/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -54,10 +54,22 @@ def accounts(self) -> list[str]: 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 @@ -81,7 +93,9 @@ def execute_code( ): data = data if isinstance(data, bytes) else bytes.fromhex(data.removeprefix("0x")) if blob_hashes is not None: - self._evm.env.tx.blob_hashes = blob_hashes + tx = self._evm.env.tx + tx.blob_hashes = blob_hashes + self._evm.set_tx_env(tx) try: return self._evm.message_call( @@ -94,6 +108,7 @@ def execute_code( is_static=not is_modifying, ) except RuntimeError as e: + # 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) @@ -106,13 +121,6 @@ def clear_transient_storage(self) -> None: def get_code(self, address: str): return self._evm.basic(address).code.rstrip(b"\0") - def time_travel(self, num_blocks=1) -> None: - """ - Move the block number forward by `num_blocks` and the timestamp forward by `time_delta`. - """ - self._evm.env.block.number += num_blocks - self._evm.env.block.timestamp += num_blocks - def get_excess_blob_gas(self) -> Optional[int]: return self._evm.env.block.excess_blob_gas diff --git a/tests/functional/builtins/codegen/test_create_functions.py b/tests/functional/builtins/codegen/test_create_functions.py index fde0cdfa4e..9677b99aab 100644 --- a/tests/functional/builtins/codegen/test_create_functions.py +++ b/tests/functional/builtins/codegen/test_create_functions.py @@ -480,9 +480,6 @@ def test2(target: address, salt: bytes32) -> address: with tx_failed(): c.test("0x" + "00" * 20) - # test1 = c.test(b"\x01") - # assert revm_env.get_code(test1) == b"\x01" - salt = keccak(b"vyper") c.test2(c.address, salt) test2 = c.created_address() @@ -683,9 +680,10 @@ def test(target: address) -> address: c = get_contract(complex_salt) bytecode = env.get_code(c.address) + assert bytecode # Sanity check c.test(c.address) test1 = c.address - assert bytecode and env.get_code(test1) == bytecode + assert env.get_code(test1) == bytecode # test msize allocator does not get trampled by value= kwarg complex_value = """ diff --git a/tests/functional/builtins/codegen/test_slice.py b/tests/functional/builtins/codegen/test_slice.py index f6487bd515..5c2cc1b6ec 100644 --- a/tests/functional/builtins/codegen/test_slice.py +++ b/tests/functional/builtins/codegen/test_slice.py @@ -167,6 +167,9 @@ def do_slice(inp: Bytes[{length_bound}], start: uint256, length: uint256) -> Byt def _get_contract(): 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) diff --git a/tests/functional/codegen/calling_convention/test_default_parameters.py b/tests/functional/codegen/calling_convention/test_default_parameters.py index b36df0e3a0..5a50453a34 100644 --- a/tests/functional/codegen/calling_convention/test_default_parameters.py +++ b/tests/functional/codegen/calling_convention/test_default_parameters.py @@ -9,6 +9,7 @@ TypeMismatch, UndeclaredDefinition, ) +from vyper.utils import method_id def test_default_param_abi(get_contract): @@ -183,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 @@ -195,14 +196,13 @@ def bar(a: int128, b: int128 = -1) -> (int128, int128): # noqa: E501 assert c.bar(-123) == (-123, -1) assert c.bar(100, 100) == (100, 100) - def visit_int(node, value): - return value.to_bytes(32, "big", signed=node.is_signed) + 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.codecs.abi.encoder.Encoder.visit_IntegerNode", visit_int) - - assert c.bar(200, 2**127 - 1) == (200, 2**127 - 1) + assert env.execute_code(c.address, data=method + good_data) == good_data with tx_failed(): - c.bar(200, 2**127, disambiguate_signature="bar(int128,int128)") + env.execute_code(c.address, data=method + bad_data) def test_default_param_private(get_contract): diff --git a/tests/functional/codegen/environment_variables/test_block_number.py b/tests/functional/codegen/environment_variables/test_block_number.py index 328a630d17..f4a854d59f 100644 --- a/tests/functional/codegen/environment_variables/test_block_number.py +++ b/tests/functional/codegen/environment_variables/test_block_number.py @@ -7,5 +7,5 @@ def block_number() -> uint256: c = get_contract(block_number_code) assert c.block_number() == 1 - env.time_travel() + 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 a7de637851..4ddbec080b 100644 --- a/tests/functional/codegen/environment_variables/test_blockhash.py +++ b/tests/functional/codegen/environment_variables/test_blockhash.py @@ -22,7 +22,7 @@ def foo() -> bytes32: def test_too_old_blockhash(tx_failed, get_contract, env): - env.time_travel(257) + env.block_number += 257 code = """ @external def get_50_blockhash() -> bytes32: diff --git a/tests/functional/codegen/features/test_assert_unreachable.py b/tests/functional/codegen/features/test_assert_unreachable.py index 855fbc21f9..ee6ccef8da 100644 --- a/tests/functional/codegen/features/test_assert_unreachable.py +++ b/tests/functional/codegen/features/test_assert_unreachable.py @@ -11,7 +11,7 @@ def foo(): with tx_failed(): c.foo(gas=gas_sent, gas_price=10) - assert env.last_result.gas_used == 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(env, get_contract, tx_failed): diff --git a/tests/functional/codegen/features/test_clampers.py b/tests/functional/codegen/features/test_clampers.py index d7a84ec8d9..a3bb43022c 100644 --- a/tests/functional/codegen/features/test_clampers.py +++ b/tests/functional/codegen/features/test_clampers.py @@ -9,18 +9,18 @@ from vyper.utils import int_bounds -def _make_tx(revm_env, address, signature, values): +def _make_tx(env, address, signature, values): # helper function to broadcast transactions that fail clamping check sig = keccak(signature.encode()).hex()[:8] data = "".join(int(i).to_bytes(32, "big", signed=i < 0).hex() for i in values) - revm_env.execute_code(address, data=f"0x{sig}{data}") + env.execute_code(address, data=f"0x{sig}{data}") -def _make_abi_encode_tx(revm_env, 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() - revm_env.execute_code(address, data=f"0x{sig}{data}") + env.execute_code(address, data=f"0x{sig}{data}") def _make_dynarray_data(offset, length, values): @@ -29,9 +29,9 @@ def _make_dynarray_data(offset, length, values): return data -def _make_invalid_dynarray_tx(revm_env, address, signature, data): +def _make_invalid_dynarray_tx(env, address, signature, data): sig = keccak(signature.encode()).hex()[:8] - revm_env.execute_code(address, data=f"0x{sig}{data}") + env.execute_code(address, data=f"0x{sig}{data}") def test_bytes_clamper(tx_failed, get_contract): @@ -77,11 +77,11 @@ def get_foo() -> Bytes[3]: return self.foo """ - c = get_contract(clamper_test_code, *[b"cat"]) + c = get_contract(clamper_test_code, b"cat") assert c.get_foo() == b"cat" with tx_failed(): - get_contract(clamper_test_code, *[b"cats"]) + get_contract(clamper_test_code, b"cats") @pytest.mark.parametrize("n", list(range(1, 33))) diff --git a/tests/functional/codegen/features/test_constructor.py b/tests/functional/codegen/features/test_constructor.py index 0534a62896..314ec55ec7 100644 --- a/tests/functional/codegen/features/test_constructor.py +++ b/tests/functional/codegen/features/test_constructor.py @@ -1,7 +1,8 @@ import pytest -from eth.codecs.abi.exceptions import EncodeError +from tests.evm_backends.base_env import _compile from vyper.exceptions import StackTooDeep +from vyper.utils import method_id def test_init_argument_test(get_contract): @@ -75,7 +76,7 @@ def get_comb() -> uint256: print("Passed advanced init argument tests") -def test_large_input_code(get_contract): +def test_large_input_code(env, get_contract, tx_failed): large_input_code = """ @external def foo(x: int128) -> int128: @@ -83,15 +84,18 @@ def foo(x: int128) -> int128: """ c = get_contract(large_input_code) - c.foo(1274124) - c.foo(2**120) + signature = "(int128)" + method = method_id(f"foo{signature}") - with pytest.raises(EncodeError): - c.foo(2**130) + env.execute_code(c.address, data=method + (1274124).to_bytes(32, "big")) + env.execute_code(c.address, data=method + (2**120).to_bytes(32, "big")) + with tx_failed(): + env.execute_code(c.address, data=method + (2**130).to_bytes(32, "big")) -def test_large_input_code_2(env, get_contract): - large_input_code_2 = """ + +def test_large_input_code_2(env, get_contract, tx_failed, output_formats, compiler_settings): + code = """ @deploy def __init__(x: int128): y: int128 = x @@ -101,12 +105,11 @@ def foo() -> int128: return 5 """ - get_contract(large_input_code_2, *[17]) - - with pytest.raises(EncodeError): - get_contract(large_input_code_2, *[2**130]) + _, bytecode = _compile(code, output_formats, compiler_settings) + env._deploy(bytecode + (2**128 - 1).to_bytes(32, "big"), value=0) - print("Passed invalid input tests") + with tx_failed(): + env._deploy(bytecode + (2**128).to_bytes(32, "big"), value=0) def test_initialise_array_with_constant_key(get_contract): diff --git a/tests/functional/codegen/integration/test_crowdfund.py b/tests/functional/codegen/integration/test_crowdfund.py index f8b3f81df0..1644985f9d 100644 --- a/tests/functional/codegen/integration/test_crowdfund.py +++ b/tests/functional/codegen/integration/test_crowdfund.py @@ -84,7 +84,7 @@ def refund(): c.participate(value=49) assert c.reached() pre_bal = env.get_balance(a1) - env.time_travel(100) + env.timestamp += 100 assert c.expired() c.finalize() post_bal = env.get_balance(a1) @@ -95,7 +95,7 @@ def refund(): c.participate(value=2, sender=a4) c.participate(value=3, sender=a5) c.participate(value=4, sender=a6) - env.time_travel(100) + env.timestamp += 100 assert c.expired() assert not c.reached() pre_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] @@ -169,7 +169,7 @@ def refund(): c = get_contract(crowdfund2, *[a1, 50, 60]) c.participate(value=5) - env.time_travel() # make sure auction has started + env.timestamp += 1 # make sure auction has started assert c.timelimit() == 60 assert c.deadline() - c.block_timestamp() == 59 assert not c.expired() @@ -177,7 +177,7 @@ def refund(): c.participate(value=49) assert c.reached() pre_bal = env.get_balance(a1) - env.time_travel(100) + env.timestamp += 100 assert c.expired() c.finalize() post_bal = env.get_balance(a1) @@ -188,7 +188,7 @@ def refund(): c.participate(value=2, sender=a4) c.participate(value=3, sender=a5) c.participate(value=4, sender=a6) - env.time_travel(100) + env.timestamp += 100 assert c.expired() assert not c.reached() pre_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] diff --git a/tests/functional/examples/auctions/test_blind_auction.py b/tests/functional/examples/auctions/test_blind_auction.py index 072fbd49fd..06f0656f1d 100644 --- a/tests/functional/examples/auctions/test_blind_auction.py +++ b/tests/functional/examples/auctions/test_blind_auction.py @@ -39,7 +39,7 @@ def test_late_bid(env, auction_contract, tx_failed, keccak): k1 = env.accounts[1] # Move time forward past bidding end - env.time_travel(BIDDING_TIME + TEST_INCREMENT) + env.timestamp += BIDDING_TIME + TEST_INCREMENT # Try to bid after bidding has ended with tx_failed(): @@ -113,7 +113,7 @@ def test_early_reval(env, auction_contract, tx_failed, keccak): ) # Move time slightly forward (still before bidding has ended) - env.time_travel(TEST_INCREMENT) + env.timestamp += TEST_INCREMENT # Try to reveal early _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -151,7 +151,7 @@ def test_late_reveal(env, auction_contract, tx_failed, keccak): ) # Move time forward past bidding _and_ reveal time - env.time_travel(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 @@ -182,7 +182,7 @@ def test_double_end(env, auction_contract, tx_failed): k0 = env.deployer # Move time forward past bidding and reveal end - env.time_travel(BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT) + env.timestamp += BIDDING_TIME + REVEAL_TIME + TEST_INCREMENT # First auction end should succeed auction_contract.auctionEnd(value=0, sender=k0) @@ -290,7 +290,7 @@ def test_blind_auction(env, auction_contract, keccak): ################################################################### # Move time forward past bidding end (still within reveal end) - env.time_travel(BIDDING_TIME + TEST_INCREMENT) + env.timestamp += BIDDING_TIME + TEST_INCREMENT # Reveal k1 bids _values = [0] * MAX_BIDS # Initialized with 128 default values @@ -356,7 +356,7 @@ def test_blind_auction(env, auction_contract, keccak): ################################################################### # Move time forward past bidding and reveal end - env.time_travel(REVEAL_TIME) + env.timestamp += REVEAL_TIME # End the auction balance_before_end = env.get_balance(k0) diff --git a/tests/functional/examples/auctions/test_simple_open_auction.py b/tests/functional/examples/auctions/test_simple_open_auction.py index 4f2e0a9eb3..f0bc8f2de9 100644 --- a/tests/functional/examples/auctions/test_simple_open_auction.py +++ b/tests/functional/examples/auctions/test_simple_open_auction.py @@ -40,7 +40,7 @@ def test_initial_state(env, auction_contract, auction_start): def test_bid(env, auction_contract, tx_failed): k1, k2, k3, k4, k5 = env.accounts[:5] - env.time_travel() # make sure auction has started + env.timestamp += 1 # make sure auction has started # Bidder cannot bid 0 with tx_failed(): @@ -85,7 +85,7 @@ def test_bid(env, auction_contract, tx_failed): def test_end_auction(env, auction_contract, tx_failed): k1, k2, k3, k4, k5 = env.accounts[:5] - env.time_travel() # make sure auction has started + env.timestamp += 1 # make sure auction has started # Fails if auction end time has not been reached with tx_failed(): @@ -93,8 +93,7 @@ def test_end_auction(env, auction_contract, tx_failed): 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) - env.time_travel(EXPIRY) + env.timestamp += EXPIRY balance_before_end = env.get_balance(k1) auction_contract.endAuction(sender=k2) balance_after_end = env.get_balance(k1) diff --git a/tests/functional/examples/crowdfund/test_crowdfund_example.py b/tests/functional/examples/crowdfund/test_crowdfund_example.py index ffcfe98669..ff0d85d61e 100644 --- a/tests/functional/examples/crowdfund/test_crowdfund_example.py +++ b/tests/functional/examples/crowdfund/test_crowdfund_example.py @@ -12,7 +12,7 @@ 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.time_travel() # make sure auction has started + env.timestamp += 1 # make sure auction has started assert c.timelimit() == 60 assert c.deadline() - env.timestamp == 59 @@ -21,7 +21,7 @@ def test_crowdfund_example(c, env): c.participate(value=49) # assert c.reached() pre_bal = env.get_balance(a1) - env.time_travel(100) + env.timestamp += 100 assert env.timestamp > c.deadline() # expired c.finalize() post_bal = env.get_balance(a1) @@ -39,7 +39,7 @@ def test_crowdfund_example2(c, env, tx_failed): c.participate(value=4, sender=a6) assert c.timelimit() == 60 - env.time_travel(100) + env.timestamp += 100 # assert c.expired() # assert not c.reached() pre_bals = [env.get_balance(x) for x in [a3, a4, a5, a6]] 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 88dab11aa5..656cbf12a8 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 @@ -39,7 +39,7 @@ def test_initial_state(env, tx_failed, get_contract, get_balance, contract_code) 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_in_eth=to_wei(2, "ether")) # Check that the seller is set correctly assert c.seller() == env.accounts[0] # Check if item value is set correctly (Half of deposit) From b5bee3ca25730779eddfa72aa7de7c4afe38c361 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 26 Apr 2024 11:23:04 +0200 Subject: [PATCH 69/87] Fix tests --- tests/evm_backends/revm_env.py | 19 +++++++++++++------ .../codegen/features/test_constructor.py | 3 ++- .../test_safe_remote_purchase.py | 2 +- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/tests/evm_backends/revm_env.py b/tests/evm_backends/revm_env.py index a6327828ca..31b52aaaa2 100644 --- a/tests/evm_backends/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -108,11 +108,7 @@ def execute_code( is_static=not is_modifying, ) except RuntimeError as e: - # 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) - self._parse_revert(output_bytes, e, int(gas_used)) + self._parse_error(e) raise EvmError(*e.args) from e def clear_transient_storage(self) -> None: @@ -131,4 +127,15 @@ 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: - return self._evm.deploy(self.deployer, code, value, gas) + 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/codegen/features/test_constructor.py b/tests/functional/codegen/features/test_constructor.py index 314ec55ec7..f4810671aa 100644 --- a/tests/functional/codegen/features/test_constructor.py +++ b/tests/functional/codegen/features/test_constructor.py @@ -106,7 +106,8 @@ def foo() -> int128: """ _, bytecode = _compile(code, output_formats, compiler_settings) - env._deploy(bytecode + (2**128 - 1).to_bytes(32, "big"), value=0) + to_bytes = (2**127 - 1).to_bytes(32, "big") + env._deploy(bytecode + to_bytes, value=0) with tx_failed(): env._deploy(bytecode + (2**128).to_bytes(32, "big"), value=0) 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 656cbf12a8..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 @@ -39,7 +39,7 @@ def test_initial_state(env, tx_failed, get_contract, get_balance, contract_code) 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=to_wei(2, "ether")) + c = get_contract(contract_code, value=to_wei(2, "ether")) # Check that the seller is set correctly assert c.seller() == env.accounts[0] # Check if item value is set correctly (Half of deposit) From ba2a5b978e56d62d87d222474e3856293d220133 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 26 Apr 2024 16:56:34 +0200 Subject: [PATCH 70/87] Cleanup dependencies --- setup.py | 2 -- tests/conftest.py | 1 - tests/evm_backends/pyevm_env.py | 3 --- tests/functional/codegen/features/test_constructor.py | 6 +++--- tests/functional/codegen/features/test_transient.py | 3 --- 5 files changed, 3 insertions(+), 12 deletions(-) diff --git a/setup.py b/setup.py index 7822675af1..f1d92cb9ed 100644 --- a/setup.py +++ b/setup.py @@ -13,10 +13,8 @@ "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", diff --git a/tests/conftest.py b/tests/conftest.py index fe905a0d90..bed8f90e1a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -318,7 +318,6 @@ def assert_side_effects_invoked(side_effects_contract, side_effects_trigger, n=1 @pytest.fixture(scope="module") def tx_failed(env): - # todo: use custom exception, we don't use eth_tester anymore @contextmanager def fn(exception=EvmError, exc_text=None): with env.anchor(), pytest.raises(exception) as excinfo: diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index 07f58a34c2..945ddb0fd7 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -38,9 +38,6 @@ def __init__( ) -> None: super().__init__(gas_limit, account_keys) - # note: we configure the evm version that we emit code for, - # but eth-tester is only configured with the latest mainnet - # version. evm_opcodes.DEFAULT_EVM_VERSION = evm_version if tracing: diff --git a/tests/functional/codegen/features/test_constructor.py b/tests/functional/codegen/features/test_constructor.py index f4810671aa..d85eec08ff 100644 --- a/tests/functional/codegen/features/test_constructor.py +++ b/tests/functional/codegen/features/test_constructor.py @@ -106,11 +106,11 @@ def foo() -> int128: """ _, bytecode = _compile(code, output_formats, compiler_settings) - to_bytes = (2**127 - 1).to_bytes(32, "big") - env._deploy(bytecode + to_bytes, value=0) + ctor_args = (2**127 - 1).to_bytes(32, "big") + env._deploy(bytecode + ctor_args, value=0) with tx_failed(): - env._deploy(bytecode + (2**128).to_bytes(32, "big"), value=0) + env._deploy(bytecode + (2**127).to_bytes(32, "big"), value=0) def test_initialise_array_with_constant_key(get_contract): diff --git a/tests/functional/codegen/features/test_transient.py b/tests/functional/codegen/features/test_transient.py index 01f6ccfc3e..36c4303b9c 100644 --- a/tests/functional/codegen/features/test_transient.py +++ b/tests/functional/codegen/features/test_transient.py @@ -7,9 +7,6 @@ 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])) From f35e90cece5e8d14e7ebf70de464700bce3fb943 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 29 Apr 2024 09:51:18 +0200 Subject: [PATCH 71/87] Missing dependency + settings mismatch --- setup.py | 1 + tests/functional/syntax/test_codehash.py | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index f1d92cb9ed..b14846567c 100644 --- a/setup.py +++ b/setup.py @@ -18,6 +18,7 @@ "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 @ git+https://github.com/DanielSchiavini/pyrevm.git@b1a6f63", diff --git a/tests/functional/syntax/test_codehash.py b/tests/functional/syntax/test_codehash.py index 7aa01a68e9..abfa1cd8a3 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, compiler_settings): 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"], settings=compiler_settings) bytecode = bytes.fromhex(compiled["bytecode_runtime"][2:]) hash_ = keccak256(bytecode) From 9cd1685d470ffaf60052a1fbf58d884353aadc66 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 29 Apr 2024 10:23:54 +0200 Subject: [PATCH 72/87] Use the global settings --- vyper/compiler/__init__.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) 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",) From 984e5854c083d0b9e708e2ffae7c590dd314ae1a Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 29 Apr 2024 11:29:05 +0200 Subject: [PATCH 73/87] Fix optimization level --- tests/unit/cli/vyper_json/test_compile_json.py | 4 ++-- tests/unit/compiler/test_source_map.py | 8 +++++++- vyper/cli/vyper_json.py | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/unit/cli/vyper_json/test_compile_json.py b/tests/unit/cli/vyper_json/test_compile_json.py index 62a799db65..6963720e16 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): return { "language": "Vyper", "sources": { @@ -81,7 +81,7 @@ def input_json(): "contracts/bar.vy": {"content": BAR_CODE}, }, "interfaces": {"contracts/ibar.json": {"abi": BAR_ABI}}, - "settings": {"outputSelection": {"*": ["*"]}}, + "settings": {"outputSelection": {"*": ["*"]}, "optimize": optimize}, } diff --git a/tests/unit/compiler/test_source_map.py b/tests/unit/compiler/test_source_map.py index 04bd141185..4469058b7c 100644 --- a/tests/unit/compiler/test_source_map.py +++ b/tests/unit/compiler/test_source_map.py @@ -1,7 +1,10 @@ from collections import namedtuple +import pytest + 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,7 +34,10 @@ def foo(a: uint256) -> int128: """ -def test_jump_map(): +def test_jump_map(optimize): + if optimize == OptimizationLevel.NONE: + raise pytest.skip("This test is not working for unoptimized code.") + 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"] diff --git a/vyper/cli/vyper_json.py b/vyper/cli/vyper_json.py index 8f39eb55e6..639f405143 100755 --- a/vyper/cli/vyper_json.py +++ b/vyper/cli/vyper_json.py @@ -271,7 +271,7 @@ def compile_from_input_dict( optimize = OptimizationLevel.default() if optimize else OptimizationLevel.NONE elif isinstance(optimize, str): optimize = OptimizationLevel.from_string(optimize) - else: + elif not isinstance(optimize, OptimizationLevel): assert optimize is None settings = Settings(evm_version=evm_version, optimize=optimize) From e6f871e7f407ec38c762a42fa95e768340ac8ddb Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 29 Apr 2024 12:29:52 +0200 Subject: [PATCH 74/87] Fix optimization level --- tests/unit/cli/vyper_json/test_compile_json.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/cli/vyper_json/test_compile_json.py b/tests/unit/cli/vyper_json/test_compile_json.py index 6963720e16..0293bfddfc 100644 --- a/tests/unit/cli/vyper_json/test_compile_json.py +++ b/tests/unit/cli/vyper_json/test_compile_json.py @@ -81,7 +81,7 @@ def input_json(optimize): "contracts/bar.vy": {"content": BAR_CODE}, }, "interfaces": {"contracts/ibar.json": {"abi": BAR_ABI}}, - "settings": {"outputSelection": {"*": ["*"]}, "optimize": optimize}, + "settings": {"outputSelection": {"*": ["*"]}, "optimize": optimize.name.lower()}, } From a627a0f47b0addbc9cd8dcd454859a4ced9780cf Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 29 Apr 2024 17:24:10 +0200 Subject: [PATCH 75/87] Settings fixes --- tests/unit/cli/vyper_json/test_compile_json.py | 8 ++++++-- tests/unit/compiler/test_source_map.py | 12 ++++++------ vyper/cli/vyper_json.py | 2 +- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/tests/unit/cli/vyper_json/test_compile_json.py b/tests/unit/cli/vyper_json/test_compile_json.py index 0293bfddfc..3edd627272 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(optimize): +def input_json(optimize, evm_version): return { "language": "Vyper", "sources": { @@ -81,7 +81,11 @@ def input_json(optimize): "contracts/bar.vy": {"content": BAR_CODE}, }, "interfaces": {"contracts/ibar.json": {"abi": BAR_ABI}}, - "settings": {"outputSelection": {"*": ["*"]}, "optimize": optimize.name.lower()}, + "settings": { + "outputSelection": {"*": ["*"]}, + "optimize": optimize.name.lower(), + "evmVersion": evm_version, + }, } diff --git a/tests/unit/compiler/test_source_map.py b/tests/unit/compiler/test_source_map.py index 4469058b7c..6b91c2790a 100644 --- a/tests/unit/compiler/test_source_map.py +++ b/tests/unit/compiler/test_source_map.py @@ -1,7 +1,5 @@ from collections import namedtuple -import pytest - from vyper.compiler import compile_code from vyper.compiler.output import _compress_source_map from vyper.compiler.settings import OptimizationLevel @@ -35,22 +33,24 @@ def foo(a: uint256) -> int128: def test_jump_map(optimize): - if optimize == OptimizationLevel.NONE: - raise pytest.skip("This test is not working for unoptimized code.") - 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 = 3 if optimize == OptimizationLevel.NONE else 1 + 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: + 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: + 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/vyper/cli/vyper_json.py b/vyper/cli/vyper_json.py index 639f405143..8f39eb55e6 100755 --- a/vyper/cli/vyper_json.py +++ b/vyper/cli/vyper_json.py @@ -271,7 +271,7 @@ def compile_from_input_dict( optimize = OptimizationLevel.default() if optimize else OptimizationLevel.NONE elif isinstance(optimize, str): optimize = OptimizationLevel.from_string(optimize) - elif not isinstance(optimize, OptimizationLevel): + else: assert optimize is None settings = Settings(evm_version=evm_version, optimize=optimize) From 1680b623876a3b161c7f64436f71b87f688a88b3 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Mon, 29 Apr 2024 20:50:16 +0200 Subject: [PATCH 76/87] More settings fixes --- tests/functional/codegen/types/numbers/test_constants.py | 5 +++-- tests/unit/cli/vyper_json/test_compile_json.py | 3 ++- vyper/cli/vyper_json.py | 5 ++++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/functional/codegen/types/numbers/test_constants.py b/tests/functional/codegen/types/numbers/test_constants.py index 72add57068..f29a20153b 100644 --- a/tests/functional/codegen/types/numbers/test_constants.py +++ b/tests/functional/codegen/types/numbers/test_constants.py @@ -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/unit/cli/vyper_json/test_compile_json.py b/tests/unit/cli/vyper_json/test_compile_json.py index 3edd627272..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(optimize, evm_version): +def input_json(optimize, evm_version, experimental_codegen): return { "language": "Vyper", "sources": { @@ -85,6 +85,7 @@ def input_json(optimize, evm_version): "outputSelection": {"*": ["*"]}, "optimize": optimize.name.lower(), "evmVersion": evm_version, + "experimentalCodegen": experimental_codegen, }, } 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) From 7a8e1930cdfe472947ff488e72fa11742622f541 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 1 May 2024 11:01:10 +0200 Subject: [PATCH 77/87] Fix small review comments --- tests/functional/examples/factory/test_factory.py | 6 ++---- tests/functional/syntax/test_address_code.py | 6 ++---- tests/functional/syntax/test_codehash.py | 4 ++-- tests/unit/compiler/test_source_map.py | 5 ++++- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/tests/functional/examples/factory/test_factory.py b/tests/functional/examples/factory/test_factory.py index 7947a4b464..ecfc0bf557 100644 --- a/tests/functional/examples/factory/test_factory.py +++ b/tests/functional/examples/factory/test_factory.py @@ -30,13 +30,11 @@ def create_exchange(token, factory): @pytest.fixture -def factory(get_contract, compiler_settings): +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=compiler_settings - ) + 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: diff --git a/tests/functional/syntax/test_address_code.py b/tests/functional/syntax/test_address_code.py index f7d9f50226..bf1651ef43 100644 --- a/tests/functional/syntax/test_address_code.py +++ b/tests/functional/syntax/test_address_code.py @@ -157,7 +157,7 @@ def test_address_code_compile_success(code: str): compiler.compile_code(code) -def test_address_code_self_success(get_contract, compiler_settings): +def test_address_code_self_success(get_contract): code = """ code_deployment: public(Bytes[32]) @@ -170,9 +170,7 @@ def code_runtime() -> Bytes[32]: return slice(self.code, 0, 32) """ contract = get_contract(code) - code_compiled = compiler.compile_code( - code, output_formats=["bytecode", "bytecode_runtime"], settings=compiler_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] diff --git a/tests/functional/syntax/test_codehash.py b/tests/functional/syntax/test_codehash.py index abfa1cd8a3..b2463025c2 100644 --- a/tests/functional/syntax/test_codehash.py +++ b/tests/functional/syntax/test_codehash.py @@ -2,7 +2,7 @@ from vyper.utils import keccak256 -def test_get_extcodehash(get_contract, compiler_settings): +def test_get_extcodehash(get_contract): code = """ a: address @@ -27,7 +27,7 @@ def foo3() -> bytes32: def foo4() -> bytes32: return self.a.codehash """ - compiled = compile_code(code, output_formats=["bytecode_runtime"], settings=compiler_settings) + compiled = compile_code(code, output_formats=["bytecode_runtime"]) bytecode = bytes.fromhex(compiled["bytecode_runtime"][2:]) hash_ = keccak256(bytecode) diff --git a/tests/unit/compiler/test_source_map.py b/tests/unit/compiler/test_source_map.py index 6b91c2790a..3e1b62362b 100644 --- a/tests/unit/compiler/test_source_map.py +++ b/tests/unit/compiler/test_source_map.py @@ -37,7 +37,10 @@ def test_jump_map(optimize): pos_map = source_map["pc_pos_map"] jump_map = source_map["pc_jump_map"] - expected_jumps = 3 if optimize == OptimizationLevel.NONE else 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 From ffc3a387d28ae18878ac9139b7e886f88102d452 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 1 May 2024 15:26:47 +0200 Subject: [PATCH 78/87] Update pyrevm, rename execute_code to message_call --- setup.py | 2 +- tests/evm_backends/abi_contract.py | 4 ++-- tests/evm_backends/base_env.py | 8 ++------ tests/evm_backends/pyevm_env.py | 2 +- tests/evm_backends/revm_env.py | 2 +- .../builtins/codegen/test_create_functions.py | 8 +++++--- tests/functional/builtins/codegen/test_raw_call.py | 2 +- .../calling_convention/test_default_function.py | 14 +++++++------- .../calling_convention/test_default_parameters.py | 4 ++-- .../test_external_contract_calls.py | 10 +++++----- .../codegen/calling_convention/test_return.py | 2 +- .../environment_variables/test_blobbasefee.py | 2 +- .../codegen/features/decorators/test_payable.py | 12 ++++++------ .../codegen/features/decorators/test_private.py | 2 +- .../codegen/features/test_address_balance.py | 2 +- tests/functional/codegen/features/test_clampers.py | 6 +++--- .../codegen/features/test_constructor.py | 6 +++--- tests/functional/codegen/modules/test_exports.py | 4 ++-- tests/functional/codegen/test_selector_table.py | 12 ++++++------ tests/functional/examples/wallet/test_wallet.py | 4 ++-- tests/functional/syntax/test_self_balance.py | 2 +- 21 files changed, 54 insertions(+), 56 deletions(-) diff --git a/setup.py b/setup.py index b14846567c..6e48129cba 100644 --- a/setup.py +++ b/setup.py @@ -21,7 +21,7 @@ "eth-account==0.12.2", "setuptools", "hexbytes>=1.2", - "pyrevm @ git+https://github.com/DanielSchiavini/pyrevm.git@b1a6f63", + "pyrevm>=0.3.2", ], "lint": [ "black==23.12.0", diff --git a/tests/evm_backends/abi_contract.py b/tests/evm_backends/abi_contract.py index c242e94e41..56bcf7099f 100644 --- a/tests/evm_backends/abi_contract.py +++ b/tests/evm_backends/abi_contract.py @@ -204,7 +204,7 @@ def __call__(self, *args, value=0, gas=None, gas_price=0, sender=None, **kwargs) if sender is None: sender = self.contract.env.deployer - computation = self.contract.env.execute_code( + computation = self.contract.env.message_call( to=self.contract.address, sender=sender, data=self.prepare_calldata(*args, **kwargs), @@ -339,7 +339,7 @@ def method_id_map(self): 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 `execute_code` + :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)})" diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index 61aa12e7c0..ffcf834635 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -70,11 +70,7 @@ def deploy(self, abi: list[dict], bytecode: bytes, value=0, *args, **kwargs): ctor = ABIFunction(ctor_abi, contract_name=factory._name) initcode += ctor.prepare_calldata(*args, **kwargs) - try: - deployed_at = self._deploy(initcode, value) - except RuntimeError as e: - raise EvmError(*e.args) from e - + deployed_at = self._deploy(initcode, value) address = to_checksum_address(deployed_at) return factory.at(self, address) @@ -163,7 +159,7 @@ def timestamp(self, value: int): def last_result(self) -> ExecutionResult: raise NotImplementedError # must be implemented by subclasses - def execute_code( + def message_call( self, to: str, sender: str | None = None, diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index 945ddb0fd7..61907f9315 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -113,7 +113,7 @@ def last_result(self) -> ExecutionResult: gas_used=result.get_gas_used(), ) - def execute_code( + def message_call( self, to: str, sender: str | None = None, diff --git a/tests/evm_backends/revm_env.py b/tests/evm_backends/revm_env.py index 31b52aaaa2..d19565b75c 100644 --- a/tests/evm_backends/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -80,7 +80,7 @@ def last_result(self) -> ExecutionResult: logs=result.logs, ) - def execute_code( + def message_call( self, to: str, sender: str | None = None, diff --git a/tests/functional/builtins/codegen/test_create_functions.py b/tests/functional/builtins/codegen/test_create_functions.py index 9677b99aab..14d81bbd13 100644 --- a/tests/functional/builtins/codegen/test_create_functions.py +++ b/tests/functional/builtins/codegen/test_create_functions.py @@ -176,6 +176,8 @@ 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 = env.get_code(foo_contract.address) + f, FooContract = deploy_blueprint_for(code, initcode_prefix=blueprint_prefix) d = get_contract(deployer_code) @@ -183,7 +185,7 @@ def test2(target: address, salt: bytes32): d.test(f.address) test = FooContract(d.created_address()) - assert env.get_code(test.address) == env.get_code(foo_contract.address) + assert env.get_code(test.address) == expected_runtime_code assert test.foo() == 123 # extcodesize check @@ -196,7 +198,7 @@ def test2(target: address, salt: bytes32): d.test2(f.address, salt) test = FooContract(d.created_address()) - assert env.get_code(test.address) == env.get_code(foo_contract.address) + assert env.get_code(test.address) == expected_runtime_code assert test.foo() == 123 # check if the create2 address matches our offchain calculation @@ -436,7 +438,7 @@ 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(): - env.execute_code(d.address, env.deployer, f"{sig}{encoded}") + env.message_call(d.address, env.deployer, f"{sig}{encoded}") @pytest.mark.parametrize("revert_on_failure", [True, False, None]) diff --git a/tests/functional/builtins/codegen/test_raw_call.py b/tests/functional/builtins/codegen/test_raw_call.py index 5fa71fa7e8..5defb72706 100644 --- a/tests/functional/builtins/codegen/test_raw_call.py +++ b/tests/functional/builtins/codegen/test_raw_call.py @@ -260,7 +260,7 @@ def __default__(): # manually construct msg.data for `caller` contract sig = keccak("foo()".encode()).hex()[:10] - assert env.execute_code(caller.address, data=sig) == b"" + assert env.message_call(caller.address, data=sig) == b"" # check max_outsize=0 does same thing as not setting max_outsize. diff --git a/tests/functional/codegen/calling_convention/test_default_function.py b/tests/functional/codegen/calling_convention/test_default_function.py index af2fdc8041..709f28cfe5 100644 --- a/tests/functional/codegen/calling_convention/test_default_function.py +++ b/tests/functional/codegen/calling_convention/test_default_function.py @@ -14,7 +14,7 @@ def __init__(): assert c.x() == 123 assert env.get_balance(c.address) == 0 with tx_failed(): - env.execute_code(c.address, value=to_wei(0.1, "ether")) # call default function + env.message_call(c.address, value=to_wei(0.1, "ether")) # call default function assert env.get_balance(c.address) == 0 @@ -30,7 +30,7 @@ def __default__(): """ c = get_contract(code) env.set_balance(env.deployer, 10**18) - env.execute_code(c.address, value=10**17) # call default function + env.message_call(c.address, value=10**17) # 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") @@ -54,7 +54,7 @@ def __default__(): """ c = get_contract(code) env.set_balance(env.deployer, 10**18) - env.execute_code(c.address, value=10**17) # call default function + env.message_call(c.address, value=10**17) # 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") @@ -72,7 +72,7 @@ def __default__(): c = get_contract(code) with tx_failed(): - env.execute_code(c.address, value=10**17) # call default function + env.message_call(c.address, value=10**17) # call default function def test_multi_arg_default(assert_compile_failed, get_contract): @@ -130,7 +130,7 @@ def __default__(): def _call_with_bytes(hexstr): # call our special contract and return the logged value data = bytes.fromhex(hexstr.removeprefix("0x")) - env.execute_code(c.address, value=0, data=data) # call default function + env.message_call(c.address, value=0, data=data) # call default function (log,) = get_logs(c, "Sent") return log.args.sig @@ -176,7 +176,7 @@ def __default__(): def _call_with_bytes(hexstr): # call our special contract and return the logged value data = bytes.fromhex(hexstr.removeprefix("0x")) - env.execute_code(c.address, value=0, data=data, gas=10**6) # call default function + env.message_call(c.address, value=0, data=data, gas=10**6) # call default function (log,) = get_logs(c, "Sent") return log.args.sig @@ -217,7 +217,7 @@ def __default__(): def _call_with_bytes(hexstr): # call our special contract and return the logged value data = bytes.fromhex(hexstr.removeprefix("0x")) - env.execute_code(c.address, value=0, data=data) # call default function + env.message_call(c.address, value=0, data=data) # call default function (log,) = get_logs(c, "Sent") return log.args.sig diff --git a/tests/functional/codegen/calling_convention/test_default_parameters.py b/tests/functional/codegen/calling_convention/test_default_parameters.py index 5a50453a34..5e73e007db 100644 --- a/tests/functional/codegen/calling_convention/test_default_parameters.py +++ b/tests/functional/codegen/calling_convention/test_default_parameters.py @@ -200,9 +200,9 @@ def bar(a: int128, b: int128 = -1) -> (int128, int128): # noqa: E501 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") - assert env.execute_code(c.address, data=method + good_data) == good_data + assert env.message_call(c.address, data=method + good_data) == good_data with tx_failed(): - env.execute_code(c.address, data=method + bad_data) + env.message_call(c.address, data=method + bad_data) def test_default_param_private(get_contract): 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 23786695c7..6ec431f072 100644 --- a/tests/functional/codegen/calling_convention/test_external_contract_calls.py +++ b/tests/functional/codegen/calling_convention/test_external_contract_calls.py @@ -2502,13 +2502,13 @@ def foo(a: {typ}): # Static size is short by 1 byte malformed = data[:-2] with tx_failed(): - env.execute_code(c1.address, data=malformed) + env.message_call(c1.address, data=malformed) # Static size is exact - env.execute_code(c1.address, data=data) + env.message_call(c1.address, data=data) # Static size exceeds by 1 byte, ok - env.execute_code(c1.address, data=data + "ff") + env.message_call(c1.address, data=data + "ff") @pytest.mark.parametrize("typ,val", [("address", ([TEST_ADDR] * 3, "vyper"))]) @@ -2527,8 +2527,8 @@ def foo(a: DynArray[{typ}, 3], b: String[5]): # Dynamic size is short by 1 byte malformed = data[:264] with tx_failed(): - env.execute_code(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] - env.execute_code(c1.address, data=valid) + env.message_call(c1.address, data=valid) diff --git a/tests/functional/codegen/calling_convention/test_return.py b/tests/functional/codegen/calling_convention/test_return.py index 059cfdbf1a..97ac627483 100644 --- a/tests/functional/codegen/calling_convention/test_return.py +++ b/tests/functional/codegen/calling_convention/test_return.py @@ -19,7 +19,7 @@ def hardtest(arg1: Bytes[64], arg2: Bytes[64]) -> Bytes[128]: assert c.hardtest(b"hello" * 5, b"hello" * 10) == b"hello" * 15 # Make sure underlying struct is correctly right padded - res = env.execute_code( + 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") diff --git a/tests/functional/codegen/environment_variables/test_blobbasefee.py b/tests/functional/codegen/environment_variables/test_blobbasefee.py index 4440f665ac..d4cc5c58a8 100644 --- a/tests/functional/codegen/environment_variables/test_blobbasefee.py +++ b/tests/functional/codegen/environment_variables/test_blobbasefee.py @@ -25,7 +25,7 @@ def get_blobbasefee() -> uint256: blob_data = text.rjust(32 * 4096) blob_hashes = [kzg_hash(blob_data)] * 6 - env.execute_code( + env.message_call( "0xb45BEc6eeCA2a09f4689Dd308F550Ad7855051B5", # random address gas=21000, gas_price=10**10, diff --git a/tests/functional/codegen/features/decorators/test_payable.py b/tests/functional/codegen/features/decorators/test_payable.py index aaf8b3af73..e5157f5050 100644 --- a/tests/functional/codegen/features/decorators/test_payable.py +++ b/tests/functional/codegen/features/decorators/test_payable.py @@ -186,7 +186,7 @@ def test_nonpayable_runtime_assertion(env, keccak, tx_failed, get_contract, code c.foo(value=0) sig = keccak("foo()".encode()).hex()[:10] with tx_failed(): - env.execute_code(c.address, data=sig, value=10**18) + env.message_call(c.address, data=sig, value=10**18) payable_code = [ @@ -354,7 +354,7 @@ def __default__(): """ c = get_contract(code) env.set_balance(env.deployer, 100) - env.execute_code(c.address, value=100, data="0x12345678") + env.message_call(c.address, value=100, data="0x12345678") def test_nonpayable_default_func_invalid_calldata(get_contract, env, tx_failed): @@ -370,9 +370,9 @@ def __default__(): """ c = get_contract(code) - env.execute_code(c.address, value=0, data="0x12345678") + env.message_call(c.address, value=0, data="0x12345678") with tx_failed(): - env.execute_code(c.address, value=100, data="0x12345678") + env.message_call(c.address, value=100, data="0x12345678") def test_batch_nonpayable(get_contract, env, tx_failed): @@ -387,9 +387,9 @@ def __default__(): """ c = get_contract(code) - env.execute_code(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(): - env.execute_code(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 031a190560..d313aa3bda 100644 --- a/tests/functional/codegen/features/decorators/test_private.py +++ b/tests/functional/codegen/features/decorators/test_private.py @@ -409,7 +409,7 @@ def __default__(): c = get_contract(code) env.set_balance(env.deployer, to_wei(1, "ether")) - env.execute_code(c.address, value=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")) diff --git a/tests/functional/codegen/features/test_address_balance.py b/tests/functional/codegen/features/test_address_balance.py index 75cd6578fc..7777802405 100644 --- a/tests/functional/codegen/features/test_address_balance.py +++ b/tests/functional/codegen/features/test_address_balance.py @@ -14,6 +14,6 @@ def foo() -> uint256: assert c.foo() == 0 env.set_balance(env.deployer, 1337) - env.execute_code(address, value=1337) + env.message_call(address, value=1337) assert c.foo() == 1337 diff --git a/tests/functional/codegen/features/test_clampers.py b/tests/functional/codegen/features/test_clampers.py index a3bb43022c..df9c480f49 100644 --- a/tests/functional/codegen/features/test_clampers.py +++ b/tests/functional/codegen/features/test_clampers.py @@ -13,14 +13,14 @@ def _make_tx(env, address, signature, values): # helper function to broadcast transactions that fail clamping check sig = keccak(signature.encode()).hex()[:8] data = "".join(int(i).to_bytes(32, "big", signed=i < 0).hex() for i in values) - env.execute_code(address, data=f"0x{sig}{data}") + env.message_call(address, data=f"0x{sig}{data}") 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() - env.execute_code(address, data=f"0x{sig}{data}") + env.message_call(address, data=f"0x{sig}{data}") def _make_dynarray_data(offset, length, values): @@ -31,7 +31,7 @@ def _make_dynarray_data(offset, length, values): def _make_invalid_dynarray_tx(env, address, signature, data): sig = keccak(signature.encode()).hex()[:8] - env.execute_code(address, data=f"0x{sig}{data}") + env.message_call(address, data=f"0x{sig}{data}") def test_bytes_clamper(tx_failed, get_contract): diff --git a/tests/functional/codegen/features/test_constructor.py b/tests/functional/codegen/features/test_constructor.py index d9334bc036..18b0d180ac 100644 --- a/tests/functional/codegen/features/test_constructor.py +++ b/tests/functional/codegen/features/test_constructor.py @@ -84,11 +84,11 @@ def foo(x: int128) -> int128: signature = "(int128)" method = method_id(f"foo{signature}") - env.execute_code(c.address, data=method + (1274124).to_bytes(32, "big")) - env.execute_code(c.address, data=method + (2**120).to_bytes(32, "big")) + 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.execute_code(c.address, data=method + (2**130).to_bytes(32, "big")) + env.message_call(c.address, data=method + (2**130).to_bytes(32, "big")) def test_large_input_code_2(env, get_contract, tx_failed, output_formats, compiler_settings): diff --git a/tests/functional/codegen/modules/test_exports.py b/tests/functional/codegen/modules/test_exports.py index 878fafa998..93f4fe6c2f 100644 --- a/tests/functional/codegen/modules/test_exports.py +++ b/tests/functional/codegen/modules/test_exports.py @@ -202,7 +202,7 @@ def send_failing_tx_to_signature(env, tx_failed): def _send_transaction(c, method_sig): data = method_id(method_sig) with tx_failed(): - env.execute_code(c.address, data=data) + env.message_call(c.address, data=data) return _send_transaction @@ -438,5 +438,5 @@ def __init__(): assert c.foo() == 1 assert c.counter() == 5 # call `c.__default__()` - env.execute_code(c.address) + env.message_call(c.address) assert c.counter() == 6 diff --git a/tests/functional/codegen/test_selector_table.py b/tests/functional/codegen/test_selector_table.py index 438f5f5344..d01dbc8981 100644 --- a/tests/functional/codegen/test_selector_table.py +++ b/tests/functional/codegen/test_selector_table.py @@ -599,7 +599,7 @@ def __default__(): else: hexstr = (method_id + argsdata).hex() with tx_failed(): - env.execute_code(c.address, data=hexstr, value=1) + env.message_call(c.address, data=hexstr, value=1) # now do calldatasize check # strip some bytes @@ -610,15 +610,15 @@ def __default__(): # no args, hit default function if default_fn_mutability == "": with tx_failed(): - env.execute_code(**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 - env.execute_code(**tx_params) + env.message_call(**tx_params) logs = get_logs(c, "CalledDefault") assert len(logs) == 1 else: - env.execute_code(**tx_params) + env.message_call(**tx_params) # note: can't emit logs from view/pure functions, # so the logging is not tested. @@ -629,9 +629,9 @@ def __default__(): # check default function reverts tx_params["value"] = 1 with tx_failed(): - env.execute_code(**tx_params) + env.message_call(**tx_params) else: with tx_failed(): - env.execute_code(**tx_params) + env.message_call(**tx_params) _test() diff --git a/tests/functional/examples/wallet/test_wallet.py b/tests/functional/examples/wallet/test_wallet.py index 85176109ae..c639974a31 100644 --- a/tests/functional/examples/wallet/test_wallet.py +++ b/tests/functional/examples/wallet/test_wallet.py @@ -15,7 +15,7 @@ def c(env, get_contract): # Sends wei to the contract for future transactions gas costs c = get_contract(code, *[[a1, a2, a3, a4, a5], 3]) env.set_balance(a0, 10**17) - env.execute_code(c.address, value=10**17) + env.message_call(c.address, value=10**17) return c @@ -111,7 +111,7 @@ def test_javascript_signatures(env, get_contract, keccak): x2 = get_contract(f.read(), *[owners, 2]) env.set_balance(env.deployer, 10**18) - env.execute_code(x2.address, value=10**17) + 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 diff --git a/tests/functional/syntax/test_self_balance.py b/tests/functional/syntax/test_self_balance.py index 91af631d2b..0da491b262 100644 --- a/tests/functional/syntax/test_self_balance.py +++ b/tests/functional/syntax/test_self_balance.py @@ -19,7 +19,7 @@ def __default__(): c = get_contract(code) env.set_balance(env.deployer, 1337) - env.execute_code(c.address, value=1337) + env.message_call(c.address, value=1337) assert c.get_balance() == 1337 assert env.get_balance(c.address) == 1337 From 3f60720d6f21206994e3288f76416aedae7d719a Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 1 May 2024 15:45:40 +0200 Subject: [PATCH 79/87] Inline kzg_hash and get_log_args, extra assert --- tests/evm_backends/base_env.py | 8 -------- .../environment_variables/test_blobbasefee.py | 10 ++++------ tests/functional/examples/tokens/test_erc20.py | 15 +++++---------- tests/unit/compiler/test_source_map.py | 2 ++ 4 files changed, 11 insertions(+), 24 deletions(-) diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index ffcf834635..b96a28fff1 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -3,9 +3,6 @@ from dataclasses import dataclass from typing import Callable, Optional -from ckzg import blob_to_kzg_commitment, load_trusted_setup -from eth.precompiles.point_evaluation import kzg_to_versioned_hash -from eth_account._utils.typed_transactions.base import TRUSTED_SETUP from eth_keys.datatypes import PrivateKey from eth_utils import to_checksum_address @@ -218,8 +215,3 @@ def _compile( 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")) - - -def kzg_hash(blob: bytes) -> bytes: - commitment = blob_to_kzg_commitment(blob, load_trusted_setup(TRUSTED_SETUP)) - return kzg_to_versioned_hash(commitment) diff --git a/tests/functional/codegen/environment_variables/test_blobbasefee.py b/tests/functional/codegen/environment_variables/test_blobbasefee.py index d4cc5c58a8..3da5c686b6 100644 --- a/tests/functional/codegen/environment_variables/test_blobbasefee.py +++ b/tests/functional/codegen/environment_variables/test_blobbasefee.py @@ -2,8 +2,6 @@ from eth.vm.forks.cancun.constants import BLOB_BASE_FEE_UPDATE_FRACTION, MIN_BLOB_BASE_FEE from eth.vm.forks.cancun.state import fake_exponential -from tests.evm_backends.base_env import kzg_hash - @pytest.mark.requires_evm_version("cancun") def test_blobbasefee(env, get_contract): @@ -20,10 +18,10 @@ def get_blobbasefee() -> uint256: env.set_balance(env.deployer, 10**20) env.set_excess_blob_gas(10**6) - text = b"Vyper is the language of the sneks" - # Blobs contain 4096 32-byte field elements. - blob_data = text.rjust(32 * 4096) - blob_hashes = [kzg_hash(blob_data)] * 6 + # kzg_hash(b"Vyper is the language of the sneks") + blob_hashes = [ + (bytes.fromhex("015a5c97e3cc516f22a95faf7eefff00eb2fee7a65037fde07ac5446fc93f2a0")) + ] * 6 env.message_call( "0xb45BEc6eeCA2a09f4689Dd308F550Ad7855051B5", # random address diff --git a/tests/functional/examples/tokens/test_erc20.py b/tests/functional/examples/tokens/test_erc20.py index 60fe5267a0..7cf1fe57ef 100644 --- a/tests/functional/examples/tokens/test_erc20.py +++ b/tests/functional/examples/tokens/test_erc20.py @@ -14,7 +14,7 @@ @pytest.fixture -def c(get_contract, env): +def c(get_contract): with open("examples/tokens/ERC20.vy") as f: code = f.read() return get_contract(code, *[TOKEN_NAME, TOKEN_SYMBOL, TOKEN_DECIMALS, TOKEN_INITIAL_SUPPLY]) @@ -31,14 +31,6 @@ def c_bad(get_contract): return get_contract(bad_code, *[TOKEN_NAME, TOKEN_SYMBOL, TOKEN_DECIMALS, TOKEN_INITIAL_SUPPLY]) -@pytest.fixture -def get_log_args(get_logs): - def get_log_args(_, c, event_name): - return get_logs(c, event_name)[0].args - - return get_log_args - - def test_initial_state(c, env): a1, a2, a3 = env.accounts[1:4] # Check total supply, name, symbol and decimals are correctly set @@ -271,9 +263,12 @@ def test_burnFrom_and_Allowance(c, env, tx_failed): c.burnFrom(ZERO_ADDRESS, 0, sender=a1) -def test_raw_logs(c, env, get_log_args): +def test_raw_logs(c, env, get_logs): minter, a1, a2, a3 = env.accounts[0:4] + def get_log_args(result, c, event_name): + return get_logs(result, c, event_name)[0].args + # Check that mint appropriately emits Transfer event args = get_log_args(c.mint(a1, 2, sender=minter), c, "Transfer") assert args.sender == ZERO_ADDRESS diff --git a/tests/unit/compiler/test_source_map.py b/tests/unit/compiler/test_source_map.py index 3e1b62362b..e4d5e69770 100644 --- a/tests/unit/compiler/test_source_map.py +++ b/tests/unit/compiler/test_source_map.py @@ -47,12 +47,14 @@ def test_jump_map(optimize): 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.") From d6f93330a5feaaa525c69700ad3800c875a1372a Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 1 May 2024 15:53:45 +0200 Subject: [PATCH 80/87] Add empty data when calling default function --- .../calling_convention/test_default_function.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/functional/codegen/calling_convention/test_default_function.py b/tests/functional/codegen/calling_convention/test_default_function.py index 709f28cfe5..2e22bc855d 100644 --- a/tests/functional/codegen/calling_convention/test_default_function.py +++ b/tests/functional/codegen/calling_convention/test_default_function.py @@ -14,7 +14,7 @@ def __init__(): assert c.x() == 123 assert env.get_balance(c.address) == 0 with tx_failed(): - env.message_call(c.address, value=to_wei(0.1, "ether")) # call default function + env.message_call(c.address, value=to_wei(0.1, "ether"), data=b"") # call default function assert env.get_balance(c.address) == 0 @@ -30,7 +30,7 @@ def __default__(): """ c = get_contract(code) env.set_balance(env.deployer, 10**18) - env.message_call(c.address, value=10**17) # call default function + 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") @@ -54,7 +54,7 @@ def __default__(): """ c = get_contract(code) env.set_balance(env.deployer, 10**18) - env.message_call(c.address, value=10**17) # call default function + 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") @@ -72,7 +72,7 @@ def __default__(): c = get_contract(code) with tx_failed(): - env.message_call(c.address, value=10**17) # call default function + env.message_call(c.address, value=10**17, data=b"") # call default function def test_multi_arg_default(assert_compile_failed, get_contract): @@ -130,7 +130,7 @@ def __default__(): def _call_with_bytes(hexstr): # call our special contract and return the logged value data = bytes.fromhex(hexstr.removeprefix("0x")) - env.message_call(c.address, value=0, data=data) # call default function + env.message_call(c.address, value=0, data=data) (log,) = get_logs(c, "Sent") return log.args.sig @@ -176,7 +176,7 @@ def __default__(): def _call_with_bytes(hexstr): # call our special contract and return the logged value data = bytes.fromhex(hexstr.removeprefix("0x")) - env.message_call(c.address, value=0, data=data, gas=10**6) # call default function + env.message_call(c.address, value=0, data=data, gas=10**6) (log,) = get_logs(c, "Sent") return log.args.sig @@ -217,7 +217,7 @@ def __default__(): def _call_with_bytes(hexstr): # call our special contract and return the logged value data = bytes.fromhex(hexstr.removeprefix("0x")) - env.message_call(c.address, value=0, data=data) # call default function + env.message_call(c.address, value=0, data=data) (log,) = get_logs(c, "Sent") return log.args.sig From 4c8e5d77034646bbac88c7e002c55fab336539a4 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 1 May 2024 16:01:20 +0200 Subject: [PATCH 81/87] Remove anchors --- .../calling_convention/test_external_contract_calls.py | 5 ----- 1 file changed, 5 deletions(-) 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 6ec431f072..10e2f55e28 100644 --- a/tests/functional/codegen/calling_convention/test_external_contract_calls.py +++ b/tests/functional/codegen/calling_convention/test_external_contract_calls.py @@ -1393,8 +1393,6 @@ def get_lucky(amount_to_send: uint256) -> int128: # Send some eth env.set_balance(env.deployer, 10000) - with env.anchor(): # anchor to check if the transaction is cancelled - assert c2.get_lucky(0, value=500) == 1 c2.get_lucky(0, value=500) # Contract 1 received money. @@ -1403,10 +1401,7 @@ def get_lucky(amount_to_send: uint256) -> int128: assert env.get_balance(c2.address) == 0 # Send subset of amount - with env.anchor(): # anchor to check if the transaction is cancelled - assert c2.get_lucky(250, value=500) == 1 c2.get_lucky(250, value=500) - # Contract 1 received more money. assert c1.get_balance() == 750 assert env.get_balance(c1.address) == 750 From 789f5a48afb4f7d15431784851498bf785992c36 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 1 May 2024 16:20:10 +0200 Subject: [PATCH 82/87] Review comments --- .../calling_convention/test_external_contract_calls.py | 4 ++-- tests/functional/codegen/calling_convention/test_return.py | 1 - .../codegen/environment_variables/test_block_number.py | 2 +- tests/functional/codegen/features/test_clampers.py | 1 - 4 files changed, 3 insertions(+), 5 deletions(-) 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 10e2f55e28..0b1969df7d 100644 --- a/tests/functional/codegen/calling_convention/test_external_contract_calls.py +++ b/tests/functional/codegen/calling_convention/test_external_contract_calls.py @@ -1394,14 +1394,14 @@ def get_lucky(amount_to_send: uint256) -> int128: # Send some eth env.set_balance(env.deployer, 10000) - c2.get_lucky(0, value=500) + assert c2.get_lucky(0, value=500) == 1 # Contract 1 received money. assert c1.get_balance() == 500 assert env.get_balance(c1.address) == 500 assert env.get_balance(c2.address) == 0 # Send subset of amount - c2.get_lucky(250, value=500) + assert c2.get_lucky(250, value=500) == 1 # Contract 1 received more money. assert c1.get_balance() == 750 assert env.get_balance(c1.address) == 750 diff --git a/tests/functional/codegen/calling_convention/test_return.py b/tests/functional/codegen/calling_convention/test_return.py index 97ac627483..6c7c0aeec5 100644 --- a/tests/functional/codegen/calling_convention/test_return.py +++ b/tests/functional/codegen/calling_convention/test_return.py @@ -18,7 +18,6 @@ def hardtest(arg1: Bytes[64], arg2: Bytes[64]) -> Bytes[128]: assert c.hardtest(b"hello" * 5, b"hello" * 10) == b"hello" * 15 - # Make sure underlying struct is correctly right padded res = env.message_call( to=c.address, data=c.hardtest.prepare_calldata(b"hello" * 5, b"hello" * 10) ) diff --git a/tests/functional/codegen/environment_variables/test_block_number.py b/tests/functional/codegen/environment_variables/test_block_number.py index f4a854d59f..c963e2e175 100644 --- a/tests/functional/codegen/environment_variables/test_block_number.py +++ b/tests/functional/codegen/environment_variables/test_block_number.py @@ -1,4 +1,4 @@ -def test_block_number(get_contract, env, compiler_settings, output_formats): +def test_block_number(get_contract, env): block_number_code = """ @external def block_number() -> uint256: diff --git a/tests/functional/codegen/features/test_clampers.py b/tests/functional/codegen/features/test_clampers.py index df9c480f49..b3abd206de 100644 --- a/tests/functional/codegen/features/test_clampers.py +++ b/tests/functional/codegen/features/test_clampers.py @@ -10,7 +10,6 @@ def _make_tx(env, address, signature, values): - # helper function to broadcast transactions that fail clamping check sig = keccak(signature.encode()).hex()[:8] data = "".join(int(i).to_bytes(32, "big", signed=i < 0).hex() for i in values) env.message_call(address, data=f"0x{sig}{data}") From cdc65aa5f07e05a5ccaf5036dc1f12936cb8ac6d Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 1 May 2024 16:28:20 +0200 Subject: [PATCH 83/87] Review comments --- tests/conftest.py | 8 ++++---- tests/functional/codegen/features/test_clampers.py | 2 +- tests/functional/codegen/features/test_logging.py | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index bed8f90e1a..366b339ae5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -109,20 +109,20 @@ def _xfail(*args, **kwargs): return _xfail -@pytest.fixture(scope="session", autouse=True) +@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", autouse=True) +@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", autouse=True) +@pytest.fixture(scope="session") def tracing(pytestconfig): return pytestconfig.getoption("tracing") @@ -320,7 +320,7 @@ def assert_side_effects_invoked(side_effects_contract, side_effects_trigger, n=1 def tx_failed(env): @contextmanager def fn(exception=EvmError, exc_text=None): - with env.anchor(), pytest.raises(exception) as excinfo: + with pytest.raises(exception) as excinfo: yield if exc_text: diff --git a/tests/functional/codegen/features/test_clampers.py b/tests/functional/codegen/features/test_clampers.py index b3abd206de..5a44d0d24d 100644 --- a/tests/functional/codegen/features/test_clampers.py +++ b/tests/functional/codegen/features/test_clampers.py @@ -119,8 +119,8 @@ 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(env, c.address, f"foo(bytes{n})", [int_value]) diff --git a/tests/functional/codegen/features/test_logging.py b/tests/functional/codegen/features/test_logging.py index 6925351bb9..fef9f50763 100644 --- a/tests/functional/codegen/features/test_logging.py +++ b/tests/functional/codegen/features/test_logging.py @@ -437,7 +437,7 @@ def foo(): # Event is decoded correctly (log,) = get_logs(c, "MyLog") assert log.args.arg1 == 1 - assert log.args.arg2.removesuffix(b"\0") == b"bar" + assert log.args.arg2 == b"bar" def test_event_logging_with_multiple_logs_topics_and_data(env, keccak, get_logs, get_contract): From 545317c4d8d0a2c15e7d61e3213564024a957cb9 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 1 May 2024 16:52:08 +0200 Subject: [PATCH 84/87] Review comments --- tests/conftest.py | 17 +++++---------- tests/evm_backends/abi_contract.py | 15 ------------- tests/evm_backends/base_env.py | 21 +++++++++---------- .../codegen/features/test_constructor.py | 4 ++-- .../codegen/features/test_transient.py | 17 +++++++++++++++ .../functional/examples/tokens/test_erc20.py | 4 ++-- 6 files changed, 36 insertions(+), 42 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 366b339ae5..5ae24f032d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -230,26 +230,19 @@ def compiler_settings(optimize, experimental_codegen, evm_version, debug): @pytest.fixture(scope="module") def get_contract(env, optimize, output_formats, compiler_settings): def fn(source_code, *args, **kwargs): - settings = kwargs.pop("compiler_settings", compiler_settings) if "override_opt_level" in kwargs: - settings = Settings( - **dict(settings.__dict__, optimize=kwargs.pop("override_opt_level")) + kwargs["compiler_settings"] = Settings( + **dict(compiler_settings.__dict__, optimize=kwargs.pop("override_opt_level")) ) - set_global_settings(settings) - return env.deploy_source(source_code, output_formats, settings, *args, **kwargs) + return env.deploy_source(source_code, output_formats, *args, **kwargs) return fn @pytest.fixture(scope="module") -def deploy_blueprint_for(env, compiler_settings, output_formats): +def deploy_blueprint_for(env, output_formats): def fn(source_code, *args, **kwargs): - settings = kwargs.pop("compiler_settings", compiler_settings) - if "override_opt_level" in kwargs: - settings = Settings( - **dict(settings.__dict__, optimize=kwargs.pop("override_opt_level")) - ) - return env.deploy_blueprint(source_code, output_formats, settings, *args, **kwargs) + return env.deploy_blueprint(source_code, output_formats, *args, **kwargs) return fn diff --git a/tests/evm_backends/abi_contract.py b/tests/evm_backends/abi_contract.py index 56bcf7099f..d9cc6cb481 100644 --- a/tests/evm_backends/abi_contract.py +++ b/tests/evm_backends/abi_contract.py @@ -328,14 +328,6 @@ def __init__( self._address = address - @cached_property - def method_id_map(self): - """ - Returns a mapping from method id to function object. - This is used to create the stack trace when an error occurs. - """ - return {function.method_id: function for function in self._functions} - def marshal_to_python(self, result: bytes, abi_type: list[str]) -> list[Any]: """ Convert the output of a contract call to a Python object. @@ -345,13 +337,6 @@ def marshal_to_python(self, result: bytes, abi_type: list[str]) -> list[Any]: schema = f"({_format_abi_type(abi_type)})" return abi_decode(schema, result) - @property - def deployer(self) -> "ABIContractFactory": - """ - Returns a factory that can be used to retrieve another deployed contract. - """ - return ABIContractFactory(self._name, self.abi, self._functions, self.log_topics) - 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!)" diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index b96a28fff1..1d12d4850a 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -9,7 +9,7 @@ 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, Settings, compile_code +from vyper.compiler import CompilerData, InputBundle, Settings, compile_code from vyper.utils import ERC5202_PREFIX, method_id @@ -75,27 +75,26 @@ def deploy_source( self, source_code: str, output_formats: dict[str, Callable[[CompilerData], str]], - compiler_settings: Settings, *args, - input_bundle=None, - value=0, + 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, compiler_settings, input_bundle) + 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, - compiler_settings: Settings, *args, - input_bundle=None, - initcode_prefix=ERC5202_PREFIX, + input_bundle: InputBundle = None, + initcode_prefix: bytes = ERC5202_PREFIX, ): """Deploy a contract with a blueprint pattern.""" - abi, bytecode = _compile(source_code, output_formats, compiler_settings, input_bundle) + 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") @@ -201,8 +200,8 @@ def _parse_revert(output_bytes: bytes, error: Exception, gas_used: int): def _compile( source_code: str, output_formats: dict[str, Callable[[CompilerData], str]], - settings: Settings, - input_bundle=None, + input_bundle: InputBundle = None, + settings: Settings = None, ) -> tuple[list[dict], bytes]: out = compile_code( source_code, diff --git a/tests/functional/codegen/features/test_constructor.py b/tests/functional/codegen/features/test_constructor.py index 18b0d180ac..6cc7007bb2 100644 --- a/tests/functional/codegen/features/test_constructor.py +++ b/tests/functional/codegen/features/test_constructor.py @@ -91,7 +91,7 @@ def foo(x: int128) -> int128: env.message_call(c.address, data=method + (2**130).to_bytes(32, "big")) -def test_large_input_code_2(env, get_contract, tx_failed, output_formats, compiler_settings): +def test_large_input_code_2(env, get_contract, tx_failed, output_formats): code = """ @deploy def __init__(x: int128): @@ -102,7 +102,7 @@ def foo() -> int128: return 5 """ - _, bytecode = _compile(code, output_formats, compiler_settings) + _, bytecode = _compile(code, output_formats) ctor_args = (2**127 - 1).to_bytes(32, "big") env._deploy(bytecode + ctor_args, value=0) diff --git a/tests/functional/codegen/features/test_transient.py b/tests/functional/codegen/features/test_transient.py index 36c4303b9c..2532def85b 100644 --- a/tests/functional/codegen/features/test_transient.py +++ b/tests/functional/codegen/features/test_transient.py @@ -71,9 +71,11 @@ def foo(a: {typ}) -> {typ}: 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 @@ -99,6 +101,7 @@ def a1() -> uint256: c = get_contract(code, val) assert c.a() == val env.clear_transient_storage() + assert c.a1() == 0 @@ -127,6 +130,7 @@ def foo(_a: uint256, _b: address, _c: String[64]) -> (uint256, address, String[6 c = get_contract(code) assert c.foo(*values) == values env.clear_transient_storage() + assert c.a() == 0 assert c.b() == ZERO_ADDRESS assert c.c() == "" @@ -158,6 +162,7 @@ def foo(_a: uint256, _b: uint256, _c: address, _d: int256) -> MyStruct: c = get_contract(code) assert c.foo(*values) == values env.clear_transient_storage() + assert c.my_struct() == (0, 0, ZERO_ADDRESS, 0) assert c.foo(*values) == values @@ -188,6 +193,7 @@ def foo(_a: address, _b: MyStruct2, _c: DynArray[DynArray[uint256, 3], 3]) -> My c = get_contract(code) assert c.foo(*values) == values env.clear_transient_storage() + assert c.my_struct() == (ZERO_ADDRESS, ([],), []) assert c.foo(*values) == values @@ -212,6 +218,7 @@ 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,) @@ -230,6 +237,7 @@ 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) @@ -278,6 +286,7 @@ def do_side_effects(): assert c.my_res(i)[0] == i assert c.my_map(i)[0] == 0 env.clear_transient_storage() + for j in range(3): assert c.my_res(i)[1][j] == i + j assert c.my_map(i)[1] == [] @@ -302,10 +311,12 @@ 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) @@ -379,14 +390,17 @@ 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) @@ -413,6 +427,7 @@ 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 @@ -440,6 +455,7 @@ def b(): c = get_contract(code) assert c.d() == 2 env.clear_transient_storage() + assert c.x() == 0 @@ -475,6 +491,7 @@ 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 diff --git a/tests/functional/examples/tokens/test_erc20.py b/tests/functional/examples/tokens/test_erc20.py index 7cf1fe57ef..aef43768cb 100644 --- a/tests/functional/examples/tokens/test_erc20.py +++ b/tests/functional/examples/tokens/test_erc20.py @@ -266,8 +266,8 @@ def test_burnFrom_and_Allowance(c, env, tx_failed): def test_raw_logs(c, env, get_logs): minter, a1, a2, a3 = env.accounts[0:4] - def get_log_args(result, c, event_name): - return get_logs(result, c, event_name)[0].args + 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, sender=minter), c, "Transfer") From c8aad5a8629d64469d59efc4aabf766a7dd83249 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 1 May 2024 17:03:42 +0200 Subject: [PATCH 85/87] Review comments --- tests/conftest.py | 2 ++ tests/evm_backends/pyevm_env.py | 6 +++--- tests/evm_backends/revm_env.py | 6 +++--- tests/functional/codegen/features/test_clampers.py | 1 + 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 5ae24f032d..2b645fc50d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -242,6 +242,7 @@ def fn(source_code, *args, **kwargs): @pytest.fixture(scope="module") 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 fn @@ -309,6 +310,7 @@ def assert_side_effects_invoked(side_effects_contract, side_effects_trigger, n=1 return assert_side_effects_invoked +# should probably be renamed since there is no longer a transaction object @pytest.fixture(scope="module") def tx_failed(env): @contextmanager diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index 61907f9315..3fabd24ac2 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -32,9 +32,9 @@ def __init__( self, gas_limit: int, account_keys: list[PrivateKey], - tracing=False, - block_number=1, - evm_version="mainnet", + tracing: bool, + block_number: int, + evm_version: str, ) -> None: super().__init__(gas_limit, account_keys) diff --git a/tests/evm_backends/revm_env.py b/tests/evm_backends/revm_env.py index d19565b75c..29481813df 100644 --- a/tests/evm_backends/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -15,9 +15,9 @@ def __init__( self, gas_limit: int, account_keys: list[PrivateKey], - tracing=False, - block_number=1, - evm_version="latest", + tracing: bool, + block_number: int, + evm_version: str, ) -> None: super().__init__(gas_limit, account_keys) self._evm = EVM( diff --git a/tests/functional/codegen/features/test_clampers.py b/tests/functional/codegen/features/test_clampers.py index 5a44d0d24d..1adffcf29a 100644 --- a/tests/functional/codegen/features/test_clampers.py +++ b/tests/functional/codegen/features/test_clampers.py @@ -10,6 +10,7 @@ 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) env.message_call(address, data=f"0x{sig}{data}") From 40a47e558c91651b425152f6e354261b278ffaeb Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 1 May 2024 21:45:42 +0200 Subject: [PATCH 86/87] Review comments --- tests/evm_backends/base_env.py | 17 ++++------------- tests/evm_backends/pyevm_env.py | 7 ++----- tests/evm_backends/revm_env.py | 7 ++----- .../auctions/test_simple_open_auction.py | 4 +--- .../market_maker/test_on_chain_market_maker.py | 2 +- 5 files changed, 10 insertions(+), 27 deletions(-) diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index 1d12d4850a..4e5188f88a 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -48,15 +48,6 @@ def __init__(self, gas_limit: int, account_keys: list[PrivateKey]) -> None: self._keys = account_keys self.deployer: str = self._keys[0].public_key.to_checksum_address() - @contextmanager - def sender(self, address: str): - original_deployer = self.deployer - self.deployer = address - try: - yield - finally: - self.deployer = original_deployer - 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) @@ -121,6 +112,10 @@ def get_logs(self, contract: ABIContract, event_name: str = None, raw=False): 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 @@ -131,10 +126,6 @@ def get_balance(self, address: str) -> int: def set_balance(self, address: str, value: int): raise NotImplementedError # must be implemented by subclasses - @property - def accounts(self) -> list[str]: - raise NotImplementedError # must be implemented by subclasses - @property def block_number(self) -> int: raise NotImplementedError # must be implemented by subclasses diff --git a/tests/evm_backends/pyevm_env.py b/tests/evm_backends/pyevm_env.py index 3fabd24ac2..fa960867c9 100644 --- a/tests/evm_backends/pyevm_env.py +++ b/tests/evm_backends/pyevm_env.py @@ -83,10 +83,6 @@ def get_balance(self, address: str) -> int: def set_balance(self, address: str, value: int): self._state.set_balance(_addr(address), value) - @property - def accounts(self) -> list[str]: - return [key.public_key.to_checksum_address() for key in self._keys] - @property def block_number(self) -> int: return self._context.block_number @@ -124,7 +120,8 @@ def message_call( is_modifying: bool = True, blob_hashes: Optional[list[bytes]] = None, # for blobbasefee >= Cancun ): - data = data if isinstance(data, bytes) else bytes.fromhex(data.removeprefix("0x")) + if isinstance(data, str): + data = bytes.fromhex(data.removeprefix("0x")) sender = _addr(sender or self.deployer) try: computation = self._state.computation_class.apply_message( diff --git a/tests/evm_backends/revm_env.py b/tests/evm_backends/revm_env.py index 29481813df..de75fd4f7d 100644 --- a/tests/evm_backends/revm_env.py +++ b/tests/evm_backends/revm_env.py @@ -46,10 +46,6 @@ def get_balance(self, address: str) -> int: def set_balance(self, address: str, value: int): self._evm.set_balance(address, value) - @property - def accounts(self) -> list[str]: - return [key.public_key.to_checksum_address() for key in self._keys] - @property def block_number(self) -> int: return self._evm.env.block.number @@ -91,7 +87,8 @@ def message_call( is_modifying: bool = True, blob_hashes: Optional[list[bytes]] = None, # for blobbasefee >= Cancun ): - data = data if isinstance(data, bytes) else bytes.fromhex(data.removeprefix("0x")) + 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 diff --git a/tests/functional/examples/auctions/test_simple_open_auction.py b/tests/functional/examples/auctions/test_simple_open_auction.py index f0bc8f2de9..430294fa79 100644 --- a/tests/functional/examples/auctions/test_simple_open_auction.py +++ b/tests/functional/examples/auctions/test_simple_open_auction.py @@ -18,6 +18,7 @@ def auction_contract(env, get_contract, auction_start): 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]) @@ -40,7 +41,6 @@ def test_initial_state(env, auction_contract, auction_start): def test_bid(env, auction_contract, tx_failed): k1, k2, k3, k4, k5 = env.accounts[:5] - env.timestamp += 1 # make sure auction has started # Bidder cannot bid 0 with tx_failed(): @@ -85,8 +85,6 @@ def test_bid(env, auction_contract, tx_failed): def test_end_auction(env, auction_contract, tx_failed): k1, k2, k3, k4, k5 = env.accounts[:5] - env.timestamp += 1 # make sure auction has started - # Fails if auction end time has not been reached with tx_failed(): auction_contract.endAuction() 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 1c99e8021a..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 @@ -36,8 +36,8 @@ def test_initial_state(market_maker): def test_initiate(env, market_maker, erc20, tx_failed): a0 = env.accounts[0] - env.set_balance(a0, to_wei(2, "ether")) 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 From 3bb3fbb6ec7042c645bf29f2bdb607c2db0cc7cd Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Wed, 1 May 2024 21:51:49 +0200 Subject: [PATCH 87/87] New exception type --- tests/evm_backends/base_env.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/evm_backends/base_env.py b/tests/evm_backends/base_env.py index 4e5188f88a..9d7548e037 100644 --- a/tests/evm_backends/base_env.py +++ b/tests/evm_backends/base_env.py @@ -31,7 +31,11 @@ class ExecutionResult: class EvmError(RuntimeError): - """Exception raised when a transaction reverts.""" + """Exception raised when a call fails.""" + + +class ExecutionReverted(EvmError): + """Exception raised when a call reverts.""" class BaseEnv: @@ -179,13 +183,11 @@ def _parse_revert(output_bytes: bytes, error: Exception, gas_used: int): """ Tries to parse the EIP-838 revert reason from the output bytes. """ - # REVIEW: not sure the prefix is needed - prefix = "execution reverted" if output_bytes[:4] == method_id("Error(string)"): (msg,) = abi_decode("(string)", output_bytes[4:]) - raise EvmError(f"{prefix}: {msg}", gas_used) from error + raise ExecutionReverted(f"{msg}", gas_used) from error - raise EvmError(f"{prefix}: 0x{output_bytes.hex()}", gas_used) from error + raise ExecutionReverted(f"0x{output_bytes.hex()}", gas_used) from error def _compile(