Skip to content

Commit

Permalink
Merge pull request #541 from protofire/gc-mutlitoken1155
Browse files Browse the repository at this point in the history
GC: mutlitoken1155 rule
  • Loading branch information
dbale-altoros authored Jan 19, 2024
2 parents e9342aa + b43a083 commit e6119ac
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 3 deletions.
1 change: 1 addition & 0 deletions conf/rulesets/solhint-all.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ module.exports = Object.freeze({
},
],
'constructor-syntax': 'warn',
'gas-multitoken1155': 'warn',
'comprehensive-interface': 'warn',
quotes: ['error', 'double'],
'const-name-snakecase': 'warn',
Expand Down
7 changes: 7 additions & 0 deletions docs/rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ title: "Rule Index of Solhint"
| [constructor-syntax](./rules/best-practises/constructor-syntax.md) | Constructors should use the new constructor keyword. | | |

## Gas Consumption Rules

| Rule Id | Error | Recommended | Deprecated |
| ------------------------------------------------------------------- | --------------------------------------------------- | ----------- | ---------- |
| [gas-multitoken1155](./rules/gas-consumption/gas-multitoken1155.md) | ERC1155 is a cheaper non-fungible token than ERC721 | | |

## Miscellaneous

| Rule Id | Error | Recommended | Deprecated |
Expand Down
38 changes: 38 additions & 0 deletions docs/rules/gas-consumption/gas-multitoken1155.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
warning: "This is a dynamically generated file. Do not edit manually."
layout: "default"
title: "gas-multitoken1155 | Solhint"
---

# gas-multitoken1155
![Category Badge](https://img.shields.io/badge/-Gas%20Consumption%20Rules-informational)
![Default Severity Badge warn](https://img.shields.io/badge/Default%20Severity-warn-yellow)

## Description
ERC1155 is a cheaper non-fungible token than ERC721

## Options
This rule accepts a string option of rule severity. Must be one of "error", "warn", "off". Default to warn.

### Example Config
```json
{
"rules": {
"gas-multitoken1155": "warn"
}
}
```

### Notes
- [source](https://www.rareskills.io/post/gas-optimization?postId=c9db474a-ff97-4fa3-a51d-fe13ccb8fe3b&utm_campaign=42ccb5d8-c2cc-4416-b661-8eec8368f72b&utm_source=so&utm_medium=mail&utm_content=40a3d3be-d07d-479e-af1d-6b2ef1b950da&cid=9619984a-b43c-4002-ba71-820fd72bb83a#viewer-8v8t9) of the rule initiciative

## Examples
This rule does not have examples.

## Version
This rule is introduced in the latest version.

## Resources
- [Rule source](https://github.com/protofire/solhint/tree/master/lib/rules/gas-consumption/gas-multitoken1155.js)
- [Document source](https://github.com/protofire/solhint/tree/master/docs/rules/gas-consumption/gas-multitoken1155.md)
- [Test cases](https://github.com/protofire/solhint/tree/master/test/rules/gas-consumption/gas-multitoken1155.js)
2 changes: 1 addition & 1 deletion e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "E2E tests for solhint",
"main": "index.js",
"scripts": {
"test": "mocha test.js formatters-test.js autofix-test.js"
"test": "mocha test.js formatters-test.js autofix-test.js --timeout 10000"
},
"author": "",
"license": "MIT",
Expand Down
45 changes: 45 additions & 0 deletions lib/rules/gas-consumption/gas-multitoken1155.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const BaseChecker = require('../base-checker')

const ruleId = 'gas-multitoken1155'
const meta = {
type: 'gas-consumption',

docs: {
description: 'ERC1155 is a cheaper non-fungible token than ERC721',
category: 'Gas Consumption Rules',
notes: [
{
note: '[source](https://www.rareskills.io/post/gas-optimization?postId=c9db474a-ff97-4fa3-a51d-fe13ccb8fe3b&utm_campaign=42ccb5d8-c2cc-4416-b661-8eec8368f72b&utm_source=so&utm_medium=mail&utm_content=40a3d3be-d07d-479e-af1d-6b2ef1b950da&cid=9619984a-b43c-4002-ba71-820fd72bb83a#viewer-8v8t9) of the rule initiciative',
},
],
},

isDefault: false,
recommended: false,
defaultSetup: 'warn',

schema: null,
}

class GasMultitoken1155 extends BaseChecker {
constructor(reporter) {
super(reporter, ruleId, meta)
}

hasERC721String(path) {
// Convert both the input string and the substring to lowercase for case-insensitive comparison
const lowercaseInput = path.toLowerCase()
const lowercaseSubstring = 'erc721'

// Check if the lowercase input string contains the lowercase substring
return lowercaseInput.includes(lowercaseSubstring)
}

ImportDirective(node) {
if (this.hasERC721String(node.path)) {
this.error(node, 'GC: ERC721 import found - Use of ERC1155 recommended')
}
}
}

module.exports = GasMultitoken1155
6 changes: 6 additions & 0 deletions lib/rules/gas-consumption/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const GasMultitoken1155 = require('./gas-multitoken1155')

// module.exports = function checkers(reporter, config, tokens) {
module.exports = function checkers(reporter, config) {
return [new GasMultitoken1155(reporter, config)]
}
2 changes: 2 additions & 0 deletions lib/rules/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const order = require('./order/index')
const bestPractises = require('./best-practises/index')
const deprecations = require('./deprecations/index')
const miscellaneous = require('./miscellaneous/index')
const gasConsumption = require('./gas-consumption/index')
const configObject = require('../config')
const { validSeverityMap } = require('../config/config-validator')

Expand Down Expand Up @@ -64,6 +65,7 @@ function coreRules(meta) {
...naming(reporter, config),
...order(reporter, tokens),
...security(reporter, config, inputSrc),
...gasConsumption(reporter, config),
]
}

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "solhint",
"version": "4.1.1",
"version": "4.2.0",
"description": "Solidity Code Linter",
"main": "lib/index.js",
"keywords": [
Expand All @@ -18,7 +18,7 @@
"scripts": {
"exec-tests": "nyc mocha --recursive && nyc report --reporter=text-lcov | coveralls",
"test:coverage": "npm run exec-tests",
"test": "mocha --recursive --timeout 10000",
"test": "mocha --recursive",
"lint": "eslint .",
"generate-rulesets": "node scripts/generate-rulesets.js && prettier --write conf/rulesets",
"docs": "node scripts/generate-rule-docs.js",
Expand Down
63 changes: 63 additions & 0 deletions test/rules/gas-consumption/gas-multitoken1155.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const assert = require('assert')
const linter = require('../../../lib/index')

const ERROR_MSG = 'GC: ERC721 import found - Use of ERC1155 recommended'

describe('Linter - gas-multitoken1155', () => {
it('should raise error', () => {
const code = `
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.4;
import '@openzeppelin/contracts/token/ERC722/ERC722.sol';
import '@openzeppelin/contracts/token/erc721.sol';
import '@openzeppelin/contracts/token/ERC721.sol';
contract A {}
`

const report = linter.processStr(code, {
rules: { 'gas-multitoken1155': 'error' },
})

assert.equal(report.errorCount, 2)
assert.equal(report.messages[0].message, ERROR_MSG)
assert.equal(report.messages[1].message, ERROR_MSG)
})

it('should raise error', () => {
const code = `
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.4;
import '@openzeppelin/contracts/token/ERC721/ERC722.sol';
contract A {}
`

const report = linter.processStr(code, {
rules: { 'gas-multitoken1155': 'error' },
})

assert.equal(report.errorCount, 1)
assert.equal(report.messages[0].message, ERROR_MSG)
})

it('should NOT raise error', () => {
const code = `
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.4;
import '@openzeppelin/contracts/token/ERC722/ERC722.sol';
import '@openzeppelin/contracts/token/erc20.sol';
contract A {}
`

const report = linter.processStr(code, {
rules: { 'gas-multitoken1155': 'error' },
})

assert.equal(report.errorCount, 0)
})
})

0 comments on commit e6119ac

Please sign in to comment.