Skip to content

Commit 3a4b0de

Browse files
authored
Merge pull request #506 from crytic/dev
merge dev into master
2 parents a741e4a + e4b529b commit 3a4b0de

File tree

2 files changed

+59
-26
lines changed

2 files changed

+59
-26
lines changed

Diff for: crytic_compile/crytic_compile.py

+33-14
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
from solc_select.solc_select import (
1818
install_artifacts,
1919
installed_versions,
20-
current_version,
2120
artifact_path,
2221
)
2322
from crytic_compile.compilation_unit import CompilationUnit
@@ -86,6 +85,31 @@ def _extract_libraries(libraries_str: Optional[str]) -> Optional[Dict[str, int]]
8685
return ret
8786

8887

88+
def _configure_solc(solc_requested: str, offline: bool) -> str:
89+
"""
90+
Determine which solc binary to use based on the requested version or path (e.g. '0.8.0' or '/usr/bin/solc-0.8.0').
91+
92+
Args:
93+
solc_requested (str): solc version or path
94+
offline (bool): whether to allow network requests
95+
96+
Returns:
97+
str: path to solc binary
98+
"""
99+
if Path(solc_requested).exists():
100+
solc_path = Path(solc_requested)
101+
else:
102+
solc_version = solc_requested
103+
if solc_requested in installed_versions():
104+
solc_path = artifact_path(solc_requested)
105+
else:
106+
# Respect foundry offline option and skip installation.
107+
if not offline:
108+
install_artifacts([solc_version])
109+
solc_path = artifact_path(solc_version)
110+
return solc_path.absolute().as_posix()
111+
112+
89113
# pylint: disable=too-many-instance-attributes
90114
class CryticCompile:
91115
"""
@@ -139,7 +163,7 @@ def __init__(self, target: Union[str, AbstractPlatform], **kwargs: str) -> None:
139163
),
140164
None,
141165
)
142-
# If no platform has been found or if it's a Solc we can't do anything
166+
# If no platform has been found or if it's the Solc platform, we can't automatically compile.
143167
if platform_wd and not isinstance(platform_wd, Solc):
144168
platform_config = platform_wd.config(str(self._working_dir))
145169
if platform_config:
@@ -148,18 +172,13 @@ def __init__(self, target: Union[str, AbstractPlatform], **kwargs: str) -> None:
148172

149173
if platform_config.remappings:
150174
kwargs["solc_remaps"] = platform_config.remappings
151-
if (
152-
platform_config.solc_version
153-
and platform_config.solc_version != current_version()[0]
154-
):
155-
solc_version = platform_config.solc_version
156-
if solc_version in installed_versions():
157-
kwargs["solc"] = str(artifact_path(solc_version).absolute())
158-
else:
159-
# Respect foundry offline option and don't install a missing solc version
160-
if not platform_config.offline:
161-
install_artifacts([solc_version])
162-
kwargs["solc"] = str(artifact_path(solc_version).absolute())
175+
if platform_config.solc_version is None:
176+
message = f"Could not detect solc version from {platform_wd.NAME} config. Falling back to system version..."
177+
LOGGER.warning(message)
178+
else:
179+
kwargs["solc"] = _configure_solc(
180+
platform_config.solc_version, platform_config.offline
181+
)
163182
if platform_config.optimizer:
164183
kwargs["solc_args"] += "--optimize"
165184
if platform_config.optimizer_runs:

Diff for: crytic_compile/platform/foundry.py

+26-12
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
import os
66
import subprocess
77
from pathlib import Path
8-
from typing import TYPE_CHECKING, List, Optional
8+
from typing import TYPE_CHECKING, List, Optional, Dict, TypeVar
9+
910
import toml
1011

1112
from crytic_compile.platform.abstract_platform import AbstractPlatform, PlatformConfig
@@ -17,6 +18,8 @@
1718
if TYPE_CHECKING:
1819
from crytic_compile import CryticCompile
1920

21+
T = TypeVar("T")
22+
2023
LOGGER = logging.getLogger("CryticCompile")
2124

2225

@@ -135,26 +138,37 @@ def config(working_dir: str) -> Optional[PlatformConfig]:
135138
foundry_toml = toml.loads(f.read())
136139
default_profile = foundry_toml["profile"]["default"]
137140

138-
if "solc_version" in default_profile:
139-
result.solc_version = default_profile["solc_version"]
141+
def lookup_by_keys(keys: List[str], dictionary: Dict[str, T]) -> Optional[T]:
142+
for key in keys:
143+
if key in dictionary:
144+
return dictionary[key]
145+
return None
146+
147+
# Foundry supports snake and kebab case.
148+
result.solc_version = lookup_by_keys(
149+
["solc", "solc_version", "solc-version"], default_profile
150+
)
151+
via_ir = lookup_by_keys(["via_ir", "via-ir"], default_profile)
152+
if via_ir:
153+
result.via_ir = via_ir
154+
result.allow_paths = lookup_by_keys(["allow_paths", "allow-paths"], default_profile)
155+
140156
if "offline" in default_profile:
141157
result.offline = default_profile["offline"]
142158
if "optimizer" in default_profile:
143159
result.optimizer = default_profile["optimizer"]
144160
else:
145161
# Default to true
146162
result.optimizer = True
147-
if "optimizer_runs" in default_profile:
148-
result.optimizer_runs = default_profile["optimizer_runs"]
149-
else:
163+
optimizer_runs = lookup_by_keys(["optimizer_runs", "optimizer-runs"], default_profile)
164+
if optimizer_runs is None:
150165
# Default to 200
151166
result.optimizer_runs = 200
152-
if "via_ir" in default_profile:
153-
result.via_ir = default_profile["via_ir"]
154-
if "allow_paths" in default_profile:
155-
result.allow_paths = default_profile["allow_paths"]
156-
if "evm_version" in default_profile:
157-
result.evm_version = default_profile["evm_version"]
167+
else:
168+
result.optimizer_runs = optimizer_runs
169+
evm_version = lookup_by_keys(["evm_version", "evm-version"], default_profile)
170+
if evm_version is None:
171+
result.evm_version = evm_version
158172
else:
159173
# Default to london
160174
result.evm_version = "london"

0 commit comments

Comments
 (0)