Static Analysis: new as const breaker

pull/1/head
Michael Fröwis 8 years ago committed by chriseth
parent d0e2d12360
commit 85ae6115e5
  1. 6
      src/app/staticanalysis/modules/constantFunctions.js
  2. 26
      src/app/staticanalysis/modules/staticAnalysisCommon.js

@ -10,7 +10,7 @@ function constantFunctions () {
var that = this var that = this
constantFunctions.prototype.visit = new AbstractAst().builder( constantFunctions.prototype.visit = new AbstractAst().builder(
(node) => common.isLowLevelCall(node) || common.isExternalDirectCall(node) || common.isEffect(node) || common.isLocalCallGraphRelevantNode(node) || common.isInlineAssembly(node), (node) => common.isLowLevelCall(node) || common.isTransfer(node) || common.isExternalDirectCall(node) || common.isEffect(node) || common.isLocalCallGraphRelevantNode(node) || common.isInlineAssembly(node) || common.isNewExpression(node),
that.contracts that.contracts
) )
} }
@ -66,9 +66,11 @@ function checkIfShouldBeConstant (startFuncName, context) {
function isConstBreaker (node, context) { function isConstBreaker (node, context) {
return common.isWriteOnStateVariable(node, context.stateVariables) || return common.isWriteOnStateVariable(node, context.stateVariables) ||
common.isLowLevelCall(node) || common.isLowLevelCall(node) ||
common.isTransfer(node) ||
isCallOnNonConstExternalInterfaceFunction(node, context) || isCallOnNonConstExternalInterfaceFunction(node, context) ||
common.isCallToNonConstLocalFunction(node) || common.isCallToNonConstLocalFunction(node) ||
common.isInlineAssembly(node) common.isInlineAssembly(node) ||
common.isNewExpression(node)
} }
function isCallOnNonConstExternalInterfaceFunction (node, context) { function isCallOnNonConstExternalInterfaceFunction (node, context) {

@ -17,7 +17,8 @@ var nodeTypes = {
INHERITANCESPECIFIER: 'InheritanceSpecifier', INHERITANCESPECIFIER: 'InheritanceSpecifier',
USERDEFINEDTYPENAME: 'UserDefinedTypeName', USERDEFINEDTYPENAME: 'UserDefinedTypeName',
INLINEASSEMBLY: 'InlineAssembly', INLINEASSEMBLY: 'InlineAssembly',
BLOCK: 'Block' BLOCK: 'Block',
NEWEXPRESSION: 'NewExpression'
} }
var basicTypes = { var basicTypes = {
@ -40,7 +41,8 @@ var basicRegex = {
var basicFunctionTypes = { var basicFunctionTypes = {
SEND: buildFunctionSignature([basicTypes.UINT], [basicTypes.BOOL], false), SEND: buildFunctionSignature([basicTypes.UINT], [basicTypes.BOOL], false),
CALL: buildFunctionSignature([], [basicTypes.BOOL], true), CALL: buildFunctionSignature([], [basicTypes.BOOL], true),
DELEGATECALL: buildFunctionSignature([], [basicTypes.BOOL], false) DELEGATECALL: buildFunctionSignature([], [basicTypes.BOOL], false),
TRANSFER: buildFunctionSignature([basicTypes.UINT], [], false)
} }
var builtinFunctions = { var builtinFunctions = {
@ -60,7 +62,8 @@ var lowLevelCallTypes = {
CALL: { ident: 'call', type: basicFunctionTypes.CALL }, CALL: { ident: 'call', type: basicFunctionTypes.CALL },
CALLCODE: { ident: 'callcode', type: basicFunctionTypes.CALL }, CALLCODE: { ident: 'callcode', type: basicFunctionTypes.CALL },
DELEGATECALL: { ident: 'delegatecall', type: basicFunctionTypes.DELEGATECALL }, DELEGATECALL: { ident: 'delegatecall', type: basicFunctionTypes.DELEGATECALL },
SEND: { ident: 'send', type: basicFunctionTypes.SEND } SEND: { ident: 'send', type: basicFunctionTypes.SEND },
TRANSFER: { ident: 'transfer', type: basicFunctionTypes.TRANSFER }
} }
var specialVariables = { var specialVariables = {
@ -351,6 +354,10 @@ function isInlineAssembly (node) {
return nodeType(node, exactMatch(nodeTypes.INLINEASSEMBLY)) return nodeType(node, exactMatch(nodeTypes.INLINEASSEMBLY))
} }
function isNewExpression (node) {
return nodeType(node, exactMatch(nodeTypes.NEWEXPRESSION))
}
// #################### Complex Node Identification // #################### Complex Node Identification
/** /**
@ -616,6 +623,17 @@ function isLLDelegatecall (node) {
undefined, exactMatch(basicTypes.ADDRESS), exactMatch(lowLevelCallTypes.DELEGATECALL.ident)) undefined, exactMatch(basicTypes.ADDRESS), exactMatch(lowLevelCallTypes.DELEGATECALL.ident))
} }
/**
* True if transfer call
* @node {ASTNode} some AstNode
* @return {bool}
*/
function isTransfer (node) {
return isMemberAccess(node,
exactMatch(utils.escapeRegExp(lowLevelCallTypes.TRANSFER.type)),
undefined, exactMatch(basicTypes.ADDRESS), exactMatch(lowLevelCallTypes.TRANSFER.ident))
}
// #################### Complex Node Identification - Private // #################### Complex Node Identification - Private
function isMemberAccess (node, retType, accessor, accessorType, memberName) { function isMemberAccess (node, retType, accessor, accessorType, memberName) {
@ -733,6 +751,7 @@ module.exports = {
isLocalCall: isLocalCall, isLocalCall: isLocalCall,
isWriteOnStateVariable: isWriteOnStateVariable, isWriteOnStateVariable: isWriteOnStateVariable,
isStateVariable: isStateVariable, isStateVariable: isStateVariable,
isTransfer: isTransfer,
isLowLevelCall: isLowLevelCall, isLowLevelCall: isLowLevelCall,
isLowLevelCallInst: isLLCall, isLowLevelCallInst: isLLCall,
isLowLevelCallcodeInst: isLLCallcode, isLowLevelCallcodeInst: isLLCallcode,
@ -757,6 +776,7 @@ module.exports = {
isContractDefinition: isContractDefinition, isContractDefinition: isContractDefinition,
isConstantFunction: isConstantFunction, isConstantFunction: isConstantFunction,
isInlineAssembly: isInlineAssembly, isInlineAssembly: isInlineAssembly,
isNewExpression: isNewExpression,
// #################### Constants // #################### Constants
nodeTypes: nodeTypes, nodeTypes: nodeTypes,

Loading…
Cancel
Save