From 85ae6115e5e9b00e845fcc0272aa81c9d9f3ade5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Fr=C3=B6wis?= Date: Wed, 17 May 2017 10:46:24 +0200 Subject: [PATCH] Static Analysis: new as const breaker --- .../modules/constantFunctions.js | 6 +++-- .../modules/staticAnalysisCommon.js | 26 ++++++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/app/staticanalysis/modules/constantFunctions.js b/src/app/staticanalysis/modules/constantFunctions.js index f5e887a0e3..ac76a90cd9 100644 --- a/src/app/staticanalysis/modules/constantFunctions.js +++ b/src/app/staticanalysis/modules/constantFunctions.js @@ -10,7 +10,7 @@ function constantFunctions () { var that = this 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 ) } @@ -66,9 +66,11 @@ function checkIfShouldBeConstant (startFuncName, context) { function isConstBreaker (node, context) { return common.isWriteOnStateVariable(node, context.stateVariables) || common.isLowLevelCall(node) || + common.isTransfer(node) || isCallOnNonConstExternalInterfaceFunction(node, context) || common.isCallToNonConstLocalFunction(node) || - common.isInlineAssembly(node) + common.isInlineAssembly(node) || + common.isNewExpression(node) } function isCallOnNonConstExternalInterfaceFunction (node, context) { diff --git a/src/app/staticanalysis/modules/staticAnalysisCommon.js b/src/app/staticanalysis/modules/staticAnalysisCommon.js index 73d799c1b8..36c3014599 100644 --- a/src/app/staticanalysis/modules/staticAnalysisCommon.js +++ b/src/app/staticanalysis/modules/staticAnalysisCommon.js @@ -17,7 +17,8 @@ var nodeTypes = { INHERITANCESPECIFIER: 'InheritanceSpecifier', USERDEFINEDTYPENAME: 'UserDefinedTypeName', INLINEASSEMBLY: 'InlineAssembly', - BLOCK: 'Block' + BLOCK: 'Block', + NEWEXPRESSION: 'NewExpression' } var basicTypes = { @@ -40,7 +41,8 @@ var basicRegex = { var basicFunctionTypes = { SEND: buildFunctionSignature([basicTypes.UINT], [basicTypes.BOOL], false), CALL: buildFunctionSignature([], [basicTypes.BOOL], true), - DELEGATECALL: buildFunctionSignature([], [basicTypes.BOOL], false) + DELEGATECALL: buildFunctionSignature([], [basicTypes.BOOL], false), + TRANSFER: buildFunctionSignature([basicTypes.UINT], [], false) } var builtinFunctions = { @@ -60,7 +62,8 @@ var lowLevelCallTypes = { CALL: { ident: 'call', type: basicFunctionTypes.CALL }, CALLCODE: { ident: 'callcode', type: basicFunctionTypes.CALL }, 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 = { @@ -351,6 +354,10 @@ function isInlineAssembly (node) { return nodeType(node, exactMatch(nodeTypes.INLINEASSEMBLY)) } +function isNewExpression (node) { + return nodeType(node, exactMatch(nodeTypes.NEWEXPRESSION)) +} + // #################### Complex Node Identification /** @@ -616,6 +623,17 @@ function isLLDelegatecall (node) { 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 function isMemberAccess (node, retType, accessor, accessorType, memberName) { @@ -733,6 +751,7 @@ module.exports = { isLocalCall: isLocalCall, isWriteOnStateVariable: isWriteOnStateVariable, isStateVariable: isStateVariable, + isTransfer: isTransfer, isLowLevelCall: isLowLevelCall, isLowLevelCallInst: isLLCall, isLowLevelCallcodeInst: isLLCallcode, @@ -757,6 +776,7 @@ module.exports = { isContractDefinition: isContractDefinition, isConstantFunction: isConstantFunction, isInlineAssembly: isInlineAssembly, + isNewExpression: isNewExpression, // #################### Constants nodeTypes: nodeTypes,