Skip to content

Commit 3bb3141

Browse files
committed
fix test setup, refactor default config for classes
1 parent 61f1fe8 commit 3bb3141

File tree

4 files changed

+41
-52
lines changed

4 files changed

+41
-52
lines changed

fuzz_utils/generate/FoundryTest.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
"""The FoundryTest class that handles generation of unit tests from call sequences"""
22
import os
33
import json
4+
import copy
45
from typing import Any
56
import jinja2
67

78
from slither import Slither
89
from fuzz_utils.utils.crytic_print import CryticPrint
910
from fuzz_utils.utils.slither_utils import get_target_contract
11+
from fuzz_utils.templates.default_config import default_config
1012

1113
from fuzz_utils.generate.fuzzers.Medusa import Medusa
1214
from fuzz_utils.generate.fuzzers.Echidna import Echidna
@@ -18,19 +20,20 @@ class FoundryTest:
1820
Handles the generation of Foundry test files
1921
"""
2022

23+
config: dict = copy.deepcopy(default_config["generate"])
24+
2125
def __init__(
2226
self,
2327
config: dict,
2428
slither: Slither,
2529
fuzzer: Echidna | Medusa,
2630
) -> None:
27-
self.inheritance_path = config["inheritancePath"]
28-
self.target_name = config["targetContract"]
29-
self.corpus_path = config["corpusDir"]
30-
self.test_dir = config["testsDir"]
31-
self.all_sequences = config["allSequences"]
3231
self.slither = slither
33-
self.target = get_target_contract(self.slither, self.target_name)
32+
for key, value in config.items():
33+
if key in self.config:
34+
self.config[key] = value
35+
36+
self.target = get_target_contract(self.slither, self.config["targetContract"])
3437
self.target_file_name = self.target.source_mapping.filename.relative.split("/")[-1]
3538
self.fuzzer = fuzzer
3639

@@ -40,7 +43,7 @@ def create_poc(self) -> str:
4043
file_list: list[dict[str, Any]] = []
4144
tests_list = []
4245
dir_list = []
43-
if self.all_sequences:
46+
if self.config["allSequences"]:
4447
dir_list = self.fuzzer.corpus_dirs
4548
else:
4649
dir_list = [self.fuzzer.reproducer_dir]
@@ -68,13 +71,12 @@ def create_poc(self) -> str:
6871

6972
# 4. Generate the test file
7073
template = jinja2.Template(templates["CONTRACT"])
71-
write_path = os.path.join(self.test_dir, self.target_name)
72-
inheritance_path = os.path.join(self.inheritance_path)
73-
print("INHERITANCE PATH", inheritance_path)
74+
write_path = os.path.join(self.config["testsDir"], self.config["targetContract"])
75+
inheritance_path = os.path.join(self.config["inheritancePath"])
7476
# 5. Save the test file
7577
test_file_str = template.render(
7678
file_path=inheritance_path,
77-
target_name=self.target_name,
79+
target_name=self.config["targetContract"],
7880
amount=0,
7981
tests=tests_list,
8082
fuzzer=self.fuzzer.name,

fuzz_utils/parsing/commands/generate.py

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -102,26 +102,7 @@ def generate_command(args: Namespace) -> None:
102102
slither = Slither(args.compilation_path)
103103
fuzzer: Echidna | Medusa
104104

105-
# Derive target if it is not defined but the compilationPath only contains one contract
106-
if "targetContract" not in config or len(config["targetContract"]) == 0:
107-
if len(slither.contracts_derived) == 1:
108-
config["targetContract"] = slither.contracts_derived[0].name
109-
CryticPrint().print_information(
110-
f"Target contract not specified. Using derived target: {config['targetContract']}."
111-
)
112-
else:
113-
handle_exit(
114-
"Target contract cannot be determined. Please specify the target with `-c targetName`"
115-
)
116-
117-
# Derive inheritance path if it is not defined
118-
if "inheritancePath" not in config or len(config["inheritancePath"]) == 0:
119-
contract = get_target_contract(slither, config["targetContract"])
120-
contract_path = Path(contract.source_mapping.filename.relative)
121-
tests_path = Path(config["testsDir"])
122-
config["inheritancePath"] = str(
123-
Path(*([".." * len(tests_path.parts)])).joinpath(contract_path)
124-
)
105+
derive_config(slither, config)
125106

126107
match config["fuzzer"]:
127108
case "echidna":
@@ -143,3 +124,27 @@ def generate_command(args: Namespace) -> None:
143124
foundry_test = FoundryTest(config, slither, fuzzer)
144125
foundry_test.create_poc()
145126
CryticPrint().print_success("Done!")
127+
128+
129+
def derive_config(slither: Slither, config: dict) -> None:
130+
"""Derive values for the target contract and inheritance path"""
131+
# Derive target if it is not defined but the compilationPath only contains one contract
132+
if "targetContract" not in config or len(config["targetContract"]) == 0:
133+
if len(slither.contracts_derived) == 1:
134+
config["targetContract"] = slither.contracts_derived[0].name
135+
CryticPrint().print_information(
136+
f"Target contract not specified. Using derived target: {config['targetContract']}."
137+
)
138+
else:
139+
handle_exit(
140+
"Target contract cannot be determined. Please specify the target with `-c targetName`"
141+
)
142+
143+
# Derive inheritance path if it is not defined
144+
if "inheritancePath" not in config or len(config["inheritancePath"]) == 0:
145+
contract = get_target_contract(slither, config["targetContract"])
146+
contract_path = Path(contract.source_mapping.filename.relative)
147+
tests_path = Path(config["testsDir"])
148+
config["inheritancePath"] = str(
149+
Path(*([".." * len(tests_path.parts)])).joinpath(contract_path)
150+
)

fuzz_utils/template/HarnessGenerator.py

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from fuzz_utils.utils.error_handler import handle_exit
1616
from fuzz_utils.utils.slither_utils import get_target_contract
1717
from fuzz_utils.templates.harness_templates import templates
18+
from fuzz_utils.templates.default_config import default_config
1819

1920
# pylint: disable=too-many-instance-attributes
2021
@dataclass
@@ -76,26 +77,7 @@ class HarnessGenerator:
7677
Handles the generation of Foundry test files from Echidna reproducers
7778
"""
7879

79-
config: dict = {
80-
"name": "DefaultHarness",
81-
"compilationPath": ".",
82-
"targets": [],
83-
"outputDir": "./test/fuzzing",
84-
"actors": [
85-
{
86-
"name": "Default",
87-
"targets": [],
88-
"number": 3,
89-
"filters": {
90-
"strict": False,
91-
"onlyModifiers": [],
92-
"onlyPayable": False,
93-
"onlyExternalCalls": [],
94-
},
95-
}
96-
],
97-
"attacks": [],
98-
}
80+
config: dict = copy.deepcopy(default_config["template"])
9981

10082
def __init__(
10183
self,

tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def __init__(self, target: str, target_path: str, corpus_dir: str):
2323
medusa = Medusa(target, f"medusa-corpora/{corpus_dir}", slither, False)
2424
config = {
2525
"targetContract": target,
26-
"inheritancePath": "../src/",
26+
"inheritancePath": f"../src/{target}.sol",
2727
"corpusDir": f"echidna-corpora/{corpus_dir}",
2828
"testsDir": "./test/",
2929
"allSequences": False,

0 commit comments

Comments
 (0)