Skip to content

Commit d0843c3

Browse files
Merge pull request #694 from protofire/develop
MERGE: develop into master v6.0.0
2 parents 2fc8b33 + 85d66ef commit d0843c3

File tree

59 files changed

+1563
-330
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1563
-330
lines changed

CHANGELOG.md

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,47 @@
1+
## [6.0.0] - 2025-07-04
2+
3+
### BREAKING CHANGE
4+
Some rules were removed from the recommended ruleset and other were promoted. See below:
5+
Rules revision - [#692](https://github.com/protofire/solhint/pull/692)
6+
7+
#### 🟥 DEMOTED
8+
9+
- `payable-fallback`: Outdated due to the introduction of receive(); rarely needed in modern Solidity.
10+
<br>
11+
12+
#### ✅ PROMOTED
13+
14+
- `interface-starts-with-i`: Promotes clarity by clearly distinguishing interfaces from contracts.
15+
- `gas-calldata-parameters`: Encourages optimal memory usage for external functions.
16+
- `gas-increment-by-one`: Suggests using ++i style for gas-efficient increments.
17+
- `gas-indexed-events`: Improves event indexing for off-chain systems and reduces gas usage.
18+
- `gas-small-strings`: Recommends cheaper encoding using bytes32 for short strings.
19+
- `gas-strict-inequalities`: Helps avoid subtle off-by-one bugs in range conditions.
20+
- `gas-struct-packing`: Maximizes storage efficiency by suggesting tight struct packing.
21+
- `duplicated-imports`: Prevents redundant imports that bloat the AST and confuse code structure.
22+
- `import-path-check`: Ensures all imported files exist and resolve correctly, avoiding runtime errors.
23+
- `function-max-lines`: Encourages smaller, more readable and maintainable functions.
24+
- `constructor-syntax`: Enforces modern constructor syntax for consistency and clarity.
25+
- `use-natspec`: Promotes proper documentation with NatSpec for better audits and readability.
26+
27+
### Fixed
28+
- `gas-struct-packing` false positives - [#690](https://github.com/protofire/solhint/pull/690)
29+
- `gas-increment-by-one` backward expression - [#691](https://github.com/protofire/solhint/pull/691)
30+
- Typo (thanks to @[MarkFizz77](https://github.com/MarkFizz77))
31+
32+
### Added
33+
- `use-natspec`: Promote the use of natspec and make several checks to enforce it - [#689](https://github.com/protofire/solhint/pull/689)
34+
35+
<br><br>
36+
137
## [5.2.0] - 2025-06-27
238
### Fixed
3-
- `imports-order` interference with `no-unused-imports` [#684](https://github.com/protofire/solhint/pull/684)
39+
- `imports-order` interference with `no-unused-imports` - [#684](https://github.com/protofire/solhint/pull/684)
440

541
### Added
642
- Added `cache` flag allowing to skip already evaluated files if no error was thrown and file did not change - [#685](https://github.com/protofire/solhint/pull/685)
743
- Added multi-directory config support by hierarchy - [#678](https://github.com/protofire/solhint/pull/678)
8-
- Added better error handling on invalid configs - [#683](https://github.com/protofire/solhint/pull/683)
44+
- Added better error handling on invalid configs - [#683](https://github.com/protofire/solhint/pull/683)
945

1046

1147
Thanks to [@smol-ninja](https://github.com/smol-ninja) - [@PaulRBerg](https://github.com/PaulRBerg) [@lechpzn](https://github.com/lechpzn), [@otc-png](https://github.com/otc-png), [@MamunC0der](https://github.com/MamunC0der), [@kks-code](https://github.com/kks-code), [@RidaMichofi](https://github.com/RidaMichofi)

conf/rulesets/solhint-all.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,31 @@ module.exports = Object.freeze({
2424
maxLength: 32,
2525
},
2626
],
27+
'use-natspec': [
28+
'warn',
29+
{
30+
title: {
31+
enabled: true,
32+
ignore: {},
33+
},
34+
author: {
35+
enabled: true,
36+
ignore: {},
37+
},
38+
notice: {
39+
enabled: true,
40+
ignore: {},
41+
},
42+
param: {
43+
enabled: true,
44+
ignore: {},
45+
},
46+
return: {
47+
enabled: true,
48+
ignore: {},
49+
},
50+
},
51+
],
2752
'constructor-syntax': 'warn',
2853
'gas-calldata-parameters': 'warn',
2954
'gas-custom-errors': 'warn',

conf/rulesets/solhint-recommended.js

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,55 @@
66
module.exports = Object.freeze({
77
rules: {
88
'explicit-types': ['warn', 'explicit'],
9+
'function-max-lines': ['warn', 50],
10+
'interface-starts-with-i': 'warn',
911
'max-states-count': ['warn', 15],
1012
'no-console': 'error',
1113
'no-empty-blocks': 'warn',
1214
'no-global-import': 'warn',
1315
'no-unused-import': 'warn',
1416
'no-unused-vars': 'warn',
1517
'one-contract-per-file': 'warn',
16-
'payable-fallback': 'warn',
1718
'reason-string': [
1819
'warn',
1920
{
2021
maxLength: 32,
2122
},
2223
],
24+
'use-natspec': [
25+
'warn',
26+
{
27+
title: {
28+
enabled: true,
29+
ignore: {},
30+
},
31+
author: {
32+
enabled: true,
33+
ignore: {},
34+
},
35+
notice: {
36+
enabled: true,
37+
ignore: {},
38+
},
39+
param: {
40+
enabled: true,
41+
ignore: {},
42+
},
43+
return: {
44+
enabled: true,
45+
ignore: {},
46+
},
47+
},
48+
],
49+
'constructor-syntax': 'warn',
50+
'gas-calldata-parameters': 'warn',
2351
'gas-custom-errors': 'warn',
52+
'gas-increment-by-one': 'warn',
53+
'gas-indexed-events': 'warn',
54+
'gas-small-strings': 'warn',
55+
'gas-strict-inequalities': 'warn',
56+
'gas-struct-packing': 'warn',
57+
'duplicated-imports': 'warn',
2458
'import-path-check': ['warn', ['[~dependenciesPath]']],
2559
quotes: ['error', 'double'],
2660
'const-name-snakecase': 'warn',

docker/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
FROM node:20-alpine
22
LABEL maintainer="diego.bale@protofire.io"
3-
ENV VERSION=5.2.0
3+
ENV VERSION=6.0.0
44

55
RUN npm install -g solhint@"$VERSION"

docs/rules.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ title: "Rule Index of Solhint"
1010
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ | ------------ | ---------- |
1111
| [code-complexity](./rules/best-practices/code-complexity.md) | Function has cyclomatic complexity "current" but allowed no more than configured max complexity. | | |
1212
| [explicit-types](./rules/best-practices/explicit-types.md) | Forbid or enforce explicit types (like uint256) that have an alias (like uint). | $~~~~~~~~$✔️ | |
13-
| [function-max-lines](./rules/best-practices/function-max-lines.md) | Function body contains "count" lines but allowed no more than maxlines. | | |
13+
| [function-max-lines](./rules/best-practices/function-max-lines.md) | Function body contains "count" lines but allowed no more than maxlines. | $~~~~~~~~$✔️ | |
1414
| [max-line-length](./rules/best-practices/max-line-length.md) | Line length should not exceed configured number of characters. | | |
1515
| [max-states-count](./rules/best-practices/max-states-count.md) | Contract has "some count" states declarations but allowed no more than defined max states. | $~~~~~~~~$✔️ | |
1616
| [no-console](./rules/best-practices/no-console.md) | No console.log/logInt/logBytesX/logString/etc & No hardhat and forge-std console.sol import statements. | $~~~~~~~~$✔️ | |
@@ -19,17 +19,18 @@ title: "Rule Index of Solhint"
1919
| [no-unused-import](./rules/best-practices/no-unused-import.md) | Imported object name is not being used by the contract. | $~~~~~~~~$✔️ | |
2020
| [no-unused-vars](./rules/best-practices/no-unused-vars.md) | Variable "name" is unused. | $~~~~~~~~$✔️ | |
2121
| [one-contract-per-file](./rules/best-practices/one-contract-per-file.md) | Enforces the use of ONE Contract per file see [here](https://docs.soliditylang.org/en/v0.8.21/style-guide.html#contract-and-library-names) | $~~~~~~~~$✔️ | |
22-
| [payable-fallback](./rules/best-practices/payable-fallback.md) | When fallback is not payable and there is no receive function you will not be able to receive currency. | $~~~~~~~~$✔️ | |
22+
| [payable-fallback](./rules/best-practices/payable-fallback.md) | When fallback is not payable and there is no receive function you will not be able to receive currency. | | |
2323
| [reason-string](./rules/best-practices/reason-string.md) | Require or revert statement must have a reason string and check that each reason string is at most N characters long. | $~~~~~~~~$✔️ | |
24-
| [constructor-syntax](./rules/best-practices/constructor-syntax.md) | Constructors should use the new constructor keyword. | | |
24+
| [use-natspec](./rules/best-practices/use-natspec.md) | Enforces the presence and correctness of NatSpec tags. | $~~~~~~~~$✔️ | |
25+
| [constructor-syntax](./rules/best-practices/constructor-syntax.md) | Constructors should use the new constructor keyword. | $~~~~~~~~$✔️ | |
2526
2627

2728
## Style Guide Rules
2829

2930
| Rule Id | Error | Recommended | Deprecated |
3031
| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- | ------------ | ---------- |
31-
| [interface-starts-with-i](./rules/naming/interface-starts-with-i.md) | Solidity Interfaces names should start with an `I` | | |
32-
| [duplicated-imports](./rules/miscellaneous/duplicated-imports.md) | Check if an import is done twice in the same file and there is no alias | | |
32+
| [interface-starts-with-i](./rules/naming/interface-starts-with-i.md) | Solidity Interfaces names should start with an `I` | $~~~~~~~~$✔️ | |
33+
| [duplicated-imports](./rules/miscellaneous/duplicated-imports.md) | Check if an import is done twice in the same file and there is no alias | $~~~~~~~~$✔️ | |
3334
| [const-name-snakecase](./rules/naming/const-name-snakecase.md) | Constant name must be in capitalized SNAKE_CASE. (Does not check IMMUTABLES, use immutable-vars-naming) | $~~~~~~~~$✔️ | |
3435
| [contract-name-capwords](./rules/naming/contract-name-capwords.md) | Contract, Structs and Enums should be in CapWords. | $~~~~~~~~$✔️ | |
3536
| [event-name-capwords](./rules/naming/event-name-capwords.md) | Event name must be in CapWords. | $~~~~~~~~$✔️ | |
@@ -53,16 +54,16 @@ title: "Rule Index of Solhint"
5354

5455
| Rule Id | Error | Recommended | Deprecated |
5556
| ----------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | ------------ | ---------- |
56-
| [gas-calldata-parameters](./rules/gas-consumption/gas-calldata-parameters.md) | Suggest calldata keyword on function arguments when read only | | |
57+
| [gas-calldata-parameters](./rules/gas-consumption/gas-calldata-parameters.md) | Suggest calldata keyword on function arguments when read only | $~~~~~~~~$✔️ | |
5758
| [gas-custom-errors](./rules/gas-consumption/gas-custom-errors.md) | Enforces the use of Custom Errors over Require with strings error and Revert statements | $~~~~~~~~$✔️ | |
58-
| [gas-increment-by-one](./rules/gas-consumption/gas-increment-by-one.md) | Suggest increments by one, like this ++i instead of other type | | |
59-
| [gas-indexed-events](./rules/gas-consumption/gas-indexed-events.md) | Suggest indexed arguments on events for uint, bool and address | | |
59+
| [gas-increment-by-one](./rules/gas-consumption/gas-increment-by-one.md) | Suggest increments by one, like this ++i instead of other type | $~~~~~~~~$✔️ | |
60+
| [gas-indexed-events](./rules/gas-consumption/gas-indexed-events.md) | Suggest indexed arguments on events for uint, bool and address | $~~~~~~~~$✔️ | |
6061
| [gas-length-in-loops](./rules/gas-consumption/gas-length-in-loops.md) | Suggest replacing object.length in a loop condition to avoid calculation on each lap | | |
6162
| [gas-multitoken1155](./rules/gas-consumption/gas-multitoken1155.md) | ERC1155 is a cheaper non-fungible token than ERC721 | | |
6263
| [gas-named-return-values](./rules/gas-consumption/gas-named-return-values.md) | Enforce the return values of a function to be named | | |
63-
| [gas-small-strings](./rules/gas-consumption/gas-small-strings.md) | Keep strings smaller than 32 bytes | | |
64-
| [gas-strict-inequalities](./rules/gas-consumption/gas-strict-inequalities.md) | Suggest Strict Inequalities over non Strict ones | | |
65-
| [gas-struct-packing](./rules/gas-consumption/gas-struct-packing.md) | Suggest to re-arrange struct packing order when it is inefficient | | |
64+
| [gas-small-strings](./rules/gas-consumption/gas-small-strings.md) | Keep strings smaller than 32 bytes. Promote the use of custom errors | $~~~~~~~~$✔️ | |
65+
| [gas-strict-inequalities](./rules/gas-consumption/gas-strict-inequalities.md) | Suggest Strict Inequalities over non Strict ones | $~~~~~~~~$✔️ | |
66+
| [gas-struct-packing](./rules/gas-consumption/gas-struct-packing.md) | Suggest to re-arrange struct packing order when it is inefficient | $~~~~~~~~$✔️ | |
6667
6768

6869
## Miscellaneous

docs/rules/best-practices/code-complexity.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ This rule accepts an array of options:
2424
```json
2525
{
2626
"rules": {
27-
"code-complexity": ["warn",7]
27+
"code-complexity": [
28+
"warn",
29+
7
30+
]
2831
}
2932
}
3033
```

docs/rules/best-practices/constructor-syntax.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ title: "constructor-syntax | Solhint"
55
---
66

77
# constructor-syntax
8+
![Recommended Badge](https://img.shields.io/badge/-Recommended-brightgreen)
89
![Category Badge](https://img.shields.io/badge/-Best%20Practices%20Rules-informational)
910
![Default Severity Badge warn](https://img.shields.io/badge/Default%20Severity-warn-yellow)
11+
> The {"extends": "solhint:recommended"} property in a configuration file enables this rule.
12+
1013

1114
## Description
1215
Constructors should use the new constructor keyword.

docs/rules/best-practices/explicit-types.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ This rule accepts an array of options:
2727
```json
2828
{
2929
"rules": {
30-
"explicit-types": ["warn","explicit"]
30+
"explicit-types": [
31+
"warn",
32+
"explicit"
33+
]
3134
}
3235
}
3336
```

docs/rules/best-practices/function-max-lines.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ title: "function-max-lines | Solhint"
55
---
66

77
# function-max-lines
8+
![Recommended Badge](https://img.shields.io/badge/-Recommended-brightgreen)
89
![Category Badge](https://img.shields.io/badge/-Best%20Practices%20Rules-informational)
910
![Default Severity Badge warn](https://img.shields.io/badge/Default%20Severity-warn-yellow)
11+
> The {"extends": "solhint:recommended"} property in a configuration file enables this rule.
12+
1013

1114
## Description
1215
Function body contains "count" lines but allowed no more than maxlines.
@@ -24,7 +27,10 @@ This rule accepts an array of options:
2427
```json
2528
{
2629
"rules": {
27-
"function-max-lines": ["warn",50]
30+
"function-max-lines": [
31+
"warn",
32+
50
33+
]
2834
}
2935
}
3036
```

docs/rules/best-practices/max-line-length.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ This rule accepts an array of options:
2626
```json
2727
{
2828
"rules": {
29-
"max-line-length": ["error",120]
29+
"max-line-length": [
30+
"error",
31+
120
32+
]
3033
}
3134
}
3235
```

0 commit comments

Comments
 (0)