From 9730459fa21b22e275b9fb26bcd42461d4e84bf9 Mon Sep 17 00:00:00 2001 From: tintinweb Date: Tue, 23 Nov 2021 19:19:56 +0100 Subject: [PATCH] add duperfinder --- src/rules/dupefinder.js | 58 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/rules/dupefinder.js diff --git a/src/rules/dupefinder.js b/src/rules/dupefinder.js new file mode 100644 index 0000000..653b6a6 --- /dev/null +++ b/src/rules/dupefinder.js @@ -0,0 +1,58 @@ +/** + * @author github.com/tintinweb + * @license MIT + * */ + +const { BaseRule } = require("./builtin"); +const utils = require('../utils'); +const {AstHashedContractSync, HASH_MODES} = require("solidity-doppelganger"); + +//["AST_EXACT", "AST_STRUCTURE"]; + +class DupeFinder extends BaseRule { + constructor(solgrep, selectedModes) { + super(solgrep); + this.selectedModes = selectedModes || HASH_MODES; + this.dupeDb = {}; // {hash: [file, file, ...]} + this.selectedModes.forEach(mode => this.dupeDb[mode] = {}); + } + + onProcess(sourceUnit) { + Object.values(sourceUnit.contracts).forEach(contract => { + HASH_MODES.forEach(mode => { + let hashAst = new AstHashedContractSync({mode:mode}, sourceUnit.filePath).fromAst(contract.ast) + if(!this.dupeDb[mode][hashAst.hash] || !Array.isArray(this.dupeDb[mode][hashAst.hash])){ + this.dupeDb[mode][hashAst.hash] = []; + } + this.dupeDb[mode][hashAst.hash].push(`${sourceUnit.filePath}::${contract.name}`) + }) + + }); + } + + onDirAnalyzed() { + this.solgrep.report(undefined, this, "DUPES", this.dupeDb); + } + onClose() { + var uniqueContracts = {}; + + this.selectedModes.forEach(mode => { + if(typeof uniqueContracts[mode] === "undefined"){ + uniqueContracts[mode] = 0; + } + uniqueContracts[mode] += Object.values(this.dupeDb[mode]).filter(v => v.length == 1).length; //number of contracts with unique hashes + this.dupeDb[mode] = utils.filterObjByValue(utils.sortObjByArrayLength(this.dupeDb[mode]), (v) => v.length > 1); + }) + console.log("") + console.log("ℹ️ Duplicate Contracts (Hash => SourceUnits):") + console.log(this.dupeDb) + console.log("") + console.log("ℹ️ Number of Unique Contracts per matching method:") + console.log(uniqueContracts) + } +} +DupeFinder.description = "Find Duplicate Contracts! Either 'similar' (AST fuzzy matching) or exact (AST structure) matches."; + +module.exports = { + DupeFinder +} \ No newline at end of file