ballot.sol integration tests

pull/7/head
aniket-engg 5 years ago committed by Aniket
parent 8ccef1c5a9
commit d08f8a3706
  1. 4
      remix-analyzer/src/solidity-analyzer/modules/abstractAstView.ts
  2. 1
      remix-analyzer/src/solidity-analyzer/modules/constantFunctions.ts
  3. 6
      remix-analyzer/src/solidity-analyzer/modules/functionCallGraph.ts
  4. 5
      remix-analyzer/src/solidity-analyzer/modules/similarVariableNames.ts
  5. 35
      remix-analyzer/src/solidity-analyzer/modules/staticAnalysisCommon.ts
  6. 4
      remix-analyzer/src/types.ts
  7. 82
      remix-analyzer/test/analysis/staticAnalysisIntegration-test-0.5.0.ts

@ -174,10 +174,10 @@ export default class abstractAstView {
private getLocalVariables (funcNode: ParameterListAstNode): VariableDeclarationAstNode[] {
const locals: VariableDeclarationAstNode[] = []
new AstWalker().walk(funcNode, {'*': function (node) {
new AstWalker().walkFull(funcNode, (node) => {
if (node.nodeType === "VariableDeclaration") locals.push(node)
return true
}})
})
return locals
}
}

@ -55,7 +55,6 @@ export default class constantFunctions implements AnalyzerModule {
)
}
})
contract.functions.filter((func) => hasFunctionBody(func.node)).forEach((func) => {
if (isConstantFunction(func.node) !== func['potentiallyshouldBeConst']) {
const funcName: string = getFullQuallyfiedFuncDefinitionIdent(contract.node, func.node, func.parameters)

@ -1,6 +1,6 @@
'use strict'
import { FunctionHLAst, ContractHLAst, FunctionCallGraph, ContractCallGraph } from "types"
import { FunctionHLAst, ContractHLAst, FunctionCallGraph, ContractCallGraph, Context } from "types"
import { isLocalCallGraphRelevantNode, isExternalDirectCall, getFullQualifiedFunctionCallIdent, getFullQuallyfiedFuncDefinitionIdent, getContractName } from './staticAnalysisCommon'
function buildLocalFuncCallGraphInternal (functions: FunctionHLAst[], nodeFilter: any , extractNodeIdent: any, extractFuncDefIdent: Function): Record<string, FunctionCallGraph> {
@ -61,11 +61,11 @@ export function buildGlobalFuncCallGraph (contracts: ContractHLAst[]): Record<st
* @nodeCheck {(ASTNode, context) -> bool} applied on every relevant node in the call graph
* @return {bool} returns map from contract name to contract call graph
*/
export function analyseCallGraph (callGraph: Record<string, ContractCallGraph>, funcName: string, context: object, nodeCheck): boolean {
export function analyseCallGraph (callGraph: Record<string, ContractCallGraph>, funcName: string, context: Context, nodeCheck: ((node: any, context: Context) => boolean)): boolean {
return analyseCallGraphInternal(callGraph, funcName, context, (a, b) => a || b, nodeCheck, {})
}
function analyseCallGraphInternal (callGraph: Record<string, ContractCallGraph>, funcName: string, context: object, combinator: Function, nodeCheck, visited : object): boolean {
function analyseCallGraphInternal (callGraph: Record<string, ContractCallGraph>, funcName: string, context: Context, combinator: Function, nodeCheck, visited : object): boolean {
const current: FunctionCallGraph | undefined = resolveCallGraphSymbol(callGraph, funcName)
if (current === undefined || visited[funcName] === true) return true

@ -52,7 +52,10 @@ export default class similarVariableNames implements AnalyzerModule {
const similar: Record<string, any>[] = []
const comb: Record<string, boolean> = {}
vars.map((varName1) => vars.map((varName2) => {
if (varName1.length > 1 && varName2.length > 1 && varName2 !== varName1 && !this.isCommonPrefixedVersion(varName1, varName2) && !this.isCommonNrSuffixVersion(varName1, varName2) && !(comb[varName1 + ';' + varName2] || comb[varName2 + ';' + varName1])) {
if (varName1.length > 1 && varName2.length > 1 &&
varName2 !== varName1 && !this.isCommonPrefixedVersion(varName1, varName2) &&
!this.isCommonNrSuffixVersion(varName1, varName2) &&
!(comb[varName1 + ';' + varName2] || comb[varName2 + ';' + varName1])) {
comb[varName1 + ';' + varName2] = true
const distance: number = get(varName1, varName2)
if (distance <= 2) similar.push({ var1: varName1, var2: varName2, distance: distance })

@ -168,10 +168,31 @@ function getFunctionCallType (func: FunctionCallAstNode): string {
* @effectNode {ASTNode} Assignmnet node
* @return {string} variable name written to
*/
function getEffectedVariableName (effectNode: AssignmentAstNode | UnaryOperationAstNode): string {
function getEffectedVariableName (effectNode: AssignmentAstNode | UnaryOperationAstNode) {
if (!isEffect(effectNode)) throw new Error('staticAnalysisCommon.js: not an effect Node')
if(effectNode.nodeType === 'Assignment') return effectNode.leftHandSide.name
else /* if(effectNode.nodeType === 'UnaryOperation') */ return effectNode.subExpression.name
if(effectNode.nodeType === 'Assignment' || effectNode.nodeType === 'UnaryOperation') {
const IdentNode = findFirstSubNodeLTR(effectNode, exactMatch(nodeTypes.IDENTIFIER))
return IdentNode.name
}
}
// developed keeping identifier node search in mind
function findFirstSubNodeLTR (node, type) {
if(node.nodeType && nodeType(node, type))
return node
else if(node.nodeType && nodeType(node, exactMatch('Assignment')))
return findFirstSubNodeLTR(node.leftHandSide, type)
else if(node.nodeType && nodeType(node, exactMatch('MemberAccess')))
return findFirstSubNodeLTR(node.expression, type)
else if(node.nodeType && nodeType(node, exactMatch('IndexAccess')))
return findFirstSubNodeLTR(node.baseExpression, type)
else if(node.nodeType && nodeType(node, exactMatch('UnaryOperation')))
return findFirstSubNodeLTR(node.subExpression, type)
}
/**
@ -417,7 +438,7 @@ function getFullQualifiedFunctionCallIdent (contract: ContractDefinitionAstNode,
else if (isSuperLocalCall(func.expression)) return getContractName(contract) + '.' + getSuperLocalCallName(func) + '(' + getFunctionCallTypeParameterType(func) + ')'
else if (isExternalDirectCall(func.expression)) return getExternalDirectCallContractName(func) + '.' + getExternalDirectCallMemberName(func) + '(' + getFunctionCallTypeParameterType(func) + ')'
else if (isLibraryCall(func.expression)) return getLibraryCallContractName(func.expression) + '.' + getLibraryCallMemberName(func) + '(' + getFunctionCallTypeParameterType(func) + ')'
else throw new Error('staticAnalysisCommon.js: Can not get function name form non function call node')
else throw new Error('staticAnalysisCommon.js: Can not get function name from non function call node')
}
function getFullQuallyfiedFuncDefinitionIdent (contract: ContractDefinitionAstNode, func: FunctionDefinitionAstNode, paramTypes: any[]): string {
@ -622,7 +643,7 @@ function isEffect (node: AssignmentAstNode | UnaryOperationAstNode | InlineAssem
* @node {list Variable declaration} state variable declaration currently in scope
* @return {bool}
*/
function isWriteOnStateVariable (effectNode: AssignmentAstNode | InlineAssemblyAstNode | UnaryOperationAstNode, stateVariables: any[]) {
function isWriteOnStateVariable (effectNode: AssignmentAstNode | InlineAssemblyAstNode | UnaryOperationAstNode, stateVariables: VariableDeclarationAstNode[]) {
return effectNode.nodeType === "InlineAssembly" || (isEffect(effectNode) && isStateVariable(getEffectedVariableName(effectNode), stateVariables))
}
@ -632,8 +653,8 @@ function isWriteOnStateVariable (effectNode: AssignmentAstNode | InlineAssemblyA
* @node {list Variable declaration} state variable declaration currently in scope
* @return {bool}
*/
function isStateVariable (name: string, stateVariables: any[]): boolean {
return stateVariables.some((item) => name === getDeclaredVariableName(item))
function isStateVariable (name: string, stateVariables: VariableDeclarationAstNode[]): boolean {
return stateVariables.some((item: VariableDeclarationAstNode) => item.stateVariable && name === getDeclaredVariableName(item))
}
/**

@ -129,7 +129,7 @@ export interface ContractDefinitionAstNode {
nodeType: 'ContractDefinition'
src: string
name: string
documentation: object | null
documentation: string | null
contractKind: 'interface' | 'contract' | 'library'
abstract: boolean
fullyImplemented: boolean
@ -202,7 +202,7 @@ export interface FunctionDefinitionAstNode {
nodeType: 'FunctionDefinition'
src: string
name: string
documentation: object | null
documentation: string | null
kind: string
stateMutability: 'pure' | 'view' | 'nonpayable' | 'payable'
visibility: string

@ -12,7 +12,7 @@ const folder = 'solidity-v0.5'
const testFiles = [
'KingOfTheEtherThrone.sol',
'assembly.sol',
// 'ballot.sol',
'ballot.sol',
// 'ballot_reentrant.sol',
// 'ballot_withoutWarnings.sol',
// 'cross_contract.sol',
@ -50,14 +50,14 @@ testFiles.forEach((fileName) => {
test('Integration test thisLocal.js', function (t) {
// console.log('testFileAsts---------',testFileAsts)
// t.plan(testFiles.length)
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/thisLocal').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 0,
'assembly.sol': 0,
// 'ballot.sol': 0,
'ballot.sol': 0,
// 'ballot_reentrant.sol': 1,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 0,
@ -89,14 +89,14 @@ test('Integration test thisLocal.js', function (t) {
})
test('Integration test checksEffectsInteraction.js', function (t) {
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/checksEffectsInteraction').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 1,
'assembly.sol': 1,
// 'ballot.sol': 0,
'ballot.sol': 0,
// 'ballot_reentrant.sol': 1,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 0,
@ -128,14 +128,14 @@ test('Integration test checksEffectsInteraction.js', function (t) {
})
test('Integration test constantFunctions.js', function (t) {
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/constantFunctions').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 0,
'assembly.sol': 0,
// 'ballot.sol': 0,
'ballot.sol': 0,
// 'ballot_reentrant.sol': 0,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 0,
@ -167,14 +167,14 @@ test('Integration test constantFunctions.js', function (t) {
})
test('Integration test inlineAssembly.js', function (t) {
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/inlineAssembly').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 0,
'assembly.sol': 2,
// 'ballot.sol': 0,
'ballot.sol': 0,
// 'ballot_reentrant.sol': 0,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 0,
@ -206,14 +206,14 @@ test('Integration test inlineAssembly.js', function (t) {
})
test('Integration test txOrigin.js', function (t) {
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/txOrigin').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 0,
'assembly.sol': 1,
// 'ballot.sol': 0,
'ballot.sol': 0,
// 'ballot_reentrant.sol': 0,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 0,
@ -245,14 +245,14 @@ test('Integration test txOrigin.js', function (t) {
})
test('Integration test gasCosts.js', function (t) {
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/gasCosts').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 2,
'assembly.sol': 2,
// 'ballot.sol': 3,
'ballot.sol': 3,
// 'ballot_reentrant.sol': 2,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 1,
@ -284,14 +284,14 @@ test('Integration test gasCosts.js', function (t) {
})
test('Integration test similarVariableNames.js', function (t) {
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/similarVariableNames').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 0,
'assembly.sol': 0,
// 'ballot.sol': 2,
'ballot.sol': 2,
// 'ballot_reentrant.sol': 11,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 0,
@ -323,14 +323,14 @@ test('Integration test similarVariableNames.js', function (t) {
})
test('Integration test blockTimestamp.js', function (t) {
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/blockTimestamp').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 1,
'assembly.sol': 0,
// 'ballot.sol': 0,
'ballot.sol': 0,
// 'ballot_reentrant.sol': 3,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 0,
@ -362,14 +362,14 @@ test('Integration test blockTimestamp.js', function (t) {
})
test('Integration test lowLevelCalls.js', function (t) {
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/lowLevelCalls').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 1,
'assembly.sol': 1,
// 'ballot.sol': 0,
'ballot.sol': 0,
// 'ballot_reentrant.sol': 7,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 1,
@ -401,14 +401,14 @@ test('Integration test lowLevelCalls.js', function (t) {
})
test('Integration test blockBlockhash.js', function (t) {
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/blockBlockhash').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 0,
'assembly.sol': 0,
// 'ballot.sol': 0,
'ballot.sol': 0,
// 'ballot_reentrant.sol': 0,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 0,
@ -483,14 +483,14 @@ test('Integration test blockBlockhash.js', function (t) {
// */
test('Integration test selfdestruct.js', function (t) {
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/selfdestruct').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 0,
'assembly.sol': 0,
// 'ballot.sol': 0,
'ballot.sol': 0,
// 'ballot_reentrant.sol': 0,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 0,
@ -522,14 +522,14 @@ test('Integration test selfdestruct.js', function (t) {
})
test('Integration test guardConditions.js', function (t) {
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/guardConditions').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 0,
'assembly.sol': 1,
// 'ballot.sol': 0,
'ballot.sol': 0,
// 'ballot_reentrant.sol': 0,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 0,
@ -561,14 +561,14 @@ test('Integration test guardConditions.js', function (t) {
})
test('Integration test deleteDynamicArrays.js', function (t) {
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/deleteDynamicArrays').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 0,
'assembly.sol': 0,
// 'ballot.sol': 0,
'ballot.sol': 0,
// 'ballot_reentrant.sol': 0,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 0,
@ -600,14 +600,14 @@ test('Integration test deleteDynamicArrays.js', function (t) {
})
test('Integration test deleteFromDynamicArray.js', function (t) {
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/deleteFromDynamicArray').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 0,
'assembly.sol': 0,
// 'ballot.sol': 0,
'ballot.sol': 0,
// 'ballot_reentrant.sol': 0,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 0,
@ -639,14 +639,14 @@ test('Integration test deleteFromDynamicArray.js', function (t) {
})
test('Integration test assignAndCompare.js', function (t) {
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/assignAndCompare').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 0,
'assembly.sol': 0,
// 'ballot.sol': 0,
'ballot.sol': 0,
// 'ballot_reentrant.sol': 0,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 0,
@ -678,14 +678,14 @@ test('Integration test assignAndCompare.js', function (t) {
})
test('Integration test intDivisionTruncate.js', function (t) {
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/intDivisionTruncate').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 0,
'assembly.sol': 0,
// 'ballot.sol': 0,
'ballot.sol': 0,
// 'ballot_reentrant.sol': 0,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 0,
@ -717,14 +717,14 @@ test('Integration test intDivisionTruncate.js', function (t) {
})
test('Integration test erc20Decimal.js', function (t) {
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/erc20Decimals').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 0,
'assembly.sol': 0,
// 'ballot.sol': 0,
'ballot.sol': 0,
// 'ballot_reentrant.sol': 0,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 0,
@ -756,14 +756,14 @@ test('Integration test erc20Decimal.js', function (t) {
})
test('Integration test stringBytesLength.js', function (t) {
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/stringBytesLength').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 0,
'assembly.sol': 0,
// 'ballot.sol': 0,
'ballot.sol': 0,
// 'ballot_reentrant.sol': 0,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 0,
@ -795,14 +795,14 @@ test('Integration test stringBytesLength.js', function (t) {
})
test('Integration test etherTransferInLoop.js', function (t) {
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/etherTransferInLoop').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 0,
'assembly.sol': 0,
// 'ballot.sol': 0,
'ballot.sol': 0,
// 'ballot_reentrant.sol': 0,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 0,
@ -834,14 +834,14 @@ test('Integration test etherTransferInLoop.js', function (t) {
})
test('Integration test forLoopIteratesOverDynamicArray.js', function (t) {
t.plan(2)
t.plan(3)
var module = require('../../dist/src/solidity-analyzer/modules/forLoopIteratesOverDynamicArray').default
var lengthCheck = {
'KingOfTheEtherThrone.sol': 0,
'assembly.sol': 0,
// 'ballot.sol': 2,
'ballot.sol': 2,
// 'ballot_reentrant.sol': 1,
// 'ballot_withoutWarnings.sol': 0,
// 'cross_contract.sol': 0,

Loading…
Cancel
Save