Skip to content

Commit

Permalink
Merge pull request #348 from crytic/foundry-multiple-compilation-unit…
Browse files Browse the repository at this point in the history
…s-mypy

support multiple compilation units for foundry (2)
  • Loading branch information
montyly authored Jan 10, 2023
2 parents a2662cb + f464090 commit fe27372
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 232 deletions.
149 changes: 9 additions & 140 deletions crytic_compile/platform/foundry.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
"""
Truffle platform
"""
import json
import logging
import os
import shutil
import subprocess
from pathlib import Path
from typing import TYPE_CHECKING, List, Tuple, Optional
from typing import TYPE_CHECKING, List

from crytic_compile.compilation_unit import CompilationUnit
from crytic_compile.compiler.compiler import CompilerVersion
from crytic_compile.platform.abstract_platform import AbstractPlatform
from crytic_compile.platform.exceptions import InvalidCompilation
from crytic_compile.platform.types import Type
from crytic_compile.utils.naming import convert_filename
from crytic_compile.utils.natspec import Natspec
from crytic_compile.platform.hardhat import hardhat_like_parsing
from crytic_compile.utils.subprocess import run

# Handle cycle
Expand All @@ -42,8 +37,6 @@ def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None:
crytic_compile (CryticCompile): CryticCompile object to populate
**kwargs: optional arguments. Used: "foundry_ignore_compile", "foundry_out_directory"
Raises:
InvalidCompilation: If foundry failed to run
"""

ignore_compile = kwargs.get("foundry_ignore_compile", False) or kwargs.get(
Expand All @@ -61,14 +54,7 @@ def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None:
cmd = [
"forge",
"build",
"--extra-output",
"abi",
"--extra-output",
"userdoc",
"--extra-output",
"devdoc",
"--extra-output",
"evm.methodIdentifiers",
"--build-info",
"--force",
]

Expand All @@ -95,69 +81,14 @@ def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None:
if stderr:
LOGGER.error(stderr)

filenames = Path(self._target, out_directory).rglob("*.json")

# foundry only support solc for now
compiler = "solc"
compilation_unit = CompilationUnit(crytic_compile, str(self._target))

for filename_txt in filenames:
with open(filename_txt, encoding="utf8") as file_desc:
target_loaded = json.load(file_desc)

userdoc = target_loaded.get("userdoc", {})
devdoc = target_loaded.get("devdoc", {})
natspec = Natspec(userdoc, devdoc)

if not "ast" in target_loaded:
continue

filename_str = target_loaded["ast"]["absolutePath"]

try:
filename = convert_filename(
filename_str, lambda x: x, crytic_compile, working_dir=self._target
)
except InvalidCompilation as i:
txt = str(i)
txt += "\nSomething went wrong, please open an issue in https://github.com/crytic/crytic-compile"
# pylint: disable=raise-missing-from
raise InvalidCompilation(txt)

source_unit = compilation_unit.create_source_unit(filename)

source_unit.ast = target_loaded["ast"]

contract_name = filename_txt.parts[-1]
contract_name = contract_name[: -len(".json")]

source_unit.natspec[contract_name] = natspec
compilation_unit.filename_to_contracts[filename].add(contract_name)
source_unit.contracts_names.add(contract_name)
source_unit.abis[contract_name] = target_loaded["abi"]
source_unit.bytecodes_init[contract_name] = target_loaded["bytecode"][
"object"
].replace("0x", "")
source_unit.bytecodes_runtime[contract_name] = target_loaded["deployedBytecode"][
"object"
].replace("0x", "")
source_unit.srcmaps_init[contract_name] = (
target_loaded["bytecode"]["sourceMap"].split(";")
if target_loaded["bytecode"].get("sourceMap")
else []
)
source_unit.srcmaps_runtime[contract_name] = (
target_loaded["deployedBytecode"]["sourceMap"].split(";")
if target_loaded["deployedBytecode"].get("sourceMap")
else []
)

version, optimized, runs = _get_config_info(self._target)

compilation_unit.compiler_version = CompilerVersion(
compiler=compiler, version=version, optimized=optimized, optimize_runs=runs
build_directory = Path(
self._target,
out_directory,
"build-info",
)

hardhat_like_parsing(crytic_compile, self._target, build_directory, self._target)

def clean(self, **kwargs: str) -> None:
"""Clean compilation artifacts
Expand Down Expand Up @@ -214,65 +145,3 @@ def _guessed_tests(self) -> List[str]:
List[str]: The guessed unit tests commands
"""
return ["forge test"]


def _get_config_info(target: str) -> Tuple[str, Optional[bool], Optional[int]]:
"""get the compiler version from solidity-files-cache.json
Args:
target (str): path to the project directory
Returns:
(str, str, str): compiler version, optimized, runs
Raises:
InvalidCompilation: If cache/solidity-files-cache.json cannot be parsed
"""
config = Path(target, "cache", "solidity-files-cache.json")
if not config.exists():
raise InvalidCompilation(
"Could not find the cache/solidity-files-cache.json file."
+ "If you are using 'cache = true' in foundry's config file, please remove it."
+ " Otherwise please open an issue in https://github.com/crytic/crytic-compile"
)
with open(config, "r", encoding="utf8") as config_f:
config_dict = json.load(config_f)

version: Optional[str] = None
optimizer: Optional[bool] = None
runs: Optional[int] = None

if "files" in config_dict:
items = list(config_dict["files"].values())
# On the form
# { ..
# "artifacts": {
# "CONTRACT_NAME": {
# "0.8.X+commit...": "filename"}
#
if len(items) >= 1:
item = items[0]
if "artifacts" in item:
items_artifact = list(item["artifacts"].values())
if len(items_artifact) >= 1:
item_version = items_artifact[0]
version = list(item_version.keys())[0]
assert version
plus_position = version.find("+")
if plus_position > 0:
version = version[:plus_position]
if (
"solcConfig" in item
and "settings" in item["solcConfig"]
and "optimizer" in item["solcConfig"]["settings"]
):
optimizer = item["solcConfig"]["settings"]["optimizer"]["enabled"]
runs = item["solcConfig"]["settings"]["optimizer"].get("runs", None)

if version is None:
raise InvalidCompilation(
"Something went wrong with cache/solidity-files-cache.json parsing"
+ ". Please open an issue in https://github.com/crytic/crytic-compile"
)

return version, optimizer, runs
Loading

0 comments on commit fe27372

Please sign in to comment.