Skip to content

Commit

Permalink
Merge pull request #112 from nventuro/compiler-gt
Browse files Browse the repository at this point in the history
Add compiler-version rule.
  • Loading branch information
fvictorio committed May 8, 2019
2 parents 95f54d3 + f5228d6 commit ca9d6e5
Show file tree
Hide file tree
Showing 7 changed files with 280 additions and 19 deletions.
21 changes: 11 additions & 10 deletions docs/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ description: List of validation rules for Solhint - Solidity security, style gui

### Options
Default list of options are *false, "error", "warn"*. It supports by all rules.
It provides in format
It provides in format
```json
{
"rules": {
Expand All @@ -31,6 +31,7 @@ description: List of validation rules for Solhint - Solidity security, style gui
| **avoid-call-value** | Avoid to use ".call.value()()" | *[default](#options)* |
| **compiler-fixed** | Compiler version must be fixed | *[default](#options)* |
| **compiler-gt-0_4** | Use at least '0.4' compiler version | *[default](#options)* |
| **compiler-version** | Use a compiler version satisfying a semver requirement. | [*\<[default](#options)\>*,&nbsp;\<*version*\>] Default *version* is **'^0.5.8'**. |
| **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)* |
Expand All @@ -40,13 +41,13 @@ description: List of validation rules for Solhint - Solidity security, style gui
| **not-rely-on-block-hash** | Do not rely on "block.blockhash". Miners can influence its value. | *[default](#options)* |
| **not-rely-on-time** | Avoid to make time-based decisions in your business logic | *[default](#options)* |
| **avoid-low-level-calls** | Avoid to use low level calls. | *[default](#options)* |

\* \- All security rules implemented according [ConsenSys Guide for Smart Contracts](https://consensys.github.io/smart-contract-best-practices/recommendations/)

### Style Guide Rules

| Rule ID | Error | Options |
|-------------------------------|----------------------------------------------------|--------------------------------|
|-------------------------------|----------------------------------------------------|--------------------------------|
| **func-name-mixedcase** | Function name must be in camelCase | *[default](#options)* |
| **func-param-name-mixedcase** | Function param name must be in mixedCase | *[default](#options)* |
| **var-name-mixedcase** | Variable name must be in mixedCase | *[default](#options)* |
Expand All @@ -69,15 +70,15 @@ description: List of validation rules for Solhint - Solidity security, style gui
| **statement-indent** | Statement indentation is incorrect. | *[default](#options)* |
| **space-after-comma** | Comma must be separated from next element by space | *[default](#options)* |
| **no-spaces-before-semicolon**| Semicolon must not have spaces before | *[default](#options)* |

\* \- All style guide rules implemented according [Solidity Style Guide](
http://solidity.readthedocs.io/en/develop/style-guide.html)

### 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**. |
|-------------------------------|----------------------------------------------------|-------------------------------|
| **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)* |
Expand Down
9 changes: 9 additions & 0 deletions lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,16 @@ module.exports = {
return _.isNumber(configVal) && configVal > 0 ? configVal : defaultValue
},

getStringByPath(path, defaultValue) {
const configVal = _.get(this, path)
return _.isString(configVal) ? configVal : defaultValue
},

getNumber(ruleName, defaultValue) {
return this.getNumberByPath(`rules["${ruleName}"][1]`, defaultValue)
},

getString(ruleName, defaultValue) {
return this.getStringByPath(`rules["${ruleName}"][1]`, defaultValue)
}
}
53 changes: 53 additions & 0 deletions lib/rules/security/compiler-version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
const semver = require('semver')
const BaseChecker = require('./../base-checker')

const ruleId = 'compiler-version'
const meta = {
type: 'security',

docs: {
description: `Compiler version must satisfy a semver requirement.`,
category: 'Security Rules'
},

isDefault: false,
recommended: true,
defaultSetup: ['error', '^0.5.7'],

schema: [
{
type: 'array',
items: [{ type: 'string' }],
uniqueItems: true,
minItems: 2
}
]
}

class CompilerVersionChecker extends BaseChecker {
constructor(reporter, config) {
super(reporter, ruleId, meta)

this.requirement = (config && config.getString(ruleId, '^0.5.8')) || '^0.5.8'
}

exitVersionConstraint(ctx) {
const versionNode =
(this.isVersionOperator(ctx.children[0]) && ctx.children[1]) || ctx.children[0]

if (!semver.satisfies(versionNode.getText(), this.requirement)) {
this.error(
ctx,
`Compiler version ${versionNode.getText()} does not satisfy the ${
this.requirement
} semver requirement`
)
}
}

isVersionOperator(ctx) {
return ctx.constructor.name.includes('VersionOperator')
}
}

module.exports = CompilerVersionChecker
4 changes: 3 additions & 1 deletion lib/rules/security/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const AvoidThrowChecker = require('./avoid-throw')
const AvoidTxOriginChecker = require('./avoid-tx-origin')
const CheckSendResultChecker = require('./check-send-result')
const CompilerFixedChecker = require('./compiler-fixed')
const CompilerVersionChecker = require('./compiler-version')
const CompilerGT04Checker = require('./compiler-gt-0_4')
const FuncVisibilityChecker = require('./func-visibility')
const MarkCallableContractsChecker = require('./mark-callable-contracts')
Expand All @@ -18,7 +19,7 @@ const NotRelyOnTimeChecker = require('./not-rely-on-time')
const ReentrancyChecker = require('./reentrancy')
const StateVisibilityChecker = require('./state-visibility')

module.exports = function security(reporter) {
module.exports = function security(reporter, config) {
return [
new AvoidCallValueChecker(reporter),
new AvoidLowLevelCallsChecker(reporter),
Expand All @@ -28,6 +29,7 @@ module.exports = function security(reporter) {
new AvoidTxOriginChecker(reporter),
new CheckSendResultChecker(reporter),
new CompilerFixedChecker(reporter),
new CompilerVersionChecker(reporter, config),
new CompilerGT04Checker(reporter),
new FuncVisibilityChecker(reporter),
new MarkCallableContractsChecker(reporter),
Expand Down
42 changes: 35 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
"glob": "^7.1.3",
"ignore": "^4.0.6",
"js-yaml": "^3.12.0",
"lodash": "^4.17.11"
"lodash": "^4.17.11",
"semver": "^6.0.0"
},
"devDependencies": {
"assert": "1.4.1",
Expand Down

0 comments on commit ca9d6e5

Please sign in to comment.