update remix-analyzer syntax to use const, let and this

pull/7/head
Iuri Matias 5 years ago
parent 89ad1dcd69
commit 83788eaeee
  1. 18
      remix-analyzer/src/solidity-analyzer/modules/abstractAstView.js
  2. 12
      remix-analyzer/src/solidity-analyzer/modules/assignAndCompare.js
  3. 12
      remix-analyzer/src/solidity-analyzer/modules/blockBlockhash.js
  4. 14
      remix-analyzer/src/solidity-analyzer/modules/blockTimestamp.js
  5. 30
      remix-analyzer/src/solidity-analyzer/modules/checksEffectsInteraction.js
  6. 26
      remix-analyzer/src/solidity-analyzer/modules/constantFunctions.js
  7. 10
      remix-analyzer/src/solidity-analyzer/modules/deleteDynamicArrays.js
  8. 8
      remix-analyzer/src/solidity-analyzer/modules/deleteFromDynamicArray.js
  9. 20
      remix-analyzer/src/solidity-analyzer/modules/erc20Decimals.js
  10. 12
      remix-analyzer/src/solidity-analyzer/modules/etherTransferInLoop.js
  11. 12
      remix-analyzer/src/solidity-analyzer/modules/forLoopIteratesOverDynamicArray.js
  12. 32
      remix-analyzer/src/solidity-analyzer/modules/functionCallGraph.js
  13. 20
      remix-analyzer/src/solidity-analyzer/modules/gasCosts.js
  14. 10
      remix-analyzer/src/solidity-analyzer/modules/guardConditions.js
  15. 10
      remix-analyzer/src/solidity-analyzer/modules/inlineAssembly.js
  16. 12
      remix-analyzer/src/solidity-analyzer/modules/intDivisionTruncate.js
  17. 16
      remix-analyzer/src/solidity-analyzer/modules/lowLevelCalls.js
  18. 22
      remix-analyzer/src/solidity-analyzer/modules/noReturn.js
  19. 14
      remix-analyzer/src/solidity-analyzer/modules/selfdestruct.js
  20. 39
      remix-analyzer/src/solidity-analyzer/modules/similarVariableNames.js
  21. 40
      remix-analyzer/src/solidity-analyzer/modules/staticAnalysisCommon.js
  22. 9
      remix-analyzer/src/solidity-analyzer/modules/stringBytesLength.js
  23. 10
      remix-analyzer/src/solidity-analyzer/modules/thisLocal.js
  24. 10
      remix-analyzer/src/solidity-analyzer/modules/txOrigin.js

@ -1,5 +1,5 @@
var common = require('./staticAnalysisCommon')
var AstWalker = require('remix-lib').AstWalker
const common = require('./staticAnalysisCommon')
const AstWalker = require('remix-lib').AstWalker
function abstractAstView () {
this.contracts = []
@ -56,8 +56,8 @@ abstractAstView.prototype.build_visit = function (relevantNodeFilter) {
stateVariables: common.getStateVariableDeclarationsFormContractNode(node)
})
} else if (common.isInheritanceSpecifier(node)) {
var currentContract = getCurrentContract(that)
var inheritsFromName = common.getInheritsFromName(node)
const currentContract = getCurrentContract(that)
const inheritsFromName = common.getInheritsFromName(node)
currentContract.inheritsFrom.push(inheritsFromName)
} else if (common.isFunctionDefinition(node)) {
setCurrentFunction(that, {
@ -85,7 +85,7 @@ abstractAstView.prototype.build_visit = function (relevantNodeFilter) {
if (!that.isFunctionNotModifier) throw new Error('abstractAstView.js: Found modifier invocation outside of function scope.')
getCurrentFunction(that).modifierInvocations.push(node)
} else if (relevantNodeFilter(node)) {
var scope = (that.isFunctionNotModifier) ? getCurrentFunction(that) : getCurrentModifier(that)
let scope = (that.isFunctionNotModifier) ? getCurrentFunction(that) : getCurrentModifier(that)
if (scope) {
scope.relevantNodes.push(node)
} else {
@ -111,10 +111,11 @@ function resolveStateVariablesInHierarchy (contracts) {
resolveStateVariablesInHierarchyForContract(c, contracts)
})
}
function resolveStateVariablesInHierarchyForContract (currentContract, contracts) {
currentContract.inheritsFrom.map((inheritsFromName) => {
// add variables from inherited contracts
var inheritsFrom = contracts.find((contract) => common.getContractName(contract.node) === inheritsFromName)
const inheritsFrom = contracts.find((contract) => common.getContractName(contract.node) === inheritsFromName)
if (inheritsFrom) {
currentContract.stateVariables = currentContract.stateVariables.concat(inheritsFrom.stateVariables)
} else {
@ -122,8 +123,9 @@ function resolveStateVariablesInHierarchyForContract (currentContract, contracts
}
})
}
function setCurrentContract (that, contract) {
var name = common.getContractName(contract.node)
const name = common.getContractName(contract.node)
if (that.contracts.map((c) => common.getContractName(c.node)).filter((n) => n === name).length > 0) {
console.log('abstractAstView.js: two or more contracts with the same name dectected, import aliases not supported at the moment')
that.multipleContractsWithSameName = true
@ -167,7 +169,7 @@ function getReturnParameters (funcNode) {
}
function getLocalVariables (funcNode) {
var locals = []
const locals = []
new AstWalker().walk(funcNode, {'*': function (node) {
if (common.isVariableDeclaration(node)) locals.push(node)
return true

@ -1,8 +1,8 @@
var name = 'Result not used: '
var desc = 'The result of an operation was not used.'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')
var algo = require('./algorithmCategories')
const name = 'Result not used: '
const desc = 'The result of an operation was not used.'
const categories = require('./categories')
const common = require('./staticAnalysisCommon')
const algo = require('./algorithmCategories')
function assignAndCompare () {
this.warningNodes = []
@ -13,7 +13,7 @@ assignAndCompare.prototype.visit = function (node) {
}
assignAndCompare.prototype.report = function (compilationResults) {
return this.warningNodes.map(function (item, i) {
return this.warningNodes.map((item, i) => {
return {
warning: 'A binary operation yields a value that is not used in the following. This is often caused by confusing assignment (=) and comparison (==).',
location: item.src

@ -1,8 +1,8 @@
var name = 'Block.blockhash usage: '
var desc = 'Semantics maybe unclear'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')
var algo = require('./algorithmCategories')
const name = 'Block.blockhash usage: '
const desc = 'Semantics maybe unclear'
const categories = require('./categories')
const common = require('./staticAnalysisCommon')
const algo = require('./algorithmCategories')
function blockBlockhash () {
this.warningNodes = []
@ -13,7 +13,7 @@ blockBlockhash.prototype.visit = function (node) {
}
blockBlockhash.prototype.report = function (compilationResults) {
return this.warningNodes.map(function (item, i) {
return this.warningNodes.map((item, i) => {
return {
warning: `use of "block.blockhash": "block.blockhash" is used to access the last 256 block hashes.
A miner computes the block hash by "summing up" the information in the current block mined.

@ -1,8 +1,8 @@
var name = 'Block timestamp: '
var desc = 'Semantics maybe unclear'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')
var algo = require('./algorithmCategories')
const name = 'Block timestamp: '
const desc = 'Semantics maybe unclear'
const categories = require('./categories')
const common = require('./staticAnalysisCommon')
const algo = require('./algorithmCategories')
function blockTimestamp () {
this.warningNowNodes = []
@ -15,14 +15,14 @@ blockTimestamp.prototype.visit = function (node) {
}
blockTimestamp.prototype.report = function (compilationResults) {
return this.warningNowNodes.map(function (item, i) {
return this.warningNowNodes.map((item, i) => {
return {
warning: `use of "now": "now" does not mean current time. Now is an alias for block.timestamp.
Block.timestamp can be influenced by miners to a certain degree, be careful.`,
location: item.src,
more: 'http://solidity.readthedocs.io/en/develop/frequently-asked-questions.html#are-timestamps-now-block-timestamp-reliable'
}
}).concat(this.warningblockTimestampNodes.map(function (item, i) {
}).concat(this.warningblockTimestampNodes.map((item, i) => {
return {
warning: `use of "block.timestamp": "block.timestamp" can be influenced by miners to a certain degree.
That means that a miner can "choose" the block.timestamp, to a certain degree, to change the outcome of a transaction in the mined block.`,

@ -1,10 +1,10 @@
var name = 'Check effects: '
var desc = 'Avoid potential reentrancy bugs'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')
var fcallGraph = require('./functionCallGraph')
var AbstractAst = require('./abstractAstView')
var algo = require('./algorithmCategories')
const name = 'Check effects: '
const desc = 'Avoid potential reentrancy bugs'
const categories = require('./categories')
const common = require('./staticAnalysisCommon')
const fcallGraph = require('./functionCallGraph')
const AbstractAst = require('./abstractAstView')
const algo = require('./algorithmCategories')
function checksEffectsInteraction () {
this.abstractAst = new AbstractAst()
@ -20,10 +20,10 @@ checksEffectsInteraction.prototype.visit = function () { throw new Error('checks
checksEffectsInteraction.prototype.report = function () { throw new Error('checksEffectsInteraction.js no report function set upon construction') }
function report (contracts, multipleContractsWithSameName) {
var warnings = []
var hasModifiers = contracts.some((item) => item.modifiers.length > 0)
const warnings = []
const hasModifiers = contracts.some((item) => item.modifiers.length > 0)
var callGraph = fcallGraph.buildGlobalFuncCallGraph(contracts)
const callGraph = fcallGraph.buildGlobalFuncCallGraph(contracts)
contracts.forEach((contract) => {
contract.functions.forEach((func) => {
@ -33,8 +33,8 @@ function report (contracts, multipleContractsWithSameName) {
contract.functions.forEach((func) => {
if (isPotentialVulnerableFunction(func, getContext(callGraph, contract, func))) {
var funcName = common.getFullQuallyfiedFuncDefinitionIdent(contract.node, func.node, func.parameters)
var comments = (hasModifiers) ? 'Note: Modifiers are currently not considered by this static analysis.' : ''
const funcName = common.getFullQuallyfiedFuncDefinitionIdent(contract.node, func.node, func.parameters)
let comments = (hasModifiers) ? 'Note: Modifiers are currently not considered by this static analysis.' : ''
comments += (multipleContractsWithSameName) ? 'Note: Import aliases are currently not supported by this static analysis.' : ''
warnings.push({
warning: `Potential Violation of Checks-Effects-Interaction pattern in ${funcName}: Could potentially lead to re-entrancy vulnerability. ${comments}`,
@ -57,8 +57,8 @@ function getStateVariables (contract, func) {
}
function isPotentialVulnerableFunction (func, context) {
var isPotentialVulnerable = false
var interaction = false
let isPotentialVulnerable = false
let interaction = false
func.relevantNodes.forEach((node) => {
if (common.isInteraction(node)) {
interaction = true
@ -71,7 +71,7 @@ function isPotentialVulnerableFunction (func, context) {
function isLocalCallWithStateChange (node, context) {
if (common.isLocalCallGraphRelevantNode(node)) {
var func = fcallGraph.resolveCallGraphSymbol(context.callGraph, common.getFullQualifiedFunctionCallIdent(context.currentContract.node, node))
const func = fcallGraph.resolveCallGraphSymbol(context.callGraph, common.getFullQualifiedFunctionCallIdent(context.currentContract.node, node))
return !func || (func && func.node.changesState)
}
return false

@ -1,10 +1,10 @@
var name = 'Constant functions: '
var desc = 'Check for potentially constant functions'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')
var fcallGraph = require('./functionCallGraph')
var AbstractAst = require('./abstractAstView')
var algo = require('./algorithmCategories')
const name = 'Constant functions: '
const desc = 'Check for potentially constant functions'
const categories = require('./categories')
const common = require('./staticAnalysisCommon')
const fcallGraph = require('./functionCallGraph')
const AbstractAst = require('./abstractAstView')
const algo = require('./algorithmCategories')
function constantFunctions () {
this.abstractAst = new AbstractAst()
@ -29,10 +29,10 @@ constantFunctions.prototype.visit = function () { throw new Error('constantFunct
constantFunctions.prototype.report = function () { throw new Error('constantFunctions.js no report function set upon construction') }
function report (contracts, multipleContractsWithSameName) {
var warnings = []
var hasModifiers = contracts.some((item) => item.modifiers.length > 0)
const warnings = []
const hasModifiers = contracts.some((item) => item.modifiers.length > 0)
var callGraph = fcallGraph.buildGlobalFuncCallGraph(contracts)
const callGraph = fcallGraph.buildGlobalFuncCallGraph(contracts)
contracts.forEach((contract) => {
contract.functions.forEach((func) => {
@ -46,8 +46,8 @@ function report (contracts, multipleContractsWithSameName) {
contract.functions.filter((func) => common.hasFunctionBody(func.node)).forEach((func) => {
if (common.isConstantFunction(func.node) !== func.potentiallyshouldBeConst) {
var funcName = common.getFullQuallyfiedFuncDefinitionIdent(contract.node, func.node, func.parameters)
var comments = (hasModifiers) ? 'Note: Modifiers are currently not considered by this static analysis.' : ''
const funcName = common.getFullQuallyfiedFuncDefinitionIdent(contract.node, func.node, func.parameters)
let comments = (hasModifiers) ? 'Note: Modifiers are currently not considered by this static analysis.' : ''
comments += (multipleContractsWithSameName) ? 'Note: Import aliases are currently not supported by this static analysis.' : ''
if (func.potentiallyshouldBeConst) {
warnings.push({
@ -95,7 +95,7 @@ function isConstBreaker (node, context) {
function isCallOnNonConstExternalInterfaceFunction (node, context) {
if (common.isExternalDirectCall(node)) {
var func = fcallGraph.resolveCallGraphSymbol(context.callGraph, common.getFullQualifiedFunctionCallIdent(context.currentContract, node))
const func = fcallGraph.resolveCallGraphSymbol(context.callGraph, common.getFullQualifiedFunctionCallIdent(context.currentContract, node))
return !func || (func && !common.isConstantFunction(func.node.node))
}
return false

@ -1,8 +1,8 @@
var name = 'Delete on dynamic Array: '
var desc = 'Use require and appropriately'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')
var algo = require('./algorithmCategories')
const name = 'Delete on dynamic Array: '
const desc = 'Use require and appropriately'
const categories = require('./categories')
const common = require('./staticAnalysisCommon')
const algo = require('./algorithmCategories')
function deleteDynamicArrays () {
this.rel = []

@ -1,7 +1,7 @@
var name = 'Delete from dynamic Array: '
var desc = 'Using delete on an array leaves a gap'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')
const name = 'Delete from dynamic Array: '
const desc = 'Using delete on an array leaves a gap'
const categories = require('./categories')
const common = require('./staticAnalysisCommon')
function deleteFromDynamicArray () {
this.relevantNodes = []

@ -1,9 +1,9 @@
var name = 'ERC20: '
var desc = 'Decimal should be uint8'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')
var AbstractAst = require('./abstractAstView')
var algo = require('./algorithmCategories')
const name = 'ERC20: '
const desc = 'Decimal should be uint8'
const categories = require('./categories')
const common = require('./staticAnalysisCommon')
const AbstractAst = require('./abstractAstView')
const algo = require('./algorithmCategories')
function erc20Decimals () {
this.abstractAst = new AbstractAst()
@ -18,14 +18,14 @@ erc20Decimals.prototype.visit = function () { throw new Error('erc20Decimals.js
erc20Decimals.prototype.report = function () { throw new Error('erc20Decimals.js no report function set upon construction') }
function report (contracts, multipleContractsWithSameName) {
var warnings = []
const warnings = []
contracts.forEach((contract) => {
let contractAbiSignatures = contract.functions.map((f) => common.helpers.buildAbiSignature(common.getFunctionDefinitionName(f.node), f.parameters))
const contractAbiSignatures = contract.functions.map((f) => common.helpers.buildAbiSignature(common.getFunctionDefinitionName(f.node), f.parameters))
if (isERC20(contractAbiSignatures)) {
let decimalsVar = contract.stateVariables.filter((stateVar) => common.getDeclaredVariableName(stateVar) === 'decimals' && (common.getDeclaredVariableType(stateVar) !== 'uint8' || stateVar.attributes.visibility !== 'public'))
let decimalsFun = contract.functions.filter((f) => common.getFunctionDefinitionName(f.node) === 'decimals' &&
const decimalsVar = contract.stateVariables.filter((stateVar) => common.getDeclaredVariableName(stateVar) === 'decimals' && (common.getDeclaredVariableType(stateVar) !== 'uint8' || stateVar.attributes.visibility !== 'public'))
const decimalsFun = contract.functions.filter((f) => common.getFunctionDefinitionName(f.node) === 'decimals' &&
(
(f.returns.length === 0 || f.returns.length > 1) ||
(f.returns.length === 1 && (f.returns[0].type !== 'uint8' || f.node.attributes.visibility !== 'public'))

@ -1,7 +1,7 @@
var name = 'Ether transfer in a loop: '
var desc = 'Avoid transferring Ether to multiple addresses in a loop'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')
const name = 'Ether transfer in a loop: '
const desc = 'Avoid transferring Ether to multiple addresses in a loop'
const categories = require('./categories')
const common = require('./staticAnalysisCommon')
function etherTransferInLoop () {
this.relevantNodes = []
@ -9,8 +9,8 @@ function etherTransferInLoop () {
etherTransferInLoop.prototype.visit = function (node) {
if (common.isLoop(node)) {
var transferNodes = []
var loopBlockStartIndex = common.getLoopBlockStartIndex(node)
let transferNodes = []
const loopBlockStartIndex = common.getLoopBlockStartIndex(node)
if (common.isBlock(node.children[loopBlockStartIndex])) {
transferNodes = node.children[loopBlockStartIndex].children
.filter(child => (common.isExpressionStatement(child) &&

@ -1,7 +1,7 @@
var name = 'For loop iterates over dynamic array: '
var desc = 'The number of \'for\' loop iterations depends on dynamic array\'s size'
var categories = require('./categories')
var { isForLoop, isDynamicArrayLengthAccess, isBinaryOperation } = require('./staticAnalysisCommon')
const name = 'For loop iterates over dynamic array: '
const desc = 'The number of \'for\' loop iterations depends on dynamic array\'s size'
const categories = require('./categories')
const { isForLoop, isDynamicArrayLengthAccess, isBinaryOperation } = require('./staticAnalysisCommon')
function forLoopIteratesOverDynamicArray () {
this.relevantNodes = []
@ -10,9 +10,9 @@ function forLoopIteratesOverDynamicArray () {
forLoopIteratesOverDynamicArray.prototype.visit = function (node) {
if (isForLoop(node)) {
// Access 'condition' node of 'for' loop statement
let forLoopConditionNode = node.children[1]
const forLoopConditionNode = node.children[1]
// Access right side of condition as its children
let conditionChildrenNode = forLoopConditionNode.children[1]
const conditionChildrenNode = forLoopConditionNode.children[1]
// Check if it is a binary operation. if yes, check if its children node access length of dynamic array
if (isBinaryOperation(conditionChildrenNode) && isDynamicArrayLengthAccess(conditionChildrenNode.children[0])) {
this.relevantNodes.push(node)

@ -1,11 +1,11 @@
'use strict'
var common = require('./staticAnalysisCommon')
const common = require('./staticAnalysisCommon')
function buildLocalFuncCallGraphInternal (functions, nodeFilter, extractNodeIdent, extractFuncDefIdent) {
var callGraph = {}
const callGraph = {}
functions.forEach((func) => {
var calls = func.relevantNodes
const calls = func.relevantNodes
.filter(nodeFilter)
.map(extractNodeIdent)
.filter((name) => name !== extractFuncDefIdent(func)) // filter self recursive call
@ -41,11 +41,11 @@ function buildLocalFuncCallGraphInternal (functions, nodeFilter, extractNodeIden
* @return {map (string -> Contract Call Graph)} returns map from contract name to contract call graph
*/
function buildGlobalFuncCallGraph (contracts) {
var callGraph = {}
const callGraph = {}
contracts.forEach((contract) => {
var filterNodes = (node) => { return common.isLocalCallGraphRelevantNode(node) || common.isExternalDirectCall(node) }
var getNodeIdent = (node) => { return common.getFullQualifiedFunctionCallIdent(contract.node, node) }
var getFunDefIdent = (funcDef) => { return common.getFullQuallyfiedFuncDefinitionIdent(contract.node, funcDef.node, funcDef.parameters) }
const filterNodes = (node) => { return common.isLocalCallGraphRelevantNode(node) || common.isExternalDirectCall(node) }
const getNodeIdent = (node) => { return common.getFullQualifiedFunctionCallIdent(contract.node, node) }
const getFunDefIdent = (funcDef) => { return common.getFullQuallyfiedFuncDefinitionIdent(contract.node, funcDef.node, funcDef.parameters) }
callGraph[common.getContractName(contract.node)] = { contract: contract, functions: buildLocalFuncCallGraphInternal(contract.functions, filterNodes, getNodeIdent, getFunDefIdent) }
})
@ -66,7 +66,7 @@ function analyseCallGraph (callGraph, funcName, context, nodeCheck) {
}
function analyseCallGraphInternal (callGraph, funcName, context, combinator, nodeCheck, visited) {
var current = resolveCallGraphSymbol(callGraph, funcName)
const current = resolveCallGraphSymbol(callGraph, funcName)
if (current === undefined || visited[funcName] === true) return true
visited[funcName] = true
@ -80,20 +80,20 @@ function resolveCallGraphSymbol (callGraph, funcName) {
}
function resolveCallGraphSymbolInternal (callGraph, funcName, silent) {
var current
let current
if (funcName.includes('.')) {
var parts = funcName.split('.')
var contractPart = parts[0]
var functionPart = parts[1]
var currentContract = callGraph[contractPart]
const parts = funcName.split('.')
const contractPart = parts[0]
const functionPart = parts[1]
const currentContract = callGraph[contractPart]
if (!(currentContract === undefined)) {
current = currentContract.functions[funcName]
// resolve inheritance hierarchy
if (current === undefined) {
// resolve inheritance lookup in linearized fashion
var inheritsFromNames = currentContract.contract.inheritsFrom.reverse()
for (var i = 0; i < inheritsFromNames.length; i++) {
var res = resolveCallGraphSymbolInternal(callGraph, inheritsFromNames[i] + '.' + functionPart, true)
const inheritsFromNames = currentContract.contract.inheritsFrom.reverse()
for (let i = 0; i < inheritsFromNames.length; i++) {
const res = resolveCallGraphSymbolInternal(callGraph, inheritsFromNames[i] + '.' + functionPart, true)
if (!(res === undefined)) return res
}
}

@ -1,7 +1,7 @@
var name = 'Gas costs: '
var desc = 'Warn if the gas requirements of functions are too high.'
var categories = require('./categories')
var algo = require('./algorithmCategories')
const name = 'Gas costs: '
const desc = 'Warn if the gas requirements of functions are too high.'
const categories = require('./categories')
const algo = require('./algorithmCategories')
function gasCosts () {
}
@ -13,15 +13,15 @@ function gasCosts () {
*/
// @TODO has been copied from remix-ide repo ! should fix that soon !
function visitContracts (contracts, cb) {
for (var file in contracts) {
for (var name in contracts[file]) {
for (let file in contracts) {
for (let name in contracts[file]) {
if (cb({ name: name, object: contracts[file][name], file: file })) return
}
}
}
gasCosts.prototype.report = function (compilationResults) {
var report = []
const report = []
visitContracts(compilationResults.contracts, (contract) => {
if (
!contract.object.evm.gasEstimates ||
@ -29,7 +29,7 @@ gasCosts.prototype.report = function (compilationResults) {
) {
return
}
var fallback = contract.object.evm.gasEstimates.external['']
const fallback = contract.object.evm.gasEstimates.external['']
if (fallback !== undefined) {
if (fallback === null || fallback >= 2100 || fallback === 'infinite') {
report.push({
@ -43,8 +43,8 @@ gasCosts.prototype.report = function (compilationResults) {
if (functionName === '') {
continue
}
var gas = contract.object.evm.gasEstimates.external[functionName]
var gasString = gas === null ? 'unknown or not constant' : 'high: ' + gas
const gas = contract.object.evm.gasEstimates.external[functionName]
const gasString = gas === null ? 'unknown or not constant' : 'high: ' + gas
if (gas === null || gas >= 3000000 || gas === 'infinite') {
report.push({
warning: `Gas requirement of function ${contract.name}.${functionName} ${gasString}.

@ -1,8 +1,8 @@
var name = 'Guard Conditions: '
var desc = 'Use require and appropriately'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')
var algo = require('./algorithmCategories')
const name = 'Guard Conditions: '
const desc = 'Use require and appropriately'
const categories = require('./categories')
const common = require('./staticAnalysisCommon')
const algo = require('./algorithmCategories')
function guardConditions () {
this.guards = []

@ -1,8 +1,8 @@
var name = 'Inline assembly: '
var desc = 'Use of Inline Assembly'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')
var algo = require('./algorithmCategories')
const name = 'Inline assembly: '
const desc = 'Use of Inline Assembly'
const categories = require('./categories')
const common = require('./staticAnalysisCommon')
const algo = require('./algorithmCategories')
function inlineAssembly () {
this.inlineAssNodes = []

@ -1,8 +1,8 @@
var name = 'Data Trucated: '
var desc = 'Division on int/uint values truncates the result.'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')
var algo = require('./algorithmCategories')
const name = 'Data Trucated: '
const desc = 'Division on int/uint values truncates the result.'
const categories = require('./categories')
const common = require('./staticAnalysisCommon')
const algo = require('./algorithmCategories')
function intDivitionTruncate () {
this.warningNodes = []
@ -13,7 +13,7 @@ intDivitionTruncate.prototype.visit = function (node) {
}
intDivitionTruncate.prototype.report = function (compilationResults) {
return this.warningNodes.map(function (item, i) {
return this.warningNodes.map((item, i) => {
return {
warning: 'Division of integer values yields an integer value again. That means e.g. 10 / 100 = 0 instead of 0.1 since the result is an integer again. This does not hold for division of (only) literal values since those yield rational constants.',
location: item.src

@ -1,8 +1,8 @@
var name = 'Low level calls: '
var desc = 'Semantics maybe unclear'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')
var algo = require('./algorithmCategories')
const name = 'Low level calls: '
const desc = 'Semantics maybe unclear'
const categories = require('./categories')
const common = require('./staticAnalysisCommon')
const algo = require('./algorithmCategories')
function lowLevelCalls () {
this.llcNodes = []
@ -27,9 +27,9 @@ lowLevelCalls.prototype.visit = function (node) {
}
lowLevelCalls.prototype.report = function (compilationResults) {
return this.llcNodes.map(function (item, i) {
var text = ''
var morehref = null
return this.llcNodes.map((item, i) => {
let text = ''
let morehref = null
switch (item.type) {
case common.lowLevelCallTypes.CALL:
text = `use of "call": the use of low level "call" should be avoided whenever possible.

@ -1,9 +1,9 @@
var name = 'no return: '
var desc = 'Function with return type is not returning'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')
var AbstractAst = require('./abstractAstView')
var algo = require('./algorithmCategories')
const name = 'no return: '
const desc = 'Function with return type is not returning'
const categories = require('./categories')
const common = require('./staticAnalysisCommon')
const AbstractAst = require('./abstractAstView')
const algo = require('./algorithmCategories')
function noReturn () {
this.abstractAst = new AbstractAst()
@ -20,11 +20,11 @@ noReturn.prototype.visit = function () { throw new Error('noReturn.js no visit f
noReturn.prototype.report = function () { throw new Error('noReturn.js no report function set upon construction') }
function report (contracts, multipleContractsWithSameName) {
var warnings = []
const warnings = []
contracts.forEach((contract) => {
contract.functions.filter((func) => common.hasFunctionBody(func.node)).forEach((func) => {
var funcName = common.getFullQuallyfiedFuncDefinitionIdent(contract.node, func.node, func.parameters)
const funcName = common.getFullQuallyfiedFuncDefinitionIdent(contract.node, func.node, func.parameters)
if (hasNamedAndUnnamedReturns(func)) {
warnings.push({
warning: `${funcName}: Mixing of named and unnamed return parameters is not advised.`,
@ -51,9 +51,9 @@ function hasReturnStatement (func) {
}
function hasAssignToAllNamedReturns (func) {
var namedReturns = func.returns.filter((n) => n.name.length > 0).map((n) => n.name)
var assignedVars = func.relevantNodes.filter(common.isAssignment).map(common.getEffectedVariableName)
var diff = namedReturns.filter(e => !assignedVars.includes(e))
const namedReturns = func.returns.filter((n) => n.name.length > 0).map((n) => n.name)
const assignedVars = func.relevantNodes.filter(common.isAssignment).map(common.getEffectedVariableName)
const diff = namedReturns.filter(e => !assignedVars.includes(e))
return diff.length === 0
}

@ -1,9 +1,9 @@
var name = 'Selfdestruct: '
var desc = 'Be aware of caller contracts.'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')
var AbstractAst = require('./abstractAstView')
var algo = require('./algorithmCategories')
const name = 'Selfdestruct: '
const desc = 'Be aware of caller contracts.'
const categories = require('./categories')
const common = require('./staticAnalysisCommon')
const AbstractAst = require('./abstractAstView')
const algo = require('./algorithmCategories')
function selfdestruct () {
this.abstractAst = new AbstractAst()
@ -21,7 +21,7 @@ selfdestruct.prototype.visit = function () { throw new Error('selfdestruct.js no
selfdestruct.prototype.report = function () { throw new Error('selfdestruct.js no report function set upon construction') }
function report (contracts, multipleContractsWithSameName) {
var warnings = []
const warnings = []
contracts.forEach((contract) => {
contract.functions.forEach((func) => {

@ -1,12 +1,12 @@
var name = 'Similar variable names: '
var desc = 'Check if variable names are too similar'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')
var AbstractAst = require('./abstractAstView')
var levenshtein = require('fast-levenshtein')
var remixLib = require('remix-lib')
var util = remixLib.util
var algo = require('./algorithmCategories')
const name = 'Similar variable names: '
const desc = 'Check if variable names are too similar'
const categories = require('./categories')
const common = require('./staticAnalysisCommon')
const AbstractAst = require('./abstractAstView')
const levenshtein = require('fast-levenshtein')
const remixLib = require('remix-lib')
const util = remixLib.util
const algo = require('./algorithmCategories')
function similarVariableNames () {
this.abstractAst = new AbstractAst()
@ -23,22 +23,22 @@ similarVariableNames.prototype.visit = function () { throw new Error('similarVar
similarVariableNames.prototype.report = function () { throw new Error('similarVariableNames.js no report function set upon construction') }
function report (contracts, multipleContractsWithSameName) {
var warnings = []
var hasModifiers = contracts.some((item) => item.modifiers.length > 0)
const warnings = []
const hasModifiers = contracts.some((item) => item.modifiers.length > 0)
contracts.forEach((contract) => {
contract.functions.forEach((func) => {
var funcName = common.getFullQuallyfiedFuncDefinitionIdent(contract.node, func.node, func.parameters)
var hasModifiersComments = ''
const funcName = common.getFullQuallyfiedFuncDefinitionIdent(contract.node, func.node, func.parameters)
let hasModifiersComments = ''
if (hasModifiers) {
hasModifiersComments = 'Note: Modifiers are currently not considered by this static analysis.'
}
var multipleContractsWithSameNameComments = ''
let multipleContractsWithSameNameComments = ''
if (multipleContractsWithSameName) {
multipleContractsWithSameNameComments = 'Note: Import aliases are currently not supported by this static analysis.'
}
var vars = getFunctionVariables(contract, func).map(common.getDeclaredVariableName)
const vars = getFunctionVariables(contract, func).map(common.getDeclaredVariableName)
findSimilarVarNames(vars).map((sim) => {
warnings.push({
@ -53,12 +53,12 @@ function report (contracts, multipleContractsWithSameName) {
}
function findSimilarVarNames (vars) {
var similar = []
var comb = {}
const similar = []
const comb = {}
vars.map((varName1) => vars.map((varName2) => {
if (varName1.length > 1 && varName2.length > 1 && varName2 !== varName1 && !isCommonPrefixedVersion(varName1, varName2) && !isCommonNrSuffixVersion(varName1, varName2) && !(comb[varName1 + ';' + varName2] || comb[varName2 + ';' + varName1])) {
comb[varName1 + ';' + varName2] = true
var distance = levenshtein.get(varName1, varName2)
const distance = levenshtein.get(varName1, varName2)
if (distance <= 2) similar.push({ var1: varName1, var2: varName2, distance: distance })
}
}))
@ -70,8 +70,7 @@ function isCommonPrefixedVersion (varName1, varName2) {
}
function isCommonNrSuffixVersion (varName1, varName2) {
var ref = '^' + util.escapeRegExp(varName1.slice(0, -1)) + '[0-9]*$'
const ref = '^' + util.escapeRegExp(varName1.slice(0, -1)) + '[0-9]*$'
return varName2.match(ref) != null
}

@ -1,9 +1,9 @@
'use strict'
var remixLib = require('remix-lib')
var util = remixLib.util
const remixLib = require('remix-lib')
const util = remixLib.util
var nodeTypes = {
const nodeTypes = {
IDENTIFIER: 'Identifier',
MEMBERACCESS: 'MemberAccess',
FUNCTIONCALL: 'FunctionCall',
@ -29,7 +29,7 @@ var nodeTypes = {
ELEMENTARYTYPENAMEEXPRESSION: 'ElementaryTypeNameExpression'
}
var basicTypes = {
const basicTypes = {
UINT: 'uint256',
BOOL: 'bool',
ADDRESS: 'address',
@ -40,7 +40,7 @@ var basicTypes = {
BYTES4: 'bytes4'
}
var basicRegex = {
const basicRegex = {
CONTRACTTYPE: '^contract ',
FUNCTIONTYPE: '^function \\(',
EXTERNALFUNCTIONTYPE: '^function \\(.*\\).* external',
@ -50,7 +50,7 @@ var basicRegex = {
LIBRARYTYPE: '^type\\(library (.*)\\)'
}
var basicFunctionTypes = {
const basicFunctionTypes = {
SEND: buildFunctionSignature([basicTypes.UINT], [basicTypes.BOOL], false),
CALL: buildFunctionSignature([], [basicTypes.BOOL], true),
'CALL-v0.5': buildFunctionSignature([basicTypes.BYTES_MEM], [basicTypes.BOOL, basicTypes.BYTES_MEM], true),
@ -59,7 +59,7 @@ var basicFunctionTypes = {
TRANSFER: buildFunctionSignature([basicTypes.UINT], [], false)
}
var builtinFunctions = {
const builtinFunctions = {
'keccak256()': true,
'sha3()': true,
'sha256()': true,
@ -79,7 +79,7 @@ var builtinFunctions = {
'address(address)': true
}
var lowLevelCallTypes = {
const lowLevelCallTypes = {
CALL: { ident: 'call', type: basicFunctionTypes.CALL },
'CALL-v0.5': { ident: 'call', type: basicFunctionTypes['CALL-v0.5'] },
CALLCODE: { ident: 'callcode', type: basicFunctionTypes.CALL },
@ -89,7 +89,7 @@ var lowLevelCallTypes = {
TRANSFER: { ident: 'transfer', type: basicFunctionTypes.TRANSFER }
}
var specialVariables = {
const specialVariables = {
BLOCKTIMESTAMP: { obj: 'block', member: 'timestamp', type: basicTypes.UINT },
BLOCKHASH: {
obj: 'block',
@ -98,7 +98,7 @@ var specialVariables = {
}
}
var abiNamespace = {
const abiNamespace = {
ENCODE: {
obj: 'abi',
member: 'encode',
@ -333,12 +333,12 @@ function getFunctionOrModifierDefinitionReturnParameterPart (funcNode) {
* @return {string} parameter signature
*/
function getFunctionCallTypeParameterType (func) {
var type = getFunctionCallType(func)
const type = getFunctionCallType(func)
if (type.startsWith('function (')) {
var paramTypes = ''
var openPar = 1
for (var x = 10; x < type.length; x++) {
var c = type.charAt(x)
let paramTypes = ''
let openPar = 1
for (let x = 10; x < type.length; x++) {
const c = type.charAt(x)
if (c === '(') openPar++
else if (c === ')') openPar--
@ -1031,7 +1031,7 @@ function nodeType (node, typeRegex) {
}
function name (node, nameRegex) {
var regex = new RegExp(nameRegex)
const regex = new RegExp(nameRegex)
return (node && !nameRegex) || (node && node.attributes && (regex.test(node.attributes.value) || regex.test(node.attributes.member_name)))
}
@ -1046,8 +1046,8 @@ function exactMatch (regexStr) {
}
function matches () {
var args = []
for (var k = 0; k < arguments.length; k++) {
const args = []
for (let k = 0; k < arguments.length; k++) {
args.push(arguments[k])
}
return '(' + args.join('|') + ')'
@ -1078,10 +1078,10 @@ function buildAbiSignature (funName, paramTypes) {
function findFirstSubNodeLTR (node, type) {
if (!node || !node.children) return null
for (let i = 0; i < node.children.length; ++i) {
var item = node.children[i]
const item = node.children[i]
if (nodeType(item, type)) return item
else {
var res = findFirstSubNodeLTR(item, type)
const res = findFirstSubNodeLTR(item, type)
if (res) return res
}
}

@ -1,7 +1,7 @@
var name = 'String Length: '
var desc = 'Bytes length != String length'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')
const name = 'String Length: '
const desc = 'Bytes length != String length'
const categories = require('./categories')
const common = require('./staticAnalysisCommon')
function stringBytesLength () {
this.stringToBytesConversions = []
@ -31,4 +31,3 @@ module.exports = {
category: categories.MISC,
Module: stringBytesLength
}

@ -1,8 +1,8 @@
var name = 'This on local calls: '
var desc = 'Invocation of local functions via this'
var categories = require('./categories')
var common = require('./staticAnalysisCommon')
var algo = require('./algorithmCategories')
const name = 'This on local calls: '
const desc = 'Invocation of local functions via this'
const categories = require('./categories')
const common = require('./staticAnalysisCommon')
const algo = require('./algorithmCategories')
function thisLocal () {
this.warningNodes = []

@ -1,7 +1,7 @@
var name = 'Transaction origin: '
var desc = 'Warn if tx.origin is used'
var categories = require('./categories')
var algo = require('./algorithmCategories')
const name = 'Transaction origin: '
const desc = 'Warn if tx.origin is used'
const categories = require('./categories')
const algo = require('./algorithmCategories')
function txOrigin () {
this.txOriginNodes = []
@ -19,7 +19,7 @@ txOrigin.prototype.visit = function (node) {
}
txOrigin.prototype.report = function () {
return this.txOriginNodes.map(function (item, i) {
return this.txOriginNodes.map((item, i) => {
return {
warning: `Use of tx.origin: "tx.origin" is useful only in very exceptional cases.
If you use it for authentication, you usually want to replace it by "msg.sender", because otherwise any contract you call can act on your behalf.`,

Loading…
Cancel
Save