Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
baas-ide
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
guxukai
baas-ide
Commits
83788eae
Commit
83788eae
authored
Dec 22, 2019
by
Iuri Matias
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update remix-analyzer syntax to use const, let and this
parent
89ad1dcd
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
209 additions
and
209 deletions
+209
-209
abstractAstView.js
...analyzer/src/solidity-analyzer/modules/abstractAstView.js
+10
-8
assignAndCompare.js
...nalyzer/src/solidity-analyzer/modules/assignAndCompare.js
+6
-6
blockBlockhash.js
...-analyzer/src/solidity-analyzer/modules/blockBlockhash.js
+6
-6
blockTimestamp.js
...-analyzer/src/solidity-analyzer/modules/blockTimestamp.js
+7
-7
checksEffectsInteraction.js
...src/solidity-analyzer/modules/checksEffectsInteraction.js
+15
-15
constantFunctions.js
...alyzer/src/solidity-analyzer/modules/constantFunctions.js
+13
-13
deleteDynamicArrays.js
...yzer/src/solidity-analyzer/modules/deleteDynamicArrays.js
+5
-5
deleteFromDynamicArray.js
...r/src/solidity-analyzer/modules/deleteFromDynamicArray.js
+4
-4
erc20Decimals.js
...x-analyzer/src/solidity-analyzer/modules/erc20Decimals.js
+10
-10
etherTransferInLoop.js
...yzer/src/solidity-analyzer/modules/etherTransferInLoop.js
+6
-6
forLoopIteratesOverDynamicArray.js
...idity-analyzer/modules/forLoopIteratesOverDynamicArray.js
+6
-6
functionCallGraph.js
...alyzer/src/solidity-analyzer/modules/functionCallGraph.js
+16
-16
gasCosts.js
remix-analyzer/src/solidity-analyzer/modules/gasCosts.js
+10
-10
guardConditions.js
...analyzer/src/solidity-analyzer/modules/guardConditions.js
+5
-5
inlineAssembly.js
...-analyzer/src/solidity-analyzer/modules/inlineAssembly.js
+5
-5
intDivisionTruncate.js
...yzer/src/solidity-analyzer/modules/intDivisionTruncate.js
+6
-6
lowLevelCalls.js
...x-analyzer/src/solidity-analyzer/modules/lowLevelCalls.js
+8
-8
noReturn.js
remix-analyzer/src/solidity-analyzer/modules/noReturn.js
+11
-11
selfdestruct.js
remix-analyzer/src/solidity-analyzer/modules/selfdestruct.js
+7
-7
similarVariableNames.js
...zer/src/solidity-analyzer/modules/similarVariableNames.js
+19
-20
staticAnalysisCommon.js
...zer/src/solidity-analyzer/modules/staticAnalysisCommon.js
+20
-20
stringBytesLength.js
...alyzer/src/solidity-analyzer/modules/stringBytesLength.js
+4
-5
thisLocal.js
remix-analyzer/src/solidity-analyzer/modules/thisLocal.js
+5
-5
txOrigin.js
remix-analyzer/src/solidity-analyzer/modules/txOrigin.js
+5
-5
No files found.
remix-analyzer/src/solidity-analyzer/modules/abstractAstView.js
View file @
83788eae
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
...
...
remix-analyzer/src/solidity-analyzer/modules/assignAndCompare.js
View file @
83788eae
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
...
...
remix-analyzer/src/solidity-analyzer/modules/blockBlockhash.js
View file @
83788eae
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.
...
...
remix-analyzer/src/solidity-analyzer/modules/blockTimestamp.js
View file @
83788eae
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.`
,
...
...
remix-analyzer/src/solidity-analyzer/modules/checksEffectsInteraction.js
View file @
83788eae
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
...
...
remix-analyzer/src/solidity-analyzer/modules/constantFunctions.js
View file @
83788eae
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
...
...
remix-analyzer/src/solidity-analyzer/modules/deleteDynamicArrays.js
View file @
83788eae
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
=
[]
...
...
remix-analyzer/src/solidity-analyzer/modules/deleteFromDynamicArray.js
View file @
83788eae
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
=
[]
...
...
remix-analyzer/src/solidity-analyzer/modules/erc20Decimals.js
View file @
83788eae
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
)
=>
{
le
t
contractAbiSignatures
=
contract
.
functions
.
map
((
f
)
=>
common
.
helpers
.
buildAbiSignature
(
common
.
getFunctionDefinitionName
(
f
.
node
),
f
.
parameters
))
cons
t
contractAbiSignatures
=
contract
.
functions
.
map
((
f
)
=>
common
.
helpers
.
buildAbiSignature
(
common
.
getFunctionDefinitionName
(
f
.
node
),
f
.
parameters
))
if
(
isERC20
(
contractAbiSignatures
))
{
le
t
decimalsVar
=
contract
.
stateVariables
.
filter
((
stateVar
)
=>
common
.
getDeclaredVariableName
(
stateVar
)
===
'decimals'
&&
(
common
.
getDeclaredVariableType
(
stateVar
)
!==
'uint8'
||
stateVar
.
attributes
.
visibility
!==
'public'
))
le
t
decimalsFun
=
contract
.
functions
.
filter
((
f
)
=>
common
.
getFunctionDefinitionName
(
f
.
node
)
===
'decimals'
&&
cons
t
decimalsVar
=
contract
.
stateVariables
.
filter
((
stateVar
)
=>
common
.
getDeclaredVariableName
(
stateVar
)
===
'decimals'
&&
(
common
.
getDeclaredVariableType
(
stateVar
)
!==
'uint8'
||
stateVar
.
attributes
.
visibility
!==
'public'
))
cons
t
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'
))
...
...
remix-analyzer/src/solidity-analyzer/modules/etherTransferInLoop.js
View file @
83788eae
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
)
&&
...
...
remix-analyzer/src/solidity-analyzer/modules/forLoopIteratesOverDynamicArray.js
View file @
83788eae
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
le
t
forLoopConditionNode
=
node
.
children
[
1
]
cons
t
forLoopConditionNode
=
node
.
children
[
1
]
// Access right side of condition as its children
le
t
conditionChildrenNode
=
forLoopConditionNode
.
children
[
1
]
cons
t
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
)
...
...
remix-analyzer/src/solidity-analyzer/modules/functionCallGraph.js
View file @
83788eae
'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
}
}
...
...
remix-analyzer/src/solidity-analyzer/modules/gasCosts.js
View file @
83788eae
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
}
.
...
...
remix-analyzer/src/solidity-analyzer/modules/guardConditions.js
View file @
83788eae
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
=
[]
...
...
remix-analyzer/src/solidity-analyzer/modules/inlineAssembly.js
View file @
83788eae
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
=
[]
...
...
remix-analyzer/src/solidity-analyzer/modules/intDivisionTruncate.js
View file @
83788eae
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
...
...
remix-analyzer/src/solidity-analyzer/modules/lowLevelCalls.js
View file @
83788eae
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.
...
...
remix-analyzer/src/solidity-analyzer/modules/noReturn.js
View file @
83788eae
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
}
...
...
remix-analyzer/src/solidity-analyzer/modules/selfdestruct.js
View file @
83788eae
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
)
=>
{
...
...
remix-analyzer/src/solidity-analyzer/modules/similarVariableNames.js
View file @
83788eae
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
}
...
...
remix-analyzer/src/solidity-analyzer/modules/staticAnalysisCommon.js
View file @
83788eae
'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
}
}
...
...
remix-analyzer/src/solidity-analyzer/modules/stringBytesLength.js
View file @
83788eae
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
}
remix-analyzer/src/solidity-analyzer/modules/thisLocal.js
View file @
83788eae
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
=
[]
...
...
remix-analyzer/src/solidity-analyzer/modules/txOrigin.js
View file @
83788eae
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.`
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment