Skip to content

Commit 8344524

Browse files
committed
Merge branch 'dev'
2 parents f11d896 + 4b74b62 commit 8344524

File tree

20,560 files changed

+7181
-2038
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

20,560 files changed

+7181
-2038
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
matrix:
2323
type: ["cli",
2424
"data_dependency",
25-
"embark",
25+
# "embark",
2626
"erc",
2727
"etherlime",
2828
"find_paths",

.github/workflows/features.yml

+1
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,5 @@ jobs:
4444
- name: Test with pytest
4545
run: |
4646
pytest tests/test_features.py
47+
pytest tests/test_constant_folding_unary.py
4748

examples/scripts/convert_to_ir.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121

2222
for node in nodes:
2323
if node.expression:
24-
print("Expression:\n\t{}".format(node.expression))
24+
print(f"Expression:\n\t{node.expression}")
2525
irs = convert_expression(node.expression, node)
2626
print("IR expressions:")
2727
for ir in irs:
28-
print("\t{}".format(ir))
28+
print(f"\t{ir}")
2929
print()

examples/scripts/data_dependency.py

+18-54
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,13 @@
1919
destination = contract.get_state_variable_from_name("destination")
2020
source = contract.get_state_variable_from_name("source")
2121

22-
print(
23-
"{} is dependent of {}: {}".format(
24-
source, destination, is_dependent(source, destination, contract)
25-
)
26-
)
22+
print(f"{source} is dependent of {destination}: {is_dependent(source, destination, contract)}")
2723
assert not is_dependent(source, destination, contract)
28-
print(
29-
"{} is dependent of {}: {}".format(
30-
destination, source, is_dependent(destination, source, contract)
31-
)
32-
)
24+
print(f"{destination} is dependent of {source}: {is_dependent(destination, source, contract)}")
3325
assert is_dependent(destination, source, contract)
34-
print("{} is tainted {}".format(source, is_tainted(source, contract)))
26+
print(f"{source} is tainted {is_tainted(source, contract)}")
3527
assert not is_tainted(source, contract)
36-
print("{} is tainted {}".format(destination, is_tainted(destination, contract)))
28+
print(f"{destination} is tainted {is_tainted(destination, contract)}")
3729
assert is_tainted(destination, contract)
3830

3931
contracts = slither.get_contract_from_name("Reference")
@@ -45,32 +37,20 @@
4537
assert source
4638

4739
print("Reference contract")
48-
print(
49-
"{} is dependent of {}: {}".format(
50-
source, destination, is_dependent(source, destination, contract)
51-
)
52-
)
40+
print(f"{source} is dependent of {destination}: {is_dependent(source, destination, contract)}")
5341
assert not is_dependent(source, destination, contract)
54-
print(
55-
"{} is dependent of {}: {}".format(
56-
destination, source, is_dependent(destination, source, contract)
57-
)
58-
)
42+
print(f"{destination} is dependent of {source}: {is_dependent(destination, source, contract)}")
5943
assert is_dependent(destination, source, contract)
60-
print("{} is tainted {}".format(source, is_tainted(source, contract)))
44+
print(f"{source} is tainted {is_tainted(source, contract)}")
6145
assert not is_tainted(source, contract)
62-
print("{} is tainted {}".format(destination, is_tainted(destination, contract)))
46+
print(f"{destination} is tainted {is_tainted(destination, contract)}")
6347
assert is_tainted(destination, contract)
6448

6549
destination_indirect_1 = contract.get_state_variable_from_name("destination_indirect_1")
66-
print(
67-
"{} is tainted {}".format(destination_indirect_1, is_tainted(destination_indirect_1, contract))
68-
)
50+
print(f"{destination_indirect_1} is tainted {is_tainted(destination_indirect_1, contract)}")
6951
assert is_tainted(destination_indirect_1, contract)
7052
destination_indirect_2 = contract.get_state_variable_from_name("destination_indirect_2")
71-
print(
72-
"{} is tainted {}".format(destination_indirect_2, is_tainted(destination_indirect_2, contract))
73-
)
53+
print(f"{destination_indirect_2} is tainted {is_tainted(destination_indirect_2, contract)}")
7454
assert is_tainted(destination_indirect_2, contract)
7555

7656
print("SolidityVar contract")
@@ -83,13 +63,9 @@
8363
addr_2 = contract.get_state_variable_from_name("addr_2")
8464
assert addr_2
8565
msgsender = SolidityVariableComposed("msg.sender")
86-
print(
87-
"{} is dependent of {}: {}".format(addr_1, msgsender, is_dependent(addr_1, msgsender, contract))
88-
)
66+
print(f"{addr_1} is dependent of {msgsender}: {is_dependent(addr_1, msgsender, contract)}")
8967
assert is_dependent(addr_1, msgsender, contract)
90-
print(
91-
"{} is dependent of {}: {}".format(addr_2, msgsender, is_dependent(addr_2, msgsender, contract))
92-
)
68+
print(f"{addr_2} is dependent of {msgsender}: {is_dependent(addr_2, msgsender, contract)}")
9369
assert not is_dependent(addr_2, msgsender, contract)
9470

9571

@@ -102,11 +78,7 @@
10278
source = contract.get_state_variable_from_name("source")
10379
assert source
10480

105-
print(
106-
"{} is dependent of {}: {}".format(
107-
destination, source, is_dependent(destination, source, contract)
108-
)
109-
)
81+
print(f"{destination} is dependent of {source}: {is_dependent(destination, source, contract)}")
11082
assert is_dependent(destination, source, contract)
11183

11284
print("Base Derived contract")
@@ -117,16 +89,10 @@
11789
destination = contract.get_state_variable_from_name("destination")
11890
source = contract.get_state_variable_from_name("source")
11991

120-
print(
121-
"{} is dependent of {}: {} (base)".format(
122-
destination, source, is_dependent(destination, source, contract)
123-
)
124-
)
92+
print(f"{destination} is dependent of {source}: {is_dependent(destination, source, contract)}")
12593
assert not is_dependent(destination, source, contract)
12694
print(
127-
"{} is dependent of {}: {} (derived)".format(
128-
destination, source, is_dependent(destination, source, contract_derived)
129-
)
95+
f"{destination} is dependent of {source}: {is_dependent(destination, source, contract_derived)}"
13096
)
13197
assert is_dependent(destination, source, contract_derived)
13298

@@ -147,12 +113,10 @@
147113
f2 = contract.get_function_from_signature("f2(uint256,uint256)")
148114

149115
print(
150-
"{} is dependent of {}: {} (base)".format(
151-
var_dependant, user_input, is_dependent(var_dependant, user_input, contract)
152-
)
116+
f"{var_dependant} is dependent of {user_input}: {is_dependent(var_dependant, user_input, contract)} (base)"
153117
)
154118
assert is_dependent(var_dependant, user_input, contract)
155-
print("{} is tainted: {}".format(var_tainted, is_tainted(var_tainted, contract)))
119+
print(f"{var_tainted} is tainted: {is_tainted(var_tainted, contract)}")
156120
assert is_tainted(var_tainted, contract)
157-
print("{} is tainted: {}".format(var_not_tainted, is_tainted(var_not_tainted, contract)))
121+
print(f"{var_not_tainted} is tainted: {is_tainted(var_not_tainted, contract)}")
158122
assert not is_tainted(var_not_tainted, contract)

examples/scripts/export_dominator_tree_to_dot.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@
1111

1212
for contract in slither.contracts:
1313
for function in list(contract.functions) + list(contract.modifiers):
14-
filename = "{}-{}-{}_dom.dot".format(sys.argv[1], contract.name, function.full_name)
15-
print("Export {}".format(filename))
14+
filename = f"{sys.argv[1]}-{contract.name}-{function.full_name}_dom.dot"
15+
print(f"Export {filename}")
1616
function.dominator_tree_to_dot(filename)

examples/scripts/export_to_dot.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@
1111

1212
for contract in slither.contracts:
1313
for function in contract.functions + contract.modifiers:
14-
filename = "{}-{}-{}.dot".format(sys.argv[1], contract.name, function.full_name)
15-
print("Export {}".format(filename))
14+
filename = f"{sys.argv[1]}-{contract.name}-{function.full_name}.dot"
15+
print(f"Export {filename}")
1616
function.slithir_cfg_to_dot(filename)

examples/scripts/functions_called.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@
2222
all_calls_formated = [f.canonical_name for f in all_calls]
2323

2424
# Print the result
25-
print("From entry_point the functions reached are {}".format(all_calls_formated))
25+
print(f"From entry_point the functions reached are {all_calls_formated}")

examples/scripts/functions_writing.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@
1919
functions_writing_a = contract.get_functions_writing_to_variable(var_a)
2020

2121
# Print the result
22-
print('The function writing "a" are {}'.format([f.name for f in functions_writing_a]))
22+
print(f'The function writing "a" are {[f.name for f in functions_writing_a]}')

examples/scripts/slithIR.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# Dont explore inherited functions
1818
if function.contract_declarer == contract:
1919

20-
print("Function: {}".format(function.name))
20+
print(f"Function: {function.name}")
2121

2222
# Iterate over the nodes of the function
2323
for node in function.nodes:
@@ -26,7 +26,7 @@
2626
# And the SlithIR operations
2727
if node.expression:
2828

29-
print("\tSolidity expression: {}".format(node.expression))
29+
print(f"\tSolidity expression: {node.expression}")
3030
print("\tSlithIR:")
3131
for ir in node.irs:
32-
print("\t\t\t{}".format(ir))
32+
print(f"\t\t\t{ir}")

examples/scripts/taint_mapping.py

+8-10
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,17 @@ def visit_node(node, visited):
2626
else:
2727
read = ir.read
2828
print(ir)
29-
print("Refs {}".format(refs))
30-
print("Read {}".format([str(x) for x in ir.read]))
31-
print("Before {}".format([str(x) for x in taints]))
29+
print(f"Refs {refs}")
30+
print(f"Read {[str(x) for x in ir.read]}")
31+
print(f"Before {[str(x) for x in taints]}")
3232
if any(var_read in taints for var_read in read):
3333
taints += [ir.lvalue]
3434
lvalue = ir.lvalue
3535
while isinstance(lvalue, ReferenceVariable):
3636
taints += [refs[lvalue]]
3737
lvalue = refs[lvalue]
3838

39-
print("After {}".format([str(x) for x in taints]))
39+
print(f"After {[str(x) for x in taints]}")
4040
print()
4141

4242
taints = [v for v in taints if not isinstance(v, (TemporaryVariable, ReferenceVariable))]
@@ -52,7 +52,7 @@ def check_call(func, taints):
5252
for ir in node.irs:
5353
if isinstance(ir, HighLevelCall):
5454
if ir.destination in taints:
55-
print("Call to tainted address found in {}".format(function.name))
55+
print(f"Call to tainted address found in {function.name}")
5656

5757

5858
if __name__ == "__main__":
@@ -74,16 +74,14 @@ def check_call(func, taints):
7474
prev_taints = slither.context[KEY]
7575
for contract in slither.contracts:
7676
for function in contract.functions:
77-
print("Function {}".format(function.name))
77+
print(f"Function {function.name}")
7878
slither.context[KEY] = list(set(slither.context[KEY] + function.parameters))
7979
visit_node(function.entry_point, [])
80-
print("All variables tainted : {}".format([str(v) for v in slither.context[KEY]]))
80+
print(f"All variables tainted : {[str(v) for v in slither.context[KEY]]}")
8181

8282
for function in contract.functions:
8383
check_call(function, slither.context[KEY])
8484

8585
print(
86-
"All state variables tainted : {}".format(
87-
[str(v) for v in prev_taints if isinstance(v, StateVariable)]
88-
)
86+
f"All state variables tainted : {[str(v) for v in prev_taints if isinstance(v, StateVariable)]}"
8987
)

examples/scripts/variable_in_condition.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,4 @@
2525
]
2626

2727
# Print the result
28-
print(
29-
'The function using "a" in condition are {}'.format(
30-
[f.name for f in function_using_a_as_condition]
31-
)
32-
)
28+
print(f'The function using "a" in condition are {[f.name for f in function_using_a_as_condition]}')

pyproject.toml

+1-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,5 @@ logging-fstring-interpolation,
1818
logging-not-lazy,
1919
duplicate-code,
2020
import-error,
21-
unsubscriptable-object,
22-
consider-using-f-string
21+
unsubscriptable-object
2322
"""

slither/__main__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ def choose_detectors(args, all_detector_classes):
208208
if detector in detectors:
209209
detectors_to_run.append(detectors[detector])
210210
else:
211-
raise Exception("Error: {} is not a detector".format(detector))
211+
raise Exception(f"Error: {detector} is not a detector")
212212
detectors_to_run = sorted(detectors_to_run, key=lambda x: x.IMPACT)
213213
return detectors_to_run
214214

slither/analyses/data_dependency/data_dependency.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -268,15 +268,15 @@ def pprint_dependency(caller_context: Context_types) -> None:
268268
print("#### SSA ####")
269269
context = caller_context.context
270270
for k, values in context[KEY_SSA].items():
271-
print("{} ({}):".format(k, id(k)))
271+
print(f"{k} ({id(k)}):")
272272
for v in values:
273-
print("\t- {}".format(v))
273+
print(f"\t- {v}")
274274

275275
print("#### NON SSA ####")
276276
for k, values in context[KEY_NON_SSA].items():
277-
print("{} ({}):".format(k, hex(id(k))))
277+
print(f"{k} ({hex(id(k))}):")
278278
for v in values:
279-
print("\t- {} ({})".format(v, hex(id(v))))
279+
print(f"\t- {v} ({hex(id(v))})")
280280

281281

282282
# endregion

slither/core/cfg/node.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ def __str__(self):
140140
return "END_LOOP"
141141
if self == NodeType.OTHER_ENTRYPOINT:
142142
return "OTHER_ENTRYPOINT"
143-
return "Unknown type {}".format(hex(self.value))
143+
return f"Unknown type {hex(self.value)}"
144144

145145

146146
# endregion

slither/core/declarations/contract.py

+26-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
ERC1820_signatures,
2121
ERC777_signatures,
2222
ERC1155_signatures,
23+
ERC2612_signatures,
24+
ERC4626_signatures,
2325
)
2426
from slither.utils.tests_pattern import is_test_contract
2527

@@ -73,7 +75,7 @@ def __init__(self, compilation_unit: "SlitherCompilationUnit", scope: "FileScope
7375
self._custom_errors: Dict[str, "CustomErrorContract"] = {}
7476

7577
# The only str is "*"
76-
self._using_for: Dict[Union[str, Type], List[str]] = {}
78+
self._using_for: Dict[Union[str, Type], List[Type]] = {}
7779
self._kind: Optional[str] = None
7880
self._is_interface: bool = False
7981

@@ -243,7 +245,7 @@ def events_as_dict(self) -> Dict[str, "Event"]:
243245
###################################################################################
244246

245247
@property
246-
def using_for(self) -> Dict[Union[str, Type], List[str]]:
248+
def using_for(self) -> Dict[Union[str, Type], List[Type]]:
247249
return self._using_for
248250

249251
# endregion
@@ -900,6 +902,8 @@ def ercs(self) -> List[str]:
900902
("ERC223", self.is_erc223),
901903
("ERC721", self.is_erc721),
902904
("ERC777", self.is_erc777),
905+
("ERC2612", self.is_erc2612),
906+
("ERC4626", self.is_erc4626),
903907
]
904908

905909
return [erc for erc, is_erc in all_erc if is_erc()]
@@ -974,6 +978,26 @@ def is_erc1155(self) -> bool:
974978
full_names = self.functions_signatures
975979
return all(s in full_names for s in ERC1155_signatures)
976980

981+
def is_erc4626(self) -> bool:
982+
"""
983+
Check if the contract is an erc4626
984+
985+
Note: it does not check for correct return values
986+
:return: Returns a true if the contract is an erc4626
987+
"""
988+
full_names = self.functions_signatures
989+
return all(s in full_names for s in ERC4626_signatures)
990+
991+
def is_erc2612(self) -> bool:
992+
"""
993+
Check if the contract is an erc2612
994+
995+
Note: it does not check for correct return values
996+
:return: Returns a true if the contract is an erc2612
997+
"""
998+
full_names = self.functions_signatures
999+
return all(s in full_names for s in ERC2612_signatures)
1000+
9771001
@property
9781002
def is_token(self) -> bool:
9791003
"""

0 commit comments

Comments
 (0)