Exemplo n.º 1
0
    def _contract_deferred(name):
        for proj in project.get_loaded_projects():
            if name in proj.dict():
                return st.sampled_from(list(proj[name]))

        raise NameError(
            f"Contract '{name}' does not exist in any active projects")
Exemplo n.º 2
0
    def __init__(self):
        projects = get_loaded_projects()
        if not projects:
            raise SystemError("No project loaded")

        if len(projects) > 1:
            raise SystemError("More than one active project")

        if self._active.is_set():
            raise SystemError("GUI is already active")
        self._active.set()

        self._project = projects[0]
        name = self._project._name
        super().__init__(className=f" Brownie GUI - {name}")
        self.bind("<Escape>", lambda k: self.destroy())

        # main widgets
        self.main = MainFrame(self)
        self.main.pack(side="bottom", expand=True, fill="both")

        # toolbar widgets
        self.toolbar = ToolbarFrame(self, self._project)
        self.toolbar.pack(side="top", expand="true", fill="both")

        self.active_report = False
        set_style(self)
Exemplo n.º 3
0
    def pytest_sessionfinish(self, session):
        """
        Called after whole test run finished, right before returning the exit
        status to the system.

        * Aggregates results from `build/tests-{workerid}.json` files and stores
          them as `build/test.json`.
        * Generates coverage report and outputs results to console
        * Closes all active projects
        """
        if session.testscollected == 0:
            raise pytest.UsageError(
                "xdist workers failed to collect tests. Ensure all test cases are "
                "isolated with the module_isolation or fn_isolation fixtures.\n\n"
                "https://eth-brownie.readthedocs.io/en/stable/tests.html#isolating-tests"
            )
        build_path = self.project._build_path

        report = {"tests": {}, "contracts": self.contracts, "tx": {}}
        for path in list(build_path.glob("tests-*.json")):
            with path.open() as fp:
                data = json.load(fp)
            assert data["contracts"] == report["contracts"]
            report["tests"].update(data["tests"])
            report["tx"].update(data["tx"])
            path.unlink()
        with build_path.joinpath("tests.json").open("w") as fp:
            json.dump(report, fp, indent=2, sort_keys=True, default=sorted)
        coverage_eval = coverage.get_merged_coverage_eval(report["tx"])
        self._sessionfinish_coverage(coverage_eval)

        for project in get_loaded_projects():
            project.close(raises=False)
Exemplo n.º 4
0
def deploy_proxy(deployer, proxy_admin, ImplContract, *args):
    """
    @dev
        Deploys upgradable contract with proxy from oz-contracts package
    @param deployer Brownie account used to deploy a contract.
    @param proxy_admin Admin address (e.g. from the contract deployed deploy_admin() or custom admin).
    @param ImplContract Brownie Contract container for the implementation.
    @param args Initializer arguments.
    @return Contract container for the proxy wrapped into the implementation interface
            Contract container for the proxy
            Contract container for the implementation
    """
    cur_project = project.get_loaded_projects()[0]

    #Deploy implementation first
    contract_impl = deployer.deploy(ImplContract)

    #Deploy proxy next
    initializer_data = contract_impl.initialize.encode_input(*args)
    proxy_contract = deployer.deploy(cur_project.UtilProxy, contract_impl.address, proxy_admin, initializer_data)

    #Route all calls to go through the proxy contract
    contract_impl_from_proxy = Contract.from_abi(ImplContract._name, proxy_contract.address, ImplContract.abi)

    return contract_impl_from_proxy, proxy_contract, contract_impl
Exemplo n.º 5
0
def withdraw_asset_on_ethereum(burn_tx_id: str = MATIC_BURN_TX_ID,
                               sender=MSG_SENDER):
    print("Building Calldata")
    calldata = build_calldata(burn_tx_id)
    fp = f"withdraw-calldata-{datetime.now().isoformat()}.txt"
    with open(fp, "w") as f:
        f.write(calldata.hex())

    root_chain_mgr_proxy_addr = ADDRS[
        network.show_active()]["RootChainManagerProxy"]
    abi = get_loaded_projects()[0].interface.RootChainManager.abi
    root_chain_mgr = Contract.from_abi("RootChainManager",
                                       root_chain_mgr_proxy_addr, abi)

    print("Calling Exit Function on Root Chain Manager")
    root_chain_mgr.exit(calldata, {
        "from": sender,
        "gas_price": GasNowScalingStrategy("fast")
    })

    # transfer USDC out of the root receiver
    usdc = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
    root_receiver = RootForwarder.at(
        "0x4473243A61b5193670D1324872368d015081822f")
    root_receiver.transfer(usdc, {
        "from": sender,
        "gas_price": GasNowScalingStrategy("fast")
    })
Exemplo n.º 6
0
def _build_gas_profile_output():
    # Formats gas profile report that may be printed to the console
    exclude_paths, exclude_contracts = _load_report_exclude_data(
        CONFIG.settings["reports"])
    try:
        project = get_loaded_projects()[0]
    except IndexError:
        project = None

    gas = TxHistory().gas_profile
    sorted_gas = sorted(gas.items())
    grouped_by_contract = {}
    padding = {}

    lines = [""]

    only_include_project = CONFIG.settings["reports"]["only_include_project"]
    for full_name, values in sorted_gas:
        contract, function = full_name.split(".", 1)

        try:
            if project._sources.get_source_path(contract) in exclude_paths:
                continue
        except (AttributeError, KeyError):
            # filters contracts that are not part of the project
            if only_include_project:
                continue
        if contract in exclude_contracts:
            continue

        # calculate padding to get table-like formatting
        padding["fn"] = max(padding.get("fn", 0), len(str(function)))
        for k, v in values.items():
            padding[k] = max(padding.get(k, 0), len(str(v)))

        # group functions with payload by contract name
        if contract in grouped_by_contract.keys():
            grouped_by_contract[contract][function] = values
        else:
            grouped_by_contract[contract] = {function: values}

    for contract, functions in grouped_by_contract.items():
        lines.append(f"{color('bright magenta')}{contract}{color} <Contract>")
        sorted_functions = dict(
            sorted(functions.items(),
                   key=lambda value: value[1]["avg"],
                   reverse=True))
        for ix, (fn_name, values) in enumerate(sorted_functions.items()):
            prefix = "\u2514\u2500" if ix == len(
                functions) - 1 else "\u251c\u2500"
            fn_name = fn_name.ljust(padding["fn"])
            values["avg"] = int(values["avg"])
            values = {k: str(v).rjust(padding[k]) for k, v in values.items()}
            lines.append(
                f"   {prefix} {fn_name} -  avg: {values['avg']}  avg (confirmed):"
                f" {values['avg_success']}  low: {values['low']}  high: {values['high']}"
            )

    return lines + [""]
Exemplo n.º 7
0
def burn_asset_on_matic(asset=MATIC_ERC20_ASSET_ADDR, amount=BURN_AMOUNT, sender=MSG_SENDER):
    """Burn an ERC20 asset on Matic Network"""
    abi = get_loaded_projects()[0].interface.ChildERC20.abi
    asset = Contract.from_abi("ChildERC20", asset, abi)

    tx = asset.withdraw(amount, {"from": sender})
    print("Burn transaction has been sent.")
    print(f"Visit https://explorer-mainnet.maticvigil.com/tx/{tx.txid} for confirmation")
Exemplo n.º 8
0
def deploy_admin(deployer):
    """
    @dev
        Deploys admin contract from oz-contracts package.
        Should be used once
    @param deployer Brownie account used to deploy a contract.
    @return Contract container for the admin contract
    """
    cur_project = project.get_loaded_projects()[0]
    return deployer.deploy(cur_project.UtilProxyAdmin)
Exemplo n.º 9
0
def withdraw_asset_on_ethereum(burn_tx_id: str = MATIC_BURN_TX_ID, sender=MSG_SENDER):
    print("Building Calldata")
    calldata = build_calldata(burn_tx_id)

    root_chain_mgr_proxy_addr = ADDRS[network.show_active()]["RootChainManagerProxy"]
    abi = get_loaded_projects()[0].interface.RootChainManager.abi
    root_chain_mgr = Contract.from_abi("RootChainManager", root_chain_mgr_proxy_addr, abi)

    print("Calling Exit Function on Root Chain Manager")
    root_chain_mgr.exit(calldata, {"from": sender})
Exemplo n.º 10
0
def main():
    # dev = accounts.add(os.getenv(config["wallets"]["from_key"]))

    print(f"Network: {network.show_active()}")
    # pm("alphachainio/[email protected]").LinkToken

    p = project.load("alphachainio/[email protected]")
    print(project.get_loaded_projects())

    print(sources.get_contract_list())
Exemplo n.º 11
0
def is_burn_checkpointed(burn_tx_id: str = MATIC_BURN_TX_ID, silent: bool = False) -> bool:
    """Check a burn tx has been checkpointed on Ethereum mainnet."""
    _, _, burn_tx_block = fetch_burn_tx_data(burn_tx_id)
    root_chain_proxy_addr = ADDRS[network.show_active()]["RootChainProxy"]
    abi = get_loaded_projects()[0].interface.RootChain.abi
    root_chain = Contract.from_abi("RootChain", root_chain_proxy_addr, abi)

    is_checkpointed = root_chain.getLastChildBlock() >= burn_tx_block["number"]
    if not silent:
        print(f"Has Burn TX been Checkpointed? {is_checkpointed}")
    return is_checkpointed
Exemplo n.º 12
0
def test_calldata(burn_tx: str, exit_tx: str):
    print(f"Testing Burn TX: {burn_tx}")

    root_chain_mgr_proxy_addr = ADDRS[network.show_active()]["RootChainManagerProxy"]
    abi = get_loaded_projects()[0].interface.RootChainManager.abi
    root_chain_mgr = Contract.from_abi("RootChainManager", root_chain_mgr_proxy_addr, abi)

    calldata = HexBytes(root_chain_mgr.exit.encode_input(build_calldata(burn_tx)))
    input_data = HexBytes(web3.eth.get_transaction(exit_tx)["input"])

    assert calldata == input_data
    print("Test passed")
Exemplo n.º 13
0
def pytest_configure(config):
    if _get_project_path():

        if not config.getoption("showinternal"):
            # do not include brownie internals in tracebacks
            base_path = Path(sys.modules["brownie"].__file__).parent.as_posix()
            for module in [
                    v for v in sys.modules.values()
                    if getattr(v, "__file__", None)
                    and v.__file__.startswith(base_path)
            ]:
                module.__tracebackhide__ = True
                module.__hypothesistracebackhide__ = True

        # enable verbose output if stdout capture is disabled
        if config.getoption("capture") == "no":
            config.option.verbose = True

        # if verbose mode is enabled, also enable hypothesis verbose mode
        if config.option.verbose:
            _modify_hypothesis_settings({"verbosity": 2}, "brownie-verbose")

        if config.getoption("numprocesses"):
            if config.getoption("interactive"):
                raise ValueError("Cannot use --interactive mode with xdist")
            Plugin = PytestBrownieMaster
        elif hasattr(config, "workerinput"):
            Plugin = PytestBrownieXdistRunner
        else:
            Plugin = PytestBrownieRunner

        if config.getoption("interactive"):
            config.option.failfast = True

        if config.getoption("failfast"):
            _modify_hypothesis_settings(
                {
                    "phases": {
                        "explicit": True,
                        "generate": True,
                        "target": True
                    }
                }, "brownie-failfast")

        active_project = project.get_loaded_projects()[0]
        session = Plugin(config, active_project)
        config.pluginmanager.register(session, "brownie-core")

        if not config.getoption("numprocesses"):
            fixtures = PytestBrownieFixtures(config, active_project)
            config.pluginmanager.register(fixtures, "brownie-fixtures")
Exemplo n.º 14
0
def withdraw_asset_on_ethereum(burn_tx_id: str = MATIC_BURN_TX_ID,
                               sender=MSG_SENDER):
    print("Building Calldata")
    calldata = build_calldata(burn_tx_id)

    root_chain_mgr_proxy_addr = ADDRS[
        network.show_active()]["RootChainManagerProxy"]
    abi = get_loaded_projects()[0].interface.RootChainManager.abi
    root_chain_mgr = Contract.from_abi("RootChainManager",
                                       root_chain_mgr_proxy_addr, abi)

    print("Calling Exit Function on Root Chain Manager")
    root_chain_mgr.exit(calldata, {"from": sender})

    # transfer USDC out of the root receiver
    usdc = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
    root_receiver = Contract("0x4473243A61b5193670D1324872368d015081822f")
    root_receiver.transfer(usdc, {"from": sender})
Exemplo n.º 15
0
def connect(network: str = None, launch_rpc: bool = True) -> None:
    """Connects to the network.

    Args:
        network: string of of the name of the network to connect to

    Network information is retrieved from brownie-config.json"""
    if is_connected():
        raise ConnectionError(
            f"Already connected to network '{CONFIG['active_network']['name']}'"
        )
    try:
        active = _modify_network_config(network
                                        or CONFIG["network"]["default"])
        if "host" not in active:
            raise KeyError(
                f"No host in brownie-config.json for network '{active['name']}'"
            )
        host = active["host"]

        if ":" not in host.split("//", maxsplit=1)[-1]:
            try:
                host += f":{active['test_rpc']['port']}"
            except KeyError:
                pass

        web3.connect(host)
        if "test_rpc" in active and launch_rpc and not rpc.is_active():
            if is_connected():
                if web3.eth.blockNumber != 0:
                    raise ValueError("Local RPC Client has a block height > 0")
                rpc.attach(host)
            else:
                rpc.launch(**active["test_rpc"])
        else:
            Accounts()._reset()
        if CONFIG["active_network"]["persist"]:
            for p in project.get_loaded_projects():
                p._load_deployments()

    except Exception:
        CONFIG["active_network"] = {"name": None}
        web3.disconnect()
        raise
Exemplo n.º 16
0
def _build_coverage_output(coverage_eval):
    # Formats a coverage evaluation report that may be printed to the console

    exclude_paths, exclude_contracts = _load_report_exclude_data(
        CONFIG.settings["reports"])
    all_totals = [(i, _get_totals(i._build, coverage_eval, exclude_contracts))
                  for i in get_loaded_projects()]
    all_totals = [i for i in all_totals if i[1]]
    lines = []

    for project, totals in all_totals:

        if len(all_totals) > 1:
            lines.append(
                f"\n======== {color('bright magenta')}{project._name}{color} ========"
            )

        for contract_name in sorted(totals):
            if project._sources.get_source_path(
                    contract_name) in exclude_paths:
                continue

            pct = _pct(
                totals[contract_name]["totals"]["statements"],
                totals[contract_name]["totals"]["branches"],
            )
            lines.append(
                f"\n  contract: {color('bright magenta')}{contract_name}{color}"
                f" - {_cov_color(pct)}{pct:.1%}{color}")

            cov = totals[contract_name]
            results = []
            for fn_name, statement_cov in cov["statements"].items():
                branch_cov = cov["branches"][fn_name] if fn_name in cov[
                    "branches"] else (0, 0, 0)
                pct = _pct(statement_cov, branch_cov)
                results.append((fn_name, pct))

            for fn_name, pct in sorted(results, key=lambda k: (-k[1], k[0])):
                lines.append(
                    f"    {fn_name} - {_cov_color(pct)}{pct:.1%}{color}")

    return lines
Exemplo n.º 17
0
def connect(network: str = None, launch_rpc: bool = True) -> None:
    """Connects to the network.

    Args:
        network: string of of the name of the network to connect to

    Network information is retrieved from brownie-config.json"""
    if is_connected():
        raise ConnectionError(
            f"Already connected to network '{CONFIG.active_network['id']}'")
    try:
        active = CONFIG.set_active_network(network)
        host = active["host"]

        if ":" not in host.split("//", maxsplit=1)[-1]:
            try:
                host += f":{active['cmd_settings']['port']}"
            except KeyError:
                pass

        web3.connect(host, active.get("timeout", 30))
        if CONFIG.network_type == "development" and launch_rpc and not rpc.is_active(
        ):
            if is_connected():
                if web3.eth.blockNumber != 0:
                    warnings.warn(
                        f"Development network has a block height of {web3.eth.blockNumber}",
                        BrownieEnvironmentWarning,
                    )
                rpc.attach(host)
            else:
                rpc.launch(active["cmd"], **active["cmd_settings"])
        else:
            Accounts()._reset()
        if CONFIG.network_type == "live" or CONFIG.settings[
                "dev_deployment_artifacts"]:
            for p in project.get_loaded_projects():
                p._load_deployments()

    except Exception:
        CONFIG.clear_active()
        web3.disconnect()
        raise
Exemplo n.º 18
0
    def __init__(self):
        projects = get_loaded_projects()

        if self._active:
            raise SystemError("GUI is already active")
        if not projects:
            raise SystemError("No project loaded")
        if len(projects) > 1:
            raise SystemError("More than one active project")
        Root._active = True

        self.active_project = projects[0]
        self.pcMap = {}

        self.report_key = None
        self.highlight_key = None
        self.reports = {}
        for path in self.active_project._path.glob("reports/*.json"):
            try:
                with path.open() as fp:
                    self.reports[path.stem] = json.load(fp)
            except Exception:
                continue

        super().__init__(
            className=f" Brownie GUI - {self.active_project._name}")
        self.bind("<Escape>", lambda k: self.destroy())

        # geometry and styling
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, minsize=30)
        self.rowconfigure(1, weight=1)
        set_style(self)

        # main widgets
        self.main = MainFrame(self)
        self.main.grid(row=1, column=0, sticky="nsew")

        # toolbar widgets
        self.toolbar = ToolbarFrame(self, self.active_project)
        self.toolbar.grid(row=0, column=0, sticky="nsew")
Exemplo n.º 19
0
def connect(network: str = None, launch_rpc: bool = True) -> None:
    """Connects to the network.

    Args:
        network: string of of the name of the network to connect to

    Network information is retrieved from brownie-config.json"""
    if is_connected():
        raise ConnectionError(f"Already connected to network '{CONFIG.active_network['id']}'")
    try:
        active = CONFIG.set_active_network(network)
        if "host" not in active:
            raise KeyError(f"No host in brownie-config.json for network '{active['id']}'")
        host = active["host"]

        if ":" not in host.split("//", maxsplit=1)[-1]:
            try:
                host += f":{active['cmd_settings']['port']}"
            except KeyError:
                pass

        web3.connect(host)
        if CONFIG.network_type == "development" and launch_rpc and not rpc.is_active():
            if is_connected():
                if web3.eth.blockNumber != 0:
                    raise ValueError("Local RPC Client has a block height > 0")
                rpc.attach(host)
            else:
                rpc.launch(active["cmd"], **active["cmd_settings"])
        else:
            Accounts()._reset()
        if CONFIG.network_type == "live":
            for p in project.get_loaded_projects():
                p._load_deployments()

    except Exception:
        CONFIG.clear_active()
        web3.disconnect()
        raise
Exemplo n.º 20
0
def _print_coverage_totals(build, coverage_eval):
    # Formats and prints a coverage evaluation report to the console
    all_totals = [(i._name, _get_totals(i._build, coverage_eval))
                  for i in get_loaded_projects()]
    print("\n\nCoverage analysis:")

    for project_name, totals in all_totals:
        if not totals:
            continue

        print(f"\n ===== {color('bright magenta')}{project_name}{color} =====")

        for name in sorted(totals):
            pct = _pct(totals[name]["totals"]["statements"],
                       totals[name]["totals"]["branches"])
            print(f"\n  contract: {color('bright magenta')}{name}{color}"
                  f" - {_cov_color(pct)}{pct:.1%}{color}")
            cov = totals[name]
            for fn_name, count in cov["statements"].items():
                branch = cov["branches"][fn_name] if fn_name in cov[
                    "branches"] else (0, 0, 0)
                pct = _pct(count, branch)
                print(f"    {fn_name} - {_cov_color(pct)}{pct:.1%}{color}")
Exemplo n.º 21
0
def main():
    proj_name = sidebar()
    st.subheader(f"Project ◇ {proj_name}")

    loaded_projs = project.get_loaded_projects()
    # print([p._name for p in loaded_projs])
    reload(proj_name)
    if proj_name not in [p._name for p in loaded_projs]:
        proj = load_proj(proj_name)
    else:
        proj = next(p for p in loaded_projs if p._name == proj_name)

    # print_info()
    contract_name = list_contracts(proj)
    # show_source(proj, contract_name)
    show_abi(proj, contract_name)
    # inst=manage_token(proj, contract_name)
    inst = get_contract(proj_name, contract_name)
    if inst:
        st.write(inst)
        show_functions(proj, contract_name, inst)
    else:
        st.write('No instance.')
Exemplo n.º 22
0
def fetch_block_inclusion_data(child_block_number: int) -> dict:
    """Fetch burn tx checkpoint block inclusion data.

    Args:
        child_block_number: The block number of the burn tx was included in on
            the matic network
    """
    CHECKPOINT_ID_INTERVAL = 10000

    root_chain_proxy_addr = ADDRS[network.show_active()]["RootChainProxy"]
    abi = get_loaded_projects()[0].interface.RootChain.abi
    root_chain = Contract.from_abi("RootChain", root_chain_proxy_addr, abi)

    start = 1
    end = root_chain.currentHeaderBlock() // CHECKPOINT_ID_INTERVAL

    header_block_number = None
    while start <= end:
        if start == end:
            header_block_number = start

        middle = (start + end) // 2
        header_block = root_chain.headerBlocks(middle * CHECKPOINT_ID_INTERVAL)
        header_start = header_block["start"]
        header_end = header_block["end"]

        if header_start <= child_block_number <= header_end:
            header_block_number = middle
            break
        elif header_start > child_block_number:
            # child block was checkpointed after
            end = middle - 1
        elif header_end < child_block_number:
            # child block was checkpointed before
            start = middle + 1

    return header_start, header_end, header_block_number * CHECKPOINT_ID_INTERVAL
Exemplo n.º 23
0
def get_proxy_admin(proxy_admin_address):
    cur_project = project.get_loaded_projects()[0]
    return Contract.from_abi(cur_project.UtilProxyAdmin._name, proxy_admin_address, cur_project.UtilProxyAdmin.abi)
Exemplo n.º 24
0
def get_proj(proj_name: str):
    return next(p for p in project.get_loaded_projects()
                if p._name == proj_name)