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")
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)
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)
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
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") })
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 + [""]
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")
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)
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})
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())
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
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")
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")
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})
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
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
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
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")
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
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}")
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.')
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
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)
def get_proj(proj_name: str): return next(p for p in project.get_loaded_projects() if p._name == proj_name)