diff --git a/crytic_compile/platform/etherscan.py b/crytic_compile/platform/etherscan.py index 2dd8e5d4..a8f54b43 100644 --- a/crytic_compile/platform/etherscan.py +++ b/crytic_compile/platform/etherscan.py @@ -372,9 +372,11 @@ def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None: working_dir: Optional[str] = None remappings: Optional[List[str]] = None + dict_source_code: Optional[Dict] = None try: # etherscan might return an object with two curly braces, {{ content }} dict_source_code = json.loads(source_code[1:-1]) + assert isinstance(dict_source_code, dict) filenames, working_dir, remappings = _handle_multiple_files( dict_source_code, addr, prefix, contract_name, export_dir ) @@ -382,6 +384,7 @@ def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None: try: # or etherscan might return an object with single curly braces, { content } dict_source_code = json.loads(source_code) + assert isinstance(dict_source_code, dict) filenames, working_dir, remappings = _handle_multiple_files( dict_source_code, addr, prefix, contract_name, export_dir ) @@ -390,6 +393,11 @@ def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None: _handle_single_file(source_code, addr, prefix, contract_name, export_dir) ] + # viaIR is not exposed on the top level JSON offered by etherscan, so we need to inspect the settings + via_ir_enabled: Optional[bool] = None + if isinstance(dict_source_code, dict): + via_ir_enabled = dict_source_code.get("settings", {}).get("viaIR", None) + compilation_unit = CompilationUnit(crytic_compile, contract_name) compilation_unit.compiler_version = CompilerVersion( @@ -413,6 +421,7 @@ def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None: working_dir=working_dir, remappings=remappings, evm_version=evm_version, + via_ir=via_ir_enabled, ) def clean(self, **_kwargs: str) -> None: diff --git a/crytic_compile/platform/solc_standard_json.py b/crytic_compile/platform/solc_standard_json.py index beadf442..3bc4a94c 100644 --- a/crytic_compile/platform/solc_standard_json.py +++ b/crytic_compile/platform/solc_standard_json.py @@ -25,12 +25,14 @@ LOGGER = logging.getLogger("CryticCompile") +# pylint: disable=too-many-arguments def standalone_compile( filenames: List[str], compilation_unit: CompilationUnit, working_dir: Optional[str] = None, remappings: Optional[List[str]] = None, evm_version: Optional[str] = None, + via_ir: Optional[bool] = None, ) -> None: """ Boilerplate function to run the the standardjson. compilation_unit.compiler_version must be set before calling this function @@ -48,6 +50,7 @@ def standalone_compile( working_dir (Optional[str]): working directory remappings (Optional[List[str]]): list of solc remaps to use evm_version (Optional[str]): EVM version to target. None for default + via_ir (Optional[bool]): whether to enable the viaIR compilation flag. None for unset Returns: @@ -70,6 +73,9 @@ def standalone_compile( if evm_version is not None: add_evm_version(standard_json_dict, evm_version) + if via_ir is not None: + add_via_ir(standard_json_dict, via_ir) + add_optimization( standard_json_dict, compilation_unit.compiler_version.optimized, @@ -278,6 +284,20 @@ def add_evm_version(json_dict: Dict, version: str) -> None: json_dict["settings"]["evmVersion"] = version +def add_via_ir(json_dict: Dict, enabled: bool) -> None: + """ + Enable or disable the "viaIR" compilation flag. + + Args: + json_dict (Dict): solc standard json input + enabled (bool): whether viaIR is enabled + + Returns: + + """ + json_dict["settings"]["viaIR"] = enabled + + def parse_standard_json_output( targets_json: Dict, compilation_unit: CompilationUnit, solc_working_dir: Optional[str] = None ) -> None: diff --git a/scripts/ci_test_etherscan.sh b/scripts/ci_test_etherscan.sh index 11918b93..7adcef2c 100755 --- a/scripts/ci_test_etherscan.sh +++ b/scripts/ci_test_etherscan.sh @@ -86,3 +86,16 @@ then exit 255 fi echo "::endgroup::" + +delay_etherscan + +# via-ir test for crytic/crytic-compile#517 +echo "::group::Etherscan #7" +crytic-compile 0x9AB6b21cDF116f611110b048987E58894786C244 --compile-remove-metadata --etherscan-apikey "$GITHUB_ETHERSCAN" + +if [ $? -ne 0 ] +then + echo "Etherscan #7 test failed" + exit 255 +fi +echo "::endgroup::"