remix-analyzer with eslint

pull/8/head
aniket-engg 4 years ago
parent ef8c4b0449
commit c63d39985a
  1. 41
      .eslintrc
  2. 7
      libs/remix-analyzer/.eslintrc
  3. 2537
      libs/remix-analyzer/package-lock.json
  4. 1
      libs/remix-analyzer/package.json
  5. 2
      libs/remix-analyzer/src/solidity-analyzer/index.ts
  6. 11
      libs/remix-analyzer/src/solidity-analyzer/modules/abstractAstView.ts
  7. 7
      libs/remix-analyzer/src/solidity-analyzer/modules/assignAndCompare.ts
  8. 7
      libs/remix-analyzer/src/solidity-analyzer/modules/blockBlockhash.ts
  9. 9
      libs/remix-analyzer/src/solidity-analyzer/modules/blockTimestamp.ts
  10. 8
      libs/remix-analyzer/src/solidity-analyzer/modules/checksEffectsInteraction.ts
  11. 4
      libs/remix-analyzer/src/solidity-analyzer/modules/constantFunctions.ts
  12. 5
      libs/remix-analyzer/src/solidity-analyzer/modules/deleteDynamicArrays.ts
  13. 5
      libs/remix-analyzer/src/solidity-analyzer/modules/deleteFromDynamicArray.ts
  14. 7
      libs/remix-analyzer/src/solidity-analyzer/modules/erc20Decimals.ts
  15. 5
      libs/remix-analyzer/src/solidity-analyzer/modules/etherTransferInLoop.ts
  16. 5
      libs/remix-analyzer/src/solidity-analyzer/modules/forLoopIteratesOverDynamicArray.ts
  17. 2
      libs/remix-analyzer/src/solidity-analyzer/modules/functionCallGraph.ts
  18. 4
      libs/remix-analyzer/src/solidity-analyzer/modules/gasCosts.ts
  19. 5
      libs/remix-analyzer/src/solidity-analyzer/modules/guardConditions.ts
  20. 5
      libs/remix-analyzer/src/solidity-analyzer/modules/inlineAssembly.ts
  21. 7
      libs/remix-analyzer/src/solidity-analyzer/modules/intDivisionTruncate.ts
  22. 11
      libs/remix-analyzer/src/solidity-analyzer/modules/lowLevelCalls.ts
  23. 6
      libs/remix-analyzer/src/solidity-analyzer/modules/noReturn.ts
  24. 7
      libs/remix-analyzer/src/solidity-analyzer/modules/selfdestruct.ts
  25. 9
      libs/remix-analyzer/src/solidity-analyzer/modules/similarVariableNames.ts
  26. 23
      libs/remix-analyzer/src/solidity-analyzer/modules/staticAnalysisCommon.ts
  27. 5
      libs/remix-analyzer/src/solidity-analyzer/modules/stringBytesLength.ts
  28. 7
      libs/remix-analyzer/src/solidity-analyzer/modules/thisLocal.ts
  29. 7
      libs/remix-analyzer/src/solidity-analyzer/modules/txOrigin.ts
  30. 56
      libs/remix-analyzer/src/types.ts
  31. 25
      libs/remix-analyzer/tsconfig.json
  32. 12
      libs/remix-analyzer/tsconfig.lib.json
  33. 8664
      package-lock.json
  34. 42
      package.json
  35. 14
      workspace.json

@ -0,0 +1,41 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module",
"project": "./tsconfig.json"
},
"ignorePatterns": ["**/*"],
"plugins": ["@typescript-eslint", "@nrwl/nx"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"prettier",
"prettier/@typescript-eslint"
],
"rules": {
"@typescript-eslint/explicit-member-accessibility": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-parameter-properties": "off",
"@nrwl/nx/enforce-module-boundaries": [
"error",
{
"enforceBuildableLibDependency": true,
"allow": [],
"depConstraints": [
{ "sourceTag": "*", "onlyDependOnLibsWithTags": ["*"] }
]
}
]
},
"overrides": [
{
"files": ["*.tsx"],
"rules": {
"@typescript-eslint/no-unused-vars": "off"
}
}
]
}

@ -0,0 +1,7 @@
{
"extends": "../../.eslintrc",
"rules": {
"@typescript-eslint/no-explicit-any": "off"
},
"ignorePatterns": ["!**/*"]
}

File diff suppressed because it is too large Load Diff

@ -43,7 +43,6 @@
"babel-plugin-transform-object-assign": "^6.22.0", "babel-plugin-transform-object-assign": "^6.22.0",
"babel-preset-es2015": "^6.24.0", "babel-preset-es2015": "^6.24.0",
"npm-install-version": "^6.0.2", "npm-install-version": "^6.0.2",
"standard": "^7.0.1",
"tape": "^4.6.0", "tape": "^4.6.0",
"ts-node": "^8.6.2", "ts-node": "^8.6.2",
"typescript": "^3.7.5" "typescript": "^3.7.5"

@ -35,7 +35,7 @@ export default class staticAnalysisRunner {
let reports: AnalysisReport[] = [] let reports: AnalysisReport[] = []
// Also provide convenience analysis via the AST walker. // Also provide convenience analysis via the AST walker.
const walker = new AstWalker() const walker = new AstWalker()
for (let k in compilationResult.sources) { for (const k in compilationResult.sources) {
walker.walkFull(compilationResult.sources[k].ast, walker.walkFull(compilationResult.sources[k].ast,
(node: any) => { (node: any) => {
modules.map((item: ModuleObj) => { modules.map((item: ModuleObj) => {

@ -8,10 +8,10 @@ type WrapFunction = ((contracts: ContractHLAst[], isSameName: boolean) => Report
export default class abstractAstView { export default class abstractAstView {
contracts: ContractHLAst[] = [] contracts: ContractHLAst[] = []
currentContractIndex: number = -1 currentContractIndex = -1
currentFunctionIndex: number = -1 currentFunctionIndex = -1
currentModifierIndex: number = -1 currentModifierIndex = -1
isFunctionNotModifier: boolean = false isFunctionNotModifier = false
/* /*
file1: contract c{} file1: contract c{}
file2: import "file1" as x; contract c{} file2: import "file1" as x; contract c{}
@ -20,7 +20,7 @@ export default class abstractAstView {
Additionally the fullQuallified function names e.g. [contractName].[functionName](param1Type, param2Type, ... ) must be prefixed to Additionally the fullQuallified function names e.g. [contractName].[functionName](param1Type, param2Type, ... ) must be prefixed to
fully support this and when inheritance is resolved it must include alias resolving e.g x.c = file1.c fully support this and when inheritance is resolved it must include alias resolving e.g x.c = file1.c
*/ */
multipleContractsWithSameName: boolean = false multipleContractsWithSameName = false
/** /**
* Builds a higher level AST view. I creates a list with each contract as an object in it. * Builds a higher level AST view. I creates a list with each contract as an object in it.
@ -102,6 +102,7 @@ export default class abstractAstView {
} }
build_report (wrap: WrapFunction): ReportFunction { build_report (wrap: WrapFunction): ReportFunction {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
return (compilationResult: CompilationResult) => { return (compilationResult: CompilationResult) => {
this.resolveStateVariablesInHierarchy(this.contracts) this.resolveStateVariablesInHierarchy(this.contracts)
return wrap(this.contracts, this.multipleContractsWithSameName) return wrap(this.contracts, this.multipleContractsWithSameName)

@ -6,8 +6,8 @@ import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, BlockAstNod
export default class assignAndCompare implements AnalyzerModule { export default class assignAndCompare implements AnalyzerModule {
warningNodes: ExpressionStatementAstNode[] = [] warningNodes: ExpressionStatementAstNode[] = []
name: string = `Result not used: ` name = `Result not used: `
description: string = `The result of an operation not used` description = `The result of an operation not used`
category: ModuleCategory = category.MISC category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = { version: SupportedVersion = {
@ -18,8 +18,9 @@ export default class assignAndCompare implements AnalyzerModule {
if (node?.nodeType && isSubScopeWithTopLevelUnAssignedBinOp(node)) getUnAssignedTopLevelBinOps(node).forEach((n) => this.warningNodes.push(n)) if (node?.nodeType && isSubScopeWithTopLevelUnAssignedBinOp(node)) getUnAssignedTopLevelBinOps(node).forEach((n) => this.warningNodes.push(n))
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] { report (compilationResults: CompilationResult): ReportObj[] {
return this.warningNodes.map((item, i) => { return this.warningNodes.map((item) => {
return { return {
warning: 'A binary operation yields a value that is not used further. This is often caused by confusing assignment (=) and comparison (==).', warning: 'A binary operation yields a value that is not used further. This is often caused by confusing assignment (=) and comparison (==).',
location: item.src location: item.src

@ -5,8 +5,8 @@ import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, Compilation
export default class blockBlockhash implements AnalyzerModule { export default class blockBlockhash implements AnalyzerModule {
warningNodes: FunctionCallAstNode[] = [] warningNodes: FunctionCallAstNode[] = []
name: string = `Block hash: ` name = `Block hash: `
description: string = `Can be influenced by miners` description = `Can be influenced by miners`
category: ModuleCategory = category.SECURITY category: ModuleCategory = category.SECURITY
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = { version: SupportedVersion = {
@ -17,8 +17,9 @@ export default class blockBlockhash implements AnalyzerModule {
if (node.nodeType === 'FunctionCall' && isBlockBlockHashAccess(node)) this.warningNodes.push(node) if (node.nodeType === 'FunctionCall' && isBlockBlockHashAccess(node)) this.warningNodes.push(node)
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] { report (compilationResults: CompilationResult): ReportObj[] {
return this.warningNodes.map((item, i) => { return this.warningNodes.map((item) => {
return { return {
warning: `Use of "blockhash": "blockhash(uint blockNumber)" is used to access the last 256 block hashes. warning: `Use of "blockhash": "blockhash(uint blockNumber)" is used to access the last 256 block hashes.
A miner computes the block hash by "summing up" the information in the current block mined. A miner computes the block hash by "summing up" the information in the current block mined.

@ -7,8 +7,8 @@ import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, Compilation
export default class blockTimestamp implements AnalyzerModule { export default class blockTimestamp implements AnalyzerModule {
warningNowNodes: IdentifierAstNode[] = [] warningNowNodes: IdentifierAstNode[] = []
warningblockTimestampNodes: MemberAccessAstNode[] = [] warningblockTimestampNodes: MemberAccessAstNode[] = []
name: string = `Block timestamp: ` name = `Block timestamp: `
description: string = `Can be influenced by miners` description = `Can be influenced by miners`
category: ModuleCategory = category.SECURITY category: ModuleCategory = category.SECURITY
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = { version: SupportedVersion = {
@ -20,15 +20,16 @@ export default class blockTimestamp implements AnalyzerModule {
else if (node.nodeType === "MemberAccess" && isBlockTimestampAccess(node)) this.warningblockTimestampNodes.push(node) else if (node.nodeType === "MemberAccess" && isBlockTimestampAccess(node)) this.warningblockTimestampNodes.push(node)
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] { report (compilationResults: CompilationResult): ReportObj[] {
return this.warningNowNodes.map((item, i) => { return this.warningNowNodes.map((item) => {
return { return {
warning: `Use of "now": "now" does not mean current time. "now" is an alias for "block.timestamp". warning: `Use of "now": "now" does not mean current time. "now" is an alias for "block.timestamp".
"block.timestamp" can be influenced by miners to a certain degree, be careful.`, "block.timestamp" can be influenced by miners to a certain degree, be careful.`,
location: item.src, location: item.src,
more: 'https://solidity.readthedocs.io/en/develop/units-and-global-variables.html?highlight=block.timestamp#block-and-transaction-properties' more: 'https://solidity.readthedocs.io/en/develop/units-and-global-variables.html?highlight=block.timestamp#block-and-transaction-properties'
} }
}).concat(this.warningblockTimestampNodes.map((item, i) => { }).concat(this.warningblockTimestampNodes.map((item) => {
return { return {
warning: `Use of "block.timestamp": "block.timestamp" can be influenced by miners to a certain degree. warning: `Use of "block.timestamp": "block.timestamp" can be influenced by miners to a certain degree.
That means that a miner can "choose" the block.timestamp, to a certain degree, to change the outcome of a transaction in the mined block.`, That means that a miner can "choose" the block.timestamp, to a certain degree, to change the outcome of a transaction in the mined block.`,

@ -9,8 +9,8 @@ import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, ContractHLA
InlineAssemblyAstNode, ReportFunction, VisitFunction, FunctionCallGraph, SupportedVersion } from './../../types' InlineAssemblyAstNode, ReportFunction, VisitFunction, FunctionCallGraph, SupportedVersion } from './../../types'
export default class checksEffectsInteraction implements AnalyzerModule { export default class checksEffectsInteraction implements AnalyzerModule {
name: string = `Check-effects-interaction: ` name = `Check-effects-interaction: `
description: string = `Potential reentrancy bugs` description = `Potential reentrancy bugs`
category: ModuleCategory = category.SECURITY category: ModuleCategory = category.SECURITY
algorithm: ModuleAlgorithm = algorithm.HEURISTIC algorithm: ModuleAlgorithm = algorithm.HEURISTIC
version: SupportedVersion = { version: SupportedVersion = {
@ -68,8 +68,8 @@ export default class checksEffectsInteraction implements AnalyzerModule {
} }
private isPotentialVulnerableFunction (func: FunctionHLAst, context: Context): boolean { private isPotentialVulnerableFunction (func: FunctionHLAst, context: Context): boolean {
let isPotentialVulnerable: boolean = false let isPotentialVulnerable = false
let interaction: boolean = false let interaction = false
func.relevantNodes.forEach((node) => { func.relevantNodes.forEach((node) => {
if (isInteraction(node)) { if (isInteraction(node)) {
interaction = true interaction = true

@ -10,8 +10,8 @@ import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, ContractCal
FunctionHLAst, VariableDeclarationAstNode, FunctionCallGraph, FunctionCallAstNode, VisitFunction, ReportFunction, SupportedVersion} from './../../types' FunctionHLAst, VariableDeclarationAstNode, FunctionCallGraph, FunctionCallAstNode, VisitFunction, ReportFunction, SupportedVersion} from './../../types'
export default class constantFunctions implements AnalyzerModule { export default class constantFunctions implements AnalyzerModule {
name: string = `Constant/View/Pure functions: ` name = `Constant/View/Pure functions: `
description: string = `Potentially constant/view/pure functions` description = `Potentially constant/view/pure functions`
category: ModuleCategory = category.MISC category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.HEURISTIC algorithm: ModuleAlgorithm = algorithm.HEURISTIC
version: SupportedVersion = { version: SupportedVersion = {

@ -5,8 +5,8 @@ import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, Compilation
export default class deleteDynamicArrays implements AnalyzerModule { export default class deleteDynamicArrays implements AnalyzerModule {
rel: UnaryOperationAstNode[] = [] rel: UnaryOperationAstNode[] = []
name: string = `Delete dynamic array: ` name = `Delete dynamic array: `
description: string = `Use require/assert to ensure complete deletion` description = `Use require/assert to ensure complete deletion`
category: ModuleCategory = category.GAS category: ModuleCategory = category.GAS
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = { version: SupportedVersion = {
@ -17,6 +17,7 @@ export default class deleteDynamicArrays implements AnalyzerModule {
if (isDeleteOfDynamicArray(node)) this.rel.push(node) if (isDeleteOfDynamicArray(node)) this.rel.push(node)
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] { report (compilationResults: CompilationResult): ReportObj[] {
return this.rel.map((node) => { return this.rel.map((node) => {
return { return {

@ -5,8 +5,8 @@ import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, Compilation
export default class deleteFromDynamicArray implements AnalyzerModule { export default class deleteFromDynamicArray implements AnalyzerModule {
relevantNodes: UnaryOperationAstNode[] = [] relevantNodes: UnaryOperationAstNode[] = []
name: string = `Delete from dynamic array: ` name = `Delete from dynamic array: `
description: string = `'delete' leaves a gap in array` description = `'delete' leaves a gap in array`
category: ModuleCategory = category.MISC category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = { version: SupportedVersion = {
@ -17,6 +17,7 @@ export default class deleteFromDynamicArray implements AnalyzerModule {
if (isDeleteFromDynamicArray(node) && !isMappingIndexAccess(node.subExpression)) this.relevantNodes.push(node) if (isDeleteFromDynamicArray(node) && !isMappingIndexAccess(node.subExpression)) this.relevantNodes.push(node)
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] { report (compilationResults: CompilationResult): ReportObj[] {
return this.relevantNodes.map((node) => { return this.relevantNodes.map((node) => {
return { return {

@ -6,8 +6,8 @@ import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, VisitFuncti
FunctionHLAst, VariableDeclarationAstNode, SupportedVersion} from './../../types' FunctionHLAst, VariableDeclarationAstNode, SupportedVersion} from './../../types'
export default class erc20Decimals implements AnalyzerModule { export default class erc20Decimals implements AnalyzerModule {
name: string = `ERC20: ` name = `ERC20: `
description: string = `'decimals' should be 'uint8'` description = `'decimals' should be 'uint8'`
category: ModuleCategory = category.ERC category: ModuleCategory = category.ERC
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = { version: SupportedVersion = {
@ -15,9 +15,12 @@ export default class erc20Decimals implements AnalyzerModule {
} }
abstractAst: AbstractAst = new AbstractAst() abstractAst: AbstractAst = new AbstractAst()
// eslint-disable-next-line @typescript-eslint/no-unused-vars
visit: VisitFunction = this.abstractAst.build_visit((node: any) => false) visit: VisitFunction = this.abstractAst.build_visit((node: any) => false)
report: ReportFunction = this.abstractAst.build_report(this._report.bind(this)) report: ReportFunction = this.abstractAst.build_report(this._report.bind(this))
// eslint-disable-next-line @typescript-eslint/no-unused-vars
private _report (contracts: ContractHLAst[], multipleContractsWithSameName: boolean): ReportObj[] { private _report (contracts: ContractHLAst[], multipleContractsWithSameName: boolean): ReportObj[] {
const warnings: ReportObj[] = [] const warnings: ReportObj[] = []

@ -6,8 +6,8 @@ import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, Compilation
export default class etherTransferInLoop implements AnalyzerModule { export default class etherTransferInLoop implements AnalyzerModule {
relevantNodes: ExpressionStatementAstNode[] = [] relevantNodes: ExpressionStatementAstNode[] = []
name: string = `Ether transfer in loop: ` name = `Ether transfer in loop: `
description: string = `Transferring Ether in a for/while/do-while loop` description = `Transferring Ether in a for/while/do-while loop`
category: ModuleCategory = category.GAS category: ModuleCategory = category.GAS
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = { version: SupportedVersion = {
@ -29,6 +29,7 @@ export default class etherTransferInLoop implements AnalyzerModule {
} }
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] { report (compilationResults: CompilationResult): ReportObj[] {
return this.relevantNodes.map((node) => { return this.relevantNodes.map((node) => {
return { return {

@ -5,8 +5,8 @@ import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, Compilation
export default class forLoopIteratesOverDynamicArray implements AnalyzerModule { export default class forLoopIteratesOverDynamicArray implements AnalyzerModule {
relevantNodes: ForStatementAstNode[] = [] relevantNodes: ForStatementAstNode[] = []
name: string = `For loop over dynamic array: ` name = `For loop over dynamic array: `
description: string = `Iterations depend on dynamic array's size` description = `Iterations depend on dynamic array's size`
category: ModuleCategory = category.GAS category: ModuleCategory = category.GAS
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = { version: SupportedVersion = {
@ -23,6 +23,7 @@ export default class forLoopIteratesOverDynamicArray implements AnalyzerModule {
} }
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] { report (compilationResults: CompilationResult): ReportObj[] {
return this.relevantNodes.map((node) => { return this.relevantNodes.map((node) => {
return { return {

@ -69,7 +69,7 @@ export function analyseCallGraph (callGraph: Record<string, ContractCallGraph>,
return analyseCallGraphInternal(callGraph, funcName, context, (a, b) => a || b, nodeCheck, {}) return analyseCallGraphInternal(callGraph, funcName, context, (a, b) => a || b, nodeCheck, {})
} }
function analyseCallGraphInternal (callGraph: Record<string, ContractCallGraph>, funcName: string, context: Context, combinator: Function, nodeCheck: ((node: any, context: Context) => boolean), visited : Record<string, boolean>): boolean { function analyseCallGraphInternal (callGraph: Record<string, ContractCallGraph>, funcName: string, context: Context, combinator, nodeCheck: ((node: any, context: Context) => boolean), visited : Record<string, boolean>): boolean {
const current: FunctionCallGraph | undefined = resolveCallGraphSymbol(callGraph, funcName) const current: FunctionCallGraph | undefined = resolveCallGraphSymbol(callGraph, funcName)
if (current === undefined || visited[funcName] === true) return true if (current === undefined || visited[funcName] === true) return true

@ -5,8 +5,8 @@ import { ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, Compiled
FunctionDefinitionAstNode, VariableDeclarationAstNode, SupportedVersion } from './../../types' FunctionDefinitionAstNode, VariableDeclarationAstNode, SupportedVersion } from './../../types'
export default class gasCosts implements AnalyzerModule { export default class gasCosts implements AnalyzerModule {
name: string = `Gas costs: ` name = `Gas costs: `
description: string = `Too high gas requirement of functions` description = `Too high gas requirement of functions`
category: ModuleCategory = category.GAS category: ModuleCategory = category.GAS
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = { version: SupportedVersion = {

@ -5,8 +5,8 @@ import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, Compilation
export default class guardConditions implements AnalyzerModule { export default class guardConditions implements AnalyzerModule {
guards: FunctionCallAstNode[] = [] guards: FunctionCallAstNode[] = []
name: string = `Guard conditions: ` name = `Guard conditions: `
description: string = `Ensure appropriate use of require/assert` description = `Ensure appropriate use of require/assert`
category: ModuleCategory = category.MISC category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = { version: SupportedVersion = {
@ -17,6 +17,7 @@ export default class guardConditions implements AnalyzerModule {
if (isRequireCall(node) || isAssertCall(node)) this.guards.push(node) if (isRequireCall(node) || isAssertCall(node)) this.guards.push(node)
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] { report (compilationResults: CompilationResult): ReportObj[] {
return this.guards.map((node) => { return this.guards.map((node) => {
return { return {

@ -4,8 +4,8 @@ import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, Compilation
export default class inlineAssembly implements AnalyzerModule { export default class inlineAssembly implements AnalyzerModule {
inlineAssNodes: InlineAssemblyAstNode[] = [] inlineAssNodes: InlineAssemblyAstNode[] = []
name: string = `Inline assembly: ` name = `Inline assembly: `
description: string = `Inline assembly used` description = `Inline assembly used`
category: ModuleCategory = category.SECURITY category: ModuleCategory = category.SECURITY
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = { version: SupportedVersion = {
@ -16,6 +16,7 @@ export default class inlineAssembly implements AnalyzerModule {
if(node.nodeType === 'InlineAssembly') this.inlineAssNodes.push(node) if(node.nodeType === 'InlineAssembly') this.inlineAssNodes.push(node)
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] { report (compilationResults: CompilationResult): ReportObj[] {
return this.inlineAssNodes.map((node) => { return this.inlineAssNodes.map((node) => {
return { return {

@ -5,8 +5,8 @@ import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, Compilation
export default class intDivisionTruncate implements AnalyzerModule { export default class intDivisionTruncate implements AnalyzerModule {
warningNodes: BinaryOperationAstNode[] = [] warningNodes: BinaryOperationAstNode[] = []
name: string = `Data truncated: ` name = `Data truncated: `
description: string = `Division on int/uint values truncates the result` description = `Division on int/uint values truncates the result`
category: ModuleCategory = category.MISC category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = { version: SupportedVersion = {
@ -17,8 +17,9 @@ export default class intDivisionTruncate implements AnalyzerModule {
if (isIntDivision(node)) this.warningNodes.push(node) if (isIntDivision(node)) this.warningNodes.push(node)
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] { report (compilationResults: CompilationResult): ReportObj[] {
return this.warningNodes.map((item, i) => { return this.warningNodes.map((item) => {
return { return {
warning: 'Division of integer values yields an integer value again. That means e.g. 10 / 100 = 0 instead of 0.1 since the result is an integer again. This does not hold for division of (only) literal values since those yield rational constants.', warning: 'Division of integer values yields an integer value again. That means e.g. 10 / 100 = 0 instead of 0.1 since the result is an integer again. This does not hold for division of (only) literal values since those yield rational constants.',
location: item.src location: item.src

@ -10,8 +10,8 @@ interface llcNode {
export default class lowLevelCalls implements AnalyzerModule { export default class lowLevelCalls implements AnalyzerModule {
llcNodes: llcNode[] = [] llcNodes: llcNode[] = []
name: string = `Low level calls: ` name = `Low level calls: `
description: string = `Should only be used by experienced devs` description = `Should only be used by experienced devs`
category: ModuleCategory = category.SECURITY category: ModuleCategory = category.SECURITY
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = { version: SupportedVersion = {
@ -36,10 +36,11 @@ export default class lowLevelCalls implements AnalyzerModule {
} }
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] { report (compilationResults: CompilationResult): ReportObj[] {
return this.llcNodes.map((item, i) => { return this.llcNodes.map((item) => {
let text: string = '' let text = ''
let morehref: string = '' let morehref = ''
switch (item.type) { switch (item.type) {
case lowLevelCallTypes.CALL: case lowLevelCallTypes.CALL:
text = `Use of "call": should be avoided whenever possible. text = `Use of "call": should be avoided whenever possible.

@ -6,8 +6,8 @@ import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, ContractHLA
VisitFunction, ReportFunction, ReturnAstNode, AssignmentAstNode, SupportedVersion} from './../../types' VisitFunction, ReportFunction, ReturnAstNode, AssignmentAstNode, SupportedVersion} from './../../types'
export default class noReturn implements AnalyzerModule { export default class noReturn implements AnalyzerModule {
name: string = `No return: ` name = `No return: `
description: string = `Function with 'returns' not returning` description = `Function with 'returns' not returning`
category: ModuleCategory = category.MISC category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = { version: SupportedVersion = {
@ -21,6 +21,8 @@ export default class noReturn implements AnalyzerModule {
) )
report: ReportFunction = this.abstractAst.build_report(this._report.bind(this)) report: ReportFunction = this.abstractAst.build_report(this._report.bind(this))
// eslint-disable-next-line @typescript-eslint/no-unused-vars
private _report (contracts: ContractHLAst[], multipleContractsWithSameName: boolean): ReportObj[] { private _report (contracts: ContractHLAst[], multipleContractsWithSameName: boolean): ReportObj[] {
const warnings: ReportObj[] = [] const warnings: ReportObj[] = []

@ -5,8 +5,8 @@ import AbstractAst from './abstractAstView'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, ContractHLAst, VisitFunction, ReportFunction, SupportedVersion} from './../../types' import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, ContractHLAst, VisitFunction, ReportFunction, SupportedVersion} from './../../types'
export default class selfdestruct implements AnalyzerModule { export default class selfdestruct implements AnalyzerModule {
name: string = `Selfdestruct: ` name = `Selfdestruct: `
description: string = `Contracts using destructed contract can be broken` description = `Contracts using destructed contract can be broken`
category: ModuleCategory = category.SECURITY category: ModuleCategory = category.SECURITY
algorithm: ModuleAlgorithm = algorithm.HEURISTIC algorithm: ModuleAlgorithm = algorithm.HEURISTIC
version: SupportedVersion = { version: SupportedVersion = {
@ -20,12 +20,13 @@ export default class selfdestruct implements AnalyzerModule {
) )
report: ReportFunction = this.abstractAst.build_report(this._report.bind(this)) report: ReportFunction = this.abstractAst.build_report(this._report.bind(this))
// eslint-disable-next-line @typescript-eslint/no-unused-vars
private _report (contracts: ContractHLAst[], multipleContractsWithSameName: boolean): ReportObj[] { private _report (contracts: ContractHLAst[], multipleContractsWithSameName: boolean): ReportObj[] {
const warnings: ReportObj[] = [] const warnings: ReportObj[] = []
contracts.forEach((contract) => { contracts.forEach((contract) => {
contract.functions.forEach((func) => { contract.functions.forEach((func) => {
let hasSelf: boolean = false let hasSelf = false
func.relevantNodes.forEach((node) => { func.relevantNodes.forEach((node) => {
if (isSelfdestructCall(node)) { if (isSelfdestructCall(node)) {
warnings.push({ warnings.push({

@ -13,8 +13,8 @@ interface SimilarRecord {
} }
export default class similarVariableNames implements AnalyzerModule { export default class similarVariableNames implements AnalyzerModule {
name: string = `Similar variable names: ` name = `Similar variable names: `
description: string = `Variable names are too similar` description = `Variable names are too similar`
category: ModuleCategory = category.MISC category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = { version: SupportedVersion = {
@ -23,6 +23,7 @@ export default class similarVariableNames implements AnalyzerModule {
abstractAst:AbstractAst = new AbstractAst() abstractAst:AbstractAst = new AbstractAst()
// eslint-disable-next-line @typescript-eslint/no-unused-vars
visit: VisitFunction = this.abstractAst.build_visit((node: any) => false) visit: VisitFunction = this.abstractAst.build_visit((node: any) => false)
report: ReportFunction = this.abstractAst.build_report(this._report.bind(this)) report: ReportFunction = this.abstractAst.build_report(this._report.bind(this))
@ -34,11 +35,11 @@ export default class similarVariableNames implements AnalyzerModule {
contracts.forEach((contract) => { contracts.forEach((contract) => {
contract.functions.forEach((func) => { contract.functions.forEach((func) => {
const funcName: string = getFullQuallyfiedFuncDefinitionIdent(contract.node, func.node, func.parameters) const funcName: string = getFullQuallyfiedFuncDefinitionIdent(contract.node, func.node, func.parameters)
let hasModifiersComments: string = '' let hasModifiersComments = ''
if (hasModifiers) { if (hasModifiers) {
hasModifiersComments = 'Note: Modifiers are currently not considered by this static analysis.' hasModifiersComments = 'Note: Modifiers are currently not considered by this static analysis.'
} }
let multipleContractsWithSameNameComments: string = '' let multipleContractsWithSameNameComments = ''
if (multipleContractsWithSameName) { if (multipleContractsWithSameName) {
multipleContractsWithSameNameComments = 'Note: Import aliases are currently not supported by this static analysis.' multipleContractsWithSameNameComments = 'Note: Import aliases are currently not supported by this static analysis.'
} }

@ -160,7 +160,7 @@ const abiNamespace: Record<string, SpecialObjDetail> = {
} }
// #################### Trivial Getters // #################### Trivial Getters
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function getType (node: any): string { function getType (node: any): string {
return node.typeDescriptions.typeString return node.typeDescriptions.typeString
} }
@ -370,8 +370,8 @@ function getFunctionDefinitionReturnParameterPart (funcNode: FunctionDefinitionA
function getFunctionCallTypeParameterType (func: FunctionCallAstNode): string | undefined { function getFunctionCallTypeParameterType (func: FunctionCallAstNode): string | undefined {
const type: string = getFunctionCallType(func) const type: string = getFunctionCallType(func)
if (type.startsWith('function (')) { if (type.startsWith('function (')) {
let paramTypes: string = '' let paramTypes = ''
let openPar: number = 1 let openPar = 1
for (let x = 10; x < type.length; x++) { for (let x = 10; x < type.length; x++) {
const c: string = type.charAt(x) const c: string = type.charAt(x)
if (c === '(') openPar++ if (c === '(') openPar++
@ -464,6 +464,7 @@ function getUnAssignedTopLevelBinOps (subScope: BlockAstNode | IfStatementAstNod
// #################### Trivial Node Identification // #################### Trivial Node Identification
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function isStatement (node: any): boolean { function isStatement (node: any): boolean {
return nodeType(node, 'Statement$') || node.nodeType === "Block" || node.nodeType === "Return" return nodeType(node, 'Statement$') || node.nodeType === "Block" || node.nodeType === "Return"
} }
@ -549,7 +550,7 @@ function isBuiltinFunctionCall (node: FunctionCallAstNode): boolean {
* @return {bool} * @return {bool}
*/ */
function isAbiNamespaceCall (node: FunctionCallAstNode): boolean { function isAbiNamespaceCall (node: FunctionCallAstNode): boolean {
return Object.keys(abiNamespace).some((key) => abiNamespace.hasOwnProperty(key) && node.expression && isSpecialVariableAccess(node.expression, abiNamespace[key])) return Object.keys(abiNamespace).some((key) => Object.prototype.hasOwnProperty.call(abiNamespace,key) && node.expression && isSpecialVariableAccess(node.expression, abiNamespace[key]))
} }
/** /**
@ -975,7 +976,8 @@ function isBytesLengthCheck (node: MemberAccessAstNode): boolean {
* @node {ASTNode} some AstNode * @node {ASTNode} some AstNode
* @return {bool} * @return {bool}
*/ */
function isLoop (node) { // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function isLoop (node: any): boolean {
return nodeType(node, exactMatch(nodeTypes.FORSTATEMENT)) || return nodeType(node, exactMatch(nodeTypes.FORSTATEMENT)) ||
nodeType(node, exactMatch(nodeTypes.WHILESTATEMENT)) || nodeType(node, exactMatch(nodeTypes.WHILESTATEMENT)) ||
nodeType(node, exactMatch(nodeTypes.DOWHILESTATEMENT)) nodeType(node, exactMatch(nodeTypes.DOWHILESTATEMENT))
@ -999,26 +1001,32 @@ function isSpecialVariableAccess (node: MemberAccessAstNode, varType: SpecialObj
// #################### Node Identification Primitives // #################### Node Identification Primitives
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function expressionTypeDescription (node: any, typeRegex: string): boolean { function expressionTypeDescription (node: any, typeRegex: string): boolean {
return new RegExp(typeRegex).test(node.expression.typeDescriptions.typeString) return new RegExp(typeRegex).test(node.expression.typeDescriptions.typeString)
} }
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function typeDescription (node: any, typeRegex: string): boolean { function typeDescription (node: any, typeRegex: string): boolean {
return new RegExp(typeRegex).test(node.typeDescriptions.typeString) return new RegExp(typeRegex).test(node.typeDescriptions.typeString)
} }
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function nodeType (node: any, typeRegex: string): boolean { function nodeType (node: any, typeRegex: string): boolean {
return new RegExp(typeRegex).test(node.nodeType) return new RegExp(typeRegex).test(node.nodeType)
} }
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function nodeTypeIn (node: any, typeRegex: string[]): boolean { function nodeTypeIn (node: any, typeRegex: string[]): boolean {
return typeRegex.some((typeRegex) => nodeType (node, typeRegex)) return typeRegex.some((typeRegex) => nodeType (node, typeRegex))
} }
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function memName (node: any, memNameRegex: any): boolean { function memName (node: any, memNameRegex: any): boolean {
return (node && !memNameRegex) || new RegExp(memNameRegex).test(node.name) || new RegExp(memNameRegex).test(node.memberName) return (node && !memNameRegex) || new RegExp(memNameRegex).test(node.name) || new RegExp(memNameRegex).test(node.memberName)
} }
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function operator (node: any, opRegex: string): boolean { function operator (node: any, opRegex: string): boolean {
return new RegExp(opRegex).test(node.operator) return new RegExp(opRegex).test(node.operator)
} }
@ -1069,6 +1077,7 @@ function findFirstSubNodeLTR (node: any, type: string): any {
* list of return type names * list of return type names
* @return {Boolean} isPayable * @return {Boolean} isPayable
*/ */
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function buildFunctionSignature (paramTypes: any[], returnTypes: any[], isPayable: boolean, additionalMods?: any): string { function buildFunctionSignature (paramTypes: any[], returnTypes: any[], isPayable: boolean, additionalMods?: any): string {
return 'function (' + util.concatWithSeperator(paramTypes, ',') + ')' + ((isPayable) ? ' payable' : '') + ((additionalMods) ? ' ' + additionalMods : '') + ((returnTypes.length) ? ' returns (' + util.concatWithSeperator(returnTypes, ',') + ')' : '') return 'function (' + util.concatWithSeperator(paramTypes, ',') + ')' + ((isPayable) ? ' payable' : '') + ((additionalMods) ? ' ' + additionalMods : '') + ((returnTypes.length) ? ' returns (' + util.concatWithSeperator(returnTypes, ',') + ')' : '')
} }
@ -1093,7 +1102,7 @@ function getMethodParamsSplittedTypeDesc(node: FunctionDefinitionAstNode, contra
e.inputs[varIndex]['internalType'] === typeString) e.inputs[varIndex]['internalType'] === typeString)
if(methodABI && methodABI.inputs) { if(methodABI && methodABI.inputs) {
const inputs = methodABI.inputs[varIndex] const inputs = methodABI.inputs[varIndex]
let typeStr = getTypeStringFromComponents(inputs['components']) const typeStr = getTypeStringFromComponents(inputs['components'])
finalTypeString = typeStr + inputs['type'].replace('tuple', '') finalTypeString = typeStr + inputs['type'].replace('tuple', '')
} }
} }
@ -1106,7 +1115,7 @@ function getMethodParamsSplittedTypeDesc(node: FunctionDefinitionAstNode, contra
function getTypeStringFromComponents(components: ABIParameter[]) { function getTypeStringFromComponents(components: ABIParameter[]) {
let typeString = '(' let typeString = '('
for(var i=0; i < components.length; i++) { for(let i=0; i < components.length; i++) {
const param = components[i] const param = components[i]
if(param.type.includes('tuple') && param.components && param.components.length > 0){ if(param.type.includes('tuple') && param.components && param.components.length > 0){
typeString = typeString + getTypeStringFromComponents(param.components) typeString = typeString + getTypeStringFromComponents(param.components)

@ -4,8 +4,8 @@ import { isStringToBytesConversion, isBytesLengthCheck } from './staticAnalysisC
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode, FunctionCallAstNode, SupportedVersion} from './../../types' import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode, FunctionCallAstNode, SupportedVersion} from './../../types'
export default class stringBytesLength implements AnalyzerModule { export default class stringBytesLength implements AnalyzerModule {
name: string = `String length: ` name = `String length: `
description: string = `Bytes length != String length` description = `Bytes length != String length`
category: ModuleCategory = category.MISC category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = { version: SupportedVersion = {
@ -20,6 +20,7 @@ export default class stringBytesLength implements AnalyzerModule {
else if (node.nodeType === "MemberAccess" && isBytesLengthCheck(node)) this.bytesLengthChecks.push(node) else if (node.nodeType === "MemberAccess" && isBytesLengthCheck(node)) this.bytesLengthChecks.push(node)
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] { report (compilationResults: CompilationResult): ReportObj[] {
if (this.stringToBytesConversions.length > 0 && this.bytesLengthChecks.length > 0) { if (this.stringToBytesConversions.length > 0 && this.bytesLengthChecks.length > 0) {
return [{ return [{

@ -5,8 +5,8 @@ import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, Compilation
export default class thisLocal implements AnalyzerModule { export default class thisLocal implements AnalyzerModule {
warningNodes: MemberAccessAstNode[] = [] warningNodes: MemberAccessAstNode[] = []
name: string = `This on local calls: ` name = `This on local calls: `
description: string = `Invocation of local functions via 'this'` description = `Invocation of local functions via 'this'`
category: ModuleCategory = category.GAS category: ModuleCategory = category.GAS
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = { version: SupportedVersion = {
@ -17,8 +17,9 @@ export default class thisLocal implements AnalyzerModule {
if (node.nodeType === 'MemberAccess' && isThisLocalCall(node)) this.warningNodes.push(node) if (node.nodeType === 'MemberAccess' && isThisLocalCall(node)) this.warningNodes.push(node)
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] { report (compilationResults: CompilationResult): ReportObj[] {
return this.warningNodes.map(function (item, i) { return this.warningNodes.map(function (item) {
return { return {
warning: `Use of "this" for local functions: Never use "this" to call functions in the same contract, it only consumes more gas than normal local calls.`, warning: `Use of "this" for local functions: Never use "this" to call functions in the same contract, it only consumes more gas than normal local calls.`,
location: item.src, location: item.src,

@ -5,8 +5,8 @@ import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, Compilation
export default class txOrigin implements AnalyzerModule { export default class txOrigin implements AnalyzerModule {
txOriginNodes: MemberAccessAstNode[] = [] txOriginNodes: MemberAccessAstNode[] = []
name: string = `Transaction origin: ` name = `Transaction origin: `
description: string = `'tx.origin' used` description = `'tx.origin' used`
category: ModuleCategory = category.SECURITY category: ModuleCategory = category.SECURITY
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = { version: SupportedVersion = {
@ -18,8 +18,9 @@ export default class txOrigin implements AnalyzerModule {
} }
// eslint-disable-next-line @typescript-eslint/no-unused-vars
report (compilationResults: CompilationResult): ReportObj[] { report (compilationResults: CompilationResult): ReportObj[] {
return this.txOriginNodes.map((item, i) => { return this.txOriginNodes.map((item) => {
return { return {
warning: `Use of tx.origin: "tx.origin" is useful only in very exceptional cases. warning: `Use of tx.origin: "tx.origin" is useful only in very exceptional cases.
If you use it for authentication, you usually want to replace it by "msg.sender", because otherwise any contract you call can act on your behalf.`, If you use it for authentication, you usually want to replace it by "msg.sender", because otherwise any contract you call can act on your behalf.`,

@ -130,7 +130,7 @@ export interface SourceUnitAstNode {
nodeType: 'SourceUnit' nodeType: 'SourceUnit'
src: string src: string
absolutePath: string absolutePath: string
exportedSymbols: object exportedSymbols: Record<string, unknown>
nodes: Array<AstNode> nodes: Array<AstNode>
} }
@ -245,7 +245,7 @@ export interface FunctionDefinitionAstNode {
parameters: ParameterListAstNode parameters: ParameterListAstNode
returnParameters: ParameterListAstNode returnParameters: ParameterListAstNode
modifiers: Array<ModifierInvocationAstNode> modifiers: Array<ModifierInvocationAstNode>
body: object | null body: Record<string, unknown> | null
implemented: boolean implemented: boolean
scope: number scope: number
functionSelector?: string functionSelector?: string
@ -268,7 +268,7 @@ export interface VariableDeclarationAstNode {
typeDescriptions: TypeDescription typeDescriptions: TypeDescription
functionSelector?: string functionSelector?: string
indexed?: boolean indexed?: boolean
baseFunctions?: object baseFunctions?: Record<string, unknown>
} }
export interface ModifierDefinitionAstNode { export interface ModifierDefinitionAstNode {
@ -276,7 +276,7 @@ export interface ModifierDefinitionAstNode {
nodeType: 'ModifierDefinition' nodeType: 'ModifierDefinition'
src: string src: string
name: string name: string
documentation: object | null documentation: Record<string, unknown> | null
visibility: string visibility: string
parameters: ParameterListAstNode parameters: ParameterListAstNode
virtual: boolean virtual: boolean
@ -298,7 +298,7 @@ export interface EventDefinitionAstNode {
nodeType: 'EventDefinition' nodeType: 'EventDefinition'
src: string src: string
name: string name: string
documentation: object | null documentation: Record<string, unknown> | null
parameters: ParameterListAstNode parameters: ParameterListAstNode
anonymous: boolean anonymous: boolean
} }
@ -386,7 +386,7 @@ export interface IfStatementAstNode {
id: number id: number
nodeType: 'IfStatement' nodeType: 'IfStatement'
src: string src: string
condition: object condition: Record<string, unknown>
trueBody: BlockAstNode | ExpressionStatementAstNode trueBody: BlockAstNode | ExpressionStatementAstNode
falseBody: BlockAstNode | ExpressionStatementAstNode falseBody: BlockAstNode | ExpressionStatementAstNode
} }
@ -404,7 +404,7 @@ export interface TryStatementAstNode {
id: number id: number
nodeType: 'TryStatement' nodeType: 'TryStatement'
src: string src: string
externalCall: object externalCall: Record<string, unknown>
clauses: Array<TryCatchClauseAstNode> clauses: Array<TryCatchClauseAstNode>
} }
@ -442,7 +442,7 @@ export interface ReturnAstNode {
id: number id: number
nodeType: 'Return' nodeType: 'Return'
src: string src: string
expression: object | null expression: Record<string, unknown> | null
functionReturnParameters: number functionReturnParameters: number
} }
@ -464,8 +464,8 @@ export interface VariableDeclarationStatementAstNode {
nodeType: 'VariableDeclarationStatement' nodeType: 'VariableDeclarationStatement'
src: string src: string
assignments: Array<number> assignments: Array<number>
declarations: Array<object> declarations: Array<Record<string, unknown>>
initialValue: object initialValue: Record<string, unknown>
} }
export interface ExpressionStatementAstNode { export interface ExpressionStatementAstNode {
@ -488,9 +488,9 @@ export interface ConditionalAstNode extends ExpressionAttributes {
id: number id: number
nodeType: 'Conditional' nodeType: 'Conditional'
src: string src: string
condition: object condition: Record<string, unknown>
trueExpression: object trueExpression: Record<string, unknown>
falseExpression: object falseExpression: Record<string, unknown>
} }
export interface AssignmentAstNode extends ExpressionAttributes { export interface AssignmentAstNode extends ExpressionAttributes {
@ -499,7 +499,7 @@ export interface AssignmentAstNode extends ExpressionAttributes {
src: string src: string
operator: string operator: string
leftHandSide: any leftHandSide: any
rightHandSide: object rightHandSide: Record<string, unknown>
} }
export interface TupleExpressionAstNode extends ExpressionAttributes { export interface TupleExpressionAstNode extends ExpressionAttributes {
@ -507,7 +507,7 @@ export interface TupleExpressionAstNode extends ExpressionAttributes {
nodeType: 'TupleExpression' nodeType: 'TupleExpression'
src: string src: string
isInlineArray: boolean isInlineArray: boolean
components: Array<object> components: Array<Record<string, unknown>>
} }
export interface UnaryOperationAstNode extends ExpressionAttributes { export interface UnaryOperationAstNode extends ExpressionAttributes {
@ -524,8 +524,8 @@ export interface BinaryOperationAstNode extends ExpressionAttributes {
nodeType: 'BinaryOperation' nodeType: 'BinaryOperation'
src: string src: string
operator: string operator: string
leftExpression: object leftExpression: Record<string, unknown>
rightExpression: object rightExpression: Record<string, unknown>
commonType: TypeDescription commonType: TypeDescription
} }
@ -535,7 +535,7 @@ export interface FunctionCallAstNode extends ExpressionAttributes {
src: string src: string
expression: any expression: any
names: Array<any> names: Array<any>
arguments: object arguments: Record<string, unknown>
tryCall: boolean tryCall: boolean
kind: 'functionCall' | 'typeConversion' | 'structConstructorCall' kind: 'functionCall' | 'typeConversion' | 'structConstructorCall'
} }
@ -544,9 +544,9 @@ export interface FunctionCallOptionsAstNode extends ExpressionAttributes {
id: number id: number
nodeType: 'FunctionCallOptions' nodeType: 'FunctionCallOptions'
src: string src: string
expression: object expression: Record<string, unknown>
names: Array<string> names: Array<string>
options: Array<object> options: Array<Record<string, unknown>>
} }
export interface NewExpressionAstNode extends ExpressionAttributes { export interface NewExpressionAstNode extends ExpressionAttributes {
@ -569,17 +569,17 @@ export interface IndexAccessAstNode extends ExpressionAttributes {
id: number id: number
nodeType: 'IndexAccess' nodeType: 'IndexAccess'
src: string src: string
baseExpression: object baseExpression: Record<string, unknown>
indexExpression: object indexExpression: Record<string, unknown>
} }
export interface IndexRangeAccessAstNode extends ExpressionAttributes { export interface IndexRangeAccessAstNode extends ExpressionAttributes {
id: number id: number
nodeType: 'IndexRangeAccess' nodeType: 'IndexRangeAccess'
src: string src: string
baseExpression: object baseExpression: Record<string, unknown>
startExpression: object startExpression: Record<string, unknown>
endExpression: object endExpression: Record<string, unknown>
} }
export interface ElementaryTypeNameExpressionAstNode extends ExpressionAttributes { export interface ElementaryTypeNameExpressionAstNode extends ExpressionAttributes {
@ -724,7 +724,7 @@ export interface CommonYulAstNode {
///////// /////////
export interface AstNode { export interface AstNode {
absolutePath?: string absolutePath?: string
exportedSymbols?: object exportedSymbols?: Record<string, unknown>
id: number id: number
nodeType: string nodeType: string
nodes?: Array<AstNode> nodes?: Array<AstNode>
@ -753,7 +753,7 @@ export interface CommonYulAstNode {
constant?: boolean constant?: boolean
name?: string name?: string
public?: boolean public?: boolean
exportedSymbols?: object exportedSymbols?: Record<string, unknown>
argumentTypes?: null argumentTypes?: null
absolutePath?: string absolutePath?: string
[x: string]: any [x: string]: any
@ -776,7 +776,7 @@ export interface CommonYulAstNode {
/** EVM-related outputs */ /** EVM-related outputs */
evm: { evm: {
assembly: string assembly: string
legacyAssembly: {} legacyAssembly: Record<string, unknown>
/** Bytecode and related details. */ /** Bytecode and related details. */
bytecode: BytecodeObject bytecode: BytecodeObject
deployedBytecode: BytecodeObject deployedBytecode: BytecodeObject

@ -1,24 +1,7 @@
{ {
"include": ["src", "index.ts"], "extends": "../../tsconfig.json",
"compilerOptions": { "compilerOptions": {
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "types": ["node"],
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ },
"lib": ["dom", "es2018"], /* Specify library files to be included in the compilation. */ "include": ["**/*.ts"]
"declaration": true, /* Generates corresponding '.d.ts' file. */
"sourceMap": true, /* Generates corresponding '.map' file. */
"outDir": "./dist", /* Redirect output structure to the directory. */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": false, /* Raise error on expressions and declarations with an implied 'any' type. */
/* Module Resolution Options */
"baseUrl": "./src", /* Base directory to resolve non-absolute module names. */
"paths": { "remix-analyzer": ["./"] }, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
"typeRoots": [
"./@types",
"./node_modules/@types"
],
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
/* Experimental Options */
"experimentalDecorators": false, /* Enables experimental support for ES7 decorators. */
}
} }

@ -0,0 +1,12 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "../../dist/out-tsc",
"declaration": true,
"rootDir": "./src",
"types": ["node"]
},
"exclude": ["**/*.spec.ts"],
"include": ["**/*.ts"]
}

8664
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -143,10 +143,19 @@
"@babel/preset-stage-0": "^7.0.0", "@babel/preset-stage-0": "^7.0.0",
"@babel/register": "^7.4.4", "@babel/register": "^7.4.4",
"@fortawesome/fontawesome-free": "^5.8.1", "@fortawesome/fontawesome-free": "^5.8.1",
"@nrwl/eslint-plugin-nx": "^9.4.4",
"@nrwl/linter": "^9.3.0", "@nrwl/linter": "^9.3.0",
"@nrwl/workspace": "9.2.4", "@nrwl/workspace": "9.2.4",
"@remix-project/remix-analyzer": "0.5.2",
"@remix-project/remix-debug": "0.4.4",
"@remix-project/remix-lib": "0.4.29",
"@remix-project/remix-simulator": "0.1.9-beta.5",
"@remix-project/remix-solidity": "0.3.30",
"@remix-project/remix-tests": "0.1.33",
"@resolver-engine/imports": "^0.3.0", "@resolver-engine/imports": "^0.3.0",
"@types/node": "~8.9.4", "@types/node": "~8.9.4",
"@typescript-eslint/eslint-plugin": "^3.3.0",
"@typescript-eslint/parser": "^3.3.0",
"ace-mode-move": "0.0.1", "ace-mode-move": "0.0.1",
"ace-mode-solidity": "^0.1.0", "ace-mode-solidity": "^0.1.0",
"ace-mode-zokrates": "^1.0.0", "ace-mode-zokrates": "^1.0.0",
@ -154,6 +163,7 @@
"babel-eslint": "^10.0.0", "babel-eslint": "^10.0.0",
"babel-plugin-fast-async": "^6.1.2", "babel-plugin-fast-async": "^6.1.2",
"babel-plugin-transform-object-rest-spread": "^6.26.0", "babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-yo-yoify": "^2.0.0",
"babelify": "^10.0.0", "babelify": "^10.0.0",
"brace": "^0.8.0", "brace": "^0.8.0",
"browserify": "^16.2.3", "browserify": "^16.2.3",
@ -165,6 +175,7 @@
"deep-equal": "^1.0.1", "deep-equal": "^1.0.1",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"eslint": "6.8.0", "eslint": "6.8.0",
"eslint-config-prettier": "^6.11.0",
"ethereumjs-util": "^6.2.0", "ethereumjs-util": "^6.2.0",
"ethers": "^4.0.27", "ethers": "^4.0.27",
"events": "^3.0.0", "events": "^3.0.0",
@ -172,6 +183,15 @@
"exorcist": "^0.4.0", "exorcist": "^0.4.0",
"fast-async": "^7.0.6", "fast-async": "^7.0.6",
"fast-levenshtein": "^2.0.6", "fast-levenshtein": "^2.0.6",
"ganache-cli": "^6.8.1",
"gists": "^1.0.1",
"ipfs-mini": "^1.1.5",
"is-electron": "^2.2.0",
"javascript-serialize": "^1.6.1",
"jquery": "^3.3.1",
"js-base64": "^2.1.9",
"js-beautify": "1.6.14",
"minixhr": "^3.2.2",
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"nanohtml": "^1.6.3", "nanohtml": "^1.6.3",
"nightwatch": "^1.3.5", "nightwatch": "^1.3.5",
@ -181,13 +201,7 @@
"npm-run-all": "^4.0.2", "npm-run-all": "^4.0.2",
"onchange": "^3.2.1", "onchange": "^3.2.1",
"prettier": "1.19.1", "prettier": "1.19.1",
"@remix-project/remix-analyzer": "0.5.2",
"@remix-project/remix-debug": "0.4.4",
"@remix-project/remix-lib": "0.4.29",
"@remix-project/remix-simulator": "0.1.9-beta.5",
"@remix-project/remix-solidity": "0.3.30",
"remix-tabs": "1.0.48", "remix-tabs": "1.0.48",
"@remix-project/remix-tests": "0.1.33",
"remixd": "0.1.8-alpha.16", "remixd": "0.1.8-alpha.16",
"request": "^2.83.0", "request": "^2.83.0",
"rimraf": "^2.6.1", "rimraf": "^2.6.1",
@ -201,20 +215,10 @@
"typescript": "~3.8.3", "typescript": "~3.8.3",
"uglify-js": "^2.8.16", "uglify-js": "^2.8.16",
"vm-browserify": "0.0.4", "vm-browserify": "0.0.4",
"yo-yo": "^1.2.2",
"yo-yoify": "^3.7.3",
"babel-plugin-yo-yoify": "^2.0.0",
"ganache-cli": "^6.8.1",
"gists": "^1.0.1",
"ipfs-mini": "^1.1.5",
"is-electron": "^2.2.0",
"javascript-serialize": "^1.6.1",
"jquery": "^3.3.1",
"js-base64": "^2.1.9",
"js-beautify": "1.6.14",
"minixhr": "^3.2.2",
"watchify": "^3.9.0", "watchify": "^3.9.0",
"web3": "1.2.4", "web3": "1.2.4",
"webworkify": "^1.2.1" "webworkify": "^1.2.1",
"yo-yo": "^1.2.2",
"yo-yoify": "^3.7.3"
} }
} }

@ -69,19 +69,19 @@
}, },
"remix-analyzer": { "remix-analyzer": {
"root": "libs/remix-analyzer", "root": "libs/remix-analyzer",
"sourceRoot": "libs/remix-analyzer/", "sourceRoot": "libs/remix-analyzer",
"projectType": "library", "projectType": "library",
"schematics": {}, "schematics": {},
"architect": { "architect": {
"lint": { "lint": {
"builder": "@nrwl/workspace:run-commands", "builder": "@nrwl/linter:lint",
"options": { "options": {
"commands": [ "linter": "eslint",
{ "config": "libs/remix-analyzer/.eslintrc",
"command": "./../../node_modules/.bin/npm-run-all lint" "tsConfig": [
} "libs/remix-analyzer/tsconfig.lib.json"
], ],
"cwd": "libs/remix-analyzer" "exclude": ["**/node_modules/**", "libs/remix-analyzer/test/**/*"]
} }
}, },
"test": { "test": {

Loading…
Cancel
Save