Exemple #1
0
def _handle_bytecode(crytic_compile: "CryticCompile", target: str,
                     result_b: bytes):
    # There is no direct API to get the bytecode from etherscan
    # The page changes from time to time, we use for now a simple parsing, it will not be robust
    begin = """Search Algorithm">\nSimilar Contracts</button>\n"""
    begin += """<div id="dividcode">\n<pre class=\'wordwrap\' style=\'height: 15pc;\'>0x"""
    result = result_b.decode("utf8")
    # Removing everything before the begin string
    result = result[result.find(begin) + len(begin):]
    bytecode = result[:result.find("<")]

    contract_name = f"Contract_{target}"

    contract_filename = Filename(absolute="", relative="", short="", used="")

    crytic_compile.contracts_names.add(contract_name)
    crytic_compile.contracts_filenames[contract_name] = contract_filename
    crytic_compile.abis[contract_name] = {}
    crytic_compile.bytecodes_init[contract_name] = bytecode
    crytic_compile.bytecodes_runtime[contract_name] = ""
    crytic_compile.srcmaps_init[contract_name] = []
    crytic_compile.srcmaps_runtime[contract_name] = []

    crytic_compile.compiler_version = CompilerVersion(compiler="unknown",
                                                      version="",
                                                      optimized=None)

    crytic_compile.bytecode_only = True
Exemple #2
0
def load_from_compile(crytic_compile, loaded_json):
    crytic_compile._asts = loaded_json['asts']
    crytic_compile._compiler_version = CompilerVersion(
        compiler=loaded_json['compiler']['compiler'],
        version=loaded_json['compiler']['version'],
        optimized=loaded_json['compiler']['optimized'])
    for contract_name, contract in loaded_json['contracts'].items():
        crytic_compile._contracts_name.add(contract_name)
        filename = Filename(absolute=contract['filenames']['absolute'],
                            relative=contract['filenames']['relative'],
                            short=contract['filenames']['short'],
                            used=contract['filenames']['used'])
        crytic_compile._contracts_filenames[contract_name] = filename

        crytic_compile._abis[contract_name] = contract['abi']
        crytic_compile._init_bytecodes[contract_name] = contract['bin']
        crytic_compile._runtime_bytecodes[contract_name] = contract[
            'bin-runtime']
        crytic_compile._srcmaps[contract_name] = contract['srcmap'].split(';')
        crytic_compile._srcmaps_runtime[contract_name] = contract[
            'srcmap-runtime'].split(';')
        crytic_compile._libraries[contract_name] = contract['libraries']

        if contract['is_dependency']:
            crytic_compile._dependencies.add(filename.absolute)
            crytic_compile._dependencies.add(filename.relative)
            crytic_compile._dependencies.add(filename.short)
            crytic_compile._dependencies.add(filename.used)

    # Set our filenames
    crytic_compile._filenames = set(
        crytic_compile._contracts_filenames.values())

    crytic_compile._working_dir = loaded_json['working_dir']
    crytic_compile._type = loaded_json['type']
Exemple #3
0
def _load_from_compile_legacy2(crytic_compile: "CryticCompile", loaded_json: Dict) -> None:
    """Load from old (old) export

    Args:
        crytic_compile (CryticCompile): CryticCompile object to populate
        loaded_json (Dict): Json representation of the CryticCompile object
    """

    for key, compilation_unit_json in loaded_json["compilation_units"].items():
        compilation_unit = CompilationUnit(crytic_compile, key)
        compilation_unit.compiler_version = CompilerVersion(
            compiler=compilation_unit_json["compiler"]["compiler"],
            version=compilation_unit_json["compiler"]["version"],
            optimized=compilation_unit_json["compiler"]["optimized"],
        )
        for contract_name, contract in compilation_unit_json["contracts"].items():
            compilation_unit.contracts_names.add(contract_name)
            filename = Filename(
                absolute=contract["filenames"]["absolute"],
                relative=contract["filenames"]["relative"],
                short=contract["filenames"]["short"],
                used=contract["filenames"]["used"],
            )
            compilation_unit.filename_to_contracts[filename].add(contract_name)

            compilation_unit.abis[contract_name] = contract["abi"]
            compilation_unit.bytecodes_init[contract_name] = contract["bin"]
            compilation_unit.bytecodes_runtime[contract_name] = contract["bin-runtime"]
            compilation_unit.srcmaps_init[contract_name] = contract["srcmap"].split(";")
            compilation_unit.srcmaps_runtime[contract_name] = contract["srcmap-runtime"].split(";")
            compilation_unit.libraries[contract_name] = contract["libraries"]

            userdoc = contract.get("userdoc", {})
            devdoc = contract.get("devdoc", {})
            compilation_unit.natspec[contract_name] = Natspec(userdoc, devdoc)

            if contract["is_dependency"]:
                crytic_compile.dependencies.add(filename.absolute)
                crytic_compile.dependencies.add(filename.relative)
                crytic_compile.dependencies.add(filename.short)
                crytic_compile.dependencies.add(filename.used)
        compilation_unit.asts = compilation_unit_json["asts"]

        if "filenames" in compilation_unit_json:
            compilation_unit.filenames = {
                _convert_dict_to_filename(filename)
                for filename in compilation_unit_json["filenames"]
            }
        else:
            # For legay code, we recover the filenames from the contracts list
            # This is not perfect, as a filename might not be associated to any contract
            for contract_name, contract in compilation_unit_json["contracts"].items():
                filename = _convert_dict_to_filename(contract["filenames"])
                compilation_unit.filenames.add(filename)
Exemple #4
0
def load_from_compile(crytic_compile: "CryticCompile",
                      loaded_json: Dict) -> Tuple[int, List[str]]:
    """
    Load from json

    :param crytic_compile:
    :param loaded_json:
    :return:
    """
    crytic_compile.package_name = loaded_json.get("package", None)
    crytic_compile.asts = loaded_json["asts"]
    crytic_compile.compiler_version = CompilerVersion(
        compiler=loaded_json["compiler"]["compiler"],
        version=loaded_json["compiler"]["version"],
        optimized=loaded_json["compiler"]["optimized"],
    )
    for contract_name, contract in loaded_json["contracts"].items():
        crytic_compile.contracts_names.add(contract_name)
        filename = Filename(
            absolute=contract["filenames"]["absolute"],
            relative=contract["filenames"]["relative"],
            short=contract["filenames"]["short"],
            used=contract["filenames"]["used"],
        )
        crytic_compile.contracts_filenames[contract_name] = filename

        crytic_compile.abis[contract_name] = contract["abi"]
        crytic_compile.bytecodes_init[contract_name] = contract["bin"]
        crytic_compile.bytecodes_runtime[contract_name] = contract[
            "bin-runtime"]
        crytic_compile.srcmaps_init[contract_name] = contract["srcmap"].split(
            ";")
        crytic_compile.srcmaps_runtime[contract_name] = contract[
            "srcmap-runtime"].split(";")
        crytic_compile.libraries[contract_name] = contract["libraries"]

        userdoc = contract.get("userdoc", {})
        devdoc = contract.get("devdoc", {})
        crytic_compile.natspec[contract_name] = Natspec(userdoc, devdoc)

        if contract["is_dependency"]:
            crytic_compile.dependencies.add(filename.absolute)
            crytic_compile.dependencies.add(filename.relative)
            crytic_compile.dependencies.add(filename.short)
            crytic_compile.dependencies.add(filename.used)

    # Set our filenames
    crytic_compile.filenames = set(crytic_compile.contracts_filenames.values())

    crytic_compile.working_dir = loaded_json["working_dir"]

    return loaded_json["type"], loaded_json.get("unit_tests", [])
Exemple #5
0
def _load_from_compile_current(crytic_compile: "CryticCompile", loaded_json: Dict) -> None:
    for key, compilation_unit_json in loaded_json["compilation_units"].items():
        compilation_unit = CompilationUnit(crytic_compile, key)
        compilation_unit.compiler_version = CompilerVersion(
            compiler=compilation_unit_json["compiler"]["compiler"],
            version=compilation_unit_json["compiler"]["version"],
            optimized=compilation_unit_json["compiler"]["optimized"],
        )
        for contracts_data in compilation_unit_json["contracts"].values():
            for contract_name, contract in contracts_data.items():
                compilation_unit.contracts_names.add(contract_name)
                filename = Filename(
                    absolute=contract["filenames"]["absolute"],
                    relative=contract["filenames"]["relative"],
                    short=contract["filenames"]["short"],
                    used=contract["filenames"]["used"],
                )
                compilation_unit.filename_to_contracts[filename].add(contract_name)

                compilation_unit.abis[contract_name] = contract["abi"]
                compilation_unit.bytecodes_init[contract_name] = contract["bin"]
                compilation_unit.bytecodes_runtime[contract_name] = contract["bin-runtime"]
                compilation_unit.srcmaps_init[contract_name] = contract["srcmap"].split(";")
                compilation_unit.srcmaps_runtime[contract_name] = contract["srcmap-runtime"].split(
                    ";"
                )
                compilation_unit.libraries[contract_name] = contract["libraries"]

                userdoc = contract.get("userdoc", {})
                devdoc = contract.get("devdoc", {})
                compilation_unit.natspec[contract_name] = Natspec(userdoc, devdoc)

                if contract["is_dependency"]:
                    crytic_compile.dependencies.add(filename.absolute)
                    crytic_compile.dependencies.add(filename.relative)
                    crytic_compile.dependencies.add(filename.short)
                    crytic_compile.dependencies.add(filename.used)
            compilation_unit.asts = compilation_unit_json["asts"]
            compilation_unit.filenames = {
                _convert_dict_to_filename(filename)
                for filename in compilation_unit_json["filenames"]
            }
Exemple #6
0
def _convert_dict_to_filename(filename: Dict) -> Filename:
    """Convert a dict to a Filename
    This function should be called only on well formed json

    Args:
        filename (Dict): Json to convert

    Returns:
        Filename: Filename converted
    """

    assert "absolute" in filename
    assert "used" in filename
    assert "short" in filename
    assert "relative" in filename

    return Filename(
        absolute=filename["absolute"],
        relative=filename["relative"],
        short=filename["short"],
        used=filename["used"],
    )
Exemple #7
0
def _handle_bytecode(crytic_compile: "CryticCompile", target: str,
                     result_b: bytes) -> None:
    """Parse the bytecode and populate CryticCompile info

    Args:
        crytic_compile (CryticCompile): Associate CryticCompile object
        target (str): path to the target
        result_b (bytes): text containing the bytecode
    """

    # There is no direct API to get the bytecode from etherscan
    # The page changes from time to time, we use for now a simple parsing, it will not be robust
    begin = """Search Algorithm">\nSimilar Contracts</button>\n"""
    begin += """<div id="dividcode">\n<pre class=\'wordwrap\' style=\'height: 15pc;\'>0x"""
    result = result_b.decode("utf8")
    # Removing everything before the begin string
    result = result[result.find(begin) + len(begin):]
    bytecode = result[:result.find("<")]

    contract_name = f"Contract_{target}"

    contract_filename = Filename(absolute="", relative="", short="", used="")

    compilation_unit = CompilationUnit(crytic_compile, str(target))

    compilation_unit.contracts_names.add(contract_name)
    compilation_unit.filename_to_contracts[contract_filename].add(
        contract_name)
    compilation_unit.abis[contract_name] = {}
    compilation_unit.bytecodes_init[contract_name] = bytecode
    compilation_unit.bytecodes_runtime[contract_name] = ""
    compilation_unit.srcmaps_init[contract_name] = []
    compilation_unit.srcmaps_runtime[contract_name] = []

    compilation_unit.compiler_version = CompilerVersion(compiler="unknown",
                                                        version="",
                                                        optimized=False)

    crytic_compile.bytecode_only = True
Exemple #8
0
def load_from_compile(crytic_compile, loaded_json):
    crytic_compile._asts = loaded_json["asts"]
    crytic_compile._compiler_version = CompilerVersion(
        compiler=loaded_json["compiler"]["compiler"],
        version=loaded_json["compiler"]["version"],
        optimized=loaded_json["compiler"]["optimized"],
    )
    for contract_name, contract in loaded_json["contracts"].items():
        crytic_compile._contracts_name.add(contract_name)
        filename = Filename(
            absolute=contract["filenames"]["absolute"],
            relative=contract["filenames"]["relative"],
            short=contract["filenames"]["short"],
            used=contract["filenames"]["used"],
        )
        crytic_compile._contracts_filenames[contract_name] = filename

        crytic_compile._abis[contract_name] = contract["abi"]
        crytic_compile._init_bytecodes[contract_name] = contract["bin"]
        crytic_compile._runtime_bytecodes[contract_name] = contract[
            "bin-runtime"]
        crytic_compile._srcmaps[contract_name] = contract["srcmap"].split(";")
        crytic_compile._srcmaps_runtime[contract_name] = contract[
            "srcmap-runtime"].split(";")
        crytic_compile._libraries[contract_name] = contract["libraries"]

        if contract["is_dependency"]:
            crytic_compile._dependencies.add(filename.absolute)
            crytic_compile._dependencies.add(filename.relative)
            crytic_compile._dependencies.add(filename.short)
            crytic_compile._dependencies.add(filename.used)

    # Set our filenames
    crytic_compile._filenames = set(
        crytic_compile._contracts_filenames.values())

    crytic_compile._working_dir = loaded_json["working_dir"]
    crytic_compile._type = loaded_json["type"]
Exemple #9
0
def _load_from_compile_legacy(crytic_compile: "CryticCompile",
                              loaded_json: Dict):
    compilation_unit = CompilationUnit(crytic_compile, "legacy")
    compilation_unit.asts = loaded_json["asts"]
    compilation_unit.compiler_version = CompilerVersion(
        compiler=loaded_json["compiler"]["compiler"],
        version=loaded_json["compiler"]["version"],
        optimized=loaded_json["compiler"]["optimized"],
    )
    for contract_name, contract in loaded_json["contracts"].items():
        compilation_unit.contracts_names.add(contract_name)
        filename = Filename(
            absolute=contract["filenames"]["absolute"],
            relative=contract["filenames"]["relative"],
            short=contract["filenames"]["short"],
            used=contract["filenames"]["used"],
        )
        compilation_unit.contracts_filenames[contract_name] = filename

        compilation_unit.abis[contract_name] = contract["abi"]
        compilation_unit.bytecodes_init[contract_name] = contract["bin"]
        compilation_unit.bytecodes_runtime[contract_name] = contract[
            "bin-runtime"]
        compilation_unit.srcmaps_init[contract_name] = contract[
            "srcmap"].split(";")
        compilation_unit.srcmaps_runtime[contract_name] = contract[
            "srcmap-runtime"].split(";")
        compilation_unit.libraries[contract_name] = contract["libraries"]

        userdoc = contract.get("userdoc", {})
        devdoc = contract.get("devdoc", {})
        compilation_unit.natspec[contract_name] = Natspec(userdoc, devdoc)

        if contract["is_dependency"]:
            compilation_unit.crytic_compile.dependencies.add(filename.absolute)
            compilation_unit.crytic_compile.dependencies.add(filename.relative)
            compilation_unit.crytic_compile.dependencies.add(filename.short)
            compilation_unit.crytic_compile.dependencies.add(filename.used)