Commit 93ba8eb6 authored by soad003's avatar soad003

StaticAnalysis: selfdestruct terminal warning

parent 32fda787
...@@ -2,25 +2,51 @@ var name = 'Selfdestruct: ' ...@@ -2,25 +2,51 @@ var name = 'Selfdestruct: '
var desc = 'Be aware of caller contracts.' var desc = 'Be aware of caller contracts.'
var categories = require('./categories') var categories = require('./categories')
var common = require('./staticAnalysisCommon') var common = require('./staticAnalysisCommon')
var AbstractAst = require('./abstractAstView')
function selfdestruct () { function selfdestruct () {
this.relevantNodes = [] this.abstractAst = new AbstractAst()
}
this.visit = this.abstractAst.build_visit(
(node) => common.isStatement(node) ||
common.isSelfdestructCall(node)
)
selfdestruct.prototype.visit = function (node) { this.report = this.abstractAst.build_report(report)
if (common.isSelfdestructCall(node)) {
this.relevantNodes.push(node)
}
} }
selfdestruct.prototype.report = function () { selfdestruct.prototype.visit = function () { throw new Error('constantFunctions.js no visit function set upon construction') }
return this.relevantNodes.map(function (item, i) {
return { selfdestruct.prototype.report = function () { throw new Error('constantFunctions.js no report function set upon construction') }
warning: 'Use of selfdestruct: can block calling contracts unexpectedly. Be especially careful if this contract is planned to be used by other contracts (i.e. library contracts, interactions). Selfdestruction of the callee contract can leave callers in an inoperable state.',
location: item.src, function report (contracts, multipleContractsWithSameName) {
more: 'https://paritytech.io/blog/security-alert.html' var warnings = []
}
contracts.forEach((contract) => {
contract.functions.forEach((func) => {
let hasSelf = false
func.relevantNodes.forEach((node) => {
if (common.isSelfdestructCall(node)) {
warnings.push({
warning: 'Use of selfdestruct: can block calling contracts unexpectedly. Be especially careful if this contract is planned to be used by other contracts (i.e. library contracts, interactions). Selfdestruction of the callee contract can leave callers in an inoperable state.',
location: node.src,
more: 'https://paritytech.io/blog/security-alert.html'
})
hasSelf = true
}
if (common.isStatement(node) && hasSelf) {
warnings.push({
warning: 'Use of selfdestruct: No code after selfdestruct is executed. Selfdestruct is a terminal.',
location: node.src,
more: 'http://solidity.readthedocs.io/en/develop/introduction-to-smart-contracts.html#self-destruct'
})
hasSelf = false
}
})
})
}) })
return warnings
} }
module.exports = { module.exports = {
......
...@@ -396,6 +396,14 @@ function isFunctionDefinition (node) { ...@@ -396,6 +396,14 @@ function isFunctionDefinition (node) {
return nodeType(node, exactMatch(nodeTypes.FUNCTIONDEFINITION)) return nodeType(node, exactMatch(nodeTypes.FUNCTIONDEFINITION))
} }
function isStatement (node) {
return nodeType(node, 'Statement$') || isBlock(node)
}
function isBlock (node) {
return nodeType(node, exactMatch(nodeTypes.BLOCK))
}
function isModifierDefinition (node) { function isModifierDefinition (node) {
return nodeType(node, exactMatch(nodeTypes.MODIFIERDEFINITION)) return nodeType(node, exactMatch(nodeTypes.MODIFIERDEFINITION))
} }
...@@ -1009,6 +1017,8 @@ module.exports = { ...@@ -1009,6 +1017,8 @@ module.exports = {
isInlineAssembly: isInlineAssembly, isInlineAssembly: isInlineAssembly,
isNewExpression: isNewExpression, isNewExpression: isNewExpression,
isReturn: isReturn, isReturn: isReturn,
isStatement: isStatement,
isBlock: isBlock,
// #################### Constants // #################### Constants
nodeTypes: nodeTypes, nodeTypes: nodeTypes,
......
...@@ -466,12 +466,12 @@ test('Integration test selfdestruct.js', function (t) { ...@@ -466,12 +466,12 @@ test('Integration test selfdestruct.js', function (t) {
'notReentrant.sol': 0, 'notReentrant.sol': 0,
'structReentrant.sol': 0, 'structReentrant.sol': 0,
'thisLocal.sol': 0, 'thisLocal.sol': 0,
'globals.sol': 1, 'globals.sol': 2,
'library.sol': 0, 'library.sol': 0,
'transfer.sol': 0, 'transfer.sol': 0,
'ctor.sol': 0, 'ctor.sol': 0,
'forgottenReturn.sol': 0, 'forgottenReturn.sol': 0,
'selfdestruct.sol': 2, 'selfdestruct.sol': 3,
'deleteDynamicArray.sol': 0, 'deleteDynamicArray.sol': 0,
'blockLevelCompare.sol': 0, 'blockLevelCompare.sol': 0,
'intDivisionTruncate.sol': 1 'intDivisionTruncate.sol': 1
......
contract sd { contract sd {
uint x = 0;
function() public payable { } function() public payable { }
function c () public constant { function c () public constant {
...@@ -8,5 +9,6 @@ contract sd { ...@@ -8,5 +9,6 @@ contract sd {
function b () public payable { function b () public payable {
selfdestruct(address(0xdeadbeef)); selfdestruct(address(0xdeadbeef));
x = 1;
} }
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment