def main(): core = Contract("0x8d5ED43dCa8C2F7dFB20CF7b53CC7E593635d7b9") roles = { name: getattr(core, name)() for name in [x for x in core.__dict__ if x.endswith("_ROLE")] } names = {str(roles[name]): name for name in roles} tree = [] for name in roles: role = roles[name] size = core.getRoleMemberCount(role) if size == 0: tree.append([name]) else: tree.append( [ name, ["admin", names[str(core.getRoleAdmin(role))]], [ "members", *[get_name(core.getRoleMember(role, i)) for i in range(size)], ], ] ) print(build_tree(tree))
def main(): from yearn.v2.registry import Registry registry = Registry() print(registry) registry.load_strategies() tree = [] for vault in registry.vaults: transforms = { 'performanceFee': lambda bps: f'{bps / 10000:.2%}', 'activation': lambda ts: datetime.utcfromtimestamp(ts), 'debtRatio': lambda bps: f'{bps / 10000:.2%}', 'debtLimit': lambda tokens: f'{tokens / vault.scale if tokens != 2**256-1 else "unlimited"}', 'minDebtPerHarvest': lambda tokens: f'{tokens / vault.scale}', 'lastReport': lambda ts: datetime.utcfromtimestamp(ts), 'maxDebtPerHarvest': lambda tokens: f'{tokens / vault.scale if tokens != 2**256-1 else "unlimited"}', 'rateLimit': lambda tokens: f'{tokens / vault.scale if tokens != 2**256-1 else "unlimited"}/s', 'totalDebt': lambda tokens: f'{tokens / vault.scale}', 'totalGain': lambda tokens: f'{tokens / vault.scale}', 'totalLoss': lambda tokens: f'{tokens / vault.scale}', } strategies = [] for strategy in vault.strategies + vault.revoked_strategies: config = vault.vault.strategies(strategy.strategy).dict() color = 'green' if strategy in vault.strategies else 'red' strategies.append([ f'{config.get("debtRatio", 0) / 10000:.2%} ' + click.style(strategy.name, fg=color) + f' {strategy.strategy}', *[f'{k} = {transforms[k](v)}' for k, v in config.items()] ]) tree.append([ click.style(vault.name, fg='green', bold=True) + f' {vault.vault}', *strategies, ]) print(build_tree(tree))
def _step_external( step: Dict, last_step: Dict, start: Union[str, int], stop: Union[str, int], gas: Tuple[int, int], subcall: Dict, expand: bool, ) -> str: key = _step_internal(step, last_step, start, stop, gas, subcall) if not expand: return key mode = black.FileMode(line_length=60) result: OrderedDict = OrderedDict({key: {}}) result[key][f"address: {step['address']}"] = None if "value" in subcall: result[key][f"value: {subcall['value']}"] = None if "inputs" not in subcall: result[key][f"calldata: {subcall['calldata']}"] = None if subcall["inputs"]: result[key]["input arguments:"] = [ f"{k}: {black.format_str(str(v), mode=mode)}" for k, v in subcall["inputs"].items() ] else: result[key]["input arguments: None"] = None if "return_value" in subcall: value = subcall["return_value"] if isinstance(value, tuple) and len(value) > 1: result[key]["return values:"] = [ black.format_str(str(i), mode=mode) for i in value ] else: if isinstance(value, tuple): value = value[0] value_str = black.format_str(str(value), mode=mode) result[key][f"return value: {value_str}"] = None if "revert_msg" in subcall: result[key][ f"revert reason: {color('bright red')}{subcall['revert_msg']}{color}"] = None return build_tree(result, multiline_pad=0).rstrip()
def call_trace(self, expand: bool = False) -> None: """ Display the complete sequence of contracts and methods called during the transaction. The format: Contract.functionName [instruction] start:stop [gas used] * start:stop are index values for the `trace` member of this object, showing the points where the call begins and ends * for calls that include subcalls, gas use is displayed as [gas used in this frame / gas used in this frame + subcalls] * Calls displayed in red ended with a `REVERT` or `INVALID` instruction. Arguments --------- expand : bool If `True`, show an expanded call trace including inputs and return values """ trace = self.trace key = _step_internal(trace[0], trace[-1], 0, len(trace), self._get_trace_gas(0, len(self.trace))) call_tree: OrderedDict = OrderedDict({key: OrderedDict()}) active_tree = [call_tree[key]] # (index, depth, jumpDepth) for relevent steps in the trace trace_index = [(0, 0, 0) ] + [(i, trace[i]["depth"], trace[i]["jumpDepth"]) for i in range(1, len(trace)) if not _step_compare(trace[i], trace[i - 1])] subcalls = self.subcalls[::-1] for i, (idx, depth, jump_depth) in enumerate(trace_index[1:], start=1): last = trace_index[i - 1] if depth == last[1] and jump_depth < last[2]: # returning from an internal function, reduce tree by one active_tree.pop() continue elif depth < last[1]: # returning from an external call, return tree by jumpDepth of the previous depth active_tree = active_tree[:-(last[2] + 1)] continue if depth > last[1]: # called to a new contract end = next((x[0] for x in trace_index[i + 1:] if x[1] < depth), len(trace)) total_gas, internal_gas = self._get_trace_gas(idx, end) key = _step_external( trace[idx], trace[end - 1], idx, end, (total_gas, internal_gas), subcalls.pop(), expand, ) elif depth == last[1] and jump_depth > last[2]: # jumped into an internal function end = next( (x[0] for x in trace_index[i + 1:] if x[1] < depth or (x[1] == depth and x[2] < jump_depth)), len(trace), ) total_gas, internal_gas = self._get_trace_gas(idx, end) key = _step_internal(trace[idx], trace[end - 1], idx, end, (total_gas, internal_gas)) active_tree[-1][key] = OrderedDict() active_tree.append(active_tree[-1][key]) print( f"Call trace for '{color('bright blue')}{self.txid}{color}':\n" f"Initial call cost [{color('bright yellow')}{self._call_cost} gas{color}]" ) print(build_tree(call_tree).rstrip())