Repository: crytic/slither

Issue:
Create a new detector category: optimization
We have public/private detectors that are classified as 'Informational', but they could be classifed through a new category: "Optimization"

For public detectors:
- constable-states
- external-function




Discussion:

Resolving patch:
diff --git a/slither/detectors/abstract_detector.py b/slither/detectors/abstract_detector.py
--- a/slither/detectors/abstract_detector.py
+++ b/slither/detectors/abstract_detector.py
@@ -14,17 +14,20 @@ class DetectorClassification:
     MEDIUM = 1
     LOW = 2
     INFORMATIONAL = 3
+    OPTIMIZATION = 4
 
 
 classification_colors = {
     DetectorClassification.INFORMATIONAL: green,
+    DetectorClassification.OPTIMIZATION: green,
     DetectorClassification.LOW: green,
     DetectorClassification.MEDIUM: yellow,
-    DetectorClassification.HIGH: red,
+    DetectorClassification.HIGH: red
 }
 
 classification_txt = {
     DetectorClassification.INFORMATIONAL: 'Informational',
+    DetectorClassification.OPTIMIZATION: 'Optimization',
     DetectorClassification.LOW: 'Low',
     DetectorClassification.MEDIUM: 'Medium',
     DetectorClassification.HIGH: 'High',
@@ -65,7 +68,8 @@ def __init__(self, slither, logger):
         if not self.WIKI_DESCRIPTION:
             raise IncorrectDetectorInitialization('WIKI_DESCRIPTION is not initialized {}'.format(self.__class__.__name__))
 
-        if not self.WIKI_EXPLOIT_SCENARIO and self.IMPACT != DetectorClassification.INFORMATIONAL:
+        if not self.WIKI_EXPLOIT_SCENARIO and self.IMPACT not in [DetectorClassification.INFORMATIONAL,
+                                                                      DetectorClassification.OPTIMIZATION]:
             raise IncorrectDetectorInitialization('WIKI_EXPLOIT_SCENARIO is not initialized {}'.format(self.__class__.__name__))
 
         if not self.WIKI_RECOMMENDATION:
@@ -77,13 +81,15 @@ def __init__(self, slither, logger):
         if self.IMPACT not in [DetectorClassification.LOW,
                                        DetectorClassification.MEDIUM,
                                        DetectorClassification.HIGH,
-                                       DetectorClassification.INFORMATIONAL]:
+                                       DetectorClassification.INFORMATIONAL,
+                                       DetectorClassification.OPTIMIZATION]:
             raise IncorrectDetectorInitialization('IMPACT is not initialized {}'.format(self.__class__.__name__))
 
         if self.CONFIDENCE not in [DetectorClassification.LOW,
                                        DetectorClassification.MEDIUM,
                                        DetectorClassification.HIGH,
-                                       DetectorClassification.INFORMATIONAL]:
+                                       DetectorClassification.INFORMATIONAL,
+                                       DetectorClassification.OPTIMIZATION]:
             raise IncorrectDetectorInitialization('CONFIDENCE is not initialized {}'.format(self.__class__.__name__))
 
 
diff --git a/slither/detectors/functions/external_function.py b/slither/detectors/functions/external_function.py
--- a/slither/detectors/functions/external_function.py
+++ b/slither/detectors/functions/external_function.py
@@ -13,7 +13,7 @@ class ExternalFunction(AbstractDetector):
 
     ARGUMENT = 'external-function'
     HELP = 'Public function that could be declared as external'
-    IMPACT = DetectorClassification.INFORMATIONAL
+    IMPACT = DetectorClassification.OPTIMIZATION
     CONFIDENCE = DetectorClassification.HIGH
 
     WIKI = 'https://github.com/crytic/slither/wiki/Detector-Documentation#public-function-that-could-be-declared-as-external'
diff --git a/slither/detectors/variables/possible_const_state_variables.py b/slither/detectors/variables/possible_const_state_variables.py
--- a/slither/detectors/variables/possible_const_state_variables.py
+++ b/slither/detectors/variables/possible_const_state_variables.py
@@ -18,7 +18,7 @@ class ConstCandidateStateVars(AbstractDetector):
 
     ARGUMENT = 'constable-states'
     HELP = 'State variables that could be declared constant'
-    IMPACT = DetectorClassification.INFORMATIONAL
+    IMPACT = DetectorClassification.OPTIMIZATION
     CONFIDENCE = DetectorClassification.HIGH
 
     WIKI = 'https://github.com/crytic/slither/wiki/Detector-Documentation#state-variables-that-could-be-declared-constant'


Test patch:
diff --git a/tests/expected_json/const_state_variables.constable-states.json b/tests/expected_json/const_state_variables.constable-states.json
--- a/tests/expected_json/const_state_variables.constable-states.json
+++ b/tests/expected_json/const_state_variables.constable-states.json
@@ -5,7 +5,7 @@
     "detectors": [
       {
         "check": "constable-states",
-        "impact": "Informational",
+        "impact": "Optimization",
         "confidence": "High",
         "description": "A.myFriendsAddress should be constant (tests/const_state_variables.sol#7)\n",
         "elements": [
@@ -66,7 +66,7 @@
       },
       {
         "check": "constable-states",
-        "impact": "Informational",
+        "impact": "Optimization",
         "confidence": "High",
         "description": "A.test should be constant (tests/const_state_variables.sol#10)\n",
         "elements": [
@@ -127,7 +127,7 @@
       },
       {
         "check": "constable-states",
-        "impact": "Informational",
+        "impact": "Optimization",
         "confidence": "High",
         "description": "A.text2 should be constant (tests/const_state_variables.sol#14)\n",
         "elements": [
@@ -188,7 +188,7 @@
       },
       {
         "check": "constable-states",
-        "impact": "Informational",
+        "impact": "Optimization",
         "confidence": "High",
         "description": "B.mySistersAddress should be constant (tests/const_state_variables.sol#26)\n",
         "elements": [
@@ -245,7 +245,7 @@
       },
       {
         "check": "constable-states",
-        "impact": "Informational",
+        "impact": "Optimization",
         "confidence": "High",
         "description": "MyConc.should_be_constant should be constant (tests/const_state_variables.sol#42)\n",
         "elements": [
@@ -302,7 +302,7 @@
       },
       {
         "check": "constable-states",
-        "impact": "Informational",
+        "impact": "Optimization",
         "confidence": "High",
         "description": "MyConc.should_be_constant_2 should be constant (tests/const_state_variables.sol#43)\n",
         "elements": [
diff --git a/tests/expected_json/external_function.external-function.json b/tests/expected_json/external_function.external-function.json
--- a/tests/expected_json/external_function.external-function.json
+++ b/tests/expected_json/external_function.external-function.json
@@ -5,7 +5,7 @@
     "detectors": [
       {
         "check": "external-function",
-        "impact": "Informational",
+        "impact": "Optimization",
         "confidence": "High",
         "description": "ContractWithFunctionNotCalled.funcNotCalled3() (tests/external_function.sol#13-15) should be declared external\n",
         "elements": [
@@ -70,7 +70,7 @@
       },
       {
         "check": "external-function",
-        "impact": "Informational",
+        "impact": "Optimization",
         "confidence": "High",
         "description": "ContractWithFunctionNotCalled.funcNotCalled2() (tests/external_function.sol#17-19) should be declared external\n",
         "elements": [
@@ -135,7 +135,7 @@
       },
       {
         "check": "external-function",
-        "impact": "Informational",
+        "impact": "Optimization",
         "confidence": "High",
         "description": "ContractWithFunctionNotCalled.funcNotCalled() (tests/external_function.sol#21-23) should be declared external\n",
         "elements": [
@@ -200,7 +200,7 @@
       },
       {
         "check": "external-function",
-        "impact": "Informational",
+        "impact": "Optimization",
         "confidence": "High",
         "description": "ContractWithFunctionNotCalled2.funcNotCalled() (tests/external_function.sol#32-39) should be declared external\n",
         "elements": [