Merge pull request #519 from crytic/dev-0.7-from-dev

Synchronize dev-0.7 with dev
dev-0.7
Feist Josselin 4 years ago committed by GitHub
commit 29e5170852
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      README.md
  2. 2
      slither/printers/guidance/echidna.py
  3. 34
      slither/solc_parsing/declarations/function.py

@ -12,6 +12,8 @@ Slither is a Solidity static analysis framework written in Python 3. It runs a s
- [Printers](#printers)
- [Tools](#tools)
- [How to Install](#how-to-install)
- [Getting Help](#getting-help)
- [Publications](#publications)
## Features
@ -178,7 +180,15 @@ Feel free to stop by our [Slack channel](https://empireslacking.herokuapp.com) (
Slither is licensed and distributed under the AGPLv3 license. [Contact us](mailto:opensource@trailofbits.com) if you're looking for an exception to the terms.
## Publication
## Publications
### Trail of Bits publication
- [Slither: A Static Analysis Framework For Smart Contracts](https://arxiv.org/abs/1908.09878), Josselin Feist, Gustavo Grieco, Alex Groce - WETSEB '19
### External publications
- [ReJection: A AST-Based Reentrancy Vulnerability Detection Method](https://www.researchgate.net/publication/339354823_ReJection_A_AST-Based_Reentrancy_Vulnerability_Detection_Method), Rui Ma, Zefeng Jian, Guangyuan Chen, Ke Ma, Yujia Chen - CTCIS 19
- [MPro: Combining Static and Symbolic Analysis forScalable Testing of Smart Contract](https://arxiv.org/pdf/1911.00570.pdf), William Zhang, Sebastian Banescu, Leodardo Pasos, Steven Stewart, Vijay Ganesh - ISSRE 2019
- [ETHPLOIT: From Fuzzing to Efficient Exploit Generation against Smart Contracts](https://wcventure.github.io/FuzzingPaper/Paper/SANER20_ETHPLOIT.pdf), Qingzhao Zhang, Yizhuo Wang, Juanru Li, Siqi Ma - SANER 20
- [Verification of Ethereum Smart Contracts: A Model Checking Approach](http://www.ijmlc.org/vol10/977-AM0059.pdf), Tam Bang, Hoang H Nguyen, Dung Nguyen, Toan Trieu, Tho Quan - IJMLC 20
If you are using Slither on an academic work, consider applying to the [Crytic $10k Research Prize](https://blog.trailofbits.com/2019/11/13/announcing-the-crytic-10k-research-prize/).

@ -71,7 +71,7 @@ def _is_constant(f: Function) -> bool:
"""
Heuristic:
- If view/pure with Solidity >= 0.4 -> Return true
- If it contains assembly -> Return false (Slither doesn't analyze asm)
- If it contains assembly -> Return false (SlitherCore doesn't analyze asm)
- Otherwise check for the rules from
https://solidity.readthedocs.io/en/v0.5.0/contracts.html?highlight=pure#view-functions
with an exception: internal dynamic call are not correctly handled, so we consider them as non-constant

@ -1051,7 +1051,7 @@ class FunctionSolc:
node_parser.add_unparsed_expression(modifier)
# The latest entry point is the entry point, or the latest modifier call
if self._function.modifiers:
latest_entry_point = self._function.modifiers[-1].nodes[-1]
latest_entry_point = self._function.modifiers_statements[-1].nodes[-1]
else:
latest_entry_point = self._function.entry_point
insert_node(latest_entry_point, node_parser.underlying_node)
@ -1132,6 +1132,9 @@ class FunctionSolc:
node.set_sons([])
to_remove.append(node)
self._function.nodes = [n for n in self._function.nodes if n not in to_remove]
for remove in to_remove:
if remove in self._node_to_nodesolc:
del self._node_to_nodesolc[remove]
# endregion
###################################################################################
@ -1176,23 +1179,23 @@ class FunctionSolc:
if node.type == NodeType.VARIABLE:
condition_node.underlying_node.add_variable_declaration(node.variable_declaration)
true_node = self._new_node(NodeType.EXPRESSION, node.source_mapping)
true_node_parser = self._new_node(NodeType.EXPRESSION, node.source_mapping)
if node.type == NodeType.VARIABLE:
assert isinstance(true_expr, AssignmentOperation)
# true_expr = true_expr.expression_right
elif node.type == NodeType.RETURN:
true_node.type = NodeType.RETURN
true_node.underlying_node.add_expression(true_expr)
true_node.analyze_expressions(self)
true_node_parser.underlying_node.type = NodeType.RETURN
true_node_parser.underlying_node.add_expression(true_expr)
true_node_parser.analyze_expressions(self)
false_node = self._new_node(NodeType.EXPRESSION, node.source_mapping)
false_node_parser = self._new_node(NodeType.EXPRESSION, node.source_mapping)
if node.type == NodeType.VARIABLE:
assert isinstance(false_expr, AssignmentOperation)
elif node.type == NodeType.RETURN:
false_node.type = NodeType.RETURN
false_node_parser.underlying_node.type = NodeType.RETURN
# false_expr = false_expr.expression_right
false_node.underlying_node.add_expression(false_expr)
false_node.analyze_expressions(self)
false_node_parser.underlying_node.add_expression(false_expr)
false_node_parser.analyze_expressions(self)
endif_node = self._new_node(NodeType.ENDIF, node.source_mapping)
@ -1206,14 +1209,15 @@ class FunctionSolc:
son.add_father(endif_node.underlying_node)
endif_node.underlying_node.add_son(son)
link_underlying_nodes(condition_node, true_node)
link_underlying_nodes(condition_node, false_node)
link_underlying_nodes(condition_node, true_node_parser)
link_underlying_nodes(condition_node, false_node_parser)
if true_node.type not in [NodeType.THROW, NodeType.RETURN]:
link_underlying_nodes(true_node, endif_node)
if false_node.type not in [NodeType.THROW, NodeType.RETURN]:
link_underlying_nodes(false_node, endif_node)
if true_node_parser.underlying_node.type not in [NodeType.THROW, NodeType.RETURN]:
link_underlying_nodes(true_node_parser, endif_node)
if false_node_parser.underlying_node.type not in [NodeType.THROW, NodeType.RETURN]:
link_underlying_nodes(false_node_parser, endif_node)
self._function.nodes = [n for n in self._function.nodes if n.node_id != node.node_id]
del self._node_to_nodesolc[node]
# endregion

Loading…
Cancel
Save