mirror of https://github.com/crytic/slither
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
2.5 KiB
68 lines
2.5 KiB
import os
|
|
import json
|
|
import re
|
|
|
|
from solc_select import solc_select
|
|
from deepdiff import DeepDiff
|
|
|
|
from slither import Slither
|
|
from slither.core.declarations import Function
|
|
from slither.core.variables import StateVariable
|
|
from slither.utils.upgradeability import compare
|
|
|
|
SLITHER_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
UPGRADE_TEST_ROOT = os.path.join(SLITHER_ROOT, "tests", "upgradeability-util")
|
|
|
|
|
|
# pylint: disable=too-many-locals
|
|
def test_upgrades_compare() -> None:
|
|
solc_select.switch_global_version("0.8.2", always_install=True)
|
|
|
|
sl = Slither(os.path.join(UPGRADE_TEST_ROOT, "TestUpgrades.sol"))
|
|
v1 = sl.get_contract_from_name("ContractV1")[0]
|
|
v2 = sl.get_contract_from_name("ContractV2")[0]
|
|
diff_dict = compare(v1, v2)
|
|
for key, lst in diff_dict.items():
|
|
if len(lst) > 0:
|
|
print(f' * {str(key).replace("-", " ")}:')
|
|
for obj in lst:
|
|
if isinstance(obj, StateVariable):
|
|
print(f" * {obj.full_name}")
|
|
elif isinstance(obj, Function):
|
|
print(f" * {obj.signature_str}")
|
|
with open("upgrade_diff.json", "w", encoding="utf-8") as file:
|
|
json_str = diff_to_json_str(diff_dict)
|
|
diff_json = json.loads(json_str)
|
|
json.dump(diff_json, file, indent=4)
|
|
|
|
expected_file = os.path.join(UPGRADE_TEST_ROOT, "TEST_upgrade_diff.json")
|
|
actual_file = os.path.join(SLITHER_ROOT, "upgrade_diff.json")
|
|
|
|
with open(expected_file, "r", encoding="utf8") as f:
|
|
expected = json.load(f)
|
|
with open(actual_file, "r", encoding="utf8") as f:
|
|
actual = json.load(f)
|
|
|
|
diff = DeepDiff(expected, actual, ignore_order=True, verbose_level=2, view="tree")
|
|
if diff:
|
|
for change in diff.get("values_changed", []):
|
|
path_list = re.findall(r"\['(.*?)'\]", change.path())
|
|
path = "_".join(path_list)
|
|
with open(f"{path}_expected.txt", "w", encoding="utf8") as f:
|
|
f.write(str(change.t1))
|
|
with open(f"{path}_actual.txt", "w", encoding="utf8") as f:
|
|
f.write(str(change.t2))
|
|
|
|
assert not diff
|
|
|
|
|
|
def diff_to_json_str(diff: dict) -> str:
|
|
out: dict = {}
|
|
for key in diff.keys():
|
|
out[key] = []
|
|
for obj in diff[key]:
|
|
if isinstance(obj, StateVariable):
|
|
out[key].append(obj.canonical_name)
|
|
elif isinstance(obj, Function):
|
|
out[key].append(obj.signature_str)
|
|
return str(out).replace("'", '"')
|
|
|