certora-cli-beta-mirror 7.31.0__py3-none-any.whl → 8.0.0__py3-none-any.whl

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 (33) hide show
  1. certora_cli/CertoraProver/certoraBuild.py +19 -18
  2. certora_cli/CertoraProver/certoraBuildCacheManager.py +2 -0
  3. certora_cli/CertoraProver/certoraBuildRust.py +31 -20
  4. certora_cli/{Shared/rustProverCommon.py → CertoraProver/certoraBuildSui.py} +24 -18
  5. certora_cli/CertoraProver/certoraCloudIO.py +37 -8
  6. certora_cli/CertoraProver/certoraCollectRunMetadata.py +20 -5
  7. certora_cli/CertoraProver/certoraConfigIO.py +15 -13
  8. certora_cli/CertoraProver/certoraContext.py +33 -8
  9. certora_cli/CertoraProver/certoraContextAttributes.py +113 -195
  10. certora_cli/CertoraProver/certoraContextValidator.py +69 -40
  11. certora_cli/CertoraProver/certoraVerifyGenerator.py +9 -4
  12. certora_cli/CertoraProver/splitRules.py +2 -0
  13. certora_cli/CertoraProver/storageExtension.py +0 -35
  14. certora_cli/Mutate/mutateApp.py +16 -10
  15. certora_cli/Mutate/mutateAttributes.py +11 -0
  16. certora_cli/Shared/certoraAttrUtil.py +11 -5
  17. certora_cli/Shared/certoraUtils.py +29 -28
  18. certora_cli/Shared/certoraValidateFuncs.py +24 -12
  19. certora_cli/Shared/proverCommon.py +4 -2
  20. certora_cli/certoraCVLFormatter.py +76 -0
  21. certora_cli/certoraConcord.py +39 -0
  22. certora_cli/certoraRun.py +55 -95
  23. certora_cli/certoraSolanaProver.py +1 -1
  24. certora_cli/certoraSorobanProver.py +1 -1
  25. {certora_cli_beta_mirror-7.31.0.dist-info → certora_cli_beta_mirror-8.0.0.dist-info}/METADATA +3 -3
  26. {certora_cli_beta_mirror-7.31.0.dist-info → certora_cli_beta_mirror-8.0.0.dist-info}/RECORD +33 -30
  27. {certora_cli_beta_mirror-7.31.0.dist-info → certora_cli_beta_mirror-8.0.0.dist-info}/entry_points.txt +1 -0
  28. certora_jars/ASTExtraction.jar +0 -0
  29. certora_jars/CERTORA-CLI-VERSION-METADATA.json +1 -1
  30. certora_jars/Typechecker.jar +0 -0
  31. {certora_cli_beta_mirror-7.31.0.dist-info → certora_cli_beta_mirror-8.0.0.dist-info}/LICENSE +0 -0
  32. {certora_cli_beta_mirror-7.31.0.dist-info → certora_cli_beta_mirror-8.0.0.dist-info}/WHEEL +0 -0
  33. {certora_cli_beta_mirror-7.31.0.dist-info → certora_cli_beta_mirror-8.0.0.dist-info}/top_level.txt +0 -0
@@ -15,7 +15,6 @@
15
15
 
16
16
  import logging
17
17
 
18
- import json5
19
18
  import sys
20
19
  from pathlib import Path
21
20
  from typing import Type, List, Optional
@@ -30,6 +29,8 @@ from CertoraProver.certoraCollectConfigurationLayout import AttributeJobConfigDa
30
29
 
31
30
  attributes_logger = logging.getLogger("attributes")
32
31
 
32
+ FORBIDDEN_PROVER_ARGS = ['-solanaInlining', '-solanaSummaries']
33
+
33
34
 
34
35
  def validate_prover_args(value: str) -> str:
35
36
 
@@ -50,6 +51,11 @@ def validate_prover_args(value: str) -> str:
50
51
  if not attr.temporary_jar_invocation_allowed:
51
52
  raise Util.CertoraUserInputError(
52
53
  f"Use CLI flag '{flag_name}' instead of 'prover_attrs' with {string} as value")
54
+
55
+ for string in strings:
56
+ if string in FORBIDDEN_PROVER_ARGS:
57
+ raise Util.CertoraUserInputError(
58
+ f"Use a Prover option instead of 'prover_attrs' with {string} as value")
53
59
  return value
54
60
 
55
61
 
@@ -210,87 +216,58 @@ class CommonAttributes(AttrUtil.Attributes):
210
216
  disables_build_cache=False
211
217
  )
212
218
 
213
-
214
- class DeprecatedAttributes(AttrUtil.Attributes):
215
- AUTO_NONDET_DIFFICULT_INTERNAL_FUNCS = AttrUtil.AttributeDefinition(
216
- arg_type=AttrUtil.AttrArgType.BOOLEAN,
217
- deprecation_msg="`auto_nondet_difficult_internal_funcs` is deprecated, use `nondet_difficult_funcs` instead",
218
- argparse_args={
219
- 'action': AttrUtil.STORE_TRUE
220
- },
221
- affects_build_cache_key=False,
222
- disables_build_cache=False
223
- )
224
- AUTO_NONDET_MINIMAL_DIFFICULTY = AttrUtil.AttributeDefinition(
225
- attr_validation_func=Vf.validate_non_negative_integer,
226
- deprecation_msg="`auto_nondet_minimal_difficulty` is deprecated, use `nondet_minimal_difficulty` instead",
219
+ URL_VISIBILITY = AttrUtil.AttributeDefinition(
220
+ attr_validation_func=Vf.validate_url_visibility,
221
+ help_msg="Sets the visibility of the generated report link",
222
+ default_desc="Generate a Private report link",
227
223
  argparse_args={
228
- 'action': AttrUtil.UniqueStore
224
+ 'nargs': AttrUtil.SINGLE_OR_NONE_OCCURRENCES,
225
+ 'action': AttrUtil.UniqueStore,
226
+ 'default': None, # 'default': when --url_visibility was not used
227
+ # when --url_visibility was used without an argument its probably because the link should be public
228
+ 'const': str(Vf.UrlVisibilityOptions.PUBLIC)
229
229
  },
230
230
  affects_build_cache_key=False,
231
- disables_build_cache=False
232
- )
233
- CONTRACT_COMPILER_SKIP_SEVERE_WARNING_AS_ERROR = AttrUtil.AttributeDefinition(
234
- arg_type=AttrUtil.AttrArgType.BOOLEAN,
235
- deprecation_msg="`contract_compiler_skip_severe_warning_as_error` is deprecated. "
236
- "Use `ignore_solidity_warnings` instead",
237
- affects_build_cache_key=True,
238
231
  disables_build_cache=False,
239
- argparse_args={
240
- 'action': AttrUtil.STORE_TRUE
241
- }
242
- )
243
-
244
- SEND_ONLY = AttrUtil.AttributeDefinition(
245
- arg_type=AttrUtil.AttrArgType.BOOLEAN,
246
- deprecation_msg="'send_only' is deprecated and is now the default. In CI, use 'wait_for_results none' instead",
247
- argparse_args={
248
- 'action': AttrUtil.STORE_TRUE
249
- },
250
- affects_build_cache_key=False,
251
- disables_build_cache=False
232
+ # Avoiding presentation of this attribute in Config Tab
233
+ config_data=None
252
234
  )
253
235
 
254
- USE_MEMORY_SAFE_AUTOFINDERS = AttrUtil.AttributeDefinition(
255
- arg_type=AttrUtil.AttrArgType.BOOLEAN,
256
- deprecation_msg="`use_memory_safe_autofinders` is deprecated and is turned on by default. To disable it"
257
- " use `no_memory_safe_autofinders`",
258
- argparse_args={
259
- 'action': AttrUtil.STORE_TRUE
260
- },
261
- affects_build_cache_key=True,
262
- disables_build_cache=False
263
- )
264
236
 
265
- DISABLE_FINDER_FRIENDLY_OPTIMIZER = AttrUtil.AttributeDefinition(
266
- arg_type=AttrUtil.AttrArgType.BOOLEAN,
267
- deprecation_msg="`disable_finder_friendly_optimizer` is deprecated, use `strict_solc_optimizer` instead",
268
- argparse_args={
269
- 'action': AttrUtil.STORE_TRUE
270
- },
271
- affects_build_cache_key=True,
272
- disables_build_cache=False
273
- )
237
+ class DeprecatedAttributes(AttrUtil.Attributes):
238
+ pass
274
239
 
275
- DO_NOT_USE_MEMORY_SAFE_AUTOFINDERS = AttrUtil.AttributeDefinition(
276
- arg_type=AttrUtil.AttrArgType.BOOLEAN,
277
- deprecation_msg="`do_not_use_memory_safe_autofinders` is deprecated, use `no_memory_safe_autofinders` instead",
240
+ PROCESS = AttrUtil.AttributeDefinition(
278
241
  argparse_args={
279
- 'action': AttrUtil.STORE_TRUE
242
+ 'action': AttrUtil.UniqueStore,
280
243
  },
281
- affects_build_cache_key=True,
244
+ deprecation_msg="`process` is deprecated and will be removed in a future release.",
245
+ affects_build_cache_key=False,
282
246
  disables_build_cache=False
283
247
  )
284
248
 
285
- FINDER_FRIENDLY_OPTIMIZER = AttrUtil.AttributeDefinition(
286
- arg_type=AttrUtil.AttrArgType.BOOLEAN,
287
- deprecation_msg="`finder_friendly_optimizer` is deprecated and is turned on by default. To disable it"
288
- " use `strict_solc_optimizer`",
249
+ SOLC_MAP = AttrUtil.AttributeDefinition(
250
+ attr_validation_func=Vf.validate_compiler_map,
251
+ arg_type=AttrUtil.AttrArgType.MAP,
252
+ deprecation_msg="`solc_map` is deprecated, use `compiler_map` instead",
253
+ help_msg='Map contracts to the appropriate Solidity compiler in case not all contract files are compiled '
254
+ 'with the same Solidity compiler version. \n\nCLI Example: '
255
+ '\n --solc_map A=solc8.11,B=solc8.9,C=solc7.5\n\nJSON Example: '
256
+ '\n "solc_map: {"'
257
+ '\n "A": "solc8.11",'
258
+ '\n "B": "solc8.9",'
259
+ '\n "C": "solc7.5"'
260
+ '\n }',
261
+ default_desc="Uses the same Solidity compiler version for all contracts",
289
262
  argparse_args={
290
- 'action': AttrUtil.STORE_TRUE
263
+ 'action': AttrUtil.UniqueStore,
264
+ 'type': lambda value: Vf.parse_ordered_dict('solc_map', value)
291
265
  },
292
266
  affects_build_cache_key=True,
293
- disables_build_cache=False
267
+ disables_build_cache=False,
268
+ config_data=AttributeJobConfigData(
269
+ main_section=MainSection.SOLIDITY_COMPILER
270
+ )
294
271
  )
295
272
 
296
273
 
@@ -393,29 +370,6 @@ class EvmAttributes(AttrUtil.Attributes):
393
370
  )
394
371
  )
395
372
 
396
- SOLC_MAP = AttrUtil.AttributeDefinition(
397
- attr_validation_func=Vf.validate_compiler_map,
398
- arg_type=AttrUtil.AttrArgType.MAP,
399
- help_msg='Map contracts to the appropriate Solidity compiler in case not all contract files are compiled '
400
- 'with the same Solidity compiler version. \n\nCLI Example: '
401
- '\n --solc_map A=solc8.11,B=solc8.9,C=solc7.5\n\nJSON Example: '
402
- '\n "solc_map: {"'
403
- '\n "A": "solc8.11",'
404
- '\n "B": "solc8.9",'
405
- '\n "C": "solc7.5"'
406
- '\n }',
407
- default_desc="Uses the same Solidity compiler version for all contracts",
408
- argparse_args={
409
- 'action': AttrUtil.UniqueStore,
410
- 'type': lambda value: Vf.parse_ordered_dict('solc_map', value)
411
- },
412
- affects_build_cache_key=True,
413
- disables_build_cache=False,
414
- config_data=AttributeJobConfigData(
415
- main_section=MainSection.SOLIDITY_COMPILER
416
- )
417
- )
418
-
419
373
  COMPILER_MAP = AttrUtil.AttributeDefinition(
420
374
  attr_validation_func=Vf.validate_compiler_map,
421
375
  arg_type=AttrUtil.AttrArgType.MAP,
@@ -824,17 +778,6 @@ class EvmAttributes(AttrUtil.Attributes):
824
778
  disables_build_cache=False
825
779
  )
826
780
 
827
- ASSERT_CONTRACTS = AttrUtil.AttributeDefinition(
828
- attr_validation_func=Vf.validate_assert_contracts,
829
- arg_type=AttrUtil.AttrArgType.LIST,
830
- argparse_args={
831
- 'nargs': AttrUtil.ONE_OR_MORE_OCCURRENCES,
832
- 'action': AttrUtil.APPEND,
833
- },
834
- affects_build_cache_key=False,
835
- disables_build_cache=False
836
- )
837
-
838
781
  EQUIVALENCE_CONTRACTS = AttrUtil.AttributeDefinition(
839
782
  attr_validation_func=Vf.validate_equivalence_contracts,
840
783
  arg_type=AttrUtil.AttrArgType.STRING,
@@ -1357,12 +1300,10 @@ class BackendAttributes(AttrUtil.Attributes):
1357
1300
  attr_validation_func=Vf.validate_sanity_value,
1358
1301
  help_msg="Select the type of sanity check that will be performed during execution",
1359
1302
  jar_flag='-ruleSanityChecks',
1360
- default_desc="No sanity checks",
1303
+ default_desc="Basic sanity checks (Vacuity and trivial invariant check)",
1361
1304
  argparse_args={
1362
- 'nargs': AttrUtil.SINGLE_OR_NONE_OCCURRENCES,
1363
1305
  'action': AttrUtil.UniqueStore,
1364
1306
  'default': None, # 'default': when no --rule_sanity given
1365
- 'const': Vf.RuleSanityValue.BASIC.name.lower() # 'default': when empty --rule_sanity is given
1366
1307
  },
1367
1308
  affects_build_cache_key=False,
1368
1309
  disables_build_cache=False
@@ -1474,17 +1415,6 @@ class BackendAttributes(AttrUtil.Attributes):
1474
1415
  disables_build_cache=False
1475
1416
  )
1476
1417
 
1477
- PROCESS = AttrUtil.AttributeDefinition(
1478
- argparse_args={
1479
- 'action': AttrUtil.UniqueStore,
1480
- 'default': 'emv'
1481
- },
1482
- affects_build_cache_key=False,
1483
- disables_build_cache=False,
1484
- # Avoiding presentation of this attribute in Config Tab
1485
- config_data=None
1486
- )
1487
-
1488
1418
  PROVER_ARGS = AttrUtil.AttributeDefinition(
1489
1419
  arg_type=AttrUtil.AttrArgType.LIST,
1490
1420
  attr_validation_func=validate_prover_args,
@@ -1663,16 +1593,6 @@ class BackendAttributes(AttrUtil.Attributes):
1663
1593
  disables_build_cache=False
1664
1594
  )
1665
1595
 
1666
- ALLOW_SOLIDITY_CALLS_IN_QUANTIFIERS = AttrUtil.AttributeDefinition(
1667
- arg_type=AttrUtil.AttrArgType.BOOLEAN,
1668
- jar_flag='-allowSolidityQuantifierCalls',
1669
- argparse_args={
1670
- 'action': AttrUtil.STORE_TRUE
1671
- },
1672
- affects_build_cache_key=False,
1673
- disables_build_cache=False
1674
- )
1675
-
1676
1596
 
1677
1597
  class RustAttributes(AttrUtil.Attributes):
1678
1598
 
@@ -1708,10 +1628,11 @@ class RustAttributes(AttrUtil.Attributes):
1708
1628
  disables_build_cache=False
1709
1629
  )
1710
1630
 
1631
+
1711
1632
  class EvmProverAttributes(CommonAttributes, DeprecatedAttributes, EvmAttributes, InternalUseAttributes,
1712
1633
  BackendAttributes):
1713
1634
  FILES = AttrUtil.AttributeDefinition(
1714
- attr_validation_func=Vf.validate_input_file,
1635
+ attr_validation_func=Vf.validate_evm_input_file,
1715
1636
  arg_type=AttrUtil.AttrArgType.LIST,
1716
1637
  help_msg="Solidity or Vyper contract files for analysis or a conf file",
1717
1638
  default_desc="",
@@ -1726,22 +1647,46 @@ class EvmProverAttributes(CommonAttributes, DeprecatedAttributes, EvmAttributes,
1726
1647
  )
1727
1648
 
1728
1649
 
1650
+ class ConcordAttributes(EvmProverAttributes):
1651
+ CHECK_METHOD = AttrUtil.AttributeDefinition(
1652
+ attr_validation_func=Vf.validate_check_method_flag,
1653
+ help_msg="the method to be checked by Concord equivalent checker",
1654
+ default_desc="Mandatory for Concord",
1655
+ jar_flag='-method',
1656
+ argparse_args={
1657
+ 'action': AttrUtil.UniqueStore
1658
+ },
1659
+ affects_build_cache_key=False,
1660
+ disables_build_cache=False
1661
+ )
1662
+
1663
+ @classmethod
1664
+ def unsupported_attributes(cls) -> List[AttrUtil.AttributeDefinition]:
1665
+ return [cls.VERIFY, cls.MSG, cls.PROTOCOL_NAME, cls.PROTOCOL_AUTHOR, cls.RULE, cls.EXCLUDE_RULE,
1666
+ cls.SPLIT_RULES, cls.EXCLUDE_METHOD, cls.PARAMETRIC_CONTRACTS, cls.COVERAGE_INFO, cls.FOUNDRY,
1667
+ cls.INDEPENDENT_SATISFY, cls.MULTI_ASSERT_CHECK, cls.MULTI_EXAMPLE, cls.PROJECT_SANITY,
1668
+ cls.RULE_SANITY, cls.ADDRESS, cls.CONTRACT_EXTENSIONS, cls.CONTRACT_RECURSION_LIMIT, cls.LINK,
1669
+ cls.OPTIMISTIC_CONTRACT_RECURSION, cls.STRUCT_LINK, cls.DYNAMIC_BOUND, cls.DYNAMIC_DISPATCH,
1670
+ cls.PROTOTYPE, cls.METHOD]
1671
+
1672
+
1729
1673
  class RangerAttributes(EvmProverAttributes):
1730
1674
  @classmethod
1731
- def ranger_unsupported_attributes(cls) -> List[AttrUtil.AttributeDefinition]:
1675
+ def unsupported_attributes(cls) -> List[AttrUtil.AttributeDefinition]:
1732
1676
  return [cls.PROJECT_SANITY, cls.RULE_SANITY, cls.COVERAGE_INFO, cls.FOUNDRY, cls.INDEPENDENT_SATISFY,
1733
1677
  cls.MULTI_ASSERT_CHECK, cls.MULTI_EXAMPLE, cls.VYPER]
1734
1678
 
1735
1679
  @classmethod
1736
- def ranger_true_by_default_attributes(cls) -> List[AttrUtil.AttributeDefinition]:
1680
+ def true_by_default_attributes(cls) -> List[AttrUtil.AttributeDefinition]:
1737
1681
  return [cls.OPTIMISTIC_LOOP, cls.OPTIMISTIC_FALLBACK, cls.AUTO_DISPATCHER, cls.OPTIMISTIC_HASHING]
1738
1682
 
1739
1683
  @classmethod
1740
1684
  def hide_attributes(cls) -> List[str]:
1741
1685
  # do not show these attributes in the help message
1742
- combined_list = cls.ranger_unsupported_attributes() + cls.ranger_true_by_default_attributes()
1686
+ combined_list = cls.unsupported_attributes() + cls.true_by_default_attributes()
1743
1687
  return [attr.name for attr in combined_list] + [cls.LOOP_ITER.name, cls.RANGER_FAILURE_LIMIT.name]
1744
1688
 
1689
+
1745
1690
  class SorobanProverAttributes(CommonAttributes, InternalUseAttributes, BackendAttributes, RustAttributes):
1746
1691
  FILES = AttrUtil.AttributeDefinition(
1747
1692
  attr_validation_func=Vf.validate_soroban_extension,
@@ -1759,6 +1704,36 @@ class SorobanProverAttributes(CommonAttributes, InternalUseAttributes, BackendAt
1759
1704
  )
1760
1705
 
1761
1706
 
1707
+ class SuiProverAttributes(CommonAttributes, InternalUseAttributes, BackendAttributes):
1708
+ FILES = AttrUtil.AttributeDefinition(
1709
+ attr_validation_func=Vf.validate_dir,
1710
+ arg_type=AttrUtil.AttrArgType.LIST,
1711
+ argparse_args={
1712
+ 'nargs': AttrUtil.MULTIPLE_OCCURRENCES
1713
+ },
1714
+ affects_build_cache_key=True,
1715
+ disables_build_cache=False,
1716
+ config_data=AttributeJobConfigData(
1717
+ main_section=MainSection.NEW_SECTION
1718
+ )
1719
+ )
1720
+
1721
+ MOVE_PATH = AttrUtil.AttributeDefinition(
1722
+ attr_validation_func=Vf.validate_dir,
1723
+ arg_type=AttrUtil.AttrArgType.STRING,
1724
+ help_msg="path to a directory which includes all binary .mv files for the Prover",
1725
+ default_desc="",
1726
+ argparse_args={
1727
+ 'action': AttrUtil.UniqueStore
1728
+ },
1729
+ affects_build_cache_key=True,
1730
+ disables_build_cache=False,
1731
+ config_data=AttributeJobConfigData(
1732
+ main_section=MainSection.NEW_SECTION
1733
+ )
1734
+ )
1735
+
1736
+
1762
1737
  class SolanaProverAttributes(CommonAttributes, InternalUseAttributes, BackendAttributes, RustAttributes):
1763
1738
  FILES = AttrUtil.AttributeDefinition(
1764
1739
  attr_validation_func=Vf.validate_solana_extension,
@@ -1817,70 +1792,6 @@ def set_attribute_class(cls: Type[AttrUtil.Attributes]) -> None:
1817
1792
  cls.set_attribute_list()
1818
1793
 
1819
1794
 
1820
- def detect_application_class(args: List[str]) -> Type[AttrUtil.Attributes]:
1821
-
1822
- attributes_logger.debug("calling detect_application_class")
1823
-
1824
- def application_by_suffix(file: str) -> Type[AttrUtil.Attributes]:
1825
- if file.endswith(Util.EVM_EXTENSIONS):
1826
- return EvmProverAttributes
1827
- elif file.endswith(Util.SOROBAN_EXEC_EXTENSION):
1828
- return SorobanProverAttributes
1829
- elif file.endswith(Util.SOLANA_EXEC_EXTENSION):
1830
- return SolanaProverAttributes
1831
- elif file.endswith('.conf'):
1832
- raise Util.CertoraUserInputError(f"Cannot use conf files inside a conf file: {file}")
1833
- else:
1834
- raise Util.CertoraUserInputError(f"Unsupported file type: {file}")
1835
-
1836
- cli_files = []
1837
- cli_conf_files = []
1838
- files = []
1839
- build_script = None
1840
- for arg in args:
1841
- if arg.startswith('-'):
1842
- break # Stop processing when a flag is detected
1843
- cli_files.append(arg)
1844
- if arg.endswith('.conf'):
1845
- cli_conf_files.append(arg)
1846
-
1847
- if len(cli_conf_files) == 1:
1848
- conf_file_path = Path(cli_conf_files[0])
1849
-
1850
- with conf_file_path.open() as conf_file:
1851
- configuration = json5.load(conf_file, allow_duplicate_keys=False)
1852
- files = configuration.get('files', [])
1853
- build_script = configuration.get('build_script')
1854
-
1855
- if build_script:
1856
- return SorobanProverAttributes
1857
-
1858
- if len(cli_conf_files) == 0:
1859
- files = cli_files
1860
-
1861
- if len(cli_conf_files) > 1:
1862
- raise Util.CertoraUserInputError(f"multiple conf files: {cli_conf_files})")
1863
-
1864
- candidate = None
1865
-
1866
- for file in files:
1867
- file = file.split(':')[0] # remove contract part if exist
1868
- app = application_by_suffix(file)
1869
- if not candidate:
1870
- candidate = app
1871
- elif candidate == app:
1872
- continue
1873
- else:
1874
- raise Util.CertoraUserInputError(f"Illegal files combination: {files})")
1875
-
1876
- if candidate:
1877
- attributes_logger.debug(f"detect_application_class returns {candidate}")
1878
- return candidate
1879
- else:
1880
- attributes_logger.debug(f"detect_application_class returns {EvmProverAttributes}")
1881
- return EvmProverAttributes
1882
-
1883
-
1884
1795
  def is_solana_app() -> bool:
1885
1796
  return get_attribute_class() == SolanaProverAttributes
1886
1797
 
@@ -1892,12 +1803,19 @@ def is_soroban_app() -> bool:
1892
1803
  def is_rust_app() -> bool:
1893
1804
  return is_soroban_app() or is_solana_app()
1894
1805
 
1895
- # Ranger will also return true for this function
1806
+
1807
+ # Ranger and Concord will also return true for this function
1896
1808
  def is_evm_app() -> bool:
1897
1809
  return issubclass(get_attribute_class(), EvmProverAttributes)
1898
1810
 
1811
+
1899
1812
  def is_ranger_app() -> bool:
1900
1813
  return get_attribute_class() == RangerAttributes
1901
1814
 
1902
- def is_sophy_app() -> bool:
1903
- return False # wait for the tool to be added
1815
+
1816
+ def is_concord_app() -> bool:
1817
+ return get_attribute_class() == ConcordAttributes
1818
+
1819
+
1820
+ def is_sui_app() -> bool:
1821
+ return get_attribute_class() == SuiProverAttributes
@@ -13,6 +13,7 @@
13
13
  # You should have received a copy of the GNU General Public License
14
14
  # along with this program. If not, see <https://www.gnu.org/licenses/>.
15
15
 
16
+
16
17
  import logging
17
18
  import os
18
19
  import re
@@ -45,10 +46,28 @@ class CertoraContextValidator:
45
46
  def __init__(self, context: CertoraContext):
46
47
  self.context = context
47
48
 
49
+ def handle_concord_attrs(self) -> None:
50
+ if Attrs.is_concord_app():
51
+ for attr in (Attrs.ConcordAttributes.unsupported_attributes()):
52
+ attr_name = attr.get_conf_key()
53
+ if getattr(self.context, attr_name):
54
+ if attr.arg_type == AttrUtil.AttrArgType.BOOLEAN:
55
+ setattr(self.context, attr_name, False)
56
+ else:
57
+ setattr(self.context, attr_name, None)
58
+ raise Util.CertoraUserInputError(f"Concord does not support {attr_name}")
59
+ if not self.context.check_method:
60
+ raise Util.CertoraUserInputError("'check_method' attribute/flag is mandatory when running Concord")
61
+ contracts = getattr(self.context, 'contracts', None)
62
+ if not contracts:
63
+ raise Util.CertoraUserInputError("No contracts were specified for Concord")
64
+ if len(contracts) != 2:
65
+ raise Util.CertoraUserInputError(f"expecting 2 contracts for Concord, got {len(contracts)}: {contracts}")
66
+
48
67
  def handle_ranger_attrs(self) -> None:
49
68
  # unset unsupported attributes
50
69
  if Attrs.is_ranger_app():
51
- for attr in Attrs.RangerAttributes.ranger_unsupported_attributes():
70
+ for attr in Attrs.RangerAttributes.unsupported_attributes():
52
71
  attr_name = attr.get_conf_key()
53
72
  if getattr(self.context, attr_name):
54
73
  if attr.arg_type == AttrUtil.AttrArgType.BOOLEAN:
@@ -66,7 +85,7 @@ class CertoraContextValidator:
66
85
  f"ignoring the set value of {self.context.loop_iter}")
67
86
  self.context.loop_iter = self.context.loop_iter or Util.DEFAULT_RANGER_LOOP_ITER
68
87
 
69
- for attr in Attrs.RangerAttributes.ranger_true_by_default_attributes():
88
+ for attr in Attrs.RangerAttributes.true_by_default_attributes():
70
89
  attr_name = attr.get_conf_key()
71
90
  setattr(self.context, attr_name, True)
72
91
 
@@ -164,6 +183,12 @@ class CertoraContextValidator:
164
183
  if len(context.files) > 1:
165
184
  raise Util.CertoraUserInputError("Rust projects must specify exactly one executable in 'files'.")
166
185
 
186
+ if context.url_visibility and context.local:
187
+ validation_logger.info("'url_visibility' has no effect in local tool runs")
188
+ set_attr_default(context, attr_name=Attrs.CommonAttributes.URL_VISIBILITY.name.lower(),
189
+ ci_value=str(Vf.UrlVisibilityOptions.PUBLIC),
190
+ default_value=str(Vf.UrlVisibilityOptions.PRIVATE))
191
+
167
192
  def check_args_post_argparse(self) -> None:
168
193
  """
169
194
  Performs checks over the arguments after basic argparse parsing
@@ -218,10 +243,18 @@ class CertoraContextValidator:
218
243
  if context.compilation_steps_only and context.build_only:
219
244
  raise Util.CertoraUserInputError("cannot use both 'compilation_steps_only' and 'build_only'")
220
245
 
221
- set_wait_for_results_default(context)
246
+ set_attr_default(context, attr_name=Attrs.CommonAttributes.WAIT_FOR_RESULTS.name.lower(),
247
+ ci_value=str(Vf.WaitForResultOptions.ALL),
248
+ default_value=str(Vf.WaitForResultOptions.NONE))
222
249
  if context.wait_for_results and context.wait_for_results != str(Vf.WaitForResultOptions.NONE) and context.local:
223
250
  validation_logger.warning("'wait_for_results' has no effect in local tool runs")
224
251
 
252
+ if context.url_visibility and context.local:
253
+ validation_logger.info("'url_visibility' has no effect in local tool runs")
254
+ set_attr_default(context, attr_name=Attrs.CommonAttributes.URL_VISIBILITY.name.lower(),
255
+ ci_value=str(Vf.UrlVisibilityOptions.PUBLIC),
256
+ default_value=str(Vf.UrlVisibilityOptions.PRIVATE))
257
+
225
258
  # packages must be in a normal form (no unneeded . or ..)
226
259
  if context.packages:
227
260
  for idx, el in enumerate(context.packages):
@@ -427,14 +460,6 @@ def check_contract_name_arg_inputs(context: CertoraContext) -> None:
427
460
  check_conflicting_link_args(context)
428
461
 
429
462
  context.verified_contract_files = []
430
- if context.assert_contracts is not None:
431
- for assert_arg in context.assert_contracts:
432
- contract = Util.get_trivial_contract_name(assert_arg)
433
- if contract not in contract_names:
434
- __suggest_contract_name(f"'assert' argument, {contract}, doesn't match any contract name", contract,
435
- contract_names, contract_to_file)
436
- else:
437
- context.verified_contract_files.append(contract_to_file[contract])
438
463
 
439
464
  context.spec_file = None
440
465
 
@@ -580,31 +605,32 @@ def check_mode_of_operation(context: CertoraContext) -> None:
580
605
 
581
606
  @param context: A namespace including all CLI arguments provided
582
607
  @raise an CertoraUserInputError when:
583
- 1. .conf|.tac|.json file is used with --assert_contracts flags
584
- 2. when both --assert_contracts and --verify flags were given
585
- 3. when the file is not .tac|.conf|.json and neither --assert_contracts nor --verify were used
586
- 4. If either --bytecode_jsons or --bytecode_spec was used without the other.
608
+ 1. when both --equivalence_contracts and --verify flags were given
609
+ 2. when the file is not .tac|.conf|.json and neither --equivalence_contracts nor --verify were used
610
+ 3. If either --bytecode_jsons or --bytecode_spec was used without the other.
587
611
  """
588
612
  context.is_verify = context.verify is not None and len(context.verify) > 0
589
- context.is_assert = context.assert_contracts is not None and len(context.assert_contracts) > 0
590
613
  context.is_bytecode = context.bytecode_jsons is not None and len(context.bytecode_jsons) > 0
591
- context.is_equivalence = context.equivalence_contracts is not None
614
+ context.is_equivalence = context.equivalence_contracts is not None or context.is_concord_app
592
615
 
593
- if (context.project_sanity or context.foundry) and (context.is_verify or context.is_assert or context.is_bytecode or context.is_equivalence):
594
- raise Util.CertoraUserInputError("The 'project_sanity' and 'foundry' options cannot coexist with the 'verify', 'assert_contract' or 'bytecode_jsons' options")
616
+ if (context.project_sanity or context.foundry) and \
617
+ (context.is_verify or context.is_bytecode or context.is_equivalence):
618
+ raise Util.CertoraUserInputError("The 'project_sanity' and 'foundry' options cannot coexist with the 'verify', "
619
+ "'assert_contract' or 'bytecode_jsons' options")
595
620
 
596
621
  if context.project_sanity and context.foundry:
597
622
  raise Util.CertoraUserInputError("The 'project_sanity' and 'foundry' options cannot coexist")
598
623
 
599
- if len(list(filter(None, [context.is_verify, context.is_assert, context.is_equivalence]))) > 1:
600
- raise Util.CertoraUserInputError("only one option of 'assert_contracts', 'verify', 'equivalence' can be used")
624
+ if len(list(filter(None, [context.is_verify, context.is_equivalence]))) > 1:
625
+ raise Util.CertoraUserInputError("only one option of 'verify', 'equivalence' can be used")
601
626
 
602
627
  has_bytecode_spec = context.bytecode_spec is not None
603
628
  if has_bytecode_spec != context.is_bytecode:
604
629
  raise Util.CertoraUserInputError("Must use 'bytecode' together with 'bytecode_spec'")
605
630
 
606
631
  if not context.files and not any((context.is_bytecode, context.project_sanity, context.foundry)):
607
- raise Util.CertoraUserInputError("Should always provide input files, unless 'bytecode_jsons' or 'project_sanity' or 'foundry' are used")
632
+ raise Util.CertoraUserInputError("Should always provide input files, unless 'bytecode_jsons' or "
633
+ "'project_sanity' or 'foundry' are used")
608
634
 
609
635
  if context.is_bytecode and context.files:
610
636
  raise Util.CertoraUserInputError("Cannot use 'bytecode_jsons' with other files")
@@ -618,7 +644,8 @@ def check_mode_of_operation(context: CertoraContext) -> None:
618
644
  if not context.files:
619
645
  file_contract_pairs = _get_project_file_contract_pairs(context)
620
646
  main_contract = file_contract_pairs[0][1] # any contract
621
- context.files = [f"{file}:{contract}" if file.stem != contract else str(file) for file, contract in file_contract_pairs]
647
+ context.files = \
648
+ [f"{file}:{contract}" if file.stem != contract else str(file) for file, contract in file_contract_pairs]
622
649
  else:
623
650
  first = context.files[0]
624
651
  if ':' in first:
@@ -630,12 +657,14 @@ def check_mode_of_operation(context: CertoraContext) -> None:
630
657
 
631
658
  context.verify = f"{main_contract}:{spec_file_name}"
632
659
  context.is_verify = True
633
- # In this mode we want to make life easy for the user, so use the auto-dispatcher mode to avoid many unresolved calls
660
+ # In this mode we want to make life easy for the user,
661
+ # so use the auto-dispatcher mode to avoid many unresolved calls
634
662
  context.auto_dispatcher = True
635
663
 
636
664
  if context.foundry:
637
665
  file_contract_pairs = _get_project_file_contract_pairs(context)
638
- test_pairs = [(file, contract) for file, contract in file_contract_pairs if file.stem.endswith(".t") and 'lib' not in file.parents]
666
+ test_pairs = [(file, contract) for file, contract in file_contract_pairs
667
+ if file.stem.endswith(".t") and 'lib' not in file.parents]
639
668
  context.files = [f"{file}:{contract}" for file, contract in test_pairs]
640
669
  main_contract = test_pairs[0][1] # any contract
641
670
  spec_file_name = _generate_temp_spec(context, "use builtin rule verifyFoundryFuzzTestsNoRevert;\n")
@@ -643,7 +672,8 @@ def check_mode_of_operation(context: CertoraContext) -> None:
643
672
  context.foundry_tests_mode = True
644
673
  context.verify = f"{main_contract}:{spec_file_name}"
645
674
  context.is_verify = True
646
- # In this mode we want to make life easy for the user, so use the auto-dispatcher mode to avoid many unresolved calls
675
+ # In this mode we want to make life easy for the user,
676
+ # so use the auto-dispatcher mode to avoid many unresolved calls
647
677
  context.auto_dispatcher = True
648
678
 
649
679
  if context.files:
@@ -656,16 +686,14 @@ def check_mode_of_operation(context: CertoraContext) -> None:
656
686
  for input_file in context.files:
657
687
  special_file_type = next((suffix for suffix in special_file_suffixes if input_file.endswith(suffix)), None)
658
688
 
659
- if special_file_type:
660
- if len(context.files) > 1:
661
- raise Util.CertoraUserInputError(
662
- f"No other files are allowed with a file of type {special_file_type}")
663
- if context.is_assert:
664
- raise Util.CertoraUserInputError(
665
- f"Option 'assert_contracts' cannot be used with a {special_file_type} file {input_file}")
689
+ if special_file_type and len(context.files) > 1:
690
+ raise Util.CertoraUserInputError(
691
+ f"No other files are allowed with a file of type {special_file_type}")
666
692
 
667
- if not any([context.is_assert, context.is_verify, context.is_bytecode, context.equivalence_contracts,
668
- special_file_type]) and not context.build_only:
693
+ if (
694
+ not Attrs.is_concord_app() and
695
+ not any([context.is_verify, context.is_bytecode,
696
+ context.equivalence_contracts, special_file_type]) and not context.build_only):
669
697
  raise Util.CertoraUserInputError("You must use 'verify' when running the Certora Prover")
670
698
 
671
699
  def find_matching_contracts(context: CertoraContext, pattern: str) -> List[str]:
@@ -883,16 +911,17 @@ def check_files_input(file_list: List[str]) -> None:
883
911
  if file.endswith(Util.SOROBAN_EXEC_EXTENSION):
884
912
  raise Util.CertoraUserInputError(f'The Soroban file {file} cannot be accompanied with other files')
885
913
 
886
- def set_wait_for_results_default(context: CertoraContext) -> None:
887
- if context.wait_for_results is None:
914
+
915
+ def set_attr_default(context: CertoraContext, attr_name: str, ci_value: str, default_value: str) -> None:
916
+ if getattr(context, attr_name, None) is None:
888
917
  if Util.is_ci_or_git_action():
889
- context.wait_for_results = str(Vf.WaitForResultOptions.ALL)
918
+ setattr(context, attr_name, ci_value)
890
919
  else:
891
- context.wait_for_results = str(Vf.WaitForResultOptions.NONE)
920
+ setattr(context, attr_name, default_value)
892
921
 
893
922
 
894
923
  def mode_has_spec_file(context: CertoraContext) -> bool:
895
- return not context.is_assert and not context.is_tac and not context.is_equivalence
924
+ return not (context.is_tac or context.is_equivalence)
896
925
 
897
926
 
898
927
  def to_relative_paths(paths: Union[str, List[str]]) -> Union[str, List[str]]: