Static Analyzer for Solidity
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.
 
 
 
 
slither/tests/test_upgradeability_util.py

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("'", '"')