Merge branch 'develop' into refactor/cli

pull/1033/head
Nathan 6 years ago committed by GitHub
commit 4b704766ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 60
      .circleci/config.yml
  2. 2
      Dockerfile
  3. 19
      Pipfile
  4. 19
      README.md
  5. 6
      docs/source/about.rst
  6. 2
      docs/source/analysis-modules.rst
  7. 28
      docs/source/conf.py
  8. 2
      docs/source/create-module.rst
  9. 2
      docs/source/index.rst
  10. 25
      docs/source/module-list.rst
  11. 2
      docs/source/security-analysis.rst
  12. 2
      mythril/__init__.py
  13. 2
      mythril/__version__.py
  14. 16
      mythril/analysis/modules/base.py
  15. 153
      mythril/analysis/modules/delegatecall.py
  16. 272
      mythril/analysis/modules/dependence_on_predictable_vars.py
  17. 3
      mythril/analysis/modules/deprecated_ops.py
  18. 127
      mythril/analysis/modules/dos.py
  19. 26
      mythril/analysis/modules/ether_thief.py
  20. 8
      mythril/analysis/modules/exceptions.py
  21. 19
      mythril/analysis/modules/external_calls.py
  22. 197
      mythril/analysis/modules/integer.py
  23. 40
      mythril/analysis/modules/multiple_sends.py
  24. 3
      mythril/analysis/modules/state_change_external_calls.py
  25. 21
      mythril/analysis/modules/suicide.py
  26. 3
      mythril/analysis/modules/unchecked_retval.py
  27. 44
      mythril/analysis/report.py
  28. 6
      mythril/analysis/security.py
  29. 132
      mythril/analysis/solver.py
  30. 50
      mythril/analysis/symbolic.py
  31. 4
      mythril/analysis/templates/report_as_markdown.jinja2
  32. 4
      mythril/analysis/templates/report_as_text.jinja2
  33. 22
      mythril/interfaces/cli.py
  34. 2
      mythril/laser/ethereum/call.py
  35. 60
      mythril/laser/ethereum/instructions.py
  36. 330
      mythril/laser/ethereum/plugins/implementations/dependency_pruner.py
  37. 9
      mythril/laser/ethereum/plugins/plugin_factory.py
  38. 10
      mythril/laser/ethereum/plugins/signals.py
  39. 12
      mythril/laser/ethereum/state/account.py
  40. 1
      mythril/laser/ethereum/state/environment.py
  41. 11
      mythril/laser/ethereum/state/machine_state.py
  42. 2
      mythril/laser/ethereum/state/memory.py
  43. 0
      mythril/laser/ethereum/strategy/extensions/__init__.py
  44. 84
      mythril/laser/ethereum/strategy/extensions/bounded_loops.py
  45. 34
      mythril/laser/ethereum/svm.py
  46. 2
      mythril/laser/ethereum/transaction/concolic.py
  47. 15
      mythril/laser/ethereum/transaction/symbolic.py
  48. 36
      mythril/laser/ethereum/transaction/transaction_models.py
  49. 7
      mythril/laser/smt/bitvec.py
  50. 11
      mythril/mythril/mythril_analyzer.py
  51. 4
      requirements.txt
  52. 138
      setup.py
  53. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/BlockNumberDynamicJump0_AfterJumpdest.json
  54. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/BlockNumberDynamicJump0_AfterJumpdest3.json
  55. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/BlockNumberDynamicJump0_foreverOutOfGas.json
  56. 52
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/BlockNumberDynamicJump0_jumpdest0.json
  57. 52
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/BlockNumberDynamicJump0_jumpdest2.json
  58. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/BlockNumberDynamicJump0_withoutJumpdest.json
  59. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/BlockNumberDynamicJump1.json
  60. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/BlockNumberDynamicJumpInsidePushWithJumpDest.json
  61. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/BlockNumberDynamicJumpInsidePushWithoutJumpDest.json
  62. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/BlockNumberDynamicJumpi0.json
  63. 52
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/BlockNumberDynamicJumpi1.json
  64. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/BlockNumberDynamicJumpi1_jumpdest.json
  65. 52
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/BlockNumberDynamicJumpiAfterStop.json
  66. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/BlockNumberDynamicJumpiOutsideBoundary.json
  67. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/BlockNumberDynamicJumpifInsidePushWithJumpDest.json
  68. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/BlockNumberDynamicJumpifInsidePushWithoutJumpDest.json
  69. 38
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DyanmicJump0_outOfBoundary.json
  70. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJump0_AfterJumpdest.json
  71. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJump0_AfterJumpdest3.json
  72. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJump0_foreverOutOfGas.json
  73. 52
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJump0_jumpdest0.json
  74. 52
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJump0_jumpdest2.json
  75. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJump0_withoutJumpdest.json
  76. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJump1.json
  77. 52
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJumpAfterStop.json
  78. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJumpInsidePushWithJumpDest.json
  79. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJumpInsidePushWithoutJumpDest.json
  80. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJumpJD_DependsOnJumps0.json
  81. 52
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJumpJD_DependsOnJumps1.json
  82. 52
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJumpPathologicalTest0.json
  83. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJumpPathologicalTest1.json
  84. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJumpPathologicalTest2.json
  85. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJumpPathologicalTest3.json
  86. 52
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJumpStartWithJumpDest.json
  87. 51
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJump_value1.json
  88. 51
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJump_value2.json
  89. 51
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJump_value3.json
  90. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJump_valueUnderflow.json
  91. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJumpi0.json
  92. 52
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJumpi1.json
  93. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJumpi1_jumpdest.json
  94. 52
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJumpiAfterStop.json
  95. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJumpiOutsideBoundary.json
  96. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJumpifInsidePushWithJumpDest.json
  97. 37
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/DynamicJumpifInsidePushWithoutJumpDest.json
  98. 38
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/JDfromStorageDynamicJump0_AfterJumpdest.json
  99. 38
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/JDfromStorageDynamicJump0_AfterJumpdest3.json
  100. 38
      tests/laser/evm_testsuite/VMTests/vmIOandFlowOperations/JDfromStorageDynamicJump0_foreverOutOfGas.json
  101. Some files were not shown because too many files have changed in this diff Show More

@ -78,44 +78,42 @@ jobs:
# command: if [ -z "$CIRCLE_PR_NUMBER" ]; then ./run-integration-tests.sh; fi # command: if [ -z "$CIRCLE_PR_NUMBER" ]; then ./run-integration-tests.sh; fi
# working_directory: /home # working_directory: /home
- run:
name: Call webhook
command: |
curl -I -X POST -H -d "https://circleci.com/api/v1/project/${ORGANIZATION}/${WEBHOOK_PROJECT}/tree/master?circle-token=${CIRCLE_TOKEN}" | head -n 1 | cut -d$' ' -f2
integration_tests: integration_tests:
docker: docker:
- image: mythril/mythx-ci - image: circleci/python:3.6.4
working_directory: /home working_directory: ~/project
steps: steps:
- checkout: - checkout
path: /home/mythril-classic - setup_remote_docker
- run: - run:
name: Builds `mythril-classic` name: Clone Edelweiss
command: cd mythril-classic && python3 setup.py install command: git clone --recurse-submodules https://$GITHUB_TOKEN@github.com/Consensys/Edelweiss.git
- run: - run:
name: Installs other MythX components name: Update SWC-registry
command: | working_directory: ~/project/Edelweiss
./install-mythx-components.sh pythx edelweiss harvey-cli \ command: git submodule update --recursive --remote
harvey-tyro maestro maru maru-tyro mythril-api \
mythril-tyro tyro
- run: - run:
background: true name: Build Edelweiss
name: Launches MythX platform command: |
command: ./launch-mythx.sh docker build \
- run: --build-arg AWS_ACCESS_KEY_ID=$S3_AWS_ACCESS_KEY_ID \
name: Waits for MythX to spin-up --build-arg AWS_SECRET_ACCESS_KEY=$S3_AWS_SECRET_ACCESS_KEY \
command: sleep 15s --build-arg AWS_DEFAULT_REGION=us-east-1 --rm -t "edelweiss-mythril:latest" . -f Edelweiss/dockerfiles/mythril/Dockerfile
- run: - run:
name: Quick Edelweiss test name: Run Edelweiss
command: /home/run-edelweiss-test.sh CircleCI/latest.quick.csv 5 command: |
docker run \
# TODO: Temporary disabled -e CIRCLE_BUILD_NUM=$CIRCLE_BUILD_NUM \
# - run: -e CIRCLE_BUILD_URL=$CIRCLE_BUILD_URL \
# name: Full Edelweiss test -e CIRCLE_WEBHOOK_URL=$CIRCLE_WEBHOOK_URL \
# environment: --rm edelweiss-mythril:latest \
# MYTHX_API_FULL_MODE: true --timeout 30 \
# command: /home/run-edelweiss-test.sh CircleCI/latest.full.csv --output-dir /opt/edelweiss \
--plugin-dir /opt/mythril \
--s3 \
--circle-ci CircleCI/mythril.csv \
--ignore-false-positives $IGNORE_FALSE_POSITIVES \
--ignore-regressions $IGNORE_REGRESSIONS
pypi_release: pypi_release:
<<: *defaults <<: *defaults

@ -39,8 +39,6 @@ COPY . /opt/mythril
RUN cd /opt/mythril \ RUN cd /opt/mythril \
&& python setup.py install && python setup.py install
RUN useradd -m mythril
USER mythril
WORKDIR /home/mythril WORKDIR /home/mythril
RUN ( [ ! -z "${SOLC}" ] && set -e && for ver in $SOLC; do python -m solc.install v${ver}; done ) || true RUN ( [ ! -z "${SOLC}" ] && set -e && for ver in $SOLC; do python -m solc.install v${ver}; done ) || true

@ -1,19 +0,0 @@
[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true
name = "pypi"
[packages]
"e1839a8" = {path = ".", editable = true}
[dev-packages]
pylint = "*"
yapf = "*"
pytest = "*"
pytest-mock = "*"
pytest-cov = "*"
[requires]
[pipenv]
allow_prereleases = true

@ -1,4 +1,4 @@
# Mythril Classic # Mythril
<p align="center"> <p align="center">
<img src="/static/mythril_new.png" height="320px"/> <img src="/static/mythril_new.png" height="320px"/>
@ -7,17 +7,14 @@
[![Discord](https://img.shields.io/discord/481002907366588416.svg)](https://discord.gg/E3YrVtG) [![Discord](https://img.shields.io/discord/481002907366588416.svg)](https://discord.gg/E3YrVtG)
[![PyPI](https://badge.fury.io/py/mythril.svg)](https://pypi.python.org/pypi/mythril) [![PyPI](https://badge.fury.io/py/mythril.svg)](https://pypi.python.org/pypi/mythril)
[![Read the Docs](https://readthedocs.org/projects/mythril-classic/badge/?version=master)](https://mythril-classic.readthedocs.io/en/master/) [![Read the Docs](https://readthedocs.org/projects/mythril-classic/badge/?version=master)](https://mythril-classic.readthedocs.io/en/master/)
![Master Build Status](https://img.shields.io/circleci/project/github/ConsenSys/mythril-classic/master.svg) ![Master Build Status](https://img.shields.io/circleci/build/github/ConsenSys/mythril.svg?token=97124ecfaee54366859cae98b5dafc0714325f8b)
[![Waffle.io - Columns and their card count](https://badge.waffle.io/ConsenSys/mythril-classic.svg?columns=In%20Progress)](https://waffle.io/ConsenSys/mythril-classic/)
[![Sonarcloud - Maintainability](https://sonarcloud.io/api/project_badges/measure?project=mythril&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=mythril) [![Sonarcloud - Maintainability](https://sonarcloud.io/api/project_badges/measure?project=mythril&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=mythril)
[![Downloads](https://pepy.tech/badge/mythril)](https://pepy.tech/project/mythril) [![Pypi Installs](https://pepy.tech/badge/mythril)](https://pepy.tech/project/mythril)
[![DockerHub Pulls](https://img.shields.io/docker/pulls/mythril/myth.svg?label=DockerHub&nbsp;Pulls)](https://cloud.docker.com/u/mythril/repository/docker/mythril/myth)
Mythril Classic is an open-source security analysis tool for Ethereum smart contracts. It uses symbolic analysis, taint analysis and control flow checking to detect a variety of security vulnerabilities. Mythril is a security analysis tool for EVM bytecode. It detects security vulnerabilities in smart contracts built for Ethereum, Quorum, Vechain, Roostock, Tron and other EVM-compatible blockchains. It uses symbolic execution, SMT solving and taint analysis detect a variety of security vulnerabilities. It's also used (in combination with other tools and techniques) in the [MythX](https://mythx.io) security analysis platform.
Note that Mythril Classic is designed for security auditors. If you are a smart contract developer, we recommend using [MythX tools](https://github.com/b-mueller/awesome-mythx-smart-contract-security) which are optimized for usability and cover a wider range of security issues: If you are a smart contract developer, we recommend using [MythX tools](https://github.com/b-mueller/awesome-mythx-smart-contract-security) which are optimized for usability and cover a wider range of security issues.
- [Sabre](https://github.com/b-mueller/sabre)
- [MythX Plugin for Truffle](https://github.com/ConsenSys/truffle-security)
Whether you want to contribute, need support, or want to learn what we have cooking for the future, our [Discord server](https://discord.gg/E3YrVtG) will serve your needs. Whether you want to contribute, need support, or want to learn what we have cooking for the future, our [Discord server](https://discord.gg/E3YrVtG) will serve your needs.
@ -39,12 +36,12 @@ See the [Wiki](https://github.com/ConsenSys/mythril/wiki/Installation-and-Setup)
## Usage ## Usage
Instructions for using Mythril Classic are found on the [Wiki](https://github.com/ConsenSys/mythril-classic/wiki). Instructions for using Mythril are found on the [Wiki](https://github.com/ConsenSys/mythril/wiki).
For support or general discussions please join the Mythril community on [Discord](https://discord.gg/E3YrVtG). For support or general discussions please join the Mythril community on [Discord](https://discord.gg/E3YrVtG).
## Bulding the Documentation ## Bulding the Documentation
Mythril Classic's documentation is contained in the `docs` folder and is published to [Read the Docs](https://mythril-classic.readthedocs.io/en/master/). It is based on Sphinx and can be built using the Makefile contained in the subdirectory: Mythril's documentation is contained in the `docs` folder and is published to [Read the Docs](https://mythril-classic.readthedocs.io/en/master/). It is based on Sphinx and can be built using the Makefile contained in the subdirectory:
``` ```
cd docs cd docs

@ -1,6 +1,6 @@
What is Mythril Classic? What is Mythril?
======================== ========================
Mythril Classic is a security analysis tool for Ethereum smart contracts. It was `introduced at HITBSecConf 2018 <https://github.com/b-mueller/smashing-smart-contracts/blob/master/smashing-smart-contracts-1of1.pdf>`_. Mythril is a security analysis tool for Ethereum smart contracts. It was `introduced at HITBSecConf 2018 <https://github.com/b-mueller/smashing-smart-contracts/blob/master/smashing-smart-contracts-1of1.pdf>`_.
Mythril Classic detects a range of security issues, including integer underflows, owner-overwrite-to-Ether-withdrawal, and others. Note that Mythril is targeted at finding common vulnerabilities, and is not able to discover issues in the business logic of an application. Furthermore, Mythril and symbolic executors are generally unsound, as they are often unable to explore all possible states of a program. Mythril detects a range of security issues, including integer underflows, owner-overwrite-to-Ether-withdrawal, and others. Note that Mythril is targeted at finding common vulnerabilities, and is not able to discover issues in the business logic of an application. Furthermore, Mythril and symbolic executors are generally unsound, as they are often unable to explore all possible states of a program.

@ -1,7 +1,7 @@
Analysis Modules Analysis Modules
================ ================
Mythril Classic's detection capabilities are written in modules in the `/analysis/modules <https://github.com/ConsenSys/mythril-classic/tree/master/mythril/analysis/modules>`_ directory. Mythril's detection capabilities are written in modules in the `/analysis/modules <https://github.com/ConsenSys/mythril/tree/master/mythril/analysis/modules>`_ directory.
.. toctree:: .. toctree::

@ -20,14 +20,14 @@ sys.path.insert(0, os.path.abspath("../../"))
# -- Project information ----------------------------------------------------- # -- Project information -----------------------------------------------------
project = "Mythril Classic" project = "Mythril"
copyright = "2018, Bernhard Mueller" copyright = "2019, ConsenSys Diligence"
author = "Bernhard Mueller" author = "ConsenSys Dilligence"
# The short X.Y version # The short X.Y version
version = "" version = ""
# The full version, including alpha/beta/rc tags # The full version, including alpha/beta/rc tags
from mythril.version import VERSION from mythril.__version__ import __version__ as VERSION
release = VERSION release = VERSION
@ -108,7 +108,7 @@ html_static_path = ["_static"]
# -- Options for HTMLHelp output --------------------------------------------- # -- Options for HTMLHelp output ---------------------------------------------
# Output file base name for HTML help builder. # Output file base name for HTML help builder.
htmlhelp_basename = "MythrilClassicdoc" htmlhelp_basename = "Mythrildoc"
# -- Options for LaTeX output ------------------------------------------------ # -- Options for LaTeX output ------------------------------------------------
@ -132,13 +132,7 @@ latex_elements = {
# (source start file, target name, title, # (source start file, target name, title,
# author, documentclass [howto, manual, or own class]). # author, documentclass [howto, manual, or own class]).
latex_documents = [ latex_documents = [
( (master_doc, "Mythril.tex", "Mythril Documentation", "Bernhard Mueller", "manual")
master_doc,
"MythrilClassic.tex",
"Mythril Classic Documentation",
"Bernhard Mueller",
"manual",
)
] ]
@ -146,9 +140,7 @@ latex_documents = [
# One entry per manual page. List of tuples # One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section). # (source start file, name, description, authors, manual section).
man_pages = [ man_pages = [(master_doc, "mythril", "Mythril Documentation", [author], 1)]
(master_doc, "mythrilclassic", "Mythril Classic Documentation", [author], 1)
]
# -- Options for Texinfo output ---------------------------------------------- # -- Options for Texinfo output ----------------------------------------------
@ -159,10 +151,10 @@ man_pages = [
texinfo_documents = [ texinfo_documents = [
( (
master_doc, master_doc,
"MythrilClassic", "Mythril",
"Mythril Classic Documentation", "Mythril Documentation",
author, author,
"MythrilClassic", "Mythril",
"One line description of project.", "One line description of project.",
"Miscellaneous", "Miscellaneous",
) )

@ -1,4 +1,4 @@
Creating a Module Creating a Module
================= =================
Create a module in the :code:`analysis/modules` directory, and create an instance of a class that inherits :code:`DetectionModule` named :code:`detector`. Take a look at the `suicide module <https://github.com/ConsenSys/mythril-classic/blob/develop/mythril/analysis/modules/suicide.py>`_ as an example. Create a module in the :code:`analysis/modules` directory, and create an instance of a class that inherits :code:`DetectionModule` named :code:`detector`. Take a look at the `suicide module <https://github.com/ConsenSys/mythril/blob/develop/mythril/analysis/modules/suicide.py>`_ as an example.

@ -1,4 +1,4 @@
Welcome to Mythril Classic's documentation! Welcome to Mythril's documentation!
=========================================== ===========================================
.. toctree:: .. toctree::

@ -5,64 +5,65 @@ Modules
Delegate Call To Untrusted Contract Delegate Call To Untrusted Contract
*********************************** ***********************************
The `delegatecall module <https://github.com/ConsenSys/mythril-classic/blob/develop/mythril/analysis/modules/delegatecall.py>`_ detects `SWC-112 (DELEGATECALL to Untrusted Callee) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-112>`_. The `delegatecall module <https://github.com/ConsenSys/mythril/blob/develop/mythril/analysis/modules/delegatecall.py>`_ detects `SWC-112 (DELEGATECALL to Untrusted Callee) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-112>`_.
*********************************** ***********************************
Dependence on Predictable Variables Dependence on Predictable Variables
*********************************** ***********************************
The `predictable variables module <https://github.com/ConsenSys/mythril-classic/blob/develop/mythril/analysis/modules/dependence_on_predictable_vars.py>`_ detects `SWC-120 (Weak Randomness) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-120>`_ and `SWC-116 (Timestamp Dependence) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-116>`_. The `predictable variables module <https://github.com/ConsenSys/mythril/blob/develop/mythril/analysis/modules/dependence_on_predictable_vars.py>`_ detects `SWC-120 (Weak Randomness) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-120>`_ and `SWC-116 (Timestamp Dependence) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-116>`_.
****************** ******************
Deprecated Opcodes Deprecated Opcodes
****************** ******************
The `deprecated opcodes module <https://github.com/ConsenSys/mythril-classic/blob/develop/mythril/analysis/modules/deprecated_ops.py>`_ detects `SWC-111 (Use of Deprecated Functions) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-111>`_. The `deprecated opcodes module <https://github.com/ConsenSys/mythril/blob/develop/mythril/analysis/modules/deprecated_ops.py>`_ detects `SWC-111 (Use of Deprecated Functions) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-111>`_.
*********** ***********
Ether Thief Ether Thief
*********** ***********
The `Ether Thief module <https://github.com/ConsenSys/mythril-classic/blob/develop/mythril/analysis/modules/ether_thief.py>`_ detects `SWC-105 (Unprotected Ether Withdrawal) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-105>`_. The `Ether Thief module <https://github.com/ConsenSys/mythril/blob/develop/mythril/analysis/modules/ether_thief.py>`_ detects `SWC-105 (Unprotected Ether Withdrawal) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-105>`_.
********** **********
Exceptions Exceptions
********** **********
The `exceptions module <https://github.com/ConsenSys/mythril-classic/blob/develop/mythril/analysis/modules/exceptions.py>`_ detects `SWC-110 (Assert Violation) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-110>`_. The `exceptions module <https://github.com/ConsenSys/mythril/blob/develop/mythril/analysis/modules/exceptions.py>`_ detects `SWC-110 (Assert Violation) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-110>`_.
************** **************
External Calls External Calls
************** **************
The `external calls module <https://github.com/ConsenSys/mythril-classic/blob/develop/mythril/analysis/modules/external_calls.py>`_ detects `SWC-117 (Reentrancy) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-117>`_ by detecting state changes after calls to external contracts. The `external calls module <https://github.com/ConsenSys/mythril/blob/develop/mythril/analysis/modules/external_calls.py>`_ warns about `SWC-117 (Reentrancy) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-107>`_ by detecting calls to external contracts.
******* *******
Integer Integer
******* *******
The `integer module <https://github.com/ConsenSys/mythril-classic/blob/develop/mythril/analysis/modules/integer.py>`_ detects `SWC-101 (Integer Overflow and Underflow) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-101>`_. The `integer module <https://github.com/ConsenSys/mythril/blob/develop/mythril/analysis/modules/integer.py>`_ detects `SWC-101 (Integer Overflow and Underflow) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-101>`_.
************** **************
Multiple Sends Multiple Sends
************** **************
The `multiple sends module <https://github.com/ConsenSys/mythril-classic/blob/develop/mythril/analysis/modules/multiple_sends.py>`_ detects `SWC-113 (Denial of Service with Failed Call) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-113>`_ by checking for multiple calls or sends in a single transaction. The `multiple sends module <https://github.com/ConsenSys/mythril/blob/develop/mythril/analysis/modules/multiple_sends.py>`_ detects `SWC-113 (Denial of Service with Failed Call) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-113>`_ by checking for multiple calls or sends in a single transaction.
******* *******
Suicide Suicide
******* *******
The `suicide module <https://github.com/ConsenSys/mythril-classic/blob/develop/mythril/analysis/modules/suicide.py>`_ detects `SWC-106 (Unprotected SELFDESTRUCT) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-106>`_. The `suicide module <https://github.com/ConsenSys/mythril/blob/develop/mythril/analysis/modules/suicide.py>`_ detects `SWC-106 (Unprotected SELFDESTRUCT) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-106>`_.
**************************** ****************************
Transaction Order Dependence State Change External Calls
**************************** ****************************
The `transaction order dependence module <https://github.com/ConsenSys/mythril-classic/blob/develop/mythril/analysis/modules/transaction_order_dependence.py>`_ detects `SWC-114 (Transaction Order Dependence / Race Conditions) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-114>`_. The `state change external calls module <https://github.com/ConsenSys/mythril/blob/develop/mythril/analysis/modules/state_change_external_calls.py>`_ detects `SWC-107 (Reentrancy) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-107>`_ by detecting state change after calls to an external contract.
**************** ****************
Unchecked Retval Unchecked Retval
**************** ****************
The `unchecked retval module <https://github.com/ConsenSys/mythril-classic/blob/develop/mythril/analysis/modules/unchecked_retval.py>`_ detects `SWC-104 (Unchecked Call Return Value) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-104>`_. The `unchecked retval module <https://github.com/ConsenSys/mythril/blob/develop/mythril/analysis/modules/unchecked_retval.py>`_ detects `SWC-104 (Unchecked Call Return Value) <https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-104>`_.

@ -1,7 +1,7 @@
Security Analysis Security Analysis
================= =================
Run :code:`myth -x` with one of the input options described below will run the analysis modules in the `/analysis/modules <https://github.com/ConsenSys/mythril-classic/tree/master/mythril/analysis/modules>`_ directory. Run :code:`myth -x` with one of the input options described below will run the analysis modules in the `/analysis/modules <https://github.com/ConsenSys/mythril/tree/master/mythril/analysis/modules>`_ directory.
*********************** ***********************
Analyzing Solidity Code Analyzing Solidity Code

@ -3,4 +3,4 @@
__docformat__ = "restructuredtext" __docformat__ = "restructuredtext"
# Accept mythril.VERSION to get mythril's current version number # Accept mythril.VERSION to get mythril's current version number
from .version import VERSION # NOQA from .__version__ import __version__ as VERSION # NOQA

@ -4,4 +4,4 @@ This file is suitable for sourcing inside POSIX shell, e.g. bash as well
as for importing into Python. as for importing into Python.
""" """
VERSION = "v0.20.6" # NOQA __version__ = "v0.21.2"

@ -49,12 +49,26 @@ class DetectionModule:
""" """
self._issues = [] self._issues = []
def execute(self, statespace): def execute(self, statespace) -> None:
"""The entry point for execution, which is being called by Mythril. """The entry point for execution, which is being called by Mythril.
:param statespace: :param statespace:
:return: :return:
""" """
log.debug("Entering analysis module: {}".format(self.__class__.__name__))
self._execute(statespace)
log.debug("Exiting analysis module: {}".format(self.__class__.__name__))
def _execute(self, statespace):
"""Module main method (override this)
:param statespace:
:return:
"""
raise NotImplementedError() raise NotImplementedError()
def __repr__(self) -> str: def __repr__(self) -> str:

@ -1,19 +1,79 @@
"""This module contains the detection code for insecure delegate call usage.""" """This module contains the detection code for insecure delegate call usage."""
import re import json
import logging import logging
from typing import List from copy import copy
from typing import List, cast, Dict
from mythril.analysis import solver
from mythril.analysis.swc_data import DELEGATECALL_TO_UNTRUSTED_CONTRACT from mythril.analysis.swc_data import DELEGATECALL_TO_UNTRUSTED_CONTRACT
from mythril.analysis.ops import get_variable, VarType, Call, Variable from mythril.laser.ethereum.transaction.symbolic import ATTACKER_ADDRESS
from mythril.laser.ethereum.transaction.transaction_models import (
ContractCreationTransaction,
)
from mythril.analysis.report import Issue from mythril.analysis.report import Issue
from mythril.analysis.call_helpers import get_call_from_state
from mythril.analysis.modules.base import DetectionModule from mythril.analysis.modules.base import DetectionModule
from mythril.exceptions import UnsatError
from mythril.laser.ethereum.state.annotation import StateAnnotation
from mythril.laser.ethereum.state.global_state import GlobalState from mythril.laser.ethereum.state.global_state import GlobalState
from mythril.laser.smt import symbol_factory, UGT
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class DelegateCallAnnotation(StateAnnotation):
def __init__(self, call_state: GlobalState, constraints: List) -> None:
"""
Initialize DelegateCall Annotation
:param call_state: Call state
"""
self.call_state = call_state
self.constraints = constraints
self.return_value = call_state.new_bitvec(
"retval_{}".format(call_state.get_current_instruction()["address"]), 256
)
def _copy__(self):
return DelegateCallAnnotation(self.call_state, copy(self.constraints))
def get_issue(self, global_state: GlobalState, transaction_sequence: Dict) -> Issue:
"""
Returns Issue for the annotation
:param global_state: Global State
:param transaction_sequence: Transaction sequence
:return: Issue
"""
address = self.call_state.get_current_instruction()["address"]
logging.debug(
"[DELEGATECALL] Detected delegatecall to a user-supplied address : {}".format(
address
)
)
description_head = "The contract delegates execution to another contract with a user-supplied address."
description_tail = (
"The smart contract delegates execution to a user-supplied address. Note that callers "
"can execute arbitrary contracts and that the callee contract "
"can access the storage of the calling contract. "
)
return Issue(
contract=self.call_state.environment.active_account.contract_name,
function_name=self.call_state.environment.active_function_name,
address=address,
swc_id=DELEGATECALL_TO_UNTRUSTED_CONTRACT,
title="Delegatecall Proxy To User-Supplied Address",
bytecode=global_state.environment.code.bytecode,
severity="Medium",
description_head=description_head,
description_tail=description_tail,
transaction_sequence=transaction_sequence,
gas_used=(
global_state.mstate.min_gas_used,
global_state.mstate.max_gas_used,
),
)
class DelegateCallModule(DetectionModule): class DelegateCallModule(DetectionModule):
"""This module detects calldata being forwarded using DELEGATECALL.""" """This module detects calldata being forwarded using DELEGATECALL."""
@ -24,18 +84,16 @@ class DelegateCallModule(DetectionModule):
swc_id=DELEGATECALL_TO_UNTRUSTED_CONTRACT, swc_id=DELEGATECALL_TO_UNTRUSTED_CONTRACT,
description="Check for invocations of delegatecall(msg.data) in the fallback function.", description="Check for invocations of delegatecall(msg.data) in the fallback function.",
entrypoint="callback", entrypoint="callback",
pre_hooks=["DELEGATECALL"], pre_hooks=["DELEGATECALL", "RETURN", "STOP"],
) )
def execute(self, state: GlobalState) -> list: def _execute(self, state: GlobalState) -> None:
""" """
:param state: :param state:
:return: :return:
""" """
log.debug("Executing module: DELEGATE_CALL")
self._issues.extend(_analyze_states(state)) self._issues.extend(_analyze_states(state))
return self.issues
def _analyze_states(state: GlobalState) -> List[Issue]: def _analyze_states(state: GlobalState) -> List[Issue]:
@ -43,59 +101,50 @@ def _analyze_states(state: GlobalState) -> List[Issue]:
:param state: the current state :param state: the current state
:return: returns the issues for that corresponding state :return: returns the issues for that corresponding state
""" """
call = get_call_from_state(state) issues = []
if call is None: op_code = state.get_current_instruction()["opcode"]
return [] annotations = cast(
issues = [] # type: List[Issue] List[DelegateCallAnnotation],
list(state.get_annotations(DelegateCallAnnotation)),
)
if call.type is not "DELEGATECALL": if len(annotations) == 0 and op_code in ("RETURN", "STOP"):
return []
if state.environment.active_function_name is not "fallback":
return [] return []
state = call.state if op_code == "DELEGATECALL":
address = state.get_current_instruction()["address"] gas = state.mstate.stack[-1]
meminstart = get_variable(state.mstate.stack[-3]) to = state.mstate.stack[-2]
if meminstart.type == VarType.CONCRETE: constraints = [
issues += _concrete_call(call, state, address, meminstart) to == ATTACKER_ADDRESS,
UGT(gas, symbol_factory.BitVecVal(2300, 256)),
]
return issues for tx in state.world_state.transaction_sequence:
if not isinstance(tx, ContractCreationTransaction):
constraints.append(tx.caller == ATTACKER_ADDRESS)
state.annotate(DelegateCallAnnotation(state, constraints))
def _concrete_call(
call: Call, state: GlobalState, address: int, meminstart: Variable
) -> List[Issue]:
"""
:param call: The current call's information
:param state: The current state
:param address: The PC address
:param meminstart: memory starting position
:return: issues
"""
if not re.search(r"calldata.*\[0", str(state.mstate.memory[meminstart.val])):
return [] return []
else:
issue = Issue( for annotation in annotations:
contract=state.environment.active_account.contract_name, try:
function_name=state.environment.active_function_name, transaction_sequence = solver.get_transaction_sequence(
address=address, state,
swc_id=DELEGATECALL_TO_UNTRUSTED_CONTRACT, state.mstate.constraints
bytecode=state.environment.code.bytecode, + annotation.constraints
title="Delegatecall Proxy", + [annotation.return_value == 1],
severity="Low",
description_head="The contract implements a delegatecall proxy.",
description_tail="The smart contract forwards the received calldata via delegatecall. Note that callers "
"can execute arbitrary functions in the callee contract and that the callee contract "
"can access the storage of the calling contract. "
"Make sure that the callee contract is audited properly.",
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used),
) )
issues.append(
annotation.get_issue(
state, transaction_sequence=transaction_sequence
)
)
except UnsatError:
continue
target = hex(call.to.val) if call.to.type == VarType.CONCRETE else str(call.to) return issues
issue.description += "DELEGATECALL target: {}".format(target)
return [issue]
detector = DelegateCallModule() detector = DelegateCallModule()

@ -1,22 +1,53 @@
"""This module contains the detection code for predictable variable """This module contains the detection code for predictable variable
dependence.""" dependence."""
import logging import logging
import re
from mythril.analysis import solver
from mythril.analysis.call_helpers import get_call_from_state
from mythril.analysis.modules.base import DetectionModule from mythril.analysis.modules.base import DetectionModule
from mythril.analysis.ops import Call, VarType
from mythril.analysis.report import Issue from mythril.analysis.report import Issue
from mythril.analysis.swc_data import TIMESTAMP_DEPENDENCE, WEAK_RANDOMNESS
from mythril.exceptions import UnsatError from mythril.exceptions import UnsatError
from mythril.analysis import solver
from mythril.laser.smt import ULT, symbol_factory
from mythril.analysis.swc_data import TIMESTAMP_DEPENDENCE, WEAK_RANDOMNESS
from mythril.laser.ethereum.state.global_state import GlobalState from mythril.laser.ethereum.state.global_state import GlobalState
from mythril.laser.ethereum.state.annotation import StateAnnotation
from typing import cast, List
import traceback
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
predictable_ops = ["COINBASE", "GASLIMIT", "TIMESTAMP", "NUMBER"]
final_ops = ["CALL", "SUICIDE", "STOP", "RETURN"]
def is_prehook() -> bool:
"""Check if we are in prehook. One of Bernhard's trademark hacks!"""
return "pre_hook" in traceback.format_stack()[-5]
class PredictableValueAnnotation:
"""Symbol annotation used if a variable is initialized from a predictable environment variable."""
def __init__(self, operation: str) -> None:
self.operation = operation
class PredictablePathAnnotation(StateAnnotation):
"""State annotation used when a path is chosen based on a predictable variable."""
def __init__(self, operation: str, location: int) -> None:
self.operation = operation
self.location = location
class OldBlockNumberUsedAnnotation(StateAnnotation):
"""State annotation set in blockhash prehook if the input value is lower than the current block number."""
def __init__(self) -> None:
pass
class PredictableDependenceModule(DetectionModule): class PredictableDependenceModule(DetectionModule):
"""This module detects whether Ether is sent using predictable """This module detects whether control flow decisions are made using predictable
parameters.""" parameters."""
def __init__(self) -> None: def __init__(self) -> None:
@ -25,26 +56,22 @@ class PredictableDependenceModule(DetectionModule):
name="Dependence of Predictable Variables", name="Dependence of Predictable Variables",
swc_id="{} {}".format(TIMESTAMP_DEPENDENCE, WEAK_RANDOMNESS), swc_id="{} {}".format(TIMESTAMP_DEPENDENCE, WEAK_RANDOMNESS),
description=( description=(
"Check for CALLs that send >0 Ether as a result of computation " "Check whether important control flow decisions are influenced by block.coinbase,"
"based on predictable variables such as block.coinbase, " "block.gaslimit, block.timestamp or block.number."
"block.gaslimit, block.timestamp, block.number"
), ),
entrypoint="callback", entrypoint="callback",
pre_hooks=["CALL", "CALLCODE", "DELEGATECALL", "STATICCALL"], pre_hooks=["BLOCKHASH", "JUMPI"] + final_ops,
post_hooks=["BLOCKHASH"] + predictable_ops,
) )
def execute(self, state: GlobalState) -> list: def _execute(self, state: GlobalState) -> None:
""" """
:param state: :param state:
:return: :return:
""" """
log.debug("Executing module: DEPENDENCE_ON_PREDICTABLE_VARS")
self._issues.extend(_analyze_states(state))
return self.issues
self._issues.extend(_analyze_states(state))
detector = PredictableDependenceModule()
def _analyze_states(state: GlobalState) -> list: def _analyze_states(state: GlobalState) -> list:
@ -53,172 +80,125 @@ def _analyze_states(state: GlobalState) -> list:
:param state: :param state:
:return: :return:
""" """
issues = [] issues = []
call = get_call_from_state(state)
if call is None:
return []
if "callvalue" in str(call.value):
log.debug("[DEPENDENCE_ON_PREDICTABLE_VARS] Skipping refund function")
return []
# We're only interested in calls that send Ether if is_prehook():
if call.value.type == VarType.CONCRETE and call.value.val == 0:
return [] opcode = state.get_current_instruction()["opcode"]
address = call.state.get_current_instruction()["address"] if opcode in final_ops:
for annotation in state.annotations:
if isinstance(annotation, PredictablePathAnnotation):
description = ( description = (
"The contract sends Ether depending on the values of the following variables:\n" "The "
+ annotation.operation
+ " is used in to determine a control flow decision. "
)
description += (
"Note that the values of variables like coinbase, gaslimit, block number and timestamp "
"are predictable and can be manipulated by a malicious miner. Also keep in mind that attackers "
"know hashes of earlier blocks. Don't use any of those environment variables for random number "
"generation or to make critical control flow decisions."
) )
# First check: look for predictable state variables in state & call recipient constraints """
Usually report low severity except in cases where the hash of a previous block is used to
vars = ["coinbase", "gaslimit", "timestamp", "number"] determine control flow.
found = [] """
for var in vars: severity = "Medium" if "hash" in annotation.operation else "Low"
for constraint in call.state.mstate.constraints[:] + [call.to]:
if var in str(constraint):
found.append(var)
if len(found): """
for item in found: Note: We report the location of the JUMPI that lead to this path. Usually this maps to an if or
description += "- block.{}\n".format(item) require statement.
if solve(call): """
swc_id = TIMESTAMP_DEPENDENCE if item == "timestamp" else WEAK_RANDOMNESS
description += ( swc_id = (
"Note that the values of variables like coinbase, gaslimit, block number and timestamp " TIMESTAMP_DEPENDENCE
"are predictable and/or can be manipulated by a malicious miner. " if "timestamp" in annotation.operation
"Don't use them for random number generation or to make critical decisions." else WEAK_RANDOMNESS
) )
issue = Issue( issue = Issue(
contract=state.environment.active_account.contract_name, contract=state.environment.active_account.contract_name,
function_name=state.environment.active_function_name, function_name=state.environment.active_function_name,
address=address, address=annotation.location,
swc_id=swc_id, swc_id=swc_id,
bytecode=call.state.environment.code.bytecode, bytecode=state.environment.code.bytecode,
title="Dependence on predictable environment variable", title="Dependence on predictable environment variable",
severity="Low", severity=severity,
description_head="Sending of Ether depends on a predictable variable.", description_head="A control flow decision is made based on a predictable variable.",
description_tail=description, description_tail=description,
gas_used=( gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used),
call.state.mstate.min_gas_used,
call.state.mstate.max_gas_used,
),
) )
issues.append(issue) issues.append(issue)
# Second check: blockhash elif opcode == "JUMPI":
for constraint in call.state.mstate.constraints[:] + [call.to]: # Look for predictable state variables in jump condition
if "blockhash" in str(constraint):
if "number" in str(constraint):
m = re.search(r"blockhash\w+(\s-\s(\d+))*", str(constraint))
if m and solve(call):
found_item = m.group(1) for annotation in state.mstate.stack[-2].annotations:
if found_item: # block.blockhash(block.number - N) if isinstance(annotation, PredictableValueAnnotation):
description = ( state.annotate(
"The predictable expression 'block.blockhash(block.number - " PredictablePathAnnotation(
+ m.group(2) annotation.operation,
+ ")' is used to determine Ether recipient" state.get_current_instruction()["address"],
) )
if int(m.group(2)) > 255:
description += (
", this expression will always be equal to zero."
) )
elif "storage" in str( break
constraint
): # block.blockhash(block.number - storage_0)
description = (
"The predictable expression 'block.blockhash(block.number - "
+ "some_storage_var)' is used to determine Ether recipient"
)
else: # block.blockhash(block.number)
description = (
"The predictable expression 'block.blockhash(block.number)'"
+ " is used to determine Ether recipient"
)
description += ", this expression will always be equal to zero."
issue = Issue( elif opcode == "BLOCKHASH":
contract=state.environment.active_account.contract_name,
function_name=state.environment.active_function_name, param = state.mstate.stack[-1]
address=address,
bytecode=call.state.environment.code.bytecode, try:
title="Dependence on Predictable Variable", constraint = [
severity="Low", ULT(param, state.environment.block_number),
description_head="Sending of Ether depends on the blockhash.", ULT(
description_tail=description, state.environment.block_number,
swc_id=WEAK_RANDOMNESS, symbol_factory.BitVecVal(2 ** 255, 256),
gas_used=(
call.state.mstate.min_gas_used,
call.state.mstate.max_gas_used,
), ),
) ]
issues.append(issue)
break # Why the second constraint? Because without it Z3 returns a solution where param overflows.
solver.get_model(constraint)
state.annotate(OldBlockNumberUsedAnnotation())
except UnsatError:
pass
else: else:
# we're in post hook
r = re.search(r"storage_([a-z0-9_&^]+)", str(constraint)) opcode = state.environment.code.instruction_list[state.mstate.pc - 1]["opcode"]
if r: # block.blockhash(storage_0)
"""We actually can do better here by adding a constraint if opcode == "BLOCKHASH":
blockhash_block_storage_0 == 0 and checking model # if we're in the post hook of a BLOCKHASH op, check if an old block number was used to create it.
satisfiability.
When this is done, severity can be raised from annotations = cast(
'Informational' to 'Warning'. Checking that storage List[OldBlockNumberUsedAnnotation],
at given index can be tainted is not necessary, list(state.get_annotations(OldBlockNumberUsedAnnotation)),
since it usually contains block.number of the )
'commit' transaction in commit-reveal workflow.
"""
index = r.group(1) if len(annotations):
if index and solve(call): state.mstate.stack[-1].annotate(
description = ( PredictableValueAnnotation("block hash of a previous block")
"A block hash is calculated using the block.blockhash(uint blockNumber) method. "
"The block number is obtained from storage index {}".format(
index
) )
else:
# Always create an annotation when COINBASE, GASLIMIT, TIMESTAMP or NUMBER is executed.
state.mstate.stack[-1].annotate(
PredictableValueAnnotation(
"block.{} environment variable".format(opcode.lower())
) )
issue = Issue(
contract=state.environment.active_account.contract_name,
function_name=state.environment.active_function_name,
address=address,
bytecode=call.state.environment.code.bytecode,
title="Dependence on Predictable Variable",
severity="Low",
description_head="Sending of Ether depends on the blockhash.",
description_tail=description,
swc_id=WEAK_RANDOMNESS,
gas_used=(
call.state.mstate.min_gas_used,
call.state.mstate.max_gas_used,
),
) )
issues.append(issue)
break
return issues
return issues
def solve(call: Call) -> bool:
"""
:param call:
:return:
"""
try:
model = solver.get_model(call.state.mstate.constraints)
log.debug("[DEPENDENCE_ON_PREDICTABLE_VARS] MODEL: " + str(model))
pretty_model = solver.pretty_print_model(model)
log.debug("[DEPENDENCE_ON_PREDICTABLE_VARS] main model: \n%s" % pretty_model)
return True
except UnsatError: detector = PredictableDependenceModule()
log.debug("[DEPENDENCE_ON_PREDICTABLE_VARS] no model found")
return False

@ -76,14 +76,13 @@ class DeprecatedOperationsModule(DetectionModule):
pre_hooks=["ORIGIN", "CALLCODE"], pre_hooks=["ORIGIN", "CALLCODE"],
) )
def execute(self, state: GlobalState): def _execute(self, state: GlobalState) -> None:
""" """
:param state: :param state:
:return: :return:
""" """
self._issues.extend(_analyze_state(state)) self._issues.extend(_analyze_state(state))
return self.issues
detector = DeprecatedOperationsModule() detector = DeprecatedOperationsModule()

@ -0,0 +1,127 @@
"""This module contains the detection code SWC-128 - DOS with block gas limit."""
import logging
from typing import Dict, cast, List
from mythril.analysis.swc_data import DOS_WITH_BLOCK_GAS_LIMIT
from mythril.analysis.report import Issue
from mythril.analysis.modules.base import DetectionModule
from mythril.laser.ethereum.state.global_state import GlobalState
from mythril.laser.ethereum.state.annotation import StateAnnotation
from mythril.laser.ethereum import util
log = logging.getLogger(__name__)
class LoopAnnotation(StateAnnotation):
def __init__(self, loop_start: int, loop_end: int) -> None:
self.loop_start = loop_start
self.loop_end = loop_end
def contains(self, address: int) -> bool:
return self.loop_start < address < self.loop_end
class DOS(DetectionModule):
"""This module consists of a makeshift loop detector that annotates the state with
a list of byte ranges likely to be loops. If a CALL or SSTORE detection is found in
one of the ranges it creates a low-severity issue. This is not super precise but
good enough to identify places that warrant a closer look. Checking the loop condition
would be a possible improvement.
"""
def __init__(self) -> None:
""""""
super().__init__(
name="DOS",
swc_id=DOS_WITH_BLOCK_GAS_LIMIT,
description="Check for DOS",
entrypoint="callback",
pre_hooks=["JUMPI", "CALL", "SSTORE"],
)
"""Keeps track of how often jump destinations are reached."""
self._jumpdest_count = {} # type: Dict[object, dict]
def _execute(self, state: GlobalState) -> None:
"""
:param state:
:return:
"""
self._issues.extend(self._analyze_states(state))
def _analyze_states(self, state: GlobalState) -> List[Issue]:
"""
:param state: the current state
:return: returns the issues for that corresponding state
"""
opcode = state.get_current_instruction()["opcode"]
address = state.get_current_instruction()["address"]
if opcode == "JUMPI":
target = util.get_concrete_int(state.mstate.stack[-1])
transaction = state.current_transaction
if state.current_transaction in self._jumpdest_count:
try:
self._jumpdest_count[transaction][target] += 1
if self._jumpdest_count[transaction][target] == 3:
annotation = (
LoopAnnotation(address, target)
if target > address
else LoopAnnotation(target, address)
)
state.annotate(annotation)
except KeyError:
self._jumpdest_count[transaction][target] = 0
else:
self._jumpdest_count[transaction] = {}
self._jumpdest_count[transaction][target] = 0
else:
annotations = cast(
List[LoopAnnotation], list(state.get_annotations(LoopAnnotation))
)
for annotation in annotations:
if annotation.contains(address):
operation = (
"A storage modification"
if opcode == "SSTORE"
else "An external call"
)
description_head = (
"Potential denial-of-service if block gas limit is reached."
)
description_tail = "{} is executed in a loop.".format(operation)
issue = Issue(
contract=state.environment.active_account.contract_name,
function_name=state.environment.active_function_name,
address=annotation.loop_start,
swc_id=DOS_WITH_BLOCK_GAS_LIMIT,
bytecode=state.environment.code.bytecode,
title="Potential denial-of-service if block gas limit is reached",
severity="Low",
description_head=description_head,
description_tail=description_tail,
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used),
)
return [issue]
return []
detector = DOS()

@ -7,6 +7,10 @@ from copy import copy
from mythril.analysis import solver from mythril.analysis import solver
from mythril.analysis.modules.base import DetectionModule from mythril.analysis.modules.base import DetectionModule
from mythril.analysis.report import Issue from mythril.analysis.report import Issue
from mythril.laser.ethereum.transaction.symbolic import ATTACKER_ADDRESS
from mythril.laser.ethereum.transaction.transaction_models import (
ContractCreationTransaction,
)
from mythril.analysis.swc_data import UNPROTECTED_ETHER_WITHDRAWAL from mythril.analysis.swc_data import UNPROTECTED_ETHER_WITHDRAWAL
from mythril.exceptions import UnsatError from mythril.exceptions import UnsatError
from mythril.laser.ethereum.state.global_state import GlobalState from mythril.laser.ethereum.state.global_state import GlobalState
@ -51,14 +55,13 @@ class EtherThief(DetectionModule):
super().reset_module() super().reset_module()
self._cache_addresses = {} self._cache_addresses = {}
def execute(self, state: GlobalState): def _execute(self, state: GlobalState) -> None:
""" """
:param state: :param state:
:return: :return:
""" """
self._issues.extend(self._analyze_state(state)) self._issues.extend(self._analyze_state(state))
return self.issues
def _analyze_state(self, state): def _analyze_state(self, state):
""" """
@ -82,23 +85,18 @@ class EtherThief(DetectionModule):
constraints = copy(state.mstate.constraints) constraints = copy(state.mstate.constraints)
for tx in state.world_state.transaction_sequence: for tx in state.world_state.transaction_sequence:
if tx.caller == 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF:
# There's sometimes no overflow check on balances added.
# But we don't care about attacks that require more 2^^256 ETH to be sent.
constraints += [BVAddNoOverflow(eth_sent_total, tx.call_value, False)] constraints += [BVAddNoOverflow(eth_sent_total, tx.call_value, False)]
eth_sent_total = Sum(eth_sent_total, tx.call_value) eth_sent_total = Sum(eth_sent_total, tx.call_value)
constraints += [
UGT(call_value, eth_sent_total), if not isinstance(tx, ContractCreationTransaction):
target == state.environment.sender, constraints.append(tx.caller == ATTACKER_ADDRESS)
]
constraints += [UGT(call_value, eth_sent_total), target == ATTACKER_ADDRESS]
try: try:
transaction_sequence = solver.get_transaction_sequence(state, constraints) transaction_sequence = solver.get_transaction_sequence(state, constraints)
debug = json.dumps(transaction_sequence, indent=4)
issue = Issue( issue = Issue(
contract=state.environment.active_account.contract_name, contract=state.environment.active_account.contract_name,
function_name=state.environment.active_function_name, function_name=state.environment.active_function_name,
@ -111,14 +109,14 @@ class EtherThief(DetectionModule):
description_tail="Arbitrary senders other than the contract creator can withdraw ETH from the contract" description_tail="Arbitrary senders other than the contract creator can withdraw ETH from the contract"
+ " account without previously having sent an equivalent amount of ETH to it. This is likely to be" + " account without previously having sent an equivalent amount of ETH to it. This is likely to be"
+ " a vulnerability.", + " a vulnerability.",
debug=debug, transaction_sequence=transaction_sequence,
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used),
) )
except UnsatError: except UnsatError:
log.debug("[ETHER_THIEF] no model found") log.debug("[ETHER_THIEF] no model found")
return [] return []
self._cache_addresses[address] = True # self._cache_addresses[address] = True
return [issue] return [issue]

@ -18,8 +18,6 @@ def _analyze_state(state) -> list:
:param state: :param state:
:return: :return:
""" """
log.info("Exceptions module: found ASSERT_FAIL instruction")
log.debug("ASSERT_FAIL in function " + state.environment.active_function_name) log.debug("ASSERT_FAIL in function " + state.environment.active_function_name)
try: try:
@ -36,7 +34,6 @@ def _analyze_state(state) -> list:
transaction_sequence = solver.get_transaction_sequence( transaction_sequence = solver.get_transaction_sequence(
state, state.mstate.constraints state, state.mstate.constraints
) )
debug = json.dumps(transaction_sequence, indent=4)
issue = Issue( issue = Issue(
contract=state.environment.active_account.contract_name, contract=state.environment.active_account.contract_name,
@ -48,7 +45,7 @@ def _analyze_state(state) -> list:
description_head="A reachable exception has been detected.", description_head="A reachable exception has been detected.",
description_tail=description_tail, description_tail=description_tail,
bytecode=state.environment.code.bytecode, bytecode=state.environment.code.bytecode,
debug=debug, transaction_sequence=transaction_sequence,
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used),
) )
return [issue] return [issue]
@ -72,14 +69,13 @@ class ReachableExceptionsModule(DetectionModule):
pre_hooks=["ASSERT_FAIL"], pre_hooks=["ASSERT_FAIL"],
) )
def execute(self, state: GlobalState) -> list: def _execute(self, state: GlobalState) -> None:
""" """
:param state: :param state:
:return: :return:
""" """
self._issues.extend(_analyze_state(state)) self._issues.extend(_analyze_state(state))
return self.issues
detector = ReachableExceptionsModule() detector = ReachableExceptionsModule()

@ -3,6 +3,10 @@ calls."""
from mythril.analysis import solver from mythril.analysis import solver
from mythril.analysis.swc_data import REENTRANCY from mythril.analysis.swc_data import REENTRANCY
from mythril.laser.ethereum.transaction.symbolic import ATTACKER_ADDRESS
from mythril.laser.ethereum.transaction.transaction_models import (
ContractCreationTransaction,
)
from mythril.analysis.modules.base import DetectionModule from mythril.analysis.modules.base import DetectionModule
from mythril.analysis.report import Issue from mythril.analysis.report import Issue
from mythril.laser.smt import UGT, symbol_factory, Or, BitVec from mythril.laser.smt import UGT, symbol_factory, Or, BitVec
@ -44,10 +48,14 @@ def _analyze_state(state):
# Check whether we can also set the callee address # Check whether we can also set the callee address
try: try:
constraints += [to == 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF] constraints += [to == ATTACKER_ADDRESS]
for tx in state.world_state.transaction_sequence:
if not isinstance(tx, ContractCreationTransaction):
constraints.append(tx.caller == ATTACKER_ADDRESS)
transaction_sequence = solver.get_transaction_sequence(state, constraints) transaction_sequence = solver.get_transaction_sequence(state, constraints)
debug = json.dumps(transaction_sequence, indent=4)
description_head = "A call to a user-supplied address is executed." description_head = "A call to a user-supplied address is executed."
description_tail = ( description_tail = (
"The callee address of an external message call can be set by " "The callee address of an external message call can be set by "
@ -66,7 +74,7 @@ def _analyze_state(state):
severity="Medium", severity="Medium",
description_head=description_head, description_head=description_head,
description_tail=description_tail, description_tail=description_tail,
debug=debug, transaction_sequence=transaction_sequence,
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used),
) )
@ -95,7 +103,7 @@ def _analyze_state(state):
severity="Low", severity="Low",
description_head=description_head, description_head=description_head,
description_tail=description_tail, description_tail=description_tail,
debug=debug, transaction_sequence=transaction_sequence,
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used),
) )
@ -137,14 +145,13 @@ class ExternalCalls(DetectionModule):
pre_hooks=["CALL"], pre_hooks=["CALL"],
) )
def execute(self, state: GlobalState): def _execute(self, state: GlobalState) -> None:
""" """
:param state: :param state:
:return: :return:
""" """
self._issues.extend(_analyze_state(state)) self._issues.extend(_analyze_state(state))
return self.issues
detector = ExternalCalls() detector = ExternalCalls()

@ -4,7 +4,7 @@ underflows."""
import json import json
from math import log2, ceil from math import log2, ceil
from typing import Dict, cast, List from typing import cast, List, Dict, Set
from mythril.analysis import solver from mythril.analysis import solver
from mythril.analysis.report import Issue from mythril.analysis.report import Issue
from mythril.analysis.swc_data import INTEGER_OVERFLOW_AND_UNDERFLOW from mythril.analysis.swc_data import INTEGER_OVERFLOW_AND_UNDERFLOW
@ -13,6 +13,7 @@ from mythril.laser.ethereum.state.global_state import GlobalState
from mythril.laser.ethereum.util import get_concrete_int from mythril.laser.ethereum.util import get_concrete_int
from mythril.laser.ethereum.state.annotation import StateAnnotation from mythril.laser.ethereum.state.annotation import StateAnnotation
from mythril.analysis.modules.base import DetectionModule from mythril.analysis.modules.base import DetectionModule
from copy import copy
from mythril.laser.smt import ( from mythril.laser.smt import (
BVAddNoOverflow, BVAddNoOverflow,
@ -28,11 +29,8 @@ from mythril.laser.smt import (
import logging import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
DISABLE_EFFECT_CHECK = True
class OverUnderflowAnnotation: class OverUnderflowAnnotation:
""" Symbol Annotation used if a BitVector can overflow""" """ Symbol Annotation used if a BitVector can overflow"""
@ -48,12 +46,19 @@ class OverUnderflowAnnotation:
class OverUnderflowStateAnnotation(StateAnnotation): class OverUnderflowStateAnnotation(StateAnnotation):
""" State Annotation used if an overflow is both possible and used in the annotated path""" """ State Annotation used if an overflow is both possible and used in the annotated path"""
def __init__( def __init__(self) -> None:
self, overflowing_state: GlobalState, operator: str, constraint: Bool self.overflowing_state_annotations = [] # type: List[OverUnderflowAnnotation]
) -> None: self.ostates_seen = set() # type: Set[GlobalState]
self.overflowing_state = overflowing_state
self.operator = operator def __copy__(self):
self.constraint = constraint new_annotation = OverUnderflowStateAnnotation()
new_annotation.overflowing_state_annotations = copy(
self.overflowing_state_annotations
)
new_annotation.ostates_seen = copy(self.ostates_seen)
return new_annotation
class IntegerOverflowUnderflowModule(DetectionModule): class IntegerOverflowUnderflowModule(DetectionModule):
@ -72,8 +77,19 @@ class IntegerOverflowUnderflowModule(DetectionModule):
entrypoint="callback", entrypoint="callback",
pre_hooks=["ADD", "MUL", "EXP", "SUB", "SSTORE", "JUMPI", "STOP", "RETURN"], pre_hooks=["ADD", "MUL", "EXP", "SUB", "SSTORE", "JUMPI", "STOP", "RETURN"],
) )
"""
Cache addresses for which overflows or underflows already have been detected.
"""
self._overflow_cache = {} # type: Dict[int, bool] self._overflow_cache = {} # type: Dict[int, bool]
self._underflow_cache = {} # type: Dict[int, bool]
"""
Cache satisfiability of overflow constraints
"""
self._ostates_satisfiable = set() # type: Set[GlobalState]
self._ostates_unsatisfiable = set() # type: Set[GlobalState]
def reset_module(self): def reset_module(self):
""" """
@ -82,20 +98,23 @@ class IntegerOverflowUnderflowModule(DetectionModule):
""" """
super().reset_module() super().reset_module()
self._overflow_cache = {} self._overflow_cache = {}
self._underflow_cache = {} self._ostates_satisfiable = set()
self._ostates_unsatisfiable = set()
def execute(self, state: GlobalState): def _execute(self, state: GlobalState) -> None:
"""Executes analysis module for integer underflow and integer overflow. """Executes analysis module for integer underflow and integer overflow.
:param state: Statespace to analyse :param state: Statespace to analyse
:return: Found issues :return: Found issues
""" """
address = _get_address_from_state(state) address = _get_address_from_state(state)
has_overflow = self._overflow_cache.get(address, False)
has_underflow = self._underflow_cache.get(address, False) if self._overflow_cache.get(address, False):
if has_overflow or has_underflow:
return return
opcode = state.get_current_instruction()["opcode"] opcode = state.get_current_instruction()["opcode"]
funcs = { funcs = {
"ADD": [self._handle_add], "ADD": [self._handle_add],
"SUB": [self._handle_sub], "SUB": [self._handle_sub],
@ -121,11 +140,6 @@ class IntegerOverflowUnderflowModule(DetectionModule):
op0, op1 = self._get_args(state) op0, op1 = self._get_args(state)
c = Not(BVAddNoOverflow(op0, op1, False)) c = Not(BVAddNoOverflow(op0, op1, False))
# Check satisfiable
model = self._try_constraints(state.mstate.constraints, [c])
if model is None:
return
annotation = OverUnderflowAnnotation(state, "addition", c) annotation = OverUnderflowAnnotation(state, "addition", c)
op0.annotate(annotation) op0.annotate(annotation)
@ -133,11 +147,6 @@ class IntegerOverflowUnderflowModule(DetectionModule):
op0, op1 = self._get_args(state) op0, op1 = self._get_args(state)
c = Not(BVMulNoOverflow(op0, op1, False)) c = Not(BVMulNoOverflow(op0, op1, False))
# Check satisfiable
model = self._try_constraints(state.mstate.constraints, [c])
if model is None:
return
annotation = OverUnderflowAnnotation(state, "multiplication", c) annotation = OverUnderflowAnnotation(state, "multiplication", c)
op0.annotate(annotation) op0.annotate(annotation)
@ -145,11 +154,6 @@ class IntegerOverflowUnderflowModule(DetectionModule):
op0, op1 = self._get_args(state) op0, op1 = self._get_args(state)
c = Not(BVSubNoUnderflow(op0, op1, False)) c = Not(BVSubNoUnderflow(op0, op1, False))
# Check satisfiable
model = self._try_constraints(state.mstate.constraints, [c])
if model is None:
return
annotation = OverUnderflowAnnotation(state, "subtraction", c) annotation = OverUnderflowAnnotation(state, "subtraction", c)
op0.annotate(annotation) op0.annotate(annotation)
@ -174,9 +178,7 @@ class IntegerOverflowUnderflowModule(DetectionModule):
) )
else: else:
constraint = op0.value ** op1.value >= 2 ** 256 constraint = op0.value ** op1.value >= 2 ** 256
model = self._try_constraints(state.mstate.constraints, [constraint])
if model is None:
return
annotation = OverUnderflowAnnotation(state, "exponentiation", constraint) annotation = OverUnderflowAnnotation(state, "exponentiation", constraint)
op0.annotate(annotation) op0.annotate(annotation)
@ -213,36 +215,42 @@ class IntegerOverflowUnderflowModule(DetectionModule):
@staticmethod @staticmethod
def _handle_sstore(state: GlobalState) -> None: def _handle_sstore(state: GlobalState) -> None:
stack = state.mstate.stack stack = state.mstate.stack
value = stack[-2] value = stack[-2]
if not isinstance(value, Expression): if not isinstance(value, Expression):
return return
state_annotation = _get_overflowunderflow_state_annotation(state)
for annotation in value.annotations: for annotation in value.annotations:
if not isinstance(annotation, OverUnderflowAnnotation): if (
not isinstance(annotation, OverUnderflowAnnotation)
or annotation.overflowing_state in state_annotation.ostates_seen
):
continue continue
state.annotate(
OverUnderflowStateAnnotation( state_annotation.overflowing_state_annotations.append(annotation)
annotation.overflowing_state, state_annotation.ostates_seen.add(annotation.overflowing_state)
annotation.operator,
annotation.constraint,
)
)
@staticmethod @staticmethod
def _handle_jumpi(state): def _handle_jumpi(state):
stack = state.mstate.stack stack = state.mstate.stack
value = stack[-2] value = stack[-2]
state_annotation = _get_overflowunderflow_state_annotation(state)
for annotation in value.annotations: for annotation in value.annotations:
if not isinstance(annotation, OverUnderflowAnnotation): if (
not isinstance(annotation, OverUnderflowAnnotation)
or annotation.overflowing_state in state_annotation.ostates_seen
):
continue continue
state.annotate(
OverUnderflowStateAnnotation( state_annotation.overflowing_state_annotations.append(annotation)
annotation.overflowing_state, state_annotation.ostates_seen.add(annotation.overflowing_state)
annotation.operator,
annotation.constraint,
)
)
@staticmethod @staticmethod
def _handle_return(state: GlobalState) -> None: def _handle_return(state: GlobalState) -> None:
@ -251,49 +259,57 @@ class IntegerOverflowUnderflowModule(DetectionModule):
locations in the memory returned by RETURN opcode. locations in the memory returned by RETURN opcode.
:param state: The Global State :param state: The Global State
""" """
stack = state.mstate.stack stack = state.mstate.stack
try: try:
offset, length = get_concrete_int(stack[-1]), get_concrete_int(stack[-2]) offset, length = get_concrete_int(stack[-1]), get_concrete_int(stack[-2])
except TypeError: except TypeError:
return return
state_annotation = _get_overflowunderflow_state_annotation(state)
for element in state.mstate.memory[offset : offset + length]: for element in state.mstate.memory[offset : offset + length]:
if not isinstance(element, Expression): if not isinstance(element, Expression):
continue continue
for annotation in element.annotations: for annotation in element.annotations:
if isinstance(annotation, OverUnderflowAnnotation): if (
state.annotate( isinstance(annotation, OverUnderflowAnnotation)
OverUnderflowStateAnnotation( and annotation not in state_annotation.overflowing_state_annotations
annotation.overflowing_state, ):
annotation.operator, state_annotation.overflowing_state_annotations.append(annotation)
annotation.constraint,
)
)
def _handle_transaction_end(self, state: GlobalState) -> None: def _handle_transaction_end(self, state: GlobalState) -> None:
for annotation in cast(
List[OverUnderflowStateAnnotation], state_annotation = _get_overflowunderflow_state_annotation(state)
state.get_annotations(OverUnderflowStateAnnotation),
): for annotation in state_annotation.overflowing_state_annotations:
ostate = annotation.overflowing_state ostate = annotation.overflowing_state
address = _get_address_from_state(ostate)
if annotation.operator == "subtraction" and self._underflow_cache.get( if ostate in self._ostates_unsatisfiable:
address, False
):
continue continue
if annotation.operator != "subtraction" and self._overflow_cache.get( if ostate not in self._ostates_satisfiable:
address, False try:
): constraints = ostate.mstate.constraints + [annotation.constraint]
solver.get_model(constraints)
self._ostates_satisfiable.add(ostate)
except:
self._ostates_unsatisfiable.add(ostate)
continue continue
log.debug(
"Checking overflow in {} at transaction end address {}, ostate address {}".format(
state.get_current_instruction()["opcode"],
state.get_current_instruction()["address"],
ostate.get_current_instruction()["address"],
)
)
try: try:
# This check can be disabled if the contraints are to difficult for z3 to solve
# within any reasonable time.
if DISABLE_EFFECT_CHECK:
constraints = ostate.mstate.constraints + [annotation.constraint]
else:
constraints = state.mstate.constraints + [annotation.constraint] constraints = state.mstate.constraints + [annotation.constraint]
transaction_sequence = solver.get_transaction_sequence( transaction_sequence = solver.get_transaction_sequence(
@ -314,29 +330,32 @@ class IntegerOverflowUnderflowModule(DetectionModule):
description_head=self._get_description_head(annotation, _type), description_head=self._get_description_head(annotation, _type),
description_tail=self._get_description_tail(annotation, _type), description_tail=self._get_description_tail(annotation, _type),
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used),
transaction_sequence=transaction_sequence,
) )
issue.debug = json.dumps(transaction_sequence, indent=4) address = _get_address_from_state(ostate)
if annotation.operator == "subtraction":
self._underflow_cache[address] = True
else:
self._overflow_cache[address] = True self._overflow_cache[address] = True
self._issues.append(issue) self._issues.append(issue)
@staticmethod
def _try_constraints(constraints, new_constraints):
""" Tries new constraints
:return Model if satisfiable otherwise None
"""
try:
return solver.get_model(constraints + new_constraints)
except UnsatError:
return None
detector = IntegerOverflowUnderflowModule() detector = IntegerOverflowUnderflowModule()
def _get_address_from_state(state): def _get_address_from_state(state):
return state.get_current_instruction()["address"] return state.get_current_instruction()["address"]
def _get_overflowunderflow_state_annotation(
state: GlobalState
) -> OverUnderflowStateAnnotation:
state_annotations = cast(
List[OverUnderflowStateAnnotation],
list(state.get_annotations(OverUnderflowStateAnnotation)),
)
if len(state_annotations) == 0:
state_annotation = OverUnderflowStateAnnotation()
state.annotate(state_annotation)
return state_annotation
else:
return state_annotations[0]

@ -1,27 +1,25 @@
"""This module contains the detection code to find multiple sends occurring in """This module contains the detection code to find multiple sends occurring in
a single transaction.""" a single transaction."""
from copy import copy from copy import copy
from typing import cast, List, Optional from typing import cast, List
from mythril.analysis.ops import Call
from mythril.analysis.report import Issue from mythril.analysis.report import Issue
from mythril.analysis.swc_data import MULTIPLE_SENDS from mythril.analysis.swc_data import MULTIPLE_SENDS
from mythril.analysis.modules.base import DetectionModule from mythril.analysis.modules.base import DetectionModule
from mythril.laser.ethereum.state.annotation import StateAnnotation from mythril.laser.ethereum.state.annotation import StateAnnotation
from mythril.laser.ethereum.state.global_state import GlobalState from mythril.laser.ethereum.state.global_state import GlobalState
import logging import logging
from mythril.analysis.call_helpers import get_call_from_state
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class MultipleSendsAnnotation(StateAnnotation): class MultipleSendsAnnotation(StateAnnotation):
def __init__(self) -> None: def __init__(self) -> None:
self.calls = [] # type: List[Optional[Call]] self.call_offsets = [] # type: List[int]
def __copy__(self): def __copy__(self):
result = MultipleSendsAnnotation() result = MultipleSendsAnnotation()
result.calls = copy(self.calls) result.call_offsets = copy(self.call_offsets)
return result return result
@ -45,9 +43,8 @@ class MultipleSendsModule(DetectionModule):
], ],
) )
def execute(self, state: GlobalState): def _execute(self, state: GlobalState) -> None:
self._issues.extend(_analyze_state(state)) self._issues.extend(_analyze_state(state))
return self.issues
def _analyze_state(state: GlobalState): def _analyze_state(state: GlobalState):
@ -62,46 +59,35 @@ def _analyze_state(state: GlobalState):
list(state.get_annotations(MultipleSendsAnnotation)), list(state.get_annotations(MultipleSendsAnnotation)),
) )
if len(annotations) == 0: if len(annotations) == 0:
log.debug("Creating annotation for state")
state.annotate(MultipleSendsAnnotation()) state.annotate(MultipleSendsAnnotation())
annotations = cast( annotations = cast(
List[MultipleSendsAnnotation], List[MultipleSendsAnnotation],
list(state.get_annotations(MultipleSendsAnnotation)), list(state.get_annotations(MultipleSendsAnnotation)),
) )
calls = annotations[0].calls call_offsets = annotations[0].call_offsets
if instruction["opcode"] in ["CALL", "DELEGATECALL", "STATICCALL", "CALLCODE"]: if instruction["opcode"] in ["CALL", "DELEGATECALL", "STATICCALL", "CALLCODE"]:
call = get_call_from_state(state) call_offsets.append(state.get_current_instruction()["address"])
if call:
calls += [call]
else: # RETURN or STOP else: # RETURN or STOP
if len(calls) > 1:
description_tail = ( for offset in call_offsets[1:]:
"Consecutive calls are executed at the following bytecode offsets:\n"
)
for call in calls: description_tail = (
description_tail += "Offset: {}\n".format( "This call is executed after a previous call in the same transaction. "
call.state.get_current_instruction()["address"] "Try to isolate each call, transfer or send into its own transaction."
)
description_tail += (
"Try to isolate each external call into its own transaction,"
" as external calls can fail accidentally or deliberately.\n"
) )
issue = Issue( issue = Issue(
contract=state.environment.active_account.contract_name, contract=state.environment.active_account.contract_name,
function_name=state.environment.active_function_name, function_name=state.environment.active_function_name,
address=instruction["address"], address=offset,
swc_id=MULTIPLE_SENDS, swc_id=MULTIPLE_SENDS,
bytecode=state.environment.code.bytecode, bytecode=state.environment.code.bytecode,
title="Multiple Calls in a Single Transaction", title="Multiple Calls in a Single Transaction",
severity="Medium", severity="Low",
description_head="Multiple sends are executed in one transaction.", description_head="Multiple calls are executed in the same transaction.",
description_tail=description_tail, description_tail=description_tail,
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used),
) )

@ -84,9 +84,8 @@ class StateChange(DetectionModule):
], ],
) )
def execute(self, state: GlobalState): def _execute(self, state: GlobalState) -> None:
self._issues.extend(self._analyze_state(state)) self._issues.extend(self._analyze_state(state))
return self.issues
@staticmethod @staticmethod
def _add_external_call(global_state: GlobalState) -> None: def _add_external_call(global_state: GlobalState) -> None:

@ -4,6 +4,10 @@ from mythril.analysis.swc_data import UNPROTECTED_SELFDESTRUCT
from mythril.exceptions import UnsatError from mythril.exceptions import UnsatError
from mythril.analysis.modules.base import DetectionModule from mythril.analysis.modules.base import DetectionModule
from mythril.laser.ethereum.state.global_state import GlobalState from mythril.laser.ethereum.state.global_state import GlobalState
from mythril.laser.ethereum.transaction.symbolic import ATTACKER_ADDRESS
from mythril.laser.ethereum.transaction.transaction_models import (
ContractCreationTransaction,
)
import logging import logging
import json import json
@ -37,14 +41,13 @@ class SuicideModule(DetectionModule):
super().reset_module() super().reset_module()
self._cache_address = {} self._cache_address = {}
def execute(self, state: GlobalState): def _execute(self, state: GlobalState) -> None:
""" """
:param state: :param state:
:return: :return:
""" """
self._issues.extend(self._analyze_state(state)) self._issues.extend(self._analyze_state(state))
return self.issues
def _analyze_state(self, state): def _analyze_state(self, state):
log.info("Suicide module: Analyzing suicide instruction") log.info("Suicide module: Analyzing suicide instruction")
@ -59,12 +62,17 @@ class SuicideModule(DetectionModule):
description_head = "The contract can be killed by anyone." description_head = "The contract can be killed by anyone."
constraints = []
for tx in state.world_state.transaction_sequence:
if not isinstance(tx, ContractCreationTransaction):
constraints.append(tx.caller == ATTACKER_ADDRESS)
try: try:
try: try:
transaction_sequence = solver.get_transaction_sequence( transaction_sequence = solver.get_transaction_sequence(
state, state,
state.mstate.constraints state.mstate.constraints + constraints + [to == ATTACKER_ADDRESS],
+ [to == 0xDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF],
) )
description_tail = ( description_tail = (
"Anyone can kill this contract and withdraw its balance to an arbitrary " "Anyone can kill this contract and withdraw its balance to an arbitrary "
@ -72,11 +80,10 @@ class SuicideModule(DetectionModule):
) )
except UnsatError: except UnsatError:
transaction_sequence = solver.get_transaction_sequence( transaction_sequence = solver.get_transaction_sequence(
state, state.mstate.constraints state, state.mstate.constraints + constraints
) )
description_tail = "Arbitrary senders can kill this contract." description_tail = "Arbitrary senders can kill this contract."
debug = json.dumps(transaction_sequence, indent=4)
self._cache_address[instruction["address"]] = True self._cache_address[instruction["address"]] = True
issue = Issue( issue = Issue(
@ -89,7 +96,7 @@ class SuicideModule(DetectionModule):
severity="High", severity="High",
description_head=description_head, description_head=description_head,
description_tail=description_tail, description_tail=description_tail,
debug=debug, transaction_sequence=transaction_sequence,
gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used), gas_used=(state.mstate.min_gas_used, state.mstate.max_gas_used),
) )
return [issue] return [issue]

@ -49,14 +49,13 @@ class UncheckedRetvalModule(DetectionModule):
post_hooks=["CALL", "DELEGATECALL", "STATICCALL", "CALLCODE"], post_hooks=["CALL", "DELEGATECALL", "STATICCALL", "CALLCODE"],
) )
def execute(self, state: GlobalState) -> list: def _execute(self, state: GlobalState) -> None:
""" """
:param state: :param state:
:return: :return:
""" """
self._issues.extend(_analyze_state(state)) self._issues.extend(_analyze_state(state))
return self.issues
def _analyze_state(state: GlobalState) -> list: def _analyze_state(state: GlobalState) -> list:

@ -31,7 +31,7 @@ class Issue:
severity=None, severity=None,
description_head="", description_head="",
description_tail="", description_tail="",
debug="", transaction_sequence=None,
): ):
""" """
@ -55,7 +55,6 @@ class Issue:
self.description_tail = description_tail self.description_tail = description_tail
self.description = "%s\n%s" % (description_head, description_tail) self.description = "%s\n%s" % (description_head, description_tail)
self.severity = severity self.severity = severity
self.debug = debug
self.swc_id = swc_id self.swc_id = swc_id
self.min_gas_used, self.max_gas_used = gas_used self.min_gas_used, self.max_gas_used = gas_used
self.filename = None self.filename = None
@ -64,6 +63,38 @@ class Issue:
self.source_mapping = None self.source_mapping = None
self.discovery_time = time() - StartTime().global_start_time self.discovery_time = time() - StartTime().global_start_time
self.bytecode_hash = get_code_hash(bytecode) self.bytecode_hash = get_code_hash(bytecode)
self.transaction_sequence = transaction_sequence
@property
def transaction_sequence_users(self):
""" Returns the transaction sequence in json without pre-generated block data"""
return (
json.dumps(self.transaction_sequence, indent=4)
if self.transaction_sequence
else None
)
@property
def transaction_sequence_jsonv2(self):
""" Returns the transaction sequence in json with pre-generated block data"""
return (
json.dumps(self.add_block_data(self.transaction_sequence), indent=4)
if self.transaction_sequence
else None
)
@staticmethod
def add_block_data(transaction_sequence: Dict):
""" Adds sane block data to a transaction_sequence """
for step in transaction_sequence["steps"]:
step["gasLimit"] = "0x7d000"
step["gasPrice"] = "0x773594000"
step["blockCoinbase"] = "0xcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb"
step["blockDifficulty"] = "0xa7d7343662e26"
step["blockGasLimit"] = "0x7d0000"
step["blockNumber"] = "0x66e393"
step["blockTime"] = "0x5bfa4639"
return transaction_sequence
@property @property
def as_dict(self): def as_dict(self):
@ -79,7 +110,7 @@ class Issue:
"function": self.function, "function": self.function,
"severity": self.severity, "severity": self.severity,
"address": self.address, "address": self.address,
"debug": self.debug, "tx_sequence": self.transaction_sequence_users,
"min_gas_used": self.min_gas_used, "min_gas_used": self.min_gas_used,
"max_gas_used": self.max_gas_used, "max_gas_used": self.max_gas_used,
"sourceMap": self.source_mapping, "sourceMap": self.source_mapping,
@ -168,6 +199,7 @@ class Report:
""" """
name = self._file_name() name = self._file_name()
template = Report.environment.get_template("report_as_text.jinja2") template = Report.environment.get_template("report_as_text.jinja2")
return template.render( return template.render(
filename=name, issues=self.sorted_issues(), verbose=self.verbose filename=name, issues=self.sorted_issues(), verbose=self.verbose
) )
@ -203,7 +235,9 @@ class Report:
title = SWC_TO_TITLE[issue.swc_id] title = SWC_TO_TITLE[issue.swc_id]
except KeyError: except KeyError:
title = "Unspecified Security Issue" title = "Unspecified Security Issue"
extra = {"discoveryTime": int(issue.discovery_time * 10 ** 9)}
if issue.transaction_sequence_jsonv2:
extra["testCase"] = str(issue.transaction_sequence_jsonv2)
_issues.append( _issues.append(
{ {
"swcID": "SWC-" + issue.swc_id, "swcID": "SWC-" + issue.swc_id,
@ -214,7 +248,7 @@ class Report:
}, },
"severity": issue.severity, "severity": issue.severity,
"locations": [{"sourceMap": "%d:1:%d" % (issue.address, idx)}], "locations": [{"sourceMap": "%d:1:%d" % (issue.address, idx)}],
"extra": {"discoveryTime": int(issue.discovery_time * 10 ** 9)}, "extra": extra,
} }
) )
meta_data = self._get_exception_data() meta_data = self._get_exception_data()

@ -52,6 +52,10 @@ def get_detection_modules(entrypoint, include_modules=()):
:param include_modules: :param include_modules:
:return: :return:
""" """
module = importlib.import_module("mythril.analysis.modules.base")
module.log.setLevel(log.level)
include_modules = list(include_modules) include_modules = list(include_modules)
_modules = [] _modules = []
@ -62,12 +66,14 @@ def get_detection_modules(entrypoint, include_modules=()):
module = importlib.import_module( module = importlib.import_module(
"mythril.analysis.modules." + module_name "mythril.analysis.modules." + module_name
) )
module.log.setLevel(log.level)
if module.detector.entrypoint == entrypoint: if module.detector.entrypoint == entrypoint:
_modules.append(module) _modules.append(module)
else: else:
for module_name in include_modules: for module_name in include_modules:
module = importlib.import_module("mythril.analysis.modules." + module_name) module = importlib.import_module("mythril.analysis.modules." + module_name)
if module.__name__ != "base" and module.detector.entrypoint == entrypoint: if module.__name__ != "base" and module.detector.entrypoint == entrypoint:
module.log.setLevel(log.level)
_modules.append(module) _modules.append(module)
log.info("Found %s detection modules", len(_modules)) log.info("Found %s detection modules", len(_modules))

@ -1,8 +1,13 @@
"""This module contains analysis module helpers to solve path constraints.""" """This module contains analysis module helpers to solve path constraints."""
from typing import Dict, List, Union
from z3 import sat, unknown, FuncInterp from z3 import sat, unknown, FuncInterp
import z3 import z3
from mythril.laser.smt import simplify, UGE, Optimize, symbol_factory from mythril.laser.ethereum.state.global_state import GlobalState
from mythril.laser.ethereum.state.world_state import Account
from mythril.laser.ethereum.state.constraints import Constraints
from mythril.laser.ethereum.transaction import BaseTransaction
from mythril.laser.smt import UGE, Optimize, symbol_factory
from mythril.laser.ethereum.time_handler import time_handler from mythril.laser.ethereum.time_handler import time_handler
from mythril.exceptions import UnsatError from mythril.exceptions import UnsatError
from mythril.laser.ethereum.transaction.transaction_models import ( from mythril.laser.ethereum.transaction.transaction_models import (
@ -51,7 +56,7 @@ def get_model(constraints, minimize=(), maximize=(), enforce_execution_time=True
def pretty_print_model(model): def pretty_print_model(model):
""" """ Pretty prints a z3 model
:param model: :param model:
:return: :return:
@ -74,7 +79,9 @@ def pretty_print_model(model):
return ret return ret
def get_transaction_sequence(global_state, constraints): def get_transaction_sequence(
global_state: GlobalState, constraints: Constraints
) -> Dict:
"""Generate concrete transaction sequence. """Generate concrete transaction sequence.
:param global_state: GlobalState to generate transaction sequence for :param global_state: GlobalState to generate transaction sequence for
@ -83,55 +90,102 @@ def get_transaction_sequence(global_state, constraints):
transaction_sequence = global_state.world_state.transaction_sequence transaction_sequence = global_state.world_state.transaction_sequence
# gaslimit & gasprice don't exist yet concrete_transactions = []
tx_template = {
"calldata": None,
"call_value": None,
"caller": "0xCA11EDEADBEEF37E636E6CA11EDEADBEEFCA11ED",
}
concrete_transactions = {}
creation_tx_ids = []
tx_constraints = constraints.copy()
minimize = []
transactions = [] tx_constraints, minimize = _set_minimisation_constraints(
for transaction in transaction_sequence: transaction_sequence, constraints.copy(), [], 5000
tx_id = str(transaction.id)
if not isinstance(transaction, ContractCreationTransaction):
transactions.append(transaction)
# Constrain calldatasize
max_calldatasize = symbol_factory.BitVecVal(5000, 256)
tx_constraints.append(
UGE(max_calldatasize, transaction.call_data.calldatasize)
) )
model = get_model(tx_constraints, minimize=minimize)
minimize.append(transaction.call_data.calldatasize) min_price_dict = {} # type: Dict[str, int]
minimize.append(transaction.call_value) for transaction in transaction_sequence:
concrete_transaction = _get_concrete_transaction(model, transaction)
concrete_transactions.append(concrete_transaction)
concrete_transactions[tx_id] = tx_template.copy() caller = concrete_transaction["origin"]
value = int(concrete_transaction["value"], 16)
min_price_dict[caller] = min_price_dict.get(caller, 0) + value
if isinstance(transaction_sequence[0], ContractCreationTransaction):
initial_accounts = transaction_sequence[0].prev_world_state.accounts
else: else:
creation_tx_ids.append(tx_id) initial_accounts = transaction_sequence[0].world_state.accounts
model = get_model(tx_constraints, minimize=minimize) concrete_initial_state = _get_concrete_state(initial_accounts, min_price_dict)
for transaction in transactions: steps = {"initialState": concrete_initial_state, "steps": concrete_transactions}
tx_id = str(transaction.id)
return steps
def _get_concrete_state(initial_accounts: Dict, min_price_dict: Dict[str, int]):
""" Gets a concrete state """
accounts = {}
for address, account in initial_accounts.items():
# Skip empty default account
data = dict() # type: Dict[str, Union[int, str]]
data["nonce"] = account.nonce
data["code"] = account.code.bytecode
data["storage"] = str(account.storage)
data["balance"] = min_price_dict.get(address, 0)
accounts[hex(address)] = data
return accounts
def _get_concrete_transaction(model: z3.Model, transaction: BaseTransaction):
""" Gets a concrete transaction from a transaction and z3 model"""
# Get concrete values from transaction
address = hex(transaction.callee_account.address.value)
value = model.eval(transaction.call_value.raw, model_completion=True).as_long()
caller = "0x" + (
"%x" % model.eval(transaction.caller.raw, model_completion=True).as_long()
).zfill(40)
concrete_transactions[tx_id]["calldata"] = "0x" + "".join( if isinstance(transaction, ContractCreationTransaction):
address = ""
input_ = transaction.code.bytecode
else:
input_ = "".join(
[ [
hex(b)[2:] if len(hex(b)) % 2 == 0 else "0" + hex(b)[2:] hex(b)[2:] if len(hex(b)) % 2 == 0 else "0" + hex(b)[2:]
for b in transaction.call_data.concrete(model) for b in transaction.call_data.concrete(model)
] ]
) )
concrete_transactions[tx_id]["call_value"] = ( # Create concrete transaction dict
"0x%x" concrete_transaction = dict() # type: Dict[str, str]
% model.eval(transaction.call_value.raw, model_completion=True).as_long() concrete_transaction["input"] = "0x" + input_
) concrete_transaction["value"] = "0x%x" % value
concrete_transactions[tx_id]["caller"] = "0x" + ( # Fixme: base origin assignment on origin symbol
"%x" % model.eval(transaction.caller.raw, model_completion=True).as_long() concrete_transaction["origin"] = caller
).zfill(40) concrete_transaction["address"] = "%s" % address
return concrete_transaction
def _set_minimisation_constraints(
transaction_sequence, constraints, minimize, max_size
):
""" Set constraints that minimise key transaction values
Constraints generated:
- Upper bound on calldata size
- Minimisation of call value's and calldata sizes
:param transaction_sequence: Transaction for which the constraints should be applied
:param constraints: The constraints array which should contain any added constraints
:param minimize: The minimisation array which should contain any variables that should be minimised
:param max_size: The max size of the calldata array
:return: updated constraints, minimize
"""
for transaction in transaction_sequence:
# Set upper bound on calldata size
max_calldata_size = symbol_factory.BitVecVal(max_size, 256)
constraints.append(UGE(max_calldata_size, transaction.call_data.calldatasize))
# Minimize
minimize.append(transaction.call_data.calldatasize)
minimize.append(transaction.call_value)
return concrete_transactions return constraints, minimize

@ -16,6 +16,19 @@ from mythril.laser.ethereum.strategy.basic import (
ReturnWeightedRandomStrategy, ReturnWeightedRandomStrategy,
BasicSearchStrategy, BasicSearchStrategy,
) )
from mythril.laser.ethereum.transaction.symbolic import (
ATTACKER_ADDRESS,
CREATOR_ADDRESS,
)
from mythril.laser.ethereum.plugins.plugin_factory import PluginFactory
from mythril.laser.ethereum.plugins.plugin_loader import LaserPluginLoader
from mythril.laser.ethereum.strategy.extensions.bounded_loops import (
BoundedLoopsStrategy,
)
from mythril.laser.smt import symbol_factory, BitVec from mythril.laser.smt import symbol_factory, BitVec
from typing import Union, List, Dict, Type from typing import Union, List, Dict, Type
from mythril.solidity.soliditycontract import EVMContract, SolidityContract from mythril.solidity.soliditycontract import EVMContract, SolidityContract
@ -37,11 +50,14 @@ class SymExecWrapper:
dynloader=None, dynloader=None,
max_depth=22, max_depth=22,
execution_timeout=None, execution_timeout=None,
loop_bound=4,
create_timeout=None, create_timeout=None,
transaction_count=2, transaction_count=2,
modules=(), modules=(),
compulsory_statespace=True, compulsory_statespace=True,
enable_iprof=False, enable_iprof=False,
disable_dependency_pruning=False,
run_analysis_modules=True,
): ):
""" """
@ -71,9 +87,23 @@ class SymExecWrapper:
else: else:
raise ValueError("Invalid strategy argument supplied") raise ValueError("Invalid strategy argument supplied")
creator_account = Account(
hex(CREATOR_ADDRESS), "", dynamic_loader=dynloader, contract_name=None
)
attacker_account = Account(
hex(ATTACKER_ADDRESS), "", dynamic_loader=dynloader, contract_name=None
)
requires_statespace = ( requires_statespace = (
compulsory_statespace or len(get_detection_modules("post", modules)) > 0 compulsory_statespace or len(get_detection_modules("post", modules)) > 0
) )
if not contract.creation_code:
self.accounts = {hex(ATTACKER_ADDRESS): attacker_account}
else:
self.accounts = {
hex(CREATOR_ADDRESS): creator_account,
hex(ATTACKER_ADDRESS): attacker_account,
}
self.laser = svm.LaserEVM( self.laser = svm.LaserEVM(
dynamic_loader=dynloader, dynamic_loader=dynloader,
@ -86,10 +116,21 @@ class SymExecWrapper:
enable_iprof=enable_iprof, enable_iprof=enable_iprof,
) )
if loop_bound is not None:
self.laser.extend_strategy(BoundedLoopsStrategy, loop_bound)
plugin_loader = LaserPluginLoader(self.laser) plugin_loader = LaserPluginLoader(self.laser)
plugin_loader.load(PluginFactory.build_mutation_pruner_plugin()) plugin_loader.load(PluginFactory.build_mutation_pruner_plugin())
plugin_loader.load(PluginFactory.build_instruction_coverage_plugin()) plugin_loader.load(PluginFactory.build_instruction_coverage_plugin())
if not disable_dependency_pruning:
plugin_loader.load(PluginFactory.build_dependency_pruner_plugin())
world_state = WorldState()
for account in self.accounts.values():
world_state.put_account(account)
if run_analysis_modules:
self.laser.register_hooks( self.laser.register_hooks(
hook_type="pre", hook_type="pre",
hook_dict=get_detection_module_hooks(modules, hook_type="pre"), hook_dict=get_detection_module_hooks(modules, hook_type="pre"),
@ -101,11 +142,15 @@ class SymExecWrapper:
if isinstance(contract, SolidityContract): if isinstance(contract, SolidityContract):
self.laser.sym_exec( self.laser.sym_exec(
creation_code=contract.creation_code, contract_name=contract.name creation_code=contract.creation_code,
contract_name=contract.name,
world_state=world_state,
) )
elif isinstance(contract, EVMContract) and contract.creation_code: elif isinstance(contract, EVMContract) and contract.creation_code:
self.laser.sym_exec( self.laser.sym_exec(
creation_code=contract.creation_code, contract_name=contract.name creation_code=contract.creation_code,
contract_name=contract.name,
world_state=world_state,
) )
else: else:
account = Account( account = Account(
@ -115,7 +160,6 @@ class SymExecWrapper:
contract_name=contract.name, contract_name=contract.name,
concrete_storage=False, concrete_storage=False,
) )
world_state = WorldState()
world_state.put_account(account) world_state.put_account(account)
self.laser.sym_exec(world_state=world_state, target_address=address.value) self.laser.sym_exec(world_state=world_state, target_address=address.value)

@ -24,11 +24,11 @@ In file: {{ issue.filename }}:{{ issue.lineno }}
{{ issue.code }} {{ issue.code }}
``` ```
{% endif %} {% endif %}
{% if verbose and issue.debug %} {% if verbose and issue.tx_sequence %}
-------------------- --------------------
### Debugging Information: ### Debugging Information:
{{ issue.debug }} {{ issue.tx_sequence }}
{% endif %} {% endif %}
{% endfor %} {% endfor %}

@ -18,11 +18,11 @@ In file: {{ issue.filename }}:{{ issue.lineno }}
-------------------- --------------------
{% endif %} {% endif %}
{% if verbose and issue.debug %} {% if verbose and issue.tx_sequence %}
-------------------- --------------------
Transaction Sequence: Transaction Sequence:
{{ issue.debug }} {{ issue.tx_sequence }}
{% endif %} {% endif %}
{% endfor %} {% endfor %}

@ -23,9 +23,7 @@ from mythril.mythril import (
MythrilConfig, MythrilConfig,
MythrilLevelDB, MythrilLevelDB,
) )
from mythril.version import VERSION from mythril.__version__ import __version__ as VERSION
# logging.basicConfig(level=logging.DEBUG)
ANALYZE_LIST = ("a", "analyze") ANALYZE_LIST = ("a", "analyze")
DISASSEMBLE_LIST = ("d", "disassemble") DISASSEMBLE_LIST = ("d", "disassemble")
@ -317,13 +315,20 @@ def create_analyzer_parser(analyzer_parser: ArgumentParser):
default=50, default=50,
help="Maximum recursion depth for symbolic execution", help="Maximum recursion depth for symbolic execution",
) )
options.add_argument( options.add_argument(
"--strategy", "--strategy",
choices=["dfs", "bfs", "naive-random", "weighted-random"], choices=["dfs", "bfs", "naive-random", "weighted-random"],
default="bfs", default="bfs",
help="Symbolic execution strategy", help="Symbolic execution strategy",
) )
options.add_argument(
"-b",
"--loop-bound",
type=int,
default=4,
help="Bound loops at n iterations",
metavar="N",
)
options.add_argument( options.add_argument(
"-t", "-t",
"--transaction-count", "--transaction-count",
@ -334,7 +339,7 @@ def create_analyzer_parser(analyzer_parser: ArgumentParser):
options.add_argument( options.add_argument(
"--execution-timeout", "--execution-timeout",
type=int, type=int,
default=600, default=86400,
help="The amount of seconds to spend on symbolic execution", help="The amount of seconds to spend on symbolic execution",
) )
options.add_argument( options.add_argument(
@ -370,6 +375,11 @@ def create_analyzer_parser(analyzer_parser: ArgumentParser):
options.add_argument( options.add_argument(
"--enable-iprof", action="store_true", help="enable the instruction profiler" "--enable-iprof", action="store_true", help="enable the instruction profiler"
) )
options.add_argument(
"--disable-dependency-pruning",
action="store_true",
help="Deactivate dependency-based pruning",
)
def validate_args(args: Namespace): def validate_args(args: Namespace):
@ -522,7 +532,6 @@ def execute_command(
return return
if args.command in DISASSEMBLE_LIST: if args.command in DISASSEMBLE_LIST:
if disassembler.contracts[0].code: if disassembler.contracts[0].code:
print("Runtime Disassembly: \n" + disassembler.contracts[0].get_easm()) print("Runtime Disassembly: \n" + disassembler.contracts[0].get_easm())
if disassembler.contracts[0].creation_code: if disassembler.contracts[0].creation_code:
@ -537,6 +546,7 @@ def execute_command(
execution_timeout=args.execution_timeout, execution_timeout=args.execution_timeout,
create_timeout=args.create_timeout, create_timeout=args.create_timeout,
enable_iprof=args.enable_iprof, enable_iprof=args.enable_iprof,
disable_dependency_pruning=args.disable_dependency_pruning,
onchain_storage_access=not args.no_onchain_storage_access, onchain_storage_access=not args.no_onchain_storage_access,
) )

@ -96,7 +96,7 @@ def get_callee_address(
# attempt to read the contract address from instance storage # attempt to read the contract address from instance storage
try: try:
callee_address = dynamic_loader.read_storage( callee_address = dynamic_loader.read_storage(
str(hex(environment.active_account.address.value)), index hex(environment.active_account.address.value), index
) )
# TODO: verify whether this happens or not # TODO: verify whether this happens or not
except: except:

@ -131,6 +131,8 @@ class StateTransition(object):
min_gas, max_gas = cast(Tuple[int, int], OPCODE_GAS[opcode]) min_gas, max_gas = cast(Tuple[int, int], OPCODE_GAS[opcode])
global_state.mstate.min_gas_used += min_gas global_state.mstate.min_gas_used += min_gas
global_state.mstate.max_gas_used += max_gas global_state.mstate.max_gas_used += max_gas
self.check_gas_usage_limit(global_state)
return global_state return global_state
def __call__(self, func: Callable) -> Callable: def __call__(self, func: Callable) -> Callable:
@ -766,18 +768,8 @@ class Instruction:
size_sym = True size_sym = True
if size_sym: if size_sym:
state.mem_extend(mstart, 1) size = 320 # The excess size will get overwritten
state.memory[mstart] = global_state.new_bitvec(
"calldata_"
+ str(environment.active_account.contract_name)
+ "["
+ str(dstart)
+ ": + "
+ str(size)
+ "]",
8,
)
return [global_state]
size = cast(int, size) size = cast(int, size)
if size > 0: if size > 0:
try: try:
@ -939,9 +931,20 @@ class Instruction:
data = symbol_factory.BitVecVal(0, 1) data = symbol_factory.BitVecVal(0, 1)
if data.symbolic: if data.symbolic:
annotations = []
for b in state.memory[index : index + length]:
if isinstance(b, BitVec):
annotations.append(b.annotations)
argument_str = str(state.memory[index]).replace(" ", "_") argument_str = str(state.memory[index]).replace(" ", "_")
result = symbol_factory.BitVecFuncSym( result = symbol_factory.BitVecFuncSym(
"KECCAC[{}]".format(argument_str), "keccak256", 256, input_=data "KECCAC[{}]".format(argument_str),
"keccak256",
256,
input_=data,
annotations=annotations,
) )
log.debug("Created BitVecFunc hash.") log.debug("Created BitVecFunc hash.")
@ -963,7 +966,7 @@ class Instruction:
:param global_state: :param global_state:
:return: :return:
""" """
global_state.mstate.stack.append(global_state.new_bitvec("gasprice", 256)) global_state.mstate.stack.append(global_state.environment.gasprice)
return [global_state] return [global_state]
@staticmethod @staticmethod
@ -1243,7 +1246,7 @@ class Instruction:
:param global_state: :param global_state:
:return: :return:
""" """
global_state.mstate.stack.append(global_state.new_bitvec("block_number", 256)) global_state.mstate.stack.append(global_state.environment.block_number)
return [global_state] return [global_state]
@StateTransition() @StateTransition()
@ -1631,7 +1634,7 @@ class Instruction:
# Get jump destination # Get jump destination
index = util.get_instruction_index(disassembly.instruction_list, jump_addr) index = util.get_instruction_index(disassembly.instruction_list, jump_addr)
if not index: if index is None:
log.debug("Invalid jump destination: " + str(jump_addr)) log.debug("Invalid jump destination: " + str(jump_addr))
return states return states
@ -1660,7 +1663,12 @@ class Instruction:
:param global_state: :param global_state:
:return: :return:
""" """
global_state.mstate.stack.append(global_state.mstate.pc - 1) index = global_state.mstate.pc
program_counter = global_state.environment.code.instruction_list[index][
"address"
]
global_state.mstate.stack.append(program_counter)
return [global_state] return [global_state]
@StateTransition() @StateTransition()
@ -1670,7 +1678,7 @@ class Instruction:
:param global_state: :param global_state:
:return: :return:
""" """
global_state.mstate.stack.append(global_state.new_bitvec("msize", 256)) global_state.mstate.stack.append(global_state.mstate.memory_size)
return [global_state] return [global_state]
@StateTransition() @StateTransition()
@ -1742,8 +1750,12 @@ class Instruction:
offset, length = state.stack.pop(), state.stack.pop() offset, length = state.stack.pop(), state.stack.pop()
return_data = [global_state.new_bitvec("return_data", 8)] return_data = [global_state.new_bitvec("return_data", 8)]
try: try:
concrete_offset = util.get_concrete_int(offset)
concrete_length = util.get_concrete_int(length)
state.mem_extend(concrete_offset, concrete_length)
StateTransition.check_gas_usage_limit(global_state)
return_data = state.memory[ return_data = state.memory[
util.get_concrete_int(offset) : util.get_concrete_int(offset + length) concrete_offset : concrete_offset + concrete_length
] ]
except TypeError: except TypeError:
log.debug("Return with symbolic length or offset. Not supported") log.debug("Return with symbolic length or offset. Not supported")
@ -1830,6 +1842,14 @@ class Instruction:
callee_address, callee_account, call_data, value, gas, memory_out_offset, memory_out_size = get_call_parameters( callee_address, callee_account, call_data, value, gas, memory_out_offset, memory_out_size = get_call_parameters(
global_state, self.dynamic_loader, True global_state, self.dynamic_loader, True
) )
if callee_account is not None and callee_account.code.bytecode == "":
log.debug("The call is related to ether transfer between accounts")
global_state.mstate.stack.append(
global_state.new_bitvec("retval_" + str(instr["address"]), 256)
)
return [global_state]
except ValueError as e: except ValueError as e:
log.debug( log.debug(
"Could not determine required parameters for call, putting fresh symbol on the stack. \n{}".format( "Could not determine required parameters for call, putting fresh symbol on the stack. \n{}".format(
@ -1847,7 +1867,6 @@ class Instruction:
) )
if native_result: if native_result:
return native_result return native_result
transaction = MessageCallTransaction( transaction = MessageCallTransaction(
world_state=global_state.world_state, world_state=global_state.world_state,
gas_price=environment.gasprice, gas_price=environment.gasprice,
@ -2098,7 +2117,6 @@ class Instruction:
"retval_" + str(instr["address"]), 256 "retval_" + str(instr["address"]), 256
) )
global_state.mstate.stack.append(return_value) global_state.mstate.stack.append(return_value)
global_state.mstate.constraints.append(return_value == 0)
return [global_state] return [global_state]
try: try:

@ -0,0 +1,330 @@
from mythril.laser.ethereum.svm import LaserEVM
from mythril.laser.ethereum.plugins.plugin import LaserPlugin
from mythril.laser.ethereum.plugins.signals import PluginSkipState
from mythril.laser.ethereum.state.annotation import StateAnnotation
from mythril.laser.ethereum.state.global_state import GlobalState
from mythril.laser.ethereum.transaction.transaction_models import (
ContractCreationTransaction,
)
from mythril.exceptions import UnsatError
from z3.z3types import Z3Exception
from mythril.analysis import solver
from typing import cast, List, Dict, Set
from copy import copy
import logging
log = logging.getLogger(__name__)
class DependencyAnnotation(StateAnnotation):
"""Dependency Annotation
This annotation tracks read and write access to the state during each transaction.
"""
def __init__(self):
self.storage_loaded = [] # type: List
self.storage_written = {} # type: Dict[int, List]
self.has_call = False
self.path = [0] # type: List
def __copy__(self):
result = DependencyAnnotation()
result.storage_loaded = copy(self.storage_loaded)
result.storage_written = copy(self.storage_written)
result.path = copy(self.path)
result.has_call = self.has_call
return result
def get_storage_write_cache(self, iteration: int):
if iteration not in self.storage_written:
self.storage_written[iteration] = []
return self.storage_written[iteration]
def extend_storage_write_cache(self, iteration: int, value: object):
if iteration not in self.storage_written:
self.storage_written[iteration] = [value]
else:
if value not in self.storage_written[iteration]:
self.storage_written[iteration].append(value)
class WSDependencyAnnotation(StateAnnotation):
"""Dependency Annotation for World state
This world state annotation maintains a stack of state annotations.
It is used to transfer individual state annotations from one transaction to the next.
"""
def __init__(self):
self.annotations_stack = []
def __copy__(self):
result = WSDependencyAnnotation()
result.annotations_stack = copy(self.annotations_stack)
return result
def get_dependency_annotation(state: GlobalState) -> DependencyAnnotation:
""" Returns a dependency annotation
:param state: A global state object
"""
annotations = cast(
List[DependencyAnnotation], list(state.get_annotations(DependencyAnnotation))
)
if len(annotations) == 0:
"""FIXME: Hack for carrying over state annotations from the STOP and RETURN states of
the previous states. The states are pushed on a stack in the world state annotation
and popped off the stack in the subsequent iteration. This might break if any
other strategy than bfs is used (?).
"""
try:
world_state_annotation = get_ws_dependency_annotation(state)
annotation = world_state_annotation.annotations_stack.pop()
except IndexError:
annotation = DependencyAnnotation()
state.annotate(annotation)
else:
annotation = annotations[0]
return annotation
def get_ws_dependency_annotation(state: GlobalState) -> WSDependencyAnnotation:
""" Returns the world state annotation
:param state: A global state object
"""
annotations = cast(
List[WSDependencyAnnotation],
list(state.world_state.get_annotations(WSDependencyAnnotation)),
)
if len(annotations) == 0:
annotation = WSDependencyAnnotation()
state.world_state.annotate(annotation)
else:
annotation = annotations[0]
return annotation
class DependencyPruner(LaserPlugin):
"""Dependency Pruner Plugin
For every basic block, this plugin keeps a list of storage locations that
are accessed (read) in the execution path containing that block. This map
is built up over the whole symbolic execution run.
After the initial build up of the map in the first transaction, blocks are
executed only if any of the storage locations written to in the previous
transaction can have an effect on that block or any of its successors.
"""
def __init__(self):
"""Creates DependencyPruner"""
self._reset()
def _reset(self):
self.iteration = 0
self.dependency_map = {} # type: Dict[int, List[object]]
self.protected_addresses = set() # type: Set[int]
def update_dependency_map(self, path: List[int], target_location: object) -> None:
"""Update the dependency map for the block offsets on the given path.
:param path
:param target_location
"""
try:
for address in path:
if address in self.dependency_map:
if target_location not in self.dependency_map[address]:
self.dependency_map[address].append(target_location)
else:
self.dependency_map[address] = [target_location]
except Z3Exception as e:
# This should not happen unless there's a bug in laser, such as an invalid type being generated.
log.debug("Error updating dependency map: {}".format(e))
def protect_path(self, path: List[int]) -> None:
"""Prevent an execution path of being pruned.
:param path
"""
for address in path:
self.protected_addresses.add(address)
def wanna_execute(self, address: int, storage_write_cache) -> bool:
"""Decide whether the basic block starting at 'address' should be executed.
:param address
:param storage_write_cache
"""
if address in self.protected_addresses or address not in self.dependency_map:
return True
dependencies = self.dependency_map[address]
# Return if *any* dependency is found
for location in storage_write_cache:
for dependency in dependencies:
try:
solver.get_model([location == dependency])
return True
except UnsatError:
continue
return False
def initialize(self, symbolic_vm: LaserEVM) -> None:
"""Initializes the DependencyPruner
:param symbolic_vm
"""
self._reset()
@symbolic_vm.laser_hook("start_sym_trans")
def start_sym_trans_hook():
self.iteration += 1
@symbolic_vm.post_hook("CALL")
def call_hook(state: GlobalState):
annotation = get_dependency_annotation(state)
annotation.has_call = True
self.protect_path(annotation.path)
@symbolic_vm.post_hook("JUMP")
def jump_hook(state: GlobalState):
address = state.get_current_instruction()["address"]
annotation = get_dependency_annotation(state)
_check_basic_block(address, annotation)
@symbolic_vm.pre_hook("JUMPDEST")
def jumpdest_hook(state: GlobalState):
address = state.get_current_instruction()["address"]
annotation = get_dependency_annotation(state)
_check_basic_block(address, annotation)
@symbolic_vm.post_hook("JUMPI")
def jumpi_hook(state: GlobalState):
address = state.get_current_instruction()["address"]
annotation = get_dependency_annotation(state)
_check_basic_block(address, annotation)
@symbolic_vm.pre_hook("SSTORE")
def sstore_hook(state: GlobalState):
annotation = get_dependency_annotation(state)
annotation.extend_storage_write_cache(
self.iteration, state.mstate.stack[-1]
)
@symbolic_vm.pre_hook("SLOAD")
def sload_hook(state: GlobalState):
annotation = get_dependency_annotation(state)
location = state.mstate.stack[-1]
if location not in annotation.storage_loaded:
annotation.storage_loaded.append(location)
# We backwards-annotate the path here as sometimes execution never reaches a stop or return
# (and this may change in a future transaction).
self.update_dependency_map(annotation.path, location)
@symbolic_vm.pre_hook("STOP")
def stop_hook(state: GlobalState):
_transaction_end(state)
@symbolic_vm.pre_hook("RETURN")
def return_hook(state: GlobalState):
_transaction_end(state)
def _transaction_end(state: GlobalState) -> None:
"""When a stop or return is reached, the storage locations read along the path are entered into
the dependency map for all nodes encountered in this path.
:param state:
"""
annotation = get_dependency_annotation(state)
if annotation.has_call:
self.protect_path(annotation.path)
for index in annotation.storage_loaded:
self.update_dependency_map(annotation.path, index)
def _check_basic_block(address: int, annotation: DependencyAnnotation):
"""This method is where the actual pruning happens.
:param address: Start address (bytecode offset) of the block
:param annotation
"""
# Don't skip any blocks in the contract creation transaction
if self.iteration < 2:
return
annotation.path.append(address)
if self.wanna_execute(
address, annotation.get_storage_write_cache(self.iteration - 1)
):
return
else:
log.debug(
"Skipping state: Storage slots {} not read in block at address {}".format(
annotation.get_storage_write_cache(self.iteration - 1), address
)
)
raise PluginSkipState
@symbolic_vm.laser_hook("add_world_state")
def world_state_filter_hook(state: GlobalState):
if isinstance(state.current_transaction, ContractCreationTransaction):
# Reset iteration variable
self.iteration = 0
return
world_state_annotation = get_ws_dependency_annotation(state)
annotation = get_dependency_annotation(state)
# Reset the state annotation except for storage written which is carried on to
# the next transaction
annotation.path = [0]
annotation.storage_loaded = []
annotation.has_call = False
world_state_annotation.annotations_stack.append(annotation)
log.debug(
"Iteration {}: Adding world state at address {}, end of function {}.\nDependency map: {}\nStorage written: {}".format(
self.iteration,
state.get_current_instruction()["address"],
state.node.function_name,
self.dependency_map,
annotation.storage_written[self.iteration],
)
)

@ -30,3 +30,12 @@ class PluginFactory:
) )
return InstructionCoveragePlugin() return InstructionCoveragePlugin()
@staticmethod
def build_dependency_pruner_plugin() -> LaserPlugin:
""" Creates an instance of the mutation pruner plugin"""
from mythril.laser.ethereum.plugins.implementations.dependency_pruner import (
DependencyPruner,
)
return DependencyPruner()

@ -15,3 +15,13 @@ class PluginSkipWorldState(PluginSignal):
""" """
pass pass
class PluginSkipState(PluginSignal):
""" Plugin to skip world state
Plugins that raise this signal while the add_world_state hook is being executed
will force laser to abandon that world state.
"""
pass

@ -38,7 +38,8 @@ class Storage:
self._storage[item] = symbol_factory.BitVecVal( self._storage[item] = symbol_factory.BitVecVal(
int( int(
self.dynld.read_storage( self.dynld.read_storage(
contract_address=self.address, index=int(item) contract_address=hex(self.address.value),
index=int(item),
), ),
16, 16,
), ),
@ -47,9 +48,13 @@ class Storage:
return self._storage[item] return self._storage[item]
except ValueError: except ValueError:
pass pass
if self.concrete: if self.concrete:
return symbol_factory.BitVecVal(0, 256) return symbol_factory.BitVecVal(0, 256)
self._storage[item] = symbol_factory.BitVecVal(0, 256)
self._storage[item] = symbol_factory.BitVecSym(
"storage_{}_{}".format(str(item), str(self.address)), 256
)
return self._storage[item] return self._storage[item]
def __setitem__(self, key: Union[int, str], value: Any) -> None: def __setitem__(self, key: Union[int, str], value: Any) -> None:
@ -69,6 +74,9 @@ class Storage:
storage._storage = copy(self._storage) storage._storage = copy(self._storage)
return storage return storage
def __str__(self):
return str(self._storage)
class Account: class Account:
"""Account class representing ethereum accounts.""" """Account class representing ethereum accounts."""

@ -40,6 +40,7 @@ class Environment:
self.active_function_name = "" self.active_function_name = ""
self.address = active_account.address self.address = active_account.address
self.block_number = symbol_factory.BitVecSym("block_number", 256)
# Ib # Ib
self.code = active_account.code if code is None else code self.code = active_account.code if code is None else code

@ -3,7 +3,7 @@ stack."""
from copy import copy from copy import copy
from typing import cast, Sized, Union, Any, List, Dict, Optional from typing import cast, Sized, Union, Any, List, Dict, Optional
from mythril.laser.smt import BitVec, Expression from mythril.laser.smt import BitVec, Expression, symbol_factory
from ethereum import opcodes, utils from ethereum import opcodes, utils
from mythril.laser.ethereum.evm_exceptions import ( from mythril.laser.ethereum.evm_exceptions import (
@ -32,6 +32,8 @@ class MachineStack(list):
:param element: element to be appended to the list :param element: element to be appended to the list
:function: appends the element to list if the size is less than STACK_LIMIT, else throws an error :function: appends the element to list if the size is less than STACK_LIMIT, else throws an error
""" """
if isinstance(element, int):
element = symbol_factory.BitVecVal(element, 256)
if super(MachineStack, self).__len__() >= self.STACK_LIMIT: if super(MachineStack, self).__len__() >= self.STACK_LIMIT:
raise StackOverflowException( raise StackOverflowException(
"Reached the EVM stack limit of {}, you can't append more " "Reached the EVM stack limit of {}, you can't append more "
@ -123,7 +125,12 @@ class MachineState:
""" """
if self.memory_size > start + size: if self.memory_size > start + size:
return 0 return 0
return start + size - self.memory_size
# The extension size is calculated based on the word length
new_size = utils.ceil32(start + size) // 32
old_size = self.memory_size // 32
return (new_size - old_size) * 32
def calculate_memory_gas(self, start: int, size: int): def calculate_memory_gas(self, start: int, size: int):
""" """

@ -157,6 +157,8 @@ class Memory:
self[start + i] = cast(List[Union[int, BitVec]], value)[i] self[start + i] = cast(List[Union[int, BitVec]], value)[i]
else: else:
if key >= len(self):
return
if isinstance(value, int): if isinstance(value, int):
assert 0 <= value <= 0xFF assert 0 <= value <= 0xFF
if isinstance(value, BitVec): if isinstance(value, BitVec):

@ -0,0 +1,84 @@
from mythril.laser.ethereum.state.global_state import GlobalState
from mythril.laser.ethereum.strategy.basic import BasicSearchStrategy
from mythril.laser.ethereum.state.annotation import StateAnnotation
from mythril.laser.ethereum import util
from typing import Dict, cast, List
from copy import copy
import logging
log = logging.getLogger(__name__)
class JumpdestCountAnnotation(StateAnnotation):
"""State annotation that counts the number of jumps per destination."""
def __init__(self) -> None:
self._jumpdest_count = {} # type: Dict[int, int]
def __copy__(self):
result = JumpdestCountAnnotation()
result._jumpdest_count = copy(self._jumpdest_count)
return result
class BoundedLoopsStrategy(BasicSearchStrategy):
"""Adds loop pruning to the search strategy.
Ignores JUMPI instruction if the destination was targeted >JUMPDEST_LIMIT times.
"""
def __init__(self, super_strategy: BasicSearchStrategy, *args) -> None:
""""""
self.super_strategy = super_strategy
self.jumpdest_limit = args[0][0]
log.info(
"Loaded search strategy extension: Loop bounds (limit = {})".format(
self.jumpdest_limit
)
)
BasicSearchStrategy.__init__(
self, super_strategy.work_list, super_strategy.max_depth
)
def get_strategic_global_state(self) -> GlobalState:
"""
:return:
"""
while True:
state = self.super_strategy.get_strategic_global_state()
opcode = state.get_current_instruction()["opcode"]
if opcode != "JUMPI":
return state
annotations = cast(
List[JumpdestCountAnnotation],
list(state.get_annotations(JumpdestCountAnnotation)),
)
if len(annotations) == 0:
annotation = JumpdestCountAnnotation()
state.annotate(annotation)
else:
annotation = annotations[0]
try:
target = util.get_concrete_int(state.mstate.stack[-1])
except TypeError:
return state
try:
annotation._jumpdest_count[target] += 1
except KeyError:
annotation._jumpdest_count[target] = 1
if annotation._jumpdest_count[target] > self.jumpdest_limit:
log.debug("JUMPDEST limit reached, skipping JUMPI")
continue
return state

@ -10,10 +10,11 @@ from mythril.laser.ethereum.evm_exceptions import StackUnderflowException
from mythril.laser.ethereum.evm_exceptions import VmException from mythril.laser.ethereum.evm_exceptions import VmException
from mythril.laser.ethereum.instructions import Instruction from mythril.laser.ethereum.instructions import Instruction
from mythril.laser.ethereum.iprof import InstructionProfiler from mythril.laser.ethereum.iprof import InstructionProfiler
from mythril.laser.ethereum.plugins.signals import PluginSkipWorldState from mythril.laser.ethereum.plugins.signals import PluginSkipWorldState, PluginSkipState
from mythril.laser.ethereum.state.global_state import GlobalState from mythril.laser.ethereum.state.global_state import GlobalState
from mythril.laser.ethereum.state.world_state import WorldState from mythril.laser.ethereum.state.world_state import WorldState
from mythril.laser.ethereum.strategy.basic import DepthFirstSearchStrategy from mythril.laser.ethereum.strategy.basic import DepthFirstSearchStrategy
from abc import ABCMeta
from mythril.laser.ethereum.time_handler import time_handler from mythril.laser.ethereum.time_handler import time_handler
from mythril.laser.ethereum.transaction import ( from mythril.laser.ethereum.transaction import (
ContractCreationTransaction, ContractCreationTransaction,
@ -68,6 +69,7 @@ class LaserEVM:
:param enable_iprof: Variable indicating whether instruction profiling should be turned on :param enable_iprof: Variable indicating whether instruction profiling should be turned on
""" """
self.open_states = [] # type: List[WorldState] self.open_states = [] # type: List[WorldState]
self.total_states = 0 self.total_states = 0
self.dynamic_loader = dynamic_loader self.dynamic_loader = dynamic_loader
@ -102,6 +104,9 @@ class LaserEVM:
log.info("LASER EVM initialized with dynamic loader: " + str(dynamic_loader)) log.info("LASER EVM initialized with dynamic loader: " + str(dynamic_loader))
def extend_strategy(self, extension: ABCMeta, *args) -> None:
self.strategy = extension(self.strategy, args)
def sym_exec( def sym_exec(
self, self,
world_state: WorldState = None, world_state: WorldState = None,
@ -121,7 +126,7 @@ class LaserEVM:
:param creation_code The creation code to create the target contract in the symbolic environment :param creation_code The creation code to create the target contract in the symbolic environment
:param contract_name The name that the created account should be associated with :param contract_name The name that the created account should be associated with
""" """
pre_configuration_mode = world_state is not None and target_address is not None pre_configuration_mode = target_address is not None
scratch_mode = creation_code is not None and contract_name is not None scratch_mode = creation_code is not None and contract_name is not None
if pre_configuration_mode == scratch_mode: if pre_configuration_mode == scratch_mode:
raise ValueError("Symbolic execution started with invalid parameters") raise ValueError("Symbolic execution started with invalid parameters")
@ -140,14 +145,16 @@ class LaserEVM:
elif scratch_mode: elif scratch_mode:
log.info("Starting contract creation transaction") log.info("Starting contract creation transaction")
created_account = execute_contract_creation( created_account = execute_contract_creation(
self, creation_code, contract_name self, creation_code, contract_name, world_state=world_state
) )
log.info( log.info(
"Finished contract creation, found {} open states".format( "Finished contract creation, found {} open states".format(
len(self.open_states) len(self.open_states)
) )
) )
if len(self.open_states) == 0: if len(self.open_states) == 0:
log.warning( log.warning(
"No contract was created during the execution of contract creation " "No contract was created during the execution of contract creation "
@ -177,8 +184,9 @@ class LaserEVM:
:param address: Address of the contract :param address: Address of the contract
:return: :return:
""" """
for i in range(self.transaction_count):
self.time = datetime.now() self.time = datetime.now()
for i in range(self.transaction_count):
log.info( log.info(
"Starting message call transaction, iteration: {}, {} initial states".format( "Starting message call transaction, iteration: {}, {} initial states".format(
i, len(self.open_states) i, len(self.open_states)
@ -210,8 +218,7 @@ class LaserEVM:
if ( if (
self.execution_timeout self.execution_timeout
and self.time and self.time + timedelta(seconds=self.execution_timeout)
+ timedelta(seconds=self.execution_timeout / self.transaction_count)
<= datetime.now() <= datetime.now()
and not create and not create
): ):
@ -267,7 +274,12 @@ class LaserEVM:
self._add_world_state(global_state) self._add_world_state(global_state)
return [], None return [], None
try:
self._execute_pre_hook(op_code, global_state) self._execute_pre_hook(op_code, global_state)
except PluginSkipState:
self._add_world_state(global_state)
return [], None
try: try:
new_global_states = Instruction( new_global_states = Instruction(
op_code, self.dynamic_loader, self.iprof op_code, self.dynamic_loader, self.iprof
@ -431,11 +443,16 @@ class LaserEVM:
new_node.flags |= NodeFlags.FUNC_ENTRY new_node.flags |= NodeFlags.FUNC_ENTRY
except StackUnderflowException: except StackUnderflowException:
new_node.flags |= NodeFlags.FUNC_ENTRY new_node.flags |= NodeFlags.FUNC_ENTRY
address = state.environment.code.instruction_list[state.mstate.pc]["address"] address = state.environment.code.instruction_list[state.mstate.pc]["address"]
environment = state.environment environment = state.environment
disassembly = environment.code disassembly = environment.code
if address in disassembly.address_to_function_name: if isinstance(
state.world_state.transaction_sequence[-1], ContractCreationTransaction
):
environment.active_function_name = "constructor"
elif address in disassembly.address_to_function_name:
# Enter a new function # Enter a new function
environment.active_function_name = disassembly.address_to_function_name[ environment.active_function_name = disassembly.address_to_function_name[
address address
@ -533,7 +550,10 @@ class LaserEVM:
for hook in self.post_hooks[op_code]: for hook in self.post_hooks[op_code]:
for global_state in global_states: for global_state in global_states:
try:
hook(global_state) hook(global_state)
except PluginSkipState:
global_states.remove(global_state)
def pre_hook(self, op_code: str) -> Callable: def pre_hook(self, op_code: str) -> Callable:
""" """

@ -88,7 +88,7 @@ def _setup_global_state_for_execution(laser_evm, transaction) -> None:
condition=None, condition=None,
) )
) )
global_state.world_state.transaction_sequence.append(transaction)
global_state.node = new_node global_state.node = new_node
new_node.states.append(global_state) new_node.states.append(global_state)
laser_evm.work_list.append(global_state) laser_evm.work_list.append(global_state)

@ -68,7 +68,7 @@ def execute_message_call(laser_evm, callee_address: BitVec) -> None:
def execute_contract_creation( def execute_contract_creation(
laser_evm, contract_initialization_code, contract_name=None laser_evm, contract_initialization_code, contract_name=None, world_state=None
) -> Account: ) -> Account:
"""Executes a contract creation transaction from all open states. """Executes a contract creation transaction from all open states.
@ -80,15 +80,9 @@ def execute_contract_creation(
# TODO: Resolve circular import between .transaction and ..svm to import LaserEVM here # TODO: Resolve circular import between .transaction and ..svm to import LaserEVM here
del laser_evm.open_states[:] del laser_evm.open_states[:]
world_state = WorldState() world_state = world_state or WorldState()
open_states = [world_state] open_states = [world_state]
new_account = world_state.create_account( new_account = None
0, concrete_storage=True, dynamic_loader=None, creator=CREATOR_ADDRESS
)
if contract_name:
new_account.contract_name = contract_name
for open_world_state in open_states: for open_world_state in open_states:
next_transaction_id = get_next_transaction_id() next_transaction_id = get_next_transaction_id()
transaction = ContractCreationTransaction( transaction = ContractCreationTransaction(
@ -103,13 +97,14 @@ def execute_contract_creation(
), ),
code=Disassembly(contract_initialization_code), code=Disassembly(contract_initialization_code),
caller=symbol_factory.BitVecVal(CREATOR_ADDRESS, 256), caller=symbol_factory.BitVecVal(CREATOR_ADDRESS, 256),
callee_account=new_account, contract_name=contract_name,
call_data=[], call_data=[],
call_value=symbol_factory.BitVecSym( call_value=symbol_factory.BitVecSym(
"call_value{}".format(next_transaction_id), 256 "call_value{}".format(next_transaction_id), 256
), ),
) )
_setup_global_state_for_execution(laser_evm, transaction) _setup_global_state_for_execution(laser_evm, transaction)
new_account = new_account or transaction.callee_account
laser_evm.exec(True) laser_evm.exec(True)
return new_account return new_account

@ -2,6 +2,7 @@
execution.""" execution."""
import array import array
from copy import deepcopy
from z3 import ExprRef from z3 import ExprRef
from typing import Union, Optional, cast from typing import Union, Optional, cast
@ -161,12 +162,37 @@ class MessageCallTransaction(BaseTransaction):
class ContractCreationTransaction(BaseTransaction): class ContractCreationTransaction(BaseTransaction):
"""Transaction object models an transaction.""" """Transaction object models an transaction."""
def __init__(self, *args, **kwargs) -> None: def __init__(
# Remove ignore after https://github.com/python/mypy/issues/4335 is fixed self,
super().__init__(*args, **kwargs, init_call_data=False) # type: ignore world_state: WorldState,
caller: ExprRef = None,
call_data=None,
identifier: Optional[str] = None,
gas_price=None,
gas_limit=None,
origin=None,
code=None,
call_value=None,
contract_name=None,
) -> None:
self.prev_world_state = deepcopy(world_state)
callee_account = world_state.create_account(
0, concrete_storage=True, creator=caller.value
)
callee_account.contract_name = contract_name
# TODO: set correct balance for new account # TODO: set correct balance for new account
self.callee_account = self.callee_account or self.world_state.create_account( super().__init__(
0, concrete_storage=True world_state=world_state,
callee_account=callee_account,
caller=caller,
call_data=call_data,
identifier=identifier,
gas_price=gas_price,
gas_limit=gas_limit,
origin=origin,
code=code,
call_value=call_value,
init_call_data=False,
) )
def initial_global_state(self) -> GlobalState: def initial_global_state(self) -> GlobalState:

@ -243,6 +243,13 @@ class BitVec(Expression[z3.BitVecRef]):
""" """
return self._handle_shift(other, rshift) return self._handle_shift(other, rshift)
def __hash__(self) -> int:
"""
:return:
"""
return self.raw.__hash__()
def _comparison_helper( def _comparison_helper(
a: BitVec, b: BitVec, operation: Callable, default_value: bool, inputs_equal: bool a: BitVec, b: BitVec, operation: Callable, default_value: bool, inputs_equal: bool

@ -35,8 +35,10 @@ class MythrilAnalyzer:
address: Optional[str] = None, address: Optional[str] = None,
max_depth: Optional[int] = None, max_depth: Optional[int] = None,
execution_timeout: Optional[int] = None, execution_timeout: Optional[int] = None,
loop_bound: Optional[int] = None,
create_timeout: Optional[int] = None, create_timeout: Optional[int] = None,
enable_iprof: bool = False, enable_iprof: bool = False,
disable_dependency_pruning: bool = False,
): ):
""" """
@ -53,8 +55,10 @@ class MythrilAnalyzer:
self.address = address self.address = address
self.max_depth = max_depth self.max_depth = max_depth
self.execution_timeout = execution_timeout self.execution_timeout = execution_timeout
self.loop_bound = loop_bound
self.create_timeout = create_timeout self.create_timeout = create_timeout
self.enable_iprof = enable_iprof self.enable_iprof = enable_iprof
self.disable_dependency_pruning = disable_dependency_pruning
def dump_statespace(self, contract: EVMContract = None) -> str: def dump_statespace(self, contract: EVMContract = None) -> str:
""" """
@ -75,6 +79,8 @@ class MythrilAnalyzer:
execution_timeout=self.execution_timeout, execution_timeout=self.execution_timeout,
create_timeout=self.create_timeout, create_timeout=self.create_timeout,
enable_iprof=self.enable_iprof, enable_iprof=self.enable_iprof,
disable_dependency_pruning=self.disable_dependency_pruning,
run_analysis_modules=False,
) )
return get_serializable_statespace(sym) return get_serializable_statespace(sym)
@ -108,6 +114,8 @@ class MythrilAnalyzer:
transaction_count=transaction_count, transaction_count=transaction_count,
create_timeout=self.create_timeout, create_timeout=self.create_timeout,
enable_iprof=self.enable_iprof, enable_iprof=self.enable_iprof,
disable_dependency_pruning=self.disable_dependency_pruning,
run_analysis_modules=False,
) )
return generate_graph(sym, physics=enable_physics, phrackify=phrackify) return generate_graph(sym, physics=enable_physics, phrackify=phrackify)
@ -140,12 +148,15 @@ class MythrilAnalyzer:
), ),
max_depth=self.max_depth, max_depth=self.max_depth,
execution_timeout=self.execution_timeout, execution_timeout=self.execution_timeout,
loop_bound=self.loop_bound,
create_timeout=self.create_timeout, create_timeout=self.create_timeout,
transaction_count=transaction_count, transaction_count=transaction_count,
modules=modules, modules=modules,
compulsory_statespace=False, compulsory_statespace=False,
enable_iprof=self.enable_iprof, enable_iprof=self.enable_iprof,
disable_dependency_pruning=self.disable_dependency_pruning,
) )
issues = fire_lasers(sym, modules) issues = fire_lasers(sym, modules)
except KeyboardInterrupt: except KeyboardInterrupt:
log.critical("Keyboard Interrupt") log.critical("Keyboard Interrupt")

@ -8,7 +8,7 @@ ethereum>=2.3.2
ethereum-input-decoder>=0.2.2 ethereum-input-decoder>=0.2.2
eth-hash>=0.1.0 eth-hash>=0.1.0
eth-keyfile>=0.5.1 eth-keyfile>=0.5.1
eth-keys>=0.2.0b3 eth-keys>=0.2.0b3,<0.3.0
eth-rlp>=0.1.0 eth-rlp>=0.1.0
eth-tester==0.1.0b32 eth-tester==0.1.0b32
eth-typing>=2.0.0 eth-typing>=2.0.0
@ -25,6 +25,6 @@ pytest_mock
requests requests
rlp>=1.0.1 rlp>=1.0.1
transaction>=2.2.1 transaction>=2.2.1
z3-solver-mythril>=4.8.4.1 z3-solver>=4.8.5.0
pysha3 pysha3
matplotlib matplotlib

@ -9,21 +9,82 @@ publish to pypi w/o having to convert Readme.md to RST:
""" """
from setuptools import setup, find_packages from setuptools import setup, find_packages
from setuptools.command.install import install from setuptools.command.install import install
from pathlib import Path
import sys import sys
import os import os
import io
# To make lint checkers happy we set VERSION here, but # Package meta-data.
# it is redefined by the exec below NAME = "mythril"
DESCRIPTION = "Security analysis tool for Ethereum smart contracts"
URL = "https://github.com/ConsenSys/mythril"
AUTHOR = "ConsenSys Dilligence"
AUTHOR_MAIL = None
REQUIRES_PYTHON = ">=3.5.0"
# What packages are required for this module to be executed?
REQUIRED = [
"coloredlogs>=10.0",
"py_ecc==1.4.2",
"ethereum>=2.3.2",
"z3-solver>=4.8.5.0",
"requests",
"py-solc",
"plyvel",
"eth_abi==1.3.0",
"eth-utils>=1.0.1",
"eth-account>=0.1.0a2,<=0.3.0",
"eth-hash>=0.1.0",
"eth-keyfile>=0.5.1",
"eth-keys>=0.2.0b3,<0.3.0",
"eth-rlp>=0.1.0",
"eth-tester==0.1.0b32",
"eth-typing>=2.0.0",
"coverage",
"jinja2>=2.9",
"rlp>=1.0.1",
"transaction>=2.2.1",
"py-flags",
"mock",
"configparser>=3.5.0",
"persistent>=4.2.0",
"ethereum-input-decoder>=0.2.2",
"matplotlib",
]
TESTS_REQUIRE = ["mypy", "pytest>=3.6.0", "pytest_mock", "pytest-cov"]
# What packages are optional?
EXTRAS = {
# 'fancy feature': ['django'],
}
# If version is set to None then it will be fetched from __version__.py
VERSION = None VERSION = None
# Package version (vX.Y.Z). It must match git tag being used for CircleCI here = os.path.abspath(os.path.dirname(__file__))
# deployment; otherwise the build will failed.
# Import the README and use it as the long-description.
# Note: this will only work if 'README.md' is present in your MANIFEST.in file!
try:
with io.open(os.path.join(here, "README.md"), encoding="utf-8") as f:
long_description = "\n" + f.read()
except FileNotFoundError:
long_description = DESCRIPTION
version_path = (Path(__file__).parent / "mythril" / "version.py").absolute()
exec(open(str(version_path), "r").read())
# Load the package's __version__.py module as a dictionary.
about = {}
if not VERSION:
project_slug = NAME.lower().replace("-", "_").replace(" ", "_")
with open(os.path.join(here, project_slug, "__version__.py")) as f:
exec(f.read(), about)
else:
about["__version__"] = VERSION
# Package version (vX.Y.Z). It must match git tag being used for CircleCI
# deployment; otherwise the build will failed.
class VerifyVersionCommand(install): class VerifyVersionCommand(install):
"""Custom command to verify that the git tag matches our version.""" """Custom command to verify that the git tag matches our version."""
@ -33,32 +94,22 @@ class VerifyVersionCommand(install):
"""""" """"""
tag = os.getenv("CIRCLE_TAG") tag = os.getenv("CIRCLE_TAG")
if tag != VERSION: if tag != about["__version__"]:
info = "Git tag: {0} does not match the version of this app: {1}".format( info = "Git tag: {0} does not match the version of this app: {1}".format(
tag, VERSION tag, about["__version__"]
) )
sys.exit(info) sys.exit(info)
def read_file(fname):
"""return file contents.
:param fname: path relative to setup.py
:return: file contents
"""
with open(os.path.join(os.path.dirname(__file__), fname), "r") as fd:
return fd.read()
setup( setup(
name="mythril", name=NAME,
version=VERSION[1:], version=about["__version__"][1:],
description="Security analysis tool for Ethereum smart contracts", description=DESCRIPTION,
long_description=read_file("README.md") if os.path.isfile("README.md") else "", long_description=long_description,
long_description_content_type="text/markdown", # requires twine and recent setuptools long_description_content_type="text/markdown", # requires twine and recent setuptools
url="https://github.com/b-mueller/mythril", url=URL,
author="Bernhard Mueller", author=AUTHOR,
author_email="bernhard.mueller11@gmail.com", author_mail=AUTHOR_MAIL,
license="MIT", license="MIT",
classifiers=[ classifiers=[
"Development Status :: 3 - Alpha", "Development Status :: 3 - Alpha",
@ -71,37 +122,10 @@ setup(
], ],
keywords="hacking disassembler security ethereum", keywords="hacking disassembler security ethereum",
packages=find_packages(exclude=["contrib", "docs", "tests"]), packages=find_packages(exclude=["contrib", "docs", "tests"]),
install_requires=[ install_requires=REQUIRED,
"coloredlogs>=10.0", tests_require=TESTS_REQUIRE,
"py_ecc==1.4.2", python_requires=REQUIRES_PYTHON,
"ethereum>=2.3.2", extras_require=EXTRAS,
"z3-solver-mythril>=4.8.4.1",
"requests",
"py-solc",
"plyvel",
"eth_abi==1.3.0",
"eth-utils>=1.0.1",
"eth-account>=0.1.0a2,<=0.3.0",
"eth-hash>=0.1.0",
"eth-keyfile>=0.5.1",
"eth-keys>=0.2.0b3",
"eth-rlp>=0.1.0",
"eth-tester==0.1.0b32",
"eth-typing>=2.0.0",
"coverage",
"jinja2>=2.9",
"rlp>=1.0.1",
"transaction>=2.2.1",
"py-flags",
"mock",
"configparser>=3.5.0",
"persistent>=4.2.0",
"ethereum-input-decoder>=0.2.2",
"matplotlib",
],
tests_require=["mypy", "pytest>=3.6.0", "pytest_mock", "pytest-cov"],
python_requires=">=3.5",
extras_require={},
package_data={"mythril.analysis.templates": ["*"], "mythril.support.assets": ["*"]}, package_data={"mythril.analysis.templates": ["*"], "mythril.support.assets": ["*"]},
include_package_data=True, include_package_data=True,
entry_points={"console_scripts": ["myth=mythril.interfaces.cli:main"]}, entry_points={"console_scripts": ["myth=mythril.interfaces.cli:main"]},

@ -0,0 +1,37 @@
{
"BlockNumberDynamicJump0_AfterJumpdest" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/BlockNumberDynamicJump0_AfterJumpdestFiller.json",
"sourceHash" : "edd08521b4a9bc311f2ba99d15c867d9a98da1e9665d9b173ff85621e170e896"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x6023600843015660015b600255",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6023600843015660015b600255",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"BlockNumberDynamicJump0_AfterJumpdest3" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/BlockNumberDynamicJump0_AfterJumpdest3Filler.json",
"sourceHash" : "1e86dccd54bd74436a1bbfe11302b675761fc6138ebd1461231acd29ee97b0f0"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x6023600b60085043015660015b600255",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6023600b60085043015660015b600255",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"BlockNumberDynamicJump0_foreverOutOfGas" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/BlockNumberDynamicJump0_foreverOutOfGasFiller.json",
"sourceHash" : "0900beba73811b8aafaefadcff3a7cd9954ccb5e4986b9cf03ca44881efd4e9c"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x5b600060000156",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x5b600060000156",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,52 @@
{
"BlockNumberDynamicJump0_jumpdest0" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/BlockNumberDynamicJump0_jumpdest0Filler.json",
"sourceHash" : "80bfa0a5db107e6f083dccdd3091e35add39a4eaac4a8757de8a3e4008c5d646"
},
"callcreates" : [
],
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x6023600743015660015b600255",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"gas" : "0x013869",
"logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"out" : "0x",
"post" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6023600743015660015b600255",
"nonce" : "0x00",
"storage" : {
"0x02" : "0x23"
}
}
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6023600743015660015b600255",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,52 @@
{
"BlockNumberDynamicJump0_jumpdest2" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/BlockNumberDynamicJump0_jumpdest2Filler.json",
"sourceHash" : "e86a87e0b5cde7d47f1e5dc295600ecc60b7344b3fb4ad64609d6b87fae642f8"
},
"callcreates" : [
],
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x6023600a60085043015660015b600255",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"gas" : "0x013864",
"logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"out" : "0x",
"post" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6023600a60085043015660015b600255",
"nonce" : "0x00",
"storage" : {
"0x02" : "0x23"
}
}
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6023600a60085043015660015b600255",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"BlockNumberDynamicJump0_withoutJumpdest" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/BlockNumberDynamicJump0_withoutJumpdestFiller.json",
"sourceHash" : "6f1fc4a9e5dff3e5d3071c576aba5b2ee1f30d7dcace92e6c6d230cfd415efd7"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x602360074301566001600255",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x602360074301566001600255",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"BlockNumberDynamicJump1" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/BlockNumberDynamicJump1Filler.json",
"sourceHash" : "88e43b5985cc4dfbcbc8476c570157e6e7bc0ee0cb3609e9e9f3dd9aa2a3a528"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x620fffff620fffff01430156",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x620fffff620fffff01430156",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"BlockNumberDynamicJumpInsidePushWithJumpDest" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/BlockNumberDynamicJumpInsidePushWithJumpDestFiller.json",
"sourceHash" : "ca0f21a5f52a8d4f2d6e1eed650f68d5f8f40e567cf17984aacc228adfa578ab"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x6004430156655b6001600155",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6004430156655b6001600155",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"BlockNumberDynamicJumpInsidePushWithoutJumpDest" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/BlockNumberDynamicJumpInsidePushWithoutJumpDestFiller.json",
"sourceHash" : "183a4ce2d0f208630db92539aaf4e38fc3025b44a2842e19e39e956465449fe5"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x600543015661eeff",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x600543015661eeff",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"BlockNumberDynamicJumpi0" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/BlockNumberDynamicJumpi0Filler.json",
"sourceHash" : "620bba922f5a1732f512d726a26e71b09d3837018a66a9aacb581b212a4f4b13"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x6023600160094301576001600255",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6023600160094301576001600255",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,52 @@
{
"BlockNumberDynamicJumpi1" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/BlockNumberDynamicJumpi1Filler.json",
"sourceHash" : "91d6fe3848fbdafff10b7bd503d560f2c614d6b53ed16b51821d3026f4a3a544"
},
"callcreates" : [
],
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x6023600060094301576001600255",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"gas" : "0x013862",
"logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"out" : "0x",
"post" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6023600060094301576001600255",
"nonce" : "0x00",
"storage" : {
"0x02" : "0x01"
}
}
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6023600060094301576001600255",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"BlockNumberDynamicJumpi1_jumpdest" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/BlockNumberDynamicJumpi1_jumpdestFiller.json",
"sourceHash" : "420810639c740487f7b8d18b29f28dcfb7d762b1aa4aa9b9f8b91928da66a539"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x60236001600a43015760015b600255",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x60236001600a43015760015b600255",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,52 @@
{
"BlockNumberDynamicJumpiAfterStop" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/BlockNumberDynamicJumpiAfterStopFiller.json",
"sourceHash" : "7331cec587701bf695329ad94c7e62963827209faffac3b24eb59341ccb1a925"
},
"callcreates" : [
],
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x600160084301570060015b6002600355",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"gas" : "0x013864",
"logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"out" : "0x",
"post" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x600160084301570060015b6002600355",
"nonce" : "0x00",
"storage" : {
"0x03" : "0x02"
}
}
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x600160084301570060015b6002600355",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"BlockNumberDynamicJumpiOutsideBoundary" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/BlockNumberDynamicJumpiOutsideBoundaryFiller.json",
"sourceHash" : "db80ec0400be086e2a316a91ee7a5f87db06ff6a5b0ad27a50ba692049a54b1c"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x60017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04301576002600355",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x60017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04301576002600355",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"BlockNumberDynamicJumpifInsidePushWithJumpDest" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/BlockNumberDynamicJumpifInsidePushWithJumpDestFiller.json",
"sourceHash" : "4b52bc3a45a966d0032eb01b3fdb8a225af48fa4f5a017b5dff3d4d88d710337"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x60016006430157655b6001600155",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x60016006430157655b6001600155",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"BlockNumberDynamicJumpifInsidePushWithoutJumpDest" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/BlockNumberDynamicJumpifInsidePushWithoutJumpDestFiller.json",
"sourceHash" : "3fccd0c56ebfd40dea69fec03d009967a80ddf93e9a68af81efd2d1645e27fcb"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x6001600743015761eeff",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6001600743015761eeff",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,38 @@
{
"DyanmicJump0_outOfBoundary" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DyanmicJump0_outOfBoundaryFiller.json",
"sourceHash" : "a2ae635e97f7381a5af1ea432d210faf19f4f84e8e0e6874bd48005674bfea92"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x6023600760005401566001600255",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6023600760005401566001600255",
"nonce" : "0x00",
"storage" : {
"0x00" : "0x04"
}
}
}
}
}

@ -0,0 +1,37 @@
{
"DynamicJump0_AfterJumpdest" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJump0_AfterJumpdestFiller.json",
"sourceHash" : "605f607251cd4a7c73bd7c814edcada6a9008fcd2896af2caf371beb31db196b"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x602360086003015660015b600255",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x602360086003015660015b600255",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"DynamicJump0_AfterJumpdest3" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJump0_AfterJumpdest3Filler.json",
"sourceHash" : "b7367314ce66b1a937c05550ac901971b5850d2a0ef03acf1feb4d6c9f38925d"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x6023600b6008506003015660015b600255",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6023600b6008506003015660015b600255",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"DynamicJump0_foreverOutOfGas" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJump0_foreverOutOfGasFiller.json",
"sourceHash" : "68b687a344b0f44d7459e095f05f6b302ee3f5d15b3c3e7765d5642fb1f46689"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x5b600060000156",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x5b600060000156",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,52 @@
{
"DynamicJump0_jumpdest0" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJump0_jumpdest0Filler.json",
"sourceHash" : "3ab9d036e3e345909b19022f4c3b80d081d214eb5c79b8e94e0f2c660ab01ec7"
},
"callcreates" : [
],
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x602360076003015660015b600255",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"gas" : "0x013868",
"logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"out" : "0x",
"post" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x602360076003015660015b600255",
"nonce" : "0x00",
"storage" : {
"0x02" : "0x23"
}
}
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x602360076003015660015b600255",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,52 @@
{
"DynamicJump0_jumpdest2" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJump0_jumpdest2Filler.json",
"sourceHash" : "a7e9d9f046151930ef4b51b8dacce5304ce74c3f5ead80f1e52f783b1a704378"
},
"callcreates" : [
],
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x6023600a6008506003015660015b600255",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"gas" : "0x013863",
"logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"out" : "0x",
"post" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6023600a6008506003015660015b600255",
"nonce" : "0x00",
"storage" : {
"0x02" : "0x23"
}
}
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6023600a6008506003015660015b600255",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"DynamicJump0_withoutJumpdest" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJump0_withoutJumpdestFiller.json",
"sourceHash" : "84c524e0cafc2ddcebdef720e46a23d10061f4a35bb06bfe7bdfe444990593a6"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x60236007600301566001600255",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x60236007600301566001600255",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"DynamicJump1" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJump1Filler.json",
"sourceHash" : "2369bac56afc1e0946f608c52027fbc88faf3844cdc2fa46954a0916221b8432"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x620fffff620fffff0160030156",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x620fffff620fffff0160030156",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,52 @@
{
"DynamicJumpAfterStop" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJumpAfterStopFiller.json",
"sourceHash" : "5ba8a9cb65319cdc8e574e0eb59695b55158e6d723945bac3b96573a576a86a8"
},
"callcreates" : [
],
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x6008600101560060015b6002600355",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"gas" : "0x013868",
"logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"out" : "0x",
"post" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6008600101560060015b6002600355",
"nonce" : "0x00",
"storage" : {
"0x03" : "0x02"
}
}
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6008600101560060015b6002600355",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"DynamicJumpInsidePushWithJumpDest" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJumpInsidePushWithJumpDestFiller.json",
"sourceHash" : "3f3586292e12e696029f38f833fe8c7cea86a0e7cda83c0cbe783aa2c3b22b0c"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x600460030156655b6001600155",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x600460030156655b6001600155",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"DynamicJumpInsidePushWithoutJumpDest" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJumpInsidePushWithoutJumpDestFiller.json",
"sourceHash" : "4e320bace2f65884d59f95dbbba6e4f9aea39e243bffd309be9bb6c5a3c1bedb"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x60056003015661eeff",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x60056003015661eeff",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"DynamicJumpJD_DependsOnJumps0" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJumpJD_DependsOnJumps0Filler.json",
"sourceHash" : "e96143bec9697fb0d565026f5fcc5ed70833bf89eb8c63aa87e0155b4e61d8f4"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x01",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x6009436006575b566001",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6009436006575b566001",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,52 @@
{
"DynamicJumpJD_DependsOnJumps1" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJumpJD_DependsOnJumps1Filler.json",
"sourceHash" : "853f3f35881b9db63508e68d34cf87a1a3697fdc969821c0659462242d859c2b"
},
"callcreates" : [
],
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x01",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x600a436006575b5660015b6001600155",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"gas" : "0x01385e",
"logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"out" : "0x",
"post" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x600a436006575b5660015b6001600155",
"nonce" : "0x00",
"storage" : {
"0x01" : "0x01"
}
}
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x600a436006575b5660015b6001600155",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,52 @@
{
"DynamicJumpPathologicalTest0" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJumpPathologicalTest0Filler.json",
"sourceHash" : "6862ac2a8fad0b3c043493fcd9c9a7e8a549c9f3ef34019ac0d7bcfd096a8040"
},
"callcreates" : [
],
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x04",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x435660615b4343025660615b60615b5b5b6001600155",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"gas" : "0x01385d",
"logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"out" : "0x",
"post" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x435660615b4343025660615b60615b5b5b6001600155",
"nonce" : "0x00",
"storage" : {
"0x01" : "0x01"
}
}
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x435660615b4343025660615b60615b5b5b6001600155",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"DynamicJumpPathologicalTest1" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJumpPathologicalTest1Filler.json",
"sourceHash" : "dfbad553b0e28f37f6a5d72740e2ae6bf17ce1b19c62caf2cc2a99c0d1d84e05"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x04",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x435660615b4343025660615b60615b605b6001600155",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x435660615b4343025660615b60615b605b6001600155",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"DynamicJumpPathologicalTest2" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJumpPathologicalTest2Filler.json",
"sourceHash" : "957bc609a0322452da86a59c96e7eea17c5463dcd7bad6ed97b57c6460a90b80"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x04",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x435631615b60615b60615b606001600155",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x435631615b60615b60615b606001600155",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"DynamicJumpPathologicalTest3" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJumpPathologicalTest3Filler.json",
"sourceHash" : "a906b3dcb41da1cdacb67bdf49111ecd2bdaab0e3584dbd3993ef0f0555766f6"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x07",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x435631615b60615b60615b606001600155",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x435631615b60615b60615b606001600155",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,52 @@
{
"DynamicJumpStartWithJumpDest" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJumpStartWithJumpDestFiller.json",
"sourceHash" : "4fb19acd65703dce630cb655f52e98d2de72d8a790d53b895d0e7bce603d4166"
},
"callcreates" : [
],
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x5b586000555960115758600052596000575b58600055",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"gas" : "0x011126",
"logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"out" : "0x",
"post" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x5b586000555960115758600052596000575b58600055",
"nonce" : "0x00",
"storage" : {
"0x00" : "0x12"
}
}
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x5b586000555960115758600052596000575b58600055",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,51 @@
{
"DynamicJump_value1" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJump_value1Filler.json",
"sourceHash" : "20503c4d21019e3d9d87b95365a0d0417fb7e163265f938d6e3f685377a2c5da"
},
"callcreates" : [
],
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x60016002600334565b5050600052596000f35b50600052596000f35b600052596000f3",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x08"
},
"gas" : "0x01867a",
"logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"out" : "0x0000000000000000000000000000000000000000000000000000000000000001",
"post" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x60016002600334565b5050600052596000f35b50600052596000f35b600052596000f3",
"nonce" : "0x00",
"storage" : {
}
}
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x60016002600334565b5050600052596000f35b50600052596000f35b600052596000f3",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,51 @@
{
"DynamicJump_value2" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJump_value2Filler.json",
"sourceHash" : "00631169ba52dbbd3d7ac8529dd960c6b297226c0f177ee3e0ef8bd202b4b1ff"
},
"callcreates" : [
],
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x60016002600334565b5050600052596000f35b50600052596000f35b600052596000f3",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x12"
},
"gas" : "0x01867c",
"logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"out" : "0x0000000000000000000000000000000000000000000000000000000000000002",
"post" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x60016002600334565b5050600052596000f35b50600052596000f35b600052596000f3",
"nonce" : "0x00",
"storage" : {
}
}
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x60016002600334565b5050600052596000f35b50600052596000f35b600052596000f3",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,51 @@
{
"DynamicJump_value3" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJump_value3Filler.json",
"sourceHash" : "a1477eeb656e1f4d09c07f020a088cc099f6661fce88f137754b1d45550d7218"
},
"callcreates" : [
],
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x60016002600334565b5050600052596000f35b50600052596000f35b600052596000f3",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x1b"
},
"gas" : "0x01867e",
"logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"out" : "0x0000000000000000000000000000000000000000000000000000000000000003",
"post" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x60016002600334565b5050600052596000f35b50600052596000f35b600052596000f3",
"nonce" : "0x00",
"storage" : {
}
}
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x60016002600334565b5050600052596000f35b50600052596000f35b600052596000f3",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"DynamicJump_valueUnderflow" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJump_valueUnderflowFiller.json",
"sourceHash" : "37f012edfeaa13e4819617af0e8dc2fd71d738a2463b1f61bfd86de0ef980f1b"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x60016002600334565b5050600052596000f35b50600052596000f35b505050600052596000f3",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x1b"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x60016002600334565b5050600052596000f35b50600052596000f35b505050600052596000f3",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"DynamicJumpi0" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJumpi0Filler.json",
"sourceHash" : "394cae3e06d120cc1a5df5e14cfae3598d62e1fefa06dce4055c6ff59c367b63"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x602360016009600301576001600255",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x602360016009600301576001600255",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,52 @@
{
"DynamicJumpi1" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJumpi1Filler.json",
"sourceHash" : "31d323d1c24dd2c2ea5a4e18fd0765bfa1be189add7e395b2679bf5a98e492ab"
},
"callcreates" : [
],
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x602360006009600301576001600255",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"gas" : "0x013861",
"logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"out" : "0x",
"post" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x602360006009600301576001600255",
"nonce" : "0x00",
"storage" : {
"0x02" : "0x01"
}
}
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x602360006009600301576001600255",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"DynamicJumpi1_jumpdest" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJumpi1_jumpdestFiller.json",
"sourceHash" : "fb4060a7f68c0f3ad9643dcfc93fa90ea0fe6123e65499ae65f400e22db20bcc"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x60236001600a6003015760015b600255",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x60236001600a6003015760015b600255",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,52 @@
{
"DynamicJumpiAfterStop" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJumpiAfterStopFiller.json",
"sourceHash" : "d61d45e9d5ea3e13d2a8a33965c9c620207156e0b4baf2dfed9a0288c7e8053b"
},
"callcreates" : [
],
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x60016008600301570060015b6002600355",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"gas" : "0x013863",
"logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"out" : "0x",
"post" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x60016008600301570060015b6002600355",
"nonce" : "0x00",
"storage" : {
"0x03" : "0x02"
}
}
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x60016008600301570060015b6002600355",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"DynamicJumpiOutsideBoundary" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJumpiOutsideBoundaryFiller.json",
"sourceHash" : "d550aa41047204857f27b7a80a1309520f3e59b41a87ef3e40492032706e5a88"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x60017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0600301576002600355",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x60017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0600301576002600355",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"DynamicJumpifInsidePushWithJumpDest" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJumpifInsidePushWithJumpDestFiller.json",
"sourceHash" : "05f764377385769e93afe47dbc0293921c211b4e68afce30f18cba4bb5955420"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x6001600660030157655b6001600155",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6001600660030157655b6001600155",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,37 @@
{
"DynamicJumpifInsidePushWithoutJumpDest" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/DynamicJumpifInsidePushWithoutJumpDestFiller.json",
"sourceHash" : "cadedb13e141e3b7bf1f0763cc831dace3ff150fc623e81fb00e798168d01188"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x00",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x600160076003015761eeff",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x600160076003015761eeff",
"nonce" : "0x00",
"storage" : {
}
}
}
}
}

@ -0,0 +1,38 @@
{
"JDfromStorageDynamicJump0_AfterJumpdest" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/JDfromStorageDynamicJump0_AfterJumpdestFiller.json",
"sourceHash" : "06126bb58e44948750e412ea81a3140fcc72b63acec0090939706f3ceb403ae8"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x60236008600054015660015b600255",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x60236008600054015660015b600255",
"nonce" : "0x00",
"storage" : {
"0x00" : "0x04"
}
}
}
}
}

@ -0,0 +1,38 @@
{
"JDfromStorageDynamicJump0_AfterJumpdest3" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/JDfromStorageDynamicJump0_AfterJumpdest3Filler.json",
"sourceHash" : "52880726a50d86ffdaea78e4a5d3293643688543eea049172fbf51e564f28f5b"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x6023600b600850600054015660015b600255",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x6023600b600850600054015660015b600255",
"nonce" : "0x00",
"storage" : {
"0x00" : "0x04"
}
}
}
}
}

@ -0,0 +1,38 @@
{
"JDfromStorageDynamicJump0_foreverOutOfGas" : {
"_info" : {
"comment" : "",
"filledwith" : "testeth 1.5.0.dev2-52+commit.d419e0a2",
"lllcversion" : "Version: 0.4.26-develop.2018.9.19+commit.785cbf40.Linux.g++",
"source" : "src/VMTestsFiller/vmIOandFlowOperations/JDfromStorageDynamicJump0_foreverOutOfGasFiller.json",
"sourceHash" : "a3046ce1b7f78c109aa36c29db004850ad5b3b4129d9085849b7af04b719826c"
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x0100",
"currentGasLimit" : "0x0f4240",
"currentNumber" : "0x02",
"currentTimestamp" : "0x01"
},
"exec" : {
"address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x5b600060000156",
"data" : "0x",
"gas" : "0x0186a0",
"gasPrice" : "0x5af3107a4000",
"origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "0x0de0b6b3a7640000"
},
"pre" : {
"0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "0x152d02c7e14af6800000",
"code" : "0x5b600060000156",
"nonce" : "0x00",
"storage" : {
"0x00" : "0x04"
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save