mirror of https://github.com/crytic/slither
commit
9fe27d375f
@ -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 |
||||||
|
|
||||||
`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. |
This tool is experimental. See [solmate documentation](https://github.com/montyly/solmate/pull/1) for an example of usage. |
||||||
|
@ -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,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.
@ -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.
@ -0,0 +1,15 @@ |
|||||||
|
import "./Initializable.sol"; |
||||||
|
|
||||||
|
contract Reinitializer is Initializable { |
||||||
|
address payable 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 = payable(msg.sender); |
||||||
|
} |
||||||
|
|
||||||
|
function kill() external { |
||||||
|
require(msg.sender == owner); |
||||||
|
selfdestruct(owner); |
||||||
|
} |
||||||
|
} |
Binary file not shown.
@ -0,0 +1,15 @@ |
|||||||
|
import "./Initializable.sol"; |
||||||
|
|
||||||
|
contract Reinitializer is Initializable { |
||||||
|
address payable owner; |
||||||
|
|
||||||
|
function initialize() external reinitializer(2) { |
||||||
|
require(owner == address(0)); |
||||||
|
owner = payable(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 = payable(msg.sender); |
||||||
|
} |
||||||
|
|
||||||
|
function kill() external { |
||||||
|
require(msg.sender == owner); |
||||||
|
selfdestruct(owner); |
||||||
|
} |
||||||
|
} |
Binary file not shown.
@ -0,0 +1,15 @@ |
|||||||
|
import "./Initializable.sol"; |
||||||
|
|
||||||
|
contract Reinitializer is Initializable { |
||||||
|
address payable owner; |
||||||
|
|
||||||
|
function initialize() external reinitializer(2) { |
||||||
|
require(owner == address(0)); |
||||||
|
owner = payable(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 = payable(msg.sender); |
||||||
|
} |
||||||
|
|
||||||
|
function kill() external { |
||||||
|
require(msg.sender == owner); |
||||||
|
selfdestruct(owner); |
||||||
|
} |
||||||
|
} |
Binary file not shown.
@ -0,0 +1,15 @@ |
|||||||
|
import "./Initializable.sol"; |
||||||
|
|
||||||
|
contract Reinitializer is Initializable { |
||||||
|
address payable owner; |
||||||
|
|
||||||
|
function initialize() external reinitializer(2) { |
||||||
|
require(owner == address(0)); |
||||||
|
owner = payable(msg.sender); |
||||||
|
} |
||||||
|
|
||||||
|
function kill() external { |
||||||
|
require(msg.sender == owner); |
||||||
|
selfdestruct(owner); |
||||||
|
} |
||||||
|
} |
Binary file not shown.
@ -1,7 +1,21 @@ |
|||||||
import "./A.sol"; |
import "./A.sol"; |
||||||
|
|
||||||
contract C is A { |
interface MyInterfaceX { |
||||||
|
function count() external view returns (uint256); |
||||||
|
|
||||||
|
function increment() external; |
||||||
|
} |
||||||
|
|
||||||
|
contract C is A, MyInterfaceX { |
||||||
function c_main() public pure { |
function c_main() public pure { |
||||||
a_main(); |
a_main(); |
||||||
} |
} |
||||||
|
|
||||||
|
function count() external view override returns (uint256){ |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
function increment() external override { |
||||||
|
|
||||||
|
} |
||||||
} |
} |
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,41 @@ |
|||||||
|
// SPDX-License-Identifier: MIT |
||||||
|
pragma solidity ^0.8.13; |
||||||
|
|
||||||
|
import { |
||||||
|
ParentContract |
||||||
|
} from "./ParentContract.sol"; |
||||||
|
|
||||||
|
import { |
||||||
|
MainErrors as Errors |
||||||
|
} from "./../errors/MainErrors.sol"; |
||||||
|
|
||||||
|
|
||||||
|
contract MainContract is ParentContract { |
||||||
|
|
||||||
|
|
||||||
|
function functionWithMainError1(uint256 a, uint256 b) external pure returns (uint256) { |
||||||
|
if (a == b) { |
||||||
|
revert Errors.MainError1(); |
||||||
|
} |
||||||
|
// Add some arithmetic operations here |
||||||
|
return a + b; |
||||||
|
} |
||||||
|
|
||||||
|
function functionWithMainError2(uint256 a, uint256 b) external pure returns (uint256) { |
||||||
|
if (a < b) { |
||||||
|
revert Errors.MainError2(); |
||||||
|
} |
||||||
|
// Add some arithmetic operations here |
||||||
|
return a - b; |
||||||
|
} |
||||||
|
|
||||||
|
function functionWithMainError3(uint256 a, uint256 b) external pure returns (uint256) { |
||||||
|
if (b == 0) { |
||||||
|
revert Errors.MainError3(); |
||||||
|
} |
||||||
|
// Add some arithmetic operations here |
||||||
|
return a * b; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
// SPDX-License-Identifier: MIT |
||||||
|
pragma solidity ^0.8.13; |
||||||
|
|
||||||
|
|
||||||
|
import { |
||||||
|
AccessControlErrors as Errors |
||||||
|
} from "../errors/ParentContractErrors.sol"; |
||||||
|
|
||||||
|
|
||||||
|
contract ParentContract { |
||||||
|
|
||||||
|
|
||||||
|
function functionWithAccessControlErrors1(uint256 a, uint256 b) external pure returns (uint256) { |
||||||
|
if (a == b) { |
||||||
|
revert Errors.AccessControlErrors1(); |
||||||
|
} |
||||||
|
// Add some arithmetic operations here |
||||||
|
return a + b; |
||||||
|
} |
||||||
|
|
||||||
|
function functionWithAccessControlErrors2(uint256 a, uint256 b) external pure returns (uint256) { |
||||||
|
if (a < b) { |
||||||
|
revert Errors.AccessControlErrors2(); |
||||||
|
} |
||||||
|
// Add some arithmetic operations here |
||||||
|
return a - b; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
// SPDX-License-Identifier: MIT |
||||||
|
pragma solidity ^0.8.13; |
||||||
|
|
||||||
|
// TODO: remove unused errors |
||||||
|
library MainErrors { |
||||||
|
error MainError1(); |
||||||
|
error MainError2(); |
||||||
|
error MainError3(); |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
// SPDX-License-Identifier: MIT |
||||||
|
pragma solidity ^0.8.13; |
||||||
|
|
||||||
|
library AccessControlErrors { |
||||||
|
error AccessControlErrors1(); |
||||||
|
error AccessControlErrors2(); |
||||||
|
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue