integration tests for 0.4.24 contracts updated

pull/5370/head
aniket-engg 5 years ago committed by Aniket
parent dcfcb34efb
commit ce7a5762a0
  1. 16
      remix-analyzer/src/solidity-analyzer/modules/lowLevelCalls.ts
  2. 4
      remix-analyzer/src/solidity-analyzer/modules/noReturn.ts
  3. 75
      remix-analyzer/src/solidity-analyzer/modules/staticAnalysisCommon.ts
  4. 14
      remix-analyzer/test/analysis/staticAnalysisCommon-test.ts
  5. 1758
      remix-analyzer/test/analysis/staticAnalysisIntegration-test-0.4.24.ts
  6. 56
      remix-analyzer/test/analysis/staticAnalysisIssues-test-0.4.24.ts

@ -1,5 +1,5 @@
import { default as category } from './categories'
import { isLLCall, isLLDelegatecall,
import { isLLCall, isLLDelegatecall, isLLCallcode, isLLCall04, isLLDelegatecall04, isLLSend04,
isLLSend, lowLevelCallTypes } from './staticAnalysisCommon'
import { default as algorithm } from './algorithmCategories'
import { AnalyzerModule, ModuleAlgorithm, ModuleCategory, ReportObj, CompilationResult, MemberAccessAstNode} from './../../types'
@ -26,6 +26,14 @@ export default class lowLevelCalls implements AnalyzerModule {
this.llcNodes.push({node: node, type: lowLevelCallTypes.DELEGATECALL})
} else if (isLLSend(node)) {
this.llcNodes.push({node: node, type: lowLevelCallTypes.SEND})
} else if (isLLDelegatecall04(node)) {
this.llcNodes.push({node: node, type: lowLevelCallTypes.DELEGATECALL})
} else if (isLLSend04(node)) {
this.llcNodes.push({node: node, type: lowLevelCallTypes.SEND})
} else if (isLLCall04(node)) {
this.llcNodes.push({node: node, type: lowLevelCallTypes.CALL})
} else if (isLLCallcode(node)) {
this.llcNodes.push({node: node, type: lowLevelCallTypes.CALLCODE})
}
}
@ -41,6 +49,12 @@ export default class lowLevelCalls implements AnalyzerModule {
morehref = 'http://solidity.readthedocs.io/en/develop/control-structures.html?#external-function-calls'
// http://solidity.readthedocs.io/en/develop/frequently-asked-questions.html?#why-is-the-low-level-function-call-less-favorable-than-instantiating-a-contract-with-a-variable-contractb-b-and-executing-its-functions-b-dosomething
break
case lowLevelCallTypes.CALLCODE:
text = `use of "callcode": the use of low level "callcode" should be avoided whenever possible.
External code that is called can change the state of the calling contract and send ether from the caller's balance.
If this is wanted behaviour use the Solidity library feature if possible.`
morehref = 'http://solidity.readthedocs.io/en/develop/contracts.html#libraries'
break
case lowLevelCallTypes.DELEGATECALL:
text = `use of "delegatecall": the use of low level "delegatecall" should be avoided whenever possible.
External code that is called can change the state of the calling contract and send ether from the caller's balance.

@ -26,12 +26,12 @@ export default class noReturn implements AnalyzerModule {
if (this.hasNamedAndUnnamedReturns(func)) {
warnings.push({
warning: `${funcName}: Mixing of named and unnamed return parameters is not advised.`,
location: func['src']
location: func.node['src']
})
} else if (this.shouldReturn(func) && !(this.hasReturnStatement(func) || (this.hasNamedReturns(func) && this.hasAssignToAllNamedReturns(func)))) {
warnings.push({
warning: `${funcName}: Defines a return type but never explicitly returns a value.`,
location: func['src']
location: func.node['src']
})
}
})

@ -81,7 +81,9 @@ const basicRegex = {
const basicFunctionTypes = {
SEND: buildFunctionSignature([basicTypes.UINT], [basicTypes.BOOL], false),
'CALL-0.4': buildFunctionSignature([], [basicTypes.BOOL], true),
CALL: buildFunctionSignature([basicTypes.BYTES_MEM], [basicTypes.BOOL, basicTypes.BYTES_MEM], true),
'DELEGATECALL-0.4': buildFunctionSignature([], [basicTypes.BOOL], false),
DELEGATECALL: buildFunctionSignature([basicTypes.BYTES_MEM], [basicTypes.BOOL, basicTypes.BYTES_MEM], false),
TRANSFER: buildFunctionSignature([basicTypes.UINT], [], false)
}
@ -107,7 +109,10 @@ const builtinFunctions = {
}
const lowLevelCallTypes = {
'CALL-0.4': { ident: 'call', type: basicFunctionTypes['CALL-0.4'] },
CALL: { ident: 'call', type: basicFunctionTypes.CALL },
CALLCODE: { ident: 'callcode', type: basicFunctionTypes['CALL-0.4'] },
'DELEGATECALL-0.4': { ident: 'delegatecall', type: basicFunctionTypes['DELEGATECALL-0.4'] },
DELEGATECALL: { ident: 'delegatecall', type: basicFunctionTypes.DELEGATECALL },
SEND: { ident: 'send', type: basicFunctionTypes.SEND },
TRANSFER: { ident: 'transfer', type: basicFunctionTypes.TRANSFER }
@ -626,8 +631,10 @@ function isStorageVariableDeclaration (node: VariableDeclarationAstNode): boolea
function isInteraction (node: FunctionCallAstNode): boolean {
// console.log('Inside isInteraction----------', node)
return isLLCall(node.expression) || isLLSend(node.expression) || isExternalDirectCall(node) || isTransfer(node.expression) ||
// to cover case of address.call.value.gas , See: inheritance.sol
(node.expression && node.expression.expression && isLLCall(node.expression.expression))
isLLCall04(node.expression) || isLLSend04(node.expression) ||
// to cover case of address.call.value.gas , See: inheritance.sol
(node.expression && node.expression.expression && isLLCall(node.expression.expression)) ||
(node.expression && node.expression.expression && isLLCall04(node.expression.expression))
}
/**
@ -685,7 +692,7 @@ function isPayableFunction (node: FunctionDefinitionAstNode): boolean {
* @return {bool}
*/
function isConstructor (node: FunctionDefinitionAstNode): boolean {
return node.kind === "constructor"
return node.kind === "constructor" // ||
}
/**
@ -879,22 +886,26 @@ function isLocalCall (node: FunctionCallAstNode): boolean {
function isLowLevelCall (node: MemberAccessAstNode): boolean {
return isLLCall(node) ||
isLLDelegatecall(node) ||
isLLSend(node)
isLLSend(node) ||
isLLSend04(node) ||
isLLCallcode(node) ||
isLLCall04(node) ||
isLLDelegatecall04(node)
}
/**
* True if low level send (solidity >= 0.5)
* True if low level send (solidity < 0.5)
* @node {ASTNode} some AstNode
* @return {bool}
*/
// function isLLSend050 (node: MemberAccessAstNode): boolean {
// return isMemberAccess(node,
// exactMatch(util.escapeRegExp(lowLevelCallTypes.SEND.type)),
// undefined, exactMatch(basicTypes.PAYABLE_ADDRESS), exactMatch(lowLevelCallTypes.SEND.ident))
// }
function isLLSend04 (node: MemberAccessAstNode): boolean {
return isMemberAccess(node,
exactMatch(util.escapeRegExp(lowLevelCallTypes.SEND.type)),
undefined, exactMatch(basicTypes.ADDRESS), exactMatch(lowLevelCallTypes.SEND.ident))
}
/**
* True if low level send (solidity < 0.5)
* True if low level send (solidity >= 0.5)
* @node {ASTNode} some AstNode
* @return {bool}
*/
@ -910,9 +921,6 @@ function isLLSend (node: MemberAccessAstNode): boolean {
* @return {bool}
*/
function isLLCall (node: MemberAccessAstNode): boolean {
// if(node && node.nodeType === 'MemberAccess' && node.memberName !== 'call' &&
// node.expression && node.expression.nodeType && nodeType(node.expression, exactMatch(nodeTypes.MEMBERACCESS)))
// node = node.expression;
return isMemberAccess(node,
exactMatch(util.escapeRegExp(lowLevelCallTypes.CALL.type)),
undefined, exactMatch(basicTypes.ADDRESS), exactMatch(lowLevelCallTypes.CALL.ident)) ||
@ -922,26 +930,26 @@ function isLLCall (node: MemberAccessAstNode): boolean {
}
/**
* True if low level payable call (solidity >= 0.5)
* True if low level payable call (solidity < 0.5)
* @node {ASTNode} some AstNode
* @return {bool}
*/
// function isLLCall050 (node: MemberAccessAstNode): boolean {
// return isMemberAccess(node,
// exactMatch(util.escapeRegExp(lowLevelCallTypes['CALL-v0.5'].type)),
// undefined, exactMatch(basicTypes.PAYABLE_ADDRESS), exactMatch(lowLevelCallTypes['CALL-v0.5'].ident))
// }
function isLLCall04 (node: MemberAccessAstNode): boolean {
return isMemberAccess(node,
exactMatch(util.escapeRegExp(lowLevelCallTypes['CALL-0.4'].type)),
undefined, exactMatch(basicTypes.ADDRESS), exactMatch(lowLevelCallTypes['CALL-0.4'].ident))
}
/**
* True if low level callcode
* @node {ASTNode} some AstNode
* @return {bool}
*/
// function isLLCallcode (node: MemberAccessAstNode): boolean {
// return isMemberAccess(node,
// exactMatch(util.escapeRegExp(lowLevelCallTypes.CALLCODE.type)),
// undefined, exactMatch(basicTypes.ADDRESS), exactMatch(lowLevelCallTypes.CALLCODE.ident))
// }
function isLLCallcode (node: MemberAccessAstNode): boolean {
return isMemberAccess(node,
exactMatch(util.escapeRegExp(lowLevelCallTypes.CALLCODE.type)),
undefined, exactMatch(basicTypes.ADDRESS), exactMatch(lowLevelCallTypes.CALLCODE.ident))
}
/**
* True if low level delegatecall
@ -955,15 +963,15 @@ function isLLDelegatecall (node: MemberAccessAstNode): boolean {
}
/**
* True if low level delegatecall (solidity >= 0.5)
* True if low level delegatecall (solidity < 0.5)
* @node {ASTNode} some AstNode
* @return {bool}
*/
// function isLLDelegatecall050 (node: MemberAccessAstNode): boolean {
// return isMemberAccess(node,
// exactMatch(util.escapeRegExp(lowLevelCallTypes.DELEGATECALL.type)),
// undefined, matches(basicTypes.PAYABLE_ADDRESS, basicTypes.ADDRESS), exactMatch(lowLevelCallTypes.DELEGATECALL.ident))
// }
function isLLDelegatecall04 (node: MemberAccessAstNode): boolean {
return isMemberAccess(node,
exactMatch(util.escapeRegExp(lowLevelCallTypes['DELEGATECALL-0.4'].type)),
undefined, matches(basicTypes.PAYABLE_ADDRESS, basicTypes.ADDRESS), exactMatch(lowLevelCallTypes['DELEGATECALL-0.4'].ident))
}
/**
* True if transfer call
@ -1186,9 +1194,12 @@ export {
isTransfer,
isLowLevelCall,
isLLCall,
// isLLCallcode as isLowLevelCallcodeInst,
isLLCall04,
isLLCallcode,
isLLDelegatecall,
isLLDelegatecall04,
isLLSend,
isLLSend04,
isExternalDirectCall,
isFullyImplementedContract,
isLibrary,

@ -10,7 +10,7 @@ function escapeRegExp (str) {
}
test('staticAnalysisCommon.helpers.buildFunctionSignature', function (t) {
t.plan(8)
t.plan(11)
t.equal(common.helpers.buildFunctionSignature([common.basicTypes.UINT, common.basicTypes.ADDRESS], [common.basicTypes.BOOL], false),
'function (uint256,address) returns (bool)',
@ -36,6 +36,14 @@ test('staticAnalysisCommon.helpers.buildFunctionSignature', function (t) {
'function (bytes memory) payable returns (bool,bytes memory)',
'check fixed call type')
t.equal(common.lowLevelCallTypes['CALL-0.4'].type,
'function () payable returns (bool)',
'check fixed call type for version before 0.5.0')
t.equal(common.lowLevelCallTypes.CALLCODE.type,
'function () payable returns (bool)',
'check fixed callcode type')
t.equal(common.lowLevelCallTypes.SEND.type,
'function (uint256) returns (bool)',
'check fixed send type')
@ -43,6 +51,10 @@ test('staticAnalysisCommon.helpers.buildFunctionSignature', function (t) {
t.equal(common.lowLevelCallTypes.DELEGATECALL.type,
'function (bytes memory) returns (bool,bytes memory)',
'check fixed call type')
t.equal(common.lowLevelCallTypes['DELEGATECALL-0.4'].type,
'function () returns (bool)',
'check fixed call type')
})
// #################### Node Identification Primitives

@ -1,32 +1,32 @@
// import { default as test} from "tape"
// import { helpers } from 'remix-lib'
// import { readFileSync } from 'fs'
// import { join } from 'path'
// import { default as StatRunner } from '../../dist/src/solidity-analyzer'
// import { install, require as requireNPMmodule } from 'npm-install-version'
// install('solc@0.4.24')
// const compiler = requireNPMmodule('solc@0.4.24')
// const {compilerInput } = helpers.compiler
// const folder = 'solidity-v0.4.24'
import { default as test} from "tape"
import { helpers } from 'remix-lib'
import { readFileSync } from 'fs'
import { join } from 'path'
import { default as StatRunner } from '../../dist/src/solidity-analyzer'
import { install, require as requireNPMmodule } from 'npm-install-version'
install('solc@0.4.24')
const compiler = requireNPMmodule('solc@0.4.24')
const { compilerInput } = helpers.compiler
const folder = 'solidity-v0.4.24'
// function compile (fileName) {
// const content = readFileSync(join(__dirname, 'test-contracts/' + folder, fileName), 'utf8')
// return JSON.parse(compiler.compileStandardWrapper(compilerInput(content)))
// }
function compile (fileName) {
const content = readFileSync(join(__dirname, 'test-contracts/' + folder, fileName), 'utf8')
return JSON.parse(compiler.compileStandardWrapper(compilerInput(content)))
}
// test('staticAnalysisIssues.functionParameterPassingError', function (t) {
// // https://github.com/ethereum/remix-ide/issues/889#issuecomment-351746474
// t.plan(2)
// const res = compile('functionParameters.sol')
// const Module = require('../../dist/src/solidity-analyzer/modules/checksEffectsInteraction').default
// const statRunner = new StatRunner()
test('staticAnalysisIssues.functionParameterPassingError', function (t) {
// https://github.com/ethereum/remix-ide/issues/889#issuecomment-351746474
t.plan(2)
const res = compile('functionParameters.sol')
const Module = require('../../dist/src/solidity-analyzer/modules/checksEffectsInteraction').default
const statRunner = new StatRunner()
// t.doesNotThrow(() => {
// statRunner.runWithModuleList(res, [{ name: new Module().name, mod: new Module() }], (reports) => {
// })
// }, 'Analysis should not throw')
t.doesNotThrow(() => {
statRunner.runWithModuleList(res, [{ name: new Module().name, mod: new Module() }], (reports) => {
})
}, 'Analysis should not throw')
// statRunner.runWithModuleList(res, [{ name: new Module().name, mod: new Module() }], (reports) => {
// t.ok(!reports.some((mod) => mod.report.some((rep) => rep.warning.includes('INTERNAL ERROR')), 'Should not have internal errors'))
// })
// })
statRunner.runWithModuleList(res, [{ name: new Module().name, mod: new Module() }], (reports) => {
t.ok(!reports.some((mod) => mod.report.some((rep) => rep.warning.includes('INTERNAL ERROR')), 'Should not have internal errors'))
})
})

Loading…
Cancel
Save