certora-cli-beta-mirror 8.4.3__tar.gz → 8.5.0__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 (89) hide show
  1. {certora_cli_beta_mirror-8.4.3/certora_cli_beta_mirror.egg-info → certora_cli_beta_mirror-8.5.0}/PKG-INFO +2 -2
  2. certora_cli_beta_mirror-8.5.0/README.md +1 -0
  3. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/Compiler/CompilerCollectorVy.py +3 -3
  4. certora_cli_beta_mirror-8.5.0/certora_cli/CertoraProver/castingInstrumenter.py +192 -0
  5. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraBuild.py +87 -7
  6. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraBuildDataClasses.py +1 -0
  7. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraCompilerParameters.py +11 -0
  8. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraContextAttributes.py +39 -0
  9. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraContextValidator.py +0 -2
  10. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraContractFuncs.py +28 -1
  11. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/Shared/certoraUtils.py +2 -0
  12. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/Shared/certoraValidateFuncs.py +14 -8
  13. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0/certora_cli_beta_mirror.egg-info}/PKG-INFO +2 -2
  14. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli_beta_mirror.egg-info/SOURCES.txt +1 -0
  15. certora_cli_beta_mirror-8.4.3/certora_jars/Typechecker.jar → certora_cli_beta_mirror-8.5.0/certora_jars/ASTExtraction.jar +0 -0
  16. certora_cli_beta_mirror-8.5.0/certora_jars/CERTORA-CLI-VERSION-METADATA.json +1 -0
  17. certora_cli_beta_mirror-8.4.3/certora_jars/ASTExtraction.jar → certora_cli_beta_mirror-8.5.0/certora_jars/Typechecker.jar +0 -0
  18. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/setup.py +2 -2
  19. certora_cli_beta_mirror-8.4.3/README.md +0 -1
  20. certora_cli_beta_mirror-8.4.3/certora_jars/CERTORA-CLI-VERSION-METADATA.json +0 -1
  21. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/LICENSE +0 -0
  22. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/MANIFEST.in +0 -0
  23. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_bins/__init__.py +0 -0
  24. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/Compiler/CompilerCollector.py +0 -0
  25. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/Compiler/CompilerCollectorFactory.py +0 -0
  26. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/Compiler/CompilerCollectorSol.py +0 -0
  27. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/Compiler/CompilerCollectorSolBased.py +0 -0
  28. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/Compiler/CompilerCollectorYul.py +0 -0
  29. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/Compiler/__init__.py +0 -0
  30. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/__init__.py +0 -0
  31. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraApp.py +0 -0
  32. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraBuildCacheManager.py +0 -0
  33. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraBuildRust.py +0 -0
  34. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraBuildSui.py +0 -0
  35. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraCloudIO.py +0 -0
  36. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraCollectConfigurationLayout.py +0 -0
  37. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraCollectRunMetadata.py +0 -0
  38. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraConfigIO.py +0 -0
  39. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraContext.py +0 -0
  40. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraContextClass.py +0 -0
  41. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraExtensionInfo.py +0 -0
  42. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraJobList.py +0 -0
  43. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraMiniSpecParser.py +0 -0
  44. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraNodeFilters.py +0 -0
  45. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraParseBuildScript.py +0 -0
  46. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraProjectScanner.py +0 -0
  47. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraSourceFinders.py +0 -0
  48. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraType.py +0 -0
  49. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/certoraVerifyGenerator.py +0 -0
  50. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/erc7201.py +0 -0
  51. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/splitRules.py +0 -0
  52. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/CertoraProver/storageExtension.py +0 -0
  53. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/EquivalenceCheck/Eq_default.conf +0 -0
  54. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/EquivalenceCheck/Eq_mc_no_out_template.spec +0 -0
  55. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/EquivalenceCheck/Eq_mc_template.spec +0 -0
  56. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/EquivalenceCheck/Eq_sanity.conf +0 -0
  57. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/EquivalenceCheck/Eq_template.spec +0 -0
  58. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/EquivalenceCheck/__init__.py +0 -0
  59. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/EquivalenceCheck/equivCheck.py +0 -0
  60. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/EquivalenceCheck/sanity.spec +0 -0
  61. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/Mutate/__init__.py +0 -0
  62. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/Mutate/mutateApp.py +0 -0
  63. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/Mutate/mutateAttributes.py +0 -0
  64. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/Mutate/mutateConstants.py +0 -0
  65. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/Mutate/mutateUtil.py +0 -0
  66. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/Mutate/mutateValidate.py +0 -0
  67. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/Shared/ExpectedComparator.py +0 -0
  68. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/Shared/__init__.py +0 -0
  69. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/Shared/certoraAttrUtil.py +0 -0
  70. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/Shared/certoraLogging.py +0 -0
  71. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/Shared/proverCommon.py +0 -0
  72. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/__init__.py +0 -0
  73. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/certoraCVLFormatter.py +0 -0
  74. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/certoraConcord.py +0 -0
  75. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/certoraEVMProver.py +0 -0
  76. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/certoraEqCheck.py +0 -0
  77. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/certoraMutate.py +0 -0
  78. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/certoraRanger.py +0 -0
  79. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/certoraRun.py +0 -0
  80. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/certoraSolanaProver.py +0 -0
  81. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/certoraSorobanProver.py +0 -0
  82. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/certoraSuiProver.py +0 -0
  83. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli/rustMutator.py +0 -0
  84. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli_beta_mirror.egg-info/dependency_links.txt +0 -0
  85. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli_beta_mirror.egg-info/entry_points.txt +0 -0
  86. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli_beta_mirror.egg-info/requires.txt +0 -0
  87. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_cli_beta_mirror.egg-info/top_level.txt +0 -0
  88. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/certora_jars/__init__.py +0 -0
  89. {certora_cli_beta_mirror-8.4.3 → certora_cli_beta_mirror-8.5.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: certora-cli-beta-mirror
3
- Version: 8.4.3
3
+ Version: 8.5.0
4
4
  Summary: Runner for the Certora Prover
5
5
  Home-page: https://pypi.org/project/certora-cli-beta-mirror
6
6
  Author: Certora
@@ -39,4 +39,4 @@ Dynamic: requires-dist
39
39
  Dynamic: requires-python
40
40
  Dynamic: summary
41
41
 
42
- Commit 0d90215. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
42
+ Commit d143e0e. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
@@ -0,0 +1 @@
1
+ Commit d143e0e. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
@@ -659,7 +659,7 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
659
659
 
660
660
  @staticmethod
661
661
  def extract_type_from_enum_def(ast_enumdef_node: Dict[str, Any]) -> VyperType:
662
- fields = [n['target']['id'] for n in ast_enumdef_node['body']]
662
+ fields = [n['target']['id'] if "target" in n else n["value"]["id"] for n in ast_enumdef_node['body']]
663
663
  return CompilerLangVy.VyperTypeEnum(ast_enumdef_node['name'], fields)
664
664
 
665
665
  @staticmethod
@@ -1273,7 +1273,7 @@ class Collector:
1273
1273
  self._collect_const(v)
1274
1274
 
1275
1275
  # Extract and resolve types
1276
- type_asts = {'EnumDef', 'StructDef', 'InterfaceDef', 'Import', 'Import', 'ImportFrom'}
1276
+ type_asts = {'EnumDef', 'StructDef', 'InterfaceDef', 'Import', 'Import', 'ImportFrom', 'FlagDef'}
1277
1277
  types = [e for e in module_node['body'] if e['ast_type'] in type_asts]
1278
1278
  for t in types:
1279
1279
  self._collect_type_decl(t)
@@ -1300,7 +1300,7 @@ class Collector:
1300
1300
 
1301
1301
  def _collect_type_decl(self, type_decl_node: Dict[str, Any]) -> None:
1302
1302
  """Update self.types to add type definition from `type_decl_node`. Expects self.consts to be initialized"""
1303
- if type_decl_node['ast_type'] == 'EnumDef':
1303
+ if type_decl_node['ast_type'] in ('EnumDef', 'FlagDef'):
1304
1304
  vy_type = CompilerLangVy.extract_type_from_enum_def(type_decl_node)
1305
1305
  elif type_decl_node['ast_type'] == 'StructDef':
1306
1306
  vy_type = CompilerLangVy.extract_type_from_struct_def(type_decl_node, self.consts)
@@ -0,0 +1,192 @@
1
+ # The Certora Prover
2
+ # Copyright (C) 2025 Certora Ltd.
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, version 3 of the License.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
15
+
16
+
17
+ from dataclasses import dataclass
18
+ from typing import Dict, Any, Optional, Generator
19
+
20
+ from CertoraProver.Compiler.CompilerCollectorSol import CompilerCollectorSol
21
+ from CertoraProver.certoraBuildDataClasses import SDC, Instrumentation, Replace
22
+ from Shared import certoraUtils as Util
23
+
24
+
25
+ @dataclass
26
+ class IntType:
27
+ is_signed: bool
28
+ bitwidth: int
29
+
30
+ def encode(self) -> Optional[int]:
31
+ """
32
+ Encodes into a 9 bit number: lowest bit is on if [IntType] is true, and upper 8 bits are the width.
33
+ returns none if width is out of bounds.
34
+ """
35
+ if self.bitwidth <= 0 or self.bitwidth > 256:
36
+ return None
37
+ return self.bitwidth * 2 + int(self.is_signed)
38
+
39
+
40
+ def parse_int_type(type_string: str) -> Optional[IntType]:
41
+ """
42
+ Parse an integer type string of the form 'int<bitwidth>' or 'uint<bitwidth>'.
43
+ Returns IntType or None if the string doesn't match the pattern.
44
+ """
45
+ if type_string == "int":
46
+ return IntType(True, 256)
47
+ elif type_string == "uint":
48
+ return IntType(False, 256)
49
+ elif type_string.startswith("int"):
50
+ is_signed = True
51
+ bitwidth_str = type_string[3:]
52
+ elif type_string.startswith("uint"):
53
+ is_signed = False
54
+ bitwidth_str = type_string[4:]
55
+ else:
56
+ return None
57
+
58
+ try:
59
+ bitwidth = int(bitwidth_str)
60
+ return IntType(is_signed, bitwidth)
61
+ except ValueError:
62
+ return None
63
+
64
+
65
+ def is_int_type(type_string: str) -> bool:
66
+ return parse_int_type(type_string) is not None
67
+
68
+
69
+ def encode_type(type_string: str) -> int:
70
+ int_type = parse_int_type(type_string)
71
+ if int_type is None:
72
+ raise Exception(f"Invalid type string: {type_string}")
73
+ encoded = int_type.encode()
74
+ if encoded is None:
75
+ raise Exception(f"Invalid type string: {type_string}")
76
+ return encoded
77
+
78
+
79
+ @dataclass
80
+ class CastInfo:
81
+ arg_type_str: str
82
+ res_type_str: str
83
+ expr_id: int
84
+
85
+
86
+ def find_casts(ast: Dict[int, Any]) -> list[CastInfo]:
87
+ """
88
+ Search all nodes that are in functions for kind "typeConversion" with one argument.
89
+ Returns a list of CastInfo instances.
90
+ """
91
+ conversions = []
92
+ function_nodes = [node for node in ast.values() if node.get('nodeType') == 'FunctionDefinition']
93
+
94
+ for func in function_nodes:
95
+ for node in iter_all_nodes(func):
96
+ if isinstance(node, dict) and node.get("kind") == "typeConversion":
97
+ arguments = node.get("arguments", [])
98
+ if len(arguments) == 1 and isinstance(arguments[0], dict):
99
+ expression = node["expression"]
100
+ expr_node_id = expression["id"]
101
+ arg_type_str = expression["argumentTypes"][0]["typeString"]
102
+ if not is_int_type(arg_type_str):
103
+ continue
104
+ if "typeName" not in expression:
105
+ continue
106
+ expr_type_node = expression["typeName"]
107
+ if isinstance(expr_type_node, str):
108
+ expr_type_str = expr_type_node
109
+ else:
110
+ expr_type_str = expr_type_node["name"]
111
+ if not is_int_type(expr_type_str):
112
+ continue
113
+ conversions.append(CastInfo(arg_type_str, expr_type_str, expr_node_id))
114
+
115
+ return conversions
116
+
117
+
118
+ def casting_func_name(counter: int) -> str:
119
+ return f"cast_{counter}"
120
+
121
+
122
+ def generate_casting_function(assembly_prefix: str, cast_info: CastInfo, counter: int) -> str:
123
+ """
124
+ returns the text of a solidity function that does casting according to CastInfo. It also has an encoded mload
125
+ call, to be decoded later on the kotlin side if we run the `safeCasting` builtin rule.
126
+ """
127
+ conversion_string = assembly_prefix + \
128
+ "{ mstore(0xffffff6e4604afefe123321beef1b03fffffffffffffffffffff" + \
129
+ f'{"%0.4x" % counter}{"%0.4x" % encode_type(cast_info.arg_type_str)}{"%0.4x" % encode_type(cast_info.res_type_str)}, x)' + "}"
130
+ function_head = f"function {casting_func_name(counter)}({cast_info.arg_type_str} x) internal pure returns ({cast_info.res_type_str})"
131
+ return function_head + "{\n" + conversion_string + f"return {cast_info.res_type_str}(x);\n" "}\n"
132
+
133
+
134
+ def generate_casting_instrumentation(asts: Dict[str, Dict[str, Dict[int, Any]]], contract_file: str, sdc: SDC) \
135
+ -> tuple[Dict[str, Dict[int, Instrumentation]], Dict[str, tuple[str, list[str]]]]:
136
+ """
137
+ Generate instrumentation for integer type casts in Solidity code.
138
+
139
+ Returns a tuple of:
140
+ - casting_instrumentation: Maps file paths to offset->Instrumentation mappings that replace type names with
141
+ library calls to casting functions we generate.
142
+ - casting_types: Maps file paths to library_name and the text for our new casting functions. This library is added
143
+ to the end of the file.
144
+
145
+ It's not hundred precent sure this works well in combination with `compiler_map`, because the counter for library
146
+ names may reset?
147
+ """
148
+ casting_instrumentation: Dict[str, Dict[int, Instrumentation]] = dict()
149
+
150
+ if not isinstance(sdc.compiler_collector, CompilerCollectorSol):
151
+ raise Exception(f"Encountered a compiler collector that is not solc for file {contract_file}"
152
+ " when trying to add casting instrumentation")
153
+ assembly_prefix = sdc.compiler_collector.gen_memory_safe_assembly_prefix()
154
+
155
+ casting_funcs : Dict[str, tuple[str, list[str]]] = dict()
156
+ counter = 0
157
+ original_files = sorted({Util.convert_path_for_solc_import(c.original_file) for c in sdc.contracts})
158
+ for file_count, solfile in enumerate(original_files, start=1):
159
+ main_ast = asts[contract_file]
160
+ curr_file_ast = main_ast.get(solfile, dict())
161
+
162
+ per_file_inst = casting_instrumentation.setdefault(solfile, dict())
163
+ libname, per_file_casts = casting_funcs.setdefault(solfile, (f"CertoraCastingLib{file_count}", []))
164
+
165
+ casts = find_casts(curr_file_ast)
166
+ for cast_info in casts:
167
+ start_offset, src_len, file = curr_file_ast[cast_info.expr_id]["src"].split(":")
168
+ counter += 1
169
+ per_file_inst[int(start_offset)] = Instrumentation(expected=bytes(cast_info.res_type_str[0], 'utf-8'),
170
+ to_ins=f"{libname}.{casting_func_name(counter)}",
171
+ mut=Replace(len(cast_info.res_type_str)))
172
+ new_func = generate_casting_function(assembly_prefix, cast_info, counter)
173
+ per_file_casts.append(new_func)
174
+
175
+ return casting_instrumentation, casting_funcs
176
+
177
+
178
+ def iter_all_nodes(node: Any) -> Generator[Any, Optional[Any], None]:
179
+ """
180
+ Yield a node and all its subnodes in depth-first order.
181
+ Works with dict nodes that may contain nested dicts and lists.
182
+ """
183
+ yield node
184
+
185
+ if isinstance(node, dict):
186
+ for value in node.values():
187
+ if isinstance(value, (dict, list)):
188
+ yield from iter_all_nodes(value)
189
+ elif isinstance(node, list):
190
+ for item in node:
191
+ if isinstance(item, (dict, list)):
192
+ yield from iter_all_nodes(item)
@@ -20,24 +20,24 @@ import os
20
20
  import re
21
21
  import shutil
22
22
  import sys
23
+ import tempfile
23
24
  import typing
24
25
  from collections import OrderedDict, defaultdict
25
26
  from enum import Enum
26
27
  from functools import lru_cache
27
28
  from pathlib import Path
28
- from Crypto.Hash import keccak
29
- import tempfile
30
-
31
29
  from typing import Any, Dict, List, Tuple, Optional, Set, Iterator, NoReturn
32
30
 
31
+ from Crypto.Hash import keccak
33
32
 
33
+ from CertoraProver.castingInstrumenter import generate_casting_instrumentation
34
34
  from CertoraProver.certoraBuildCacheManager import CertoraBuildCacheManager, CachedFiles
35
35
  from CertoraProver.certoraBuildDataClasses import CONTRACTS, ImmutableReference, ContractExtension, ContractInSDC, SDC, \
36
36
  Instrumentation, InsertBefore, InsertAfter, UnspecializedSourceFinder, instrumentation_logger
37
37
  from CertoraProver.certoraCompilerParameters import SolcParameters
38
+ from CertoraProver.certoraContractFuncs import Func, InternalFunc, STATEMUT, SourceBytes, VyperMetadata
38
39
  from CertoraProver.certoraSourceFinders import add_source_finders
39
40
  from CertoraProver.certoraVerifyGenerator import CertoraVerifyGenerator
40
- from CertoraProver.certoraContractFuncs import Func, InternalFunc, STATEMUT, SourceBytes
41
41
 
42
42
  scripts_dir_path = Path(__file__).parent.parent.resolve() # containing directory
43
43
  sys.path.insert(0, str(scripts_dir_path))
@@ -1381,11 +1381,17 @@ class CertoraBuildGenerator:
1381
1381
 
1382
1382
  return bytecode
1383
1383
 
1384
- def get_solc_via_ir_value(self, contract_file_path: Path) -> bool:
1385
- match = Ctx.get_map_attribute_value(self.context, contract_file_path, 'solc_via_ir')
1386
- assert isinstance(match, (bool, type(None))), f"Expected solc_via_ir to be bool or None, got {type(match)}"
1384
+ def get_map_bool_attribute_value(self, contract_file_path: Path, attr_name: str) -> bool:
1385
+ match = Ctx.get_map_attribute_value(self.context, contract_file_path, attr_name)
1386
+ assert isinstance(match, (bool, type(None))), f"Expected {attr_name} to be bool or None, got {type(match)}"
1387
1387
  return bool(match)
1388
1388
 
1389
+ def get_solc_via_ir_value(self, contract_file_path: Path) -> bool:
1390
+ return self.get_map_bool_attribute_value(contract_file_path, 'solc_via_ir')
1391
+
1392
+ def get_vyper_venom_value(self, contract_file_path: Path) -> bool:
1393
+ return self.get_map_bool_attribute_value(contract_file_path, 'vyper_venom')
1394
+
1389
1395
  def get_solc_evm_version_value(self, contract_file_path: Path) -> Optional[str]:
1390
1396
  match = Ctx.get_map_attribute_value(self.context, contract_file_path, 'solc_evm_version')
1391
1397
  assert isinstance(match, (str, type(None))), f"Expected solc_evm_version to be string or None, got {type(match)}"
@@ -1398,6 +1404,10 @@ class CertoraBuildGenerator:
1398
1404
  match = str(match)
1399
1405
  return match
1400
1406
 
1407
+ def _handle_venom(self, contract_file_path: Path, settings_dict: Dict[str, Any]) -> None:
1408
+ if self.get_vyper_venom_value(contract_file_path):
1409
+ settings_dict["experimentalCodegen"] = True
1410
+
1401
1411
  def _handle_via_ir(self, contract_file_path: Path, settings_dict: Dict[str, Any]) -> None:
1402
1412
  if self.get_solc_via_ir_value(contract_file_path):
1403
1413
  settings_dict["viaIR"] = True
@@ -1510,6 +1520,9 @@ class CertoraBuildGenerator:
1510
1520
  self._handle_via_ir(contract_file_path, settings_dict)
1511
1521
  self._handle_evm_version(contract_file_path, settings_dict)
1512
1522
  self._handle_optimize(contract_file_path, settings_dict, compiler_collector)
1523
+ compiler_lang = compiler_collector.smart_contract_lang
1524
+ if compiler_lang == CompilerLangVy():
1525
+ self._handle_venom(contract_file_path, settings_dict)
1513
1526
 
1514
1527
  @staticmethod
1515
1528
  def solc_setting_optimizer_runs(settings_dict: Dict[str, Any]) -> Tuple[bool, Optional[int]]:
@@ -1569,6 +1582,8 @@ class CertoraBuildGenerator:
1569
1582
  contents = f.read()
1570
1583
  sources_dict = {str(contract_file_posix_abs): {"content": contents}}
1571
1584
  output_selection = ["abi", "evm.bytecode", "evm.deployedBytecode", "evm.methodIdentifiers"]
1585
+ if compiler_collector.compiler_version >= (0, 4, 4):
1586
+ output_selection += ["metadata", "evm.deployedBytecode.symbolMap"]
1572
1587
  ast_selection = ["ast"]
1573
1588
 
1574
1589
  settings_dict: Dict[str, Any] = \
@@ -2225,6 +2240,40 @@ class CertoraBuildGenerator:
2225
2240
  storage_slot['descriptor'] = type_descriptor.as_dict()
2226
2241
  return storage_data
2227
2242
 
2243
+ @staticmethod
2244
+ def add_vyper_internal_function_data(internal_funcs: Set[Func], contract_data: Dict[str, Any]) -> None:
2245
+ metadata = contract_data["metadata"]
2246
+ symbol_map = contract_data["evm"]["deployedBytecode"]["symbolMap"]
2247
+
2248
+ for internal_func in internal_funcs:
2249
+ # find metadata entry
2250
+ func_name = internal_func.name
2251
+ func_info = metadata['function_info']
2252
+ metadata_func_info = None
2253
+ for value in func_info.values():
2254
+ if value.get("name") == func_name:
2255
+ metadata_func_info = value
2256
+ break
2257
+ assert metadata_func_info is not None, f"Could not find metadata for internal function {func_name}"
2258
+ vyper_metadata = VyperMetadata()
2259
+ if metadata_func_info.get('frame_info'):
2260
+ vyper_metadata.frame_size = metadata_func_info['frame_info']['frame_size']
2261
+ vyper_metadata.frame_start = metadata_func_info['frame_info']['frame_start']
2262
+ if metadata_func_info.get('venom_via_stack'):
2263
+ vyper_metadata.venom_via_stack = metadata_func_info['venom_via_stack']
2264
+ if metadata_func_info.get('venom_return_via_stack'):
2265
+ vyper_metadata.venom_return_via_stack = metadata_func_info['venom_return_via_stack']
2266
+ pattern_in_symbol_map = re.compile(fr"{func_name}\(.*\)_runtime$")
2267
+ matches = [k for k in symbol_map if pattern_in_symbol_map.search(k)]
2268
+ if len(matches) == 0:
2269
+ build_logger.warning(f"Could not find symbol map entry for {func_name} probably was inlined")
2270
+ continue
2271
+ elif len(matches) > 1:
2272
+ raise RuntimeError(f"Found multiple matches for {func_name} in symbol map: {matches}")
2273
+ else:
2274
+ vyper_metadata.runtime_start_pc = symbol_map[matches[0]]
2275
+ internal_func.vyper_metadata = vyper_metadata
2276
+
2228
2277
  def get_contract_in_sdc(self,
2229
2278
  source_code_file: str,
2230
2279
  contract_name: str,
@@ -2349,6 +2398,9 @@ class CertoraBuildGenerator:
2349
2398
  else:
2350
2399
  compiler_parameters = None
2351
2400
 
2401
+ if compiler_lang == CompilerLangVy() and compiler_collector_for_contract_file.compiler_version >= (0, 4, 4):
2402
+ self.add_vyper_internal_function_data(internal_funcs, contract_data)
2403
+
2352
2404
  return ContractInSDC(contract_name,
2353
2405
  # somehow make sure this is an absolute path which obeys the autofinder remappings
2354
2406
  # (i.e. make sure this file doesn't start with autoFinder_)
@@ -2865,6 +2917,8 @@ class CertoraBuildGenerator:
2865
2917
 
2866
2918
  self.SDCs[self.get_sdc_key(sdc.primary_contract, sdc.primary_contract_address)] = sdc
2867
2919
 
2920
+ if self.context.dump_asts:
2921
+ self.dump_asts()
2868
2922
  self.handle_links()
2869
2923
  self.handle_struct_links()
2870
2924
  self.handle_contract_extensions()
@@ -3285,6 +3339,15 @@ class CertoraBuildGenerator:
3285
3339
  else:
3286
3340
  added_source_finders = {}
3287
3341
 
3342
+ try:
3343
+ casting_instrumentations, casting_types = generate_casting_instrumentation(self.asts, build_arg_contract_file, sdc_pre_finder)
3344
+ except Exception as e:
3345
+ instrumentation_logger.warning(
3346
+ f"Computing casting instrumentation failed for {build_arg_contract_file}: {e}", exc_info=True)
3347
+ casting_instrumentations, casting_types = {}, {}
3348
+
3349
+ instr = CertoraBuildGenerator.merge_dicts_instrumentation(instr, casting_instrumentations)
3350
+
3288
3351
  abs_build_arg_contract_file = Util.abs_posix_path(build_arg_contract_file)
3289
3352
  if abs_build_arg_contract_file not in instr:
3290
3353
  instrumentation_logger.debug(
@@ -3338,6 +3401,13 @@ class CertoraBuildGenerator:
3338
3401
  read_so_far += amt + 1 + to_skip
3339
3402
  output.write(in_file.read(-1))
3340
3403
 
3404
+ library_name, funcs = casting_types.get(contract_file, ("", list()))
3405
+ if len(funcs) > 0:
3406
+ output.write(bytes(f"\nlibrary {library_name}" + "{\n", "utf8"))
3407
+ for f in funcs:
3408
+ output.write(bytes(f, "utf8"))
3409
+ output.write(bytes("}\n", "utf8"))
3410
+
3341
3411
  new_file = self.to_autofinder_file(build_arg_contract_file)
3342
3412
  self.context.file_to_contract[new_file] = self.context.file_to_contract[
3343
3413
  build_arg_contract_file]
@@ -3813,6 +3883,16 @@ class CertoraBuildGenerator:
3813
3883
  # Avoiding Python interpreter shutdown exceptions which are safe to ignore
3814
3884
  pass
3815
3885
 
3886
+ def dump_asts(self) -> None:
3887
+ asts_dump_file = Util.get_asts_file()
3888
+ filtered_asts = {k: v for k, v in self.asts.items() if not str(k).startswith(f"{Util.get_build_dir()}")}
3889
+ with asts_dump_file.open("w+") as output_file:
3890
+ try:
3891
+ json.dump(filtered_asts, output_file, indent=4, sort_keys=True)
3892
+ except Exception as e:
3893
+ ast_logger.debug(f"Couldn't dump ASTs to {asts_dump_file}", exc_info=e)
3894
+ raise
3895
+
3816
3896
 
3817
3897
  # make sure each source file exists and its path is in absolute format
3818
3898
  def sources_to_abs(sources: Set[Path]) -> Set[Path]:
@@ -189,6 +189,7 @@ class ContractInSDC:
189
189
  # why are we using this and not the normal list of functions?
190
190
  "internalFunctions": {key: method.as_dict() for key, method in self.function_finders.items()},
191
191
  # this doesn't even have all functions
192
+ "internalFuncs": [f.as_dict() for f in self.internal_funcs],
192
193
  "allMethods": [f.as_dict() for f in self.all_funcs],
193
194
  "solidityTypes": [x.as_dict() for x in self.types],
194
195
  "compilerName": "" if not self.compiler_collector else self.compiler_collector.compiler_name,
@@ -35,3 +35,14 @@ class SolcParameters(CompilerParameters):
35
35
  as_dict.update({"optimizerOn": self.optimizer_on, "optimizerRuns": self.optimizer_runs, "viaIR": self.via_ir,
36
36
  "type": "SolcParameters"})
37
37
  return as_dict
38
+
39
+ class VyperParameters(CompilerParameters):
40
+
41
+ def __init__(self, is_venom: bool):
42
+ self.is_venom = is_venom
43
+ CompilerParameters.__init__(self)
44
+
45
+ def as_dict(self) -> Dict[str, Any]:
46
+ as_dict = CompilerParameters.as_dict(self)
47
+ as_dict.update({"is_venom": self.is_venom, "type": "VyperParameters"})
48
+ return as_dict
@@ -298,6 +298,34 @@ class EvmAttributes(AttrUtil.Attributes):
298
298
  disables_build_cache=False
299
299
  )
300
300
 
301
+ VYPER_VENOM_MAP = AttrUtil.AttributeDefinition(
302
+ attr_validation_func=Vf.validate_vyper_venom_map,
303
+ arg_type=AttrUtil.AttrArgType.MAP,
304
+ help_msg="Map contracts to the appropriate experimental-codegen option (Vyper >= 4 only)",
305
+ default_desc="All contracts are compiled without experimental codegen",
306
+ argparse_args={
307
+ "action": AttrUtil.UniqueStore,
308
+ "type": lambda value: Vf.parse_ordered_dict("vyper_venom_map", value, bool)
309
+ },
310
+ affects_build_cache_key=True,
311
+ disables_build_cache=False,
312
+ config_data=AttributeJobConfigData(main_section=MainSection.SOLIDITY_COMPILER)
313
+ )
314
+
315
+ VYPER_VENOM = AttrUtil.AttributeDefinition(
316
+ arg_type=AttrUtil.AttrArgType.BOOLEAN,
317
+ help_msg="Whether to use experimental-codegen (Vyper >= 4 only)",
318
+ default_desc="All contracts are compiled without experimental codegen",
319
+ argparse_args={
320
+ "action": AttrUtil.STORE_TRUE
321
+ },
322
+ affects_build_cache_key=True,
323
+ disables_build_cache=False,
324
+ config_data=AttributeJobConfigData(
325
+ main_section=MainSection.SOLIDITY_COMPILER
326
+ )
327
+ )
328
+
301
329
  SOLC_VIA_IR = AttrUtil.AttributeDefinition(
302
330
  arg_type=AttrUtil.AttrArgType.BOOLEAN,
303
331
  help_msg="Pass the `--via-ir` flag to the Solidity compiler",
@@ -1163,6 +1191,17 @@ class EvmAttributes(AttrUtil.Attributes):
1163
1191
  disables_build_cache=False,
1164
1192
  )
1165
1193
 
1194
+ DUMP_ASTS = AttrUtil.AttributeDefinition(
1195
+ arg_type=AttrUtil.AttrArgType.BOOLEAN,
1196
+ help_msg="dump all solidity files' asts to asts.json in the build directory",
1197
+ default_desc="asts are not saved",
1198
+ argparse_args={
1199
+ 'action': AttrUtil.STORE_TRUE
1200
+ },
1201
+ affects_build_cache_key=False,
1202
+ disables_build_cache=False,
1203
+ )
1204
+
1166
1205
  @classmethod
1167
1206
  def hide_attributes(cls) -> List[str]:
1168
1207
  # do not show these attributes in the help message
@@ -417,8 +417,6 @@ def check_vyper_flag(context: CertoraContext) -> None:
417
417
  vy_paths = [path for path in context.files if path.endswith(".vy")]
418
418
  if not vy_paths:
419
419
  validation_logger.warning("vyper attribute was set but no Vyper files were set")
420
- if context.solc:
421
- raise Util.CertoraUserInputError("cannot set both vyper attribute and solc attribute")
422
420
 
423
421
  def check_contract_name_arg_inputs(context: CertoraContext) -> None:
424
422
  """
@@ -13,7 +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
- from typing import List, Optional, Tuple, Dict, Any
16
+ from typing import List, Optional, Tuple, Dict, Any, cast
17
17
  from CertoraProver import certoraType as CT
18
18
  from Shared import certoraUtils as Util
19
19
 
@@ -46,6 +46,30 @@ class SourceBytes:
46
46
  except (KeyError, ValueError):
47
47
  return None
48
48
 
49
+ class VyperMetadata:
50
+ def __init__(
51
+ self,
52
+ frame_size: Optional[int] = None,
53
+ frame_start: Optional[int] = None,
54
+ venom_via_stack: Optional[List[str]] = None,
55
+ venom_return_via_stack: bool = False,
56
+ runtime_start_pc: Optional[int] = None,
57
+ ):
58
+ self.frame_size = frame_size
59
+ self.frame_start = frame_start
60
+ self.venom_via_stack = venom_via_stack
61
+ self.venom_return_via_stack = venom_return_via_stack
62
+ self.runtime_start_pc = runtime_start_pc
63
+
64
+ def as_dict(self) -> Dict[str, Any]:
65
+ return {
66
+ "frame_size": self.frame_size,
67
+ "frame_start": self.frame_start,
68
+ "venom_via_stack": self.venom_via_stack,
69
+ "venom_return_via_stack": self.venom_return_via_stack,
70
+ "runtime_start_pc": self.runtime_start_pc,
71
+ }
72
+
49
73
 
50
74
  class Func:
51
75
  def __init__(self,
@@ -69,6 +93,7 @@ class Func:
69
93
  original_file: Optional[str],
70
94
  location: Optional[str],
71
95
  body_location: Optional[str],
96
+ vyper_metadata: Optional[VyperMetadata] = None
72
97
  ):
73
98
  self.name = name
74
99
  self.fullArgs = fullArgs
@@ -90,6 +115,7 @@ class Func:
90
115
  self.virtual = virtual
91
116
  self.contractName = contractName
92
117
  self.source_bytes = source_bytes
118
+ self.vyper_metadata = vyper_metadata
93
119
 
94
120
  def as_dict(self) -> Dict[str, Any]:
95
121
  return {
@@ -105,6 +131,7 @@ class Func:
105
131
  "contractName": self.contractName,
106
132
  "sourceBytes": None if self.source_bytes is None else self.source_bytes.as_dict(),
107
133
  "originalFile": None if self.original_file is None else Util.resolve_original_file(self.original_file),
134
+ "vyper_metadata": cast(VyperMetadata, self.vyper_metadata).as_dict() if self.vyper_metadata is not None else None
108
135
  }
109
136
 
110
137
  def name_for_contract(self, contract_name: str) -> str:
@@ -265,6 +265,8 @@ 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
+ def get_asts_file() -> Path:
269
+ return path_in_build_directory(Path(".asts.json"))
268
270
 
269
271
  def get_zip_output_url_file() -> Path:
270
272
  return CERTORA_INTERNAL_ROOT / '.zip-output-url.txt'
@@ -667,14 +667,14 @@ def validate_address(value: str) -> str:
667
667
  return value
668
668
 
669
669
 
670
- def validate_solc_via_ir_map(args: Dict[str, bool]) -> None:
670
+ def validate_boolean_map(args: Dict[str, bool], attr_name: str) -> None:
671
+ attr_map_name = attr_name + "_map"
671
672
  if not isinstance(args, dict):
672
- raise Util.CertoraUserInputError("'solc_via_ir_map' should be stored as a map "
673
- f"(type was {type(args).__name__})")
673
+ raise Util.CertoraUserInputError(f"'{attr_map_name}' should be stored as a map (type was {type(args).__name__})")
674
674
 
675
675
  for contract, value in args.items():
676
676
  if not isinstance(value, bool):
677
- raise Util.CertoraUserInputError(f"'solc_via_ir_map' should map {contract} to a boolean value, "
677
+ raise Util.CertoraUserInputError(f"'{attr_map_name}' should map {contract} to a boolean value, "
678
678
  f"got ({value}, type: {type(value).__name__})")
679
679
 
680
680
  values = args.values()
@@ -682,9 +682,15 @@ def validate_solc_via_ir_map(args: Dict[str, bool]) -> None:
682
682
 
683
683
  if all(x == first for x in values):
684
684
  if first:
685
- validation_logger.warning("all via_ir values are set to True '--solc_via_ir' can be used instead")
685
+ validation_logger.warning(f"all {attr_map_name} values are set to True '{attr_name}' can be used instead")
686
686
  else:
687
- validation_logger.warning("all via_ir values are set to False, this flag/attribute can be omitted")
687
+ validation_logger.warning(f"all {attr_map_name} values are set to False, this flag/attribute can be omitted")
688
+
689
+ def validate_solc_via_ir_map(args: Dict[str, bool]) -> None:
690
+ validate_boolean_map(args, 'solc_via_ir')
691
+
692
+ def validate_vyper_venom_map(args: Dict[str, bool]) -> None:
693
+ validate_boolean_map(args, 'vyper_venom')
688
694
 
689
695
  def validate_solc_evm_version_map(args: Dict[str, str]) -> None:
690
696
  if not isinstance(args, dict):
@@ -838,7 +844,7 @@ def validate_evm_rule_name(rule_str: str) -> str:
838
844
  return __validate_solidity_id(rule_str, "rule")
839
845
 
840
846
  def validate_move_function_name(name: str) -> str:
841
- if not re.match(r"^0x[0-9a-fA-F]+::[a-zA-Z_][a-zA-Z0-9_]*::[a-zA-Z_][a-zA-Z0-9_]*$", name):
847
+ 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):
842
848
  raise Util.CertoraUserInputError(f"invalid Move function name \"{name}\": must be a fully-qualified Move "
843
849
  "function name")
844
850
  return name
@@ -859,7 +865,7 @@ def validate_msg(msg: str) -> str:
859
865
  msg = (msg[:MAX_MSG_LEN - 3] + "...")
860
866
  validation_logger.warning(f"'msg' can't accept strings longer than {MAX_MSG_LEN} chars, string was truncated")
861
867
 
862
- additional_chars = {'(', ' ', ',', '/', '[', "'", '-', '"', '_', ']', '.', ')', ':', '\\', '='}
868
+ additional_chars = {'(', ' ', ',', '/', '[', "'", '-', '"', '_', ']', '.', ')', ':', '\\', '=', '*', '$'}
863
869
  valid_chars = set(string.ascii_letters) | set(string.digits) | additional_chars
864
870
  invalid_chars = set(msg) - valid_chars
865
871
  if len(invalid_chars) > 0:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: certora-cli-beta-mirror
3
- Version: 8.4.3
3
+ Version: 8.5.0
4
4
  Summary: Runner for the Certora Prover
5
5
  Home-page: https://pypi.org/project/certora-cli-beta-mirror
6
6
  Author: Certora
@@ -39,4 +39,4 @@ Dynamic: requires-dist
39
39
  Dynamic: requires-python
40
40
  Dynamic: summary
41
41
 
42
- Commit 0d90215. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
42
+ Commit d143e0e. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
@@ -16,6 +16,7 @@ certora_cli/certoraSorobanProver.py
16
16
  certora_cli/certoraSuiProver.py
17
17
  certora_cli/rustMutator.py
18
18
  certora_cli/CertoraProver/__init__.py
19
+ certora_cli/CertoraProver/castingInstrumenter.py
19
20
  certora_cli/CertoraProver/certoraApp.py
20
21
  certora_cli/CertoraProver/certoraBuild.py
21
22
  certora_cli/CertoraProver/certoraBuildCacheManager.py
@@ -0,0 +1 @@
1
+ {"name": "certora-cli-beta-mirror", "tag": "8.5.0", "branch": "", "commit": "d143e0e", "timestamp": "20251116.12.6.675546", "version": "8.5.0"}
@@ -3,11 +3,11 @@ import setuptools
3
3
 
4
4
  setuptools.setup(
5
5
  name="certora-cli-beta-mirror",
6
- version="8.4.3",
6
+ version="8.5.0",
7
7
  author="Certora",
8
8
  author_email="support@certora.com",
9
9
  description="Runner for the Certora Prover",
10
- long_description="Commit 0d90215. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.",
10
+ long_description="Commit d143e0e. 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-beta-mirror",
13
13
  packages=setuptools.find_packages(),
@@ -1 +0,0 @@
1
- Commit 0d90215. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
@@ -1 +0,0 @@
1
- {"name": "certora-cli-beta-mirror", "tag": "8.4.3", "branch": "", "commit": "0d90215", "timestamp": "20251030.12.0.379579", "version": "8.4.3"}