Repository: crytic/slither

Issue:
"not in UPPER_CASE_WITH_UNDERSCORES" should not apply to public/external constants
### Describe the issue:

`public`/`external` fields of a contract are exported as functions, so they are part of a public API, and Slither should not report the warning `not in UPPER_CASE_WITH_UNDERSCORES` if these fields are in lowercase.

### Code example to reproduce the issue:

```
contract A { uint256 public myVal; }
```

### Version:

0.8.3

### Relevant log output:

```shell
Constant A.myVal (contracts/A.sol#1) is not in UPPER_CASE_WITH_UNDERSCORES
```
```



Discussion:
When I run slither on this contract, I only get:
```
A.myVal (test.sol#1) should be constant
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#state-variables-that-could-be-declared-constant
```
Perhaps you had something like this?
```
contract A { uint256 public constant myVal = 0; }
```
Sorry, I didn't test the minimal example I manually typed in. Yes, if you add `constant` it should trigger the Slither warning that is masked by the warning you got instead. 

Resolving patch:
diff --git a/slither/detectors/naming_convention/naming_convention.py b/slither/detectors/naming_convention/naming_convention.py
--- a/slither/detectors/naming_convention/naming_convention.py
+++ b/slither/detectors/naming_convention/naming_convention.py
@@ -139,7 +139,8 @@ def _detect(self):  # pylint: disable=too-many-branches,too-many-statements
                     # For ERC20 compatibility
                     if var.name in ["symbol", "name", "decimals"]:
                         continue
-
+                    if var.visibility == "public":
+                        continue
                     if not self.is_upper_case_with_underscores(var.name):
                         info = [
                             "Constant ",


Test patch:
diff --git a/tests/detectors/naming-convention/0.4.25/no_warning_for_public_constants.sol b/tests/detectors/naming-convention/0.4.25/no_warning_for_public_constants.sol
new file mode 100644
--- /dev/null
+++ b/tests/detectors/naming-convention/0.4.25/no_warning_for_public_constants.sol
@@ -0,0 +1,4 @@
+contract A 
+{ 
+    uint256 public constant myVal = 0; 
+}
\ No newline at end of file
diff --git a/tests/detectors/naming-convention/0.4.25/no_warning_for_public_constants.sol.0.4.25.NamingConvention.json b/tests/detectors/naming-convention/0.4.25/no_warning_for_public_constants.sol.0.4.25.NamingConvention.json
new file mode 100644
--- /dev/null
+++ b/tests/detectors/naming-convention/0.4.25/no_warning_for_public_constants.sol.0.4.25.NamingConvention.json
@@ -0,0 +1,3 @@
+[
+    []
+]
\ No newline at end of file
diff --git a/tests/detectors/naming-convention/0.5.16/no_warning_for_public_constants.sol b/tests/detectors/naming-convention/0.5.16/no_warning_for_public_constants.sol
new file mode 100644
--- /dev/null
+++ b/tests/detectors/naming-convention/0.5.16/no_warning_for_public_constants.sol
@@ -0,0 +1,4 @@
+contract A 
+{ 
+    uint256 public constant myVal = 0; 
+}
\ No newline at end of file
diff --git a/tests/detectors/naming-convention/0.5.16/no_warning_for_public_constants.sol.0.5.16.NamingConvention.json b/tests/detectors/naming-convention/0.5.16/no_warning_for_public_constants.sol.0.5.16.NamingConvention.json
new file mode 100644
--- /dev/null
+++ b/tests/detectors/naming-convention/0.5.16/no_warning_for_public_constants.sol.0.5.16.NamingConvention.json
@@ -0,0 +1,3 @@
+[
+    []
+]
\ No newline at end of file
diff --git a/tests/detectors/naming-convention/0.6.11/no_warning_for_public_constants.sol b/tests/detectors/naming-convention/0.6.11/no_warning_for_public_constants.sol
new file mode 100644
--- /dev/null
+++ b/tests/detectors/naming-convention/0.6.11/no_warning_for_public_constants.sol
@@ -0,0 +1,4 @@
+contract A 
+{ 
+    uint256 public constant myVal = 0; 
+}
\ No newline at end of file
diff --git a/tests/detectors/naming-convention/0.6.11/no_warning_for_public_constants.sol.0.6.11.NamingConvention.json b/tests/detectors/naming-convention/0.6.11/no_warning_for_public_constants.sol.0.6.11.NamingConvention.json
new file mode 100644
--- /dev/null
+++ b/tests/detectors/naming-convention/0.6.11/no_warning_for_public_constants.sol.0.6.11.NamingConvention.json
@@ -0,0 +1,3 @@
+[
+    []
+]
\ No newline at end of file
diff --git a/tests/detectors/naming-convention/0.7.6/no_warning_for_public_constants.sol b/tests/detectors/naming-convention/0.7.6/no_warning_for_public_constants.sol
new file mode 100644
--- /dev/null
+++ b/tests/detectors/naming-convention/0.7.6/no_warning_for_public_constants.sol
@@ -0,0 +1,4 @@
+contract A 
+{ 
+    uint256 public constant myVal = 0; 
+}
diff --git a/tests/detectors/naming-convention/0.7.6/no_warning_for_public_constants.sol.0.7.6.NamingConvention.json b/tests/detectors/naming-convention/0.7.6/no_warning_for_public_constants.sol.0.7.6.NamingConvention.json
new file mode 100644
--- /dev/null
+++ b/tests/detectors/naming-convention/0.7.6/no_warning_for_public_constants.sol.0.7.6.NamingConvention.json
@@ -0,0 +1,3 @@
+[
+    []
+]
\ No newline at end of file
diff --git a/tests/test_detectors.py b/tests/test_detectors.py
--- a/tests/test_detectors.py
+++ b/tests/test_detectors.py
@@ -609,6 +609,26 @@ def id_test(test_item: Test):
         "naming_convention.sol",
         "0.7.6",
     ),
+    Test(
+        all_detectors.NamingConvention,
+        "no_warning_for_public_constants.sol",
+        "0.4.25",
+    ),
+    Test(
+        all_detectors.NamingConvention,
+        "no_warning_for_public_constants.sol",
+        "0.5.16",
+    ),
+    Test(
+        all_detectors.NamingConvention,
+        "no_warning_for_public_constants.sol",
+        "0.6.11",
+    ),
+    Test(
+        all_detectors.NamingConvention,
+        "no_warning_for_public_constants.sol",
+        "0.7.6",
+    ),
     Test(
         all_detectors.ControlledDelegateCall,
         "controlled_delegatecall.sol",