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
3d7c17ec
Commit
3d7c17ec
authored
May 14, 2020
by
aniket-engg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gas costs analysis using AST
parent
5594cdea
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
51 additions
and
37 deletions
+51
-37
gasCosts.ts
remix-analyzer/src/solidity-analyzer/modules/gasCosts.ts
+50
-36
types.ts
remix-analyzer/src/types.ts
+1
-1
No files found.
remix-analyzer/src/solidity-analyzer/modules/gasCosts.ts
View file @
3d7c17ec
import
{
default
as
category
}
from
'./categories'
import
{
default
as
algorithm
}
from
'./algorithmCategories'
import
AbstractAst
from
'./abstractAstView
'
import
{
ModuleAlgorithm
,
ModuleCategory
,
ReportObj
,
CompilationResult
,
CompiledContractObj
,
CompiledContract
,
VisitFunction
,
AnalyzerModule
}
from
'./../../types'
import
{
getFunctionDefinitionName
,
helpers
,
getType
}
from
'./staticAnalysisCommon
'
import
{
ModuleAlgorithm
,
ModuleCategory
,
ReportObj
,
CompilationResult
,
CompiledContractObj
,
CompiledContract
,
VisitFunction
,
AnalyzerModule
,
FunctionDefinitionAstNode
}
from
'./../../types'
interface
VisitedContract
{
name
:
string
...
...
@@ -15,57 +15,71 @@ export default class gasCosts implements AnalyzerModule {
category
:
ModuleCategory
=
category
.
GAS
algorithm
:
ModuleAlgorithm
=
algorithm
.
EXACT
abstractAst
:
AbstractAst
=
new
AbstractAst
()
visit
:
VisitFunction
=
this
.
abstractAst
.
build_visit
((
node
:
any
)
=>
false
)
warningNodes
:
FunctionDefinitionAstNode
[]
=
[]
visit
(
node
:
FunctionDefinitionAstNode
):
void
{
if
(
node
.
nodeType
===
'FunctionDefinition'
&&
node
.
kind
!==
'constructor'
)
this
.
warningNodes
.
push
(
node
)
}
report
(
compilationResults
:
CompilationResult
):
ReportObj
[]
{
const
report
:
ReportObj
[]
=
[]
this
.
visitContracts
(
compilationResults
.
contracts
,
(
contract
:
VisitedContract
)
=>
{
if
(
!
contract
.
object
.
evm
.
gasEstimates
||
!
contract
.
object
.
evm
.
gasEstimates
.
external
)
{
return
const
methodsWithSignature
=
this
.
warningNodes
.
map
(
node
=>
{
return
{
name
:
node
.
name
,
src
:
node
.
src
,
signature
:
helpers
.
buildAbiSignature
(
getFunctionDefinitionName
(
node
),
node
.
parameters
.
parameters
.
map
(
node
=>
node
.
typeDescriptions
.
typeString
.
split
(
' '
)[
0
]))
}
const
fallback
:
string
=
contract
.
object
.
evm
.
gasEstimates
.
external
[
''
]
if
(
fallback
!==
undefined
)
{
if
(
fallback
===
null
||
parseInt
(
fallback
)
>=
2100
||
fallback
===
'infinite'
)
{
})
for
(
const
method
of
methodsWithSignature
)
{
for
(
const
contractName
in
compilationResults
.
contracts
[
'test.sol'
])
{
const
contract
=
compilationResults
.
contracts
[
'test.sol'
][
contractName
]
const
methodGas
:
any
=
this
.
checkMethodGas
(
contract
,
method
.
signature
)
if
(
methodGas
.
isInfinite
)
{
if
(
methodGas
.
isFallback
)
{
report
.
push
({
warning
:
`Fallback function of contract
${
contract
.
name
}
requires too much gas (
${
fallback
}
).
warning
:
`Fallback function of contract
${
contractName
}
requires too much gas (
${
methodGas
.
msg
}
).
If the fallback function requires more than 2300 gas, the contract cannot receive Ether.`
})
}
}
for
(
var
functionName
in
contract
.
object
.
evm
.
gasEstimates
.
external
)
{
if
(
functionName
===
''
)
{
continue
}
const
gas
:
string
=
contract
.
object
.
evm
.
gasEstimates
.
external
[
functionName
]
const
gasString
:
string
=
gas
===
null
?
'unknown or not constant'
:
'high: '
+
gas
if
(
gas
===
null
||
parseInt
(
gas
)
>=
3000000
||
gas
===
'infinite'
)
{
}
else
{
report
.
push
({
warning
:
`Gas requirement of function
${
contract
.
name
}
.
${
functionName
}
${
gasStrin
g
}
.
warning
:
`Gas requirement of function
${
contractName
}
.
${
method
.
name
}
${
methodGas
.
ms
g
}
.
If the gas requirement of a function is higher than the block gas limit, it cannot be executed.
Please avoid loops in your functions or actions that modify large areas of storage
(this includes clearing or copying arrays in storage)`
})
}
}
})
}
}
return
report
}
/**
* call the given @arg cb (function) for all the contracts. Uses last compilation result
* stop visiting when cb return true
* @param {Function} cb - callback
*/
// @TODO has been copied from remix-ide repo ! should fix that soon !
private
visitContracts
(
contracts
:
CompiledContractObj
|
undefined
,
cb
:
((
contract
:
VisitedContract
)
=>
void
|
undefined
)):
void
{
for
(
let
file
in
contracts
)
{
for
(
let
name
in
contracts
[
file
])
{
if
(
cb
({
name
:
name
,
object
:
contracts
[
file
][
name
],
file
:
file
}))
return
private
checkMethodGas
(
contract
:
any
,
methodSignature
:
string
)
{
if
(
methodSignature
===
'()'
)
{
const
fallback
:
string
=
contract
.
evm
.
gasEstimates
.
external
[
''
]
if
(
fallback
!==
undefined
&&
(
fallback
===
null
||
parseInt
(
fallback
)
>=
2100
||
fallback
===
'infinite'
))
{
return
{
isInfinite
:
true
,
isFallback
:
true
,
msg
:
fallback
}
}
else
{
return
{
isInfinite
:
false
}
}
}
else
{
const
gas
:
string
=
contract
.
evm
.
gasEstimates
.
external
[
methodSignature
]
const
gasString
:
string
=
gas
===
null
?
'unknown or not constant'
:
'high: '
+
gas
if
(
gas
===
null
||
parseInt
(
gas
)
>=
3000000
||
gas
===
'infinite'
)
{
return
{
isInfinite
:
true
,
msg
:
gasString
}
}
else
{
return
{
isInfinite
:
false
}
}
}
}
...
...
remix-analyzer/src/types.ts
View file @
3d7c17ec
...
...
@@ -51,7 +51,7 @@ export interface CompilationResult {
[
contractName
:
string
]:
CompilationSource
}
/** This contains the contract-level outputs. It can be limited/filtered by the outputSelection settings */
contracts
?
:
CompiledContractObj
/** If the language used has no contract names, this field should equal to an empty string. */
contracts
:
CompiledContractObj
/** If the language used has no contract names, this field should equal to an empty string. */
}
export
interface
CompiledContractObj
{
...
...
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