diff --git a/src/ape/exceptions.py b/src/ape/exceptions.py index aabdc51ae3..7ac9d177b7 100644 --- a/src/ape/exceptions.py +++ b/src/ape/exceptions.py @@ -8,16 +8,15 @@ from inspect import getframeinfo, stack from pathlib import Path from types import CodeType, TracebackType -from typing import TYPE_CHECKING, Any, Callable, Optional, Union, cast +from typing import TYPE_CHECKING, Any, Callable, Optional, Union import click -from eth_typing import Hash32, HexStr -from eth_utils import humanize_hash, to_hex from rich import print as rich_print from ape.logging import LogLevel, logger if TYPE_CHECKING: + from eth_typing import HexStr from ethpm_types.abi import ConstructorABI, ErrorABI, MethodABI from ethpm_types.contract_type import ContractType @@ -521,9 +520,11 @@ class BlockNotFoundError(ProviderError): def __init__(self, block_id: "BlockID", reason: Optional[str] = None): if isinstance(block_id, bytes): - block_id_str = to_hex(block_id) + block_id_str = block_id.hex() + if not block_id_str.startswith("0x"): + block_id_str = f"0x{block_id_str}" else: - block_id_str = HexStr(str(block_id)) + block_id_str: "HexStr" = f"{block_id}" # type: ignore message = ( "Missing latest block." @@ -621,11 +622,26 @@ class UnknownSnapshotError(ChainError): """ def __init__(self, snapshot_id: "SnapshotID"): + snapshot_id_str: str if isinstance(snapshot_id, bytes): - # Is block hash - snapshot_id = humanize_hash(cast(Hash32, snapshot_id)) + # Is block hash. Logic borrowed from `eth_utils.humanize_hash()`. + if len(snapshot_id) <= 5: + snapshot_id_str = snapshot_id.hex() + else: + value_hex = snapshot_id.hex() + head = value_hex[:4] + tail_idx = -1 * 4 + tail = value_hex[tail_idx:] + snapshot_id_str = f"{head}..{tail}" + + snapshot_id_str = ( + f"0x{snapshot_id_str}" if not snapshot_id_str.startswith("0x") else snapshot_id_str + ) + + else: + snapshot_id_str = f"{snapshot_id}" # type: ignore - super().__init__(f"Unknown snapshot ID '{snapshot_id}'.") + super().__init__(f"Unknown snapshot ID '{snapshot_id_str}'.") class QueryEngineError(ApeException): diff --git a/src/ape/managers/config.py b/src/ape/managers/config.py index 92d94bf53a..f96ad38ec6 100644 --- a/src/ape/managers/config.py +++ b/src/ape/managers/config.py @@ -16,7 +16,7 @@ ) from ape.utils.misc import log_instead_of_fail from ape.utils.os import create_tempdir, in_tempdir -from ape.utils.rpc import RPCHeaders +from ape.utils.rpc import USER_AGENT, RPCHeaders if TYPE_CHECKING: from ethpm_types import PackageManifest @@ -39,6 +39,10 @@ def __init__(self, data_folder: Optional[Path] = None, request_header: Optional[ else: self.DATA_FOLDER = data_folder or Path.home() / ".ape" + request_header = request_header or { + "User-Agent": USER_AGENT, + "Content-Type": "application/json", + } self.REQUEST_HEADER = request_header or {} def __ape_extra_attributes__(self): diff --git a/src/ape/utils/basemodel.py b/src/ape/utils/basemodel.py index ba92547759..3d80bf1e48 100644 --- a/src/ape/utils/basemodel.py +++ b/src/ape/utils/basemodel.py @@ -17,7 +17,6 @@ from ape.exceptions import ApeAttributeError, ApeIndexError, ProviderNotConnectedError from ape.logging import logger from ape.utils.misc import log_instead_of_fail, raises_not_implemented -from ape.utils.rpc import USER_AGENT if TYPE_CHECKING: from pydantic.main import Model @@ -173,9 +172,7 @@ def config_manager(cls) -> "ConfigManager": The :class:`~ape.managers.config.ConfigManager`. """ config = import_module("ape.managers.config") - return config.ConfigManager( - request_header={"User-Agent": USER_AGENT, "Content-Type": "application/json"}, - ) + return config.ConfigManager() @manager_access def conversion_manager(cls) -> "ConversionManager": diff --git a/src/ape_ethereum/ecosystem.py b/src/ape_ethereum/ecosystem.py index 115f30e793..50bf9cee65 100644 --- a/src/ape_ethereum/ecosystem.py +++ b/src/ape_ethereum/ecosystem.py @@ -518,18 +518,16 @@ def str_to_slot(text): return ProxyInfo(type=_type, target=target) # safe >=1.1.0 provides `masterCopy()`, which is also stored in slot 0 - # detect safe-specific bytecode of push32 keccak256("masterCopy()") - safe_pattern = b"\x7f" + keccak(text="masterCopy()")[:4] + bytes(28) - if to_hex(safe_pattern) in code: - try: - singleton = ContractCall(MASTER_COPY_ABI, address)(skip_trace=True) - slot_0 = self.provider.get_storage(address, 0) - target = self.conversion_manager.convert(slot_0[-20:], AddressType) - # NOTE: `target` is set in initialized proxies - if target != ZERO_ADDRESS and target == singleton: - return ProxyInfo(type=ProxyType.GnosisSafe, target=target) - except ApeException: - pass + # call it and check that target matches + try: + singleton = ContractCall(MASTER_COPY_ABI, address)(skip_trace=True) + slot_0 = self.provider.get_storage(address, 0) + target = self.conversion_manager.convert(slot_0[-20:], AddressType) + # NOTE: `target` is set in initialized proxies + if target != ZERO_ADDRESS and target == singleton: + return ProxyInfo(type=ProxyType.GnosisSafe, target=target) + except ApeException: + pass # eip-897 delegate proxy, read `proxyType()` and `implementation()` # perf: only make a call when a proxyType() selector is mentioned in the code diff --git a/tests/functional/data/contracts/ethereum/local/BeaconProxy.json b/tests/functional/data/contracts/ethereum/local/BeaconProxy.json index 39a7f1dd2a..de72b26aaa 100644 --- a/tests/functional/data/contracts/ethereum/local/BeaconProxy.json +++ b/tests/functional/data/contracts/ethereum/local/BeaconProxy.json @@ -1 +1,137 @@ -{"abi":[{"inputs":[{"internalType":"address","name":"beacon","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"stateMutability":"payable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"stateMutability":"payable","type":"fallback"},{"stateMutability":"payable","type":"receive"}],"ast":{"ast_type":"SourceUnit","children":[{"ast_type":"PragmaDirective","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":23,"start":97}},{"ast_type":"ImportDirective","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":23,"start":122}},{"ast_type":"ImportDirective","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":22,"start":146}},{"ast_type":"ImportDirective","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":39,"start":169}},{"ast_type":"ContractDefinition","children":[{"ast_type":"InheritanceSpecifier","children":[{"ast_type":"IdentifierPath","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"Proxy","src":{"contract_id":167,"jump_code":"","length":5,"start":588}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":5,"start":588}},{"ast_type":"InheritanceSpecifier","children":[{"ast_type":"IdentifierPath","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"ERC1967Upgrade","src":{"contract_id":167,"jump_code":"","length":14,"start":595}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":14,"start":595}},{"ast_type":"StructuredDocumentation","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":353,"start":210}},{"ast_type":"FunctionDefinition","children":[{"ast_type":"Block","children":[{"ast_type":"ExpressionStatement","children":[{"ast_type":"FunctionCall","children":[{"ast_type":"BinaryOperation","children":[{"ast_type":"Identifier","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"_BEACON_SLOT","src":{"contract_id":167,"jump_code":"","length":12,"start":1118}},{"ast_type":"FunctionCall","children":[{"ast_type":"BinaryOperation","children":[{"ast_type":"FunctionCall","children":[{"ast_type":"FunctionCall","children":[{"ast_type":"Literal","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":22,"start":1160}},{"ast_type":"Identifier","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"keccak256","src":{"contract_id":167,"jump_code":"","length":9,"start":1150}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":33,"start":1150}},{"ast_type":"ElementaryTypeNameExpression","children":[{"ast_type":"ElementaryTypeName","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"uint256","src":{"contract_id":167,"jump_code":"","length":7,"start":1142}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":7,"start":1142}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":42,"start":1142}},{"ast_type":"Literal","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":1,"start":1187}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":46,"start":1142}},{"ast_type":"ElementaryTypeNameExpression","children":[{"ast_type":"ElementaryTypeName","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"bytes32","src":{"contract_id":167,"jump_code":"","length":7,"start":1134}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":7,"start":1134}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":55,"start":1134}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":71,"start":1118}},{"ast_type":"Identifier","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"assert","src":{"contract_id":167,"jump_code":"","length":6,"start":1111}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":79,"start":1111}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":79,"start":1111}},{"ast_type":"ExpressionStatement","children":[{"ast_type":"FunctionCall","children":[{"ast_type":"Identifier","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"beacon","src":{"contract_id":167,"jump_code":"","length":6,"start":1224}},{"ast_type":"Identifier","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"data","src":{"contract_id":167,"jump_code":"","length":4,"start":1232}},{"ast_type":"Literal","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":5,"start":1238}},{"ast_type":"Identifier","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"_upgradeBeaconToAndCall","src":{"contract_id":167,"jump_code":"","length":23,"start":1200}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":44,"start":1200}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":44,"start":1200}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":150,"start":1101}},{"ast_type":"StructuredDocumentation","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":425,"start":616}},{"ast_type":"ParameterList","children":[{"ast_type":"VariableDeclaration","children":[{"ast_type":"ElementaryTypeName","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"address","src":{"contract_id":167,"jump_code":"","length":7,"start":1058}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"beacon","src":{"contract_id":167,"jump_code":"","length":14,"start":1058}},{"ast_type":"VariableDeclaration","children":[{"ast_type":"ElementaryTypeName","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"bytes","src":{"contract_id":167,"jump_code":"","length":5,"start":1074}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"data","src":{"contract_id":167,"jump_code":"","length":17,"start":1074}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":35,"start":1057}},{"ast_type":"ParameterList","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","start":1101}}],"classification":1,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"","src":{"contract_id":167,"jump_code":"","length":205,"start":1046}},{"ast_type":"FunctionDefinition","children":[{"ast_type":"Block","children":[{"ast_type":"Return","children":[{"ast_type":"FunctionCall","children":[{"ast_type":"Identifier","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"_getBeacon","src":{"contract_id":167,"jump_code":"","length":10,"start":1397}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":12,"start":1397}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":19,"start":1390}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":36,"start":1380}},{"ast_type":"StructuredDocumentation","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":59,"start":1257}},{"ast_type":"ParameterList","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":2,"start":1337}},{"ast_type":"ParameterList","children":[{"ast_type":"VariableDeclaration","children":[{"ast_type":"ElementaryTypeName","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"address","src":{"contract_id":167,"jump_code":"","length":7,"start":1371}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"","src":{"contract_id":167,"jump_code":"","length":7,"start":1371}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":9,"start":1370}}],"classification":1,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"_beacon","src":{"contract_id":167,"jump_code":"","length":95,"start":1321}},{"ast_type":"FunctionDefinition","children":[{"ast_type":"Block","children":[{"ast_type":"Return","children":[{"ast_type":"FunctionCall","children":[{"ast_type":"MemberAccess","children":[{"ast_type":"FunctionCall","children":[{"ast_type":"FunctionCall","children":[{"ast_type":"Identifier","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"_getBeacon","src":{"contract_id":167,"jump_code":"","length":10,"start":1620}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":12,"start":1620}},{"ast_type":"Identifier","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"IBeacon","src":{"contract_id":167,"jump_code":"","length":7,"start":1612}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":21,"start":1612}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":36,"start":1612}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":38,"start":1612}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":45,"start":1605}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":62,"start":1595}},{"ast_type":"StructuredDocumentation","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":92,"start":1422}},{"ast_type":"OverrideSpecifier","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":8,"start":1568}},{"ast_type":"ParameterList","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":2,"start":1543}},{"ast_type":"ParameterList","children":[{"ast_type":"VariableDeclaration","children":[{"ast_type":"ElementaryTypeName","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"address","src":{"contract_id":167,"jump_code":"","length":7,"start":1586}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"","src":{"contract_id":167,"jump_code":"","length":7,"start":1586}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":9,"start":1585}}],"classification":1,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"_implementation","src":{"contract_id":167,"jump_code":"","length":138,"start":1519}},{"ast_type":"FunctionDefinition","children":[{"ast_type":"Block","children":[{"ast_type":"ExpressionStatement","children":[{"ast_type":"FunctionCall","children":[{"ast_type":"Identifier","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"beacon","src":{"contract_id":167,"jump_code":"","length":6,"start":2141}},{"ast_type":"Identifier","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"data","src":{"contract_id":167,"jump_code":"","length":4,"start":2149}},{"ast_type":"Literal","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":5,"start":2155}},{"ast_type":"Identifier","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"_upgradeBeaconToAndCall","src":{"contract_id":167,"jump_code":"","length":23,"start":2117}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":44,"start":2117}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":44,"start":2117}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":61,"start":2107}},{"ast_type":"StructuredDocumentation","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":367,"start":1663}},{"ast_type":"ParameterList","children":[{"ast_type":"VariableDeclaration","children":[{"ast_type":"ElementaryTypeName","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"address","src":{"contract_id":167,"jump_code":"","length":7,"start":2055}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"beacon","src":{"contract_id":167,"jump_code":"","length":14,"start":2055}},{"ast_type":"VariableDeclaration","children":[{"ast_type":"ElementaryTypeName","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"bytes","src":{"contract_id":167,"jump_code":"","length":5,"start":2071}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"data","src":{"contract_id":167,"jump_code":"","length":17,"start":2071}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":35,"start":2054}},{"ast_type":"ParameterList","children":[],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","start":2107}}],"classification":1,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"_setBeacon","src":{"contract_id":167,"jump_code":"","length":133,"start":2035}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"name":"BeaconProxy","src":{"contract_id":167,"jump_code":"","length":1606,"start":564}}],"classification":0,"col_offset":-1,"end_col_offset":-1,"end_lineno":-1,"lineno":-1,"src":{"contract_id":167,"jump_code":"","length":2074,"start":97}},"contractName":"BeaconProxy","deploymentBytecode":{"bytecode":"0x608060405260405161074f38038061074f8339810160408190526100229161044c565b61004d60017fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5161050c565b600080516020610708833981519152146100695761006961052d565b6100758282600061007c565b50506105ad565b6100858361013d565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a26000825111806100c65750805b1561013857610136836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561010c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101309190610543565b836102af565b505b505050565b6001600160a01b0381163b6101a75760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b61021b816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061020c9190610543565b6001600160a01b03163b151590565b6102805760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b606482015260840161019e565b60008051602061070883398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b60606102d48383604051806060016040528060278152602001610728602791396102dd565b90505b92915050565b60606001600160a01b0384163b6103455760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840161019e565b600080856001600160a01b031685604051610360919061055e565b600060405180830381855af49150503d806000811461039b576040519150601f19603f3d011682016040523d82523d6000602084013e6103a0565b606091505b5090925090506103b18282866103bd565b925050505b9392505050565b606083156103cc5750816103b6565b8251156103dc5782518084602001fd5b8160405162461bcd60e51b815260040161019e919061057a565b80516001600160a01b038116811461040d57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561044357818101518382015260200161042b565b50506000910152565b6000806040838503121561045f57600080fd5b610468836103f6565b60208401519092506001600160401b038082111561048557600080fd5b818501915085601f83011261049957600080fd5b8151818111156104ab576104ab610412565b604051601f8201601f19908116603f011681019083821181831017156104d3576104d3610412565b816040528281528860208487010111156104ec57600080fd5b6104fd836020830160208801610428565b80955050505050509250929050565b818103818111156102d757634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b60006020828403121561055557600080fd5b6102d4826103f6565b60008251610570818460208701610428565b9190910192915050565b6020815260008251806020840152610599816040850160208701610428565b601f01601f19169190910160400192915050565b61014c806105bc6000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610029565b6100c2565b565b600061005c7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610099573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100bd91906100e6565b905090565b3660008037600080366000845af43d6000803e8080156100e1573d6000f35b3d6000fd5b6000602082840312156100f857600080fd5b81516001600160a01b038116811461010f57600080fd5b939250505056fea264697066735822122063db4d42188d1e6b6e228313c7b8d13c59cda8eaf494c66fdc23c60ba163181664736f6c63430008140033a3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564"},"devdoc":{"details":"This contract implements a proxy that gets the implementation address for each call from a {UpgradeableBeacon}. The beacon address is stored in storage slot `uint256(keccak256('eip1967.proxy.beacon')) - 1`, so that it doesn't conflict with the storage layout of the implementation behind the proxy. _Available since v3.4._","events":{"AdminChanged(address,address)":{"details":"Emitted when the admin account has changed."},"BeaconUpgraded(address)":{"details":"Emitted when the beacon is upgraded."},"Upgraded(address)":{"details":"Emitted when the implementation is upgraded."}},"kind":"dev","methods":{"constructor":{"details":"Initializes the proxy with `beacon`. If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This will typically be an encoded function call, and allows initializating the storage of the proxy like a Solidity constructor. Requirements: - `beacon` must be a contract with the interface {IBeacon}."}},"version":1},"runtimeBytecode":{"bytecode":"0x60806040523661001357610011610017565b005b6100115b610027610022610029565b6100c2565b565b600061005c7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610099573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100bd91906100e6565b905090565b3660008037600080366000845af43d6000803e8080156100e1573d6000f35b3d6000fd5b6000602082840312156100f857600080fd5b81516001600160a01b038116811461010f57600080fd5b939250505056fea264697066735822122063db4d42188d1e6b6e228313c7b8d13c59cda8eaf494c66fdc23c60ba163181664736f6c63430008140033"},"sourceId":"proxy/beacon/BeaconProxy.sol","sourcemap":"564:1606:167:-:0;;;1046:205;;;;;;;;;;;;;;;;;;:::i;:::-;1142:46;1187:1;1150:33;1142:46;:::i;:::-;-1:-1:-1;;;;;;;;;;;1118:71:167;1111:79;;;;:::i;:::-;1200:44;1224:6;1232:4;1238:5;1200:23;:44::i;:::-;1046:205;;564:1606;;6168:343:165;6304:21;6315:9;6304:10;:21::i;:::-;6340:25;;-1:-1:-1;;;;;6340:25:165;;;;;;;;6393:1;6379:4;:11;:15;:28;;;;6398:9;6379:28;6375:130;;;6423:71;6460:9;-1:-1:-1;;;;;6452:33:165;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6489:4;6423:28;:71::i;:::-;;6375:130;6168:343;;;:::o;5494:371::-;-1:-1:-1;;;;;1465:19:224;;;5551:79:165;;;;-1:-1:-1;;;5551:79:165;;2346:2:267;5551:79:165;;;2328:21:267;2385:2;2365:18;;;2358:30;2424:34;2404:18;;;2397:62;-1:-1:-1;;;2475:18:267;;;2468:35;2520:19;;5551:79:165;;;;;;;;;5661:55;5688:9;-1:-1:-1;;;;;5680:33:165;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;1465:19:224;;:23;;;1175:320;5661:55:165;5640:150;;;;-1:-1:-1;;;5640:150:165;;2752:2:267;5640:150:165;;;2734:21:267;2791:2;2771:18;;;2764:30;2830:34;2810:18;;;2803:62;-1:-1:-1;;;2881:18:267;;;2874:46;2937:19;;5640:150:165;2550:412:267;5640:150:165;-1:-1:-1;;;;;;;;;;;5800:58:165;;-1:-1:-1;;;;;;5800:58:165;-1:-1:-1;;;;;5800:58:165;;;;;;;;;;5494:371::o;6570:198:224:-;6653:12;6684:77;6705:6;6713:4;6684:77;;;;;;;;;;;;;;;;;:20;:77::i;:::-;6677:84;;6570:198;;;;;:::o;6954:387::-;7095:12;-1:-1:-1;;;;;1465:19:224;;;7119:69;;;;-1:-1:-1;;;7119:69:224;;3169:2:267;7119:69:224;;;3151:21:267;3208:2;3188:18;;;3181:30;3247:34;3227:18;;;3220:62;-1:-1:-1;;;3298:18:267;;;3291:36;3344:19;;7119:69:224;2967:402:267;7119:69:224;7200:12;7214:23;7241:6;-1:-1:-1;;;;;7241:19:224;7261:4;7241:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7199:67:224;;-1:-1:-1;7199:67:224;-1:-1:-1;7283:51:224;7199:67;;7321:12;7283:16;:51::i;:::-;7276:58;;;;6954:387;;;;;;:::o;7561:692::-;7707:12;7735:7;7731:516;;;-1:-1:-1;7765:10:224;7758:17;;7731:516;7876:17;;:21;7872:365;;8070:10;8064:17;8130:15;8117:10;8113:2;8109:19;8102:44;7872:365;8209:12;8202:20;;-1:-1:-1;;;8202:20:224;;;;;;;;:::i;14:177:267:-;93:13;;-1:-1:-1;;;;;135:31:267;;125:42;;115:70;;181:1;178;171:12;115:70;14:177;;;:::o;196:127::-;257:10;252:3;248:20;245:1;238:31;288:4;285:1;278:15;312:4;309:1;302:15;328:250;413:1;423:113;437:6;434:1;431:13;423:113;;;513:11;;;507:18;494:11;;;487:39;459:2;452:10;423:113;;;-1:-1:-1;;570:1:267;552:16;;545:27;328:250::o;583:981::-;671:6;679;732:2;720:9;711:7;707:23;703:32;700:52;;;748:1;745;738:12;700:52;771:40;801:9;771:40;:::i;:::-;855:2;840:18;;834:25;761:50;;-1:-1:-1;;;;;;908:14:267;;;905:34;;;935:1;932;925:12;905:34;973:6;962:9;958:22;948:32;;1018:7;1011:4;1007:2;1003:13;999:27;989:55;;1040:1;1037;1030:12;989:55;1069:2;1063:9;1091:2;1087;1084:10;1081:36;;;1097:18;;:::i;:::-;1172:2;1166:9;1140:2;1226:13;;-1:-1:-1;;1222:22:267;;;1246:2;1218:31;1214:40;1202:53;;;1270:18;;;1290:22;;;1267:46;1264:72;;;1316:18;;:::i;:::-;1356:10;1352:2;1345:22;1391:2;1383:6;1376:18;1431:7;1426:2;1421;1417;1413:11;1409:20;1406:33;1403:53;;;1452:1;1449;1442:12;1403:53;1465:68;1530:2;1525;1517:6;1513:15;1508:2;1504;1500:11;1465:68;:::i;:::-;1552:6;1542:16;;;;;;;583:981;;;;;:::o;1569:225::-;1636:9;;;1657:11;;;1654:134;;;1710:10;1705:3;1701:20;1698:1;1691:31;1745:4;1742:1;1735:15;1773:4;1770:1;1763:15;1799:127;1860:10;1855:3;1851:20;1848:1;1841:31;1891:4;1888:1;1881:15;1915:4;1912:1;1905:15;1931:208;2001:6;2054:2;2042:9;2033:7;2029:23;2025:32;2022:52;;;2070:1;2067;2060:12;2022:52;2093:40;2123:9;2093:40;:::i;3374:287::-;3503:3;3541:6;3535:13;3557:66;3616:6;3611:3;3604:4;3596:6;3592:17;3557:66;:::i;:::-;3639:16;;;;;3374:287;-1:-1:-1;;3374:287:267:o;3666:396::-;3815:2;3804:9;3797:21;3778:4;3847:6;3841:13;3890:6;3885:2;3874:9;3870:18;3863:34;3906:79;3978:6;3973:2;3962:9;3958:18;3953:2;3945:6;3941:15;3906:79;:::i;:::-;4046:2;4025:15;-1:-1:-1;;4021:29:267;4006:45;;;;4053:2;4002:54;;3666:396;-1:-1:-1;;3666:396:267:o;:::-;564:1606:167;;;;;;","userdoc":{"kind":"user","methods":{},"version":1}} +{ + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "beacon", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "ERC1967InvalidBeacon", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "ERC1967InvalidImplementation", + "type": "error" + }, + { + "inputs": [], + "name": "ERC1967NonPayable", + "type": "error" + }, + { + "inputs": [], + "name": "FailedCall", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + } + ], + "contractName": "BeaconProxy", + "deploymentBytecode": { + "bytecode": "0x60a060405260405161057738038061057783398101604081905261002291610354565b61002c828261003e565b506001600160a01b0316608052610445565b610047826100fb565b6040516001600160a01b038316907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e905f90a28051156100ef576100ea826001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100e49190610416565b82610209565b505050565b6100f761027c565b5050565b806001600160a01b03163b5f0361013557604051631933b43b60e21b81526001600160a01b03821660048201526024015b60405180910390fd5b807fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5080546001600160a01b0319166001600160a01b0392831617905560408051635c60da1b60e01b815290515f92841691635c60da1b9160048083019260209291908290030181865afa1580156101ae573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101d29190610416565b9050806001600160a01b03163b5f036100f757604051634c9c8ce360e01b81526001600160a01b038216600482015260240161012c565b60605f5f846001600160a01b031684604051610225919061042f565b5f60405180830381855af49150503d805f811461025d576040519150601f19603f3d011682016040523d82523d5f602084013e610262565b606091505b50909250905061027385838361029d565b95945050505050565b341561029b5760405163b398979f60e01b815260040160405180910390fd5b565b6060826102b2576102ad826102fc565b6102f5565b81511580156102c957506001600160a01b0384163b155b156102f257604051639996b31560e01b81526001600160a01b038516600482015260240161012c565b50805b9392505050565b80511561030c5780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b80516001600160a01b038116811461033b575f5ffd5b919050565b634e487b7160e01b5f52604160045260245ffd5b5f5f60408385031215610365575f5ffd5b61036e83610325565b60208401519092506001600160401b03811115610389575f5ffd5b8301601f81018513610399575f5ffd5b80516001600160401b038111156103b2576103b2610340565b604051601f8201601f19908116603f011681016001600160401b03811182821017156103e0576103e0610340565b6040528181528282016020018710156103f7575f5ffd5b8160208401602083015e5f602083830101528093505050509250929050565b5f60208284031215610426575f5ffd5b6102f582610325565b5f82518060208501845e5f920191825250919050565b60805161011b61045c5f395f601d015261011b5ff3fe6080604052600a600c565b005b60186014601a565b609d565b565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156076573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906098919060ba565b905090565b365f5f375f5f365f845af43d5f5f3e80801560b6573d5ff35b3d5ffd5b5f6020828403121560c9575f5ffd5b81516001600160a01b038116811460de575f5ffd5b939250505056fea26469706673582212202d07d0101b6d159b30713ba046f5650ac1a0e2bbd87cc2d5f82d5a7b663cd8e364736f6c634300081c0033" + }, + "devdoc": { + "details": "This contract implements a proxy that gets the implementation address for each call from an {UpgradeableBeacon}. The beacon address can only be set once during construction, and cannot be changed afterwards. It is stored in an immutable variable to avoid unnecessary storage reads, and also in the beacon storage slot specified by https://eips.ethereum.org/EIPS/eip-1967[ERC-1967] so that it can be accessed externally. CAUTION: Since the beacon address can never be changed, you must ensure that you either control the beacon, or trust the beacon to not upgrade the implementation maliciously. IMPORTANT: Do not use the implementation logic to modify the beacon storage slot. Doing so would leave the proxy in an inconsistent state where the beacon storage slot does not match the beacon address.", + "errors": { + "AddressEmptyCode(address)": [ + { + "details": "There's no code at `target` (it is not a contract)." + } + ], + "ERC1967InvalidBeacon(address)": [ + { + "details": "The `beacon` of the proxy is invalid." + } + ], + "ERC1967InvalidImplementation(address)": [ + { + "details": "The `implementation` of the proxy is invalid." + } + ], + "ERC1967NonPayable()": [ + { + "details": "An upgrade function sees `msg.value > 0` that may be lost." + } + ], + "FailedCall()": [ + { + "details": "A call to an address target failed. The target may have reverted." + } + ] + }, + "events": { + "BeaconUpgraded(address)": { + "details": "Emitted when the beacon is changed." + } + }, + "kind": "dev", + "methods": { + "constructor": { + "details": "Initializes the proxy with `beacon`. If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity constructor. Requirements: - `beacon` must be a contract with the interface {IBeacon}. - If `data` is empty, `msg.value` must be zero." + } + }, + "version": 1 + }, + "methodIdentifiers": {}, + "runtimeBytecode": { + "bytecode": "0x6080604052600a600c565b005b60186014601a565b609d565b565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156076573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906098919060ba565b905090565b365f5f375f5f365f845af43d5f5f3e80801560b6573d5ff35b3d5ffd5b5f6020828403121560c9575f5ffd5b81516001600160a01b038116811460de575f5ffd5b939250505056fea26469706673582212202d07d0101b6d159b30713ba046f5650ac1a0e2bbd87cc2d5f82d5a7b663cd8e364736f6c634300081c0033" + }, + "sourceId": "tests/functional/data/sources/BeaconProxy.sol", + "sourcemap": "21764:1194:0:-:0;;;22421:147;;;;;;;;;;;;;;;;;;:::i;:::-;22486:49;22522:6;22530:4;22486:35;:49::i;:::-;-1:-1:-1;;;;;;22545:16:0;;;21764:1194;;20140:342;20229:21;20240:9;20229:10;:21::i;:::-;20265:34;;-1:-1:-1;;;;;20265:34:0;;;;;;;;20314:11;;:15;20310:166;;20345:71;20382:9;-1:-1:-1;;;;;20374:33:0;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20411:4;20345:28;:71::i;:::-;;20140:342;;:::o;20310:166::-;20447:18;:16;:18::i;:::-;20140:342;;:::o;19178:437::-;19239:9;-1:-1:-1;;;;;19239:21:0;;19264:1;19239:26;19235:95;;19288:31;;-1:-1:-1;;;19288:31:0;;-1:-1:-1;;;;;1729:32:1;;19288:31:0;;;1711:51:1;1684:18;;19288:31:0;;;;;;;;19235:95;19388:9;18844:66;19340:57;;-1:-1:-1;;;;;;19340:57:0;-1:-1:-1;;;;;19340:57:0;;;;;;19439:35;;;-1:-1:-1;;;19439:35:0;;;;-1:-1:-1;;19439:33:0;;;;;:35;;;;;;;;;;;;;;:33;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;19408:66;;19488:20;-1:-1:-1;;;;;19488:32:0;;19524:1;19488:37;19484:125;;19548:50;;-1:-1:-1;;;19548:50:0;;-1:-1:-1;;;;;1729:32:1;;19548:50:0;;;1711:51:1;1684:18;;19548:50:0;1565:203:1;12647:253:0;12730:12;12755;12769:23;12796:6;-1:-1:-1;;;;;12796:19:0;12816:4;12796:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12754:67:0;;-1:-1:-1;12754:67:0;-1:-1:-1;12838:55:0;12865:6;12754:67;;12838:26;:55::i;:::-;12831:62;12647:253;-1:-1:-1;;;;;12647:253:0:o;20671:122::-;20721:9;:13;20717:70;;20757:19;;-1:-1:-1;;;20757:19:0;;;;;;;;;;;20717:70;20671:122::o;13168:582::-;13312:12;13341:7;13336:408;;13364:19;13372:10;13364:7;:19::i;:::-;13336:408;;;13588:17;;:22;:49;;;;-1:-1:-1;;;;;;13614:18:0;;;:23;13588:49;13584:119;;;13664:24;;-1:-1:-1;;;13664:24:0;;-1:-1:-1;;;;;1729:32:1;;13664:24:0;;;1711:51:1;1684:18;;13664:24:0;1565:203:1;13584:119:0;-1:-1:-1;13723:10:0;13336:408;13168:582;;;;;:::o;14290:487::-;14421:17;;:21;14417:354;;14618:10;14612:17;14674:15;14661:10;14657:2;14653:19;14646:44;14417:354;14741:19;;-1:-1:-1;;;14741:19:0;;;;;;;;;;;14:177:1;93:13;;-1:-1:-1;;;;;135:31:1;;125:42;;115:70;;181:1;178;171:12;115:70;14:177;;;:::o;196:127::-;257:10;252:3;248:20;245:1;238:31;288:4;285:1;278:15;312:4;309:1;302:15;328:1019;416:6;424;477:2;465:9;456:7;452:23;448:32;445:52;;;493:1;490;483:12;445:52;516:40;546:9;516:40;:::i;:::-;600:2;585:18;;579:25;506:50;;-1:-1:-1;;;;;;616:30:1;;613:50;;;659:1;656;649:12;613:50;682:22;;735:4;727:13;;723:27;-1:-1:-1;713:55:1;;764:1;761;754:12;713:55;791:9;;-1:-1:-1;;;;;812:30:1;;809:56;;;845:18;;:::i;:::-;894:2;888:9;986:2;948:17;;-1:-1:-1;;944:31:1;;;977:2;940:40;936:54;924:67;;-1:-1:-1;;;;;1006:34:1;;1042:22;;;1003:62;1000:88;;;1068:18;;:::i;:::-;1104:2;1097:22;1128;;;1169:15;;;1186:2;1165:24;1162:37;-1:-1:-1;1159:57:1;;;1212:1;1209;1202:12;1159:57;1261:6;1256:2;1252;1248:11;1243:2;1235:6;1231:15;1225:43;1314:1;1309:2;1300:6;1292;1288:19;1284:28;1277:39;1335:6;1325:16;;;;;328:1019;;;;;:::o;1352:208::-;1422:6;1475:2;1463:9;1454:7;1450:23;1446:32;1443:52;;;1491:1;1488;1481:12;1443:52;1514:40;1544:9;1514:40;:::i;1773:301::-;1902:3;1940:6;1934:13;1986:6;1979:4;1971:6;1967:17;1962:3;1956:37;2048:1;2012:16;;2037:13;;;-1:-1:-1;2012:16:1;1773:301;-1:-1:-1;1773:301:1:o;:::-;21764:1194:0;;;;;;;;;;;;", + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + } +} diff --git a/tests/functional/data/contracts/ethereum/local/ERCProxy.json b/tests/functional/data/contracts/ethereum/local/ERCProxy.json new file mode 100644 index 0000000000..45d2266e9a --- /dev/null +++ b/tests/functional/data/contracts/ethereum/local/ERCProxy.json @@ -0,0 +1,57 @@ +{ + "abi": [ + { + "inputs": [], + "name": "proxyType", + "outputs": [ + { + "name": "proxyTypeId", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "name": "_target", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + } + ], + "contractName": "ERCProxy", + "deploymentBytecode": { + "bytecode": "0x608060405234801561001057600080fd5b5060405160208061014a833981016040525160008054600160a060020a03909216600160a060020a031990921691909117905560f9806100516000396000f30060806040526004361060485763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416634555d5c98114604d5780635c60da1b146071575b600080fd5b348015605857600080fd5b50605f60ac565b60408051918252519081900360200190f35b348015607c57600080fd5b50608360b1565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b600190565b60005473ffffffffffffffffffffffffffffffffffffffff16905600a165627a7a72305820ae971f5c593cbaf95a4ff9c244af7a9afd16cda9faff299ef9f50e1953626a340029" + }, + "devdoc": { + "methods": {} + }, + "methodIdentifiers": { + "implementation()": "0x5c60da1b", + "proxyType()": "0x4555d5c9" + }, + "runtimeBytecode": { + "bytecode": "0x60806040526004361060485763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416634555d5c98114604d5780635c60da1b146071575b600080fd5b348015605857600080fd5b50605f60ac565b60408051918252519081900360200190f35b348015607c57600080fd5b50608360b1565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b600190565b60005473ffffffffffffffffffffffffffffffffffffffff16905600a165627a7a72305820ae971f5c593cbaf95a4ff9c244af7a9afd16cda9faff299ef9f50e1953626a340029" + }, + "sourceId": "tests/functional/data/sources/DelegateProxy.sol", + "sourcemap": "27:278:0:-;;;77:56;8:9:-1;5:2;;;30:1;27;20:12;5:2;77:56:0;;;;;;;;;;;;;112:6;:16;;-1:-1:-1;;;;;112:16:0;;;-1:-1:-1;;;;;;112:16:0;;;;;;;;;27:278;;;;;;", + "userdoc": { + "methods": {} + } +} diff --git a/tests/functional/data/contracts/ethereum/local/MinimalProxyFactory.json b/tests/functional/data/contracts/ethereum/local/MinimalProxyFactory.json new file mode 100644 index 0000000000..28a42cf087 --- /dev/null +++ b/tests/functional/data/contracts/ethereum/local/MinimalProxyFactory.json @@ -0,0 +1,587 @@ +{ + "abi": [ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "addr", + "type": "address" + } + ], + "name": "Log", + "type": "event" + }, + { + "inputs": [ + { + "name": "master_copy", + "type": "address" + } + ], + "name": "deploy", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "ast": { + "ast_type": "Module", + "children": [ + { + "ast_type": "EventDef", + "children": [ + { + "ast_type": "AnnAssign", + "children": [ + { + "ast_type": "Name", + "children": [], + "classification": 1, + "col_offset": 10, + "end_col_offset": 17, + "end_lineno": 2, + "lineno": 2, + "src": { + "jump_code": "", + "length": 7, + "start": 21 + } + }, + { + "ast_type": "Name", + "children": [], + "classification": 1, + "col_offset": 4, + "end_col_offset": 8, + "end_lineno": 2, + "lineno": 2, + "src": { + "jump_code": "", + "length": 4, + "start": 15 + } + } + ], + "classification": 0, + "col_offset": 4, + "end_col_offset": 17, + "end_lineno": 2, + "lineno": 2, + "src": { + "jump_code": "", + "length": 13, + "start": 15 + } + } + ], + "classification": 0, + "col_offset": 0, + "end_col_offset": 17, + "end_lineno": 2, + "lineno": 1, + "name": "Log", + "src": { + "jump_code": "", + "length": 28 + } + }, + { + "ast_type": "FunctionDef", + "children": [ + { + "ast_type": "arguments", + "children": [ + { + "ast_type": "arg", + "children": [ + { + "ast_type": "Name", + "children": [], + "classification": 1, + "col_offset": 24, + "end_col_offset": 31, + "end_lineno": 5, + "lineno": 5, + "src": { + "jump_code": "", + "length": 7, + "start": 64 + } + } + ], + "classification": 0, + "col_offset": 11, + "end_col_offset": 31, + "end_lineno": 5, + "lineno": 5, + "src": { + "jump_code": "", + "length": 20, + "start": 51 + } + } + ], + "classification": 1, + "col_offset": 11, + "end_col_offset": 31, + "end_lineno": 5, + "lineno": 5, + "src": { + "jump_code": "", + "length": 20, + "start": 51 + } + }, + { + "ast_type": "AnnAssign", + "children": [ + { + "ast_type": "Name", + "children": [], + "classification": 1, + "col_offset": 10, + "end_col_offset": 17, + "end_lineno": 6, + "lineno": 6, + "src": { + "jump_code": "", + "length": 7, + "start": 95 + } + }, + { + "ast_type": "Name", + "children": [], + "classification": 1, + "col_offset": 4, + "end_col_offset": 8, + "end_lineno": 6, + "lineno": 6, + "src": { + "jump_code": "", + "length": 4, + "start": 89 + } + }, + { + "ast_type": "Call", + "children": [ + { + "ast_type": "Name", + "children": [], + "classification": 1, + "col_offset": 44, + "end_col_offset": 55, + "end_lineno": 6, + "lineno": 6, + "src": { + "jump_code": "", + "length": 11, + "start": 129 + } + }, + { + "ast_type": "Name", + "children": [], + "classification": 1, + "col_offset": 20, + "end_col_offset": 43, + "end_lineno": 6, + "lineno": 6, + "src": { + "jump_code": "", + "length": 23, + "start": 105 + } + } + ], + "classification": 0, + "col_offset": 20, + "end_col_offset": 56, + "end_lineno": 6, + "lineno": 6, + "src": { + "jump_code": "", + "length": 36, + "start": 105 + } + } + ], + "classification": 0, + "col_offset": 4, + "end_col_offset": 56, + "end_lineno": 6, + "lineno": 6, + "src": { + "jump_code": "", + "length": 52, + "start": 89 + } + }, + { + "ast_type": "Log", + "children": [ + { + "ast_type": "Call", + "children": [ + { + "ast_type": "Name", + "children": [], + "classification": 1, + "col_offset": 12, + "end_col_offset": 16, + "end_lineno": 7, + "lineno": 7, + "src": { + "jump_code": "", + "length": 4, + "start": 154 + } + }, + { + "ast_type": "Name", + "children": [], + "classification": 1, + "col_offset": 8, + "end_col_offset": 11, + "end_lineno": 7, + "lineno": 7, + "src": { + "jump_code": "", + "length": 3, + "start": 150 + } + } + ], + "classification": 0, + "col_offset": 8, + "end_col_offset": 17, + "end_lineno": 7, + "lineno": 7, + "src": { + "jump_code": "", + "length": 9, + "start": 150 + } + } + ], + "classification": 0, + "col_offset": 4, + "end_col_offset": 17, + "end_lineno": 7, + "lineno": 7, + "src": { + "jump_code": "", + "length": 13, + "start": 146 + } + }, + { + "ast_type": "Return", + "children": [ + { + "ast_type": "Name", + "children": [], + "classification": 1, + "col_offset": 11, + "end_col_offset": 15, + "end_lineno": 9, + "lineno": 9, + "src": { + "jump_code": "", + "length": 4, + "start": 172 + } + } + ], + "classification": 0, + "col_offset": 4, + "end_col_offset": 15, + "end_lineno": 9, + "lineno": 9, + "src": { + "jump_code": "", + "length": 11, + "start": 165 + } + }, + { + "ast_type": "Name", + "children": [], + "classification": 1, + "col_offset": 1, + "end_col_offset": 9, + "end_lineno": 4, + "lineno": 4, + "src": { + "jump_code": "", + "length": 8, + "start": 31 + } + }, + { + "ast_type": "Name", + "children": [], + "classification": 1, + "col_offset": 36, + "end_col_offset": 43, + "end_lineno": 5, + "lineno": 5, + "src": { + "jump_code": "", + "length": 7, + "start": 76 + } + } + ], + "classification": 1, + "col_offset": 0, + "end_col_offset": 15, + "end_lineno": 9, + "lineno": 5, + "name": "deploy", + "src": { + "jump_code": "", + "length": 136, + "start": 40 + } + } + ], + "classification": 0, + "col_offset": 0, + "end_col_offset": 15, + "end_lineno": 9, + "lineno": 1, + "src": { + "jump_code": "", + "length": 176 + } + }, + "contractName": "MinimalProxyFactory", + "deploymentBytecode": { + "bytecode": "0x6100c161000f6000396100c16000f35f3560e01c634c96a38981186100b9576024361034176100bd576004358060a01c6100bd576040527f602d3d8160093d39f3363d3d373d3d3d363d730000000000000000000000000060805260405160601b6093527f5af43d82803e903d91602b57fd5bf3000000000000000000000000000000000060a752603660805ff080156100bd576060527fb8a00d6d8ca1be30bfec34d8f97e55f0f0fd9eeb7fb46e030516363d4cfe1ad660605160805260206080a160206060f35b5f5ffd5b5f80fd8418c18000a1657679706572830004000012" + }, + "dev_messages": {}, + "devdoc": {}, + "methodIdentifiers": { + "deploy(address)": "0x4c96a389" + }, + "pcmap": { + "0": { + "location": [ + 1, + 0, + 9, + 15 + ] + }, + "120": { + "location": [ + 6, + 20, + 6, + 56 + ] + }, + "121": { + "dev": "dev: CREATE_FAILED", + "location": null + }, + "123": { + "dev": "dev: CREATE_FAILED", + "location": null + }, + "125": { + "dev": "dev: CREATE_FAILED", + "location": null + }, + "126": { + "dev": "dev: CREATE_FAILED", + "location": null + }, + "127": { + "dev": "dev: CREATE_FAILED", + "location": null + }, + "128": { + "dev": "dev: CREATE_FAILED", + "location": null + }, + "129": { + "dev": "dev: CREATE_FAILED", + "location": null + }, + "132": { + "dev": "dev: CREATE_FAILED", + "location": null + }, + "133": { + "location": [ + 6, + 4, + 6, + 56 + ] + }, + "135": { + "location": [ + 6, + 4, + 6, + 56 + ] + }, + "136": { + "location": [ + 7, + 4, + 7, + 17 + ] + }, + "169": { + "location": [ + 7, + 12, + 7, + 16 + ] + }, + "177": { + "location": [ + 7, + 4, + 7, + 17 + ] + }, + "179": { + "location": [ + 7, + 4, + 7, + 17 + ] + }, + "180": { + "location": [ + 5, + 0, + 9, + 15 + ] + }, + "182": { + "location": [ + 9, + 11, + 9, + 15 + ] + }, + "184": { + "location": [ + 5, + 0, + 9, + 15 + ] + }, + "188": { + "dev": "dev: Fallback not defined", + "location": null + }, + "22": { + "dev": "dev: Invalid calldata or value", + "location": [ + 1, + 0, + 9, + 15 + ] + }, + "25": { + "dev": "dev: Invalid calldata or value", + "location": [ + 1, + 0, + 9, + 15 + ] + }, + "33": { + "dev": "dev: Integer overflow", + "location": [ + 1, + 0, + 9, + 15 + ] + }, + "36": { + "dev": "dev: Integer overflow", + "location": [ + 1, + 0, + 9, + 15 + ] + }, + "37": { + "location": [ + 5, + 11, + 5, + 31 + ] + }, + "39": { + "location": [ + 5, + 11, + 5, + 31 + ] + }, + "73": { + "dev": "dev: CREATE_FAILED", + "location": null + }, + "75": { + "location": [ + 6, + 20, + 6, + 56 + ] + }, + "76": { + "location": [ + 6, + 44, + 6, + 55 + ] + }, + "84": { + "location": [ + 6, + 20, + 6, + 56 + ] + } + }, + "runtimeBytecode": { + "bytecode": "0x5f3560e01c634c96a38981186100b9576024361034176100bd576004358060a01c6100bd576040527f602d3d8160093d39f3363d3d373d3d3d363d730000000000000000000000000060805260405160601b6093527f5af43d82803e903d91602b57fd5bf3000000000000000000000000000000000060a752603660805ff080156100bd576060527fb8a00d6d8ca1be30bfec34d8f97e55f0f0fd9eeb7fb46e030516363d4cfe1ad660605160805260206080a160206060f35b5f5ffd5b5f80fd" + }, + "sourceId": "tests/functional/data/sources/MinimalProxyFactory.vy", + "sourcemap": "0:176:0:-;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1:-;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1:-;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1:-;51:20:0;-1:-1:-1;51:20:0;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;105:36:0;129:11:0;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;105:36:0;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;105:36:0;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1:-;89:52:0;-1:-1:-1;89:52:0;146:13:0;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;154:4:0;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1;146:13:0;-1:-1:-1;146:13:0;40:136:0;-1:-1:-1;172:4:0;-1:-1:-1;40:136:0;-1:-1:-1:-;-1:-1:-1;-1:-1:-1;-1:-1:-1;-1:-1:-1:-;-1:-1:-1;-1:-1:-1;-1:-1:-1", + "userdoc": {} +} diff --git a/tests/functional/data/contracts/ethereum/local/SafeProxy.json b/tests/functional/data/contracts/ethereum/local/SafeProxy.json new file mode 100644 index 0000000000..25b2b9e5d7 --- /dev/null +++ b/tests/functional/data/contracts/ethereum/local/SafeProxy.json @@ -0,0 +1,49 @@ +{ + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_singleton", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "fallback" + } + ], + "contractName": "SafeProxy", + "deploymentBytecode": { + "bytecode": "0x608060405234801561001057600080fd5b506040516101473803806101478339818101604052602081101561003357600080fd5b50516001600160a01b03811661007a5760405162461bcd60e51b81526004018080602001828103825260228152602001806101256022913960400191505060405180910390fd5b600080546001600160a01b039092166001600160a01b0319909216919091179055607c806100a96000396000f3fe608060405260008054813563530ca43760e11b14156028576001600160f41b0381168252602082f35b3682833781823684845af490503d82833e806041573d82fd5b503d81f3fea2646970667358221220a47dd8169e42c0cddf67ea4002d222dfb51d4610cb7a4846430abf7d73f7e5a564736f6c63430007060033496e76616c69642073696e676c65746f6e20616464726573732070726f7669646564" + }, + "devdoc": { + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_singleton": "Singleton address." + } + } + }, + "version": 1 + }, + "methodIdentifiers": {}, + "runtimeBytecode": { + "bytecode": "0x608060405260008054813563530ca43760e11b14156028576001600160f41b0381168252602082f35b3682833781823684845af490503d82833e806041573d82fd5b503d81f3fea2646970667358221220a47dd8169e42c0cddf67ea4002d222dfb51d4610cb7a4846430abf7d73f7e5a564736f6c63430007060033" + }, + "sourceId": "tests/functional/data/sources/GnosisSafe.sol", + "sourcemap": "120:1964:0:-:0;;;565:152;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;565:152:0;-1:-1:-1;;;;;615:24:0;;607:71;;;;-1:-1:-1;;;607:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;688:9;:22;;-1:-1:-1;;;;;688:22:0;;;-1:-1:-1;;;;;;688:22:0;;;;;;;;;120:1964;;;;;;", + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Constructor function sets address of singleton contract." + } + }, + "version": 1 + } +} diff --git a/tests/functional/data/contracts/ethereum/local/UpgradeabilityProxy.json b/tests/functional/data/contracts/ethereum/local/UpgradeabilityProxy.json new file mode 100644 index 0000000000..76f57fee57 --- /dev/null +++ b/tests/functional/data/contracts/ethereum/local/UpgradeabilityProxy.json @@ -0,0 +1,51 @@ +{ + "abi": [ + { + "inputs": [ + { + "name": "_constructor", + "type": "address" + }, + { + "name": "_implementation", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + } + ], + "contractName": "UpgradeabilityProxy", + "deploymentBytecode": { + "bytecode": "0x608060405234801561001057600080fd5b5060405160408061026883398101604081815282516020938401517f6f72672e7a657070656c696e6f732e70726f78792e696d706c656d656e74617484527f696f6e0000000000000000000000000000000000000000000000000000000000948401949094529051918290036023019091209091906000805160206102488339815191521461009b57fe5b604051600160a060020a038316906000818181855af491505015156100bf57600080fd5b6100d1816401000000006100d8810204565b505061019e565b60006100f08264010000000061006861019682021704565b151561018357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f43616e6e6f742073657420612070726f787920696d706c656d656e746174696f60448201527f6e20746f2061206e6f6e2d636f6e747261637420616464726573730000000000606482015290519081900360840190fd5b5060008051602061024883398151915255565b6000903b1190565b609c806101ac6000396000f3006080604052600a600c565b005b6012601e565b601e601a6020565b6045565b565b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35490565b3660008037600080366000845af43d6000803e8080156063573d6000f35b3d6000fd5b6000903b11905600a165627a7a723058209808855d7616f060f8c0896ae6f4ac20f6abc22f074895157eaef1e2f72f26d100297050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3" + }, + "devdoc": { + "methods": {}, + "title": "UpgradeabilityProxy" + }, + "methodIdentifiers": {}, + "runtimeBytecode": { + "bytecode": "0x6080604052600a600c565b005b6012601e565b601e601a6020565b6045565b565b7f7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c35490565b3660008037600080366000845af43d6000803e8080156063573d6000f35b3d6000fd5b6000903b11905600a165627a7a723058209808855d7616f060f8c0896ae6f4ac20f6abc22f074895157eaef1e2f72f26d10029" + }, + "sourceId": "tests/functional/data/sources/UpgradeabilityProxy.sol", + "sourcemap": "3358:1858:0:-;;;4001:241;8:9:-1;5:2;;;30:1;27;20:12;5:2;4001:241:0;;;;;;;;;;;;;;;;;;;;;4103:48;;;;;;;;;;;;;;;;;;;;;;4001:241;;;-1:-1:-1;;;;;;;;;;;4080:71:0;4073:79;;;;4167:27;;-1:-1:-1;;;;;4167:25:0;;;:27;;;;:25;:27;;;;;4159:36;;;;;;;;4202:35;4221:15;4202:18;;;;:35;:::i;:::-;4001:241;;3358:1858;;4925:289;5115:12;5002:42;5026:17;5002:23;;;;;;:42;:::i;:::-;4994:114;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;5173:31:0;5165:45::o;2564:578::-;2622:4;3097:18;;3129:8;;2564:578::o;3358:1858::-;;;;;;;", + "userdoc": { + "methods": {} + } +} diff --git a/tests/functional/data/contracts/ethereum/local/Uups.json b/tests/functional/data/contracts/ethereum/local/Uups.json new file mode 100644 index 0000000000..fb415d7553 --- /dev/null +++ b/tests/functional/data/contracts/ethereum/local/Uups.json @@ -0,0 +1,44 @@ +{ + "abi": [ + { + "inputs": [ + { + "internalType": "bytes", + "name": "constructData", + "type": "bytes" + }, + { + "internalType": "address", + "name": "contractLogic", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "stateMutability": "payable", + "type": "fallback" + } + ], + "contractName": "Uups", + "deploymentBytecode": { + "bytecode": "0x608060405234801561001057600080fd5b506040516102e23803806102e283398101604081905261002f916100fd565b807fc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf755600080826001600160a01b03168460405161006d91906101b8565b600060405180830381855af49150503d80600081146100a8576040519150601f19603f3d011682016040523d82523d6000602084013e6100ad565b606091505b5091509150816100d85760405162461bcd60e51b81526004016100cf906101d4565b60405180910390fd5b50505050610251565b80516001600160a01b03811681146100f857600080fd5b919050565b6000806040838503121561010f578182fd5b82516001600160401b0380821115610125578384fd5b818501915085601f830112610138578384fd5b81518181111561014a5761014a61023b565b604051601f8201601f19908116603f011681019083821181831017156101725761017261023b565b8160405282815288602084870101111561018a578687fd5b61019b83602083016020880161020b565b80965050505050506101af602084016100e1565b90509250929050565b600082516101ca81846020870161020b565b9190910192915050565b60208082526013908201527f436f6e737472756374696f6e206661696c656400000000000000000000000000604082015260600190565b60005b8381101561022657818101518382015260200161020e565b83811115610235576000848401525b50505050565b634e487b7160e01b600052604160045260246000fd5b60838061025f6000396000f3fe60806040527fc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf754600036818237808036818561270f195a01f491503d8082833e8280156049578183f35b8183fdfea2646970667358221220ae2d20378da1ac277d03f84c6902a9385f4ad5f8a73c75abb10c7d1b14885fcc64736f6c63430008010033" + }, + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "methodIdentifiers": {}, + "runtimeBytecode": { + "bytecode": "0x60806040527fc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf754600036818237808036818561270f195a01f491503d8082833e8280156049578183f35b8183fdfea2646970667358221220ae2d20378da1ac277d03f84c6902a9385f4ad5f8a73c75abb10c7d1b14885fcc64736f6c63430008010033" + }, + "sourceId": "contracts/Uups.sol", + "sourcemap": "56:1168:0:-:0;;;205:419;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;432:13;364:66;357:89;466:12;480:19;504:13;-1:-1:-1;;;;;504:26:0;531:13;504:41;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;465:80;;;;586:7;578:39;;;;-1:-1:-1;;;578:39:0;;;;;;;:::i;:::-;;;;;;;;;205:419;;;;56:1168;;14:179:1;95:13;;-1:-1:-1;;;;;137:31:1;;127:42;;117:2;;183:1;180;173:12;117:2;76:117;;;:::o;198:1018::-;;;347:2;335:9;326:7;322:23;318:32;315:2;;;368:6;360;353:22;315:2;400:16;;-1:-1:-1;;;;;465:14:1;;;462:2;;;497:6;489;482:22;462:2;540:6;529:9;525:22;515:32;;585:7;578:4;574:2;570:13;566:27;556:2;;612:6;604;597:22;556:2;646;640:9;668:2;664;661:10;658:2;;;674:18;;:::i;:::-;749:2;743:9;717:2;803:13;;-1:-1:-1;;799:22:1;;;823:2;795:31;791:40;779:53;;;847:18;;;867:22;;;844:46;841:2;;;893:18;;:::i;:::-;933:10;929:2;922:22;968:2;960:6;953:18;1010:7;1003:4;998:2;994;990:11;986:22;983:35;980:2;;;1036:6;1028;1021:22;980:2;1054:59;1110:2;1103:4;1095:6;1091:17;1084:4;1080:2;1076:13;1054:59;:::i;:::-;1132:6;1122:16;;;;;;;1157:53;1204:4;1193:9;1189:20;1157:53;:::i;:::-;1147:63;;305:911;;;;;:::o;1221:274::-;;1388:6;1382:13;1404:53;1450:6;1445:3;1438:4;1430:6;1426:17;1404:53;:::i;:::-;1473:16;;;;;1358:137;-1:-1:-1;;1358:137:1:o;1500:343::-;1702:2;1684:21;;;1741:2;1721:18;;;1714:30;1780:21;1775:2;1760:18;;1753:49;1834:2;1819:18;;1674:169::o;1848:258::-;1920:1;1930:113;1944:6;1941:1;1938:13;1930:113;;;2020:11;;;2014:18;2001:11;;;1994:39;1966:2;1959:10;1930:113;;;2061:6;2058:1;2055:13;2052:2;;;2096:1;2087:6;2082:3;2078:16;2071:27;2052:2;;1901:205;;;:::o;2111:127::-;2172:10;2167:3;2163:20;2160:1;2153:31;2203:4;2200:1;2193:15;2227:4;2224:1;2217:15;2143:95;56:1168:0;;;;;;", + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + } +} diff --git a/tests/functional/data/sources/BeaconProxy.sol b/tests/functional/data/sources/BeaconProxy.sol new file mode 100644 index 0000000000..b853bfe6a1 --- /dev/null +++ b/tests/functional/data/sources/BeaconProxy.sol @@ -0,0 +1,662 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20 ^0.8.22; + +// contracts/interfaces/IERC1967.sol + +// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1967.sol) + +/** + * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. + */ +interface IERC1967 { + /** + * @dev Emitted when the implementation is upgraded. + */ + event Upgraded(address indexed implementation); + + /** + * @dev Emitted when the admin account has changed. + */ + event AdminChanged(address previousAdmin, address newAdmin); + + /** + * @dev Emitted when the beacon is changed. + */ + event BeaconUpgraded(address indexed beacon); +} + +// contracts/proxy/Proxy.sol + +// OpenZeppelin Contracts (last updated v5.0.0) (proxy/Proxy.sol) + +/** + * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM + * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to + * be specified by overriding the virtual {_implementation} function. + * + * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a + * different contract through the {_delegate} function. + * + * The success and return data of the delegated call will be returned back to the caller of the proxy. + */ +abstract contract Proxy { + /** + * @dev Delegates the current call to `implementation`. + * + * This function does not return to its internal call site, it will return directly to the external caller. + */ + function _delegate(address implementation) internal virtual { + assembly { + // Copy msg.data. We take full control of memory in this inline assembly + // block because it will not return to Solidity code. We overwrite the + // Solidity scratch pad at memory position 0. + calldatacopy(0, 0, calldatasize()) + + // Call the implementation. + // out and outsize are 0 because we don't know the size yet. + let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) + + // Copy the returned data. + returndatacopy(0, 0, returndatasize()) + + switch result + // delegatecall returns 0 on error. + case 0 { + revert(0, returndatasize()) + } + default { + return(0, returndatasize()) + } + } + } + + /** + * @dev This is a virtual function that should be overridden so it returns the address to which the fallback + * function and {_fallback} should delegate. + */ + function _implementation() internal view virtual returns (address); + + /** + * @dev Delegates the current call to the address returned by `_implementation()`. + * + * This function does not return to its internal call site, it will return directly to the external caller. + */ + function _fallback() internal virtual { + _delegate(_implementation()); + } + + /** + * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other + * function in the contract matches the call data. + */ + fallback() external payable virtual { + _fallback(); + } +} + +// contracts/proxy/beacon/IBeacon.sol + +// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol) + +/** + * @dev This is the interface that {BeaconProxy} expects of its beacon. + */ +interface IBeacon { + /** + * @dev Must return an address that can be used as a delegate call target. + * + * {UpgradeableBeacon} will check that this address is a contract. + */ + function implementation() external view returns (address); +} + +// contracts/utils/Errors.sol + +// OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol) + +/** + * @dev Collection of common custom errors used in multiple contracts + * + * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library. + * It is recommended to avoid relying on the error API for critical functionality. + * + * _Available since v5.1._ + */ +library Errors { + /** + * @dev The ETH balance of the account is not enough to perform the operation. + */ + error InsufficientBalance(uint256 balance, uint256 needed); + + /** + * @dev A call to an address target failed. The target may have reverted. + */ + error FailedCall(); + + /** + * @dev The deployment failed. + */ + error FailedDeployment(); + + /** + * @dev A necessary precompile is missing. + */ + error MissingPrecompile(address); +} + +// contracts/utils/StorageSlot.sol + +// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol) +// This file was procedurally generated from scripts/generate/templates/StorageSlot.js. + +/** + * @dev Library for reading and writing primitive types to specific storage slots. + * + * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. + * This library helps with reading and writing to such slots without the need for inline assembly. + * + * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. + * + * Example usage to set ERC-1967 implementation slot: + * ```solidity + * contract ERC1967 { + * // Define the slot. Alternatively, use the SlotDerivation library to derive the slot. + * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + * + * function _getImplementation() internal view returns (address) { + * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; + * } + * + * function _setImplementation(address newImplementation) internal { + * require(newImplementation.code.length > 0); + * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; + * } + * } + * ``` + * + * TIP: Consider using this library along with {SlotDerivation}. + */ +library StorageSlot { + struct AddressSlot { + address value; + } + + struct BooleanSlot { + bool value; + } + + struct Bytes32Slot { + bytes32 value; + } + + struct Uint256Slot { + uint256 value; + } + + struct Int256Slot { + int256 value; + } + + struct StringSlot { + string value; + } + + struct BytesSlot { + bytes value; + } + + /** + * @dev Returns an `AddressSlot` with member `value` located at `slot`. + */ + function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { + assembly ("memory-safe") { + r.slot := slot + } + } + + /** + * @dev Returns a `BooleanSlot` with member `value` located at `slot`. + */ + function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { + assembly ("memory-safe") { + r.slot := slot + } + } + + /** + * @dev Returns a `Bytes32Slot` with member `value` located at `slot`. + */ + function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { + assembly ("memory-safe") { + r.slot := slot + } + } + + /** + * @dev Returns a `Uint256Slot` with member `value` located at `slot`. + */ + function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { + assembly ("memory-safe") { + r.slot := slot + } + } + + /** + * @dev Returns a `Int256Slot` with member `value` located at `slot`. + */ + function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) { + assembly ("memory-safe") { + r.slot := slot + } + } + + /** + * @dev Returns a `StringSlot` with member `value` located at `slot`. + */ + function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { + assembly ("memory-safe") { + r.slot := slot + } + } + + /** + * @dev Returns an `StringSlot` representation of the string storage pointer `store`. + */ + function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { + assembly ("memory-safe") { + r.slot := store.slot + } + } + + /** + * @dev Returns a `BytesSlot` with member `value` located at `slot`. + */ + function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { + assembly ("memory-safe") { + r.slot := slot + } + } + + /** + * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. + */ + function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { + assembly ("memory-safe") { + r.slot := store.slot + } + } +} + +// contracts/utils/Address.sol + +// OpenZeppelin Contracts (last updated v5.1.0) (utils/Address.sol) + +/** + * @dev Collection of functions related to the address type + */ +library Address { + /** + * @dev There's no code at `target` (it is not a contract). + */ + error AddressEmptyCode(address target); + + /** + * @dev Replacement for Solidity's `transfer`: sends `amount` wei to + * `recipient`, forwarding all available gas and reverting on errors. + * + * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost + * of certain opcodes, possibly making contracts go over the 2300 gas limit + * imposed by `transfer`, making them unable to receive funds via + * `transfer`. {sendValue} removes this limitation. + * + * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. + * + * IMPORTANT: because control is transferred to `recipient`, care must be + * taken to not create reentrancy vulnerabilities. Consider using + * {ReentrancyGuard} or the + * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. + */ + function sendValue(address payable recipient, uint256 amount) internal { + if (address(this).balance < amount) { + revert Errors.InsufficientBalance(address(this).balance, amount); + } + + (bool success, ) = recipient.call{value: amount}(""); + if (!success) { + revert Errors.FailedCall(); + } + } + + /** + * @dev Performs a Solidity function call using a low level `call`. A + * plain `call` is an unsafe replacement for a function call: use this + * function instead. + * + * If `target` reverts with a revert reason or custom error, it is bubbled + * up by this function (like regular Solidity function calls). However, if + * the call reverted with no returned reason, this function reverts with a + * {Errors.FailedCall} error. + * + * Returns the raw returned data. To convert to the expected return value, + * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. + * + * Requirements: + * + * - `target` must be a contract. + * - calling `target` with `data` must not revert. + */ + function functionCall(address target, bytes memory data) internal returns (bytes memory) { + return functionCallWithValue(target, data, 0); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], + * but also transferring `value` wei to `target`. + * + * Requirements: + * + * - the calling contract must have an ETH balance of at least `value`. + * - the called Solidity function must be `payable`. + */ + function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { + if (address(this).balance < value) { + revert Errors.InsufficientBalance(address(this).balance, value); + } + (bool success, bytes memory returndata) = target.call{value: value}(data); + return verifyCallResultFromTarget(target, success, returndata); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], + * but performing a static call. + */ + function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { + (bool success, bytes memory returndata) = target.staticcall(data); + return verifyCallResultFromTarget(target, success, returndata); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], + * but performing a delegate call. + */ + function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { + (bool success, bytes memory returndata) = target.delegatecall(data); + return verifyCallResultFromTarget(target, success, returndata); + } + + /** + * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target + * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case + * of an unsuccessful call. + */ + function verifyCallResultFromTarget( + address target, + bool success, + bytes memory returndata + ) internal view returns (bytes memory) { + if (!success) { + _revert(returndata); + } else { + // only check if target is a contract if the call was successful and the return data is empty + // otherwise we already know that it was a contract + if (returndata.length == 0 && target.code.length == 0) { + revert AddressEmptyCode(target); + } + return returndata; + } + } + + /** + * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the + * revert reason or with a default {Errors.FailedCall} error. + */ + function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { + if (!success) { + _revert(returndata); + } else { + return returndata; + } + } + + /** + * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}. + */ + function _revert(bytes memory returndata) private pure { + // Look for revert reason and bubble it up if present + if (returndata.length > 0) { + // The easiest way to bubble the revert reason is using memory via assembly + assembly ("memory-safe") { + let returndata_size := mload(returndata) + revert(add(32, returndata), returndata_size) + } + } else { + revert Errors.FailedCall(); + } + } +} + +// contracts/proxy/ERC1967/ERC1967Utils.sol + +// OpenZeppelin Contracts (last updated v5.1.0) (proxy/ERC1967/ERC1967Utils.sol) + +/** + * @dev This library provides getters and event emitting update functions for + * https://eips.ethereum.org/EIPS/eip-1967[ERC-1967] slots. + */ +library ERC1967Utils { + /** + * @dev Storage slot with the address of the current implementation. + * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1. + */ + // solhint-disable-next-line private-vars-leading-underscore + bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + + /** + * @dev The `implementation` of the proxy is invalid. + */ + error ERC1967InvalidImplementation(address implementation); + + /** + * @dev The `admin` of the proxy is invalid. + */ + error ERC1967InvalidAdmin(address admin); + + /** + * @dev The `beacon` of the proxy is invalid. + */ + error ERC1967InvalidBeacon(address beacon); + + /** + * @dev An upgrade function sees `msg.value > 0` that may be lost. + */ + error ERC1967NonPayable(); + + /** + * @dev Returns the current implementation address. + */ + function getImplementation() internal view returns (address) { + return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value; + } + + /** + * @dev Stores a new address in the ERC-1967 implementation slot. + */ + function _setImplementation(address newImplementation) private { + if (newImplementation.code.length == 0) { + revert ERC1967InvalidImplementation(newImplementation); + } + StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation; + } + + /** + * @dev Performs implementation upgrade with additional setup call if data is nonempty. + * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected + * to avoid stuck value in the contract. + * + * Emits an {IERC1967-Upgraded} event. + */ + function upgradeToAndCall(address newImplementation, bytes memory data) internal { + _setImplementation(newImplementation); + emit IERC1967.Upgraded(newImplementation); + + if (data.length > 0) { + Address.functionDelegateCall(newImplementation, data); + } else { + _checkNonPayable(); + } + } + + /** + * @dev Storage slot with the admin of the contract. + * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1. + */ + // solhint-disable-next-line private-vars-leading-underscore + bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; + + /** + * @dev Returns the current admin. + * + * TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using + * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. + * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103` + */ + function getAdmin() internal view returns (address) { + return StorageSlot.getAddressSlot(ADMIN_SLOT).value; + } + + /** + * @dev Stores a new address in the ERC-1967 admin slot. + */ + function _setAdmin(address newAdmin) private { + if (newAdmin == address(0)) { + revert ERC1967InvalidAdmin(address(0)); + } + StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin; + } + + /** + * @dev Changes the admin of the proxy. + * + * Emits an {IERC1967-AdminChanged} event. + */ + function changeAdmin(address newAdmin) internal { + emit IERC1967.AdminChanged(getAdmin(), newAdmin); + _setAdmin(newAdmin); + } + + /** + * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. + * This is the keccak-256 hash of "eip1967.proxy.beacon" subtracted by 1. + */ + // solhint-disable-next-line private-vars-leading-underscore + bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; + + /** + * @dev Returns the current beacon. + */ + function getBeacon() internal view returns (address) { + return StorageSlot.getAddressSlot(BEACON_SLOT).value; + } + + /** + * @dev Stores a new beacon in the ERC-1967 beacon slot. + */ + function _setBeacon(address newBeacon) private { + if (newBeacon.code.length == 0) { + revert ERC1967InvalidBeacon(newBeacon); + } + + StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon; + + address beaconImplementation = IBeacon(newBeacon).implementation(); + if (beaconImplementation.code.length == 0) { + revert ERC1967InvalidImplementation(beaconImplementation); + } + } + + /** + * @dev Change the beacon and trigger a setup call if data is nonempty. + * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected + * to avoid stuck value in the contract. + * + * Emits an {IERC1967-BeaconUpgraded} event. + * + * CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since + * it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for + * efficiency. + */ + function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal { + _setBeacon(newBeacon); + emit IERC1967.BeaconUpgraded(newBeacon); + + if (data.length > 0) { + Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); + } else { + _checkNonPayable(); + } + } + + /** + * @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract + * if an upgrade doesn't perform an initialization call. + */ + function _checkNonPayable() private { + if (msg.value > 0) { + revert ERC1967NonPayable(); + } + } +} + +// contracts/proxy/beacon/BeaconProxy.sol + +// OpenZeppelin Contracts (last updated v5.1.0) (proxy/beacon/BeaconProxy.sol) + +/** + * @dev This contract implements a proxy that gets the implementation address for each call from an {UpgradeableBeacon}. + * + * The beacon address can only be set once during construction, and cannot be changed afterwards. It is stored in an + * immutable variable to avoid unnecessary storage reads, and also in the beacon storage slot specified by + * https://eips.ethereum.org/EIPS/eip-1967[ERC-1967] so that it can be accessed externally. + * + * CAUTION: Since the beacon address can never be changed, you must ensure that you either control the beacon, or trust + * the beacon to not upgrade the implementation maliciously. + * + * IMPORTANT: Do not use the implementation logic to modify the beacon storage slot. Doing so would leave the proxy in + * an inconsistent state where the beacon storage slot does not match the beacon address. + */ +contract BeaconProxy is Proxy { + // An immutable address for the beacon to avoid unnecessary SLOADs before each delegate call. + address private immutable _beacon; + + /** + * @dev Initializes the proxy with `beacon`. + * + * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This + * will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity + * constructor. + * + * Requirements: + * + * - `beacon` must be a contract with the interface {IBeacon}. + * - If `data` is empty, `msg.value` must be zero. + */ + constructor(address beacon, bytes memory data) payable { + ERC1967Utils.upgradeBeaconToAndCall(beacon, data); + _beacon = beacon; + } + + /** + * @dev Returns the current implementation address of the associated beacon. + */ + function _implementation() internal view virtual override returns (address) { + return IBeacon(_getBeacon()).implementation(); + } + + /** + * @dev Returns the beacon. + */ + function _getBeacon() internal view virtual returns (address) { + return _beacon; + } +} + diff --git a/tests/functional/data/sources/ERCProxy.sol b/tests/functional/data/sources/ERCProxy.sol new file mode 100644 index 0000000000..fb20c55e29 --- /dev/null +++ b/tests/functional/data/sources/ERCProxy.sol @@ -0,0 +1,20 @@ +pragma solidity ^0.4.18; + +// Ref: https://eips.ethereum.org/EIPS/eip-897 + +contract ERCProxy { + address internal target; + + constructor(address _target) { + target = _target; + } + + + function implementation() public view returns (address) { + return target; + } + + function proxyType() public pure returns (uint256 proxyTypeId){ + return 1; + } +} diff --git a/tests/functional/data/sources/MinimalProxyFactory.vy b/tests/functional/data/sources/MinimalProxyFactory.vy new file mode 100644 index 0000000000..fc1e303b10 --- /dev/null +++ b/tests/functional/data/sources/MinimalProxyFactory.vy @@ -0,0 +1,9 @@ +event Log: + addr: address + +@external +def deploy(master_copy: address) -> address: + addr: address = create_minimal_proxy_to(master_copy) + log Log(addr) + + return addr diff --git a/tests/functional/data/sources/SafeProxy.sol b/tests/functional/data/sources/SafeProxy.sol new file mode 100644 index 0000000000..0082f10ce8 --- /dev/null +++ b/tests/functional/data/sources/SafeProxy.sol @@ -0,0 +1,47 @@ +/ SPDX-License-Identifier: LGPL-3.0-only +/* solhint-disable one-contract-per-file */ + +pragma solidity >=0.7.0 <0.8.0; + + +//copied from https://github.com/safe-global/safe-smart-account/blob/main/contracts/proxies/SafeProxy.sol + +contract SafeProxy { + // Singleton always needs to be first declared variable, to ensure that it is at the same location in the contracts to which calls are delegated. + // To reduce deployment costs this variable is internal and needs to be retrieved via `getStorageAt` + address internal singleton; + + /** + * @notice Constructor function sets address of singleton contract. + * @param _singleton Singleton address. + */ + constructor(address _singleton) { + require(_singleton != address(0), "Invalid singleton address provided"); + singleton = _singleton; + } + + /// @dev Fallback function forwards all transactions and returns all received return data. + fallback() external payable { + // Note that this assembly block is **intentionally** not marked as memory-safe. First of all, it isn't memory + // safe to begin with, and turning this into memory-safe assembly would just make it less gas efficient. + // Additionally, we noticed that converting this to memory-safe assembly had no affect on optimizations of other + // contracts (as it always gets compiled alone in its own compilation unit anyway). + /* solhint-disable no-inline-assembly */ + assembly { + let _singleton := sload(0) + // 0xa619486e == keccak("masterCopy()"). The value is right padded to 32-bytes with 0s + if eq(calldataload(0), 0xa619486e00000000000000000000000000000000000000000000000000000000) { + mstore(0, shr(12, shl(12, _singleton))) + return(0, 0x20) + } + calldatacopy(0, 0, calldatasize()) + let success := delegatecall(gas(), _singleton, 0, calldatasize(), 0, 0) + returndatacopy(0, 0, returndatasize()) + if iszero(success) { + revert(0, returndatasize()) + } + return(0, returndatasize()) + } + /* solhint-enable no-inline-assembly */ + } +} diff --git a/tests/functional/data/sources/UpgradeabilityProxy.sol b/tests/functional/data/sources/UpgradeabilityProxy.sol new file mode 100644 index 0000000000..081e68f688 --- /dev/null +++ b/tests/functional/data/sources/UpgradeabilityProxy.sol @@ -0,0 +1,167 @@ +pragma solidity ^0.4.24; + +//https://github.com/OpenZeppelin/openzeppelin-labs/blob/master/initializer_contracts/contracts/UpgradeabilityProxy.sol + +// initializer_contracts/contracts/Proxy.sol + +/** + * @title Proxy + * @dev Implements delegation of calls to other contracts, with proper + * forwarding of return values and bubbling of failures. + * It defines a fallback function that delegates all calls to the address + * returned by the abstract _implementation() internal function. + */ +contract Proxy { + /** + * @dev Fallback function. + * Implemented entirely in `_fallback`. + */ + function () payable external { + _fallback(); + } + + /** + * @return The Address of the implementation. + */ + function _implementation() internal view returns (address); + + /** + * @dev Delegates execution to an implementation contract. + * This is a low level function that doesn't return to its internal call site. + * It will return to the external caller whatever the implementation returns. + * @param implementation Address to delegate. + */ + function _delegate(address implementation) internal { + assembly { + // Copy msg.data. We take full control of memory in this inline assembly + // block because it will not return to Solidity code. We overwrite the + // Solidity scratch pad at memory position 0. + calldatacopy(0, 0, calldatasize) + + // Call the implementation. + // out and outsize are 0 because we don't know the size yet. + let result := delegatecall(gas, implementation, 0, calldatasize, 0, 0) + + // Copy the returned data. + returndatacopy(0, 0, returndatasize) + + switch result + // delegatecall returns 0 on error. + case 0 { revert(0, returndatasize) } + default { return(0, returndatasize) } + } + } + + /** + * @dev Function that is run as the first thing in the fallback function. + * Can be redefined in derived contracts to add functionality. + * Redefinitions must call super._willFallback(). + */ + function _willFallback() internal { + } + + /** + * @dev fallback implementation. + * Extracted to enable manual triggering. + */ + function _fallback() internal { + _willFallback(); + _delegate(_implementation()); + } +} + +// initializer_contracts/contracts/UpgradeabilityProxy.sol + +/** + * Utility library of inline functions on addresses + */ +library AddressUtils { + + /** + * Returns whether the target address is a contract + * @dev This function will return false if invoked during the constructor of a contract, + * as the code is not actually created until after the constructor finishes. + * @param _addr address to check + * @return whether the target address is a contract + */ + function isContract(address _addr) internal view returns (bool) { + uint256 size; + // XXX Currently there is no better way to check if there is a contract in an address + // than to check the size of the code at that address. + // See https://ethereum.stackexchange.com/a/14016/36603 + // for more details about how this works. + // TODO Check this again before the Serenity release, because all addresses will be + // contracts then. + // solium-disable-next-line security/no-inline-assembly + assembly { size := extcodesize(_addr) } + return size > 0; + } + +} +/** + * @title UpgradeabilityProxy + * @dev This contract implements a proxy that allows to change the + * implementation address to which it will delegate. + * Such a change is called an implementation upgrade. + */ +contract UpgradeabilityProxy is Proxy { + /** + * @dev Emitted when the implementation is upgraded. + * @param implementation Address of the new implementation. + */ + event Upgraded(address implementation); + + /** + * @dev Storage slot with the address of the current implementation. + * This is the keccak-256 hash of "org.zeppelinos.proxy.implementation", and is + * validated in the constructor. + */ + bytes32 private constant IMPLEMENTATION_SLOT = 0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3; + + /** + * @dev Contract constructor. + * @param _implementation Address of the initial implementation. + */ + constructor(address _constructor, address _implementation) public { + assert(IMPLEMENTATION_SLOT == keccak256("org.zeppelinos.proxy.implementation")); + + require(_constructor.delegatecall()); + + _setImplementation(_implementation); + } + + /** + * @dev Returns the current implementation. + * @return Address of the current implementation + */ + function _implementation() internal view returns (address impl) { + bytes32 slot = IMPLEMENTATION_SLOT; + assembly { + impl := sload(slot) + } + } + + /** + * @dev Upgrades the proxy to a new implementation. + * @param newImplementation Address of the new implementation. + */ + function _upgradeTo(address newImplementation) internal { + _setImplementation(newImplementation); + emit Upgraded(newImplementation); + } + + /** + * @dev Sets the implementation address of the proxy. + * @param newImplementation Address of the new implementation. + */ + function _setImplementation(address newImplementation) private { + require(AddressUtils.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address"); + + bytes32 slot = IMPLEMENTATION_SLOT; + + assembly { + sstore(slot, newImplementation) + } + } +} + diff --git a/tests/functional/data/sources/Uups.sol b/tests/functional/data/sources/Uups.sol new file mode 100644 index 0000000000..294306a66a --- /dev/null +++ b/tests/functional/data/sources/Uups.sol @@ -0,0 +1,32 @@ +//SPDX-License-Identifier: MIT + +pragma solidity 0.8.1; + +contract Uups { + // Code position in storage is keccak256("PROXIABLE") = "0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7" + constructor(bytes memory constructData, address contractLogic) { + // save the code address + assembly { // solium-disable-line + sstore(0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7, contractLogic) + } + (bool success, bytes memory result ) = contractLogic.delegatecall(constructData); // solium-disable-line + require(success, "Construction failed"); + } + + fallback() external payable { + assembly { // solium-disable-line + let contractLogic := sload(0xc5f16f0fcc639fa48a6947836d9850f504798523bf8c9a3a87d5876cf622bcf7) + calldatacopy(0x0, 0x0, calldatasize()) + let success := delegatecall(sub(gas(), 10000), contractLogic, 0x0, calldatasize(), 0, 0) + let retSz := returndatasize() + returndatacopy(0, 0, retSz) + switch success + case 0 { + revert(0, retSz) + } + default { + return(0, retSz) + } + } + } +} diff --git a/tests/functional/geth/test_proxy.py b/tests/functional/geth/test_proxy.py new file mode 100644 index 0000000000..4d39b186ae --- /dev/null +++ b/tests/functional/geth/test_proxy.py @@ -0,0 +1,106 @@ +from eth_pydantic_types import HexBytes + +from ape.contracts import ContractContainer +from ape_ethereum.proxies import ProxyType +from tests.conftest import geth_process_test + + +@geth_process_test +def test_standard_proxy(get_contract_type, owner, geth_contract, ethereum): + """ + NOTE: Geth is used here because EthTester does not implement getting storage slots. + """ + _type = get_contract_type("eip1967") + contract = ContractContainer(_type) + target = geth_contract.address + contract_instance = owner.deploy(contract, target, HexBytes("")) + actual = ethereum.get_proxy_info(contract_instance.address) + assert actual is not None + assert actual.type == ProxyType.Standard + assert actual.target == target + + +@geth_process_test +def test_beacon_proxy(get_contract_type, geth_contract, owner, ethereum): + """ + NOTE: Geth is used here because EthTester does not implement getting storage slots. + """ + _type = get_contract_type("beacon") + beacon_contract = ContractContainer(_type) + target = geth_contract.address + beacon_instance = owner.deploy(beacon_contract, target) + beacon = beacon_instance.address + + _type = get_contract_type("BeaconProxy") + contract = ContractContainer(_type) + contract_instance = owner.deploy(contract, beacon, HexBytes("")) + + actual = ethereum.get_proxy_info(contract_instance.address) + assert actual is not None + assert actual.type == ProxyType.Beacon + assert actual.target == target + + +@geth_process_test +def test_uups_proxy(get_contract_type, geth_contract, owner, ethereum): + _type = get_contract_type("Uups") + contract = ContractContainer(_type) + + target = geth_contract.address + + contract_instance = owner.deploy(contract, HexBytes("0x2beb1711"), target) + + actual = ethereum.get_proxy_info(contract_instance.address) + assert actual is not None + assert actual.type == ProxyType.UUPS + assert actual.target == target + + +@geth_process_test +def test_gnosis_safe(get_contract_type, geth_contract, owner, ethereum): + _type = get_contract_type("SafeProxy") + contract = ContractContainer(_type) + + target = geth_contract.address + + contract_instance = owner.deploy(contract, target) + + actual = ethereum.get_proxy_info(contract_instance.address) + + assert actual is not None + assert actual.type == ProxyType.GnosisSafe + assert actual.target == target + + +@geth_process_test +def test_openzeppelin(get_contract_type, geth_contract, owner, ethereum, sender): + _type = get_contract_type("UpgradeabilityProxy") + contract = ContractContainer(_type) + + target = geth_contract.address + _type = get_contract_type("SolFallbackAndReceive") + constructor_container = ContractContainer(_type) + constructor_contract = owner.deploy(constructor_container) + + contract_instance = owner.deploy(contract, constructor_contract.address, target) + + actual = ethereum.get_proxy_info(contract_instance.address) + assert actual is not None + assert actual.type == ProxyType.OpenZeppelin + assert actual.target == target + + +@geth_process_test +def test_delegate(get_contract_type, geth_contract, owner, ethereum): + _type = get_contract_type("ERCProxy") + contract = ContractContainer(_type) + + target = geth_contract.address + + contract_instance = owner.deploy(contract, target) + + actual = ethereum.get_proxy_info(contract_instance.address) + + assert actual is not None + assert actual.type == ProxyType.Delegate + assert actual.target == target diff --git a/tests/functional/geth/text_proxy.py b/tests/functional/geth/text_proxy.py deleted file mode 100644 index 1a21f4a042..0000000000 --- a/tests/functional/geth/text_proxy.py +++ /dev/null @@ -1,24 +0,0 @@ -from ape_ethereum.proxies import ProxyType -from tests.conftest import geth_process_test - - -@geth_process_test -def test_standard_proxy(ethereum, standard_proxy, geth_provider, geth_vyper_contract): - """ - NOTE: Geth is used here because EthTester does not implement getting storage slots. - """ - actual = ethereum.get_proxy_info(standard_proxy.address) - assert actual is not None - assert actual.type == ProxyType.Standard - assert actual.target == geth_vyper_contract.address - - -@geth_process_test -def test_beacon_proxy(ethereum, beacon_proxy, geth_provider, geth_vyper_contract): - """ - NOTE: Geth is used here because EthTester does not implement getting storage slots. - """ - actual = ethereum.get_proxy_info(beacon_proxy.address) - assert actual is not None - assert actual.type == ProxyType.Beacon - assert actual.target == geth_vyper_contract.address diff --git a/tests/functional/test_exceptions.py b/tests/functional/test_exceptions.py index d6ccf200eb..f8b209c0bf 100644 --- a/tests/functional/test_exceptions.py +++ b/tests/functional/test_exceptions.py @@ -253,7 +253,7 @@ class TestUnknownSnapshotError: def test_bytes(self): snapshot_id = b"asdfasdfasdf" err = UnknownSnapshotError(snapshot_id) - assert str(err) == "Unknown snapshot ID '6173..6466'." + assert str(err) == "Unknown snapshot ID '0x6173..6466'." @pytest.mark.parametrize("snapshot_id", (123, "123")) def test_not_bytes(self, snapshot_id): diff --git a/tests/functional/test_provider.py b/tests/functional/test_provider.py index ab97be84ed..8dca463fc1 100644 --- a/tests/functional/test_provider.py +++ b/tests/functional/test_provider.py @@ -612,13 +612,11 @@ def test_ipc_per_network(project, key): ipc = "path/to/example.ipc" with project.temp_config(node={"ethereum": {"sepolia": {key: ipc}}}): node = project.network_manager.ethereum.sepolia.get_provider("node") - if key != "ipc_path": - assert node.uri == ipc - # else: uri gets to set to random HTTP from default settings, - # but we may want to change that behavior. - # TODO: 0.9 investigate not using random if ipc set. - assert node.ipc_path == Path(ipc) + if key == "uri": + assert node.uri == ipc + # else: uri ends up as a random HTTP URI from evmchains. + # TODO: Do we want to change this in 0.9? def test_snapshot(eth_tester_provider):