supported Solidity version added in analyzer modules

pull/7/head
aniket-engg 5 years ago committed by Aniket
parent e511e36ad0
commit 3d2b3ecd36
  1. 5
      remix-analyzer/src/solidity-analyzer/modules/assignAndCompare.ts
  2. 5
      remix-analyzer/src/solidity-analyzer/modules/blockBlockhash.ts
  3. 5
      remix-analyzer/src/solidity-analyzer/modules/blockTimestamp.ts
  4. 5
      remix-analyzer/src/solidity-analyzer/modules/checksEffectsInteraction.ts
  5. 5
      remix-analyzer/src/solidity-analyzer/modules/constantFunctions.ts
  6. 5
      remix-analyzer/src/solidity-analyzer/modules/deleteDynamicArrays.ts
  7. 5
      remix-analyzer/src/solidity-analyzer/modules/deleteFromDynamicArray.ts
  8. 5
      remix-analyzer/src/solidity-analyzer/modules/erc20Decimals.ts
  9. 5
      remix-analyzer/src/solidity-analyzer/modules/etherTransferInLoop.ts
  10. 5
      remix-analyzer/src/solidity-analyzer/modules/forLoopIteratesOverDynamicArray.ts
  11. 5
      remix-analyzer/src/solidity-analyzer/modules/gasCosts.ts
  12. 5
      remix-analyzer/src/solidity-analyzer/modules/guardConditions.ts
  13. 5
      remix-analyzer/src/solidity-analyzer/modules/inlineAssembly.ts
  14. 5
      remix-analyzer/src/solidity-analyzer/modules/intDivisionTruncate.ts
  15. 5
      remix-analyzer/src/solidity-analyzer/modules/lowLevelCalls.ts
  16. 5
      remix-analyzer/src/solidity-analyzer/modules/noReturn.ts
  17. 5
      remix-analyzer/src/solidity-analyzer/modules/selfdestruct.ts
  18. 5
      remix-analyzer/src/solidity-analyzer/modules/similarVariableNames.ts
  19. 5
      remix-analyzer/src/solidity-analyzer/modules/stringBytesLength.ts
  20. 5
      remix-analyzer/src/solidity-analyzer/modules/thisLocal.ts
  21. 5
      remix-analyzer/src/solidity-analyzer/modules/txOrigin.ts
  22. 6
      remix-analyzer/src/types.ts

@ -2,7 +2,7 @@ import { default as category } from './categories'
import { isSubScopeWithTopLevelUnAssignedBinOp, getUnAssignedTopLevelBinOps } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, BlockAstNode, IfStatementAstNode,
WhileStatementAstNode, ForStatementAstNode, CompilationResult, ExpressionStatementAstNode} from './../../types'
WhileStatementAstNode, ForStatementAstNode, CompilationResult, ExpressionStatementAstNode, SupportedVersion} from './../../types'
export default class assignAndCompare implements AnalyzerModule {
warningNodes: ExpressionStatementAstNode[] = []
@ -10,6 +10,9 @@ export default class assignAndCompare implements AnalyzerModule {
description: string = `The result of an operation not used`
category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = {
start: '0.4.12'
}
visit (node: BlockAstNode | IfStatementAstNode | WhileStatementAstNode | ForStatementAstNode): void {
if (node?.nodeType && isSubScopeWithTopLevelUnAssignedBinOp(node)) getUnAssignedTopLevelBinOps(node).forEach((n) => this.warningNodes.push(n))

@ -1,7 +1,7 @@
import { default as category } from './categories'
import { isBlockBlockHashAccess } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, FunctionCallAstNode} from './../../types'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, FunctionCallAstNode, SupportedVersion} from './../../types'
export default class blockBlockhash implements AnalyzerModule {
warningNodes: FunctionCallAstNode[] = []
@ -9,6 +9,9 @@ export default class blockBlockhash implements AnalyzerModule {
description: string = `Can be influenced by miners`
category: ModuleCategory = category.SECURITY
algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = {
start: '0.4.12'
}
visit (node: FunctionCallAstNode): void {
if (node.nodeType === 'FunctionCall' && isBlockBlockHashAccess(node)) this.warningNodes.push(node)

@ -2,7 +2,7 @@ import { default as category } from './categories'
import { isNowAccess, isBlockTimestampAccess } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, IdentifierAstNode,
MemberAccessAstNode} from './../../types'
MemberAccessAstNode, SupportedVersion} from './../../types'
export default class blockTimestamp implements AnalyzerModule {
warningNowNodes: IdentifierAstNode[] = []
@ -11,6 +11,9 @@ export default class blockTimestamp implements AnalyzerModule {
description: string = `Can be influenced by miners`
category: ModuleCategory = category.SECURITY
algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = {
start: '0.4.12'
}
visit (node: IdentifierAstNode | MemberAccessAstNode ): void {
if (node.nodeType === "Identifier" && isNowAccess(node)) this.warningNowNodes.push(node)

@ -6,13 +6,16 @@ import { buildGlobalFuncCallGraph, resolveCallGraphSymbol, analyseCallGraph } fr
import AbstractAst from './abstractAstView'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, ContractHLAst, VariableDeclarationAstNode,
FunctionHLAst, ContractCallGraph, Context, FunctionCallAstNode, AssignmentAstNode, UnaryOperationAstNode,
InlineAssemblyAstNode, ReportFunction, VisitFunction, FunctionCallGraph } from './../../types'
InlineAssemblyAstNode, ReportFunction, VisitFunction, FunctionCallGraph, SupportedVersion } from './../../types'
export default class checksEffectsInteraction implements AnalyzerModule {
name: string = `Check-effects-interaction: `
description: string = `Potential reentrancy bugs`
category: ModuleCategory = category.SECURITY
algorithm: ModuleAlgorithm = algorithm.HEURISTIC
version: SupportedVersion = {
start: '0.4.12'
}
abstractAst: AbstractAst = new AbstractAst()

@ -7,13 +7,16 @@ import { default as algorithm } from './algorithmCategories'
import { buildGlobalFuncCallGraph, resolveCallGraphSymbol, analyseCallGraph } from './functionCallGraph'
import AbstractAst from './abstractAstView'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, ContractCallGraph, Context, ContractHLAst,
FunctionHLAst, VariableDeclarationAstNode, FunctionCallGraph, FunctionCallAstNode, VisitFunction, ReportFunction} from './../../types'
FunctionHLAst, VariableDeclarationAstNode, FunctionCallGraph, FunctionCallAstNode, VisitFunction, ReportFunction, SupportedVersion} from './../../types'
export default class constantFunctions implements AnalyzerModule {
name: string = `Constant/View/Pure functions: `
description: string = `Potentially constant/view/pure functions`
category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.HEURISTIC
version: SupportedVersion = {
start: '0.4.12'
}
abstractAst: AbstractAst = new AbstractAst()

@ -1,7 +1,7 @@
import { default as category } from './categories'
import { isDeleteOfDynamicArray } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, UnaryOperationAstNode} from './../../types'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, UnaryOperationAstNode, SupportedVersion} from './../../types'
export default class deleteDynamicArrays implements AnalyzerModule {
rel: UnaryOperationAstNode[] = []
@ -9,6 +9,9 @@ export default class deleteDynamicArrays implements AnalyzerModule {
description: string = `Use require/assert to ensure complete deletion`
category: ModuleCategory = category.GAS
algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = {
start: '0.4.12'
}
visit (node: UnaryOperationAstNode): void {
if (isDeleteOfDynamicArray(node)) this.rel.push(node)

@ -1,7 +1,7 @@
import { default as category } from './categories'
import { default as algorithm } from './algorithmCategories'
import { isDeleteFromDynamicArray, isMappingIndexAccess } from './staticAnalysisCommon'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, UnaryOperationAstNode} from './../../types'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, UnaryOperationAstNode, SupportedVersion} from './../../types'
export default class deleteFromDynamicArray implements AnalyzerModule {
relevantNodes: UnaryOperationAstNode[] = []
@ -9,6 +9,9 @@ export default class deleteFromDynamicArray implements AnalyzerModule {
description: string = `'delete' leaves a gap in array`
category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = {
start: '0.4.12'
}
visit (node: UnaryOperationAstNode): void {
if (isDeleteFromDynamicArray(node) && !isMappingIndexAccess(node.subExpression)) this.relevantNodes.push(node)

@ -3,13 +3,16 @@ import { getFunctionDefinitionName, helpers, getDeclaredVariableName, getDeclare
import { default as algorithm } from './algorithmCategories'
import AbstractAst from './abstractAstView'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, VisitFunction, ReportFunction, ContractHLAst,
FunctionHLAst, VariableDeclarationAstNode} from './../../types'
FunctionHLAst, VariableDeclarationAstNode, SupportedVersion} from './../../types'
export default class erc20Decimals implements AnalyzerModule {
name: string = `ERC20: `
description: string = `'decimals' should be 'uint8'`
category: ModuleCategory = category.ERC
algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = {
start: '0.4.12'
}
abstractAst: AbstractAst = new AbstractAst()
visit: VisitFunction = this.abstractAst.build_visit((node: any) => false)

@ -2,7 +2,7 @@ import { default as category } from './categories'
import { default as algorithm } from './algorithmCategories'
import { isLoop, isTransfer } from './staticAnalysisCommon'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, ForStatementAstNode,
WhileStatementAstNode, ExpressionStatementAstNode} from './../../types'
WhileStatementAstNode, ExpressionStatementAstNode, SupportedVersion} from './../../types'
export default class etherTransferInLoop implements AnalyzerModule {
relevantNodes: ExpressionStatementAstNode[] = []
@ -10,6 +10,9 @@ export default class etherTransferInLoop implements AnalyzerModule {
description: string = `Transferring Ether in a for/while/do-while loop`
category: ModuleCategory = category.GAS
algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = {
start: '0.4.12'
}
visit (node: ForStatementAstNode | WhileStatementAstNode): void {
let transferNodes: ExpressionStatementAstNode[] = []

@ -1,7 +1,7 @@
import { default as category } from './categories'
import { default as algorithm } from './algorithmCategories'
import { isDynamicArrayLengthAccess } from './staticAnalysisCommon'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, ForStatementAstNode} from './../../types'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, ForStatementAstNode, SupportedVersion} from './../../types'
export default class forLoopIteratesOverDynamicArray implements AnalyzerModule {
relevantNodes: ForStatementAstNode[] = []
@ -9,6 +9,9 @@ export default class forLoopIteratesOverDynamicArray implements AnalyzerModule {
description: string = `Iterations depend on dynamic array's size`
category: ModuleCategory = category.GAS
algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = {
start: '0.4.12'
}
visit (node: ForStatementAstNode): void {
const { condition } = node

@ -2,13 +2,16 @@ import { default as category } from './categories'
import { default as algorithm } from './algorithmCategories'
import { getFunctionDefinitionName, helpers, isVariableTurnedIntoGetter, getMethodParamsSplittedTypeDesc } from './staticAnalysisCommon'
import { ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, CompiledContract, AnalyzerModule,
FunctionDefinitionAstNode, VariableDeclarationAstNode } from './../../types'
FunctionDefinitionAstNode, VariableDeclarationAstNode, SupportedVersion } from './../../types'
export default class gasCosts implements AnalyzerModule {
name: string = `Gas costs: `
description: string = `Too high gas requirement of functions`
category: ModuleCategory = category.GAS
algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = {
start: '0.4.12'
}
warningNodes: any[] = []
visit (node: FunctionDefinitionAstNode | VariableDeclarationAstNode): void {

@ -1,7 +1,7 @@
import { default as category } from './categories'
import { isRequireCall, isAssertCall } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, FunctionCallAstNode} from './../../types'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, FunctionCallAstNode, SupportedVersion} from './../../types'
export default class guardConditions implements AnalyzerModule {
guards: FunctionCallAstNode[] = []
@ -9,6 +9,9 @@ export default class guardConditions implements AnalyzerModule {
description: string = `Ensure appropriate use of require/assert`
category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = {
start: '0.4.12'
}
visit (node: FunctionCallAstNode): void {
if (isRequireCall(node) || isAssertCall(node)) this.guards.push(node)

@ -1,6 +1,6 @@
import { default as category } from './categories'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, InlineAssemblyAstNode} from './../../types'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, InlineAssemblyAstNode, SupportedVersion} from './../../types'
export default class inlineAssembly implements AnalyzerModule {
inlineAssNodes: InlineAssemblyAstNode[] = []
@ -8,6 +8,9 @@ export default class inlineAssembly implements AnalyzerModule {
description: string = `Inline assembly used`
category: ModuleCategory = category.SECURITY
algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = {
start: '0.4.12'
}
visit (node: InlineAssemblyAstNode): void {
if(node.nodeType === 'InlineAssembly') this.inlineAssNodes.push(node)

@ -1,7 +1,7 @@
import { default as category } from './categories'
import { isIntDivision } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, BinaryOperationAstNode} from './../../types'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, BinaryOperationAstNode, SupportedVersion} from './../../types'
export default class intDivisionTruncate implements AnalyzerModule {
warningNodes: BinaryOperationAstNode[] = []
@ -9,6 +9,9 @@ export default class intDivisionTruncate implements AnalyzerModule {
description: string = `Division on int/uint values truncates the result`
category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = {
start: '0.4.12'
}
visit (node: BinaryOperationAstNode): void {
if (isIntDivision(node)) this.warningNodes.push(node)

@ -1,7 +1,7 @@
import { default as category } from './categories'
import { isLLCall, isLLDelegatecall, isLLCallcode, isLLCall04, isLLDelegatecall04, isLLSend04, isLLSend, lowLevelCallTypes } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode} from './../../types'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode, SupportedVersion} from './../../types'
interface llcNode {
node: MemberAccessAstNode
@ -14,6 +14,9 @@ export default class lowLevelCalls implements AnalyzerModule {
description: string = `Should only be used by experienced devs`
category: ModuleCategory = category.SECURITY
algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = {
start: '0.4.12'
}
visit (node : MemberAccessAstNode): void {
if (isLLCall(node)) {

@ -3,13 +3,16 @@ import { hasFunctionBody, getFullQuallyfiedFuncDefinitionIdent, getEffectedVaria
import { default as algorithm } from './algorithmCategories'
import AbstractAst from './abstractAstView'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, ContractHLAst, FunctionHLAst,
VisitFunction, ReportFunction, ReturnAstNode, AssignmentAstNode} from './../../types'
VisitFunction, ReportFunction, ReturnAstNode, AssignmentAstNode, SupportedVersion} from './../../types'
export default class noReturn implements AnalyzerModule {
name: string = `No return: `
description: string = `Function with 'returns' not returning`
category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = {
start: '0.4.12'
}
abstractAst: AbstractAst = new AbstractAst()

@ -2,13 +2,16 @@ import { default as category } from './categories'
import { isStatement, isSelfdestructCall } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories'
import AbstractAst from './abstractAstView'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, ContractHLAst, VisitFunction, ReportFunction} from './../../types'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, ContractHLAst, VisitFunction, ReportFunction, SupportedVersion} from './../../types'
export default class selfdestruct implements AnalyzerModule {
name: string = `Selfdestruct: `
description: string = `Contracts using destructed contract can be broken`
category: ModuleCategory = category.SECURITY
algorithm: ModuleAlgorithm = algorithm.HEURISTIC
version: SupportedVersion = {
start: '0.4.12'
}
abstractAst: AbstractAst = new AbstractAst()

@ -4,7 +4,7 @@ import { default as algorithm } from './algorithmCategories'
import AbstractAst from './abstractAstView'
import { get } from 'fast-levenshtein'
import { util } from 'remix-lib'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, ContractHLAst, FunctionHLAst, VariableDeclarationAstNode, VisitFunction, ReportFunction} from './../../types'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, ContractHLAst, FunctionHLAst, VariableDeclarationAstNode, VisitFunction, ReportFunction, SupportedVersion} from './../../types'
interface SimilarRecord {
var1: string
@ -17,6 +17,9 @@ export default class similarVariableNames implements AnalyzerModule {
description: string = `Variable names are too similar`
category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = {
start: '0.4.12'
}
abstractAst:AbstractAst = new AbstractAst()

@ -1,13 +1,16 @@
import { default as category } from './categories'
import { default as algorithm } from './algorithmCategories'
import { isStringToBytesConversion, isBytesLengthCheck } from './staticAnalysisCommon'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode, FunctionCallAstNode} from './../../types'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode, FunctionCallAstNode, SupportedVersion} from './../../types'
export default class stringBytesLength implements AnalyzerModule {
name: string = `String length: `
description: string = `Bytes length != String length`
category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = {
start: '0.4.12'
}
stringToBytesConversions: FunctionCallAstNode[] = []
bytesLengthChecks: MemberAccessAstNode[] = []

@ -1,7 +1,7 @@
import { default as category } from './categories'
import { isThisLocalCall } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode} from './../../types'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode, SupportedVersion} from './../../types'
export default class thisLocal implements AnalyzerModule {
warningNodes: MemberAccessAstNode[] = []
@ -9,6 +9,9 @@ export default class thisLocal implements AnalyzerModule {
description: string = `Invocation of local functions via 'this'`
category: ModuleCategory = category.GAS
algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = {
start: '0.4.12'
}
visit (node: MemberAccessAstNode): void {
if (node.nodeType === 'MemberAccess' && isThisLocalCall(node)) this.warningNodes.push(node)

@ -1,7 +1,7 @@
import { default as category } from './categories'
import { default as algorithm } from './algorithmCategories'
import { isTxOriginAccess } from './staticAnalysisCommon'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode} from './../../types'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode, SupportedVersion} from './../../types'
export default class txOrigin implements AnalyzerModule {
txOriginNodes: MemberAccessAstNode[] = []
@ -9,6 +9,9 @@ export default class txOrigin implements AnalyzerModule {
description: string = `'tx.origin' used`
category: ModuleCategory = category.SECURITY
algorithm: ModuleAlgorithm = algorithm.EXACT
version: SupportedVersion = {
start: '0.4.12'
}
visit (node: MemberAccessAstNode): void {
if (isTxOriginAccess(node)) this.txOriginNodes.push(node)

@ -3,10 +3,16 @@ export interface AnalyzerModule {
description: string,
category: ModuleCategory
algorithm: ModuleAlgorithm
version: SupportedVersion
visit: VisitFunction
report: ReportFunction
}
export interface SupportedVersion {
start: string
end?: string
}
export interface ModuleAlgorithm {
hasFalsePositives: boolean,
hasFalseNegatives: boolean,

Loading…
Cancel
Save