Merge pull request #1660 from crytic/bart1e-detector_for_cc

High cyclomatic complexity detector
pull/1665/head
Feist Josselin 2 years ago committed by GitHub
commit 90efe7adc1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      slither/detectors/all_detectors.py
  2. 50
      slither/detectors/functions/cyclomatic_complexity.py
  3. 32
      tests/detectors/cyclomatic-complexity/0.8.16/HighCyclomaticComplexity.sol
  4. 96
      tests/detectors/cyclomatic-complexity/0.8.16/HighCyclomaticComplexity.sol.0.8.16.CyclomaticComplexity.json
  5. 15
      tests/detectors/cyclomatic-complexity/0.8.16/LowCyclomaticComplexity.sol
  6. 3
      tests/detectors/cyclomatic-complexity/0.8.16/LowCyclomaticComplexity.sol.0.8.16.CyclomaticComplexity.json
  7. 10
      tests/test_detectors.py

@ -88,3 +88,4 @@ from .statements.delegatecall_in_loop import DelegatecallInLoop
from .functions.protected_variable import ProtectedVariables
from .functions.permit_domain_signature_collision import DomainSeparatorCollision
from .functions.codex import Codex
from .functions.cyclomatic_complexity import CyclomaticComplexity

@ -0,0 +1,50 @@
from typing import List, Tuple
from slither.core.declarations import Function
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
from slither.utils.code_complexity import compute_cyclomatic_complexity
from slither.utils.output import Output
def _check_for_high_cc(high_cc_functions: List[Tuple[Function, int]], f: Function) -> None:
cc = compute_cyclomatic_complexity(f)
if cc > 11:
high_cc_functions.append((f, cc))
class CyclomaticComplexity(AbstractDetector):
"""
Detects functions with high (> 11) cyclomatic complexity.
"""
ARGUMENT = "cyclomatic-complexity"
HELP = "Detects functions with high (> 11) cyclomatic complexity"
IMPACT = DetectorClassification.INFORMATIONAL
CONFIDENCE = DetectorClassification.HIGH
WIKI = 'https://github.com/crytic/slither/wiki/Detector-Documentation#cyclomatic-complexity"'
WIKI_TITLE = "Cyclomatic complexity"
WIKI_DESCRIPTION = "Detects functions with high (> 11) cyclomatic complexity."
WIKI_EXPLOIT_SCENARIO = ""
WIKI_RECOMMENDATION = (
"Reduce cyclomatic complexity by splitting the function into several smaller subroutines."
)
def _detect(self) -> List[Output]:
results = []
high_cc_functions: List[Tuple[Function, int]] = []
f: Function
for c in self.compilation_unit.contracts:
for f in c.functions_declared:
_check_for_high_cc(high_cc_functions, f)
for f in self.compilation_unit.functions_top_level:
_check_for_high_cc(high_cc_functions, f)
for f, cc in high_cc_functions:
info = [f, f" has a high cyclomatic complexity ({cc}).\n"]
res = self.generate_result(info)
results.append(res)
return results

@ -0,0 +1,32 @@
pragma solidity 0.8.16;
contract HighCyclomaticComplexity
{
bool bool1;
bool bool2;
bool bool3;
bool bool4;
bool bool5;
bool bool6;
bool bool7;
bool bool8;
bool bool9;
bool bool10;
bool bool11;
function highCC() internal view
{
if (bool1)
if (bool2)
if (bool3)
if (bool4)
if (bool5)
if (bool6)
if (bool7)
if (bool8)
if (bool9)
if (bool10)
if (bool11)
revert();
}
}

@ -0,0 +1,96 @@
[
[
{
"elements": [
{
"type": "function",
"name": "highCC",
"source_mapping": {
"start": 244,
"length": 536,
"filename_relative": "tests/detectors/cyclomatic-complexity/0.8.16/HighCyclomaticComplexity.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/cyclomatic-complexity/0.8.16/HighCyclomaticComplexity.sol",
"is_dependency": false,
"lines": [
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31
],
"starting_column": 5,
"ending_column": 6
},
"type_specific_fields": {
"parent": {
"type": "contract",
"name": "HighCyclomaticComplexity",
"source_mapping": {
"start": 25,
"length": 757,
"filename_relative": "tests/detectors/cyclomatic-complexity/0.8.16/HighCyclomaticComplexity.sol",
"filename_absolute": "/GENERIC_PATH",
"filename_short": "tests/detectors/cyclomatic-complexity/0.8.16/HighCyclomaticComplexity.sol",
"is_dependency": false,
"lines": [
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33
],
"starting_column": 1,
"ending_column": 0
}
},
"signature": "highCC()"
}
}
],
"description": "HighCyclomaticComplexity.highCC() (tests/detectors/cyclomatic-complexity/0.8.16/HighCyclomaticComplexity.sol#17-31) has a high cyclomatic complexity (12).\n",
"markdown": "[HighCyclomaticComplexity.highCC()](tests/detectors/cyclomatic-complexity/0.8.16/HighCyclomaticComplexity.sol#L17-L31) has a high cyclomatic complexity (12).\n",
"first_markdown_element": "tests/detectors/cyclomatic-complexity/0.8.16/HighCyclomaticComplexity.sol#L17-L31",
"id": "405b9e7f5697539c75171d728f0a10b6ebb7fe08441c445b0e63c33982c98e2d",
"check": "cyclomatic-complexity",
"impact": "Informational",
"confidence": "High"
}
]
]

@ -0,0 +1,15 @@
pragma solidity 0.8.16;
contract LowCyclomaticComplexity
{
function lowCC() public pure
{
for (uint i = 0; i < 10; i++)
{
for (uint j = 0; j < i; j++)
{
uint a = i + 1;
}
}
}
}

@ -1623,6 +1623,16 @@ ALL_TEST_OBJECTS = [
"var_read_using_this.sol",
"0.8.15",
),
Test(
all_detectors.CyclomaticComplexity,
"HighCyclomaticComplexity.sol",
"0.8.16",
),
Test(
all_detectors.CyclomaticComplexity,
"LowCyclomaticComplexity.sol",
"0.8.16",
),
]

Loading…
Cancel
Save