Check inheritance tree consistency (#2727)
Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
This commit is contained in:
1
.github/workflows/test.yml
vendored
1
.github/workflows/test.yml
vendored
@ -29,6 +29,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
FORCE_COLOR: 1
|
FORCE_COLOR: 1
|
||||||
ENABLE_GAS_REPORT: true
|
ENABLE_GAS_REPORT: true
|
||||||
|
- run: npm run test:inheritance
|
||||||
- name: Print gas report
|
- name: Print gas report
|
||||||
run: cat gas-report.txt
|
run: cat gas-report.txt
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ pragma solidity ^0.8.0;
|
|||||||
import "../token/ERC1155/IERC1155Receiver.sol";
|
import "../token/ERC1155/IERC1155Receiver.sol";
|
||||||
import "../utils/introspection/ERC165.sol";
|
import "../utils/introspection/ERC165.sol";
|
||||||
|
|
||||||
contract ERC1155ReceiverMock is IERC1155Receiver, ERC165 {
|
contract ERC1155ReceiverMock is ERC165, IERC1155Receiver {
|
||||||
bytes4 private _recRetval;
|
bytes4 private _recRetval;
|
||||||
bool private _recReverts;
|
bool private _recReverts;
|
||||||
bytes4 private _batRetval;
|
bytes4 private _batRetval;
|
||||||
|
|||||||
132
package-lock.json
generated
132
package-lock.json
generated
@ -27,6 +27,7 @@
|
|||||||
"eth-sig-util": "^3.0.0",
|
"eth-sig-util": "^3.0.0",
|
||||||
"ethereumjs-util": "^7.0.7",
|
"ethereumjs-util": "^7.0.7",
|
||||||
"ethereumjs-wallet": "^1.0.1",
|
"ethereumjs-wallet": "^1.0.1",
|
||||||
|
"graphlib": "^2.1.8",
|
||||||
"hardhat": "^2.0.6",
|
"hardhat": "^2.0.6",
|
||||||
"hardhat-gas-reporter": "^1.0.4",
|
"hardhat-gas-reporter": "^1.0.4",
|
||||||
"keccak256": "^1.0.2",
|
"keccak256": "^1.0.2",
|
||||||
@ -38,6 +39,7 @@
|
|||||||
"prettier-plugin-solidity": "^1.0.0-beta.13",
|
"prettier-plugin-solidity": "^1.0.0-beta.13",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"solhint": "^3.3.6",
|
"solhint": "^3.3.6",
|
||||||
|
"solidity-ast": "^0.4.25",
|
||||||
"solidity-coverage": "^0.7.11",
|
"solidity-coverage": "^0.7.11",
|
||||||
"solidity-docgen": "^0.5.3",
|
"solidity-docgen": "^0.5.3",
|
||||||
"web3": "^1.3.0",
|
"web3": "^1.3.0",
|
||||||
@ -7713,7 +7715,104 @@
|
|||||||
"bundleDependencies": [
|
"bundleDependencies": [
|
||||||
"source-map-support",
|
"source-map-support",
|
||||||
"yargs",
|
"yargs",
|
||||||
"ethereumjs-util"
|
"ethereumjs-util",
|
||||||
|
"@types/bn.js",
|
||||||
|
"@types/node",
|
||||||
|
"@types/pbkdf2",
|
||||||
|
"@types/secp256k1",
|
||||||
|
"ansi-regex",
|
||||||
|
"ansi-styles",
|
||||||
|
"base-x",
|
||||||
|
"blakejs",
|
||||||
|
"bn.js",
|
||||||
|
"brorand",
|
||||||
|
"browserify-aes",
|
||||||
|
"bs58",
|
||||||
|
"bs58check",
|
||||||
|
"buffer-from",
|
||||||
|
"buffer-xor",
|
||||||
|
"camelcase",
|
||||||
|
"cipher-base",
|
||||||
|
"cliui",
|
||||||
|
"color-convert",
|
||||||
|
"color-name",
|
||||||
|
"create-hash",
|
||||||
|
"create-hmac",
|
||||||
|
"cross-spawn",
|
||||||
|
"decamelize",
|
||||||
|
"elliptic",
|
||||||
|
"emoji-regex",
|
||||||
|
"end-of-stream",
|
||||||
|
"ethereum-cryptography",
|
||||||
|
"ethjs-util",
|
||||||
|
"evp_bytestokey",
|
||||||
|
"execa",
|
||||||
|
"find-up",
|
||||||
|
"get-caller-file",
|
||||||
|
"get-stream",
|
||||||
|
"hash-base",
|
||||||
|
"hash.js",
|
||||||
|
"hmac-drbg",
|
||||||
|
"inherits",
|
||||||
|
"invert-kv",
|
||||||
|
"is-fullwidth-code-point",
|
||||||
|
"is-hex-prefixed",
|
||||||
|
"is-stream",
|
||||||
|
"isexe",
|
||||||
|
"keccak",
|
||||||
|
"lcid",
|
||||||
|
"locate-path",
|
||||||
|
"map-age-cleaner",
|
||||||
|
"md5.js",
|
||||||
|
"mem",
|
||||||
|
"mimic-fn",
|
||||||
|
"minimalistic-assert",
|
||||||
|
"minimalistic-crypto-utils",
|
||||||
|
"nice-try",
|
||||||
|
"node-addon-api",
|
||||||
|
"node-gyp-build",
|
||||||
|
"npm-run-path",
|
||||||
|
"once",
|
||||||
|
"os-locale",
|
||||||
|
"p-defer",
|
||||||
|
"p-finally",
|
||||||
|
"p-is-promise",
|
||||||
|
"p-limit",
|
||||||
|
"p-locate",
|
||||||
|
"p-try",
|
||||||
|
"path-exists",
|
||||||
|
"path-key",
|
||||||
|
"pbkdf2",
|
||||||
|
"pump",
|
||||||
|
"randombytes",
|
||||||
|
"readable-stream",
|
||||||
|
"require-directory",
|
||||||
|
"require-main-filename",
|
||||||
|
"ripemd160",
|
||||||
|
"rlp",
|
||||||
|
"safe-buffer",
|
||||||
|
"scrypt-js",
|
||||||
|
"secp256k1",
|
||||||
|
"semver",
|
||||||
|
"set-blocking",
|
||||||
|
"setimmediate",
|
||||||
|
"sha.js",
|
||||||
|
"shebang-command",
|
||||||
|
"shebang-regex",
|
||||||
|
"signal-exit",
|
||||||
|
"source-map",
|
||||||
|
"string_decoder",
|
||||||
|
"string-width",
|
||||||
|
"strip-ansi",
|
||||||
|
"strip-eof",
|
||||||
|
"strip-hex-prefix",
|
||||||
|
"util-deprecate",
|
||||||
|
"which",
|
||||||
|
"which-module",
|
||||||
|
"wrap-ansi",
|
||||||
|
"wrappy",
|
||||||
|
"y18n",
|
||||||
|
"yargs-parser"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -9040,6 +9139,15 @@
|
|||||||
"integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
|
"integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/graphlib": {
|
||||||
|
"version": "2.1.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz",
|
||||||
|
"integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"lodash": "^4.17.15"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/growl": {
|
"node_modules/growl": {
|
||||||
"version": "1.10.5",
|
"version": "1.10.5",
|
||||||
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
|
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
|
||||||
@ -15965,6 +16073,12 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/solidity-ast": {
|
||||||
|
"version": "0.4.25",
|
||||||
|
"resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.25.tgz",
|
||||||
|
"integrity": "sha512-8IpweS/vgHEpKvY4l0sfr3EsHk+JFIzRWqq/0JefRjzP/Wyi2xZYfx8aHlJ9kcEn2M2RCQK9PexuZ+scaa83OQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/solidity-comments-extractor": {
|
"node_modules/solidity-comments-extractor": {
|
||||||
"version": "0.0.7",
|
"version": "0.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz",
|
||||||
@ -20678,7 +20792,6 @@
|
|||||||
"integrity": "sha512-5vwpq6kbvwkQwKqAoOU3L72GZ3Ta8RRrewKj9OJRolx28KLJJ8Dg9Rf7obRwt5jQA9bkYd8gqzMTrI7H3xLfaw==",
|
"integrity": "sha512-5vwpq6kbvwkQwKqAoOU3L72GZ3Ta8RRrewKj9OJRolx28KLJJ8Dg9Rf7obRwt5jQA9bkYd8gqzMTrI7H3xLfaw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@oclif/config": "^1.15.1",
|
|
||||||
"@oclif/errors": "^1.3.3",
|
"@oclif/errors": "^1.3.3",
|
||||||
"@oclif/parser": "^3.8.3",
|
"@oclif/parser": "^3.8.3",
|
||||||
"@oclif/plugin-help": "^3",
|
"@oclif/plugin-help": "^3",
|
||||||
@ -27034,6 +27147,15 @@
|
|||||||
"integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
|
"integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"graphlib": {
|
||||||
|
"version": "2.1.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz",
|
||||||
|
"integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"lodash": "^4.17.15"
|
||||||
|
}
|
||||||
|
},
|
||||||
"growl": {
|
"growl": {
|
||||||
"version": "1.10.5",
|
"version": "1.10.5",
|
||||||
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
|
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
|
||||||
@ -32535,6 +32657,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"solidity-ast": {
|
||||||
|
"version": "0.4.25",
|
||||||
|
"resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.25.tgz",
|
||||||
|
"integrity": "sha512-8IpweS/vgHEpKvY4l0sfr3EsHk+JFIzRWqq/0JefRjzP/Wyi2xZYfx8aHlJ9kcEn2M2RCQK9PexuZ+scaa83OQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"solidity-comments-extractor": {
|
"solidity-comments-extractor": {
|
||||||
"version": "0.0.7",
|
"version": "0.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz",
|
||||||
|
|||||||
@ -28,6 +28,7 @@
|
|||||||
"release": "scripts/release/release.sh",
|
"release": "scripts/release/release.sh",
|
||||||
"version": "scripts/release/version.sh",
|
"version": "scripts/release/version.sh",
|
||||||
"test": "hardhat test",
|
"test": "hardhat test",
|
||||||
|
"test:inheritance": "node scripts/inheritanceOrdering artifacts/build-info/*",
|
||||||
"gas-report": "env ENABLE_GAS_REPORT=true npm run test"
|
"gas-report": "env ENABLE_GAS_REPORT=true npm run test"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
@ -64,6 +65,7 @@
|
|||||||
"eth-sig-util": "^3.0.0",
|
"eth-sig-util": "^3.0.0",
|
||||||
"ethereumjs-util": "^7.0.7",
|
"ethereumjs-util": "^7.0.7",
|
||||||
"ethereumjs-wallet": "^1.0.1",
|
"ethereumjs-wallet": "^1.0.1",
|
||||||
|
"graphlib": "^2.1.8",
|
||||||
"hardhat": "^2.0.6",
|
"hardhat": "^2.0.6",
|
||||||
"hardhat-gas-reporter": "^1.0.4",
|
"hardhat-gas-reporter": "^1.0.4",
|
||||||
"keccak256": "^1.0.2",
|
"keccak256": "^1.0.2",
|
||||||
@ -75,6 +77,7 @@
|
|||||||
"prettier-plugin-solidity": "^1.0.0-beta.13",
|
"prettier-plugin-solidity": "^1.0.0-beta.13",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"solhint": "^3.3.6",
|
"solhint": "^3.3.6",
|
||||||
|
"solidity-ast": "^0.4.25",
|
||||||
"solidity-coverage": "^0.7.11",
|
"solidity-coverage": "^0.7.11",
|
||||||
"solidity-docgen": "^0.5.3",
|
"solidity-docgen": "^0.5.3",
|
||||||
"web3": "^1.3.0",
|
"web3": "^1.3.0",
|
||||||
|
|||||||
38
scripts/inheritanceOrdering.js
Normal file
38
scripts/inheritanceOrdering.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const graphlib = require('graphlib');
|
||||||
|
const { findAll } = require('solidity-ast/utils');
|
||||||
|
const { _: artifacts } = require('yargs').argv;
|
||||||
|
|
||||||
|
for (const artifact of artifacts) {
|
||||||
|
const { output: solcOutput } = require(path.resolve(__dirname, '..', artifact));
|
||||||
|
|
||||||
|
const graph = new graphlib.Graph({ directed: true });
|
||||||
|
const names = {};
|
||||||
|
const linearized = [];
|
||||||
|
|
||||||
|
for (const source in solcOutput.contracts) {
|
||||||
|
for (const contractDef of findAll('ContractDefinition', solcOutput.sources[source].ast)) {
|
||||||
|
names[contractDef.id] = contractDef.name;
|
||||||
|
linearized.push(contractDef.linearizedBaseContracts);
|
||||||
|
|
||||||
|
contractDef.linearizedBaseContracts.forEach((c1, i, contracts) => contracts.slice(i + 1).forEach(c2 => {
|
||||||
|
graph.setEdge(c1, c2);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
graphlib.alg.findCycles(graph).forEach(([ c1, c2 ]) => {
|
||||||
|
console.log(`Conflict between ${names[c1]} and ${names[c2]} detected in the following dependency chains:`);
|
||||||
|
linearized
|
||||||
|
.filter(chain => chain.includes(parseInt(c1)) && chain.includes(parseInt(c2)))
|
||||||
|
.forEach(chain => {
|
||||||
|
const comp = chain.indexOf(c1) < chain.indexOf(c2) ? '>' : '<';
|
||||||
|
console.log(`- ${names[c1]} ${comp} ${names[c2]}: ${chain.reverse().map(id => names[id]).join(', ')}`);
|
||||||
|
});
|
||||||
|
process.exitCode = 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!process.exitCode) {
|
||||||
|
console.log('Contract ordering is consistent.');
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user