mirror of https://github.com/crytic/slither
commit
353d4da401
@ -0,0 +1,25 @@ |
||||
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json |
||||
language: "en" |
||||
early_access: false |
||||
knowledge_base: |
||||
learnings: |
||||
scope: auto |
||||
issues: |
||||
scope: global |
||||
reviews: |
||||
profile: "chill" |
||||
request_changes_workflow: false |
||||
high_level_summary: true |
||||
poem: false |
||||
review_status: true |
||||
collapse_walkthrough: true |
||||
auto_review: |
||||
enabled: true |
||||
ignore_title_keywords: |
||||
- "WIP" |
||||
- "DO NOT MERGE" |
||||
drafts: false |
||||
base_branches: |
||||
- dev |
||||
chat: |
||||
auto_reply: true |
@ -1,84 +0,0 @@ |
||||
#!/usr/bin/env bash |
||||
|
||||
### Test Detectors |
||||
|
||||
DIR="$(cd "$(dirname "$0")" && pwd)" |
||||
|
||||
CURRENT_PATH=$(pwd) |
||||
TRAVIS_PATH='/home/travis/build/crytic/slither' |
||||
|
||||
# test_slither file.sol detectors |
||||
test_slither(){ |
||||
|
||||
expected="$DIR/../tests/expected_json/$(basename "$1" .sol).$2.json" |
||||
|
||||
# run slither detector on input file and save output as json |
||||
if ! slither "$1" --solc-disable-warnings --detect "$2" --json "$DIR/tmp-test.json"; |
||||
then |
||||
echo "Slither crashed" |
||||
exit 255 |
||||
fi |
||||
|
||||
if [ ! -f "$DIR/tmp-test.json" ]; then |
||||
echo "" |
||||
echo "Missing generated file" |
||||
echo "" |
||||
exit 1 |
||||
fi |
||||
sed "s|$CURRENT_PATH|$TRAVIS_PATH|g" "$DIR/tmp-test.json" -i |
||||
result=$(python "$DIR/json_diff.py" "$expected" "$DIR/tmp-test.json") |
||||
|
||||
rm "$DIR/tmp-test.json" |
||||
if [ "$result" != "{}" ]; then |
||||
echo "" |
||||
echo "failed test of file: $1, detector: $2" |
||||
echo "" |
||||
echo "$result" |
||||
echo "" |
||||
exit 1 |
||||
fi |
||||
|
||||
# run slither detector on input file and save output as json |
||||
if ! slither "$1" --solc-disable-warnings --detect "$2" --legacy-ast --json "$DIR/tmp-test.json"; |
||||
then |
||||
echo "Slither crashed" |
||||
exit 255 |
||||
fi |
||||
|
||||
if [ ! -f "$DIR/tmp-test.json" ]; then |
||||
echo "" |
||||
echo "Missing generated file" |
||||
echo "" |
||||
exit 1 |
||||
fi |
||||
|
||||
sed "s|$CURRENT_PATH|$TRAVIS_PATH|g" "$DIR/tmp-test.json" -i |
||||
result=$(python "$DIR/json_diff.py" "$expected" "$DIR/tmp-test.json") |
||||
|
||||
rm "$DIR/tmp-test.json" |
||||
if [ "$result" != "{}" ]; then |
||||
echo "" |
||||
echo "failed test of file: $1, detector: $2" |
||||
echo "" |
||||
echo "$result" |
||||
echo "" |
||||
exit 1 |
||||
fi |
||||
} |
||||
|
||||
# generate_expected_json file.sol detectors |
||||
generate_expected_json(){ |
||||
# generate output filename |
||||
# e.g. file: uninitialized.sol detector: uninitialized-state |
||||
# ---> uninitialized.uninitialized-state.json |
||||
output_filename="$DIR/../tests/expected_json/$(basename "$1" .sol).$2.json" |
||||
output_filename_txt="$DIR/../tests/expected_json/$(basename "$1" .sol).$2.txt" |
||||
|
||||
# run slither detector on input file and save output as json |
||||
slither "$1" --solc-disable-warnings --detect "$2" --json "$output_filename" > "$output_filename_txt" 2>&1 |
||||
|
||||
|
||||
sed "s|$CURRENT_PATH|$TRAVIS_PATH|g" "$output_filename" -i |
||||
sed "s|$CURRENT_PATH|$TRAVIS_PATH|g" "$output_filename_txt" -i |
||||
} |
||||
|
@ -1,27 +0,0 @@ |
||||
import sys |
||||
import json |
||||
from pprint import pprint |
||||
from deepdiff import DeepDiff # pip install deepdiff |
||||
|
||||
|
||||
if len(sys.argv) != 3: |
||||
print("Usage: python json_diff.py 1.json 2.json") |
||||
sys.exit(-1) |
||||
|
||||
with open(sys.argv[1], encoding="utf8") as f: |
||||
d1 = json.load(f) |
||||
|
||||
with open(sys.argv[2], encoding="utf8") as f: |
||||
d2 = json.load(f) |
||||
|
||||
|
||||
# Remove description field to allow non deterministic print |
||||
for elem in d1: |
||||
if "description" in elem: |
||||
del elem["description"] |
||||
for elem in d2: |
||||
if "description" in elem: |
||||
del elem["description"] |
||||
|
||||
|
||||
pprint(DeepDiff(d1, d2, ignore_order=True, verbose_level=2)) |
@ -1,106 +0,0 @@ |
||||
""" |
||||
Check for state variables too similar |
||||
Do not check contract inheritance |
||||
""" |
||||
import difflib |
||||
from typing import List, Set, Tuple |
||||
|
||||
from slither.core.declarations.contract import Contract |
||||
from slither.core.variables.local_variable import LocalVariable |
||||
from slither.detectors.abstract_detector import ( |
||||
AbstractDetector, |
||||
DetectorClassification, |
||||
DETECTOR_INFO, |
||||
) |
||||
from slither.utils.output import Output |
||||
|
||||
|
||||
class SimilarVarsDetection(AbstractDetector): |
||||
""" |
||||
Variable similar detector |
||||
""" |
||||
|
||||
ARGUMENT = "similar-names" |
||||
HELP = "Variable names are too similar" |
||||
IMPACT = DetectorClassification.INFORMATIONAL |
||||
CONFIDENCE = DetectorClassification.MEDIUM |
||||
|
||||
WIKI = ( |
||||
"https://github.com/crytic/slither/wiki/Detector-Documentation#variable-names-too-similar" |
||||
) |
||||
|
||||
WIKI_TITLE = "Variable names too similar" |
||||
WIKI_DESCRIPTION = "Detect variables with names that are too similar." |
||||
WIKI_EXPLOIT_SCENARIO = "Bob uses several variables with similar names. As a result, his code is difficult to review." |
||||
WIKI_RECOMMENDATION = "Prevent variables from having similar names." |
||||
|
||||
@staticmethod |
||||
def similar(seq1: str, seq2: str) -> bool: |
||||
"""Test the name similarity |
||||
|
||||
Two name are similar if difflib.SequenceMatcher on the lowercase |
||||
version of the name is greater than 0.90 |
||||
See: https://docs.python.org/2/library/difflib.html |
||||
Args: |
||||
seq1 (str): first name |
||||
seq2 (str): second name |
||||
Returns: |
||||
bool: true if names are similar |
||||
""" |
||||
val = difflib.SequenceMatcher(a=seq1, b=seq2).ratio() |
||||
ret = val > 0.90 |
||||
return ret |
||||
|
||||
@staticmethod |
||||
def detect_sim(contract: Contract) -> Set[Tuple[LocalVariable, LocalVariable]]: |
||||
"""Detect variables with similar name |
||||
|
||||
Returns: |
||||
bool: true if variables have similar name |
||||
""" |
||||
all_var = [x.variables for x in contract.functions] |
||||
all_var = [x for l in all_var for x in l] |
||||
|
||||
contract_var = contract.variables |
||||
|
||||
all_var = list(set(all_var + contract_var)) |
||||
|
||||
ret = set() |
||||
# pylint: disable=consider-using-enumerate |
||||
for i in range(len(all_var)): |
||||
v1 = all_var[i] |
||||
_v1_name_lower = v1.name.lower() |
||||
for j in range(i, len(all_var)): |
||||
v2 = all_var[j] |
||||
if len(v1.name) != len(v2.name): |
||||
continue |
||||
_v2_name_lower = v2.name.lower() |
||||
if _v1_name_lower != _v2_name_lower: |
||||
if SimilarVarsDetection.similar(_v1_name_lower, _v2_name_lower): |
||||
ret.add((v1, v2)) |
||||
|
||||
return ret |
||||
|
||||
def _detect(self) -> List[Output]: |
||||
"""Detect similar variables name |
||||
|
||||
Returns: |
||||
list: {'vuln', 'filename,'contract','vars'} |
||||
""" |
||||
results = [] |
||||
for c in self.contracts: |
||||
allVars = self.detect_sim(c) |
||||
if allVars: |
||||
for (v1, v2) in sorted(allVars, key=lambda x: (x[0].name, x[1].name)): |
||||
v_left = v1 if v1.name < v2.name else v2 |
||||
v_right = v2 if v_left == v1 else v1 |
||||
info: DETECTOR_INFO = [ |
||||
"Variable ", |
||||
v_left, |
||||
" is too similar to ", |
||||
v_right, |
||||
"\n", |
||||
] |
||||
json = self.generate_result(info) |
||||
results.append(json) |
||||
return results |
@ -1,5 +1,5 @@ |
||||
# slither-documentation |
||||
|
||||
`slither-documentation` uses [codex](https://beta.openai.com) to generate natspec documenation. |
||||
`slither-documentation` uses [codex](https://platform.openai.com) to generate natspec documenation. |
||||
|
||||
This tool is experimental. See [solmate documentation](https://github.com/montyly/solmate/pull/1) for an example of usage. |
||||
|
@ -0,0 +1,3 @@ |
||||
# Foundry |
||||
|
||||
To init this test case, run `forge install --no-commit --no-git foundry-rs/forge-std` |
@ -0,0 +1,6 @@ |
||||
[profile.default] |
||||
src = "src" |
||||
out = "out" |
||||
libs = ["lib"] |
||||
|
||||
# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options |
@ -0,0 +1,16 @@ |
||||
// SPDX-License-Identifier: UNLICENSED |
||||
pragma solidity ^0.8.13; |
||||
|
||||
contract Counter { |
||||
uint256 public number; |
||||
|
||||
function setNumber(uint256 newNumber) public { |
||||
number = newNumber; |
||||
} |
||||
|
||||
//START |
||||
function increment() public { |
||||
number++; |
||||
} |
||||
//END |
||||
} |
@ -0,0 +1,40 @@ |
||||
from pathlib import Path |
||||
import shutil |
||||
import re |
||||
|
||||
import pytest |
||||
|
||||
from slither import Slither |
||||
from slither.exceptions import SlitherException |
||||
|
||||
|
||||
TEST_DATA_DIR = Path(__file__).resolve().parent / "test_data" |
||||
|
||||
foundry_available = shutil.which("forge") is not None |
||||
project_ready = Path(TEST_DATA_DIR, "test_change/lib/forge-std").exists() |
||||
|
||||
|
||||
@pytest.mark.skipif( |
||||
not foundry_available or not project_ready, reason="requires Foundry and project setup" |
||||
) |
||||
def test_diagnostic(): |
||||
|
||||
test_file_directory = TEST_DATA_DIR / "test_change" |
||||
|
||||
sl = Slither(test_file_directory.as_posix()) |
||||
assert len(sl.compilation_units) == 1 |
||||
|
||||
counter_file = test_file_directory / "src" / "Counter.sol" |
||||
shutil.copy(counter_file, counter_file.with_suffix(".bak")) |
||||
|
||||
with counter_file.open("r") as file: |
||||
content = file.read() |
||||
|
||||
with counter_file.open("w") as file: |
||||
file.write(re.sub(r"//START.*?//END\n?", "", content, flags=re.DOTALL)) |
||||
|
||||
with pytest.raises(SlitherException): |
||||
Slither(test_file_directory.as_posix(), ignore_compile=True) |
||||
|
||||
# Restore the original counter so the test is idempotent |
||||
Path(counter_file.with_suffix(".bak")).rename(counter_file) |
@ -1,6 +1,6 @@ |
||||
2 different versions of Solidity are used: |
||||
- Version constraint ^0.4.25 is used by: |
||||
- tests/e2e/detectors/test_data/pragma/0.4.25/pragma.0.4.25.sol#1 |
||||
-^0.4.25 (tests/e2e/detectors/test_data/pragma/0.4.25/pragma.0.4.25.sol#1) |
||||
- Version constraint ^0.4.24 is used by: |
||||
- tests/e2e/detectors/test_data/pragma/0.4.25/pragma.0.4.24.sol#1 |
||||
-^0.4.24 (tests/e2e/detectors/test_data/pragma/0.4.25/pragma.0.4.24.sol#1) |
||||
|
||||
|
@ -1,6 +1,6 @@ |
||||
2 different versions of Solidity are used: |
||||
- Version constraint ^0.5.16 is used by: |
||||
- tests/e2e/detectors/test_data/pragma/0.5.16/pragma.0.5.16.sol#1 |
||||
-^0.5.16 (tests/e2e/detectors/test_data/pragma/0.5.16/pragma.0.5.16.sol#1) |
||||
- Version constraint ^0.5.15 is used by: |
||||
- tests/e2e/detectors/test_data/pragma/0.5.16/pragma.0.5.15.sol#1 |
||||
-^0.5.15 (tests/e2e/detectors/test_data/pragma/0.5.16/pragma.0.5.15.sol#1) |
||||
|
||||
|
@ -1,6 +1,6 @@ |
||||
2 different versions of Solidity are used: |
||||
- Version constraint ^0.6.11 is used by: |
||||
- tests/e2e/detectors/test_data/pragma/0.6.11/pragma.0.6.11.sol#1 |
||||
-^0.6.11 (tests/e2e/detectors/test_data/pragma/0.6.11/pragma.0.6.11.sol#1) |
||||
- Version constraint ^0.6.10 is used by: |
||||
- tests/e2e/detectors/test_data/pragma/0.6.11/pragma.0.6.10.sol#1 |
||||
-^0.6.10 (tests/e2e/detectors/test_data/pragma/0.6.11/pragma.0.6.10.sol#1) |
||||
|
||||
|
@ -1,6 +1,6 @@ |
||||
2 different versions of Solidity are used: |
||||
- Version constraint ^0.7.6 is used by: |
||||
- tests/e2e/detectors/test_data/pragma/0.7.6/pragma.0.7.6.sol#1 |
||||
-^0.7.6 (tests/e2e/detectors/test_data/pragma/0.7.6/pragma.0.7.6.sol#1) |
||||
- Version constraint ^0.7.5 is used by: |
||||
- tests/e2e/detectors/test_data/pragma/0.7.6/pragma.0.7.5.sol#1 |
||||
-^0.7.5 (tests/e2e/detectors/test_data/pragma/0.7.6/pragma.0.7.5.sol#1) |
||||
|
||||
|
@ -1,6 +1,6 @@ |
||||
Version constraint >=0.7.0<=0.7.6 is too complex. |
||||
It is used by: |
||||
- tests/e2e/detectors/test_data/solc-version/0.7.6/dynamic_2.sol#1 |
||||
|
||||
solc-0.7.6 is an outdated solc version. Use a more recent version (at least 0.8.0), if possible. |
||||
|
||||
Version constraint >=0.7.0<=0.7.6 is too complex. |
||||
It is used by: |
||||
- >=0.7.0<=0.7.6 (tests/e2e/detectors/test_data/solc-version/0.7.6/dynamic_2.sol#1) |
||||
|
||||
|
@ -1,2 +0,0 @@ |
||||
Variable Similar.f().testVariable (tests/e2e/detectors/test_data/similar-names/0.4.25/similar_variables.sol#3) is too similar to Similar.f().textVariable (tests/e2e/detectors/test_data/similar-names/0.4.25/similar_variables.sol#4) |
||||
|
@ -1,2 +0,0 @@ |
||||
Variable Similar.f().testVariable (tests/e2e/detectors/test_data/similar-names/0.5.16/similar_variables.sol#3) is too similar to Similar.f().textVariable (tests/e2e/detectors/test_data/similar-names/0.5.16/similar_variables.sol#4) |
||||
|
@ -1,2 +0,0 @@ |
||||
Variable Similar.f().testVariable (tests/e2e/detectors/test_data/similar-names/0.6.11/similar_variables.sol#3) is too similar to Similar.f().textVariable (tests/e2e/detectors/test_data/similar-names/0.6.11/similar_variables.sol#4) |
||||
|
@ -1,2 +0,0 @@ |
||||
Variable Similar.f().testVariable (tests/e2e/detectors/test_data/similar-names/0.7.6/similar_variables.sol#3) is too similar to Similar.f().textVariable (tests/e2e/detectors/test_data/similar-names/0.7.6/similar_variables.sol#4) |
||||
|
@ -0,0 +1 @@ |
||||
AnyInitializer (tests/e2e/detectors/test_data/unprotected-upgrade/0.4.25/AnyInitializer.sol#3-15) is an upgradeable contract that does not protect its initialize functions: AnyInitializer.anyName() (tests/e2e/detectors/test_data/unprotected-upgrade/0.4.25/AnyInitializer.sol#6-9). Anyone can delete the contract with: AnyInitializer.kill() (tests/e2e/detectors/test_data/unprotected-upgrade/0.4.25/AnyInitializer.sol#11-14) |
@ -0,0 +1 @@ |
||||
Reinitializer (tests/e2e/detectors/test_data/unprotected-upgrade/0.4.25/Reinitializer.sol#3-15) is an upgradeable contract that does not protect its initialize functions: Reinitializer.initialize() (tests/e2e/detectors/test_data/unprotected-upgrade/0.4.25/Reinitializer.sol#6-9). Anyone can delete the contract with: Reinitializer.kill() (tests/e2e/detectors/test_data/unprotected-upgrade/0.4.25/Reinitializer.sol#11-14) |
@ -0,0 +1 @@ |
||||
AnyInitializer (tests/e2e/detectors/test_data/unprotected-upgrade/0.5.16/AnyInitializer.sol#3-15) is an upgradeable contract that does not protect its initialize functions: AnyInitializer.anyName() (tests/e2e/detectors/test_data/unprotected-upgrade/0.5.16/AnyInitializer.sol#6-9). Anyone can delete the contract with: AnyInitializer.kill() (tests/e2e/detectors/test_data/unprotected-upgrade/0.5.16/AnyInitializer.sol#11-14) |
@ -0,0 +1 @@ |
||||
Reinitializer (tests/e2e/detectors/test_data/unprotected-upgrade/0.5.16/Reinitializer.sol#3-15) is an upgradeable contract that does not protect its initialize functions: Reinitializer.initialize() (tests/e2e/detectors/test_data/unprotected-upgrade/0.5.16/Reinitializer.sol#6-9). Anyone can delete the contract with: Reinitializer.kill() (tests/e2e/detectors/test_data/unprotected-upgrade/0.5.16/Reinitializer.sol#11-14) |
@ -0,0 +1 @@ |
||||
AnyInitializer (tests/e2e/detectors/test_data/unprotected-upgrade/0.6.11/AnyInitializer.sol#3-15) is an upgradeable contract that does not protect its initialize functions: AnyInitializer.anyName() (tests/e2e/detectors/test_data/unprotected-upgrade/0.6.11/AnyInitializer.sol#6-9). Anyone can delete the contract with: AnyInitializer.kill() (tests/e2e/detectors/test_data/unprotected-upgrade/0.6.11/AnyInitializer.sol#11-14) |
@ -0,0 +1 @@ |
||||
Reinitializer (tests/e2e/detectors/test_data/unprotected-upgrade/0.6.11/Reinitializer.sol#3-15) is an upgradeable contract that does not protect its initialize functions: Reinitializer.initialize() (tests/e2e/detectors/test_data/unprotected-upgrade/0.6.11/Reinitializer.sol#6-9). Anyone can delete the contract with: Reinitializer.kill() (tests/e2e/detectors/test_data/unprotected-upgrade/0.6.11/Reinitializer.sol#11-14) |
@ -0,0 +1 @@ |
||||
AnyInitializer (tests/e2e/detectors/test_data/unprotected-upgrade/0.7.6/AnyInitializer.sol#3-15) is an upgradeable contract that does not protect its initialize functions: AnyInitializer.anyName() (tests/e2e/detectors/test_data/unprotected-upgrade/0.7.6/AnyInitializer.sol#6-9). Anyone can delete the contract with: AnyInitializer.kill() (tests/e2e/detectors/test_data/unprotected-upgrade/0.7.6/AnyInitializer.sol#11-14) |
@ -0,0 +1 @@ |
||||
Reinitializer (tests/e2e/detectors/test_data/unprotected-upgrade/0.7.6/Reinitializer.sol#3-15) is an upgradeable contract that does not protect its initialize functions: Reinitializer.initialize() (tests/e2e/detectors/test_data/unprotected-upgrade/0.7.6/Reinitializer.sol#6-9). Anyone can delete the contract with: Reinitializer.kill() (tests/e2e/detectors/test_data/unprotected-upgrade/0.7.6/Reinitializer.sol#11-14) |
@ -0,0 +1 @@ |
||||
AnyInitializer (tests/e2e/detectors/test_data/unprotected-upgrade/0.8.15/AnyInitializer.sol#3-15) is an upgradeable contract that does not protect its initialize functions: AnyInitializer.anyName() (tests/e2e/detectors/test_data/unprotected-upgrade/0.8.15/AnyInitializer.sol#6-9). Anyone can delete the contract with: AnyInitializer.kill() (tests/e2e/detectors/test_data/unprotected-upgrade/0.8.15/AnyInitializer.sol#11-14) |
@ -0,0 +1 @@ |
||||
Reinitializer (tests/e2e/detectors/test_data/unprotected-upgrade/0.8.15/Reinitializer.sol#3-15) is an upgradeable contract that does not protect its initialize functions: Reinitializer.initialize() (tests/e2e/detectors/test_data/unprotected-upgrade/0.8.15/Reinitializer.sol#6-9). Anyone can delete the contract with: Reinitializer.kill() (tests/e2e/detectors/test_data/unprotected-upgrade/0.8.15/Reinitializer.sol#11-14) |
@ -1,6 +1,6 @@ |
||||
The following unused import(s) in tests/e2e/detectors/test_data/unused-imports/0.8.16/B.sol should be removed: |
||||
-import "./A.sol"; (tests/e2e/detectors/test_data/unused-imports/0.8.16/B.sol#4) |
||||
|
||||
The following unused import(s) in tests/e2e/detectors/test_data/unused-imports/0.8.16/C.sol should be removed: |
||||
The following unused import(s) in tests/e2e/detectors/test_data/unused-imports/0.8.16/C.sol should be removed: |
||||
-import "./B.sol"; (tests/e2e/detectors/test_data/unused-imports/0.8.16/C.sol#4) |
||||
|
||||
The following unused import(s) in tests/e2e/detectors/test_data/unused-imports/0.8.16/B.sol should be removed: |
||||
-import "./A.sol"; (tests/e2e/detectors/test_data/unused-imports/0.8.16/B.sol#4) |
||||
|
||||
|
@ -1,7 +0,0 @@ |
||||
contract Similar { |
||||
function f() public returns (uint) { |
||||
uint testVariable = 1; |
||||
uint textVariable = 2; |
||||
return testVariable + textVariable; |
||||
} |
||||
} |
Binary file not shown.
@ -1,7 +0,0 @@ |
||||
contract Similar { |
||||
function f() public returns (uint) { |
||||
uint testVariable = 1; |
||||
uint textVariable = 2; |
||||
return testVariable + textVariable; |
||||
} |
||||
} |
Binary file not shown.
@ -1,7 +0,0 @@ |
||||
contract Similar { |
||||
function f() public returns (uint) { |
||||
uint testVariable = 1; |
||||
uint textVariable = 2; |
||||
return testVariable + textVariable; |
||||
} |
||||
} |
Binary file not shown.
@ -1,7 +0,0 @@ |
||||
contract Similar { |
||||
function f() public returns (uint) { |
||||
uint testVariable = 1; |
||||
uint textVariable = 2; |
||||
return testVariable + textVariable; |
||||
} |
||||
} |
Binary file not shown.
@ -0,0 +1,15 @@ |
||||
import "./Initializable.sol"; |
||||
|
||||
contract AnyInitializer is Initializable { |
||||
address owner; |
||||
|
||||
function anyName() external initializer { |
||||
require(owner == address(0)); |
||||
owner = msg.sender; |
||||
} |
||||
|
||||
function kill() external { |
||||
require(msg.sender == owner); |
||||
selfdestruct(owner); |
||||
} |
||||
} |
Binary file not shown.
@ -1,5 +1,9 @@ |
||||
contract Initializable{ |
||||
modifier initializer() { |
||||
_; |
||||
} |
||||
} |
||||
contract Initializable { |
||||
modifier initializer() { |
||||
_; |
||||
} |
||||
|
||||
modifier reinitializer(uint64 version) { |
||||
_; |
||||
} |
||||
} |
||||
|
@ -0,0 +1,15 @@ |
||||
import "./Initializable.sol"; |
||||
|
||||
contract Reinitializer is Initializable { |
||||
address owner; |
||||
|
||||
function initialize() external reinitializer(2) { |
||||
require(owner == address(0)); |
||||
owner = msg.sender; |
||||
} |
||||
|
||||
function kill() external { |
||||
require(msg.sender == owner); |
||||
selfdestruct(owner); |
||||
} |
||||
} |
Binary file not shown.
@ -0,0 +1,15 @@ |
||||
import "./Initializable.sol"; |
||||
|
||||
contract AnyInitializer is Initializable { |
||||
address payable owner; |
||||
|
||||
function anyName() external initializer { |
||||
require(owner == address(0)); |
||||
owner = msg.sender; |
||||
} |
||||
|
||||
function kill() external { |
||||
require(msg.sender == owner); |
||||
selfdestruct(owner); |
||||
} |
||||
} |
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue