certora-cli 6.3.1__tar.gz → 7.3.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.
- {certora-cli-6.3.1/certora_cli.egg-info → certora-cli-7.3.0}/PKG-INFO +2 -2
- certora-cli-7.3.0/README.md +1 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/Compiler/CompilerCollector.py +41 -32
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/Compiler/CompilerCollectorFactory.py +8 -2
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/Compiler/CompilerCollectorSol.py +29 -17
- certora-cli-7.3.0/certora_cli/EVMVerifier/Compiler/CompilerCollectorSolBased.py +21 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/Compiler/CompilerCollectorVy.py +109 -51
- certora-cli-7.3.0/certora_cli/EVMVerifier/Compiler/CompilerCollectorYul.py +90 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/certoraBuild.py +323 -241
- certora-cli-7.3.0/certora_cli/EVMVerifier/certoraCompilerParameters.py +22 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/certoraConfigIO.py +6 -6
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/certoraContext.py +19 -12
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/certoraContextAttribute.py +151 -49
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/certoraContextValidator.py +113 -136
- certora-cli-7.3.0/certora_cli/EVMVerifier/certoraContractFuncs.py +121 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/certoraType.py +2 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EquivalenceCheck/equivCheck.py +4 -2
- certora-cli-7.3.0/certora_cli/Mutate/mutateApp.py +1750 -0
- certora-cli-7.3.0/certora_cli/Mutate/mutateAttribute.py +314 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/Mutate/mutateConstants.py +35 -9
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/Mutate/mutateValidate.py +45 -58
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/Shared/ExpectedComparator.py +32 -15
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/Shared/certoraAttrUtil.py +13 -22
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/Shared/certoraUtils.py +123 -29
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/Shared/certoraValidateFuncs.py +59 -12
- certora-cli-7.3.0/certora_cli/certoraMutate.py +94 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/certoraRun.py +6 -11
- {certora-cli-6.3.1 → certora-cli-7.3.0/certora_cli.egg-info}/PKG-INFO +2 -2
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli.egg-info/SOURCES.txt +4 -1
- certora-cli-7.3.0/certora_jars/CERTORA-CLI-VERSION-METADATA.json +1 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_jars/Typechecker.jar +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/setup.py +2 -2
- certora-cli-6.3.1/README.md +0 -1
- certora-cli-6.3.1/certora_cli/EVMVerifier/certoraMutateGenerator.py +0 -133
- certora-cli-6.3.1/certora_cli/Mutate/mutateApp.py +0 -1347
- certora-cli-6.3.1/certora_cli/Mutate/mutateAttribute.py +0 -227
- certora-cli-6.3.1/certora_cli/certoraMutate.py +0 -72
- certora-cli-6.3.1/certora_jars/CERTORA-CLI-VERSION-METADATA.json +0 -1
- {certora-cli-6.3.1 → certora-cli-7.3.0}/LICENSE +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/MANIFEST.in +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_bins/__init__.py +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/Compiler/__init__.py +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/__init__.py +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/certoraCloudIO.py +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/certoraCollectRunMetadata.py +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/certoraContextClass.py +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/certoraExtensionInfo.py +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/certoraJobList.py +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/certoraNodeFilters.py +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EquivalenceCheck/Eq_default.conf +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EquivalenceCheck/Eq_mc_no_out_template.spec +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EquivalenceCheck/Eq_mc_template.spec +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EquivalenceCheck/Eq_sanity.conf +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EquivalenceCheck/Eq_template.spec +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EquivalenceCheck/__init__.py +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EquivalenceCheck/sanity.spec +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/Mutate/__init__.py +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/Shared/__init__.py +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/Shared/certoraLogging.py +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/__init__.py +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/certoraEqCheck.py +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli.egg-info/dependency_links.txt +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli.egg-info/entry_points.txt +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli.egg-info/requires.txt +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli.egg-info/top_level.txt +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/certora_jars/__init__.py +0 -0
- {certora-cli-6.3.1 → certora-cli-7.3.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: certora-cli
|
|
3
|
-
Version:
|
|
3
|
+
Version: 7.3.0
|
|
4
4
|
Summary: Runner for the Certora Prover
|
|
5
5
|
Home-page: https://pypi.org/project/certora-cli
|
|
6
6
|
Author: Certora
|
|
@@ -21,4 +21,4 @@ Requires-Dist: tabulate
|
|
|
21
21
|
Requires-Dist: tqdm
|
|
22
22
|
Requires-Dist: StrEnum
|
|
23
23
|
|
|
24
|
-
Commit
|
|
24
|
+
Commit 3dce873. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Commit 3dce873. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
|
{certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/Compiler/CompilerCollector.py
RENAMED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from abc import abstractmethod, ABC
|
|
2
|
+
from dataclasses import dataclass
|
|
2
3
|
from pathlib import Path
|
|
3
4
|
from typing import Any, Dict, List, Optional, Tuple, Set
|
|
4
5
|
from Shared.certoraUtils import AbstractAndSingleton, CompilerVersion
|
|
@@ -6,39 +7,23 @@ import EVMVerifier.certoraType as CT
|
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
# TODO: merge this with Func in certoraBuild
|
|
10
|
+
@dataclass
|
|
9
11
|
class CompilerLangFunc:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
where: Optional[Tuple[str, str]] = None # 1st element: source file name, 2nd element: location string
|
|
26
|
-
):
|
|
27
|
-
self.name = name
|
|
28
|
-
self.fullArgs = fullargs
|
|
29
|
-
self.paramNames = paramnames
|
|
30
|
-
self.returns = returns
|
|
31
|
-
self.sighash = sighash
|
|
32
|
-
self.notpayable = notpayable
|
|
33
|
-
self.fromLib = fromlib
|
|
34
|
-
self.isConstructor = isconstructor
|
|
35
|
-
self.stateMutability = statemutability
|
|
36
|
-
self.visibility = visibility
|
|
37
|
-
self.where = where
|
|
38
|
-
self.implemented = implemented
|
|
39
|
-
self.ast_id = ast_id
|
|
40
|
-
self.overrides = overrides
|
|
41
|
-
self.contractName = contractName
|
|
12
|
+
name: str
|
|
13
|
+
fullArgs: List[CT.TypeInstance]
|
|
14
|
+
paramNames: List[str]
|
|
15
|
+
returns: List[CT.TypeInstance]
|
|
16
|
+
sighash: str
|
|
17
|
+
notpayable: bool
|
|
18
|
+
fromLib: bool # not serialized
|
|
19
|
+
isConstructor: bool # not serialized
|
|
20
|
+
stateMutability: str
|
|
21
|
+
visibility: str
|
|
22
|
+
implemented: bool # does this function have a body? (false for interface functions)
|
|
23
|
+
overrides: bool # does this function override an interface declaration or super-contract definition?
|
|
24
|
+
contractName: str
|
|
25
|
+
ast_id: Optional[int] = None
|
|
26
|
+
where: Optional[Tuple[str, str]] = None # 1st element: source file name, 2nd element: location string
|
|
42
27
|
|
|
43
28
|
|
|
44
29
|
class CompilerLang(metaclass=AbstractAndSingleton):
|
|
@@ -146,6 +131,30 @@ class CompilerLang(metaclass=AbstractAndSingleton):
|
|
|
146
131
|
"""
|
|
147
132
|
pass
|
|
148
133
|
|
|
134
|
+
@property
|
|
135
|
+
@abstractmethod
|
|
136
|
+
def supports_typed_immutables(self) -> bool:
|
|
137
|
+
"""
|
|
138
|
+
:return: True if has type information associated to immutables
|
|
139
|
+
"""
|
|
140
|
+
pass
|
|
141
|
+
|
|
142
|
+
@property
|
|
143
|
+
@abstractmethod
|
|
144
|
+
def supports_ast_output(self) -> bool:
|
|
145
|
+
"""
|
|
146
|
+
:return: True if compiling contracts in this language produces AST output
|
|
147
|
+
"""
|
|
148
|
+
pass
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
@abstractmethod
|
|
152
|
+
def supports_srclist_output(self) -> bool:
|
|
153
|
+
"""
|
|
154
|
+
:return: True if compiling contracts in this language produces srclist output
|
|
155
|
+
"""
|
|
156
|
+
pass
|
|
157
|
+
|
|
149
158
|
|
|
150
159
|
class CompilerCollector(ABC):
|
|
151
160
|
"""
|
{certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/Compiler/CompilerCollectorFactory.py
RENAMED
|
@@ -9,6 +9,7 @@ import re
|
|
|
9
9
|
import logging
|
|
10
10
|
from EVMVerifier.Compiler.CompilerCollector import CompilerLang, CompilerCollector
|
|
11
11
|
from EVMVerifier.Compiler.CompilerCollectorSol import CompilerCollectorSol, CompilerLangSol
|
|
12
|
+
from EVMVerifier.Compiler.CompilerCollectorYul import CompilerLangYul, CompilerCollectorYul
|
|
12
13
|
from EVMVerifier.Compiler.CompilerCollectorVy import CompilerCollectorVy, CompilerLangVy
|
|
13
14
|
from Shared.certoraUtils import is_windows, match_path_to_mapping_key, remove_file, get_certora_config_dir
|
|
14
15
|
from EVMVerifier.certoraContextClass import CertoraContext
|
|
@@ -71,9 +72,12 @@ class CompilerCollectorFactory:
|
|
|
71
72
|
return CompilerCollectorVy(version)
|
|
72
73
|
elif str(path).endswith(".sol"):
|
|
73
74
|
version = self.__get_solc_version(path)
|
|
74
|
-
return CompilerCollectorSol(version)
|
|
75
|
+
return CompilerCollectorSol(version, CompilerLangSol(), self.context.use_memory_safe_autofinders)
|
|
76
|
+
elif str(path).endswith(".yul"):
|
|
77
|
+
version = self.__get_solc_version(path)
|
|
78
|
+
return CompilerCollectorYul(version, CompilerLangYul())
|
|
75
79
|
else:
|
|
76
|
-
raise RuntimeError(f'expected {path} to represent a Solidity or Vyper file')
|
|
80
|
+
raise RuntimeError(f'expected {path} to represent a Solidity, Yul, or Vyper file')
|
|
77
81
|
|
|
78
82
|
@staticmethod
|
|
79
83
|
def get_vyper_compiler(contract_file_path: Path, default_compiler: str, compiler_mappings: Dict[str, str]) -> str:
|
|
@@ -170,5 +174,7 @@ def get_compiler_lang(file_name: str) -> CompilerLang:
|
|
|
170
174
|
return CompilerLangVy()
|
|
171
175
|
elif file_name.endswith(".sol"):
|
|
172
176
|
return CompilerLangSol()
|
|
177
|
+
elif file_name.endswith(".yul"):
|
|
178
|
+
return CompilerLangYul()
|
|
173
179
|
else:
|
|
174
180
|
raise RuntimeError(f'expected {file_name} to represent a Solidity or Vyper file')
|
{certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/Compiler/CompilerCollectorSol.py
RENAMED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
from typing import Any, List, Tuple, Dict, Set
|
|
3
3
|
|
|
4
|
-
from EVMVerifier.Compiler.CompilerCollector import CompilerLang,
|
|
4
|
+
from EVMVerifier.Compiler.CompilerCollector import CompilerLang, CompilerLangFunc
|
|
5
|
+
from EVMVerifier.Compiler.CompilerCollectorSolBased import CompilerCollectorSolBased
|
|
5
6
|
from Shared.certoraUtils import Singleton, CompilerVersion, get_certora_config_dir
|
|
6
7
|
import EVMVerifier.certoraType as CT
|
|
7
8
|
|
|
@@ -62,33 +63,44 @@ class CompilerLangSol(CompilerLang, metaclass=Singleton):
|
|
|
62
63
|
Tuple[List[CT.Type], List[CompilerLangFunc]]:
|
|
63
64
|
assert False, "collect_source_type_descriptions() has not yet been implemented in CompilerLangSol"
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
# This class is intended for calculations of compiler-settings related queries
|
|
67
|
-
class CompilerCollectorSol(CompilerCollector):
|
|
68
|
-
|
|
69
|
-
def __init__(self, version: CompilerVersion):
|
|
70
|
-
self.__compiler_version = version
|
|
71
|
-
|
|
72
66
|
@property
|
|
73
|
-
def
|
|
74
|
-
return
|
|
67
|
+
def supports_typed_immutables(self) -> bool:
|
|
68
|
+
return True
|
|
75
69
|
|
|
76
70
|
@property
|
|
77
|
-
def
|
|
78
|
-
return
|
|
71
|
+
def supports_ast_output(self) -> bool:
|
|
72
|
+
return True
|
|
79
73
|
|
|
80
74
|
@property
|
|
81
|
-
def
|
|
82
|
-
return
|
|
75
|
+
def supports_srclist_output(self) -> bool:
|
|
76
|
+
return True
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# This class is intended for calculations of compiler-settings related queries
|
|
80
|
+
class CompilerCollectorSol(CompilerCollectorSolBased):
|
|
81
|
+
|
|
82
|
+
def __init__(self, version: CompilerVersion, lang: CompilerLang, use_memory_safe_autofinders: bool):
|
|
83
|
+
super().__init__(version, lang)
|
|
84
|
+
self.__use_memory_safe_autofinders = use_memory_safe_autofinders
|
|
83
85
|
|
|
84
86
|
def normalize_storage(self, is_storage: bool, arg_name: str) -> str:
|
|
85
87
|
if not is_storage:
|
|
86
88
|
return arg_name
|
|
87
|
-
if self.
|
|
89
|
+
if self.compiler_version[0] == 0 and self.compiler_version[1] < 7:
|
|
88
90
|
return arg_name + "_slot"
|
|
89
91
|
else:
|
|
90
92
|
return arg_name + ".slot"
|
|
91
93
|
|
|
92
94
|
def supports_calldata_assembly(self, arg_name: str) -> bool:
|
|
93
|
-
return (self.
|
|
94
|
-
self.
|
|
95
|
+
return (self.compiler_version[1] > 7 or (
|
|
96
|
+
self.compiler_version[1] == 7 and self.compiler_version[2] >= 5)) and arg_name != ""
|
|
97
|
+
|
|
98
|
+
def supports_memory_safe_assembly(self) -> bool:
|
|
99
|
+
return (self.compiler_version[1] > 8 or (
|
|
100
|
+
self.compiler_version[1] == 8 and self.compiler_version[2] >= 13))
|
|
101
|
+
|
|
102
|
+
def gen_memory_safe_assembly_prefix(self) -> str:
|
|
103
|
+
if self.supports_memory_safe_assembly() and self.__use_memory_safe_autofinders:
|
|
104
|
+
return 'assembly ("memory-safe")'
|
|
105
|
+
else:
|
|
106
|
+
return 'assembly'
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from EVMVerifier.Compiler.CompilerCollector import CompilerCollector, CompilerLang
|
|
2
|
+
from Shared.certoraUtils import CompilerVersion
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class CompilerCollectorSolBased(CompilerCollector):
|
|
6
|
+
|
|
7
|
+
def __init__(self, version: CompilerVersion, lang: CompilerLang):
|
|
8
|
+
self.__compiler_version = version
|
|
9
|
+
self.__smart_contract_lang = lang
|
|
10
|
+
|
|
11
|
+
@property
|
|
12
|
+
def compiler_name(self) -> str:
|
|
13
|
+
return self.smart_contract_lang.compiler_name
|
|
14
|
+
|
|
15
|
+
@property
|
|
16
|
+
def smart_contract_lang(self) -> CompilerLang:
|
|
17
|
+
return self.__smart_contract_lang
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def compiler_version(self) -> CompilerVersion:
|
|
21
|
+
return self.__compiler_version
|
{certora-cli-6.3.1 → certora-cli-7.3.0}/certora_cli/EVMVerifier/Compiler/CompilerCollectorVy.py
RENAMED
|
@@ -80,6 +80,10 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
80
80
|
return {CompilerLangVy.compilation_output_path(sdc_name),
|
|
81
81
|
CompilerLangVy.compilation_error_path(sdc_name)}
|
|
82
82
|
|
|
83
|
+
@staticmethod
|
|
84
|
+
def pad(x: int) -> int:
|
|
85
|
+
return (x + 31) & ~31
|
|
86
|
+
|
|
83
87
|
class VyperType(ABC):
|
|
84
88
|
uniqueId: int = 0
|
|
85
89
|
|
|
@@ -90,11 +94,11 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
90
94
|
return r
|
|
91
95
|
|
|
92
96
|
@abstractmethod
|
|
93
|
-
def size_in_bytes(self) -> int:
|
|
97
|
+
def size_in_bytes(self, storage: bool = False) -> int:
|
|
94
98
|
pass
|
|
95
99
|
|
|
96
100
|
@abstractmethod
|
|
97
|
-
def generate_types_field(self) -> Dict[str, Any]:
|
|
101
|
+
def generate_types_field(self, storage: bool = False) -> Dict[str, Any]:
|
|
98
102
|
"""Returns a JSON-style object containing the fields of a [bridge.SolcType] (in kotlin)"""
|
|
99
103
|
pass
|
|
100
104
|
|
|
@@ -126,10 +130,10 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
126
130
|
def __init__(self, name: str):
|
|
127
131
|
self.name = name
|
|
128
132
|
|
|
129
|
-
def size_in_bytes(self) -> int:
|
|
133
|
+
def size_in_bytes(self, storage: bool = False) -> int:
|
|
130
134
|
raise NotImplementedError
|
|
131
135
|
|
|
132
|
-
def generate_types_field(self) -> Dict[str, Any]:
|
|
136
|
+
def generate_types_field(self, storage: bool = False) -> Dict[str, Any]:
|
|
133
137
|
raise NotImplementedError
|
|
134
138
|
|
|
135
139
|
def get_canonical_vyper_name(self) -> str:
|
|
@@ -154,15 +158,21 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
154
158
|
self.element_type = element_type
|
|
155
159
|
self.max_num_elements = max_num_elements
|
|
156
160
|
|
|
157
|
-
def size_in_bytes(self) -> int:
|
|
158
|
-
|
|
161
|
+
def size_in_bytes(self, storage: bool = False) -> int:
|
|
162
|
+
element_size = self.element_type.size_in_bytes(storage)
|
|
163
|
+
# bytes _are_ actually packed in storage arrays
|
|
164
|
+
if storage and self.element_type != CompilerLangVy.primitive_types['byte']:
|
|
165
|
+
element_size = CompilerLangVy.pad(element_size)
|
|
166
|
+
return element_size * self.max_num_elements
|
|
167
|
+
else:
|
|
168
|
+
return CompilerLangVy.pad(element_size * self.max_num_elements)
|
|
159
169
|
|
|
160
|
-
def generate_types_field(self) -> Dict[str, Any]:
|
|
170
|
+
def generate_types_field(self, storage: bool = False) -> Dict[str, Any]:
|
|
161
171
|
return {
|
|
162
172
|
'label': self.get_canonical_vyper_name(),
|
|
163
173
|
'encoding': 'inplace',
|
|
164
174
|
'base': self.element_type.get_canonical_vyper_name(),
|
|
165
|
-
'numberOfBytes': str(self.size_in_bytes())
|
|
175
|
+
'numberOfBytes': str(self.size_in_bytes(storage))
|
|
166
176
|
}
|
|
167
177
|
|
|
168
178
|
def get_canonical_vyper_name(self) -> str:
|
|
@@ -173,7 +183,7 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
173
183
|
return self
|
|
174
184
|
|
|
175
185
|
def get_used_types(self) -> List[Any]:
|
|
176
|
-
return [self] +
|
|
186
|
+
return [self] + self.element_type.get_used_types()
|
|
177
187
|
|
|
178
188
|
def get_certora_type(self, contract_name: str, ref: int) -> CT.Type:
|
|
179
189
|
return CT.ArrayType(self.element_type.get_canonical_vyper_name(),
|
|
@@ -193,14 +203,14 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
193
203
|
self.name = name
|
|
194
204
|
self.members = members
|
|
195
205
|
|
|
196
|
-
def size_in_bytes(self) -> int:
|
|
206
|
+
def size_in_bytes(self, storage: bool = False) -> int:
|
|
197
207
|
return 1
|
|
198
208
|
|
|
199
|
-
def generate_types_field(self) -> Dict[str, Any]:
|
|
209
|
+
def generate_types_field(self, storage: bool = False) -> Dict[str, Any]:
|
|
200
210
|
return {
|
|
201
211
|
'label': self.get_canonical_vyper_name(),
|
|
202
212
|
'encoding': 'inplace',
|
|
203
|
-
'numberOfBytes': str(self.size_in_bytes())
|
|
213
|
+
'numberOfBytes': str(self.size_in_bytes(storage))
|
|
204
214
|
}
|
|
205
215
|
|
|
206
216
|
def get_canonical_vyper_name(self) -> str:
|
|
@@ -227,15 +237,20 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
227
237
|
self.name = name
|
|
228
238
|
self.members = members
|
|
229
239
|
|
|
230
|
-
def size_in_bytes(self) -> int:
|
|
231
|
-
|
|
240
|
+
def size_in_bytes(self, storage: bool = False) -> int:
|
|
241
|
+
def mem_size(f: Tuple[str, Any]) -> int:
|
|
242
|
+
sz = f[1].size_in_bytes(storage)
|
|
243
|
+
if storage:
|
|
244
|
+
sz = CompilerLangVy.pad(sz)
|
|
245
|
+
return sz
|
|
246
|
+
return sum([mem_size(f) for f in self.members])
|
|
232
247
|
|
|
233
|
-
def generate_types_field(self) -> Dict[str, Any]:
|
|
248
|
+
def generate_types_field(self, storage: bool = False) -> Dict[str, Any]:
|
|
234
249
|
bytes_so_far_rounded_up = 0
|
|
235
250
|
slots = {}
|
|
236
251
|
for n, t in self.members:
|
|
237
252
|
slots.update({n: bytes_so_far_rounded_up // 32})
|
|
238
|
-
bytes_so_far_rounded_up += (t.size_in_bytes()
|
|
253
|
+
bytes_so_far_rounded_up += CompilerLangVy.pad(t.size_in_bytes(storage))
|
|
239
254
|
members_field = [
|
|
240
255
|
{
|
|
241
256
|
'label': n,
|
|
@@ -248,7 +263,7 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
248
263
|
'label': self.get_canonical_vyper_name(),
|
|
249
264
|
'encoding': 'inplace',
|
|
250
265
|
'members': members_field,
|
|
251
|
-
'numberOfBytes': str(self.size_in_bytes())
|
|
266
|
+
'numberOfBytes': str(self.size_in_bytes(storage))
|
|
252
267
|
}
|
|
253
268
|
|
|
254
269
|
def get_canonical_vyper_name(self) -> str:
|
|
@@ -282,12 +297,12 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
282
297
|
self.max_num_elements = max_num_elements
|
|
283
298
|
|
|
284
299
|
self.count_type = CompilerLangVy.VyperTypeBoundedInteger(
|
|
285
|
-
CompilerLangVy.primitive_types['uint256'],
|
|
300
|
+
CompilerLangVy.primitive_types['uint256'], 0, max_num_elements)
|
|
286
301
|
self.array_type = CompilerLangVy.VyperTypeStaticArray(element_type, int(max_num_elements))
|
|
287
302
|
super().__init__(self.get_canonical_vyper_name(), [('count', self.count_type), ('data', self.array_type)])
|
|
288
303
|
|
|
289
304
|
def get_canonical_vyper_name(self) -> str:
|
|
290
|
-
return f"DynArray[{self.element_type.get_canonical_vyper_name()},{self.max_num_elements}]"
|
|
305
|
+
return f"DynArray[{self.element_type.get_canonical_vyper_name()}, {self.max_num_elements}]"
|
|
291
306
|
|
|
292
307
|
def get_certora_type(self, contract_name: str, ref: int) -> CT.Type:
|
|
293
308
|
element_type = self.element_type.get_certora_type(contract_name, ref)
|
|
@@ -308,15 +323,25 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
308
323
|
def get_certora_type(self, contract_name: str, ref: int) -> CT.Type:
|
|
309
324
|
return CT.StringType()
|
|
310
325
|
|
|
326
|
+
class VyperTypeBytes(VyperTypeDynArray):
|
|
327
|
+
def __init__(self, max_num_elements: int):
|
|
328
|
+
super().__init__(CompilerLangVy.primitive_types['byte'], max_num_elements)
|
|
329
|
+
|
|
330
|
+
def get_canonical_vyper_name(self) -> str:
|
|
331
|
+
return 'Bytes[' + str(self.array_type.max_num_elements) + ']'
|
|
332
|
+
|
|
333
|
+
def get_certora_type(self, contract_name: str, ref: int) -> CT.Type:
|
|
334
|
+
return CT.PackedBytes()
|
|
335
|
+
|
|
311
336
|
class VyperTypeHashMap(VyperType):
|
|
312
337
|
def __init__(self, key_type: Any, value_type: Any):
|
|
313
338
|
self.key_type = key_type
|
|
314
339
|
self.value_type = value_type
|
|
315
340
|
|
|
316
|
-
def size_in_bytes(self) -> int:
|
|
341
|
+
def size_in_bytes(self, storage: bool = False) -> int:
|
|
317
342
|
return 32
|
|
318
343
|
|
|
319
|
-
def generate_types_field(self) -> Dict[str, Any]:
|
|
344
|
+
def generate_types_field(self, storage: bool = False) -> Dict[str, Any]:
|
|
320
345
|
return {
|
|
321
346
|
'label': self.get_canonical_vyper_name(),
|
|
322
347
|
'encoding': 'mapping',
|
|
@@ -335,7 +360,7 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
335
360
|
return self
|
|
336
361
|
|
|
337
362
|
def get_used_types(self) -> List[Any]:
|
|
338
|
-
return [self] +
|
|
363
|
+
return [self] + self.key_type.get_used_types() + self.value_type.get_used_types()
|
|
339
364
|
|
|
340
365
|
def get_certora_type(self, contract_name: str, ref: int) -> CT.Type:
|
|
341
366
|
in_type = self.key_type.get_certora_type(contract_name, ref)
|
|
@@ -353,17 +378,17 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
353
378
|
def __init__(self, name: str):
|
|
354
379
|
self.name = name
|
|
355
380
|
|
|
356
|
-
def size_in_bytes(self) -> int:
|
|
381
|
+
def size_in_bytes(self, storage: bool = False) -> int:
|
|
357
382
|
return 20
|
|
358
383
|
|
|
359
384
|
def get_canonical_vyper_name(self) -> str:
|
|
360
385
|
return self.name
|
|
361
386
|
|
|
362
|
-
def generate_types_field(self) -> Dict[str, Any]:
|
|
387
|
+
def generate_types_field(self, storage: bool = False) -> Dict[str, Any]:
|
|
363
388
|
return {
|
|
364
389
|
'label': "contract " + self.get_canonical_vyper_name(),
|
|
365
390
|
'encoding': 'inplace',
|
|
366
|
-
'numberOfBytes': str(self.size_in_bytes())
|
|
391
|
+
'numberOfBytes': str(self.size_in_bytes(storage))
|
|
367
392
|
}
|
|
368
393
|
|
|
369
394
|
def get_certora_type(self, contract_name: str, ref: int) -> CT.Type:
|
|
@@ -380,14 +405,14 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
380
405
|
self.name = name
|
|
381
406
|
self.size = size
|
|
382
407
|
|
|
383
|
-
def size_in_bytes(self) -> int:
|
|
408
|
+
def size_in_bytes(self, storage: bool = False) -> int:
|
|
384
409
|
return self.size
|
|
385
410
|
|
|
386
|
-
def generate_types_field(self) -> Dict[str, Any]:
|
|
411
|
+
def generate_types_field(self, storage: bool = False) -> Dict[str, Any]:
|
|
387
412
|
return {
|
|
388
413
|
'label': self.get_canonical_vyper_name(),
|
|
389
414
|
'encoding': 'inplace',
|
|
390
|
-
'numberOfBytes': str(self.size_in_bytes())
|
|
415
|
+
'numberOfBytes': str(self.size_in_bytes(storage))
|
|
391
416
|
}
|
|
392
417
|
|
|
393
418
|
def get_canonical_vyper_name(self) -> str:
|
|
@@ -428,11 +453,11 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
428
453
|
self.lower_bound = lower_bound
|
|
429
454
|
self.upper_bound = upper_bound
|
|
430
455
|
|
|
431
|
-
def generate_types_field(self) -> Dict[str, Any]:
|
|
456
|
+
def generate_types_field(self, storage: bool = False) -> Dict[str, Any]:
|
|
432
457
|
return {
|
|
433
458
|
'label': self.get_canonical_vyper_name(),
|
|
434
459
|
'encoding': 'inplace',
|
|
435
|
-
'numberOfBytes': str(self.size_in_bytes()),
|
|
460
|
+
'numberOfBytes': str(self.size_in_bytes(storage)),
|
|
436
461
|
'lowerBound': str(self.lower_bound),
|
|
437
462
|
'upperBound': str(self.upper_bound)
|
|
438
463
|
}
|
|
@@ -464,6 +489,20 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
464
489
|
**build_sequence(lambda i: f"bytes{i}", lambda i: 32 + i) # type: ignore
|
|
465
490
|
}
|
|
466
491
|
|
|
492
|
+
vyper_constructor_name = "__init__"
|
|
493
|
+
|
|
494
|
+
@property
|
|
495
|
+
def supports_typed_immutables(self) -> bool:
|
|
496
|
+
return True
|
|
497
|
+
|
|
498
|
+
@property
|
|
499
|
+
def supports_ast_output(self) -> bool:
|
|
500
|
+
return True
|
|
501
|
+
|
|
502
|
+
@property
|
|
503
|
+
def supports_srclist_output(self) -> bool:
|
|
504
|
+
return True
|
|
505
|
+
|
|
467
506
|
@staticmethod
|
|
468
507
|
def extract_constant(ast_node: Dict[str, Any], named_constants: Dict[str, int]) -> int:
|
|
469
508
|
"""
|
|
@@ -509,6 +548,9 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
509
548
|
if value_id == 'String':
|
|
510
549
|
max_bytes = ast_subscript_node['slice']['value']['value']
|
|
511
550
|
return CompilerLangVy.VyperTypeString(max_bytes)
|
|
551
|
+
elif value_id == 'Bytes':
|
|
552
|
+
max_bytes = ast_subscript_node['slice']['value']['value']
|
|
553
|
+
return CompilerLangVy.VyperTypeBytes(max_bytes)
|
|
512
554
|
elif value_id == 'DynArray':
|
|
513
555
|
elem_type = CompilerLangVy.extract_type_from_type_annotation_node(
|
|
514
556
|
ast_subscript_node['slice']['value']['elements'][0], named_constants)
|
|
@@ -626,18 +668,23 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
626
668
|
decorators = [dec['id'] for dec in function_def['decorator_list'] if 'id' in dec] # ignores Call decorators
|
|
627
669
|
|
|
628
670
|
result = []
|
|
671
|
+
is_constructor = function_def['name'] == CompilerLangVy.vyper_constructor_name
|
|
629
672
|
for args in arg_variants:
|
|
630
673
|
arg_names, arg_types = [n for n, t in args], [t for n, t in args] # python's not smart enough to type `zip`
|
|
674
|
+
if not is_constructor:
|
|
675
|
+
func_selector = CompilerLangVy.get_function_selector(function_def['name'], arg_types, is_lib=False)
|
|
676
|
+
else:
|
|
677
|
+
func_selector = "0" # this is the sighash for constructors in Solidity too
|
|
631
678
|
result.append(CompilerLangFunc(
|
|
632
679
|
name = function_def['name'],
|
|
633
|
-
|
|
634
|
-
|
|
680
|
+
fullArgs = arg_types,
|
|
681
|
+
paramNames = arg_names,
|
|
635
682
|
returns = ret_types,
|
|
636
|
-
sighash =
|
|
683
|
+
sighash = func_selector,
|
|
637
684
|
notpayable = "payable" not in decorators,
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
685
|
+
fromLib = False,
|
|
686
|
+
isConstructor = is_constructor,
|
|
687
|
+
stateMutability = first_of(decorators, ["pure", "view", "payable"], default="nonpayable"),
|
|
641
688
|
implemented = True,
|
|
642
689
|
overrides = False,
|
|
643
690
|
visibility = first_of(decorators, ["internal", "external"]),
|
|
@@ -656,14 +703,14 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
656
703
|
|
|
657
704
|
return CompilerLangFunc(
|
|
658
705
|
name = var_name,
|
|
659
|
-
|
|
660
|
-
|
|
706
|
+
fullArgs = arg_types,
|
|
707
|
+
paramNames = [],
|
|
661
708
|
returns = ret_types,
|
|
662
709
|
sighash = CompilerLangVy.get_function_selector(var_name, arg_types, is_lib=False),
|
|
663
710
|
notpayable = True,
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
711
|
+
fromLib = False,
|
|
712
|
+
isConstructor = False,
|
|
713
|
+
stateMutability = "view",
|
|
667
714
|
implemented = True,
|
|
668
715
|
overrides = False,
|
|
669
716
|
visibility = "external",
|
|
@@ -699,15 +746,22 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
699
746
|
result_types = []
|
|
700
747
|
public_vardecls = {}
|
|
701
748
|
named_constants: Dict[str, int] = {}
|
|
749
|
+
|
|
750
|
+
# Process named constants ahead of time, as their use site in the source may precede
|
|
751
|
+
# their definition site, e.g.
|
|
752
|
+
for ast_node in ast_body_nodes.values():
|
|
753
|
+
if ast_node['ast_type'] != 'VariableDecl':
|
|
754
|
+
continue
|
|
755
|
+
if ast_node['is_constant'] and ast_node['value'] is not None and \
|
|
756
|
+
(ast_node['value']['ast_type'] == 'Int'):
|
|
757
|
+
named_constants.update({ast_node['target']['id']: int(ast_node['value']['value'])})
|
|
758
|
+
|
|
702
759
|
for ast_node in ast_body_nodes.values():
|
|
703
760
|
if ast_node['ast_type'] == 'VariableDecl':
|
|
704
761
|
decltype = CompilerLangVy.extract_type_from_variable_decl(ast_node, named_constants)
|
|
705
762
|
result_types.append(decltype)
|
|
706
763
|
if ast_node['is_public']:
|
|
707
764
|
public_vardecls[ast_node['target']['id']] = decltype
|
|
708
|
-
if ast_node['is_constant'] and (ast_node['value'] is not None) and \
|
|
709
|
-
(ast_node['value']['ast_type'] == 'Int'):
|
|
710
|
-
named_constants.update({ast_node['target']['id']: int(ast_node['value']['value'])})
|
|
711
765
|
elif ast_node['ast_type'] == 'StructDef':
|
|
712
766
|
result_types.append(CompilerLangVy.extract_type_from_struct_def(ast_node, named_constants))
|
|
713
767
|
# Not sure if `Import` is an actual ast type. It was already there, so I am not removing it.
|
|
@@ -791,7 +845,7 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
791
845
|
list(CompilerLangVy.primitive_types.values())
|
|
792
846
|
type_descriptors_by_name = {i.get_canonical_vyper_name(): i.get_storage_type_descriptor()
|
|
793
847
|
for i in all_used_types}
|
|
794
|
-
types_field = {i.get_canonical_vyper_name(): i.generate_types_field() for i in all_used_types}
|
|
848
|
+
types_field = {i.get_canonical_vyper_name(): i.generate_types_field(storage=True) for i in all_used_types}
|
|
795
849
|
|
|
796
850
|
def annotate_desc(desc: Dict[Any, Any], type_name: str, all_types: Dict[Any, Any], slot: Any = None,
|
|
797
851
|
offset: Any = None) -> Dict[Any, Any]:
|
|
@@ -968,20 +1022,24 @@ class CompilerLangVy(CompilerLang, metaclass=Singleton):
|
|
|
968
1022
|
solidity_type_args = [get_solidity_type_from_abi(p) for p in params]
|
|
969
1023
|
solidity_type_outs = [get_solidity_type_from_abi(p) for p in out_params]
|
|
970
1024
|
|
|
971
|
-
|
|
1025
|
+
is_constructor = name == CompilerLangVy.vyper_constructor_name
|
|
1026
|
+
if not is_constructor:
|
|
1027
|
+
func_selector = get_function_selector({}, name, solidity_type_args, True)
|
|
1028
|
+
else:
|
|
1029
|
+
func_selector = "0" # this is the sighash for constructors in Solidity too
|
|
972
1030
|
state_mutability = abi_data["stateMutability"]
|
|
973
1031
|
|
|
974
1032
|
funcs.append(
|
|
975
1033
|
CompilerLangFunc(
|
|
976
1034
|
name=name,
|
|
977
|
-
|
|
978
|
-
|
|
1035
|
+
fullArgs=solidity_type_args,
|
|
1036
|
+
paramNames=[],
|
|
979
1037
|
returns=solidity_type_outs,
|
|
980
1038
|
sighash=func_selector,
|
|
981
1039
|
notpayable=state_mutability in ["nonpayable", "view", "pure"],
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
1040
|
+
fromLib=False,
|
|
1041
|
+
isConstructor=is_constructor,
|
|
1042
|
+
stateMutability=state_mutability,
|
|
985
1043
|
implemented=True,
|
|
986
1044
|
overrides=False,
|
|
987
1045
|
# according to Solidity docs, getter functions have external visibility
|