Beispiel #1
0
def _step_internal(
    step: Dict,
    last_step: Dict,
    start: Union[str, int],
    stop: Union[str, int],
    gas: Tuple[int, int],
    subcall: Dict = None,
) -> str:
    if last_step["op"] in {"REVERT", "INVALID"} and _step_compare(
            step, last_step):
        contract_color = color("bright red")
    else:
        contract_color = color(
            "bright cyan") if not step["jumpDepth"] else color()
    key = f"{color('dark white')}{contract_color}{step['fn']}  {color('dark white')}"

    left_bracket = f"{color('dark white')}["
    right_bracket = f"{color('dark white')}]"

    if subcall:
        key = f"{key}[{color}{subcall['op']}{right_bracket}  "

    key = f"{key}{start}:{stop}{color}"

    if gas:
        if gas[0] == gas[1]:
            gas_str = f"{color('bright yellow')}{gas[0]} gas"
        else:
            gas_str = f"{color('bright yellow')}{gas[0]} / {gas[1]} gas"
        key = f"{key}  {left_bracket}{gas_str}{right_bracket}"

    if last_step["op"] == "SELFDESTRUCT":
        key = f"{key}  {left_bracket}{color('bright red')}SELFDESTRUCT{right_bracket}"

    return key
Beispiel #2
0
def _step_print(
    step: Dict,
    last_step: Dict,
    indent: Optional[str],
    start: Union[str, int],
    stop: Union[str, int],
    gas: Tuple[int, int],
) -> str:
    print_str = f"\n{color('dark white')}"
    if indent is not None:
        print_str += f"{indent}\u2500"
    if last_step["op"] in {"REVERT", "INVALID"} and _step_compare(
            step, last_step):
        contract_color = color("bright red")
    else:
        contract_color = color(
            "bright magenta" if not step["jumpDepth"] else "")
    print_str += f"{contract_color}{step['fn']} {color('dark white')}{start}:{stop}{color}"
    if gas[0] == gas[1]:
        print_str += f"  [{color('bright yellow')}{gas[0]} gas{color}]"
    else:
        print_str += f"  [{color('bright yellow')}{gas[0]} / {gas[1]} gas{color}]"
    if not step["jumpDepth"]:
        print_str += (
            f"  {color('dark white')}({color}{step['address']}{color('dark white')}){color}"
        )
    return print_str
Beispiel #3
0
def _dir_color(obj):
    if type(obj).__name__ == "module":
        return color("module")
    if hasattr(obj, "_dir_color"):
        return color(obj._dir_color)
    if not callable(obj):
        return color("value")
    return color("callable")
Beispiel #4
0
def _dir_color(obj):
    if type(obj).__name__ == "module":
        return color("brownie blue")
    if hasattr(obj, "_dir_color"):
        return color(obj._dir_color)
    if not callable(obj):
        return color("bright blue")
    return color("bright cyan")
Beispiel #5
0
def print_console_report(stdout_report) -> None:
    """Highlight and print a given stdout report to the console.

    This adds color formatting to the given stdout report and prints
    a summary of the vulnerabilities MythX has detected.

    :return: None
    """

    total_issues = sum(x for i in stdout_report.values() for x in i.values())
    if not total_issues:
        notify("SUCCESS", "No issues found!")
        return

    # display console report
    total_high_severity = sum(i.get("HIGH", 0) for i in stdout_report.values())
    if total_high_severity:
        notify(
            "WARNING",
            f"Found {total_issues} issues including {total_high_severity} high severity!"
        )
    else:
        print(f"Found {total_issues} issues:")
    for name in sorted(stdout_report):
        print(f"\n  contract: {color('bright magenta')}{name}{color}")
        for key in [
                i for i in ("HIGH", "MEDIUM", "LOW")
                if i in stdout_report[name]
        ]:
            c = color("bright red" if key == "HIGH" else "bright yellow")
            print(f"    {key.title()}: {c}{stdout_report[name][key]}{color}")
Beispiel #6
0
def _step_print(
    step: Dict,
    last_step: Dict,
    indent: Optional[str],
    start: Union[str, int],
    stop: Union[str, int],
) -> str:
    print_str = f"\n{color['dull']}"
    if indent is not None:
        print_str += f"{indent}\u2500"
    if last_step["op"] in {"REVERT", "INVALID"} and _step_compare(
            step, last_step):
        contract_color = color("error")
    else:
        contract_color = color(
            "contract_method" if not step["jumpDepth"] else "")
    print_str += f"{contract_color}{step['fn']} {color['dull']}{start}:{stop}{color}"
    if not step["jumpDepth"]:
        print_str += f"  {color['dull']}({color}{step['address']}{color['dull']}){color}"
    return print_str
Beispiel #7
0
def _list(project_path):
    installed, modified = ethpm.get_installed_packages(project_path)
    package_list = sorted(installed + modified)
    if not package_list:
        print("No packages are currently installed in this project.")
        return
    if modified:
        notify(
            "WARNING",
            f"One or more files in {len(modified)} packages have been modified since installation.",
        )
        print("Unlink or reinstall them to silence this warning.")
        print(f"Modified packages name are highlighted in {color['bright blue']}blue{color}.\n")
    print(f"Found {color('bright magenta')}{len(package_list)}{color} installed packages:")
    for name in package_list:
        u = "\u2514" if name == package_list[-1] else "\u251c"
        c = color("bright blue") if name in modified else color("bright white")
        print(
            f" {color('bright black')}{u}\u2500{c}{name[0]}{color}@"
            f"{color('bright white')}{name[1]}{color}"
        )
Beispiel #8
0
    def generate_highlighting_report(self) -> None:
        """Generate a Brownie highlighting report from a MythX issue report.

        This will convert a MythX issue report into a Brownie report that allows
        issues to be highlighted in the native Brownie GUI. It iterates over the
        internal :code:`reports` dictionary and fills the :code:`highlight_report`
        instance variable.

        :return: None
        """

        source_to_name = {
            d["sourcePath"]: d["contractName"]
            for _, d in self.build.items()
        }
        for idx, (contract_name,
                  issue_report) in enumerate(self.reports.items()):
            print("Generating report for {}{}{} ({}/{})".format(
                color("bright blue"), contract_name, color, idx,
                len(self.reports)))
            for report in issue_report.issue_reports:
                for issue in report:
                    # convert issue locations to report locations
                    # severities are highlighted according to SEVERITY_COLOURS
                    for loc in issue.locations:
                        comp = loc.source_map.components[0]
                        source_list = loc.source_list or report.source_list

                        if source_list and 0 <= comp.file_id < len(
                                source_list):
                            filename = source_list[comp.file_id]
                            if filename not in source_to_name:
                                continue
                            contract_name = source_to_name[filename]
                            severity = issue.severity.name
                            self.highlight_report["highlights"][
                                "MythX"].setdefault(contract_name,
                                                    {filename: []})
                            self.highlight_report["highlights"]["MythX"][
                                contract_name][filename].append([
                                    comp.offset,
                                    comp.offset + comp.length,
                                    SEVERITY_COLOURS[severity],
                                    "{}: {}\n{}".format(
                                        issue.swc_id,
                                        issue.description_short,
                                        issue.description_long,
                                    ),
                                ])
Beispiel #9
0
    def __init__(self) -> None:
        brownie.chain.revert()
        sf.RuleBasedStateMachine.__init__(self)

        # pytest capturemanager plugin, added when accessed via the state_manager fixture
        capman = getattr(self, "_capman", None)
        if capman:
            with capman.global_and_fixture_disabled():
                c = color("red" if self._failed else "yellow")
                sys.stdout.write(f"{c}{marker[0]}\033[1D")
                sys.stdout.flush()
            marker.rotate(1)

        if hasattr(self, "setup"):
            self.setup()  # type: ignore
Beispiel #10
0
def _print_verbose_network_description(network_dict, is_last, indent=0):
    u = "\u2514" if is_last else "\u251c"
    v = " " if is_last else "\u2502"
    if "name" in network_dict:
        print(f"{color('bright black')}  {u}\u2500{color}{network_dict.pop('name')}")

    obj_keys = sorted(network_dict)
    if "id" in obj_keys:
        obj_keys.remove("id")
        obj_keys.insert(0, "id")

    for key in obj_keys:
        value = network_dict[key]
        u = "\u2514" if key == obj_keys[-1] else "\u251c"

        if indent:
            u = (" " * indent) + u
        c = color("green") if key == "id" else ""
        print(f"{color('bright black')}  {v} {u}\u2500{color}{key}: {c}{value}{color}")
Beispiel #11
0
def main():
    args = docopt(__doc__)
    project_path = project.check_for_project(".")
    if project_path is None:
        raise ProjectNotFound

    build_path = project_path.joinpath(
        _load_project_structure_config(project_path)["build"])

    contract_artifact_path = build_path.joinpath("contracts")
    interface_artifact_path = build_path.joinpath("interfaces")

    if args["--all"]:
        shutil.rmtree(contract_artifact_path, ignore_errors=True)
        shutil.rmtree(interface_artifact_path, ignore_errors=True)
    elif args["<contract>"]:
        for name in args["<contract>"]:
            path = contract_artifact_path.joinpath(f"{name}.json")
            if path.exists():
                path.unlink()

    proj = project.load()

    if args["--size"]:
        print("============ Deployment Bytecode Sizes ============")
        codesize = []
        for contract in proj:
            bytecode = contract._build["deployedBytecode"]
            if bytecode:
                codesize.append((contract._name, len(bytecode) // 2))
        indent = max(len(i[0]) for i in codesize)
        for name, size in sorted(codesize, key=lambda k: k[1], reverse=True):
            pct = size / 24577
            pct_color = color(
                next((i[1] for i in CODESIZE_COLORS if pct >= i[0]), ""))
            print(
                f"  {name:<{indent}}  -  {size:>6,}B  ({pct_color}{pct:.2%}{color})"
            )
        print()

    print(
        f"Project has been compiled. Build artifacts saved at {contract_artifact_path}"
    )
Beispiel #12
0
def test_call():
    assert color("red") != ""
    assert str(color) == "\x1b[0;m"
Beispiel #13
0
def test_bright_dark():
    assert color("yellow") != color("dark yellow") != color(
        "bright yellow") != ""
Beispiel #14
0
def test_unknown():
    assert color("potato") == color()
Beispiel #15
0
def main():
    args = docopt(__doc__)
    _update_argv_from_docopt(args)

    project_path = project.check_for_project(".")
    if project_path is None:
        raise ProjectNotFound

    build = project.load()._build

    print("Preparing project data for submission to MythX...")
    contracts, libraries = get_contract_types(build)

    job_data = assemble_contract_jobs(build, contracts)
    job_data = update_contract_jobs_with_dependencies(build, contracts,
                                                      libraries, job_data)

    client, authenticated = get_mythx_client()

    job_uuids = send_to_mythx(job_data, client, authenticated)

    # exit if user wants an async analysis run
    if ARGV["async"] and authenticated:
        print(
            "\nAll contracts were submitted successfully. Check the dashboard at "
            "https://dashboard.mythx.io/ for the progress and results of your analyses"
        )
        return

    print("\nWaiting for results...")
    wait_for_jobs(job_uuids, client)

    # assemble report json
    source_to_name = get_contract_locations(build)
    highlight_report = {"highlights": {"MythX": {}}}
    stdout_report = {}
    for c, uuid in enumerate(job_uuids, start=1):
        print(
            f"Generating report for job {color['value']}{uuid}{color} ({c}/{len(job_uuids)})"
        )
        if authenticated:
            print("You can also check the results at {}{}\n".format(
                DASHBOARD_BASE_URL, uuid))

        update_report(client, uuid, highlight_report, stdout_report,
                      source_to_name)

    # erase previous report
    report_path = Path("reports/security.json")
    if report_path.exists():
        report_path.unlink()

    total_issues = sum(x for i in stdout_report.values() for x in i.values())
    if not total_issues:
        notify("SUCCESS", "No issues found!")
        return

    # display console report
    total_high_severity = sum(i.get("HIGH", 0) for i in stdout_report.values())
    if total_high_severity:
        notify(
            "WARNING",
            f"Found {total_issues} issues including {total_high_severity} high severity!"
        )
    else:
        print(f"Found {total_issues} issues:")
    for name in sorted(stdout_report):
        print(f"\n  contract: {color['contract']}{name}{color}")
        for key in [
                i for i in ("HIGH", "MEDIUM", "LOW")
                if i in stdout_report[name]
        ]:
            c = color("bright " + SEVERITY_COLOURS[key])
            print(f"    {key.title()}: {c}{stdout_report[name][key]}{color}")

    # Write report to Brownie directory
    with report_path.open("w+") as fp:
        json.dump(highlight_report, fp, indent=2, sort_keys=True)

    # Launch GUI if user requested it
    if ARGV["gui"]:
        print("Launching the Brownie GUI")
        Gui = importlib.import_module("brownie._gui").Gui
        Gui().mainloop()
Beispiel #16
0
def test_call_getitem():
    assert color("success") == color["success"] != ""
    assert str(color) == "\x1b[0;m"
Beispiel #17
0
def _cov_color(pct):
    return color(next(i[1] for i in COVERAGE_COLORS if pct <= i[0]))
Beispiel #18
0
def test_show_colors_config(config):
    config.settings["console"]["show_colors"] = False
    assert color("blue") == ""