certora-cli-alpha-master 20250619.9.58.547847__tar.gz → 20250619.15.39.58921__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.
Files changed (83) hide show
  1. {certora_cli_alpha_master-20250619.9.58.547847/certora_cli_alpha_master.egg-info → certora_cli_alpha_master-20250619.15.39.58921}/PKG-INFO +2 -2
  2. certora_cli_alpha_master-20250619.15.39.58921/README.md +1 -0
  3. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/Compiler/CompilerCollectorFactory.py +5 -2
  4. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraBuild.py +31 -30
  5. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraCollectConfigurationLayout.py +62 -51
  6. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraContext.py +29 -0
  7. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraContextAttributes.py +1 -2
  8. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraContextValidator.py +29 -25
  9. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/Shared/certoraUtils.py +1 -29
  10. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/Shared/certoraValidateFuncs.py +1 -1
  11. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921/certora_cli_alpha_master.egg-info}/PKG-INFO +2 -2
  12. certora_cli_alpha_master-20250619.15.39.58921/certora_jars/CERTORA-CLI-VERSION-METADATA.json +1 -0
  13. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_jars/Typechecker.jar +0 -0
  14. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/setup.py +2 -2
  15. certora_cli_alpha_master-20250619.9.58.547847/README.md +0 -1
  16. certora_cli_alpha_master-20250619.9.58.547847/certora_jars/CERTORA-CLI-VERSION-METADATA.json +0 -1
  17. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/LICENSE +0 -0
  18. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/MANIFEST.in +0 -0
  19. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_bins/__init__.py +0 -0
  20. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/Compiler/CompilerCollector.py +0 -0
  21. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/Compiler/CompilerCollectorSol.py +0 -0
  22. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/Compiler/CompilerCollectorSolBased.py +0 -0
  23. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/Compiler/CompilerCollectorVy.py +0 -0
  24. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/Compiler/CompilerCollectorYul.py +0 -0
  25. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/Compiler/__init__.py +0 -0
  26. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/__init__.py +0 -0
  27. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraBuildCacheManager.py +0 -0
  28. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraBuildDataClasses.py +0 -0
  29. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraBuildRust.py +0 -0
  30. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraCloudIO.py +0 -0
  31. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraCollectRunMetadata.py +0 -0
  32. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraCompilerParameters.py +0 -0
  33. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraConfigIO.py +0 -0
  34. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraContextClass.py +0 -0
  35. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraContractFuncs.py +0 -0
  36. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraExtensionInfo.py +0 -0
  37. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraJobList.py +0 -0
  38. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraMiniSpecParser.py +0 -0
  39. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraNodeFilters.py +0 -0
  40. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraParseBuildScript.py +0 -0
  41. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraProjectScanner.py +0 -0
  42. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraSourceFinders.py +0 -0
  43. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraType.py +0 -0
  44. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/certoraVerifyGenerator.py +0 -0
  45. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/erc7201.py +0 -0
  46. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/splitRules.py +0 -0
  47. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/CertoraProver/storageExtension.py +0 -0
  48. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/EquivalenceCheck/Eq_default.conf +0 -0
  49. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/EquivalenceCheck/Eq_mc_no_out_template.spec +0 -0
  50. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/EquivalenceCheck/Eq_mc_template.spec +0 -0
  51. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/EquivalenceCheck/Eq_sanity.conf +0 -0
  52. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/EquivalenceCheck/Eq_template.spec +0 -0
  53. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/EquivalenceCheck/__init__.py +0 -0
  54. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/EquivalenceCheck/equivCheck.py +0 -0
  55. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/EquivalenceCheck/sanity.spec +0 -0
  56. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/Mutate/__init__.py +0 -0
  57. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/Mutate/mutateApp.py +0 -0
  58. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/Mutate/mutateAttributes.py +0 -0
  59. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/Mutate/mutateConstants.py +0 -0
  60. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/Mutate/mutateUtil.py +0 -0
  61. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/Mutate/mutateValidate.py +0 -0
  62. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/Shared/ExpectedComparator.py +0 -0
  63. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/Shared/__init__.py +0 -0
  64. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/Shared/certoraAttrUtil.py +0 -0
  65. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/Shared/certoraLogging.py +0 -0
  66. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/Shared/proverCommon.py +0 -0
  67. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/Shared/rustProverCommon.py +0 -0
  68. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/__init__.py +0 -0
  69. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/certoraEVMProver.py +0 -0
  70. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/certoraEqCheck.py +0 -0
  71. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/certoraMutate.py +0 -0
  72. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/certoraRanger.py +0 -0
  73. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/certoraRun.py +0 -0
  74. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/certoraSolanaProver.py +0 -0
  75. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/certoraSorobanProver.py +0 -0
  76. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli/rustMutator.py +0 -0
  77. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli_alpha_master.egg-info/SOURCES.txt +0 -0
  78. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli_alpha_master.egg-info/dependency_links.txt +0 -0
  79. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli_alpha_master.egg-info/entry_points.txt +0 -0
  80. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli_alpha_master.egg-info/requires.txt +0 -0
  81. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_cli_alpha_master.egg-info/top_level.txt +0 -0
  82. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/certora_jars/__init__.py +0 -0
  83. {certora_cli_alpha_master-20250619.9.58.547847 → certora_cli_alpha_master-20250619.15.39.58921}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: certora-cli-alpha-master
3
- Version: 20250619.9.58.547847
3
+ Version: 20250619.15.39.58921
4
4
  Summary: Runner for the Certora Prover
5
5
  Home-page: https://pypi.org/project/certora-cli-alpha-master
6
6
  Author: Certora
@@ -38,4 +38,4 @@ Dynamic: requires-dist
38
38
  Dynamic: requires-python
39
39
  Dynamic: summary
40
40
 
41
- Commit e775225. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
41
+ Commit ee27c34. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
@@ -0,0 +1 @@
1
+ Commit ee27c34. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
@@ -25,8 +25,9 @@ from CertoraProver.Compiler.CompilerCollector import CompilerLang, CompilerColle
25
25
  from CertoraProver.Compiler.CompilerCollectorSol import CompilerCollectorSol, CompilerLangSol
26
26
  from CertoraProver.Compiler.CompilerCollectorYul import CompilerLangYul, CompilerCollectorYul
27
27
  from CertoraProver.Compiler.CompilerCollectorVy import CompilerCollectorVy, CompilerLangVy
28
- from Shared.certoraUtils import match_path_to_mapping_key, remove_file, get_certora_config_dir
28
+ from Shared.certoraUtils import remove_file, get_certora_config_dir
29
29
  from CertoraProver.certoraContextClass import CertoraContext
30
+ import CertoraProver.certoraContext as Ctx
30
31
 
31
32
  # logger for running the Solidity compiler and reporting any errors it emits
32
33
  compiler_logger = logging.getLogger("compiler")
@@ -49,7 +50,9 @@ def get_relevant_compiler(contract_file_path: Path, context: CertoraContext) ->
49
50
  contract_file_path = Path(os.path.relpath(contract_file_path, cwd_in_source))
50
51
 
51
52
  if context.compiler_map:
52
- match = match_path_to_mapping_key(contract_file_path, context.compiler_map)
53
+ match = Ctx.get_map_attribute_value(context, contract_file_path, 'compiler')
54
+ assert isinstance(match, str), (f"In the attribute compiler_map, {contract_file_path} expected to be matched "
55
+ f"to a string, {match} is of type {type(match)} not a string")
53
56
  if match:
54
57
  return match
55
58
  else:
@@ -1365,47 +1365,48 @@ class CertoraBuildGenerator:
1365
1365
 
1366
1366
  return bytecode
1367
1367
 
1368
- def get_via_ir_value(self, contract_file_path: str) -> bool:
1369
- if not self.context.solc_via_ir_map and not self.context.solc_via_ir:
1370
- return False
1371
- if self.context.solc_via_ir_map:
1372
- return bool(Util.match_path_to_mapping_key(Path(contract_file_path), self.context.solc_via_ir_map))
1373
- return self.context.solc_via_ir
1374
-
1375
- def _handle_via_ir(self, contract_file_path: str, settings_dict: Dict[str, Any]) -> None:
1376
- if self.get_via_ir_value(contract_file_path):
1368
+ def get_solc_via_ir_value(self, contract_file_path: Path) -> bool:
1369
+ match = Ctx.get_map_attribute_value(self.context, contract_file_path, 'solc_via_ir')
1370
+ assert isinstance(match, (bool, type(None))), f"Expected solc_via_ir to be bool or None, got {type(match)}"
1371
+ return bool(match)
1372
+
1373
+ def get_solc_evm_version_value(self, contract_file_path: Path) -> Optional[str]:
1374
+ match = Ctx.get_map_attribute_value(self.context, contract_file_path, 'solc_evm_version')
1375
+ assert isinstance(match, (str, type(None))), f"Expected solc_evm_version to be string or None, got {type(match)}"
1376
+ return match
1377
+
1378
+ def get_solc_optimize_value(self, contract_file_path: Path) -> Optional[str]:
1379
+ match = Ctx.get_map_attribute_value(self.context, contract_file_path, 'solc_optimize')
1380
+ assert isinstance(match, (str, type(None))), f"Expected solc_optimize to be string or None, got {type(match)}"
1381
+ return match
1382
+
1383
+ def _handle_via_ir(self, contract_file_path: Path, settings_dict: Dict[str, Any]) -> None:
1384
+ if self.get_solc_via_ir_value(contract_file_path):
1377
1385
  settings_dict["viaIR"] = True
1378
1386
 
1379
- def _handle_evm_version(self, contract_file_path: str, settings_dict: Dict[str, Any]) -> None:
1380
- if self.context.solc_evm_version_map:
1381
- match = Util.match_path_to_mapping_key(Path(contract_file_path), self.context.solc_evm_version_map)
1382
- if match:
1383
- settings_dict["evmVersion"] = match
1384
- elif self.context.solc_evm_version:
1385
- settings_dict["evmVersion"] = self.context.solc_evm_version
1387
+ def _handle_evm_version(self, contract_file_path: Path, settings_dict: Dict[str, Any]) -> None:
1388
+ match = self.get_solc_evm_version_value(contract_file_path)
1389
+ if match:
1390
+ settings_dict["evmVersion"] = match
1386
1391
 
1387
- def _handle_optimize(self, contract_file_path: str, settings_dict: Dict[str, Any],
1392
+ def _handle_optimize(self, contract_file_path: Path, settings_dict: Dict[str, Any],
1388
1393
  compiler_collector: CompilerCollector) -> None:
1389
1394
  """
1390
1395
  @param contract_file_path: the contract that we are working on
1391
1396
  @param settings_dict: data structure for sending to the solc compiler
1392
1397
  """
1393
- if self.context.solc_optimize_map:
1394
- match = Util.match_path_to_mapping_key(Path(contract_file_path), self.context.solc_optimize_map)
1395
- if match and int(match) > 0:
1396
- settings_dict["optimizer"] = {"enabled": True}
1397
- settings_dict["optimizer"]['runs'] = int(match)
1398
- elif self.context.solc_optimize:
1398
+ match = self.get_solc_optimize_value(contract_file_path)
1399
+ if match:
1399
1400
  settings_dict["optimizer"] = {"enabled": True}
1400
- if int(self.context.solc_optimize) > 0:
1401
- settings_dict["optimizer"]['runs'] = int(self.context.solc_optimize)
1401
+ if int(match) > 0:
1402
+ settings_dict["optimizer"]['runs'] = int(match)
1402
1403
 
1403
1404
  # if optimizer is true, we should also define settings_dict["optimizer"]["details"]
1404
1405
  # for both optimize map and optimize
1405
1406
  optimizer = settings_dict.get("optimizer")
1406
1407
  if optimizer and isinstance(optimizer, dict) and optimizer.get('enabled'):
1407
1408
  # if we are not disabling finder friendly optimizer specifically, enable it whenever viaIR is also enabled
1408
- if not self.context.strict_solc_optimizer and self.get_via_ir_value(contract_file_path):
1409
+ if not self.context.strict_solc_optimizer and self.get_solc_via_ir_value(contract_file_path):
1409
1410
  # The default optimizer steps (taken from libsolidity/interface/OptimiserSettings.h) but with the
1410
1411
  # full inliner step removed
1411
1412
  solc0_8_26_to_0_8_30 = ("dhfoDgvulfnTUtnIfxa[r]EscLMVcul[j]Trpeulxa[r]cLCTUca[r]LSsTFOtfDnca[r]" +
@@ -1475,7 +1476,7 @@ class CertoraBuildGenerator:
1475
1476
  for opt_pass in self.context.disable_solc_optimizers:
1476
1477
  settings_dict["optimizer"]["details"][opt_pass] = False
1477
1478
 
1478
- def _fill_codegen_related_options(self, contract_file_path: str, settings_dict: Dict[str, Any],
1479
+ def _fill_codegen_related_options(self, contract_file_path: Path, settings_dict: Dict[str, Any],
1479
1480
  compiler_collector: CompilerCollector) -> None:
1480
1481
  """
1481
1482
  Fills options that control how we call solc and affect the bytecode in some way
@@ -1556,7 +1557,7 @@ class CertoraBuildGenerator:
1556
1557
  }
1557
1558
  }
1558
1559
 
1559
- self._fill_codegen_related_options(contract_file_as_provided, settings_dict, compiler_collector)
1560
+ self._fill_codegen_related_options(Path(contract_file_as_provided), settings_dict, compiler_collector)
1560
1561
 
1561
1562
  result_dict = {"language": compiler_collector_lang.name, "sources": sources_dict, "settings": settings_dict}
1562
1563
  # debug_print("Standard json input")
@@ -2291,7 +2292,7 @@ class CertoraBuildGenerator:
2291
2292
 
2292
2293
  if compiler_lang == CompilerLangSol():
2293
2294
  settings_dict: Dict[str, Any] = {}
2294
- self._fill_codegen_related_options(build_arg_contract_file, settings_dict,
2295
+ self._fill_codegen_related_options(Path(build_arg_contract_file), settings_dict,
2295
2296
  compiler_collector_for_contract_file)
2296
2297
  solc_optimizer_on, solc_optimizer_runs = self.solc_setting_optimizer_runs(settings_dict)
2297
2298
  solc_via_ir = self.solc_setting_via_ir(settings_dict)
@@ -2421,7 +2422,7 @@ class CertoraBuildGenerator:
2421
2422
  # if no function finder mode set, determine based on viaIR enabled or not:
2422
2423
  if self.context.function_finder_mode is None:
2423
2424
  # in via-ir, should not compress
2424
- if self.get_via_ir_value(contract_file):
2425
+ if self.get_solc_via_ir_value(Path(contract_file)):
2425
2426
  should_compress = False
2426
2427
  else:
2427
2428
  should_compress = True
@@ -25,12 +25,13 @@ sys.path.insert(0, str(scripts_dir_path))
25
25
  import CertoraProver.certoraContextAttributes as Attrs
26
26
  from CertoraProver.certoraCollectRunMetadata import RunMetaData, MetadataEncoder
27
27
  import Shared.certoraUtils as Utils
28
+ from typing import List
28
29
 
29
30
 
30
31
  class MainSection(Enum):
31
32
  GENERAL = "GENERAL"
33
+ OPTIONS = "OPTIONS"
32
34
  SOLIDITY_COMPILER = "SOLIDITY_COMPILER"
33
- GIT = "GIT"
34
35
  NEW_SECTION = "NEW_SECTION"
35
36
 
36
37
 
@@ -47,13 +48,11 @@ class InnerContent:
47
48
  content: Any
48
49
  doc_link: str = ''
49
50
  tooltip: str = ''
50
- unsound: str = 'false'
51
+ unsound: bool = False
51
52
 
52
53
  def __post_init__(self) -> None:
53
54
  if isinstance(self.content, bool):
54
55
  self.content = 'true' if self.content else 'false'
55
- if isinstance(self.unsound, bool):
56
- self.unsound = 'true' if self.unsound else 'false'
57
56
 
58
57
 
59
58
  @dataclasses.dataclass
@@ -65,6 +64,7 @@ class CardContent:
65
64
 
66
65
  DOC_LINK_PREFIX = 'https://docs.certora.com/en/latest/docs/'
67
66
  GIT_ATTRIBUTES = ['origin', 'revision', 'branch', 'dirty']
67
+ ARG_LIST_ATTRIBUTES = ['prover_args', 'java_args']
68
68
 
69
69
 
70
70
  class AttributeJobConfigData:
@@ -73,13 +73,13 @@ class AttributeJobConfigData:
73
73
  This should be added to the AttributeDefinition and configured for every new attribute
74
74
  presented in the Rule report.
75
75
 
76
- Note: Attributes which do not contain specific information will be assigned as a Flag in the General main section!
76
+ Note: Attributes that do not contain specific information will be presented in the OPTIONS main section!
77
77
 
78
78
  arguments:
79
79
  - main_section : MainSection -- the main section inside the config tab
80
- default: MainSection.GENERAL
81
- - subsection : str -- the subsection within the main_section (e.g Flags)
82
- default: Flags
80
+ default: MainSection.OPTIONS
81
+ - subsection : str -- the subsection within the main_section
82
+ default: None - they will be presented inside the OPTIONS card
83
83
  - doc_link : Optional[str] -- a link to the Documentation page of this attribute (if exists)
84
84
  default: 'https://docs.certora.com/en/latest/docs/' + Solana/EVM path + #<attribute_name>
85
85
  - tooltip : Optional[str] -- a description of this attribute to present in the config tab
@@ -88,7 +88,7 @@ class AttributeJobConfigData:
88
88
  default: False
89
89
  """
90
90
 
91
- def __init__(self, main_section: MainSection = MainSection.GENERAL, subsection: str = '',
91
+ def __init__(self, main_section: MainSection = MainSection.OPTIONS, subsection: str = '',
92
92
  doc_link: Optional[str] = '', tooltip: Optional[str] = '', unsound: bool = False):
93
93
  self.main_section = main_section
94
94
  self.subsection = subsection
@@ -201,6 +201,40 @@ def create_or_get_card_content(output: list[CardContent], name: str) -> CardCont
201
201
  return main_section
202
202
 
203
203
 
204
+ def split_and_sort_arg_list_value(args_list: List[str]) -> List[str]:
205
+ """
206
+ Splits a unified CLI argument list of strings into a sorted list of flag+value groups.
207
+ This is useful mainly for --prover_args and --java_args.
208
+
209
+ For example:
210
+ "-depth 15 -adaptiveSolverConfig false" → ["-adaptiveSolverConfig false", "-depth 15"]
211
+
212
+ Assumes each flag starts with '-' and its value follows immediately, if exists.
213
+ Lines are sorted alphabetically.
214
+ """
215
+ unified_args = ''.join(args_list)
216
+
217
+ if not unified_args.strip():
218
+ return []
219
+
220
+ lines: List[str] = []
221
+ tokens = unified_args.split()
222
+ curr_line = ""
223
+
224
+ for token in tokens:
225
+ if token.startswith('-'):
226
+ if curr_line:
227
+ lines.append(curr_line)
228
+ curr_line = token
229
+ else:
230
+ curr_line += f" {token}"
231
+
232
+ if curr_line:
233
+ lines.append(curr_line)
234
+
235
+ return sorted(lines)
236
+
237
+
204
238
  def create_inner_content(name: str, content_type: ContentType, value: Any, doc_link: str,
205
239
  config_data: AttributeJobConfigData) -> InnerContent:
206
240
  return InnerContent(
@@ -209,7 +243,7 @@ def create_inner_content(name: str, content_type: ContentType, value: Any, doc_l
209
243
  content=value,
210
244
  doc_link=doc_link,
211
245
  tooltip=config_data.tooltip or '',
212
- unsound='true' if config_data.unsound else 'false'
246
+ unsound=config_data.unsound
213
247
  )
214
248
 
215
249
 
@@ -260,35 +294,23 @@ def collect_attribute_configs(metadata: dict) -> list[CardContent]:
260
294
  )
261
295
  continue
262
296
 
263
- # Find or create the subsection (if it exists)
297
+ # Find or create the subsection (if it doesn't exist)
264
298
  if isinstance(attr_value, list):
265
- current_section: Any = main_section
266
299
  content_type = ContentType.SIMPLE
300
+ if attr_name in ARG_LIST_ATTRIBUTES:
301
+ attr_value = split_and_sort_arg_list_value(attr_value)
267
302
 
268
303
  elif isinstance(attr_value, dict):
269
- current_section = main_section
270
304
  content_type = ContentType.COMPLEX
271
305
  attr_value = [
272
306
  create_inner_content(key, ContentType.FLAG, value, doc_link, config_data)
273
307
  for key, value in attr_value.items()
274
308
  ]
275
309
  else:
276
- # this attribute is a value attribute without a subsection, it will be placed in flags.
277
- subsection_key = config_data.subsection.lower() if config_data.subsection else 'flags'
278
- current_section = next((section for section in main_section.content
279
- if section.inner_title == subsection_key), None)
280
- if current_section is None:
281
- current_section = InnerContent(
282
- inner_title=subsection_key,
283
- content_type=ContentType.COMPLEX.value,
284
- content=[]
285
- )
286
- main_section.content.append(current_section)
287
-
288
310
  content_type = ContentType.FLAG
289
311
 
290
312
  # Update the current section with attribute details
291
- current_section.content.append(
313
+ main_section.content.append(
292
314
  create_inner_content(attr_name, content_type, attr_value, doc_link, config_data)
293
315
  )
294
316
 
@@ -300,37 +322,23 @@ def collect_run_config_from_metadata(attributes_configs: list[CardContent], meta
300
322
  Adding CLI and Git configuration from metadata
301
323
  """
302
324
 
303
- # Define a mapping of metadata attributes to their keys in general_section
304
- metadata_mappings = {
305
- 'CLI Version': metadata.get('CLI_version'),
306
- 'Verify': metadata.get('conf', {}).get('verify'),
307
- }
308
-
309
325
  general_section = create_or_get_card_content(attributes_configs, MainSection.GENERAL.value.lower())
310
326
 
311
- # Add metadata attributes dynamically if they exist
312
- for key, value in metadata_mappings.items():
313
- if value:
314
- general_section.content.append(InnerContent(
315
- inner_title=key,
316
- content_type=ContentType.FLAG.value,
317
- content=value,
318
- ))
327
+ if cli_version := metadata.get('CLI_version'):
328
+ general_section.content.append(InnerContent(
329
+ inner_title='CLI Version',
330
+ content_type=ContentType.FLAG.value,
331
+ content=cli_version,
332
+ ))
319
333
 
320
- # Adding GIT configuration from metadata only if attributes are found
321
- git_content = []
322
334
  for attr in GIT_ATTRIBUTES:
323
335
  if attr_value := metadata.get(attr):
324
- git_content.append(InnerContent(
336
+ general_section.content.append(InnerContent(
325
337
  inner_title=attr,
326
338
  content_type=ContentType.FLAG.value,
327
339
  content=attr_value,
328
340
  ))
329
341
 
330
- if git_content:
331
- git_section = create_or_get_card_content(attributes_configs, MainSection.GIT.value.lower())
332
- git_section.content = git_content
333
-
334
342
  return attributes_configs
335
343
 
336
344
 
@@ -338,14 +346,17 @@ def sort_configuration_layout(data: list[CardContent]) -> list[CardContent]:
338
346
  """
339
347
  Sorts a configuration layout:
340
348
  - Top-level sorted by 'card_title'
341
- - Nested content sorted by 'inner_title', with 'Verify' first
349
+ - Nested content sorted by 'inner_title', with 'verify' first
342
350
  """
343
351
  priority = {
344
- "Verify": 0,
352
+ # Priorities for top-level cards
345
353
  "general": 0,
354
+ "files": 1,
355
+ "options": 2,
356
+ # Top level items inside their respective cards
357
+ "verify": 0,
346
358
  "solc": 0,
347
- "CLI Version": 1,
348
- "flags": 2
359
+ "CLI Version": 0
349
360
  }
350
361
 
351
362
  def inner_sort_key(item: Any) -> Any:
@@ -20,6 +20,8 @@ import os
20
20
  import re
21
21
  import sys
22
22
  import logging
23
+ import fnmatch
24
+ from wcmatch import glob
23
25
 
24
26
 
25
27
  from pathlib import Path
@@ -613,3 +615,30 @@ def attrs_to_relative(context: CertoraContext) -> None:
613
615
  packages_to_relative()
614
616
  prover_resource_file_to_relative()
615
617
  verify_to_relative()
618
+
619
+ def get_map_attribute_value(context: CertoraContext, path: Path, attr_name: str) -> Optional[str | bool]:
620
+
621
+ value = getattr(context, attr_name, None)
622
+ if value:
623
+ return value
624
+
625
+ map_value = getattr(context, f"{attr_name}_map", None)
626
+ if not map_value:
627
+ return None # No map value defined
628
+ for key, entry_value in map_value.items():
629
+ # Split key to handle contract:field syntax
630
+ key_parts = key.split(':')
631
+ pattern = key_parts[0]
632
+
633
+ if Path(pattern).suffix == "": # This is a contract pattern
634
+ # Find contracts that match the pattern
635
+ for contract_name, contract_file_path in context.contract_to_file.items():
636
+ if fnmatch.fnmatch(contract_name, pattern):
637
+ # Check if this contract's file matches our target path
638
+ if Path(contract_file_path) == path:
639
+ return entry_value
640
+ else: # This is a file pattern
641
+ # Match the file pattern against the path
642
+ if glob.globmatch(str(path), pattern, flags=glob.GLOBSTAR):
643
+ return entry_value
644
+ return None # No match
@@ -740,8 +740,7 @@ class EvmAttributes(AttrUtil.Attributes):
740
740
  'action': AttrUtil.UniqueStore
741
741
  },
742
742
  affects_build_cache_key=False,
743
- disables_build_cache=False,
744
- config_data=None
743
+ disables_build_cache=False
745
744
  )
746
745
 
747
746
  BUILD_CACHE = AttrUtil.AttributeDefinition(
@@ -19,7 +19,9 @@ import re
19
19
  import sys
20
20
  import itertools
21
21
  import tempfile
22
+ import fnmatch
22
23
  from pathlib import Path
24
+ from wcmatch import glob
23
25
  from typing import Dict, List, Tuple, Set, Any, Union, OrderedDict
24
26
 
25
27
  import CertoraProver.certoraContext as Ctx
@@ -666,6 +668,20 @@ def check_mode_of_operation(context: CertoraContext) -> None:
666
668
  special_file_type]) and not context.build_only:
667
669
  raise Util.CertoraUserInputError("You must use 'verify' when running the Certora Prover")
668
670
 
671
+ def find_matching_contracts(context: CertoraContext, pattern: str) -> List[str]:
672
+ result = []
673
+ for contract in context.contract_to_file:
674
+ if fnmatch.fnmatch(contract, pattern):
675
+ result.append(context.contract_to_file[contract])
676
+ return result
677
+
678
+ def find_matching_files(context: CertoraContext, pattern: str) -> List[str]:
679
+ result = []
680
+
681
+ for path in context.file_paths:
682
+ if glob.globmatch(path, pattern, flags=glob.GLOBSTAR):
683
+ result.append(path)
684
+ return result
669
685
 
670
686
  def check_map_attributes(context: CertoraContext) -> None:
671
687
 
@@ -686,33 +702,21 @@ def check_map_attributes(context: CertoraContext) -> None:
686
702
  if not isinstance(map_attr, OrderedDict):
687
703
  raise RuntimeError(f"`map_attr` is not an ordered dictionary, got {map_attr}")
688
704
 
689
- # handle contracts
690
- # creating a copy since we cannot modify the OrderedDict while iterating over it
691
- new_map_attr = map_attr.copy()
705
+ # will check that all the contract files are matched
706
+ file_list: Dict[str, bool] = {path: False for path in context.file_paths}
692
707
 
693
708
  for key, value in map_attr.items():
694
- key_parts = key.split(':')
695
- if Path(key_parts[0]).suffix == "" and key_parts[0] in context.contract_to_file:
696
- # key is a contract in a known file
697
- contract_key = key_parts[0]
698
- contract_file = context.contract_to_file[contract_key]
699
- if contract_file in map_attr:
700
- if map_attr[contract_file] != value:
701
- # contract binding conflicts with an existing binding
702
- raise Util.CertoraUserInputError(f"mapping of `{key}` to `{value}` in `{map_attr_name}` conflicts"
703
- f" with an existing binding of `{contract_file}` to"
704
- f" `{map_attr[contract_file]}`")
705
- else:
706
- # no binding for the contract file, so we add it to the attribute
707
- new_map_attr[contract_file] = value
708
- # move to head
709
- new_map_attr.move_to_end(contract_file, last=False)
710
- setattr(context, map_attr_name, new_map_attr)
711
-
712
- for path in context.file_paths:
713
- match = Util.match_path_to_mapping_key(Path(path), new_map_attr)
714
- if match is None:
715
- raise RuntimeError(f'cannot match compiler to {path} from {map_attr_name}')
709
+ pattern = key.split(':')[0] # ignore the contract part
710
+ if Path(pattern).suffix == "":
711
+ for path in find_matching_contracts(context, pattern):
712
+ file_list[path] = True
713
+ else:
714
+ for path in find_matching_files(context, pattern):
715
+ file_list[path] = True
716
+
717
+ none_keys = [k for k, v in file_list.items() if v is False]
718
+ if none_keys:
719
+ raise Util.CertoraUserInputError(f"The following files are not matched in {map_attr_name}: {none_keys}")
716
720
 
717
721
 
718
722
  def check_parametric_contracts(context: CertoraContext) -> None:
@@ -30,7 +30,7 @@ import urllib3.util
30
30
  from collections import defaultdict
31
31
  from types import SimpleNamespace
32
32
 
33
- from typing import Any, Callable, Dict, List, Optional, Set, Union, Generator, Tuple, Iterable, Sequence, TypeVar, OrderedDict
33
+ from typing import Any, Callable, Dict, List, Optional, Set, Union, Generator, Tuple, Iterable, Sequence, TypeVar
34
34
  from pathlib import Path
35
35
 
36
36
  scripts_dir_path = Path(__file__).parent.parent.resolve() # containing directory
@@ -44,7 +44,6 @@ import tempfile
44
44
  from datetime import datetime
45
45
  from rich.console import Console
46
46
  from rich.text import Text
47
- from wcmatch import glob
48
47
 
49
48
  CONSOLE = Console()
50
49
 
@@ -1172,36 +1171,9 @@ class Singleton(type):
1172
1171
  cls.__instancesinstances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
1173
1172
  return cls.__instancesinstances[cls]
1174
1173
 
1175
-
1176
1174
  class AbstractAndSingleton(Singleton, ABCMeta):
1177
1175
  pass
1178
1176
 
1179
-
1180
- def match_path_to_mapping_key(path: Path, m: OrderedDict[str, str]) -> Optional[str]:
1181
- """
1182
- Matches the path to the first key in the map that matches the path.
1183
- paths may include wildcards
1184
-
1185
- For example, if the ordered dictionary in compiler_map has the mapping:
1186
-
1187
- dir/a.sol -> solc7.1
1188
- dir/*.sol -> solc6.3
1189
- **/*.sol -> 8.10
1190
-
1191
- dir/a.sol will be matched by the first rule
1192
- dir/b.sol by the second rule
1193
- and
1194
- a.sol by the third rule
1195
-
1196
- @param path: the path to match against
1197
- @param m: the map whose keys we're searching
1198
- @return: the value from the map that best matches the path, None if not found.
1199
- """
1200
- for k, v in m.items():
1201
- if glob.globmatch(str(path), k, flags=glob.GLOBSTAR):
1202
- return v
1203
- return None # No match
1204
-
1205
1177
  def find_in(dir_path: Path, file_to_find: Path) -> Optional[Path]:
1206
1178
  """
1207
1179
  Given a directory dir_path and a file we wish to find within that directory,
@@ -686,7 +686,7 @@ def validate_solc_via_ir_map(args: Dict[str, bool]) -> None:
686
686
  if first:
687
687
  validation_logger.warning("all via_ir values are set to True '--solc_via_ir' can be used instead")
688
688
  else:
689
- validation_logger.warning("all via_ir values are set to False, this flag/attribute can be omitted")
689
+ validation_logger.warning("all via_ir values are set to False, this flag/attribute can be omitted")
690
690
 
691
691
  def validate_solc_evm_version_map(args: Dict[str, str]) -> None:
692
692
  if not isinstance(args, dict):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: certora-cli-alpha-master
3
- Version: 20250619.9.58.547847
3
+ Version: 20250619.15.39.58921
4
4
  Summary: Runner for the Certora Prover
5
5
  Home-page: https://pypi.org/project/certora-cli-alpha-master
6
6
  Author: Certora
@@ -38,4 +38,4 @@ Dynamic: requires-dist
38
38
  Dynamic: requires-python
39
39
  Dynamic: summary
40
40
 
41
- Commit e775225. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
41
+ Commit ee27c34. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
@@ -0,0 +1 @@
1
+ {"name": "certora-cli-alpha-master", "tag": "", "branch": "master", "commit": "ee27c34", "timestamp": "20250619.15.39.058921", "version": "20250619.15.39.058921+ee27c34"}
@@ -3,11 +3,11 @@ import setuptools
3
3
 
4
4
  setuptools.setup(
5
5
  name="certora-cli-alpha-master",
6
- version="20250619.9.58.547847",
6
+ version="20250619.15.39.058921",
7
7
  author="Certora",
8
8
  author_email="support@certora.com",
9
9
  description="Runner for the Certora Prover",
10
- long_description="Commit e775225. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.",
10
+ long_description="Commit ee27c34. 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-alpha-master",
13
13
  packages=setuptools.find_packages(),
@@ -1 +0,0 @@
1
- Commit e775225. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
@@ -1 +0,0 @@
1
- {"name": "certora-cli-alpha-master", "tag": "", "branch": "master", "commit": "e775225", "timestamp": "20250619.9.58.547847", "version": "20250619.9.58.547847+e775225"}