Socket
Socket
Sign inDemoInstall

solhint

Package Overview
Dependencies
Maintainers
1
Versions
85
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

solhint - npm Package Compare versions

Comparing version 1.1.5 to 1.1.6

.npmignore

23

docs/readme.md
## Solhint Project
[![Build Status](https://travis-ci.org/tokenhouse/solhint.svg?branch=master)](https://travis-ci.org/tokenhouse/solhint)
[![Build Status](https://travis-ci.org/protofire/solhint.svg?branch=master)](https://travis-ci.org/protofire/solhint)
[![npm version](http://img.shields.io/npm/v/solhint.svg?style=flat)](https://npmjs.org/package/solhint
"View this project on npm")
[![Coverage Status](https://coveralls.io/repos/github/tokenhouse/solhint/badge.svg?branch=master)](
https://coveralls.io/github/tokenhouse/solhint?branch=master)
[![Coverage Status](https://coveralls.io/repos/github/protofire/solhint/badge.svg?branch=master)](
https://coveralls.io/github/protofire/solhint?branch=master)

@@ -18,3 +18,3 @@ This is an open source project for linting [solidity](http://solidity.readthedocs.io/en/develop/) code. This project

npm install -g solhint
solhint *.sol
solhint -V
```

@@ -24,2 +24,10 @@

For linting Solidity files you need to execute next command
```sh
solhint *.sol **/*.sol <any_other_glob_pattern>
```
Solhint command details
```text

@@ -48,6 +56,13 @@ Usage: solhint [options] <file> [...other_files]

- [Configuration](./configuration.html)
- [Formatters](https://eslint.org/docs/user-guide/formatters/)
- [Use Solhint in Your Application](./use-in-app.html)
### IDE Integrations
- [Sublime Text 3](https://packagecontrol.io/search/solhint)
- [Atom](https://atom.io/packages/atom-solidity-linter)
- [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=idrabenia.solidity-solhint)
### Licence
MIT

39

docs/rules.md

@@ -13,7 +13,7 @@

### Security Rules
### Security Error Codes:
| Rule ID | Error | Options |
|-------------------------------|-------------------------------------------------|---------------------------|
| **reentrancy** | Possible reentrancy vulnerabilities. Avoid state changes after transfer. | *[default](#options)* |
| **avoid-sha3** | Use "keccak256" instead of deprecated "sha3" | *[default](#options)* |

@@ -29,9 +29,15 @@ | **avoid-suicide** | Use "selfdestruct" instead of deprecated "suicide" | *[default](#options)* |

| **no-complex-fallback** | Fallback function must be simple | *[default](#options)* |
| **mark-callable-contracts** | Explicitly mark all external contracts as trusted or untrusted | *[default](#options)*|
| **multiple-sends** | Avoid multiple calls of "send" method in single transaction | *[default](#options)*|
| **mark-callable-contracts** | Explicitly mark all external contracts as trusted or untrusted | *[default](#options)* |
| **multiple-sends** | Avoid multiple calls of "send" method in single transaction | *[default](#options)* |
| **no-simple-event-func-name** | Event and function names must be different | *[default](#options)* |
| **avoid-tx-origin** | Avoid to use tx.origin | *[default](#options)* |
| **no-inline-assembly** | Avoid to use inline assembly. It is acceptable only in rare cases | *[default](#options)* |
| **not-rely-on-block-hash** | Do not rely on "block.blockhash". Miners can influence its value. | *[default](#options)* |
| **avoid-low-level-calls** | Avoid to use low level calls. | *[default](#options)* |
### Style Guide Codes:
\* \- All security rules implemented according [ConsenSys Guide for Smart Contracts](
https://github.com/ConsenSys/smart-contract-best-practices#recommendations-for-smart-contract-security-in-solidity)
### Style Guide Rules
| Rule ID | Error | Options |

@@ -62,12 +68,15 @@ |-------------------------------|----------------------------------------------------|--------------------------------|

### Best Practise Codes:
\* \- All style guide rules implemented according [Solidity Style Guide](
http://solidity.readthedocs.io/en/develop/style-guide.html)
| Rule ID | Error | Options |
|-------------------------------|----------------------------------------------------|-------------------------------|
| **max-line-length** | Line length must be no more than *maxlen*. | [*\<[default](#options)\>*,&nbsp;*\<maxlen\>*] Default *maxlen* is **120**. |
| **payable-fallback** | When fallback is not payable you will not be able to receive ethers | *[default](#options)* |
| **no-empty-blocks** | Code contains empty block | *[default](#options)* |
| **no-unused-vars** | Variable "name" is unused | *[default](#options)* |
| **function-max-lines** | Function body contains "count" lines but allowed no more than *maxlines*. | [*\<[default](#options)\>*,&nbsp;*\<maxlines\>*] Default *maxlines* is **45**. |
| **code-complexity** | Function has cyclomatic complexity "current" but allowed no more than *maxcompl*. | [*\<[default](#options)\>*,&nbsp;*\<maxcompl\>*] Default *maxcompl* is **7**. |
| **max-states-count** | Contract has "some count" states declarations but allowed no more than *maxstates* | [*\<[default](#options)\>*,&nbsp;*\<maxstates\>*] Default *maxstates* is **15**. |
### Best Practise Rules
| Rule ID | Error | Options |
|-------------------------------|----------------------------------------------------|-------------------------------|
| **max-line-length** | Line length must be no more than *maxlen*. | [*\<[default](#options)\>*,&nbsp;*\<maxlen\>*] Default *maxlen* is **120**. |
| **payable-fallback** | When fallback is not payable you will not be able to receive ethers | *[default](#options)* |
| **no-empty-blocks** | Code contains empty block | *[default](#options)* |
| **no-unused-vars** | Variable "name" is unused | *[default](#options)* |
| **function-max-lines** | Function body contains "count" lines but allowed no more than *maxlines*. | [*\<[default](#options)\>*,&nbsp;*\<maxlines\>*] Default *maxlines* is **45**. |
| **code-complexity** | Function has cyclomatic complexity "current" but allowed no more than *maxcompl*. | [*\<[default](#options)\>*,&nbsp;*\<maxcompl\>*] Default *maxcompl* is **7**. |
| **max-states-count** | Contract has "some count" states declarations but allowed no more than *maxstates* | [*\<[default](#options)\>*,&nbsp;*\<maxstates\>*] Default *maxstates* is **15**. |

@@ -19,3 +19,3 @@ ### Use Solhint in Your Application

**linter.parseStr**:
**linter.processStr**:

@@ -28,3 +28,3 @@ - Arguments:

**linter.parseFile**:
**linter.processFile**:

@@ -37,3 +37,3 @@ - Arguments:

**linter.parsePath**
**linter.processPath**

@@ -40,0 +40,0 @@ - Arguments:

@@ -71,3 +71,2 @@

}
}

@@ -74,0 +73,0 @@

@@ -83,2 +83,20 @@

TreeTraversing.hasMethodCalls = function (ctx, methodNames) {
const text = ctx.getText();
return methodNames.some(i => text.startsWith(`${i}(`));
};
TreeTraversing.findPropertyInParents = function (ctx, property) {
let curCtx = ctx;
while (curCtx !== null && !curCtx[property]) {
curCtx = curCtx.parentCtx;
}
return curCtx && curCtx[property];
};
module.exports = TreeTraversing;

@@ -27,3 +27,3 @@ const fs = require('fs');

function processFile (file, config={}) {
function processFile (file, config) {
const report = processStr(fs.readFileSync(file).toString(), config);

@@ -35,3 +35,3 @@ report.file = file;

function processPath(path, config={}) {
function processPath(path, config) {
return new Promise((res) =>

@@ -38,0 +38,0 @@ glob(path, (err, files) => res(files.map(curFile => processFile(curFile, config))))

@@ -5,3 +5,3 @@ const CommentDirectiveParser = require('./comment-directive-parser');

class Reporter {
constructor (tokenStream, config = {}) {
constructor (tokenStream, config) {
this.commentDirectiveParser = new CommentDirectiveParser(tokenStream);

@@ -17,3 +17,3 @@ this.reports = [];

addMessage(interval, defaultSeverity, message, ruleId='') {
addMessage(interval, defaultSeverity, message, ruleId) {
const line = this.tokenStream.get(interval.start).line;

@@ -25,3 +25,3 @@ const charAtLine = this.tokenStream.get(interval.start).column;

addMessageExplicitLine(line, column, defaultSeverity, message, ruleId='') {
addMessageExplicitLine(line, column, defaultSeverity, message, ruleId) {
const configSeverity = this.severityOf(ruleId);

@@ -28,0 +28,0 @@

const BaseChecker = require('./../base-checker');
const { hasSpaceBefore, onSameLine, prevToken, startOf } = require('./../../common/tokens');
const { typeOf } = require('./../../common/tree-traversing');
const _ = require('lodash');

@@ -33,31 +34,40 @@

validateBlock(ctx) {
if (typeOf(ctx.parentCtx) === 'functionDefinition') {
return;
const bracket = new Block(ctx).openBracket();
if (bracket && !bracket.isCorrectAligned()) {
this._error(bracket);
}
}
this._validateOpenBracket(ctx);
_error({ ctx, errorMessage }) {
this.error(ctx, 'bracket-align', errorMessage);
}
}
_validateOpenBracket(ctx) {
const bracket = this._openBracket(ctx);
if (bracket && !this._isCorrectAligned(bracket)) {
this._error(bracket);
}
class Block {
constructor (ctx) {
this.ctx = ctx;
}
_isCorrectAligned(bracket) {
return hasSpaceBefore(bracket) && onSameLine(startOf(bracket), prevToken(bracket));
openBracket () {
const bracketCtx = this._openBracketCtx();
return (bracketCtx) ? this._makeBracketObj(bracketCtx) : null;
}
_openBracket(ctx) {
const children = ctx.children;
const bracket = children && children.filter(i => i.getText() === '{');
isFunctionDefinition () {
return typeOf(this.ctx.parentCtx) === 'functionDefinition';
}
return (bracket && bracket.length === 1) ? bracket[0] : null;
_openBracketCtx () {
const children = this.ctx.children;
const openBrackets = children && children.filter(i => i.getText() === '{');
return (_.size(openBrackets) === 1) ? openBrackets[0] : null;
}
_error(ctx) {
const message = 'Open bracket must be on same line. It must be indented by other constructions by space';
this.error(ctx, 'bracket-align', message);
_makeBracketObj(ctx) {
return (this.isFunctionDefinition()) ? new FunctionOpenBracket(ctx) : new UsualOpenBracket(ctx);
}

@@ -67,2 +77,39 @@ }

class OpenBracket {
constructor (ctx) {
this.ctx = ctx;
this.errorMessage = 'Open bracket must be indented by other constructions by space';
}
isCorrectAligned () {
return hasSpaceBefore(this.ctx);
}
}
class FunctionOpenBracket extends OpenBracket {
}
class UsualOpenBracket extends OpenBracket {
constructor (ctx) {
super(ctx);
this.errorMessage = 'Open bracket must be on same line. It must be indented by other constructions by space';
}
isOnSameLineWithPreviousToken () {
const ctx = this.ctx;
return onSameLine(startOf(ctx), prevToken(ctx));
}
isCorrectAligned () {
return super.isCorrectAligned() && this.isOnSameLineWithPreviousToken();
}
}
module.exports = BracketsAlign;
const BaseChecker = require('./../base-checker');
const { hasSpace, nextTokenFromToken, BaseTokenList, Token, AlignValidatable } = require('./../../common/tokens');
const { noSpaces, prevTokenFromToken } = require('./../../common/tokens');

@@ -44,11 +45,27 @@

isCorrectAligned() {
return this._isNoSpacesBefore() && (this._isSpaceAfter() || this._isCommaInEndOfExpression());
}
_isNoSpacesBefore() {
return noSpaces(this.curToken, this._prevToken());
}
_isSpaceAfter() {
return hasSpace(this._nextToken(), this.curToken);
}
_isCommaInEndOfExpression() {
const curToken = this.curToken;
const _nextToken = nextTokenFromToken(this.tokens, curToken);
return hasSpace(_nextToken, curToken) || this._isCommaInEndOfExpression(_nextToken);
return [')', '}'].includes(_nextToken.text);
}
_isCommaInEndOfExpression(token) {
return [')', '}'].includes(token.text);
_prevToken() {
return prevTokenFromToken(this.tokens, this.curToken);
}
_nextToken() {
return nextTokenFromToken(this.tokens, this.curToken);
}
}

@@ -55,0 +72,0 @@

@@ -11,2 +11,6 @@ const ExternalCallChecker = require('./external-call');

const NotRelyOnTimeChecker = require('./not-rely-on-time');
const NoInlineAssemblyChecker = require('./no-inline-assembly');
const NotRelyOnBlockHashChecker = require('./not-rely-on-block-hash');
const ReentrancyChecker = require('./reentrancy');
const AvoidLowLevelCallsChecker = require('./avoid-low-level-calls');

@@ -25,4 +29,8 @@

new AvoidTxOriginChecker(reporter),
new NotRelyOnTimeChecker(reporter)
new NotRelyOnTimeChecker(reporter),
new NoInlineAssemblyChecker(reporter),
new NotRelyOnBlockHashChecker(reporter),
new ReentrancyChecker(reporter),
new AvoidLowLevelCallsChecker(reporter)
];
};

@@ -48,3 +48,2 @@ const TreeTraversing = require('./../../common/tree-traversing');

}
}

@@ -51,0 +50,0 @@

@@ -11,10 +11,21 @@ const BaseChecker = require('./../base-checker');

exitIdentifier(ctx) {
if (ctx.getText() === 'now') {
this.warn(ctx, 'not-rely-on-time', 'Avoid to make time-based decisions in your business logic');
this._textNotAllowed(ctx, 'now');
}
exitExpression(ctx) {
this._textNotAllowed(ctx, 'block.timestamp');
}
_textNotAllowed(ctx, avoidedName) {
if (ctx.getText() === avoidedName) {
this._warn(ctx);
}
}
_warn(ctx) {
this.warn(ctx, 'not-rely-on-time', 'Avoid to make time-based decisions in your business logic');
}
}
module.exports = NotRelyOnTimeChecker;
module.exports = NotRelyOnTimeChecker;
{
"name": "solhint",
"version": "1.1.5",
"version": "1.1.6",
"description": "Solidity Code Linter",

@@ -16,4 +16,4 @@ "main": "solhint.js",

],
"homepage": "https://tokenhouse.github.io/solhint/",
"repository": "https://github.com/tokenhouse/solhint",
"homepage": "https://protofire.github.io/solhint/",
"repository": "https://github.com/protofire/solhint",
"scripts": {

@@ -30,3 +30,2 @@ "exec-tests": "nyc -x \"**/grammar/**\" mocha && nyc report --reporter=text-lcov | coveralls",

"antlr4": "4.7.0",
"colors": "1.1.2",
"commander": "2.11.0",

@@ -33,0 +32,0 @@ "glob": "7.1.2",

## Solhint Project
[![Build Status](https://travis-ci.org/tokenhouse/solhint.svg?branch=master)](https://travis-ci.org/tokenhouse/solhint)
[![Build Status](https://travis-ci.org/protofire/solhint.svg?branch=master)](https://travis-ci.org/protofire/solhint)
[![npm version](http://img.shields.io/npm/v/solhint.svg?style=flat)](https://npmjs.org/package/solhint
"View this project on npm")
[![Coverage Status](https://coveralls.io/repos/github/tokenhouse/solhint/badge.svg?branch=master)](
https://coveralls.io/github/tokenhouse/solhint?branch=master)
[![Coverage Status](https://coveralls.io/repos/github/protofire/solhint/badge.svg?branch=master)](
https://coveralls.io/github/protofire/solhint?branch=master)
This is an open source project for linting [solidity](http://solidity.readthedocs.io/en/develop/) code. This project
provide both **security** and **style guide** validations.
This is an open source project for linting [Solidity](http://solidity.readthedocs.io/en/develop/) code. This project
provide both **Security** and **Style Guide** validations.

@@ -23,2 +23,10 @@ ### Installation

For linting Solidity files you need to execute next command
```sh
solhint *.sol **/*.sol <any_other_glob_pattern>
```
Solhint command description
```text

@@ -33,3 +41,3 @@ Usage: solhint [options] <file> [...other_files]

-V, --version output the version number
-f, --formatter [name] Report formatter name (stylish, table, tap, unix)'
-f, --formatter [name] report formatter name (stylish, table, tap, unix)'
-h, --help output usage information

@@ -40,7 +48,6 @@

stdin [options]
init-config
stdin [options] put source code to stdin of this utility
init-config create sample solhint config in current folder
```
### Configuration

@@ -110,66 +117,82 @@

### Security Error Codes:
### Security Rules
| Rule ID | Error |
|-------------------------------|----------------------------------------------------|
| **avoid-sha3** | Use "keccak256" instead of deprecated "sha3" |
| **avoid-suicide** | Use "selfdestruct" instead of deprecated "suicide" |
| **avoid-throw** | "throw" is deprecated, avoid to use it |
| **func-visibility** | Explicitly mark visibility in function |
| **state-visibility** | Explicitly mark visibility of state |
| **check-send-result** | Check result of "send" call |
| **avoid-call-value** | Avoid to use ".call.value()()" |
| **compiler-fixed** | Compiler version must be fixed |
| **compiler-gt-0_4** | Use at least '0.4' compiler version |
| **no-complex-fallback** | Fallback function must be simple |
| **mark-callable-contracts** | Explicitly mark all external contracts as trusted or untrusted |
| **multiple-sends** | Avoid multiple calls of "send" method in single transaction |
| **no-simple-event-func-name** | Event and function names must be different |
| **avoid-tx-origin** | Avoid to use tx.origin |
| Rule ID | Error |
|-------------------------------|-------------------------------------------------------------------|
| **reentrancy** | Possible reentrancy vulnerabilities. Avoid state changes after transfer. |
| **avoid-sha3** | Use "keccak256" instead of deprecated "sha3" |
| **avoid-suicide** | Use "selfdestruct" instead of deprecated "suicide" |
| **avoid-throw** | "throw" is deprecated, avoid to use it |
| **func-visibility** | Explicitly mark visibility in function |
| **state-visibility** | Explicitly mark visibility of state |
| **check-send-result** | Check result of "send" call |
| **avoid-call-value** | Avoid to use ".call.value()()" |
| **compiler-fixed** | Compiler version must be fixed |
| **compiler-gt-0_4** | Use at least '0.4' compiler version |
| **no-complex-fallback** | Fallback function must be simple |
| **mark-callable-contracts** | Explicitly mark all external contracts as trusted or untrusted |
| **multiple-sends** | Avoid multiple calls of "send" method in single transaction |
| **no-simple-event-func-name** | Event and function names must be different |
| **avoid-tx-origin** | Avoid to use tx.origin |
| **no-inline-assembly** | Avoid to use inline assembly. It is acceptable only in rare cases |
| **not-rely-on-block-hash** | Do not rely on "block.blockhash". Miners can influence its value. |
| **avoid-low-level-calls** | Avoid to use low level calls. |
### Style Guide Codes:
\* \- All security rules implemented according [ConsenSys Guide for Smart Contracts](
https://github.com/ConsenSys/smart-contract-best-practices#recommendations-for-smart-contract-security-in-solidity)
| Rule ID | Error |
|-------------------------------|----------------------------------------------------|
| **func-name-mixedcase** | Function name must be in camelCase |
| **func-param-name-mixedcase** | Function param name must be in mixedCase |
| **var-name-mixedcase** | Variable name must be in mixedCase |
| **event-name-camelcase** | Event name must be in CamelCase |
| **const-name-snakecase** | Constant name must be in SNAKE_CASE |
| **modifier-name-mixedcase** | Modifier name must be in mixedCase |
| **contract-name-camelcase** | Contract name must be in CamelCase |
| **use-forbidden-name** | Avoid to use letters 'I', 'l', 'O' as identifiers |
| **visibility-modifier-order** | Visibility modifier must be first in list of modifiers |
| **imports-on-top** | Import statements must be on top |
| **two-lines-top-level-separator** | Definition must be surrounded with two blank line indent |
| **func-order** | Function order is incorrect |
| **quotes** | Use double quotes for string literals |
| **no-mix-tabs-and-spaces** | Mixed tabs and spaces |
| **indent** | Indentation is incorrect |
### Style Guide Rules
| Rule ID | Error |
|-------------------------------|---------------------------------------------------------------------------|
| **func-name-mixedcase** | Function name must be in camelCase |
| **func-param-name-mixedcase** | Function param name must be in mixedCase |
| **var-name-mixedcase** | Variable name must be in mixedCase |
| **event-name-camelcase** | Event name must be in CamelCase |
| **const-name-snakecase** | Constant name must be in SNAKE_CASE |
| **modifier-name-mixedcase** | Modifier name must be in mixedCase |
| **contract-name-camelcase** | Contract name must be in CamelCase |
| **use-forbidden-name** | Avoid to use letters 'I', 'l', 'O' as identifiers |
| **visibility-modifier-order** | Visibility modifier must be first in list of modifiers |
| **imports-on-top** | Import statements must be on top |
| **two-lines-top-level-separator** | Definition must be surrounded with two blank line indent |
| **func-order** | Function order is incorrect |
| **quotes** | Use double quotes for string literals |
| **no-mix-tabs-and-spaces** | Mixed tabs and spaces |
| **indent** | Indentation is incorrect |
| **bracket-align** | Open bracket must be on same line. It must be indented by other constructions by space |
| **array-declaration-spaces** | Array declaration must not contains spaces |
| **separate-by-one-line-in-contract** | Definitions inside contract / library must be separated by one line |
| **expression-indent** | Expression indentation is incorrect. |
| **statement-indent** | Statement indentation is incorrect. |
| **space-after-comma** | Comma must be separated from next element by space |
| **no-spaces-before-semicolon**| Semicolon must not have spaces before |
| **array-declaration-spaces** | Array declaration must not contains spaces |
| **separate-by-one-line-in-contract** | Definitions inside contract / library must be separated by one line|
| **expression-indent** | Expression indentation is incorrect. |
| **statement-indent** | Statement indentation is incorrect. |
| **space-after-comma** | Comma must be separated from next element by space |
| **no-spaces-before-semicolon**| Semicolon must not have spaces before |
### Best Practise Codes:
\* \- All style guide rules implemented according [Solidity Style Guide](
http://solidity.readthedocs.io/en/develop/style-guide.html)
| Rule ID | Error |
|-------------------------------|----------------------------------------------------|
| **max-line-length** | Line length must be no more than 120 but current length is 121. |
| **payable-fallback** | When fallback is not payable you will not be able to receive ethers |
| **no-empty-blocks** | Code contains empty block |
| **no-unused-vars** | Variable "name" is unused |
| **function-max-lines** | Function body contains "count" lines but allowed no more than "maxLines" lines |
| **code-complexity** | Function has cyclomatic complexity "current" but allowed no more than "max" |
| **max-states-count** | Contract has "curCount" states declarations but allowed no more than "max" |
### Best Practise Rules
| Rule ID | Error |
|-------------------------------|----------------------------------------------------------------------------------|
| **max-line-length** | Line length must be no more than 120 but current length is 121. |
| **payable-fallback** | When fallback is not payable you will not be able to receive ethers |
| **no-empty-blocks** | Code contains empty block |
| **no-unused-vars** | Variable "name" is unused |
| **function-max-lines** | Function body contains "count" lines but allowed no more than "maxLines" lines |
| **code-complexity** | Function has cyclomatic complexity "current" but allowed no more than "max" |
| **max-states-count** | Contract has "curCount" states declarations but allowed no more than "max" |
### Documentation
Related documentation you may find [there](https://tokenhouse.github.io/solhint/).
Related documentation you may find [there](https://protofire.github.io/solhint/).
### IDE Integrations
- **[Sublime Text 3](https://packagecontrol.io/search/solhint)**
- **[Atom](https://atom.io/packages/atom-solidity-linter)**
- **[Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=idrabenia.solidity-solhint)**
### Licence
MIT

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc