certora-cli-beta-mirror 8.4.3__py3-none-macosx_10_9_universal2.whl → 8.5.0__py3-none-macosx_10_9_universal2.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.
- certora_cli/CertoraProver/Compiler/CompilerCollectorVy.py +3 -3
- certora_cli/CertoraProver/castingInstrumenter.py +192 -0
- certora_cli/CertoraProver/certoraBuild.py +87 -7
- certora_cli/CertoraProver/certoraBuildDataClasses.py +1 -0
- certora_cli/CertoraProver/certoraCompilerParameters.py +11 -0
- certora_cli/CertoraProver/certoraContextAttributes.py +39 -0
- certora_cli/CertoraProver/certoraContextValidator.py +0 -2
- certora_cli/CertoraProver/certoraContractFuncs.py +28 -1
- certora_cli/Shared/certoraUtils.py +2 -0
- certora_cli/Shared/certoraValidateFuncs.py +14 -8
- {certora_cli_beta_mirror-8.4.3.dist-info → certora_cli_beta_mirror-8.5.0.dist-info}/METADATA +2 -2
- {certora_cli_beta_mirror-8.4.3.dist-info → certora_cli_beta_mirror-8.5.0.dist-info}/RECORD +19 -18
- certora_jars/ASTExtraction.jar +0 -0
- certora_jars/CERTORA-CLI-VERSION-METADATA.json +1 -1
- certora_jars/Typechecker.jar +0 -0
- {certora_cli_beta_mirror-8.4.3.dist-info → certora_cli_beta_mirror-8.5.0.dist-info}/LICENSE +0 -0
- {certora_cli_beta_mirror-8.4.3.dist-info → certora_cli_beta_mirror-8.5.0.dist-info}/WHEEL +0 -0
- {certora_cli_beta_mirror-8.4.3.dist-info → certora_cli_beta_mirror-8.5.0.dist-info}/entry_points.txt +0 -0
- {certora_cli_beta_mirror-8.4.3.dist-info → certora_cli_beta_mirror-8.5.0.dist-info}/top_level.txt +0 -0
|
@@ -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']
|
|
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
|
|
1385
|
-
match = Ctx.get_map_attribute_value(self.context, contract_file_path,
|
|
1386
|
-
assert isinstance(match, (bool, type(None))), f"Expected
|
|
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
|
|
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("'
|
|
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"'
|
|
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
|
|
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
|
|
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]
|
|
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:
|
{certora_cli_beta_mirror-8.4.3.dist-info → certora_cli_beta_mirror-8.5.0.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: certora-cli-beta-mirror
|
|
3
|
-
Version: 8.
|
|
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
|
|
42
|
+
Commit d143e0e. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
|
|
@@ -13,22 +13,23 @@ certora_cli/certoraSorobanProver.py,sha256=SYJKz5Sw-N0bJrSa1njRCE53R9_PMz7IWLhfa
|
|
|
13
13
|
certora_cli/certoraSuiProver.py,sha256=gRs-iihB35ZSEIQ5-hJN-wLgrHZlcfmpk76Wr6vza74,2827
|
|
14
14
|
certora_cli/rustMutator.py,sha256=6AvOGU8Ijz89zW_ZJCWlfXkeobJsk7EsqZhK7Eqwn-Y,14544
|
|
15
15
|
certora_cli/CertoraProver/__init__.py,sha256=QHNr-PJQAoyuPgTkO7gg23GRchiWSXglWNG7yLSQZvs,849
|
|
16
|
+
certora_cli/CertoraProver/castingInstrumenter.py,sha256=4FDjQjnN9s8I3B9J-_G9rug9Jf3LnWnAuRngr50oTH4,7898
|
|
16
17
|
certora_cli/CertoraProver/certoraApp.py,sha256=RKJ2Krb_CzbRUvczbdE6FhUDrFcvrR8j0JS8MNWXX7s,1469
|
|
17
|
-
certora_cli/CertoraProver/certoraBuild.py,sha256
|
|
18
|
+
certora_cli/CertoraProver/certoraBuild.py,sha256=-4cBWcMj3dU9cc2BzJ7AT3TzY1tDYGTKaLrcvxUOW6Y,231453
|
|
18
19
|
certora_cli/CertoraProver/certoraBuildCacheManager.py,sha256=DnVd7w92xjmg0DIrMgoJnCvaU0yCz7ySy0M4RiHEXEM,13648
|
|
19
|
-
certora_cli/CertoraProver/certoraBuildDataClasses.py,sha256=
|
|
20
|
+
certora_cli/CertoraProver/certoraBuildDataClasses.py,sha256=BKOjO0yBUWA26cK_VO_lczXrOD7VWC8egQiXY4jGpmk,14914
|
|
20
21
|
certora_cli/CertoraProver/certoraBuildRust.py,sha256=ZPbNp4ttRmzcKhFsgHSiHDRExNPaLOzgxTRqu23o1D0,6061
|
|
21
22
|
certora_cli/CertoraProver/certoraBuildSui.py,sha256=zMXD2XnC4oqRDzPcBvSZmVquL3UG5paBZkfUT3JPbYY,4180
|
|
22
23
|
certora_cli/CertoraProver/certoraCloudIO.py,sha256=ElRVD-c69aSURtgobuxbEfg6rPzQDSTqtTZJmeT_SYU,54430
|
|
23
24
|
certora_cli/CertoraProver/certoraCollectConfigurationLayout.py,sha256=Rln6LsqMp-u0H2fAFulTLAn7GW-j3ox2XZSz0ghdjk0,14116
|
|
24
25
|
certora_cli/CertoraProver/certoraCollectRunMetadata.py,sha256=SonKgq2l6_8o6xySbinEinEd32Ufrk3VB0Roq-CmwoM,13718
|
|
25
|
-
certora_cli/CertoraProver/certoraCompilerParameters.py,sha256=
|
|
26
|
+
certora_cli/CertoraProver/certoraCompilerParameters.py,sha256=v-MIt4sDJSQ7vpEFmCt9XBkKBhdBbZuZA4PWNErJwcU,1807
|
|
26
27
|
certora_cli/CertoraProver/certoraConfigIO.py,sha256=-1EhJYsiheYvyCgOOWrRCQBjqtqNXrpMKJYRq5cKJ0Y,8171
|
|
27
28
|
certora_cli/CertoraProver/certoraContext.py,sha256=bBbLPet5si6jFEdL1TBORN-HCiJGQK7hD6OQZ_ODmFY,28878
|
|
28
|
-
certora_cli/CertoraProver/certoraContextAttributes.py,sha256=
|
|
29
|
+
certora_cli/CertoraProver/certoraContextAttributes.py,sha256=P1_wgeodSY3-n8c79E64whVSJ6y52pQGvxtvPc4le38,72244
|
|
29
30
|
certora_cli/CertoraProver/certoraContextClass.py,sha256=d7HDqM72K7YnswR7kEcAHGwkFNrTqRz5-_0m7cl2Mso,900
|
|
30
|
-
certora_cli/CertoraProver/certoraContextValidator.py,sha256=
|
|
31
|
-
certora_cli/CertoraProver/certoraContractFuncs.py,sha256
|
|
31
|
+
certora_cli/CertoraProver/certoraContextValidator.py,sha256=Ja5XrVT1KY4XOG_tQsnUXq5wCifXpEdUUJba3073NaI,46366
|
|
32
|
+
certora_cli/CertoraProver/certoraContractFuncs.py,sha256=IKe4xbDh0yFoYVCuLeAxnGg9h59rQCla3Qpy0GwS3HE,8236
|
|
32
33
|
certora_cli/CertoraProver/certoraExtensionInfo.py,sha256=YlShzdoqJQgXXj3r0TJ3fir1KntIR99Rk8JN5qii2lk,2026
|
|
33
34
|
certora_cli/CertoraProver/certoraJobList.py,sha256=FBIYgJ60I0Ok7vchfTbcuJJbiXgnfAhrONoVeZoHti4,11464
|
|
34
35
|
certora_cli/CertoraProver/certoraMiniSpecParser.py,sha256=NjjMwf5Rav3YWpoOJh4PZ-QOS8exC2cg4yIBSbZA6l0,9660
|
|
@@ -45,7 +46,7 @@ certora_cli/CertoraProver/Compiler/CompilerCollector.py,sha256=cr-PIl7LY9VfNs4s4
|
|
|
45
46
|
certora_cli/CertoraProver/Compiler/CompilerCollectorFactory.py,sha256=drMPTUz9cabxqIu2ngGp0x1ZZ_Jqqn-Db2qql97PTaw,8544
|
|
46
47
|
certora_cli/CertoraProver/Compiler/CompilerCollectorSol.py,sha256=7nAY2FLMUlGJn4f_YoZMqpa3rf7THqhJVjLwTaChcBc,5027
|
|
47
48
|
certora_cli/CertoraProver/Compiler/CompilerCollectorSolBased.py,sha256=UasYWyu8Of6R84vXsqRNGpscYcFQghmSIY_dyaAWDYA,1350
|
|
48
|
-
certora_cli/CertoraProver/Compiler/CompilerCollectorVy.py,sha256=
|
|
49
|
+
certora_cli/CertoraProver/Compiler/CompilerCollectorVy.py,sha256=kPzB_qbSbIFNmJd2cQ89ULwvgiGs7OdI9N_w9raaM4Y,69981
|
|
49
50
|
certora_cli/CertoraProver/Compiler/CompilerCollectorYul.py,sha256=ZTyWIMtaf4gLPRM3_jjq58Gb0r5LE_giajz6sssIi0Y,5299
|
|
50
51
|
certora_cli/CertoraProver/Compiler/__init__.py,sha256=tEFAmNyx9WL0kzpp_-4s7b6pLvxHmBWz6pQAq0yeROM,789
|
|
51
52
|
certora_cli/EquivalenceCheck/Eq_default.conf,sha256=J-tMFzIuQa1NcklOh-wv2bpnikfAxFogpRFOl3qoSwM,164
|
|
@@ -66,16 +67,16 @@ certora_cli/Shared/ExpectedComparator.py,sha256=eyRR-jni4WJoa6j2TK2lnZ89Tyb8U99w
|
|
|
66
67
|
certora_cli/Shared/__init__.py,sha256=s0dhvolFtsS4sRNzPVhC_rlw8mm194rCZ0WhOxInY40,1025
|
|
67
68
|
certora_cli/Shared/certoraAttrUtil.py,sha256=Nw8ban5Axp6c6dT-KJfCD9i9tKnGk1DbvRDDNH3--DU,8574
|
|
68
69
|
certora_cli/Shared/certoraLogging.py,sha256=cV2UQMhQ5j8crGXgeq9CEamI-Lk4HgdiA3HCrP-kSR4,14013
|
|
69
|
-
certora_cli/Shared/certoraUtils.py,sha256=
|
|
70
|
-
certora_cli/Shared/certoraValidateFuncs.py,sha256=
|
|
70
|
+
certora_cli/Shared/certoraUtils.py,sha256=lHd7Da2BmpFAMUoVpdmg5IICsCEIX9qCuD7Ts5QaLpQ,59556
|
|
71
|
+
certora_cli/Shared/certoraValidateFuncs.py,sha256=gCM-YP0Tpngpasd2AWxhu90UNz1wtls3WqJYp18n_Q8,43503
|
|
71
72
|
certora_cli/Shared/proverCommon.py,sha256=DUB-uEKjOkZ-8qil6xukPqfTynpigXW-gcrm0_kRUZY,11383
|
|
72
|
-
certora_jars/ASTExtraction.jar,sha256=
|
|
73
|
-
certora_jars/CERTORA-CLI-VERSION-METADATA.json,sha256=
|
|
74
|
-
certora_jars/Typechecker.jar,sha256=
|
|
73
|
+
certora_jars/ASTExtraction.jar,sha256=rBQRW5FNQvTwMCgKoqGC57e5Z4Nr8bfudvGrGLlTl18,21985312
|
|
74
|
+
certora_jars/CERTORA-CLI-VERSION-METADATA.json,sha256=ppx9Vemc6qNycgG68gPOhJOtdkWdvoP3quVgINQz7oE,143
|
|
75
|
+
certora_jars/Typechecker.jar,sha256=qqtuhN-2TnyY6VjuKJ2ELunS9lnbDecUd8GXNWGZSd0,21947424
|
|
75
76
|
certora_jars/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
76
|
-
certora_cli_beta_mirror-8.
|
|
77
|
-
certora_cli_beta_mirror-8.
|
|
78
|
-
certora_cli_beta_mirror-8.
|
|
79
|
-
certora_cli_beta_mirror-8.
|
|
80
|
-
certora_cli_beta_mirror-8.
|
|
81
|
-
certora_cli_beta_mirror-8.
|
|
77
|
+
certora_cli_beta_mirror-8.5.0.dist-info/LICENSE,sha256=UGKSKIJSetF8m906JLKqNLkUS2CL60XfQdNvxBvpQXo,620
|
|
78
|
+
certora_cli_beta_mirror-8.5.0.dist-info/METADATA,sha256=R7o6xR4P3zsUcfbMsNJXf7hSIcUgEJI6KwV_6fJNmGo,1286
|
|
79
|
+
certora_cli_beta_mirror-8.5.0.dist-info/WHEEL,sha256=9Ig2YBzm5cpS_YWKLeuYxVAxcKv_uDQsCzy9XJbRZ_g,110
|
|
80
|
+
certora_cli_beta_mirror-8.5.0.dist-info/entry_points.txt,sha256=YXGQmR4tGdYD9lLdG_TEJkmVNrRauCtCDE88HwvO2Jo,569
|
|
81
|
+
certora_cli_beta_mirror-8.5.0.dist-info/top_level.txt,sha256=8C77w3JLanY0-NW45vpJsjRssyCqVP-qmPiN9FjWiX4,38
|
|
82
|
+
certora_cli_beta_mirror-8.5.0.dist-info/RECORD,,
|
certora_jars/ASTExtraction.jar
CHANGED
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name": "certora-cli-beta-mirror", "tag": "8.
|
|
1
|
+
{"name": "certora-cli-beta-mirror", "tag": "8.5.0", "branch": "", "commit": "d143e0e", "timestamp": "20251116.12.6.675546", "version": "8.5.0"}
|
certora_jars/Typechecker.jar
CHANGED
|
Binary file
|
|
File without changes
|
|
File without changes
|
{certora_cli_beta_mirror-8.4.3.dist-info → certora_cli_beta_mirror-8.5.0.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{certora_cli_beta_mirror-8.4.3.dist-info → certora_cli_beta_mirror-8.5.0.dist-info}/top_level.txt
RENAMED
|
File without changes
|