commons, modules & test ASTs updated

pull/7/head
aniket-engg 5 years ago committed by Aniket
parent 04dccc9254
commit dd3edce02f
  1. 12
      remix-analyzer/src/solidity-analyzer/modules/blockTimestamp.ts
  2. 8
      remix-analyzer/src/solidity-analyzer/modules/deleteFromDynamicArray.ts
  3. 2
      remix-analyzer/src/solidity-analyzer/modules/etherTransferInLoop.ts
  4. 6
      remix-analyzer/src/solidity-analyzer/modules/guardConditions.ts
  5. 2
      remix-analyzer/src/solidity-analyzer/modules/noReturn.ts
  6. 5
      remix-analyzer/src/solidity-analyzer/modules/selfdestruct.ts
  7. 2
      remix-analyzer/src/solidity-analyzer/modules/similarVariableNames.ts
  8. 139
      remix-analyzer/src/solidity-analyzer/modules/staticAnalysisCommon.ts
  9. 12
      remix-analyzer/src/solidity-analyzer/modules/stringBytesLength.ts
  10. 2
      remix-analyzer/src/solidity-analyzer/modules/thisLocal.ts
  11. 12
      remix-analyzer/src/types.ts
  12. 93
      remix-analyzer/test/analysis/astBlocks/assignment.json
  13. 25
      remix-analyzer/test/analysis/astBlocks/blockHashAccess.json
  14. 236
      remix-analyzer/test/analysis/astBlocks/doWhileLoopNode.json
  15. 370
      remix-analyzer/test/analysis/astBlocks/forLoopNode.json
  16. 88
      remix-analyzer/test/analysis/astBlocks/functionDefinition.json
  17. 27
      remix-analyzer/test/analysis/astBlocks/inheritance.json
  18. 98
      remix-analyzer/test/analysis/astBlocks/inlineAssembly.json
  19. 38
      remix-analyzer/test/analysis/astBlocks/libCall.json
  20. 53
      remix-analyzer/test/analysis/astBlocks/localCall.json
  21. 170
      remix-analyzer/test/analysis/astBlocks/lowlevelCall.json
  22. 126
      remix-analyzer/test/analysis/astBlocks/parameterFunction.json
  23. 67
      remix-analyzer/test/analysis/astBlocks/selfdestruct.json
  24. 358
      remix-analyzer/test/analysis/astBlocks/stateVariableContractNode.json
  25. 38
      remix-analyzer/test/analysis/astBlocks/superLocal.json
  26. 40
      remix-analyzer/test/analysis/astBlocks/thisLocalCall.json
  27. 229
      remix-analyzer/test/analysis/astBlocks/whileLoopNode.json
  28. 184
      remix-analyzer/test/analysis/staticAnalysisCommon-test.ts
  29. 6
      remix-analyzer/test/analysis/test-contracts/solidity-v0.5/library.sol

@ -1,19 +1,19 @@
import { default as category } from './categories' import { default as category } from './categories'
import { isNowAccess, isBlockTimestampAccess } from './staticAnalysisCommon' import { isNowAccess, isBlockTimestampAccess } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories' import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult} from './../../types' import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult, IdentifierAstNode, MemberAccessAstNode} from './../../types'
export default class blockTimestamp implements AnalyzerModule { export default class blockTimestamp implements AnalyzerModule {
warningNowNodes: AstNodeLegacy[] = [] warningNowNodes: IdentifierAstNode[] = []
warningblockTimestampNodes: AstNodeLegacy[] = [] warningblockTimestampNodes: MemberAccessAstNode[] = []
name: string = 'Block timestamp: ' name: string = 'Block timestamp: '
description: string = 'Semantics maybe unclear' description: string = 'Semantics maybe unclear'
category: ModuleCategory = category.SECURITY category: ModuleCategory = category.SECURITY
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
visit (node: AstNodeLegacy): void { visit (node: IdentifierAstNode | MemberAccessAstNode ): void {
if (isNowAccess(node)) this.warningNowNodes.push(node) if (node.nodeType === "Identifier" && isNowAccess(node)) this.warningNowNodes.push(node)
else if (isBlockTimestampAccess(node)) this.warningblockTimestampNodes.push(node) else if (node.nodeType === "MemberAccess" && isBlockTimestampAccess(node)) this.warningblockTimestampNodes.push(node)
} }
report (compilationResults: CompilationResult): ReportObj[] { report (compilationResults: CompilationResult): ReportObj[] {

@ -1,17 +1,17 @@
import { default as category } from './categories' import { default as category } from './categories'
import { default as algorithm } from './algorithmCategories' import { default as algorithm } from './algorithmCategories'
import { isDeleteFromDynamicArray, isMappingIndexAccess } from './staticAnalysisCommon' import { isDeleteFromDynamicArray, isMappingIndexAccess } from './staticAnalysisCommon'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult} from './../../types' import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, UnaryOperationAstNode} from './../../types'
export default class deleteFromDynamicArray implements AnalyzerModule { export default class deleteFromDynamicArray implements AnalyzerModule {
relevantNodes: AstNodeLegacy[] = [] relevantNodes: UnaryOperationAstNode[] = []
name: string = 'Delete from dynamic Array: ' name: string = 'Delete from dynamic Array: '
description: string = 'Using delete on an array leaves a gap' description: string = 'Using delete on an array leaves a gap'
category: ModuleCategory = category.MISC category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
visit (node: AstNodeLegacy): void { visit (node: UnaryOperationAstNode): void {
if (isDeleteFromDynamicArray(node) && node.children && !isMappingIndexAccess(node.children[0])) this.relevantNodes.push(node) if (isDeleteFromDynamicArray(node) && !isMappingIndexAccess(node.subExpression)) this.relevantNodes.push(node)
} }
report (compilationResults: CompilationResult): ReportObj[] { report (compilationResults: CompilationResult): ReportObj[] {

@ -1,6 +1,6 @@
import { default as category } from './categories' import { default as category } from './categories'
import { default as algorithm } from './algorithmCategories' import { default as algorithm } from './algorithmCategories'
import { getLoopBlockStartIndex, isTransfer } from './staticAnalysisCommon' import { isTransfer } from './staticAnalysisCommon'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult, ForStatementAstNode, WhileStatementAstNode, CommonAstNode, ExpressionStatementAstNode} from './../../types' import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult, ForStatementAstNode, WhileStatementAstNode, CommonAstNode, ExpressionStatementAstNode} from './../../types'
export default class etherTransferInLoop implements AnalyzerModule { export default class etherTransferInLoop implements AnalyzerModule {

@ -1,16 +1,16 @@
import { default as category } from './categories' import { default as category } from './categories'
import { isRequireCall, isAssertCall } from './staticAnalysisCommon' import { isRequireCall, isAssertCall } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories' import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult} from './../../types' import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, FunctionCallAstNode} from './../../types'
export default class guardConditions implements AnalyzerModule { export default class guardConditions implements AnalyzerModule {
guards: AstNodeLegacy[] = [] guards: FunctionCallAstNode[] = []
name: string = 'Guard Conditions: ' name: string = 'Guard Conditions: '
description: string = 'Use require and appropriately' description: string = 'Use require and appropriately'
category: ModuleCategory = category.MISC category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
visit (node: AstNodeLegacy): void { visit (node: FunctionCallAstNode): void {
if (isRequireCall(node) || isAssertCall(node)) this.guards.push(node) if (isRequireCall(node) || isAssertCall(node)) this.guards.push(node)
} }

@ -2,7 +2,7 @@ import { default as category } from './categories'
import { hasFunctionBody, getFullQuallyfiedFuncDefinitionIdent, getEffectedVariableName } from './staticAnalysisCommon' import { hasFunctionBody, getFullQuallyfiedFuncDefinitionIdent, getEffectedVariableName } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories' import { default as algorithm } from './algorithmCategories'
import AbstractAst from './abstractAstView' import AbstractAst from './abstractAstView'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult, CommonAstNode, FunctionDefinitionAstNode} from './../../types' import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, CommonAstNode, FunctionDefinitionAstNode} from './../../types'
export default class noReturn implements AnalyzerModule { export default class noReturn implements AnalyzerModule {
name: string = 'no return: ' name: string = 'no return: '

@ -2,7 +2,7 @@ import { default as category } from './categories'
import { isStatement, isSelfdestructCall } from './staticAnalysisCommon' import { isStatement, isSelfdestructCall } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories' import { default as algorithm } from './algorithmCategories'
import AbstractAst from './abstractAstView' import AbstractAst from './abstractAstView'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult} from './../../types' import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult} from './../../types'
export default class selfdestruct implements AnalyzerModule { export default class selfdestruct implements AnalyzerModule {
name: string = 'Selfdestruct: ' name: string = 'Selfdestruct: '
@ -13,8 +13,7 @@ export default class selfdestruct implements AnalyzerModule {
abstractAst = new AbstractAst() abstractAst = new AbstractAst()
visit = this.abstractAst.build_visit( visit = this.abstractAst.build_visit(
(node: AstNodeLegacy) => isStatement(node) || (node: any) => isStatement(node) || isSelfdestructCall(node.expression)
isSelfdestructCall(node)
) )
report = this.abstractAst.build_report(this._report.bind(this)) report = this.abstractAst.build_report(this._report.bind(this))

@ -70,7 +70,7 @@ export default class similarVariableNames implements AnalyzerModule {
return varName2.match(ref) != null return varName2.match(ref) != null
} }
private getFunctionVariables (contract, func): string[] { private getFunctionVariables (contract, func) {
return contract.stateVariables.concat(func.localVariables) return contract.stateVariables.concat(func.localVariables)
} }
} }

@ -1,6 +1,6 @@
'use strict' 'use strict'
import { FunctionDefinitionAstNode, ModifierDefinitionAstNode, ParameterListAstNode, CommonAstNode, ForStatementAstNode, WhileStatementAstNode, VariableDeclarationAstNode, ContractDefinitionAstNode, InheritanceSpecifierAstNode, MemberAccessAstNode, BinaryOperationAstNode, FunctionCallAstNode, ExpressionStatementAstNode, UnaryOperationAstNode, IdentifierAstNode, MappingAstNode, IndexAccessAstNode } from "types" import { FunctionDefinitionAstNode, ModifierDefinitionAstNode, ParameterListAstNode, CommonAstNode, ForStatementAstNode, WhileStatementAstNode, VariableDeclarationAstNode, ContractDefinitionAstNode, InheritanceSpecifierAstNode, MemberAccessAstNode, BinaryOperationAstNode, FunctionCallAstNode, ExpressionStatementAstNode, UnaryOperationAstNode, IdentifierAstNode, MappingAstNode, IndexAccessAstNode, UserDefinedTypeNameAstNode, BlockAstNode } from "types"
const remixLib = require('remix-lib') const remixLib = require('remix-lib')
const util = remixLib.util const util = remixLib.util
@ -125,8 +125,8 @@ const abiNamespace = {
// #################### Trivial Getters // #################### Trivial Getters
function getType (node: CommonAstNode) { function getType (node: any) {
return node.nodeType return node.typeDescriptions.typeString
} }
// #################### Complex Getters // #################### Complex Getters
@ -159,9 +159,9 @@ function getEffectedVariableName (effectNode) {
* @localCallNode {ASTNode} Function call node * @localCallNode {ASTNode} Function call node
* @return {string} name of the function called * @return {string} name of the function called
*/ */
function getLocalCallName (localCallNode) { function getLocalCallName (localCallNode: FunctionCallAstNode): string {
if (!isLocalCall(localCallNode) && !isAbiNamespaceCall(localCallNode)) throw new Error('staticAnalysisCommon.js: not an local call Node') if (!isLocalCall(localCallNode) && !isAbiNamespaceCall(localCallNode)) throw new Error('staticAnalysisCommon.js: not an local call Node')
return localCallNode.children[0].attributes.value return localCallNode.expression.name
} }
/** /**
@ -170,9 +170,9 @@ function getLocalCallName (localCallNode) {
* @localCallNode {ASTNode} Function call node * @localCallNode {ASTNode} Function call node
* @return {string} name of the function called * @return {string} name of the function called
*/ */
function getThisLocalCallName (localCallNode) { function getThisLocalCallName (localCallNode: FunctionCallAstNode): string {
if (!isThisLocalCall(localCallNode)) throw new Error('staticAnalysisCommon.js: not an this local call Node') if (!isThisLocalCall(localCallNode.expression)) throw new Error('staticAnalysisCommon.js: not an this local call Node')
return localCallNode.attributes.value return localCallNode.expression.memberName
} }
/** /**
@ -181,9 +181,9 @@ function getThisLocalCallName (localCallNode) {
* @localCallNode {ASTNode} Function call node * @localCallNode {ASTNode} Function call node
* @return {string} name of the function called * @return {string} name of the function called
*/ */
function getSuperLocalCallName (localCallNode) { function getSuperLocalCallName (localCallNode: FunctionCallAstNode): string {
if (!isSuperLocalCall(localCallNode)) throw new Error('staticAnalysisCommon.js: not an super local call Node') if (!isSuperLocalCall(localCallNode.expression)) throw new Error('staticAnalysisCommon.js: not an super local call Node')
return localCallNode.attributes.member_name return localCallNode.expression.memberName
} }
/** /**
@ -209,9 +209,9 @@ function getExternalDirectCallContractName (extDirectCall) {
* @thisLocalCall {ASTNode} Function call node * @thisLocalCall {ASTNode} Function call node
* @return {string} name of the contract the function is defined in * @return {string} name of the contract the function is defined in
*/ */
function getThisLocalCallContractName (thisLocalCall) { function getThisLocalCallContractName (thisLocalCall: FunctionCallAstNode) {
if (!isThisLocalCall(thisLocalCall)) throw new Error('staticAnalysisCommon.js: not an this local call Node') if (!isThisLocalCall(thisLocalCall.expression)) throw new Error('staticAnalysisCommon.js: not an this local call Node')
return thisLocalCall.children[0].attributes.type.replace(new RegExp(basicRegex.CONTRACTTYPE), '') return thisLocalCall.expression.expression.typeDescriptions.typeString.replace(new RegExp(basicRegex.CONTRACTTYPE), '')
} }
/** /**
@ -257,7 +257,7 @@ function getFunctionDefinitionName (funcDef: FunctionDefinitionAstNode): string
* @func {ASTNode} Inheritance specifier * @func {ASTNode} Inheritance specifier
* @return {string} name of contract inherited from * @return {string} name of contract inherited from
*/ */
function getInheritsFromName (inheritsNode: InheritanceSpecifierAstNode) { function getInheritsFromName (inheritsNode: InheritanceSpecifierAstNode): UserDefinedTypeNameAstNode {
return inheritsNode.baseName return inheritsNode.baseName
} }
@ -268,7 +268,7 @@ function getInheritsFromName (inheritsNode: InheritanceSpecifierAstNode) {
* @varDeclNode {ASTNode} Variable declaration node * @varDeclNode {ASTNode} Variable declaration node
* @return {string} variable name * @return {string} variable name
*/ */
function getDeclaredVariableName (varDeclNode: VariableDeclarationAstNode) { function getDeclaredVariableName (varDeclNode: VariableDeclarationAstNode): string {
return varDeclNode.name return varDeclNode.name
} }
@ -279,8 +279,8 @@ function getDeclaredVariableName (varDeclNode: VariableDeclarationAstNode) {
* @varDeclNode {ASTNode} Variable declaration node * @varDeclNode {ASTNode} Variable declaration node
* @return {string} variable type * @return {string} variable type
*/ */
function getDeclaredVariableType (varDeclNode: VariableDeclarationAstNode) { function getDeclaredVariableType (varDeclNode: VariableDeclarationAstNode): string {
return varDeclNode.typeName return varDeclNode.typeName.name
} }
/** /**
@ -356,9 +356,9 @@ function getFunctionCallTypeParameterType (func) {
* @funcCall {ASTNode} function call node * @funcCall {ASTNode} function call node
* @return {string} name of the lib defined * @return {string} name of the lib defined
*/ */
function getLibraryCallContractName (funcCall) { function getLibraryCallContractName (node: MemberAccessAstNode): string | undefined {
if (!isLibraryCall(funcCall)) throw new Error('staticAnalysisCommon.js: not an this library call Node') if (!isLibraryCall(node)) throw new Error('staticAnalysisCommon.js: not an this library call Node')
const types = new RegExp(basicRegex.LIBRARYTYPE).exec(funcCall.children[0].attributes.type) const types: RegExpExecArray | null = new RegExp(basicRegex.LIBRARYTYPE).exec(node.expression.typeDescriptions.typeString)
if(types) if(types)
return types[1] return types[1]
} }
@ -373,9 +373,9 @@ function getLibraryCallContractName (funcCall) {
* @func {ASTNode} function call node * @func {ASTNode} function call node
* @return {string} name of function called on the library * @return {string} name of function called on the library
*/ */
function getLibraryCallMemberName (funcCall) { function getLibraryCallMemberName (funcCall: FunctionCallAstNode): string {
// if (!isLibraryCall(funcCall)) throw new Error('staticAnalysisCommon.js: not an library call Node') // if (!isLibraryCall(funcCall)) throw new Error('staticAnalysisCommon.js: not an library call Node')
return funcCall.attributes.member_name return funcCall.expression.memberName
} }
/** /**
@ -407,13 +407,13 @@ function getUnAssignedTopLevelBinOps (subScope) {
return subScope.children.filter(isBinaryOpInExpression) return subScope.children.filter(isBinaryOpInExpression)
} }
function getLoopBlockStartIndex (node: ForStatementAstNode | WhileStatementAstNode): 3|1 { // function getLoopBlockStartIndex (node: ForStatementAstNode | WhileStatementAstNode): 3|1 {
return node.nodeType === "ForStatement" ? 3 : 1 // return node.nodeType === "ForStatement" ? 3 : 1
} // }
// #################### Trivial Node Identification // #################### Trivial Node Identification
function isStatement (node: CommonAstNode) { 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"
} }
@ -422,9 +422,9 @@ function isStatement (node: CommonAstNode) {
* @node {ASTNode} some AstNode * @node {ASTNode} some AstNode
* @return {bool} * @return {bool}
*/ */
function isBinaryOperation (node) { // function isBinaryOperation (node) {
return nodeType(node, exactMatch(nodeTypes.BINARYOPERATION)) // return nodeType(node, exactMatch(nodeTypes.BINARYOPERATION))
} // }
// #################### Complex Node Identification // #################### Complex Node Identification
@ -433,8 +433,8 @@ function isBinaryOperation (node) {
* @funcNode {ASTNode} function defintion node * @funcNode {ASTNode} function defintion node
* @return {bool} * @return {bool}
*/ */
function hasFunctionBody (funcNode: FunctionDefinitionAstNode) { function hasFunctionBody (funcNode: FunctionDefinitionAstNode): boolean {
return funcNode.body != null return funcNode.body !== null
} }
/** /**
@ -442,7 +442,7 @@ function hasFunctionBody (funcNode: FunctionDefinitionAstNode) {
* @node {ASTNode} node to check for * @node {ASTNode} node to check for
* @return {bool} * @return {bool}
*/ */
function isDeleteOfDynamicArray (node: UnaryOperationAstNode) { function isDeleteOfDynamicArray (node: UnaryOperationAstNode): boolean {
return isDeleteUnaryOperation(node) && isDynamicArrayAccess(node.subExpression) return isDeleteUnaryOperation(node) && isDynamicArrayAccess(node.subExpression)
} }
@ -451,7 +451,7 @@ function isDeleteOfDynamicArray (node: UnaryOperationAstNode) {
* @node {ASTNode} node to check for * @node {ASTNode} node to check for
* @return {bool} * @return {bool}
*/ */
function isDynamicArrayAccess (node: IdentifierAstNode) { function isDynamicArrayAccess (node: IdentifierAstNode): boolean {
return typeDescription(node, '[] storage ref') || typeDescription(node, 'bytes storage ref') || typeDescription(node, 'string storage ref') return typeDescription(node, '[] storage ref') || typeDescription(node, 'bytes storage ref') || typeDescription(node, 'string storage ref')
} }
@ -460,7 +460,7 @@ function isDynamicArrayAccess (node: IdentifierAstNode) {
* @node {ASTNode} node to check for * @node {ASTNode} node to check for
* @return {bool} * @return {bool}
*/ */
function isDynamicArrayLengthAccess (node: MemberAccessAstNode) { function isDynamicArrayLengthAccess (node: MemberAccessAstNode): boolean {
return (node.memberName === 'length') && // accessing 'length' member return (node.memberName === 'length') && // accessing 'length' member
node.expression['typeDescriptions']['typeString'].indexOf('[]') !== -1 // member is accessed from dynamic array, notice [] without any number node.expression['typeDescriptions']['typeString'].indexOf('[]') !== -1 // member is accessed from dynamic array, notice [] without any number
} }
@ -470,8 +470,8 @@ function isDynamicArrayLengthAccess (node: MemberAccessAstNode) {
* @node {ASTNode} node to check for * @node {ASTNode} node to check for
* @return {bool} * @return {bool}
*/ */
function isDeleteFromDynamicArray (node) { function isDeleteFromDynamicArray (node: UnaryOperationAstNode): boolean {
return isDeleteUnaryOperation(node) && isIndexAccess(node.children[0]) return isDeleteUnaryOperation(node) && node.subExpression.nodeType === 'IndexAccess'
} }
/** /**
@ -479,17 +479,17 @@ function isDeleteFromDynamicArray (node) {
* @node {ASTNode} node to check for * @node {ASTNode} node to check for
* @return {bool} * @return {bool}
*/ */
function isIndexAccess (node) { // function isIndexAccess (node) {
return node && node.name === 'IndexAccess' // return node && node.name === 'IndexAccess'
} // }
/** /**
* True if node is the access of a mapping index * True if node is the access of a mapping index
* @node {ASTNode} node to check for * @node {ASTNode} node to check for
* @return {bool} * @return {bool}
*/ */
function isMappingIndexAccess (node) { function isMappingIndexAccess (node: IndexAccessAstNode): boolean {
return isIndexAccess(node) && node.children && node.children[0].attributes.type.startsWith('mapping') return node.typeDescriptions.typeString.startsWith('mapping')
} }
/** /**
@ -506,7 +506,7 @@ function isLocalCallGraphRelevantNode (node) {
* @node {ASTNode} some AstNode * @node {ASTNode} some AstNode
* @return {bool} * @return {bool}
*/ */
function isBuiltinFunctionCall (node) { function isBuiltinFunctionCall (node: FunctionCallAstNode): boolean {
return (isLocalCall(node) && builtinFunctions[getLocalCallName(node) + '(' + getFunctionCallTypeParameterType(node) + ')'] === true) || isAbiNamespaceCall(node) return (isLocalCall(node) && builtinFunctions[getLocalCallName(node) + '(' + getFunctionCallTypeParameterType(node) + ')'] === true) || isAbiNamespaceCall(node)
} }
@ -515,8 +515,8 @@ function isBuiltinFunctionCall (node) {
* @node {ASTNode} some AstNode * @node {ASTNode} some AstNode
* @return {bool} * @return {bool}
*/ */
function isAbiNamespaceCall (node) { function isAbiNamespaceCall (node: FunctionCallAstNode): boolean {
return Object.keys(abiNamespace).some((key) => abiNamespace.hasOwnProperty(key) && node.children && node.children[0] && isSpecialVariableAccess(node.children[0], abiNamespace[key])) return Object.keys(abiNamespace).some((key) => abiNamespace.hasOwnProperty(key) && node.expression && isSpecialVariableAccess(node.expression, abiNamespace[key]))
} }
/** /**
@ -524,7 +524,7 @@ function isAbiNamespaceCall (node) {
* @node {ASTNode} some AstNode * @node {ASTNode} some AstNode
* @return {bool} * @return {bool}
*/ */
function isSelfdestructCall (node) { function isSelfdestructCall (node: FunctionCallAstNode): boolean {
return isBuiltinFunctionCall(node) && getLocalCallName(node) === 'selfdestruct' return isBuiltinFunctionCall(node) && getLocalCallName(node) === 'selfdestruct'
} }
@ -533,7 +533,7 @@ function isSelfdestructCall (node) {
* @node {ASTNode} some AstNode * @node {ASTNode} some AstNode
* @return {bool} * @return {bool}
*/ */
function isAssertCall (node) { function isAssertCall (node: FunctionCallAstNode): boolean {
return isBuiltinFunctionCall(node) && getLocalCallName(node) === 'assert' return isBuiltinFunctionCall(node) && getLocalCallName(node) === 'assert'
} }
@ -542,7 +542,7 @@ function isAssertCall (node) {
* @node {ASTNode} some AstNode * @node {ASTNode} some AstNode
* @return {bool} * @return {bool}
*/ */
function isRequireCall (node) { function isRequireCall (node: FunctionCallAstNode): boolean {
return isBuiltinFunctionCall(node) && getLocalCallName(node) === 'require' return isBuiltinFunctionCall(node) && getLocalCallName(node) === 'require'
} }
@ -625,7 +625,7 @@ function isConstructor (node: FunctionDefinitionAstNode): boolean {
* @node {ASTNode} some AstNode * @node {ASTNode} some AstNode
* @return {bool} * @return {bool}
*/ */
function isIntDivision (node: BinaryOperationAstNode) { function isIntDivision (node: BinaryOperationAstNode): boolean {
return operator(node, exactMatch(util.escapeRegExp('/'))) && typeDescription(node.rightExpression, util.escapeRegExp('int')) return operator(node, exactMatch(util.escapeRegExp('/'))) && typeDescription(node.rightExpression, util.escapeRegExp('int'))
} }
@ -635,7 +635,7 @@ function isIntDivision (node: BinaryOperationAstNode) {
* @return {bool} * @return {bool}
*/ */
function isSubScopeWithTopLevelUnAssignedBinOp (node) { function isSubScopeWithTopLevelUnAssignedBinOp (node) {
return nodeType(node, exactMatch(nodeTypes.BLOCK)) && node.children && node.children.some(isBinaryOpInExpression) || return nodeType(node, exactMatch(nodeTypes.BLOCK)) && node.statements.some(isBinaryOpInExpression) ||
isSubScopeStatement(node) && node.children && node.children.some(isBinaryOpInExpression) // Second Case for if without braces isSubScopeStatement(node) && node.children && node.children.some(isBinaryOpInExpression) // Second Case for if without braces
} }
@ -652,7 +652,7 @@ function isSubScopeStatement (node) {
* @node {ASTNode} some AstNode * @node {ASTNode} some AstNode
* @return {bool} * @return {bool}
*/ */
function isBinaryOpInExpression (node: ExpressionStatementAstNode) { function isBinaryOpInExpression (node: ExpressionStatementAstNode): boolean {
return node.nodeType === "ExpressionStatement" && node.expression.nodeType === "BinaryOperation" return node.nodeType === "ExpressionStatement" && node.expression.nodeType === "BinaryOperation"
} }
@ -661,7 +661,7 @@ function isBinaryOpInExpression (node: ExpressionStatementAstNode) {
* @node {ASTNode} some AstNode * @node {ASTNode} some AstNode
* @return {bool} * @return {bool}
*/ */
function isPlusPlusUnaryOperation (node: UnaryOperationAstNode) { function isPlusPlusUnaryOperation (node: UnaryOperationAstNode): boolean {
return node.operator === '++' return node.operator === '++'
} }
@ -670,7 +670,7 @@ function isPlusPlusUnaryOperation (node: UnaryOperationAstNode) {
* @node {ASTNode} some AstNode * @node {ASTNode} some AstNode
* @return {bool} * @return {bool}
*/ */
function isDeleteUnaryOperation (node: UnaryOperationAstNode) { function isDeleteUnaryOperation (node: UnaryOperationAstNode): boolean {
return node.operator === 'delete' return node.operator === 'delete'
} }
@ -679,7 +679,7 @@ function isDeleteUnaryOperation (node: UnaryOperationAstNode) {
* @node {ASTNode} some AstNode * @node {ASTNode} some AstNode
* @return {bool} * @return {bool}
*/ */
function isMinusMinusUnaryOperation (node: UnaryOperationAstNode) { function isMinusMinusUnaryOperation (node: UnaryOperationAstNode): boolean {
return node.operator === '--' return node.operator === '--'
} }
@ -688,7 +688,7 @@ function isMinusMinusUnaryOperation (node: UnaryOperationAstNode) {
* @node {ASTNode} some AstNode * @node {ASTNode} some AstNode
* @return {bool} * @return {bool}
*/ */
function isFullyImplementedContract (node: ContractDefinitionAstNode) { function isFullyImplementedContract (node: ContractDefinitionAstNode): boolean {
return node.fullyImplemented === true return node.fullyImplemented === true
} }
@ -697,7 +697,7 @@ function isFullyImplementedContract (node: ContractDefinitionAstNode) {
* @node {ASTNode} some AstNode * @node {ASTNode} some AstNode
* @return {bool} * @return {bool}
*/ */
function isLibrary (node: ContractDefinitionAstNode) { function isLibrary (node: ContractDefinitionAstNode): boolean {
return node.contractKind === 'library' return node.contractKind === 'library'
} }
@ -706,7 +706,7 @@ function isLibrary (node: ContractDefinitionAstNode) {
* @node {ASTNode} some AstNode * @node {ASTNode} some AstNode
* @return {bool} * @return {bool}
*/ */
function isCallToNonConstLocalFunction (node: FunctionCallAstNode) { function isCallToNonConstLocalFunction (node: FunctionCallAstNode): boolean {
return isLocalCall(node) && !expressionType(node, basicRegex.CONSTANTFUNCTIONTYPE) return isLocalCall(node) && !expressionType(node, basicRegex.CONSTANTFUNCTIONTYPE)
} }
@ -715,7 +715,7 @@ function isCallToNonConstLocalFunction (node: FunctionCallAstNode) {
* @node {ASTNode} some AstNode * @node {ASTNode} some AstNode
* @return {bool} * @return {bool}
*/ */
function isLibraryCall (node: MemberAccessAstNode) { function isLibraryCall (node: MemberAccessAstNode): boolean {
return isMemberAccess(node, basicRegex.FUNCTIONTYPE, undefined, basicRegex.LIBRARYTYPE, undefined) return isMemberAccess(node, basicRegex.FUNCTIONTYPE, undefined, basicRegex.LIBRARYTYPE, undefined)
} }
@ -724,7 +724,7 @@ function isLibraryCall (node: MemberAccessAstNode) {
* @node {ASTNode} some AstNode * @node {ASTNode} some AstNode
* @return {bool} * @return {bool}
*/ */
function isExternalDirectCall (node: MemberAccessAstNode) { function isExternalDirectCall (node: MemberAccessAstNode): boolean {
return isMemberAccess(node, basicRegex.EXTERNALFUNCTIONTYPE, undefined, basicRegex.CONTRACTTYPE, undefined) && !isThisLocalCall(node) && !isSuperLocalCall(node) return isMemberAccess(node, basicRegex.EXTERNALFUNCTIONTYPE, undefined, basicRegex.CONTRACTTYPE, undefined) && !isThisLocalCall(node) && !isSuperLocalCall(node)
} }
@ -733,7 +733,7 @@ function isExternalDirectCall (node: MemberAccessAstNode) {
* @node {ASTNode} some AstNode * @node {ASTNode} some AstNode
* @return {bool} * @return {bool}
*/ */
function isNowAccess (node: IdentifierAstNode) { function isNowAccess (node: IdentifierAstNode): boolean {
return node.name === "now" && typeDescription(node, exactMatch(basicTypes.UINT)) return node.name === "now" && typeDescription(node, exactMatch(basicTypes.UINT))
} }
@ -751,7 +751,7 @@ function isBlockTimestampAccess (node: MemberAccessAstNode) {
* @node {ASTNode} some AstNode * @node {ASTNode} some AstNode
* @return {bool} * @return {bool}
*/ */
function isBlockBlockHashAccess (node: MemberAccessAstNode) { function isBlockBlockHashAccess (node) {
return isSpecialVariableAccess(node, specialVariables.BLOCKHASH) || isBuiltinFunctionCall(node) && getLocalCallName(node) === 'blockhash' return isSpecialVariableAccess(node, specialVariables.BLOCKHASH) || isBuiltinFunctionCall(node) && getLocalCallName(node) === 'blockhash'
} }
@ -782,7 +782,7 @@ function isLocalCall (node: FunctionCallAstNode) {
return node.kind === 'functionCall' && return node.kind === 'functionCall' &&
node.expression.nodeType === 'Identifier' && node.expression.nodeType === 'Identifier' &&
expressionTypeDescription(node, basicRegex.FUNCTIONTYPE) && expressionTypeDescription(node, basicRegex.FUNCTIONTYPE) &&
!expressionTypeDescription(node, basicRegex.FUNCTIONTYPE) !expressionTypeDescription(node, basicRegex.EXTERNALFUNCTIONTYPE)
} }
/** /**
@ -888,7 +888,7 @@ function isTransfer (node: MemberAccessAstNode) {
undefined, matches(basicTypes.ADDRESS, basicTypes.PAYABLE_ADDRESS), exactMatch(lowLevelCallTypes.TRANSFER.ident)) undefined, matches(basicTypes.ADDRESS, basicTypes.PAYABLE_ADDRESS), exactMatch(lowLevelCallTypes.TRANSFER.ident))
} }
function isStringToBytesConversion (node) { function isStringToBytesConversion (node: FunctionCallAstNode) {
return isExplicitCast(node, util.escapeRegExp('string *'), util.escapeRegExp('bytes')) return isExplicitCast(node, util.escapeRegExp('string *'), util.escapeRegExp('bytes'))
} }
@ -926,11 +926,10 @@ function isBytesLengthCheck (node: MemberAccessAstNode) {
// #################### Complex Node Identification - Private // #################### Complex Node Identification - Private
function isMemberAccess (node: MemberAccessAstNode, retType: string, accessor: string| undefined, accessorType, memberName: string | undefined) { function isMemberAccess (node: MemberAccessAstNode, retType: string, accessor: string| undefined, accessorType, memberName: string | undefined) {
return nodeType(node, exactMatch(nodeTypes.MEMBERACCESS)) && return typeDescription(node, retType) &&
expressionType(node, retType) &&
memName(node, memberName) && memName(node, memberName) &&
memName(node.expression, accessor) && memName(node.expression, accessor) &&
expressionType(node.expression, accessorType) expressionTypeDescription(node.expression, accessorType)
} }
function isSpecialVariableAccess (node: MemberAccessAstNode, varType) { function isSpecialVariableAccess (node: MemberAccessAstNode, varType) {
@ -965,7 +964,7 @@ function nodeType (node, typeRegex) {
function memName (node, memNameRegex) { function memName (node, memNameRegex) {
const regex = new RegExp(memNameRegex) const regex = new RegExp(memNameRegex)
return (node && !memNameRegex) || (node && node.attributes && (regex.test(node.attributes.value) || regex.test(node.attributes.member_name))) return regex.test(node.name) || regex.test(node.memberName)
} }
function operator (node, opRegex) { function operator (node, opRegex) {
@ -1058,7 +1057,7 @@ export {
getFunctionOrModifierDefinitionParameterPart, getFunctionOrModifierDefinitionParameterPart,
getFunctionDefinitionReturnParameterPart, getFunctionDefinitionReturnParameterPart,
getUnAssignedTopLevelBinOps, getUnAssignedTopLevelBinOps,
getLoopBlockStartIndex, // getLoopBlockStartIndex,
// #################### Complex Node Identification // #################### Complex Node Identification
isDeleteOfDynamicArray, isDeleteOfDynamicArray,
@ -1067,7 +1066,7 @@ export {
isSpecialVariableAccess, isSpecialVariableAccess,
isDynamicArrayAccess, isDynamicArrayAccess,
isDynamicArrayLengthAccess, isDynamicArrayLengthAccess,
isIndexAccess, // isIndexAccess,
isMappingIndexAccess, isMappingIndexAccess,
isSubScopeWithTopLevelUnAssignedBinOp, isSubScopeWithTopLevelUnAssignedBinOp,
hasFunctionBody, hasFunctionBody,
@ -1126,7 +1125,7 @@ export {
isStatement, isStatement,
// isExpressionStatement, // isExpressionStatement,
// isBlock, // isBlock,
isBinaryOperation, // isBinaryOperation,
// #################### Constants // #################### Constants
nodeTypes, nodeTypes,

@ -1,7 +1,7 @@
import { default as category } from './categories' import { default as category } from './categories'
import { default as algorithm } from './algorithmCategories' import { default as algorithm } from './algorithmCategories'
import { isStringToBytesConversion, isBytesLengthCheck } from './staticAnalysisCommon' import { isStringToBytesConversion, isBytesLengthCheck } from './staticAnalysisCommon'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult} from './../../types' import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode, FunctionCallAstNode} from './../../types'
export default class stringBytesLength implements AnalyzerModule { export default class stringBytesLength implements AnalyzerModule {
name: string = 'String Length: ' name: string = 'String Length: '
@ -9,13 +9,13 @@ export default class stringBytesLength implements AnalyzerModule {
category: ModuleCategory = category.MISC category: ModuleCategory = category.MISC
algorithm: ModuleAlgorithm = algorithm.EXACT algorithm: ModuleAlgorithm = algorithm.EXACT
stringToBytesConversions: AstNodeLegacy[] = [] stringToBytesConversions: FunctionCallAstNode[] = []
bytesLengthChecks: AstNodeLegacy[] = [] bytesLengthChecks: MemberAccessAstNode[] = []
visit (node: AstNodeLegacy): void { visit (node: FunctionCallAstNode | MemberAccessAstNode): void {
if (isStringToBytesConversion(node)) this.stringToBytesConversions.push(node) if (node.nodeType === "FunctionCall" && isStringToBytesConversion(node)) this.stringToBytesConversions.push(node)
else if (isBytesLengthCheck(node)) this.bytesLengthChecks.push(node) else if (node.nodeType === "MemberAccess" && isBytesLengthCheck(node)) this.bytesLengthChecks.push(node)
} }
report (compilationResults: CompilationResult): ReportObj[] { report (compilationResults: CompilationResult): ReportObj[] {

@ -1,7 +1,7 @@
import { default as category } from './categories' import { default as category } from './categories'
import { isThisLocalCall } from './staticAnalysisCommon' import { isThisLocalCall } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories' import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, AstNodeLegacy, CompilationResult, MemberAccessAstNode} from './../../types' import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode} from './../../types'
export default class thisLocal implements AnalyzerModule { export default class thisLocal implements AnalyzerModule {
warningNodes: MemberAccessAstNode[] = [] warningNodes: MemberAccessAstNode[] = []

@ -169,7 +169,7 @@ export interface FunctionDefinitionAstNode {
overrides: OverrideSpecifierAstNode | null overrides: OverrideSpecifierAstNode | null
parameters: ParameterListAstNode parameters: ParameterListAstNode
returnParameters: ParameterListAstNode returnParameters: ParameterListAstNode
modifiers: Array<any> modifiers: Array<ModifierInvocationAstNode>
body: object | null body: object | null
implemented: boolean implemented: boolean
scope: number scope: number
@ -182,7 +182,7 @@ export interface VariableDeclarationAstNode {
nodeType: 'VariableDeclaration' nodeType: 'VariableDeclaration'
src: string src: string
name: string name: string
typeName: object typeName: ElementaryTypeNameAstNode | UserDefinedTypeNameAstNode
constant: boolean constant: boolean
stateVariable: boolean stateVariable: boolean
storageLocation: 'storage' | 'memory' | 'calldata' | 'default' storageLocation: 'storage' | 'memory' | 'calldata' | 'default'
@ -298,7 +298,7 @@ export interface BlockAstNode {
id: number id: number
nodeType: 'Block' nodeType: 'Block'
src: string src: string
statements: Array<CommonAstNode> statements: Array<any>
} }
export interface PlaceholderStatementAstNode { export interface PlaceholderStatementAstNode {
@ -481,10 +481,12 @@ export interface NewExpressionAstNode extends ExpressionAttributes {
typeName: UserDefinedTypeNameAstNode | ElementaryTypeNameAstNode typeName: UserDefinedTypeNameAstNode | ElementaryTypeNameAstNode
} }
export interface MemberAccessAstNode extends CommonAstNode, ExpressionAttributes { export interface MemberAccessAstNode extends ExpressionAttributes {
id: number
nodeType: 'MemberAccess' nodeType: 'MemberAccess'
src: string
memberName: string memberName: string
expression: object expression: any
referencedDeclaration: number | null referencedDeclaration: number | null
} }

@ -1,62 +1,51 @@
{ {
"attributes": { "argumentTypes": null,
"operator": "=", "id": 5,
"type": "uint256" "isConstant": false,
}, "isLValue": false,
"children": [ "isPure": false,
"lValueRequested": false,
"leftHandSide":
{ {
"attributes": { "argumentTypes": null,
"type": "uint256" "id": 3,
}, "name": "a",
"children": [ "nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 22,
"src": "52:1:0",
"typeDescriptions":
{ {
"attributes": { "typeIdentifier": "t_uint256",
"type": "mapping(address => uint256)", "typeString": "uint256"
"value": "c" }
},
"id": 61,
"name": "Identifier",
"src": "873:1:0"
}, },
"nodeType": "Assignment",
"operator": "=",
"rightHandSide":
{ {
"attributes": { "argumentTypes": null,
"member_name": "sender", "hexValue": "31",
"type": "address" "id": 4,
}, "isConstant": false,
"children": [ "isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "56:5:0",
"subdenomination": "wei",
"typeDescriptions":
{ {
"attributes": { "typeIdentifier": "t_rational_1_by_1",
"type": "msg", "typeString": "int_const 1"
"value": "msg"
}, },
"id": 62, "value": "1"
"name": "Identifier",
"src": "875:3:0"
}
],
"id": 63,
"name": "MemberAccess",
"src": "875:10:0"
}
],
"id": 64,
"name": "IndexAccess",
"src": "873:13:0"
}, },
"src": "52:9:0",
"typeDescriptions":
{ {
"attributes": { "typeIdentifier": "t_uint256",
"hexvalue": "30", "typeString": "uint256"
"subdenomination": null,
"token": null,
"type": "int_const 0",
"value": "0"
},
"id": 65,
"name": "Literal",
"src": "889:1:0"
}
],
"id": 66,
"name": "Assignment",
"src": "873:17:0"
} }
}

@ -1,16 +1,19 @@
{ {
"attributes": { "argumentTypes":[
"member_name": "blockhash",
"type": "function (uint256) returns (bytes32)"
},
"children": [
{ {
"attributes": { "typeIdentifier": "t_rational_3_by_1",
"type": "block", "typeString": "int_const 3"
"value": "block"
},
"name": "Identifier"
} }
], ],
"name": "MemberAccess" "id": 5,
"name": "blockhash",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": -5,
"src": "69:9:0",
"typeDescriptions":
{
"typeIdentifier": "t_function_blockhash_view$_t_uint256_$returns$_t_bytes32_$",
"typeString": "function (uint256) view returns (bytes32)"
}
} }

@ -1,204 +1,96 @@
{ {
"children": "body":
[
{
"attributes":
{ {
"argumentTypes": null, "id": 10,
"commonType": "nodeType": "Block",
{ "src": "113:2:0",
"typeIdentifier": "t_uint256", "statements": []
"typeString": "uint256"
},
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"operator": "<",
"type": "bool"
}, },
"children": "condition":
[
{
"attributes":
{ {
"argumentTypes": null, "argumentTypes": null,
"overloadedDeclarations": "expression":
[
null
],
"referencedDeclaration": 69,
"type": "uint256",
"value": "i"
},
"id": 82,
"name": "Identifier",
"src": "592:1:0"
},
{
"attributes":
{ {
"argumentTypes": null, "argumentTypes": null,
"hexvalue": "3130", "components":
"isConstant": false,
"isLValue": false,
"isPure": true,
"lValueRequested": false,
"subdenomination": null,
"token": "number",
"type": "int_const 10",
"value": "10"
},
"id": 83,
"name": "Literal",
"src": "596:2:0"
}
],
"id": 84,
"name": "BinaryOperation",
"src": "592:6:0"
},
{
"children":
[
{
"children":
[ [
{
"attributes":
{ {
"argumentTypes": null, "argumentTypes": null,
"id": 13,
"isConstant": false, "isConstant": false,
"isLValue": false, "isLValue": false,
"isPure": false, "isPure": false,
"isStructConstructorCall": false,
"lValueRequested": false, "lValueRequested": false,
"names": "leftHandSide":
[
null
],
"type": "uint256",
"type_conversion": false
},
"children":
[
{
"attributes":
{ {
"argumentTypes": "argumentTypes": null,
[ "id": 11,
{ "name": "c",
"typeIdentifier": "t_uint256", "nodeType": "Identifier",
"typeString": "uint256" "overloadedDeclarations": [],
"referencedDeclaration": 8,
"src": "123:1:0",
"typeDescriptions":
{
"typeIdentifier": "t_struct$_S_$3_storage_ptr",
"typeString": "struct C.S storage pointer"
} }
],
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"member_name": "push",
"referencedDeclaration": null,
"type": "function (uint256) returns (uint256)"
}, },
"children": "nodeType": "Assignment",
[ "operator": "=",
{ "rightHandSide":
"attributes":
{ {
"argumentTypes": null, "argumentTypes": null,
"overloadedDeclarations": "id": 12,
[ "name": "s",
null "nodeType": "Identifier",
], "overloadedDeclarations": [],
"referencedDeclaration": 4, "referencedDeclaration": 5,
"type": "uint256[] storage ref", "src": "127:1:0",
"value": "array" "typeDescriptions":
}, {
"id": 72, "typeIdentifier": "t_struct$_S_$3_storage",
"name": "Identifier", "typeString": "struct C.S storage ref"
"src": "544:5:0"
} }
],
"id": 74,
"name": "MemberAccess",
"src": "544:10:0"
}, },
"src": "123:5:0",
"typeDescriptions":
{ {
"attributes": "typeIdentifier": "t_struct$_S_$3_storage_ptr",
{ "typeString": "struct C.S storage pointer"
"argumentTypes": null,
"overloadedDeclarations":
[
null
],
"referencedDeclaration": 69,
"type": "uint256",
"value": "i"
},
"id": 75,
"name": "Identifier",
"src": "555:1:0"
} }
],
"id": 76,
"name": "FunctionCall",
"src": "544:13:0"
} }
], ],
"id": 77, "id": 14,
"name": "ExpressionStatement",
"src": "544:13:0"
},
{
"children":
[
{
"attributes":
{
"argumentTypes": null,
"isConstant": false, "isConstant": false,
"isInlineArray": false,
"isLValue": false, "isLValue": false,
"isPure": false, "isPure": false,
"lValueRequested": false, "lValueRequested": false,
"operator": "++", "nodeType": "TupleExpression",
"prefix": false, "src": "122:7:0",
"type": "uint256" "typeDescriptions":
},
"children":
[
{
"attributes":
{ {
"argumentTypes": null, "typeIdentifier": "t_struct$_S_$3_storage_ptr",
"overloadedDeclarations": "typeString": "struct C.S storage pointer"
[
null
],
"referencedDeclaration": 69,
"type": "uint256",
"value": "i"
},
"id": 78,
"name": "Identifier",
"src": "571:1:0"
} }
], },
"id": 79, "id": 15,
"name": "UnaryOperation", "isConstant": false,
"src": "571:3:0" "isLValue": true,
} "isPure": false,
], "lValueRequested": false,
"id": 80, "memberName": "f",
"name": "ExpressionStatement", "nodeType": "MemberAccess",
"src": "571:3:0" "referencedDeclaration": 2,
} "src": "122:9:0",
], "typeDescriptions":
"id": 81, {
"name": "Block", "typeIdentifier": "t_bool",
"src": "530:55:0" "typeString": "bool"
}
],
"id": 85,
"name": "DoWhileStatement",
"src": "528:72:0"
} }
},
"id": 16,
"nodeType": "DoWhileStatement",
"src": "110:23:0"
}

@ -1,68 +1,101 @@
{ {
"children": "body":
{
"id": 20,
"nodeType": "Block",
"src": "81:58:0",
"statements":
[ [
{ {
"attributes": "id": 13,
"nodeType": "Break",
"src": "95:5:0"
},
{ {
"assignments": "assignments":
[ [
21 15
] ],
}, "declarations":
"children":
[ [
{
"attributes":
{ {
"constant": false, "constant": false,
"name": "i", "id": 15,
"scope": 39, "name": "b",
"nodeType": "VariableDeclaration",
"overrides": null,
"scope": 20,
"src": "114:6:0",
"stateVariable": false, "stateVariable": false,
"storageLocation": "default", "storageLocation": "default",
"type": "uint256", "typeDescriptions":
"value": null,
"visibility": "internal"
},
"children":
[
{ {
"attributes": "typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName":
{ {
"id": 14,
"name": "uint", "name": "uint",
"type": "uint256" "nodeType": "ElementaryTypeName",
"src": "114:4:0",
"typeDescriptions":
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
}, },
"id": 20, "value": null,
"name": "ElementaryTypeName", "visibility": "internal"
"src": "207:4:0"
} }
], ],
"id": 21, "id": 17,
"name": "VariableDeclaration", "initialValue":
"src": "207:6:0" {
"argumentTypes": null,
"hexValue": "3432",
"id": 16,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "123:2:0",
"subdenomination": null,
"typeDescriptions":
{
"typeIdentifier": "t_rational_42_by_1",
"typeString": "int_const 42"
},
"value": "42"
},
"nodeType": "VariableDeclarationStatement",
"src": "114:11:0"
}, },
{ {
"attributes": "expression":
{ {
"argumentTypes": null, "argumentTypes": null,
"overloadedDeclarations": "id": 18,
[ "name": "b",
null "nodeType": "Identifier",
], "overloadedDeclarations": [],
"referencedDeclaration": 17, "referencedDeclaration": 15,
"type": "uint256", "src": "127:1:0",
"value": "index" "typeDescriptions":
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
}, },
"id": 22, "id": 19,
"name": "Identifier", "nodeType": "ExpressionStatement",
"src": "216:5:0" "src": "127:1:0"
} }
], ]
"id": 23,
"name": "VariableDeclarationStatement",
"src": "207:14:0"
}, },
{ "condition":
"attributes":
{ {
"argumentTypes": null, "argumentTypes": null,
"commonType": "commonType":
@ -70,195 +103,158 @@
"typeIdentifier": "t_uint256", "typeIdentifier": "t_uint256",
"typeString": "uint256" "typeString": "uint256"
}, },
"id": 9,
"isConstant": false, "isConstant": false,
"isLValue": false, "isLValue": false,
"isPure": false, "isPure": false,
"lValueRequested": false, "lValueRequested": false,
"operator": "<", "leftExpression":
"type": "bool"
},
"children":
[
{
"attributes":
{ {
"argumentTypes": null, "argumentTypes": null,
"overloadedDeclarations": "id": 7,
[ "name": "a",
null "nodeType": "Identifier",
], "overloadedDeclarations": [],
"referencedDeclaration": 21, "referencedDeclaration": 4,
"type": "uint256", "src": "69:1:0",
"value": "i" "typeDescriptions":
},
"id": 24,
"name": "Identifier",
"src": "223:1:0"
},
{ {
"attributes": "typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "BinaryOperation",
"operator": "<",
"rightExpression":
{ {
"argumentTypes": null, "argumentTypes": null,
"hexvalue": "3130", "hexValue": "31",
"id": 8,
"isConstant": false, "isConstant": false,
"isLValue": false, "isLValue": false,
"isPure": true, "isPure": true,
"kind": "number",
"lValueRequested": false, "lValueRequested": false,
"nodeType": "Literal",
"src": "73:1:0",
"subdenomination": null, "subdenomination": null,
"token": "number", "typeDescriptions":
"type": "int_const 10", {
"value": "10" "typeIdentifier": "t_rational_1_by_1",
"typeString": "int_const 1"
},
"value": "1"
}, },
"id": 25, "src": "69:5:0",
"name": "Literal", "typeDescriptions":
"src": "227:2:0" {
"typeIdentifier": "t_bool",
"typeString": "bool"
} }
],
"id": 26,
"name": "BinaryOperation",
"src": "223:6:0"
}, },
"id": 21,
"initializationExpression":
{ {
"children": "assignments":
[
4
],
"declarations":
[ [
{ {
"attributes": "constant": false,
"id": 4,
"name": "a",
"nodeType": "VariableDeclaration",
"overrides": null,
"scope": 21,
"src": "57:6:0",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions":
{ {
"argumentTypes": null, "typeIdentifier": "t_uint256",
"isConstant": false, "typeString": "uint256"
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"operator": "++",
"prefix": false,
"type": "uint256"
}, },
"children": "typeName":
[
{ {
"attributes": "id": 3,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "57:4:0",
"typeDescriptions":
{ {
"argumentTypes": null, "typeIdentifier": "t_uint256",
"overloadedDeclarations": "typeString": "uint256"
[
null
],
"referencedDeclaration": 21,
"type": "uint256",
"value": "i"
},
"id": 27,
"name": "Identifier",
"src": "231:1:0"
} }
], },
"id": 28, "value": null,
"name": "UnaryOperation", "visibility": "internal"
"src": "231:3:0"
} }
], ],
"id": 29, "id": 6,
"name": "ExpressionStatement", "initialValue":
"src": "231:3:0"
},
{
"children":
[
{
"children":
[
{
"attributes":
{ {
"argumentTypes": null, "argumentTypes": null,
"hexValue": "30",
"id": 5,
"isConstant": false, "isConstant": false,
"isLValue": false, "isLValue": false,
"isPure": false, "isPure": true,
"isStructConstructorCall": false, "kind": "number",
"lValueRequested": false, "lValueRequested": false,
"names": "nodeType": "Literal",
[ "src": "66:1:0",
null "subdenomination": null,
], "typeDescriptions":
"type": "uint256",
"type_conversion": false
},
"children":
[
{ {
"attributes": "typeIdentifier": "t_rational_0_by_1",
"typeString": "int_const 0"
},
"value": "0"
},
"nodeType": "VariableDeclarationStatement",
"src": "57:10:0"
},
"loopExpression":
{ {
"argumentTypes": "expression":
[
{ {
"typeIdentifier": "t_uint256", "argumentTypes": null,
"typeString": "uint256" "id": 11,
}
],
"isConstant": false, "isConstant": false,
"isLValue": false, "isLValue": false,
"isPure": false, "isPure": false,
"lValueRequested": false, "lValueRequested": false,
"member_name": "push", "nodeType": "UnaryOperation",
"referencedDeclaration": null, "operator": "++",
"type": "function (uint256) returns (uint256)" "prefix": false,
}, "src": "76:3:0",
"children": "subExpression":
[
{
"attributes":
{ {
"argumentTypes": null, "argumentTypes": null,
"overloadedDeclarations": "id": 10,
[ "name": "a",
null "nodeType": "Identifier",
], "overloadedDeclarations": [],
"referencedDeclaration": 4, "referencedDeclaration": 4,
"type": "uint256[] storage ref", "src": "76:1:0",
"value": "array" "typeDescriptions":
}, {
"id": 30, "typeIdentifier": "t_uint256",
"name": "Identifier", "typeString": "uint256"
"src": "250:5:0"
} }
],
"id": 32,
"name": "MemberAccess",
"src": "250:10:0"
}, },
"typeDescriptions":
{ {
"attributes": "typeIdentifier": "t_uint256",
{ "typeString": "uint256"
"argumentTypes": null,
"overloadedDeclarations":
[
null
],
"referencedDeclaration": 21,
"type": "uint256",
"value": "i"
},
"id": 33,
"name": "Identifier",
"src": "261:1:0"
}
],
"id": 34,
"name": "FunctionCall",
"src": "250:13:0"
}
],
"id": 35,
"name": "ExpressionStatement",
"src": "250:13:0"
}
],
"id": 36,
"name": "Block",
"src": "236:38:0"
}
],
"id": 37,
"name": "ForStatement",
"src": "202:72:0"
} }
},
"id": 12,
"nodeType": "ExpressionStatement",
"src": "76:3:0"
},
"nodeType": "ForStatement",
"src": "52:87:0"
}

@ -1,24 +1,82 @@
{ {
"attributes": { "body":
"constant": true,
"name": "winnerName",
"payable": false,
"visibility": "public"
},
"children": [
{ {
"children": [ "id": 6,
"nodeType": "Block",
"src": "42:23:0",
"statements":
[
{
"assignments":
[
4
], ],
"name": "ParameterList" "declarations":
}, [
{ {
"children": [], "constant": false,
"name": "ParameterList" "id": 4,
"name": "a",
"nodeType": "VariableDeclaration",
"overrides": null,
"scope": 6,
"src": "52:6:0",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions":
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}, },
"typeName":
{
"id": 3,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "52:4:0",
"typeDescriptions":
{ {
"children": [], "typeIdentifier": "t_uint256",
"name": "Block" "typeString": "uint256"
}
},
"value": null,
"visibility": "internal"
} }
], ],
"name": "FunctionDefinition" "id": 5,
"initialValue": null,
"nodeType": "VariableDeclarationStatement",
"src": "52:6:0"
} }
]
},
"documentation": null,
"functionSelector": "26121ff0",
"id": 7,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "f",
"nodeType": "FunctionDefinition",
"overrides": null,
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "27:2:0"
},
"returnParameters":
{
"id": 2,
"nodeType": "ParameterList",
"parameters": [],
"src": "42:0:0"
},
"scope": 8,
"src": "17:48:0",
"stateMutability": "pure",
"virtual": false,
"visibility": "public"
}

@ -1,15 +1,20 @@
{ {
"children": [ "arguments": null,
"baseName":
{ {
"attributes": { "contractScope": null,
"name": "r" "id": 19,
}, "name": "A",
"id": 7, "nodeType": "UserDefinedTypeName",
"name": "UserDefinedTypeName", "referencedDeclaration": 9,
"src": "84:1:0" "src": "176:1:0",
"typeDescriptions":
{
"typeIdentifier": "t_contract$_A_$9",
"typeString": "contract A"
} }
], },
"id": 8, "id": 20,
"name": "InheritanceSpecifier", "nodeType": "InheritanceSpecifier",
"src": "84:1:0" "src": "176:1:0"
} }

@ -1,7 +1,95 @@
{ {
"children": [ "AST":
], {
"id": 21, "nodeType": "YulBlock",
"name": "InlineAssembly", "src": "148:83:0",
"src": "809:41:0" "statements":
[
{
"nodeType": "YulVariableDeclaration",
"src": "162:11:0",
"value":
{
"name": "x",
"nodeType": "YulIdentifier",
"src": "172:1:0"
},
"variables":
[
{
"name": "c1",
"nodeType": "YulTypedName",
"src": "166:2:0",
"type": ""
}
]
},
{
"nodeType": "YulVariableDeclaration",
"src": "186:11:0",
"value":
{
"name": "b",
"nodeType": "YulIdentifier",
"src": "196:1:0"
},
"variables":
[
{
"name": "c2",
"nodeType": "YulTypedName",
"src": "190:2:0",
"type": ""
}
]
},
{
"nodeType": "YulVariableDeclaration",
"src": "210:11:0",
"value":
{
"name": "s",
"nodeType": "YulIdentifier",
"src": "220:1:0"
},
"variables":
[
{
"name": "c3",
"nodeType": "YulTypedName",
"src": "214:2:0",
"type": ""
} }
]
}
]
},
"evmVersion": "istanbul",
"externalReferences":
[
{
"declaration": 8,
"isOffset": false,
"isSlot": false,
"src": "196:1:0",
"valueSize": 1
},
{
"declaration": 11,
"isOffset": false,
"isSlot": false,
"src": "220:1:0",
"valueSize": 1
},
{
"declaration": 5,
"isOffset": false,
"isSlot": false,
"src": "172:1:0",
"valueSize": 1
}
],
"id": 14,
"nodeType": "InlineAssembly",
"src": "139:92:0"
}

@ -1,16 +1,32 @@
{ {
"attributes": { "argumentTypes": null,
"member_name": "insert", "expression":
"type": "function (struct Set.Data storage pointer,uint256) returns (bool)" {
}, "argumentTypes": null,
"children": [ "id": 33,
"name": "L",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 21,
"src": "244:1:0",
"typeDescriptions":
{ {
"attributes": { "typeIdentifier": "t_type$_t_contract$_L_$21_$",
"type": "type(library Set)", "typeString": "type(library L)"
"value": "Set" }
}, },
"name": "Identifier" "id": 34,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "f",
"nodeType": "MemberAccess",
"referencedDeclaration": 6,
"src": "244:3:0",
"typeDescriptions":
{
"typeIdentifier": "t_function_delegatecall_nonpayable$_t_uint256_$returns$__$",
"typeString": "function (uint256)"
} }
],
"name": "MemberAccess"
} }

@ -1,29 +1,34 @@
{ {
"attributes": { "argumentTypes": null,
"type": "tuple()", "arguments": [],
"type_conversion": false "expression":
},
"children": [
{ {
"attributes": { "argumentTypes": [],
"type": "function (struct Ballot.Voter storage pointer)", "id": 13,
"value": "bli" "name": "sha3",
}, "nodeType": "Identifier",
"id": 37, "overloadedDeclarations": [],
"name": "Identifier", "referencedDeclaration": 8,
"src": "540:3:0" "src": "129:4:0",
}, "typeDescriptions":
{ {
"attributes": { "typeIdentifier": "t_function_internal_pure$__$returns$_t_bool_$",
"type": "struct Ballot.Voter storage pointer", "typeString": "function () pure returns (bool)"
"value": "x"
},
"id": 38,
"name": "Identifier",
"src": "544:1:0"
} }
], },
"id": 39, "id": 14,
"name": "FunctionCall", "isConstant": false,
"src": "540:6:0" "isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "129:6:0",
"tryCall": false,
"typeDescriptions":
{
"typeIdentifier": "t_bool",
"typeString": "bool"
} }
}

@ -1,42 +1,142 @@
{ {
"sendAst": { "name": "MemberAccess", "sendAst": {
"children": [ "argumentTypes":
[
{ {
"attributes": { "typeIdentifier": "t_rational_1_by_1",
"value": "d", "typeString": "int_const 1"
"type": "address" }
],
"expression":
{
"argumentTypes": null,
"id": 27,
"name": "addr",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 4,
"src": "227:4:0",
"typeDescriptions":
{
"typeIdentifier": "t_address_payable",
"typeString": "address payable"
}
},
"id": 28,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "send",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "227:9:0",
"typeDescriptions":
{
"typeIdentifier": "t_function_send_nonpayable$_t_uint256_$returns$_t_bool_$",
"typeString": "function (uint256) returns (bool)"
}
},
"callAst": {
"argumentTypes": null,
"expression":
{
"argumentTypes": null,
"id": 9,
"name": "a",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 6,
"src": "91:1:0",
"typeDescriptions":
{
"typeIdentifier": "t_address",
"typeString": "address"
}
},
"id": 12,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "call",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "91:6:0",
"typeDescriptions":
{
"typeIdentifier": "t_function_barecall_payable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$",
"typeString": "function (bytes memory) payable returns (bool,bytes memory)"
} }
}],
"attributes": {
"value": "send",
"type": "function (uint256) returns (bool)" }
}, },
"callAst": { "name": "MemberAccess", "children": [{
"attributes": {
"value": "f",
"type": "address"
}}],
"attributes": {
"member_name": "call",
"type": "function () payable returns (bool)" } },
"callcodeAst": { "callcodeAst": {
"name": "MemberAccess", "argumentTypes": [],
"children": [{ "expression":
"attributes": { {
"value": "f", "argumentTypes": null,
"type": "address" "id": 3,
}}], "name": "test",
"attributes": { "nodeType": "Identifier",
"member_name": "callcode", "overloadedDeclarations": [],
"type": "function () payable returns (bool)" } }, "referencedDeclaration": 10,
"src": "62:4:0",
"typeDescriptions":
{
"typeIdentifier": "t_type$_t_contract$_test_$10_$",
"typeString": "type(contract test)"
}
},
"id": 5,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "callcode",
"nodeType": "MemberAccess",
"referencedDeclaration": 9,
"src": "62:13:0",
"typeDescriptions":
{
"typeIdentifier": "t_function_internal_pure$__$returns$__$",
"typeString": "function () pure"
}
},
"delegatecallAst": { "delegatecallAst": {
"name": "MemberAccess", "argumentTypes":
"children": [{ [
"attributes": { {
"value": "g", "typeIdentifier": "t_stringliteral_c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
"type": "address" "typeString": "literal_string \"\""
}}], }
"attributes": { ],
"member_name": "delegatecall", "expression":
"type": "function () returns (bool)" } } {
"argumentTypes": null,
"id": 20,
"name": "addr",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 4,
"src": "181:4:0",
"typeDescriptions":
{
"typeIdentifier": "t_address_payable",
"typeString": "address payable"
}
},
"id": 21,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "delegatecall",
"nodeType": "MemberAccess",
"referencedDeclaration": null,
"src": "181:17:0",
"typeDescriptions":
{
"typeIdentifier": "t_function_baredelegatecall_nonpayable$_t_bytes_memory_ptr_$returns$_t_bool_$_t_bytes_memory_ptr_$",
"typeString": "function (bytes memory) returns (bool,bytes memory)"
}
}
} }

@ -1,71 +1,93 @@
{ {
"attributes": {
"argumentTypes": null, "argumentTypes": null,
"arguments":
[
{
"argumentTypes": null,
"hexValue": "32",
"id": 37,
"isConstant": false, "isConstant": false,
"isLValue": false, "isLValue": false,
"isPure": false, "isPure": true,
"isStructConstructorCall": false, "kind": "number",
"lValueRequested": false, "lValueRequested": false,
"names": [ "nodeType": "Literal",
null "src": "234:1:0",
], "subdenomination": null,
"type": "uint256", "typeDescriptions":
"type_conversion": false {
"typeIdentifier": "t_rational_2_by_1",
"typeString": "int_const 2"
},
"value": "2"
}, },
"children": [
{ {
"attributes": { "argumentTypes": null,
"argumentTypes": [ "hexValue": "31",
"id": 38,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "240:1:0",
"subdenomination": null,
"typeDescriptions":
{ {
"typeIdentifier": "t_uint256", "typeIdentifier": "t_rational_1_by_1",
"typeString": "uint256" "typeString": "int_const 1"
}, },
{ "value": "1"
"typeIdentifier": "t_uint256",
"typeString": "uint256"
} }
], ],
"overloadedDeclarations": [ "expression":
null
],
"referencedDeclaration": 25,
"type": "function (uint256,uint256) pure returns (uint256)",
"value": "f"
},
"id": 34,
"name": "Identifier",
"src": "267:1:0"
},
{ {
"attributes": { "argumentTypes":
"argumentTypes": null, [
"overloadedDeclarations": [ {
null "typeIdentifier": "t_rational_2_by_1",
], "typeString": "int_const 2"
"referencedDeclaration": 27,
"type": "uint256",
"value": "x"
},
"id": 35,
"name": "Identifier",
"src": "269:1:0"
}, },
{ {
"attributes": { "typeIdentifier": "t_rational_1_by_1",
"argumentTypes": null, "typeString": "int_const 1"
"overloadedDeclarations": [ }
null
], ],
"referencedDeclaration": 29,
"type": "uint256",
"value": "y"
},
"id": 36, "id": 36,
"name": "Identifier", "name": "f",
"src": "272:1:0" "nodeType": "Identifier",
"overloadedDeclarations":
[
6,
14,
24
],
"referencedDeclaration": 14,
"src": "228:1:0",
"typeDescriptions":
{
"typeIdentifier": "t_function_internal_nonpayable$_t_uint256_$_t_uint256_$returns$__$",
"typeString": "function (uint256,uint256)"
} }
},
"id": 39,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names":
[
"y",
"x"
], ],
"id": 37, "nodeType": "FunctionCall",
"name": "FunctionCall", "src": "228:15:0",
"src": "267:7:0" "tryCall": false,
"typeDescriptions":
{
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
} }
}

@ -1,23 +1,56 @@
{ {
"attributes": { "argumentTypes": null,
"type": "tuple()", "arguments":
"type_conversion": false [
},
"children": [
{ {
"attributes": { "argumentTypes": null,
"type": "function (address)", "id": 6,
"value": "selfdestruct" "name": "a",
}, "nodeType": "Identifier",
"name": "Identifier" "overloadedDeclarations": [],
}, "referencedDeclaration": 2,
"src": "77:1:0",
"typeDescriptions":
{ {
"attributes": { "typeIdentifier": "t_address_payable",
"type": "address", "typeString": "address payable"
"value": "a" }
},
"name": "Identifier"
} }
], ],
"name": "FunctionCall" "expression":
{
"argumentTypes":
[
{
"typeIdentifier": "t_address_payable",
"typeString": "address payable"
}
],
"id": 5,
"name": "selfdestruct",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": -21,
"src": "64:12:0",
"typeDescriptions":
{
"typeIdentifier": "t_function_selfdestruct_nonpayable$_t_address_payable_$returns$__$",
"typeString": "function (address payable)"
}
},
"id": 7,
"isConstant": false,
"isLValue": false,
"isPure": false,
"kind": "functionCall",
"lValueRequested": false,
"names": [],
"nodeType": "FunctionCall",
"src": "64:15:0",
"tryCall": false,
"typeDescriptions":
{
"typeIdentifier": "t_tuple$__$",
"typeString": "tuple()"
} }
}

@ -1,108 +1,336 @@
{ {
"attributes": { "abstract": false,
"baseContracts": [],
"contractDependencies": [],
"contractKind": "contract",
"documentation": null,
"fullyImplemented": true, "fullyImplemented": true,
"isLibrary": false, "id": 24,
"linearizedBaseContracts": [ "linearizedBaseContracts":
274 [
24
], ],
"name": "Ballot" "name": "C",
}, "nodeType": "ContractDefinition",
"children": [ "nodes":
[
{ {
"attributes": { "body":
"name": "Voter" {
}, "id": 22,
"children": [], "nodeType": "Block",
"name": "StructDefinition" "src": "52:69:0",
}, "statements":
[
{ {
"attributes": { "assignments":
"name": "Proposal" [
10
],
"declarations":
[
{
"constant": false,
"id": 10,
"name": "z",
"nodeType": "VariableDeclaration",
"overrides": null,
"scope": 22,
"src": "62:17:0",
"stateVariable": false,
"storageLocation": "memory",
"typeDescriptions":
{
"typeIdentifier": "t_array$_t_uint8_$4_memory_ptr",
"typeString": "uint8[4]"
}, },
"children": [], "typeName":
"name": "StructDefinition" {
"baseType":
{
"id": 8,
"name": "uint8",
"nodeType": "ElementaryTypeName",
"src": "62:5:0",
"typeDescriptions":
{
"typeIdentifier": "t_uint8",
"typeString": "uint8"
}
}, },
"id": 9,
"length":
{
"argumentTypes": null,
"hexValue": "34",
"id": 7,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "68:1:0",
"subdenomination": null,
"typeDescriptions":
{ {
"attributes": { "typeIdentifier": "t_rational_4_by_1",
"name": "chairperson", "typeString": "int_const 4"
"type": "address"
}, },
"children": [ "value": "4"
},
"nodeType": "ArrayTypeName",
"src": "62:8:0",
"typeDescriptions":
{ {
"attributes": { "typeIdentifier": "t_array$_t_uint8_$4_storage_ptr",
"name": "address" "typeString": "uint8[4]"
}
}, },
"name": "ElementaryTypeName" "value": null,
"visibility": "internal"
} }
], ],
"name": "VariableDeclaration" "id": 16,
"initialValue":
{
"argumentTypes": null,
"components":
[
{
"argumentTypes": null,
"hexValue": "31",
"id": 11,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "83:1:0",
"subdenomination": null,
"typeDescriptions":
{
"typeIdentifier": "t_rational_1_by_1",
"typeString": "int_const 1"
},
"value": "1"
}, },
{ {
"attributes": { "argumentTypes": null,
"name": "voters", "hexValue": "32",
"type": "mapping(address => struct Ballot.Voter storage ref)" "id": 12,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "85:1:0",
"subdenomination": null,
"typeDescriptions":
{
"typeIdentifier": "t_rational_2_by_1",
"typeString": "int_const 2"
},
"value": "2"
}, },
"children": [
{ {
"children": [ "argumentTypes": null,
"hexValue": "33",
"id": 13,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "87:1:0",
"subdenomination": null,
"typeDescriptions":
{ {
"attributes": { "typeIdentifier": "t_rational_3_by_1",
"name": "address" "typeString": "int_const 3"
}, },
"name": "ElementaryTypeName" "value": "3"
}, },
{ {
"attributes": { "argumentTypes": null,
"name": "Voter" "hexValue": "35",
"id": 14,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "89:1:0",
"subdenomination": null,
"typeDescriptions":
{
"typeIdentifier": "t_rational_5_by_1",
"typeString": "int_const 5"
}, },
"name": "UserDefinedTypeName" "value": "5"
} }
], ],
"name": "Mapping" "id": 15,
"isConstant": false,
"isInlineArray": true,
"isLValue": false,
"isPure": true,
"lValueRequested": false,
"nodeType": "TupleExpression",
"src": "82:9:0",
"typeDescriptions":
{
"typeIdentifier": "t_array$_t_uint8_$4_memory_ptr",
"typeString": "uint8[4] memory"
} }
], },
"name": "VariableDeclaration" "nodeType": "VariableDeclarationStatement",
"src": "62:29:0"
}, },
{ {
"attributes": { "expression":
"name": "proposals", {
"type": "struct Ballot.Proposal storage ref[] storage ref" "argumentTypes": null,
"components":
[
{
"argumentTypes": null,
"baseExpression":
{
"argumentTypes": null,
"id": 17,
"name": "z",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 10,
"src": "109:1:0",
"typeDescriptions":
{
"typeIdentifier": "t_array$_t_uint8_$4_memory_ptr",
"typeString": "uint8[4] memory"
}
}, },
"children": [ "id": 19,
"indexExpression":
{ {
"children": [ "argumentTypes": null,
"hexValue": "30",
"id": 18,
"isConstant": false,
"isLValue": false,
"isPure": true,
"kind": "number",
"lValueRequested": false,
"nodeType": "Literal",
"src": "111:1:0",
"subdenomination": null,
"typeDescriptions":
{ {
"attributes": { "typeIdentifier": "t_rational_0_by_1",
"name": "Proposal" "typeString": "int_const 0"
},
"value": "0"
}, },
"name": "UserDefinedTypeName" "isConstant": false,
"isLValue": true,
"isPure": false,
"lValueRequested": false,
"nodeType": "IndexAccess",
"src": "109:4:0",
"typeDescriptions":
{
"typeIdentifier": "t_uint8",
"typeString": "uint8"
} }
],
"name": "ArrayTypeName"
} }
], ],
"name": "VariableDeclaration" "id": 20,
}, "isConstant": false,
"isInlineArray": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"nodeType": "TupleExpression",
"src": "108:6:0",
"typeDescriptions":
{ {
"attributes": { "typeIdentifier": "t_uint8",
"constant": false, "typeString": "uint8"
"name": "Ballot", }
"payable": false,
"visibility": "public"
}, },
"children": [], "functionReturnParameters": 4,
"name": "FunctionDefinition" "id": 21,
"nodeType": "Return",
"src": "101:13:0"
}
]
}, },
"documentation": null,
"functionSelector": "26121ff0",
"id": 23,
"implemented": true,
"kind": "function",
"modifiers": [],
"name": "f",
"nodeType": "FunctionDefinition",
"overrides": null,
"parameters":
{
"id": 1,
"nodeType": "ParameterList",
"parameters": [],
"src": "27:2:0"
},
"returnParameters":
{
"id": 4,
"nodeType": "ParameterList",
"parameters":
[
{ {
"attributes": {
"constant": false, "constant": false,
"name": "giveRightToVote", "id": 3,
"payable": false, "name": "",
"visibility": "public" "nodeType": "VariableDeclaration",
"overrides": null,
"scope": 23,
"src": "46:4:0",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions":
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"typeName":
{
"id": 2,
"name": "uint",
"nodeType": "ElementaryTypeName",
"src": "46:4:0",
"typeDescriptions":
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
}, },
"children": [], "value": null,
"name": "FunctionDefinition" "visibility": "internal"
} }
], ],
"name": "ContractDefinition" "src": "45:6:0"
},
"scope": 24,
"src": "17:104:0",
"stateMutability": "nonpayable",
"virtual": false,
"visibility": "public"
} }
],
"scope": 25,
"src": "0:123:0"
}

@ -1,16 +1,32 @@
{ {
"attributes": { "argumentTypes": [],
"member_name": "duper", "expression":
"type": "function ()" {
}, "argumentTypes": null,
"children": [ "id": 10,
"name": "super",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": -25,
"src": "162:5:0",
"typeDescriptions":
{ {
"attributes": { "typeIdentifier": "t_super$_B_$17",
"type": "contract super a", "typeString": "contract super B"
"value": "super" }
}, },
"name": "Identifier" "id": 12,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "x",
"nodeType": "MemberAccess",
"referencedDeclaration": 4,
"src": "162:7:0",
"typeDescriptions":
{
"typeIdentifier": "t_function_internal_pure$__$returns$__$",
"typeString": "function () pure"
} }
],
"name": "MemberAccess"
} }

@ -1,10 +1,32 @@
{ {
"name": "MemberAccess", "argumentTypes": null,
"children": [ { "expression":
"attributes": { {
"value": "this", "argumentTypes": null,
"type": "contract test" }, "id": 13,
"name": "Identifier" } ], "name": "this",
"attributes": { "nodeType": "Identifier",
"value": "b", "overloadedDeclarations": [],
"type": "function (bytes32,address) returns (bool)" } } "referencedDeclaration": -28,
"src": "138:4:0",
"typeDescriptions":
{
"typeIdentifier": "t_contract$_C_$21",
"typeString": "contract C"
}
},
"id": 14,
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"memberName": "h",
"nodeType": "MemberAccess",
"referencedDeclaration": 4,
"src": "138:6:0",
"typeDescriptions":
{
"typeIdentifier": "t_function_external_payable$__$returns$__$",
"typeString": "function () payable external"
}
}

@ -1,204 +1,101 @@
{ {
"children": "body":
{
"id": 13,
"nodeType": "Block",
"src": "89:27:0",
"statements":
[ [
{ {
"attributes": "expression":
{ {
"argumentTypes": null, "argumentTypes": null,
"commonType": "id": 9,
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
},
"isConstant": false, "isConstant": false,
"isLValue": false, "isLValue": false,
"isPure": false, "isPure": false,
"lValueRequested": false, "lValueRequested": false,
"operator": "<", "leftHandSide":
"type": "bool"
},
"children":
[
{
"attributes":
{ {
"argumentTypes": null, "argumentTypes": null,
"overloadedDeclarations": "id": 7,
[ "name": "x",
null "nodeType": "Identifier",
], "overloadedDeclarations": [],
"referencedDeclaration": 45, "referencedDeclaration": 4,
"type": "uint256", "src": "91:1:0",
"value": "i" "typeDescriptions":
},
"id": 48,
"name": "Identifier",
"src": "372:1:0"
},
{ {
"attributes": "typeIdentifier": "t_uint256",
"typeString": "uint256"
}
},
"nodeType": "Assignment",
"operator": "=",
"rightHandSide":
{ {
"argumentTypes": null, "argumentTypes": null,
"hexvalue": "3130", "hexValue": "31",
"id": 8,
"isConstant": false, "isConstant": false,
"isLValue": false, "isLValue": false,
"isPure": true, "isPure": true,
"kind": "number",
"lValueRequested": false, "lValueRequested": false,
"nodeType": "Literal",
"src": "95:1:0",
"subdenomination": null, "subdenomination": null,
"token": "number", "typeDescriptions":
"type": "int_const 10",
"value": "10"
},
"id": 49,
"name": "Literal",
"src": "376:2:0"
}
],
"id": 50,
"name": "BinaryOperation",
"src": "372:6:0"
},
{
"children":
[
{
"children":
[
{ {
"attributes": "typeIdentifier": "t_rational_1_by_1",
{ "typeString": "int_const 1"
"argumentTypes": null,
"isConstant": false,
"isLValue": false,
"isPure": false,
"isStructConstructorCall": false,
"lValueRequested": false,
"names":
[
null
],
"type": "uint256",
"type_conversion": false
}, },
"children": "value": "1"
[ },
{ "src": "91:5:0",
"attributes": "typeDescriptions":
{
"argumentTypes":
[
{ {
"typeIdentifier": "t_uint256", "typeIdentifier": "t_uint256",
"typeString": "uint256" "typeString": "uint256"
} }
],
"isConstant": false,
"isLValue": false,
"isPure": false,
"lValueRequested": false,
"member_name": "push",
"referencedDeclaration": null,
"type": "function (uint256) returns (uint256)"
}, },
"children": "id": 10,
[ "nodeType": "ExpressionStatement",
{ "src": "91:5:0"
"attributes":
{
"argumentTypes": null,
"overloadedDeclarations":
[
null
],
"referencedDeclaration": 4,
"type": "uint256[] storage ref",
"value": "array"
},
"id": 51,
"name": "Identifier",
"src": "394:5:0"
}
],
"id": 53,
"name": "MemberAccess",
"src": "394:10:0"
}, },
{ {
"attributes": "id": 11,
{ "nodeType": "Break",
"argumentTypes": null, "src": "98:5:0"
"overloadedDeclarations":
[
null
],
"referencedDeclaration": 45,
"type": "uint256",
"value": "i"
}, },
"id": 54, {
"name": "Identifier", "id": 12,
"src": "405:1:0" "nodeType": "Continue",
} "src": "105:8:0"
],
"id": 55,
"name": "FunctionCall",
"src": "394:13:0"
} }
], ]
"id": 56,
"name": "ExpressionStatement",
"src": "394:13:0"
}, },
{ "condition":
"children":
[
{
"attributes":
{ {
"argumentTypes": null, "argumentTypes": null,
"hexValue": "74727565",
"id": 6,
"isConstant": false, "isConstant": false,
"isLValue": false, "isLValue": false,
"isPure": false, "isPure": true,
"kind": "bool",
"lValueRequested": false, "lValueRequested": false,
"operator": "++", "nodeType": "Literal",
"prefix": false, "src": "83:4:0",
"type": "uint256" "subdenomination": null,
}, "typeDescriptions":
"children":
[
{
"attributes":
{ {
"argumentTypes": null, "typeIdentifier": "t_bool",
"overloadedDeclarations": "typeString": "bool"
[
null
],
"referencedDeclaration": 45,
"type": "uint256",
"value": "i"
}, },
"id": 57, "value": "true"
"name": "Identifier", },
"src": "421:1:0" "id": 14,
} "nodeType": "WhileStatement",
], "src": "76:40:0"
"id": 58, }
"name": "UnaryOperation",
"src": "421:3:0"
}
],
"id": 59,
"name": "ExpressionStatement",
"src": "421:3:0"
}
],
"id": 60,
"name": "Block",
"src": "380:55:0"
}
],
"id": 61,
"name": "WhileStatement",
"src": "365:70:0"
}

@ -103,36 +103,36 @@ test('staticAnalysisCommon.helpers.expressionType', function (t) {
lowlevelAccessersCommon(t, common.helpers.expressionType, node) lowlevelAccessersCommon(t, common.helpers.expressionType, node)
}) })
test('staticAnalysisCommon.helpers.nrOfChildren', function (t) { // test('staticAnalysisCommon.helpers.nrOfChildren', function (t) {
t.plan(10) // t.plan(10)
const node = { name: 'Identifier', children: ['a', 'b'], attributes: { value: 'now', type: 'uint256' } } // const node = { name: 'Identifier', children: ['a', 'b'], attributes: { value: 'now', type: 'uint256' } }
const node2 = { name: 'FunctionCall', children: [], attributes: { member_name: 'call', type: 'function () payable returns (bool)' } } // const node2 = { name: 'FunctionCall', children: [], attributes: { member_name: 'call', type: 'function () payable returns (bool)' } }
const node3 = { name: 'FunctionCall', attributes: { member_name: 'call', type: 'function () payable returns (bool)' } } // const node3 = { name: 'FunctionCall', attributes: { member_name: 'call', type: 'function () payable returns (bool)' } }
t.ok(common.helpers.nrOfChildren(node, 2), 'should work for 2 children') // t.ok(common.helpers.nrOfChildren(node, 2), 'should work for 2 children')
t.notOk(common.helpers.nrOfChildren(node, '1+2'), 'regex should not work') // t.notOk(common.helpers.nrOfChildren(node, '1+2'), 'regex should not work')
t.ok(common.helpers.nrOfChildren(node2, 0), 'should work for 0 children') // t.ok(common.helpers.nrOfChildren(node2, 0), 'should work for 0 children')
t.ok(common.helpers.nrOfChildren(node3, 0), 'should work without children arr') // t.ok(common.helpers.nrOfChildren(node3, 0), 'should work without children arr')
lowlevelAccessersCommon(t, common.helpers.nrOfChildren, node) // lowlevelAccessersCommon(t, common.helpers.nrOfChildren, node)
}) // })
test('staticAnalysisCommon.helpers.minNrOfChildren', function (t) {
t.plan(13)
const node = { name: 'Identifier', children: ['a', 'b'], attributes: { value: 'now', type: 'uint256' } }
const node2 = { name: 'FunctionCall', children: [], attributes: { member_name: 'call', type: 'function () payable returns (bool)' } }
const node3 = { name: 'FunctionCall', attributes: { member_name: 'call', type: 'function () payable returns (bool)' } }
t.ok(common.helpers.minNrOfChildren(node, 2), 'should work for 2 children')
t.ok(common.helpers.minNrOfChildren(node, 1), 'should work for 1 children')
t.ok(common.helpers.minNrOfChildren(node, 0), 'should work for 0 children')
t.notOk(common.helpers.minNrOfChildren(node, 3), 'has less than 3 children')
t.notOk(common.helpers.minNrOfChildren(node, '1+2'), 'regex should not work')
t.ok(common.helpers.minNrOfChildren(node2, 0), 'should work for 0 children')
t.ok(common.helpers.minNrOfChildren(node3, 0), 'should work without children arr')
lowlevelAccessersCommon(t, common.helpers.minNrOfChildren, node) // test('staticAnalysisCommon.helpers.minNrOfChildren', function (t) {
}) // t.plan(13)
// const node = { name: 'Identifier', children: ['a', 'b'], attributes: { value: 'now', type: 'uint256' } }
// const node2 = { name: 'FunctionCall', children: [], attributes: { member_name: 'call', type: 'function () payable returns (bool)' } }
// const node3 = { name: 'FunctionCall', attributes: { member_name: 'call', type: 'function () payable returns (bool)' } }
// t.ok(common.helpers.minNrOfChildren(node, 2), 'should work for 2 children')
// t.ok(common.helpers.minNrOfChildren(node, 1), 'should work for 1 children')
// t.ok(common.helpers.minNrOfChildren(node, 0), 'should work for 0 children')
// t.notOk(common.helpers.minNrOfChildren(node, 3), 'has less than 3 children')
// t.notOk(common.helpers.minNrOfChildren(node, '1+2'), 'regex should not work')
// t.ok(common.helpers.minNrOfChildren(node2, 0), 'should work for 0 children')
// t.ok(common.helpers.minNrOfChildren(node3, 0), 'should work without children arr')
// lowlevelAccessersCommon(t, common.helpers.minNrOfChildren, node)
// })
function lowlevelAccessersCommon (t, f, someNode) { function lowlevelAccessersCommon (t, f, someNode) {
t.ok(f(someNode), 'always ok if type is undefinded') t.ok(f(someNode), 'always ok if type is undefinded')
@ -146,14 +146,22 @@ function lowlevelAccessersCommon (t, f, someNode) {
// #################### Trivial Getter Test // #################### Trivial Getter Test
test('staticAnalysisCommon.getType', function (t) { test('staticAnalysisCommon.getType', function (t) {
t.plan(3) t.plan(2)
const node = { name: 'Identifier', children: ['a', 'b'], attributes: { value: 'now', type: 'uint256' } } const node = { "argumentTypes": null,
const node2 = { name: 'FunctionCall', children: [], attributes: { member_name: 'call', type: 'function () payable returns (bool)' } } "id": 3,
const node3 = { name: 'FunctionCall', attributes: { member_name: 'call', type: 'function () payable returns (bool)' } } "name": "a",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 22,
"src": "52:1:0",
"typeDescriptions":
{
"typeIdentifier": "t_uint256",
"typeString": "uint256"
}
}
t.ok(common.getType(blockHashAccess) === 'function (uint256) view returns (bytes32)', 'gettype should work for different nodes')
t.ok(common.getType(node) === 'uint256', 'gettype should work for different nodes') t.ok(common.getType(node) === 'uint256', 'gettype should work for different nodes')
t.ok(common.getType(node2) === 'function () payable returns (bool)', 'gettype should work for different nodes')
t.ok(common.getType(node3) === 'function () payable returns (bool)', 'gettype should work for different nodes')
}) })
// #################### Complex Getter Test // #################### Complex Getter Test
@ -297,110 +305,6 @@ test('staticAnalysisCommon.getFullQuallyfiedFuncDefinitionIdent', function (t) {
t.throws(() => common.getFullQuallyfiedFuncDefinitionIdent({ name: 'FunctionCall' }, fullyQualifiedFunctionDefinition, ['uint256', 'bool']), Error, 'throws on wrong nodes') t.throws(() => common.getFullQuallyfiedFuncDefinitionIdent({ name: 'FunctionCall' }, fullyQualifiedFunctionDefinition, ['uint256', 'bool']), Error, 'throws on wrong nodes')
}) })
test('staticAnalysisCommon.getLoopBlockStartIndex', function (t) {
t.plan(3)
t.equal(common.getLoopBlockStartIndex(forLoopNode), 3) // 'for' loop
t.equal(common.getLoopBlockStartIndex(doWhileLoopNode), 1) // 'do-while' loop
t.equal(common.getLoopBlockStartIndex(whileLoopNode), 1) // 'while' loop
})
// #################### Trivial Node Identification
// test('staticAnalysisCommon.isFunctionDefinition', function (t) {
// t.plan(3)
// const node1 = { name: 'FunctionDefinition' }
// const node2 = { name: 'MemberAccess' }
// const node3 = { name: 'FunctionDefinitionBLABLA' }
// t.ok(common.isFunctionDefinition(node1), 'is exact match should work')
// t.notOk(common.isFunctionDefinition(node2), 'different node should not work')
// t.notOk(common.isFunctionDefinition(node3), 'substring should not work')
// })
// test('staticAnalysisCommon.isModifierDefinition', function (t) {
// t.plan(3)
// const node1 = { name: 'ModifierDefinition' }
// const node2 = { name: 'MemberAccess' }
// const node3 = { name: 'ModifierDefinitionBLABLA' }
// t.ok(common.isModifierDefinition(node1), 'is exact match should work')
// t.notOk(common.isModifierDefinition(node2), 'different node should not work')
// t.notOk(common.isModifierDefinition(node3), 'substring should not work')
// })
// test('staticAnalysisCommon.isModifierInvocation', function (t) {
// t.plan(3)
// const node1 = { name: 'ModifierInvocation' }
// const node2 = { name: 'MemberAccess' }
// const node3 = { name: 'ModifierInvocationBLABLA' }
// t.ok(common.isModifierInvocation(node1), 'is exact match should work')
// t.notOk(common.isModifierInvocation(node2), 'different node should not work')
// t.notOk(common.isModifierInvocation(node3), 'substring should not work')
// })
// test('staticAnalysisCommon.isVariableDeclaration', function (t) {
// t.plan(3)
// const node1 = { name: 'VariableDeclaration' }
// const node2 = { name: 'MemberAccess' }
// const node3 = { name: 'VariableDeclarationBLABLA' }
// t.ok(common.isVariableDeclaration(node1), 'is exact match should work')
// t.notOk(common.isVariableDeclaration(node2), 'different node should not work')
// t.notOk(common.isVariableDeclaration(node3), 'substring should not work')
// })
// test('staticAnalysisCommon.isInheritanceSpecifier', function (t) {
// t.plan(3)
// const node1 = { name: 'InheritanceSpecifier' }
// const node2 = { name: 'MemberAccess' }
// const node3 = { name: 'InheritanceSpecifierBLABLA' }
// t.ok(common.isInheritanceSpecifier(node1), 'is exact match should work')
// t.notOk(common.isInheritanceSpecifier(node2), 'different node should not work')
// t.notOk(common.isInheritanceSpecifier(node3), 'substring should not work')
// })
// test('staticAnalysisCommon.isAssignment', function (t) {
// t.plan(3)
// const node1 = { name: 'Assignment' }
// const node2 = { name: 'MemberAccess' }
// const node3 = { name: 'AssignmentBLABLA' }
// t.ok(common.isAssignment(node1), 'is exact match should work')
// t.notOk(common.isAssignment(node2), 'different node should not work')
// t.notOk(common.isAssignment(node3), 'substring should not work')
// })
// test('staticAnalysisCommon.isContractDefinition', function (t) {
// t.plan(3)
// const node1 = { name: 'ContractDefinition' }
// const node2 = { name: 'MemberAccess' }
// const node3 = { name: 'ContractDefinitionBLABLA' }
// t.ok(common.isContractDefinition(node1), 'is exact match should work')
// t.notOk(common.isContractDefinition(node2), 'different node should not work')
// t.notOk(common.isContractDefinition(node3), 'substring should not work')
// })
// test('staticAnalysisCommon.isInlineAssembly', function (t) {
// t.plan(3)
// const node1 = { name: 'InlineAssembly' }
// const node2 = { name: 'MemberAccess' }
// const node3 = { name: 'InlineAssemblyBLABLA' }
// t.ok(common.isInlineAssembly(node1), 'is exact match should work')
// t.notOk(common.isInlineAssembly(node2), 'different node should not work')
// t.notOk(common.isInlineAssembly(node3), 'substring should not work')
// })
// test('staticAnalysisCommon.isLoop', function (t) {
// t.plan(3)
// t.equal(common.isLoop(forLoopNode), true)
// t.equal(common.isLoop(doWhileLoopNode), true)
// t.equal(common.isLoop(whileLoopNode), true)
// })
// #################### Complex Node Identification // #################### Complex Node Identification
test('staticAnalysisCommon.isBuiltinFunctionCall', function (t) { test('staticAnalysisCommon.isBuiltinFunctionCall', function (t) {

@ -1,4 +1,4 @@
pragma solidity >=0.4.9 <0.6.0; pragma solidity >=0.4.9 <0.7.0;
library Set { library Set {
// We define a new struct datatype that will be used to // We define a new struct datatype that will be used to
@ -50,5 +50,9 @@ contract C {
if (!Set.insert(knownValues, value)) if (!Set.insert(knownValues, value))
revert(); revert();
} }
function tests2() public {
this.register(10);
}
// In this contract, we can also directly access knownValues.flags, if we want. // In this contract, we can also directly access knownValues.flags, if we want.
} }
Loading…
Cancel
Save