or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-interface.mdconfiguration-management.mdcore-processing.mdindex.mdoutput-formatting.mdresult-reporting.mdrules-system.md

rules-system.mddocs/

0

# Rules System

1

2

Comprehensive rule system with 64+ rules across 7 categories for security, style, and best practices validation. The rules system is the core of Solhint's linting capabilities, providing extensive validation of Solidity code.

3

4

## Capabilities

5

6

### Main Rules Function

7

8

Creates and returns array of enabled rule checkers based on configuration.

9

10

```javascript { .api }

11

/**

12

* Creates and returns array of enabled rule checkers

13

* @param {Reporter} reporter - Reporter instance for collecting issues

14

* @param {Object} configVals - Configuration values

15

* @param {string} inputSrc - Source code being linted

16

* @param {Array} tokens - Parsed tokens

17

* @param {string} fileName - File name being processed

18

* @returns {Array} Array of enabled rule checker instances

19

*/

20

function checkers(reporter, configVals, inputSrc, tokens, fileName);

21

```

22

23

**Usage Examples:**

24

25

```javascript

26

const checkers = require('solhint/lib/rules/index');

27

const Reporter = require('solhint/lib/reporter');

28

29

// Create rule checkers (typically done internally)

30

const reporter = new Reporter([], {});

31

const config = { rules: { 'func-visibility': 'error' } };

32

const ruleCheckers = checkers(reporter, config, sourceCode, tokens, 'test.sol');

33

34

console.log(`Enabled rules: ${ruleCheckers.length}`);

35

```

36

37

## Rule Categories

38

39

### Security Rules (16 rules)

40

41

Rules focused on identifying potential security vulnerabilities and unsafe patterns.

42

43

**Key Rules:**

44

- `avoid-call-value` - Avoid using `.call.value()()`

45

- `avoid-low-level-calls` - Avoid low-level calls like `call`, `delegatecall`, `staticcall`

46

- `avoid-tx-origin` - Avoid using `tx.origin` for authorization

47

- `check-send-result` - Check result of `send()` calls

48

- `compiler-version` - Enforce specific compiler version constraints

49

- `func-visibility` - Require explicit function visibility declarations

50

- `reentrancy` - Detect potential reentrancy vulnerabilities

51

- `state-visibility` - Require explicit state variable visibility

52

53

**Configuration Examples:**

54

55

```javascript

56

{

57

"rules": {

58

"avoid-low-level-calls": "error",

59

"compiler-version": ["error", "^0.8.0"],

60

"func-visibility": "error",

61

"reentrancy": "warn"

62

}

63

}

64

```

65

66

### Naming Rules (13 rules)

67

68

Rules for enforcing consistent naming conventions across Solidity code.

69

70

**Key Rules:**

71

- `const-name-snakecase` - Constants in SCREAMING_SNAKE_CASE

72

- `contract-name-capwords` - Contracts, structs, enums in CapWords

73

- `event-name-capwords` - Events in CapWords

74

- `func-name-mixedcase` - Functions in mixedCase

75

- `modifier-name-mixedcase` - Modifiers in mixedCase

76

- `var-name-mixedcase` - Variables in mixedCase

77

- `private-vars-leading-underscore` - Private variables with leading underscore

78

79

**Configuration Examples:**

80

81

```javascript

82

{

83

"rules": {

84

"contract-name-capwords": "error",

85

"func-name-mixedcase": "error",

86

"var-name-mixedcase": "warn",

87

"private-vars-leading-underscore": ["error", { "strict": false }]

88

}

89

}

90

```

91

92

### Best Practices Rules (15 rules)

93

94

Rules promoting good coding practices, code quality, and maintainability.

95

96

**Key Rules:**

97

- `code-complexity` - Limit cyclomatic complexity

98

- `explicit-types` - Require or forbid explicit types (uint256 vs uint)

99

- `function-max-lines` - Limit function length

100

- `max-line-length` - Limit line length

101

- `no-console` - Forbid console.log statements

102

- `no-empty-blocks` - Forbid empty code blocks

103

- `no-global-import` - Require specific imports instead of global imports

104

- `no-unused-vars` - Detect unused variables

105

- `reason-string` - Require reason strings in require/revert statements

106

107

**Configuration Examples:**

108

109

```javascript

110

{

111

"rules": {

112

"code-complexity": ["warn", 7],

113

"function-max-lines": ["warn", 50],

114

"max-line-length": ["warn", 120],

115

"no-console": "error",

116

"reason-string": ["warn", { "maxLength": 64 }]

117

}

118

}

119

```

120

121

### Order Rules (4 rules)

122

123

Rules for code organization and element ordering within contracts.

124

125

**Key Rules:**

126

- `imports-on-top` - Import statements must be at file top

127

- `imports-order` - Enforce specific import ordering

128

- `ordering` - Enforce element ordering within contracts

129

- `visibility-modifier-order` - Visibility modifier must come first

130

131

**Configuration Examples:**

132

133

```javascript

134

{

135

"rules": {

136

"imports-on-top": "error",

137

"ordering": "warn",

138

"visibility-modifier-order": "error"

139

}

140

}

141

```

142

143

### Miscellaneous Rules (4 rules)

144

145

General utility rules for various code quality checks.

146

147

**Key Rules:**

148

- `comprehensive-interface` - Ensure interface completeness

149

- `duplicated-imports` - Prevent duplicate imports

150

- `import-path-check` - Validate import paths

151

- `quotes` - Enforce quote style consistency

152

153

**Configuration Examples:**

154

155

```javascript

156

{

157

"rules": {

158

"quotes": ["warn", "double"],

159

"duplicated-imports": "error"

160

}

161

}

162

```

163

164

### Deprecations Rules (1 rule)

165

166

Rules for identifying and migrating deprecated language features.

167

168

**Key Rules:**

169

- `constructor-syntax` - Use new constructor keyword syntax

170

171

### Gas Consumption Rules (11 rules)

172

173

Rules focused on gas optimization and efficient contract design.

174

175

**Key Rules:**

176

- `gas-calldata-parameters` - Use calldata for read-only function parameters

177

- `gas-custom-errors` - Use custom errors instead of string reasons

178

- `gas-indexed-events` - Use indexed event parameters appropriately

179

- `gas-length-in-loops` - Avoid repeated length calculations in loops

180

- `gas-struct-packing` - Optimize struct field packing

181

182

**Configuration Examples:**

183

184

```javascript

185

{

186

"rules": {

187

"gas-custom-errors": "warn",

188

"gas-indexed-events": ["warn", { "maxIndexed": 3 }],

189

"gas-length-in-loops": "warn"

190

}

191

}

192

```

193

194

## Rule Configuration Patterns

195

196

### Severity Levels

197

198

```javascript

199

{

200

"rules": {

201

"func-visibility": "error", // Block deployment

202

"max-line-length": "warn", // Show warning

203

"no-console": "off" // Disabled

204

}

205

}

206

```

207

208

### Rules with Options

209

210

Many rules accept configuration options:

211

212

```javascript

213

{

214

"rules": {

215

"compiler-version": ["error", "^0.8.0"],

216

"code-complexity": ["warn", 10],

217

"max-line-length": ["warn", 120],

218

"gas-indexed-events": ["warn", { "maxIndexed": 3 }],

219

"private-vars-leading-underscore": ["error", { "strict": true }]

220

}

221

}

222

```

223

224

### Built-in Rule Sets

225

226

```javascript

227

{

228

"extends": "solhint:recommended", // Recommended rules

229

// OR

230

"extends": "solhint:all", // All rules enabled

231

"rules": {

232

"no-console": "off" // Override specific rules

233

}

234

}

235

```

236

237

## Rule Implementation Structure

238

239

Each rule follows a consistent pattern:

240

241

```javascript { .api }

242

class RuleChecker {

243

constructor(reporter, config) {

244

this.reporter = reporter;

245

this.config = config;

246

this.ruleId = 'rule-name';

247

}

248

249

// Visit AST nodes

250

visitFunctionDefinition(node) {

251

// Check rule conditions

252

if (violatesRule(node)) {

253

this.reporter.error(node, this.ruleId, 'Error message');

254

}

255

}

256

}

257

```

258

259

**Rule Metadata:**

260

261

```javascript { .api }

262

class RuleChecker {

263

static get meta() {

264

return {

265

type: 'best-practices',

266

docs: {

267

description: 'Rule description',

268

category: 'Best Practices'

269

},

270

schema: {

271

type: 'object',

272

properties: {

273

maxLength: { type: 'integer' }

274

}

275

}

276

};

277

}

278

}

279

```

280

281

## Plugin System

282

283

Solhint supports external rule plugins:

284

285

```javascript

286

{

287

"plugins": ["prettier", "security"],

288

"rules": {

289

"prettier/prettier": "error",

290

"security/no-hardcoded-secrets": "warn"

291

}

292

}

293

```

294

295

**Plugin Structure:**

296

297

```javascript

298

// solhint-plugin-security/index.js

299

module.exports = [

300

require('./rules/no-hardcoded-secrets'),

301

require('./rules/safe-math-usage')

302

];

303

```

304

305

## Rule Execution Flow

306

307

1. **Initialization**: Rules are instantiated based on configuration

308

2. **AST Traversal**: Parser visits each AST node

309

3. **Rule Checking**: Matching rules inspect nodes and report issues

310

4. **Result Collection**: Reporter collects all issues

311

5. **Output Formatting**: Results are formatted for display

312

313

## Rule Development

314

315

Rules can be categorized by their inspection approach:

316

317

- **AST Node Visitors**: Inspect specific node types (functions, variables, etc.)

318

- **Token Analyzers**: Examine raw token sequences

319

- **Source Code Processors**: Analyze source text directly

320

- **Cross-Reference Checkers**: Track relationships between code elements

321

322

## Error Handling in Rules

323

324

Rules should handle edge cases gracefully:

325

326

```javascript

327

visitFunctionDefinition(node) {

328

try {

329

// Rule logic

330

if (node.body && node.body.statements) {

331

// Process statements

332

}

333

} catch (error) {

334

// Log but don't crash

335

console.warn(`Rule ${this.ruleId} failed:`, error.message);

336

}

337

}

338

```

339

340

## Rule Performance

341

342

- Rules execute during AST traversal, so efficiency matters

343

- Cache expensive computations when possible

344

- Avoid deep object traversals in hot paths

345

- Use early returns to skip unnecessary processing