certora-cli 8.8.1__tar.gz → 8.11.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {certora_cli-8.8.1/certora_cli.egg-info → certora_cli-8.11.3}/PKG-INFO +2 -2
- certora_cli-8.11.3/README.md +1 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraBuild.py +83 -28
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraBuildCacheManager.py +16 -1
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraBuildSui.py +42 -12
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraCloudIO.py +6 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraContext.py +39 -8
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraContextAttributes.py +77 -4
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraContextValidator.py +25 -1
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/Shared/certoraUtils.py +3 -1
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/Shared/certoraValidateFuncs.py +7 -1
- {certora_cli-8.8.1 → certora_cli-8.11.3/certora_cli.egg-info}/PKG-INFO +2 -2
- certora_cli-8.8.1/certora_jars/Typechecker.jar → certora_cli-8.11.3/certora_jars/ASTExtraction.jar +0 -0
- certora_cli-8.11.3/certora_jars/CERTORA-CLI-VERSION-METADATA.json +1 -0
- certora_cli-8.8.1/certora_jars/ASTExtraction.jar → certora_cli-8.11.3/certora_jars/Typechecker.jar +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/setup.py +2 -2
- certora_cli-8.8.1/README.md +0 -1
- certora_cli-8.8.1/certora_jars/CERTORA-CLI-VERSION-METADATA.json +0 -1
- {certora_cli-8.8.1 → certora_cli-8.11.3}/LICENSE +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/MANIFEST.in +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_bins/__init__.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/Compiler/CompilerCollector.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/Compiler/CompilerCollectorFactory.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/Compiler/CompilerCollectorSol.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/Compiler/CompilerCollectorSolBased.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/Compiler/CompilerCollectorVy.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/Compiler/CompilerCollectorYul.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/Compiler/__init__.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/__init__.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/castingInstrumenter.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraApp.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraBuildDataClasses.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraBuildRust.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraCollectConfigurationLayout.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraCollectRunMetadata.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraCompilerParameters.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraConfigIO.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraContextClass.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraContractFuncs.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraExtensionInfo.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraJobList.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraMiniSpecParser.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraNodeFilters.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraOffsetConverter.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraParseBuildScript.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraProjectScanner.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraSourceFinders.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraType.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraVerifyGenerator.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/erc7201.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/splitRules.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/storageExtension.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/uncheckedOverflowInstrumenter.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/EquivalenceCheck/Eq_default.conf +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/EquivalenceCheck/Eq_mc_no_out_template.spec +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/EquivalenceCheck/Eq_mc_template.spec +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/EquivalenceCheck/Eq_sanity.conf +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/EquivalenceCheck/Eq_template.spec +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/EquivalenceCheck/__init__.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/EquivalenceCheck/equivCheck.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/EquivalenceCheck/sanity.spec +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/Mutate/__init__.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/Mutate/mutateApp.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/Mutate/mutateAttributes.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/Mutate/mutateConstants.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/Mutate/mutateUtil.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/Mutate/mutateValidate.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/Shared/ExpectedComparator.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/Shared/__init__.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/Shared/certoraAttrUtil.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/Shared/certoraLogging.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/Shared/proverCommon.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/__init__.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/certoraCVLFormatter.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/certoraConcord.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/certoraEVMProver.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/certoraEqCheck.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/certoraMutate.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/certoraRanger.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/certoraRun.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/certoraSolanaProver.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/certoraSorobanProver.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/certoraSuiProver.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/rustMutator.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli.egg-info/SOURCES.txt +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli.egg-info/dependency_links.txt +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli.egg-info/entry_points.txt +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli.egg-info/requires.txt +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli.egg-info/top_level.txt +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/certora_jars/__init__.py +0 -0
- {certora_cli-8.8.1 → certora_cli-8.11.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: certora-cli
|
|
3
|
-
Version: 8.
|
|
3
|
+
Version: 8.11.3
|
|
4
4
|
Summary: Runner for the Certora Prover
|
|
5
5
|
Home-page: https://pypi.org/project/certora-cli
|
|
6
6
|
Author: Certora
|
|
@@ -38,4 +38,4 @@ Dynamic: requires-dist
|
|
|
38
38
|
Dynamic: requires-python
|
|
39
39
|
Dynamic: summary
|
|
40
40
|
|
|
41
|
-
Commit
|
|
41
|
+
Commit d4f463a. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Commit d4f463a. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
|
|
@@ -890,7 +890,7 @@ class CertoraBuildGenerator:
|
|
|
890
890
|
# same name but used separately could exist right?
|
|
891
891
|
# Add to the current contract all public/external functions, and internal/private ones if
|
|
892
892
|
# this is the declaring contract.
|
|
893
|
-
if func_visibility in ("public", "external") or (c_name == contract_name):
|
|
893
|
+
if func_visibility in ("public", "external") or (c_name == contract_name and c_file == contract_file):
|
|
894
894
|
funcs.append(func)
|
|
895
895
|
ast_logger.debug(f"Function {func.source_code_signature()} added")
|
|
896
896
|
|
|
@@ -1114,11 +1114,12 @@ class CertoraBuildGenerator:
|
|
|
1114
1114
|
assert "baseName" in bc and "referencedDeclaration" in bc["baseName"]
|
|
1115
1115
|
next_bc_ref = bc["baseName"]["referencedDeclaration"]
|
|
1116
1116
|
next_bc = self.get_contract_file_of(build_arg_contract_file, next_bc_ref)
|
|
1117
|
-
|
|
1117
|
+
next_bc_name = self.asts[build_arg_contract_file][next_bc][next_bc_ref]["name"]
|
|
1118
|
+
if (next_bc, next_bc_name) not in [(e[0], e[1]) for e in base_contracts_lst]:
|
|
1118
1119
|
base_contracts_lst.append(
|
|
1119
|
-
(next_bc,
|
|
1120
|
+
(next_bc, next_bc_name,
|
|
1120
1121
|
self.is_library_def_node(next_bc, next_bc_ref, build_arg_contract_file)))
|
|
1121
|
-
base_contracts_queue.insert(0, (next_bc,
|
|
1122
|
+
base_contracts_queue.insert(0, (next_bc, next_bc_ref))
|
|
1122
1123
|
|
|
1123
1124
|
if base_contracts_queue:
|
|
1124
1125
|
retrieve_base_contracts_list_rec(base_contracts_queue, base_contracts_lst)
|
|
@@ -1447,7 +1448,9 @@ class CertoraBuildGenerator:
|
|
|
1447
1448
|
if not self.context.strict_solc_optimizer and self.get_solc_via_ir_value(contract_file_path):
|
|
1448
1449
|
# The default optimizer steps (taken from libsolidity/interface/OptimiserSettings.h) but with the
|
|
1449
1450
|
# full inliner step removed
|
|
1450
|
-
|
|
1451
|
+
solc0_8_34_to_0_8_34 = ("dfDvulfnTUtnIfxa[r]EscLMVcul[j]Trpeulxa[r]cLvifMCTUca[r]LSsTFOtfDnca[r]"
|
|
1452
|
+
"IulcscCTUtvifMx[scCTUt]TOntnfDIulvifMjmul[jul]VcTOculjmul")
|
|
1453
|
+
solc0_8_26_to_0_8_33 = ("dhfoDgvulfnTUtnIfxa[r]EscLMVcul[j]Trpeulxa[r]cLCTUca[r]LSsTFOtfDnca[r]" +
|
|
1451
1454
|
"IulcscCTUtx[scCTUt]TOntnfDIuljmul[jul]VcTOculjmul")
|
|
1452
1455
|
solc0_8_13_to_0_8_25 = "dhfoDgvulfnTUtnIf[xa[r]EscLMcCTUtTOntnfDIulLculVcul[j]T" + \
|
|
1453
1456
|
"peulxa[rul]xa[r]cLgvifCTUca[r]LSsTFOtfDnca[r]Iulc]jmul[jul]VcTOculjmul"
|
|
@@ -1496,8 +1499,10 @@ class CertoraBuildGenerator:
|
|
|
1496
1499
|
yul_optimizer_steps = solc0_8_12
|
|
1497
1500
|
elif minor == 8 and 13 <= patch <= 25:
|
|
1498
1501
|
yul_optimizer_steps = solc0_8_13_to_0_8_25
|
|
1499
|
-
elif minor == 8 and 26 <= patch <=
|
|
1500
|
-
yul_optimizer_steps =
|
|
1502
|
+
elif minor == 8 and 26 <= patch <= 33:
|
|
1503
|
+
yul_optimizer_steps = solc0_8_26_to_0_8_33
|
|
1504
|
+
elif minor == 8 and 34 <= patch <= 34:
|
|
1505
|
+
yul_optimizer_steps = solc0_8_34_to_0_8_34
|
|
1501
1506
|
assert yul_optimizer_steps is not None, \
|
|
1502
1507
|
'Yul Optimizer steps missing for requested Solidity version. Please contact Certora team.'
|
|
1503
1508
|
|
|
@@ -1591,10 +1596,12 @@ class CertoraBuildGenerator:
|
|
|
1591
1596
|
"evm.bytecode.functionDebugData"]
|
|
1592
1597
|
ast_selection = ["id", "ast"]
|
|
1593
1598
|
elif compiler_collector_lang == CompilerLangVy():
|
|
1594
|
-
main_contract_for_output_selection = "*"
|
|
1595
1599
|
sources_dict = {}
|
|
1596
|
-
|
|
1597
|
-
|
|
1600
|
+
vyper_custom_std_json_in = None
|
|
1601
|
+
|
|
1602
|
+
if self.context.vyper_custom_std_json_in_map:
|
|
1603
|
+
main_contract_for_output_selection = contract_file_as_provided
|
|
1604
|
+
if contract_file_as_provided in self.context.vyper_custom_std_json_in_map:
|
|
1598
1605
|
"""
|
|
1599
1606
|
If we're given a custom standard_json, we'll take from it the sources and
|
|
1600
1607
|
the search paths.
|
|
@@ -1606,18 +1613,36 @@ class CertoraBuildGenerator:
|
|
|
1606
1613
|
if we get more projects.
|
|
1607
1614
|
"""
|
|
1608
1615
|
vyper_custom_std_json_in = self.context.vyper_custom_std_json_in_map[contract_file_as_provided]
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1616
|
+
elif self.context.resolve_vyper_imports and compiler_collector.compiler_version >= (0, 4, 0):
|
|
1617
|
+
main_contract_for_output_selection = contract_file_as_provided
|
|
1618
|
+
"""
|
|
1619
|
+
If resolve_vyper_imports is enabled, we ask the vyper compiler to generate a standard_json for us.
|
|
1620
|
+
"""
|
|
1621
|
+
compiler_ver_to_run = get_relevant_compiler(Path(contract_file_as_provided), self.context)
|
|
1622
|
+
vyper_options = f"-f solc_json {contract_file_as_provided} --disable-sys-path"
|
|
1623
|
+
for path in ((self.context.vyper_system_path or []) + (self.context.vyper_import_path or [])):
|
|
1624
|
+
vyper_options += f" -p {path}"
|
|
1625
|
+
Util.run_compiler_cmd(f"{compiler_ver_to_run} {vyper_options}",
|
|
1626
|
+
f"{contract_file_posix_abs.name}.std_json_generated.json",
|
|
1627
|
+
wd=compile_wd)
|
|
1628
|
+
vyper_custom_std_json_in = compiler_collector_lang.compilation_output_path(
|
|
1629
|
+
f"{contract_file_posix_abs.name}.std_json_generated.stdout.json")
|
|
1630
|
+
|
|
1631
|
+
if vyper_custom_std_json_in:
|
|
1632
|
+
with open(vyper_custom_std_json_in) as custom:
|
|
1633
|
+
custom_json = json.load(custom)
|
|
1634
|
+
sources_dict = custom_json.get("sources", None)
|
|
1635
|
+
search_paths_arr = custom_json.get("settings", {}).get("search_paths", None)
|
|
1636
|
+
additional_asts = [x for x, _ in sources_dict.items() if x.endswith(".vy")]
|
|
1637
|
+
|
|
1638
|
+
if not sources_dict:
|
|
1639
|
+
with open(contract_file_posix_abs) as f:
|
|
1615
1640
|
contents = f.read()
|
|
1616
1641
|
sources_dict = {str(contract_file_posix_abs): {"content": contents}}
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1642
|
+
output_selection = ["abi", "evm.bytecode", "evm.deployedBytecode", "evm.methodIdentifiers"]
|
|
1643
|
+
if compiler_collector.compiler_version >= (0, 4, 4):
|
|
1644
|
+
output_selection += ["metadata", "evm.deployedBytecode.symbolMap"]
|
|
1645
|
+
ast_selection = ["ast"]
|
|
1621
1646
|
else:
|
|
1622
1647
|
# "non-compilable" language so no need to deal with it
|
|
1623
1648
|
fatal_error(compiler_logger, "Expected only Solidity and Vyper as "
|
|
@@ -2483,8 +2508,8 @@ class CertoraBuildGenerator:
|
|
|
2483
2508
|
return f"{contract}_{address}"
|
|
2484
2509
|
|
|
2485
2510
|
@staticmethod
|
|
2486
|
-
def get_primary_contract_from_sdc(contracts: List[ContractInSDC], primary: str) -> List[ContractInSDC]:
|
|
2487
|
-
return [x for x in contracts if x.name == primary]
|
|
2511
|
+
def get_primary_contract_from_sdc(contracts: List[ContractInSDC], primary: str, primary_file: str) -> List[ContractInSDC]:
|
|
2512
|
+
return [x for x in contracts if x.name == primary and Util.abs_norm_path(x.original_file) == Util.abs_norm_path(primary_file)]
|
|
2488
2513
|
|
|
2489
2514
|
@staticmethod
|
|
2490
2515
|
def generate_library_import(file_absolute_path: str, library_name: str) -> str:
|
|
@@ -2945,7 +2970,7 @@ class CertoraBuildGenerator:
|
|
|
2945
2970
|
sdc.original_srclist,
|
|
2946
2971
|
sdc.report_srclist,
|
|
2947
2972
|
f"{sdc.sdc_name}_{library_contract.name}",
|
|
2948
|
-
self.get_primary_contract_from_sdc(sdc.contracts, library_contract.name),
|
|
2973
|
+
self.get_primary_contract_from_sdc(sdc.contracts, library_contract.name, library_contract.original_file),
|
|
2949
2974
|
[],
|
|
2950
2975
|
{},
|
|
2951
2976
|
{},
|
|
@@ -2956,7 +2981,7 @@ class CertoraBuildGenerator:
|
|
|
2956
2981
|
self.SDCs[self.get_sdc_key(sdc_lib.primary_contract, sdc_lib.primary_contract_address)] = sdc_lib
|
|
2957
2982
|
|
|
2958
2983
|
# Filter out irrelevant contracts, now that we extracted the libraries, leave just the primary
|
|
2959
|
-
sdc.contracts = self.get_primary_contract_from_sdc(sdc.contracts, sdc.primary_contract)
|
|
2984
|
+
sdc.contracts = self.get_primary_contract_from_sdc(sdc.contracts, sdc.primary_contract, sdc.sdc_origin_file)
|
|
2960
2985
|
assert len(
|
|
2961
2986
|
sdc.contracts) == 1, f"Found multiple primary contracts ({sdc.contracts}) in SDC {sdc.sdc_name}"
|
|
2962
2987
|
|
|
@@ -2977,8 +3002,13 @@ class CertoraBuildGenerator:
|
|
|
2977
3002
|
corresponding to the namespaced types.
|
|
2978
3003
|
|
|
2979
3004
|
Args:
|
|
2980
|
-
original_file: Path to the Solidity file containing namespaced storage declarations
|
|
3005
|
+
original_file: Path to the Solidity file containing namespaced storage declarations.
|
|
3006
|
+
This may be a (transitivly) imported file rather than a user-specified target.
|
|
2981
3007
|
ns_storage: Set of tuples (type_name, namespace) for each namespaced storage
|
|
3008
|
+
compiler_version: The compiler version to use, already resolved from target_file
|
|
3009
|
+
target_file: The user-specified file (from conf file) that imported original_file.
|
|
3010
|
+
Used to resolve compilation settings (solc_optimize_map, solc_via_ir_map, etc.)
|
|
3011
|
+
for the temporary harness file, since original_file may not have entries in those maps.
|
|
2982
3012
|
|
|
2983
3013
|
Returns:
|
|
2984
3014
|
NewStorageInfo: A tuple (fields, types) where:
|
|
@@ -2997,8 +3027,24 @@ class CertoraBuildGenerator:
|
|
|
2997
3027
|
# directly can cause issues.
|
|
2998
3028
|
tmp_file.write(f"import \"{original_file}\";\n\n")
|
|
2999
3029
|
rel_path = os.path.relpath(tmp_file.name, Path.cwd())
|
|
3000
|
-
|
|
3001
|
-
|
|
3030
|
+
tmp_abs_path = Util.abs_posix_path(tmp_file.name)
|
|
3031
|
+
# Add the temp file to all map attributes so that map lookups
|
|
3032
|
+
# (solc_optimize_map, solc_via_ir_map, etc.) succeed during compilation.
|
|
3033
|
+
# We resolve values from target_file (a user-specified file in context.file_paths)
|
|
3034
|
+
# rather than original_file (which may be a transitive dependency not in any map).
|
|
3035
|
+
# We store both relative and absolute path keys because different lookup sites
|
|
3036
|
+
# normalize paths differently: get_relevant_compiler uses relative paths,
|
|
3037
|
+
# while _handle_via_ir/_handle_optimize use absolute paths.
|
|
3038
|
+
for map_attr in self.context.app.attr_class.all_map_attrs():
|
|
3039
|
+
map_attr_value = getattr(self.context, map_attr, None)
|
|
3040
|
+
if not map_attr_value:
|
|
3041
|
+
continue
|
|
3042
|
+
attr_name = map_attr[:-len(Util.MAP_SUFFIX)]
|
|
3043
|
+
target_value = Ctx.get_map_attribute_value(
|
|
3044
|
+
self.context, Path(target_file), attr_name
|
|
3045
|
+
)
|
|
3046
|
+
if target_value is not None:
|
|
3047
|
+
map_attr_value.update({rel_path: target_value, tmp_abs_path: target_value}, last=False)
|
|
3002
3048
|
# Write the harness contract with dummy fields for each namespaced storage
|
|
3003
3049
|
var_to_slot = storageExtension.write_harness_contract(tmp_file, harness_name, ns_storage)
|
|
3004
3050
|
tmp_file.flush()
|
|
@@ -4121,8 +4167,13 @@ def build_from_scratch(context: CertoraContext,
|
|
|
4121
4167
|
indent=4,
|
|
4122
4168
|
sort_keys=True)
|
|
4123
4169
|
|
|
4170
|
+
# check if asts file exists (only when --dump_asts is used)
|
|
4171
|
+
asts_file = Util.get_asts_file()
|
|
4172
|
+
asts_file_if_exists = asts_file if asts_file.exists() else None
|
|
4173
|
+
|
|
4124
4174
|
return CachedFiles(certora_build_file, all_contract_files, build_output_props_file, may_store_in_build_cache,
|
|
4125
|
-
path_with_additional_included_files=absolute_sources_dir
|
|
4175
|
+
path_with_additional_included_files=absolute_sources_dir,
|
|
4176
|
+
asts_file=asts_file_if_exists)
|
|
4126
4177
|
|
|
4127
4178
|
|
|
4128
4179
|
def build_from_cache_or_scratch(context: CertoraContext,
|
|
@@ -4204,6 +4255,10 @@ def build_from_cache_or_scratch(context: CertoraContext,
|
|
|
4204
4255
|
else:
|
|
4205
4256
|
shutil.copyfile(p, Util.get_certora_sources_dir() / p.name)
|
|
4206
4257
|
|
|
4258
|
+
# restore asts file from cache if present
|
|
4259
|
+
if cached_files.asts_file is not None and cached_files.asts_file.exists():
|
|
4260
|
+
shutil.copyfile(cached_files.asts_file, Util.get_asts_file())
|
|
4261
|
+
|
|
4207
4262
|
return False, cached_files
|
|
4208
4263
|
|
|
4209
4264
|
|
{certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraBuildCacheManager.py
RENAMED
|
@@ -41,6 +41,9 @@ class CachedFiles:
|
|
|
41
41
|
# to keep .post_autofinders
|
|
42
42
|
path_with_additional_included_files: Path
|
|
43
43
|
|
|
44
|
+
# optional asts file (only present when --dump_asts is used)
|
|
45
|
+
asts_file: Optional[Path] = None
|
|
46
|
+
|
|
44
47
|
def all_exist(self, main_cache_entry_dir: Path, sub_cache_key: str) -> bool:
|
|
45
48
|
exist = self.certora_build_file.exists() and \
|
|
46
49
|
self.certora_build_file == main_cache_entry_dir / f"{sub_cache_key}.{CachedFiles.certora_build_suffix}"
|
|
@@ -55,6 +58,7 @@ class CachedFiles:
|
|
|
55
58
|
file_list_suffix = "file_list.json"
|
|
56
59
|
build_output_props_suffix = "build_output_props.json"
|
|
57
60
|
additional_included_files = "additional_included_files"
|
|
61
|
+
asts_suffix = "asts.json"
|
|
58
62
|
|
|
59
63
|
|
|
60
64
|
class CertoraBuildCacheManager:
|
|
@@ -124,8 +128,14 @@ class CertoraBuildCacheManager:
|
|
|
124
128
|
return None
|
|
125
129
|
|
|
126
130
|
additional_included_files = main_cache_entry_dir / f"{sub_cache_key}.{CachedFiles.additional_included_files}"
|
|
131
|
+
|
|
132
|
+
# check if asts file exists in cache
|
|
133
|
+
asts_file_in_cache = main_cache_entry_dir / f"{sub_cache_key}.{CachedFiles.asts_suffix}"
|
|
134
|
+
asts_file = asts_file_in_cache if asts_file_in_cache.exists() else None
|
|
135
|
+
|
|
127
136
|
return CachedFiles(certora_build_file, all_contract_files, build_output_props_file,
|
|
128
|
-
may_store_in_build_cache=True, path_with_additional_included_files=additional_included_files
|
|
137
|
+
may_store_in_build_cache=True, path_with_additional_included_files=additional_included_files,
|
|
138
|
+
asts_file=asts_file)
|
|
129
139
|
|
|
130
140
|
@staticmethod
|
|
131
141
|
def save_build_cache(context: CertoraContext, cached_files: CachedFiles) -> None:
|
|
@@ -170,6 +180,11 @@ class CertoraBuildCacheManager:
|
|
|
170
180
|
# save additional props file
|
|
171
181
|
shutil.copyfile(cached_files.build_output_props_file,
|
|
172
182
|
main_cache_entry_dir / f"{sub_cache_key}.{CachedFiles.build_output_props_suffix}")
|
|
183
|
+
# save asts file if present
|
|
184
|
+
if cached_files.asts_file is not None and cached_files.asts_file.exists():
|
|
185
|
+
shutil.copyfile(cached_files.asts_file,
|
|
186
|
+
main_cache_entry_dir / f"{sub_cache_key}.{CachedFiles.asts_suffix}")
|
|
187
|
+
|
|
173
188
|
# save .post_autofinders from additional included files
|
|
174
189
|
trg_path_with_additional_included_files = \
|
|
175
190
|
main_cache_entry_dir / f"{sub_cache_key}.{CachedFiles.additional_included_files}"
|
|
@@ -55,13 +55,42 @@ def build_sui_project(context: CertoraContext, timings: Dict) -> None:
|
|
|
55
55
|
def set_sui_build_directory(context: CertoraContext) -> None:
|
|
56
56
|
sources: Set[Path] = set()
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
move_toml_file: Path | None = None
|
|
59
|
+
|
|
60
|
+
if context.move_path:
|
|
61
|
+
# If move_path is specified, we assume the user has already built the spec package separately. This is a legacy
|
|
62
|
+
# option that should not be used by new projects; they should use `spec_package_path` and/or `build_script`
|
|
63
|
+
# instead.
|
|
64
|
+
assert not context.build_script, "cannot have move_path and build_script together"
|
|
65
|
+
assert not context.spec_package_path, "cannot have move_path and spec_package_path together"
|
|
66
|
+
context.sui_package_summary_path = None
|
|
67
|
+
else:
|
|
68
|
+
if context.spec_package_path:
|
|
69
|
+
# Verify that there is a Move.toml at the specified spec_package_path
|
|
70
|
+
spec_package_dir = Path(context.spec_package_path)
|
|
71
|
+
move_toml_file = spec_package_dir / "Move.toml"
|
|
72
|
+
if not move_toml_file.exists():
|
|
73
|
+
raise Util.CertoraUserInputError(f"Could not find Move.toml at specified spec_package_path '{context.spec_package_path}'")
|
|
74
|
+
else:
|
|
75
|
+
# If spec_package_path is not specified, try to find the package that the current directory is in.
|
|
76
|
+
move_toml_file = Util.find_file_in_parents("Move.toml")
|
|
77
|
+
if not move_toml_file:
|
|
78
|
+
raise Util.CertoraUserInputError("Could not find Move.toml, and no spec_package_path was specified.")
|
|
79
|
+
spec_package_dir = move_toml_file.parent
|
|
80
|
+
context.spec_package_path = str(spec_package_dir)
|
|
81
|
+
|
|
63
82
|
sources.add(move_toml_file.absolute())
|
|
64
|
-
|
|
83
|
+
context.move_path = str(spec_package_dir / "build")
|
|
84
|
+
context.sui_package_summary_path = spec_package_dir / "package_summaries"
|
|
85
|
+
|
|
86
|
+
if context.build_script:
|
|
87
|
+
# Run the user-provided build script
|
|
88
|
+
script_path = Path(context.build_script).resolve()
|
|
89
|
+
sources.add(script_path)
|
|
90
|
+
run_sui_build([str(script_path), str(spec_package_dir)])
|
|
91
|
+
else:
|
|
92
|
+
# Build the package using `sui move summary`, which will also produce the package summaries.
|
|
93
|
+
run_sui_build(["sui", "move", "summary", "--test", "--path", str(move_toml_file.parent)])
|
|
65
94
|
|
|
66
95
|
assert context.move_path, "expecting move_path to be set after build"
|
|
67
96
|
move_dir = Path(context.move_path)
|
|
@@ -81,6 +110,12 @@ def set_sui_build_directory(context: CertoraContext) -> None:
|
|
|
81
110
|
Util.get_build_dir() / move_dir.name,
|
|
82
111
|
ignore=shutil.ignore_patterns('*.move'))
|
|
83
112
|
|
|
113
|
+
# Copy package summary directory if it exists. Projects built manually with "sui move build" may not have this.
|
|
114
|
+
if context.sui_package_summary_path and context.sui_package_summary_path.exists():
|
|
115
|
+
assert context.sui_package_summary_path.is_dir(), f"Package summary path '{context.sui_package_summary_path}' is not a directory"
|
|
116
|
+
shutil.copytree(context.sui_package_summary_path,
|
|
117
|
+
Util.get_build_dir() / context.sui_package_summary_path.name)
|
|
118
|
+
|
|
84
119
|
try:
|
|
85
120
|
# Create generators
|
|
86
121
|
build_source_tree(sources, context)
|
|
@@ -88,11 +123,8 @@ def set_sui_build_directory(context: CertoraContext) -> None:
|
|
|
88
123
|
except Exception as e:
|
|
89
124
|
raise Util.CertoraUserInputError(f"Collecting build files failed with the exception: {e}")
|
|
90
125
|
|
|
91
|
-
def run_sui_build(context: CertoraContext, package_dir: Path) -> None:
|
|
92
|
-
assert not context.move_path, "run_sui_build: expecting move_path to be empty"
|
|
93
|
-
|
|
94
|
-
build_cmd = ["sui", "move", "build", "--test", "--path", str(package_dir)]
|
|
95
126
|
|
|
127
|
+
def run_sui_build(build_cmd: list[str]) -> None:
|
|
96
128
|
try:
|
|
97
129
|
build_cmd_text = ' '.join(build_cmd)
|
|
98
130
|
log.info(f"Building by calling `{build_cmd_text}`")
|
|
@@ -102,8 +134,6 @@ def run_sui_build(context: CertoraContext, package_dir: Path) -> None:
|
|
|
102
134
|
if result.returncode != 0:
|
|
103
135
|
raise Util.CertoraUserInputError(f"Error running `{build_cmd_text}`")
|
|
104
136
|
|
|
105
|
-
context.move_path = str(package_dir / "build")
|
|
106
|
-
|
|
107
137
|
except Util.TestResultsReady as e:
|
|
108
138
|
raise e
|
|
109
139
|
except Util.CertoraUserInputError as e:
|
|
@@ -615,6 +615,9 @@ class CloudVerification:
|
|
|
615
615
|
|
|
616
616
|
elif Attrs.is_sui_app():
|
|
617
617
|
sui_jar_settings = ['-movePath', Path(self.context.move_path).name]
|
|
618
|
+
if self.context.sui_package_summary_path and self.context.sui_package_summary_path.exists():
|
|
619
|
+
sui_jar_settings.append('-suiPackageSummaryPath')
|
|
620
|
+
sui_jar_settings.append(self.context.sui_package_summary_path.name)
|
|
618
621
|
auth_data["jarSettings"] = sui_jar_settings + jar_settings
|
|
619
622
|
|
|
620
623
|
elif Attrs.is_concord_app():
|
|
@@ -766,6 +769,9 @@ class CloudVerification:
|
|
|
766
769
|
Util.get_configuration_layout_data_file(),
|
|
767
770
|
Util.get_build_dir() / Path(self.context.move_path).name]
|
|
768
771
|
|
|
772
|
+
if self.context.sui_package_summary_path and self.context.sui_package_summary_path.exists():
|
|
773
|
+
files_list.append(Util.get_build_dir() / self.context.sui_package_summary_path.name)
|
|
774
|
+
|
|
769
775
|
if Util.get_certora_sources_dir().exists():
|
|
770
776
|
files_list.append(Util.get_certora_sources_dir())
|
|
771
777
|
|
|
@@ -63,6 +63,9 @@ def is_evm_app_class(context: CertoraContext) -> bool:
|
|
|
63
63
|
def is_rust_app_class(context: CertoraContext) -> bool:
|
|
64
64
|
return issubclass(context.app, App.RustAppClass)
|
|
65
65
|
|
|
66
|
+
def is_move_app_class(context: CertoraContext) -> bool:
|
|
67
|
+
return issubclass(context.app, App.MoveAppClass)
|
|
68
|
+
|
|
66
69
|
def get_attr_value(context: CertoraContext, attr: AttrUtil.AttributeDefinition) -> Any:
|
|
67
70
|
conf_key = attr.get_conf_key()
|
|
68
71
|
return getattr(context, conf_key, None)
|
|
@@ -133,6 +136,9 @@ def get_local_run_cmd(context: CertoraContext) -> List[str]:
|
|
|
133
136
|
# For local runs, we want path to be relative to cwd instead of zip root.
|
|
134
137
|
move_rel_path = os.path.relpath(Path(context.move_path), os.getcwd())
|
|
135
138
|
run_args.extend(['-movePath', move_rel_path])
|
|
139
|
+
if context.sui_package_summary_path and context.sui_package_summary_path.exists():
|
|
140
|
+
spec_package_summary_rel_path = os.path.relpath(context.sui_package_summary_path, os.getcwd())
|
|
141
|
+
run_args.extend(['-suiPackageSummaryPath', spec_package_summary_rel_path])
|
|
136
142
|
elif is_rust_app_class(context):
|
|
137
143
|
# For local runs, we want path to be relative to cwd instead of zip root.
|
|
138
144
|
rust_rel_path = os.path.relpath(Path(context.files[0]), os.getcwd())
|
|
@@ -284,6 +290,9 @@ def get_args(args_list: List[str], app: Type[App.CertoraApp]) -> CertoraContext:
|
|
|
284
290
|
Util.reset_certora_internal_dir(context.build_dir)
|
|
285
291
|
os.rename(current_build_directory, context.build_dir)
|
|
286
292
|
|
|
293
|
+
if is_evm_app_class(context):
|
|
294
|
+
handle_vyper_system_path(context)
|
|
295
|
+
|
|
287
296
|
# Store current options (including the ones read from .conf file)
|
|
288
297
|
context.conf_options = current_conf_to_file(context)
|
|
289
298
|
|
|
@@ -297,6 +306,8 @@ def get_args(args_list: List[str], app: Type[App.CertoraApp]) -> CertoraContext:
|
|
|
297
306
|
validator.handle_concord_attrs()
|
|
298
307
|
if is_rust_app_class(context):
|
|
299
308
|
validator.check_rust_args_post_argparse()
|
|
309
|
+
if is_move_app_class(context):
|
|
310
|
+
validator.check_move_args_post_argparse()
|
|
300
311
|
|
|
301
312
|
attrs_to_relative(context)
|
|
302
313
|
# Setup defaults (defaults are not recorded in conf file)
|
|
@@ -594,14 +605,14 @@ def run_local_spec_check(with_typechecking: bool, context: CertoraContext, extra
|
|
|
594
605
|
raise Util.CertoraUserInputError("Cannot run local checks because of missing a suitable java installation. "
|
|
595
606
|
"To skip local checks run with the --disable_local_typechecking flag")
|
|
596
607
|
|
|
597
|
-
def
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
return input_path
|
|
608
|
+
def to_relative(input_path: Union[str, Path]) -> Union[str, Path]:
|
|
609
|
+
path = Path(input_path) if isinstance(input_path, str) else input_path
|
|
610
|
+
if path.is_absolute():
|
|
611
|
+
relative_path = os.path.relpath(path, Path.cwd()) # Path.relative_to only works for subdirectories
|
|
612
|
+
return str(relative_path) if isinstance(input_path, str) else relative_path
|
|
613
|
+
return input_path
|
|
604
614
|
|
|
615
|
+
def attrs_to_relative(context: CertoraContext) -> None:
|
|
605
616
|
def str_attr_to_relative(attr_name: str) -> None:
|
|
606
617
|
attr_value = getattr(context, attr_name, None)
|
|
607
618
|
if attr_value:
|
|
@@ -647,7 +658,6 @@ def attrs_to_relative(context: CertoraContext) -> None:
|
|
|
647
658
|
if Path(spec_file).is_absolute():
|
|
648
659
|
context.verify = ':'.join([contract, str(to_relative(spec_file))])
|
|
649
660
|
|
|
650
|
-
cwd = Path.cwd()
|
|
651
661
|
str_attr_to_relative('packages_path')
|
|
652
662
|
str_attr_to_relative('bytecode_spec')
|
|
653
663
|
str_attr_to_relative('yul_abi')
|
|
@@ -683,3 +693,24 @@ def get_map_attribute_value(context: CertoraContext, path: Path, attr_name: str)
|
|
|
683
693
|
if glob.globmatch(str(path), pattern, flags=glob.GLOBSTAR):
|
|
684
694
|
return entry_value
|
|
685
695
|
raise RuntimeError(f"cannot match {attr_name} to {path} from {attr_name}_map")
|
|
696
|
+
|
|
697
|
+
def handle_vyper_system_path(context: CertoraContext) -> None:
|
|
698
|
+
"""
|
|
699
|
+
Just like the Vyper compiler, we add the sys.path to the search path for imports, which allows us to resolve imports
|
|
700
|
+
using a package manager.
|
|
701
|
+
|
|
702
|
+
Note that we do this here, rather than allowing the Vyper compiler to do it, because we want to persist these paths
|
|
703
|
+
in the generated run.conf file, to make it easy to reproduce in a different environment.
|
|
704
|
+
"""
|
|
705
|
+
if context.resolve_vyper_imports:
|
|
706
|
+
if not context.vyper_system_path:
|
|
707
|
+
# Pass the directories from sys.path in reversed order (Vyper treats later paths as higher precedence)
|
|
708
|
+
context.vyper_system_path = [
|
|
709
|
+
to_relative(p) for p in reversed(sys.path) if Path(p).is_dir()
|
|
710
|
+
]
|
|
711
|
+
else:
|
|
712
|
+
# Filter out any directories that do not exist, to make the generated run.conf file more portable to
|
|
713
|
+
# different environments.
|
|
714
|
+
context.vyper_system_path = [
|
|
715
|
+
p for p in context.vyper_system_path if Path(p).is_dir()
|
|
716
|
+
]
|
{certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraContextAttributes.py
RENAMED
|
@@ -269,6 +269,22 @@ class DeprecatedAttributes(AttrUtil.Attributes):
|
|
|
269
269
|
main_section=MainSection.SOLIDITY_COMPILER
|
|
270
270
|
)
|
|
271
271
|
)
|
|
272
|
+
MOVE_PATH = AttrUtil.AttributeDefinition(
|
|
273
|
+
attr_validation_func=Vf.validate_dir,
|
|
274
|
+
arg_type=AttrUtil.AttrArgType.STRING,
|
|
275
|
+
help_msg="path to a directory which includes all binary .mv files for the Prover",
|
|
276
|
+
deprecation_msg="`move_path` is deprecated and will be removed in a future release. "
|
|
277
|
+
"Please use `spec_package_path` instead.",
|
|
278
|
+
default_desc="",
|
|
279
|
+
argparse_args={
|
|
280
|
+
'action': AttrUtil.UniqueStore
|
|
281
|
+
},
|
|
282
|
+
affects_build_cache_key=True,
|
|
283
|
+
disables_build_cache=False,
|
|
284
|
+
config_data=AttributeJobConfigData(
|
|
285
|
+
main_section=MainSection.NEW_SECTION
|
|
286
|
+
)
|
|
287
|
+
)
|
|
272
288
|
|
|
273
289
|
|
|
274
290
|
class EvmAttributes(AttrUtil.Attributes):
|
|
@@ -326,6 +342,51 @@ class EvmAttributes(AttrUtil.Attributes):
|
|
|
326
342
|
)
|
|
327
343
|
)
|
|
328
344
|
|
|
345
|
+
RESOLVE_VYPER_IMPORTS = AttrUtil.AttributeDefinition(
|
|
346
|
+
arg_type=AttrUtil.AttrArgType.BOOLEAN,
|
|
347
|
+
help_msg="Whether to resolve Vyper imports (Vyper >= 4 only)",
|
|
348
|
+
default_desc="Vyper contracts are assumed not to use the import system",
|
|
349
|
+
argparse_args={
|
|
350
|
+
"action": AttrUtil.STORE_TRUE
|
|
351
|
+
},
|
|
352
|
+
affects_build_cache_key=True,
|
|
353
|
+
disables_build_cache=False,
|
|
354
|
+
config_data=AttributeJobConfigData(
|
|
355
|
+
main_section=MainSection.SOLIDITY_COMPILER
|
|
356
|
+
)
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
VYPER_IMPORT_PATH = AttrUtil.AttributeDefinition(
|
|
360
|
+
attr_validation_func=Vf.validate_dir,
|
|
361
|
+
arg_type=AttrUtil.AttrArgType.LIST,
|
|
362
|
+
help_msg="Additional paths to search for Vyper imports (Vyper >= 4 only)",
|
|
363
|
+
default_desc="Only the Python system path will be searched",
|
|
364
|
+
argparse_args={
|
|
365
|
+
'nargs': AttrUtil.MULTIPLE_OCCURRENCES,
|
|
366
|
+
'action': AttrUtil.APPEND
|
|
367
|
+
},
|
|
368
|
+
affects_build_cache_key=True,
|
|
369
|
+
disables_build_cache=False,
|
|
370
|
+
config_data=AttributeJobConfigData(
|
|
371
|
+
main_section=MainSection.NEW_SECTION
|
|
372
|
+
)
|
|
373
|
+
)
|
|
374
|
+
|
|
375
|
+
VYPER_SYSTEM_PATH = AttrUtil.AttributeDefinition(
|
|
376
|
+
arg_type=AttrUtil.AttrArgType.LIST,
|
|
377
|
+
help_msg="The system path to pass to Vyper (Vyper >= 4 only); typically automatically populated",
|
|
378
|
+
default_desc="Use the current Python system path",
|
|
379
|
+
argparse_args={
|
|
380
|
+
'nargs': AttrUtil.MULTIPLE_OCCURRENCES,
|
|
381
|
+
'action': AttrUtil.APPEND
|
|
382
|
+
},
|
|
383
|
+
affects_build_cache_key=True,
|
|
384
|
+
disables_build_cache=False,
|
|
385
|
+
config_data=AttributeJobConfigData(
|
|
386
|
+
main_section=MainSection.NEW_SECTION
|
|
387
|
+
)
|
|
388
|
+
)
|
|
389
|
+
|
|
329
390
|
VYPER_CUSTOM_STD_JSON_IN_MAP = AttrUtil.AttributeDefinition(
|
|
330
391
|
arg_type=AttrUtil.AttrArgType.MAP,
|
|
331
392
|
attr_validation_func=Vf.validate_vyper_custom_std_json_in_map,
|
|
@@ -1215,7 +1276,7 @@ class EvmAttributes(AttrUtil.Attributes):
|
|
|
1215
1276
|
argparse_args={
|
|
1216
1277
|
'action': AttrUtil.STORE_TRUE
|
|
1217
1278
|
},
|
|
1218
|
-
affects_build_cache_key=
|
|
1279
|
+
affects_build_cache_key=True,
|
|
1219
1280
|
disables_build_cache=False,
|
|
1220
1281
|
)
|
|
1221
1282
|
|
|
@@ -1874,7 +1935,7 @@ class SorobanProverAttributes(CommonAttributes, InternalUseAttributes, BackendAt
|
|
|
1874
1935
|
)
|
|
1875
1936
|
|
|
1876
1937
|
|
|
1877
|
-
class SuiProverAttributes(CommonAttributes, InternalUseAttributes, BackendAttributes):
|
|
1938
|
+
class SuiProverAttributes(CommonAttributes, InternalUseAttributes, BackendAttributes, DeprecatedAttributes):
|
|
1878
1939
|
FILES = AttrUtil.AttributeDefinition(
|
|
1879
1940
|
attr_validation_func=Vf.validate_dir,
|
|
1880
1941
|
arg_type=AttrUtil.AttrArgType.LIST,
|
|
@@ -1888,10 +1949,10 @@ class SuiProverAttributes(CommonAttributes, InternalUseAttributes, BackendAttrib
|
|
|
1888
1949
|
)
|
|
1889
1950
|
)
|
|
1890
1951
|
|
|
1891
|
-
|
|
1952
|
+
SPEC_PACKAGE_PATH = AttrUtil.AttributeDefinition(
|
|
1892
1953
|
attr_validation_func=Vf.validate_dir,
|
|
1893
1954
|
arg_type=AttrUtil.AttrArgType.STRING,
|
|
1894
|
-
help_msg="path to
|
|
1955
|
+
help_msg="path to the Move package containing the specification to be verified",
|
|
1895
1956
|
default_desc="",
|
|
1896
1957
|
argparse_args={
|
|
1897
1958
|
'action': AttrUtil.UniqueStore
|
|
@@ -1903,6 +1964,17 @@ class SuiProverAttributes(CommonAttributes, InternalUseAttributes, BackendAttrib
|
|
|
1903
1964
|
)
|
|
1904
1965
|
)
|
|
1905
1966
|
|
|
1967
|
+
BUILD_SCRIPT = AttrUtil.AttributeDefinition(
|
|
1968
|
+
attr_validation_func=Vf.validate_exec_file,
|
|
1969
|
+
help_msg="script to build a Move project",
|
|
1970
|
+
default_desc="Using default building command",
|
|
1971
|
+
argparse_args={
|
|
1972
|
+
'action': AttrUtil.UniqueStore
|
|
1973
|
+
},
|
|
1974
|
+
affects_build_cache_key=False,
|
|
1975
|
+
disables_build_cache=False
|
|
1976
|
+
)
|
|
1977
|
+
|
|
1906
1978
|
RULE = AttrUtil.AttributeDefinition(
|
|
1907
1979
|
arg_type=AttrUtil.AttrArgType.LIST,
|
|
1908
1980
|
attr_validation_func=Vf.validate_move_rule_name,
|
|
@@ -2006,6 +2078,7 @@ class SolanaProverAttributes(CommonAttributes, InternalUseAttributes, BackendAtt
|
|
|
2006
2078
|
ATTRIBUTES_CLASS: Optional[Type[AttrUtil.Attributes]] = None
|
|
2007
2079
|
|
|
2008
2080
|
ARG_FLAG_LIST_ATTRIBUTES = ['prover_args', 'java_args']
|
|
2081
|
+
DUPLICATES_ALLOWED_LIST_ATTRIBUTES = [*ARG_FLAG_LIST_ATTRIBUTES, 'vyper_system_path']
|
|
2009
2082
|
|
|
2010
2083
|
|
|
2011
2084
|
def get_attribute_class() -> Type[AttrUtil.Attributes]:
|
{certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraContextValidator.py
RENAMED
|
@@ -146,7 +146,7 @@ class CertoraContextValidator:
|
|
|
146
146
|
# Check for duplicates, we exclude ARG_FLAG_LIST_ATTRIBUTES as those can have duplicates e.g.
|
|
147
147
|
# prover_args value of “-rule rule1 -rule rule2" is valid, although the -rule string appears more than once.
|
|
148
148
|
|
|
149
|
-
if conf_key not in Attrs.
|
|
149
|
+
if conf_key not in Attrs.DUPLICATES_ALLOWED_LIST_ATTRIBUTES:
|
|
150
150
|
if len(value) != len(set(value)):
|
|
151
151
|
raise Util.CertoraUserInputError(f"The value of attribute '{conf_key}' contains duplicate entries: {value}")
|
|
152
152
|
|
|
@@ -196,6 +196,20 @@ class CertoraContextValidator:
|
|
|
196
196
|
ci_value=str(Vf.UrlVisibilityOptions.PUBLIC),
|
|
197
197
|
default_value=str(Vf.UrlVisibilityOptions.PRIVATE))
|
|
198
198
|
|
|
199
|
+
def check_move_args_post_argparse(self) -> None:
|
|
200
|
+
context = self.context
|
|
201
|
+
if context.move_path:
|
|
202
|
+
# Old-style move_path specification. We don't support build scripts or package paths in this case
|
|
203
|
+
if context.build_script:
|
|
204
|
+
raise Util.CertoraUserInputError(
|
|
205
|
+
"'move_path' and 'build_script' cannot be used together. To target a specific Move package with a "
|
|
206
|
+
"build script, specify `spec_package_path`."
|
|
207
|
+
)
|
|
208
|
+
if context.spec_package_path:
|
|
209
|
+
raise Util.CertoraUserInputError(
|
|
210
|
+
"'move_path' and 'spec_package_path' cannot be used together. `spec_package_path` is preferred."
|
|
211
|
+
)
|
|
212
|
+
|
|
199
213
|
def check_args_post_argparse(self) -> None:
|
|
200
214
|
"""
|
|
201
215
|
Performs checks over the arguments after basic argparse parsing
|
|
@@ -229,6 +243,7 @@ class CertoraContextValidator:
|
|
|
229
243
|
set_bytecode_relative_paths(context)
|
|
230
244
|
check_files_input(context.files)
|
|
231
245
|
check_vyper_flag(context)
|
|
246
|
+
check_vyper_imports(context)
|
|
232
247
|
check_via_ir_attr(context)
|
|
233
248
|
check_contract_name_arg_inputs(context) # Here context.contracts is set
|
|
234
249
|
Util.check_packages_arguments(context)
|
|
@@ -426,6 +441,15 @@ def check_vyper_flag(context: CertoraContext) -> None:
|
|
|
426
441
|
if not vy_paths:
|
|
427
442
|
validation_logger.warning("vyper attribute was set but no Vyper files were set")
|
|
428
443
|
|
|
444
|
+
def check_vyper_imports(context: CertoraContext) -> None:
|
|
445
|
+
if not context.resolve_vyper_imports:
|
|
446
|
+
if context.vyper_import_path:
|
|
447
|
+
raise Util.CertoraUserInputError("cannot set 'vyper_import_path' without setting 'resolve_vyper_imports' "
|
|
448
|
+
"to true")
|
|
449
|
+
if context.vyper_system_path:
|
|
450
|
+
raise Util.CertoraUserInputError("cannot set 'vyper_system_path' without setting 'resolve_vyper_imports' "
|
|
451
|
+
"to true")
|
|
452
|
+
|
|
429
453
|
def check_contract_name_arg_inputs(context: CertoraContext) -> None:
|
|
430
454
|
"""
|
|
431
455
|
This function verifies that all options that expect to get contract names get valid contract names.
|
|
@@ -265,8 +265,10 @@ def get_debug_log_file() -> Path:
|
|
|
265
265
|
def get_extension_info_file() -> Path:
|
|
266
266
|
return path_in_build_directory(Path(".vscode_extension_info.json"))
|
|
267
267
|
|
|
268
|
+
ASTS_FILE_NAME = ".asts.json"
|
|
269
|
+
|
|
268
270
|
def get_asts_file() -> Path:
|
|
269
|
-
return path_in_build_directory(Path(
|
|
271
|
+
return path_in_build_directory(Path(ASTS_FILE_NAME))
|
|
270
272
|
|
|
271
273
|
def get_zip_output_url_file() -> Path:
|
|
272
274
|
return CERTORA_INTERNAL_ROOT / '.zip-output-url.txt'
|
|
@@ -874,6 +874,12 @@ def validate_evm_rule_name(rule_str: str) -> str:
|
|
|
874
874
|
else:
|
|
875
875
|
return __validate_solidity_id(rule_str, "rule")
|
|
876
876
|
|
|
877
|
+
def validate_move_rule_pattern_string(rule_str: str) -> str:
|
|
878
|
+
if not re.match(r"^([a-zA-Z0-9_$*]|::)+$", rule_str):
|
|
879
|
+
raise Util.CertoraUserInputError(f"invalid rule pattern \"{rule_str}\": rule patterns must contain only "
|
|
880
|
+
"letters, digits, dollar signs, underscores, asterisks, or double colons")
|
|
881
|
+
return rule_str
|
|
882
|
+
|
|
877
883
|
def validate_move_function_name(name: str) -> str:
|
|
878
884
|
if not re.match(r"^(0x[0-9a-fA-F]+|([a-zA-Z_][a-zA-Z0-9_]*))::[a-zA-Z_][a-zA-Z0-9_]*::[a-zA-Z_][a-zA-Z0-9_]*$", name):
|
|
879
885
|
raise Util.CertoraUserInputError(f"invalid Move function name \"{name}\": must be a fully-qualified Move "
|
|
@@ -882,7 +888,7 @@ def validate_move_function_name(name: str) -> str:
|
|
|
882
888
|
|
|
883
889
|
def validate_move_rule_name(rule_str: str) -> str:
|
|
884
890
|
if ("*" in rule_str):
|
|
885
|
-
return
|
|
891
|
+
return validate_move_rule_pattern_string(rule_str)
|
|
886
892
|
else:
|
|
887
893
|
return validate_move_function_name(rule_str)
|
|
888
894
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: certora-cli
|
|
3
|
-
Version: 8.
|
|
3
|
+
Version: 8.11.3
|
|
4
4
|
Summary: Runner for the Certora Prover
|
|
5
5
|
Home-page: https://pypi.org/project/certora-cli
|
|
6
6
|
Author: Certora
|
|
@@ -38,4 +38,4 @@ Dynamic: requires-dist
|
|
|
38
38
|
Dynamic: requires-python
|
|
39
39
|
Dynamic: summary
|
|
40
40
|
|
|
41
|
-
Commit
|
|
41
|
+
Commit d4f463a. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
|
certora_cli-8.8.1/certora_jars/Typechecker.jar → certora_cli-8.11.3/certora_jars/ASTExtraction.jar
RENAMED
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"name": "certora-cli", "tag": "8.11.3", "branch": "", "commit": "d4f463a", "timestamp": "20260421.18.49.434064", "version": "8.11.3"}
|
certora_cli-8.8.1/certora_jars/ASTExtraction.jar → certora_cli-8.11.3/certora_jars/Typechecker.jar
RENAMED
|
Binary file
|
|
@@ -3,11 +3,11 @@ import setuptools
|
|
|
3
3
|
|
|
4
4
|
setuptools.setup(
|
|
5
5
|
name="certora-cli",
|
|
6
|
-
version="8.
|
|
6
|
+
version="8.11.3",
|
|
7
7
|
author="Certora",
|
|
8
8
|
author_email="support@certora.com",
|
|
9
9
|
description="Runner for the Certora Prover",
|
|
10
|
-
long_description="Commit
|
|
10
|
+
long_description="Commit d4f463a. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.",
|
|
11
11
|
long_description_content_type="text/markdown",
|
|
12
12
|
url="https://pypi.org/project/certora-cli",
|
|
13
13
|
packages=setuptools.find_packages(),
|
certora_cli-8.8.1/README.md
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
Commit 64c2b53. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"name": "certora-cli", "tag": "8.8.1", "branch": "", "commit": "64c2b53", "timestamp": "20260224.14.28.979875", "version": "8.8.1"}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/Compiler/CompilerCollector.py
RENAMED
|
File without changes
|
|
File without changes
|
{certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/Compiler/CompilerCollectorSol.py
RENAMED
|
File without changes
|
|
File without changes
|
{certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/Compiler/CompilerCollectorVy.py
RENAMED
|
File without changes
|
{certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/Compiler/CompilerCollectorYul.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraBuildDataClasses.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraCollectRunMetadata.py
RENAMED
|
File without changes
|
{certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraCompilerParameters.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraOffsetConverter.py
RENAMED
|
File without changes
|
{certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraParseBuildScript.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/certoraVerifyGenerator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/CertoraProver/uncheckedOverflowInstrumenter.py
RENAMED
|
File without changes
|
|
File without changes
|
{certora_cli-8.8.1 → certora_cli-8.11.3}/certora_cli/EquivalenceCheck/Eq_mc_no_out_template.spec
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|