mirror of https://github.com/ConsenSys/mythril
Merge to Master (#1680)
* Fix error message (#1506) * Fix bug during checking potential issues (#1507) * Fix bug due to list.remove() in a loop * Mythril v0.22.25 * Add BASEFEE opcode (#1513) * Add BASEFEE opcode * Add test * Support Panic(uint256) calls for asserts in v0.8.0+ (#1514) * Support panic() asserts * Use typing extensions * Add typing extensions (#1516) * Mythril v0.22.26 * [WIP] Add safe function support (#1510) * Add safe functions cli * Add a change * Add tests * Change examples * Fix bytecode tests * Use last jump as source for yul mapping (#1518) * Mythril v0.22.27 * Fix issue with source mapping (#1526) * Fix issue with source mapping * Fix issues with deployedBytecode * Add typing * Refactor opcode files and fix issues (#1532) * Use symbol_factory (#1533) * Use symbol_factory * Black * Support native calls for delegatecall and callcode (#1534) * Fix issue with calldatasize (#1537) * Mythril v0.22.28 * Fix issue with integer arthimetic (#1541) * Fix issues with exceptions module (#1542) * Mythril v0.22.29 * Ignore plyvel (#1543) * Remove additional eth transfer (#1544) * Fix issues with out of index code (#1545) * Mythril v0.22.30 * Fixes issues by considering future concrete hashes (#1547) * Fix issues with hashing * Fix offsets and edge cases * Fix onchain storage access (#1548) * Fix issues with onsite storage access * Fix issue with copy * Fix issue with get_constraints (#1549) * Handle an edgecase from local host clients (#1550) * Handle an edgecase from local host clients * Fix eth-typing * Fix pyparsing (#1551) * Mythril v0.22.31 * Removes pyethereum Dependencies and leveldb libraries (#1555) * change versions * Move away from pyethereum dependency * Remove leveldb * Change requirements * Add rzpad() * Fix issues with sha3 * Fix sha3 edge cases * Fix setup.py * Restrict eth-utils * Restrict eth-typing * Fix py-ecc * Remove mythx analysis doc * Remove -l option from docs * Fix typing_extensions (#1556) * change versions * Move away from pyethereum dependency * Remove leveldb * Change requirements * Add rzpad() * Fix issues with sha3 * Fix sha3 edge cases * Fix setup.py * Restrict eth-utils * Restrict eth-typing * Fix py-ecc * Fix typing_extensions * Fix blake2bpy (#1557) * Fix case where loader is not present (#1558) * Use empty code to denote address (#1559) * Mythril v0.22.32 * Use concrete storage (#1562) * Support symbolic bytecode (#1560) * Support symbolic bytecode * Use hex notation * Handle swarm hash * Use requirements in setup (#1564) * Fix myth --version typo in docs (#1563) Co-authored-by: Nikhil Parasaram <nikhilparasaram@gmail.com> * Fixes issues with NoneType and restricts rlp version (#1567) * Fix when args are NoneType * Fix rlp * Fix creation case and use better error message (#1569) * Handle creation code * Fix eth-keys * Mythril v0.22.33 * Fix py-evm version (#1570) * Fix py-evm when it's in alpha * Downgrade py-evm * upgrade py-evm * remove py-evm restriction * Fix trie * Fix versions * Edit versions * Edit versions * Restrict versions * Remove eth-tester * add blake2b * Support multiple function names (#1571) * Fix the leaking file descriptor when returning a z3 smt check result (#1574) * Mythril v0.22.34 * Add more precompile tests (#1576) * Add tests for natives * Black updates * Update black * Refactor code (#1577) * clean up code * Update lolcat * Fixes issues with create with symbolic bytecode (#1578) * Handle cases when create get's symbolic bytecodes * Refactor * fix typing * Mythril v0.22.35 * Handle cases with symbolic bytecode (#1581) * Fix issues with string code * revert solc changes * Allow missing solc (#1582) * allow missing solc * reformatted * dummy commit Co-authored-by: mrx23dot <none> * Handle changes in allow-paths in solc versions 0.8.8+ (#1584) * Handle changes in allow-paths in solc versions 0.8.8+ * Add docker * Remove test * Mythril v0.22.36 * Update LICENSE (#1585) * Restrict eth-rlp, eth-keyfile (#1586) * Restrict eth-rlp * Restrict eth-keyfile * Helper functions for symbolic summaries (#1587) * Restrict eth-rlp * Restrict eth-keyfile * Add functions for summaries * Add some tweaks * Revert a change * Rewrite BaseArray class * Remove unused variable * Support Pragmas (#1591) * Support Pragmas * Fix MarkUpSafe * Stop Edelweiss temporarily (#1593) * Mythril v0.22.37 * Concolic tool (#1445) * Mythril v0.22.14 * Add trace plugin and find trace * Add finding trace * Add some changes * change help text * Add some comments * Add support for concolic strategy * Fix issues * Add concolic exec tool * Add a few fixes * Fix a few errors * Add tests * Fix test interface * Add muti flip test * Add multi contract test * Fix cases with multicontract calls * Add more tests and fixes * Fix tests * Fix mypy * Change tests and other small fixes * Add more documentation * Add some changes * Update mythril/concolic/find_trace.py Co-authored-by: JoranHonig <JoranHonig@users.noreply.github.com> * Remove space Co-authored-by: JoranHonig <JoranHonig@users.noreply.github.com> * Fix typing * Fix Review issues * Change test type * Remove deepcopy * Use 3.8 for typing * Use typing_extensions * Fix prev_state * Add changes to tests and fix some bugs * Fix address assignment * Fix issues and format * Remove set_option * Split plugins * Refactor Co-authored-by: JoranHonig <JoranHonig@users.noreply.github.com> * Mythril v0.22.38 * Fix issues with sqlite3 (#1594) * Mythril v0.22.14 * Add trace plugin and find trace * Add finding trace * Add some changes * change help text * Add some comments * Add support for concolic strategy * Fix issues * Add concolic exec tool * Add a few fixes * Fix a few errors * Add tests * Fix test interface * Add muti flip test * Add multi contract test * Fix cases with multicontract calls * Add more tests and fixes * Fix tests * Fix mypy * Change tests and other small fixes * Add more documentation * Add some changes * Update mythril/concolic/find_trace.py Co-authored-by: JoranHonig <JoranHonig@users.noreply.github.com> * Remove space Co-authored-by: JoranHonig <JoranHonig@users.noreply.github.com> * Fix typing * Fix Review issues * Change test type * Remove deepcopy * Use 3.8 for typing * Use typing_extensions * Fix prev_state * Add changes to tests and fix some bugs * Fix address assignment * Fix issues and format * Remove set_option * Split plugins * Refactor * Handle sqlite3 Co-authored-by: JoranHonig <JoranHonig@users.noreply.github.com> * Mythril v0.22.39 * Init config dir (#1595) * Mythril v0.22.40 * Fixes optimizer issue (#1597) * Init config dir * Fix solc optimizer * Mythril v0.22.41 * Handle constructor edge case (#1600) * Init config dir * Fix solc optimizer * Handle constructor edge case * Fix NPM code block issue (#1602) * Init config dir * Fix solc optimizer * Fix NPM code block issue * Extend tests * Beam search (#1606) * Init config dir * Fix solc optimizer * Add beam search * Use dict over reference * Change default execution time * Support TX constraints and refactor CLI (#1607) * Support TX constraints and refactor CLI * Fix typing * Add additional typing * Use dict over accessor * Fix z3py requirements * Init storage args * Init storage args * Init args in vm tests * Unrestrict z3 to 4.8.15.0 (#1608) * Mythril v0.22.42 * Fix caching of issues across modules (#1610) * Fix caching of issues across modules * Fix caching of issues across modules * Remove logging (#1611) * Fix caching of issues across modules * Fix caching of issues across modules * Use log.info * Merge * remove comment * Check versions before using integer module (#1613) * use more secure approach to call docker (#1614) * Mythril v0.22.43 * Use better issue annotations for search (#1615) * Check versions before using integer module * Use IssueAnnotations * Fix misc issues related to summaries (#1617) * Check versions before using integer module * Use IssueAnnotations * Fix misc issues with summaries * Fix issue with cache during summaries (#1619) * Check versions before using integer module * Use IssueAnnotations * Fix misc issues with summaries * Fix cache issue * Fix safe functions * dead link (#1616) * Fix issue with PluginSkipState (#1620) * Check versions before using integer module * Use IssueAnnotations * Fix misc issues with summaries * Fix cache issue * Fix safe functions * Fix issue with PluginSkipState * Update black * Mythril v0.23.0 * fixed module links in documentation (#1622) * Use int argument (#1625) * remove depth for jump (#1628) * Use a more precise modeling of return data (#1630) * remove depth for jump * Use a more precise modeling of return data * Fix issues with lists * Fix issues * Fix misc issues (#1631) * remove depth for jump * Use a more precise modeling of return data * Fix issues with lists * Fix issues * Fix misc issues * Mythril v0.23.1 * Correct comment (#1632) * Correct comment * Update bitvec_helper.py * Fix caching for exceptions module (#1633) * Fix loop bound and other instruction performance issues (#1635) * Fix caching for exceptions module * Fix loop bound and other instruction performance issues * Remove unused variable * Increase loop bound * Mythril v0.23.2 * Handle CRLF line endings (#1637) * Handle CRLF line endings * Add new line at the end of file * Typo: External Calls now states correctly SWC-107 (#1639) External Calls mentioned *SWC-117* but links (corrrectly) to SWC-107, fixed typo to *SWC-107* * Fix Bitvec issue (#1641) * Fix issues with Bitvec (#1642) * Fix Bitvec issue * Fix issues with Bitvec * Mythril v0.23.3 * Use latest blake2bpy, Fix version extraction (#1644) * Use latest blake2bpy, Fix version extraction * Fix setup.py * Handle setup.py * Handle setup.py * Handle setup.py * Fix requirements * Fix requirements * Fix requirements * restrict eth-hash * Support py36 through py39 (#1646) * Support py36 through py39 * Remove usage of cytoolz * Update tox * Add a get set for summaries (#1647) * Support py36 through py39 * Remove usage of cytoolz * Update tox * Add a get set for summaries * Mythril v0.23.4 * Deepcopy storage load and store sets (#1648) * Support py36 through py39 * Remove usage of cytoolz * Update tox * Add a get set for summaries * Support get/set * Restrict cytoolz * Move cytoolz up the dependency list * Move cytoolz up the dependency list * Fix CI (#1651) * Support py36 through py39 * Remove usage of cytoolz * Update tox * Add a get set for summaries * Support get/set * Restrict cytoolz * Move cytoolz up the dependency list * Move cytoolz up the dependency list * Add cython * Black * Remove from requirements * Add cython * Remove cython from setup * Remove cython from setup * Add cython * set cytoolz version * Add support for locking config file (#1652) * Add support for locking config file * Remove abi decode test * Fix typo * Mythril v0.23.5 * Fix issues with arbitrary jump dest (#1654) * Add partial abi support (#1655) * Fix issues with arbitrary jump dest * Support abi * Add partial abi support * Fix test * Fix test directory * Mythril v0.23.6 * Update Readme * Fix OOG issue (#1658) * Fix issues with arbitrary jump dest * Support abi * Add partial abi support * Fix test * Fix test directory * Fix OOG issue * Fix issue with simplify (#1660) * Fix issues with arbitrary jump dest * Support abi * Add partial abi support * Fix test * Fix test directory * Fix OOG issue * Fix issue with simplify * Fix typo * Fix imports for python 3.10 (#1661) * Fix issues with arbitrary jump dest * Support abi * Add partial abi support * Fix test * Fix test directory * Fix OOG issue * Fix issue with simplify * Fix typo * Fix import * Refactor * Add exit code (#1662) * Add exit code * Fix tests * Remove additional python runs in tox (#1663) Since `geth` gets killed by CI after some time, it is better to run only the necessary python versions. * Update docs and Add tutorial (#1664) * Add exit code * Update docs with tutorial * Fix docs * Reformat * Mythril v0.23.7 (#1665) * Handles issue with low constructor loop bound and new way to deal with solver-timeout (#1668) * Add exit code * Update docs with tutorial * Fix docs * Reformat * Fix the issue with loop-bound and solver-timeout * Add test changes * Restrict hexbytes * Mythril v0.23.8 (#1669) * last_jump has type `int` but is used as type `None`. (#1670) * last_jump has type `int` but is used as type `None`. "filename": "mythril/analysis/module/modules/exceptions.py" "warning_type": "Incompatible variable type [9]" "warning_message": " last_jump is declared to have type `int` but is used as type `None`." "warning_line": 28 "fix": None to 0 * Update exceptions.py * Fix typo * Add import Co-authored-by: Nikhil Parasaram <tommycjniko@gmail.com> Co-authored-by: norhh <nikhilparasaram@gmail.com> * Handle issues with simplify (#1674) * Add exit code * Update docs with tutorial * Fix docs * Reformat * Fix the issue with loop-bound and solver-timeout * Add test changes * Restrict hexbytes * Use solver over simplify * Handle OOG during CALL (#1675) * Mythril v0.23.9 Co-authored-by: Peilin Zheng <tczpl@163.com> Co-authored-by: Sir Hashalot <95114813+sirhashalot@users.noreply.github.com> Co-authored-by: Iaroslav Zeigerman <zeigerman.ia@gmail.com> Co-authored-by: Kis Gabor <mrx23dot@users.noreply.github.com> Co-authored-by: Serafim Cloud <55061526+serafimcloud@users.noreply.github.com> Co-authored-by: JoranHonig <JoranHonig@users.noreply.github.com> Co-authored-by: shafu.eth <selfouly@gmail.com> Co-authored-by: Zach Obront <zobront@gmail.com> Co-authored-by: 72521 <ysl47698@gmail.com> Co-authored-by: Christian <christiancattai@gmail.com> Co-authored-by: Luca Di Grazia <luca.digrazia94@gmail.com>master
parent
563332bd42
commit
d22da1c212
@ -1,2 +1,3 @@ |
||||
include mythril/support/assets/* |
||||
include mythril/analysis/templates/* |
||||
include requirements.txt |
@ -0,0 +1,7 @@ |
||||
mythril |
||||
======= |
||||
|
||||
.. toctree:: |
||||
:maxdepth: 4 |
||||
|
||||
mythril |
@ -0,0 +1,125 @@ |
||||
mythril.analysis.module.modules package |
||||
======================================= |
||||
|
||||
Submodules |
||||
---------- |
||||
|
||||
mythril.analysis.module.modules.arbitrary\_jump module |
||||
------------------------------------------------------ |
||||
|
||||
.. automodule:: mythril.analysis.module.modules.arbitrary_jump |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.module.modules.arbitrary\_write module |
||||
------------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.module.modules.arbitrary_write |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.module.modules.delegatecall module |
||||
--------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.module.modules.delegatecall |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.module.modules.dependence\_on\_origin module |
||||
------------------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.module.modules.dependence_on_origin |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.module.modules.dependence\_on\_predictable\_vars module |
||||
------------------------------------------------------------------------ |
||||
|
||||
.. automodule:: mythril.analysis.module.modules.dependence_on_predictable_vars |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.module.modules.ether\_thief module |
||||
--------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.module.modules.ether_thief |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.module.modules.exceptions module |
||||
------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.module.modules.exceptions |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.module.modules.external\_calls module |
||||
------------------------------------------------------ |
||||
|
||||
.. automodule:: mythril.analysis.module.modules.external_calls |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.module.modules.integer module |
||||
---------------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.module.modules.integer |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.module.modules.multiple\_sends module |
||||
------------------------------------------------------ |
||||
|
||||
.. automodule:: mythril.analysis.module.modules.multiple_sends |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.module.modules.state\_change\_external\_calls module |
||||
--------------------------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.module.modules.state_change_external_calls |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.module.modules.suicide module |
||||
---------------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.module.modules.suicide |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.module.modules.unchecked\_retval module |
||||
-------------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.module.modules.unchecked_retval |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.module.modules.user\_assertions module |
||||
------------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.module.modules.user_assertions |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
Module contents |
||||
--------------- |
||||
|
||||
.. automodule:: mythril.analysis.module.modules |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
@ -0,0 +1,53 @@ |
||||
mythril.analysis.module package |
||||
=============================== |
||||
|
||||
Subpackages |
||||
----------- |
||||
|
||||
.. toctree:: |
||||
:maxdepth: 4 |
||||
|
||||
mythril.analysis.module.modules |
||||
|
||||
Submodules |
||||
---------- |
||||
|
||||
mythril.analysis.module.base module |
||||
----------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.module.base |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.module.loader module |
||||
------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.module.loader |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.module.module\_helpers module |
||||
---------------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.module.module_helpers |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.module.util module |
||||
----------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.module.util |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
Module contents |
||||
--------------- |
||||
|
||||
.. automodule:: mythril.analysis.module |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
@ -1,110 +0,0 @@ |
||||
mythril.analysis.modules package |
||||
================================ |
||||
|
||||
Submodules |
||||
---------- |
||||
|
||||
mythril.analysis.modules.base module |
||||
------------------------------------ |
||||
|
||||
.. automodule:: mythril.analysis.modules.base |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.modules.delegatecall module |
||||
-------------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.modules.delegatecall |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.modules.dependence\_on\_predictable\_vars module |
||||
----------------------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.modules.dependence_on_predictable_vars |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.modules.deprecated\_ops module |
||||
----------------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.modules.deprecated_ops |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.modules.ether\_thief module |
||||
-------------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.modules.ether_thief |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.modules.exceptions module |
||||
------------------------------------------ |
||||
|
||||
.. automodule:: mythril.analysis.modules.exceptions |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.modules.external\_calls module |
||||
----------------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.modules.external_calls |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.modules.integer module |
||||
--------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.modules.integer |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.modules.multiple\_sends module |
||||
----------------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.modules.multiple_sends |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.modules.suicide module |
||||
--------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.modules.suicide |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.modules.transaction\_order\_dependence module |
||||
-------------------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.modules.transaction_order_dependence |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.analysis.modules.unchecked\_retval module |
||||
------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.analysis.modules.unchecked_retval |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
|
||||
Module contents |
||||
--------------- |
||||
|
||||
.. automodule:: mythril.analysis.modules |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
@ -0,0 +1,37 @@ |
||||
mythril.concolic package |
||||
======================== |
||||
|
||||
Submodules |
||||
---------- |
||||
|
||||
mythril.concolic.concolic\_execution module |
||||
------------------------------------------- |
||||
|
||||
.. automodule:: mythril.concolic.concolic_execution |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.concolic.concrete\_data module |
||||
-------------------------------------- |
||||
|
||||
.. automodule:: mythril.concolic.concrete_data |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.concolic.find\_trace module |
||||
----------------------------------- |
||||
|
||||
.. automodule:: mythril.concolic.find_trace |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
Module contents |
||||
--------------- |
||||
|
||||
.. automodule:: mythril.concolic |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
@ -1,46 +0,0 @@ |
||||
mythril.ethereum.interface.leveldb package |
||||
========================================== |
||||
|
||||
Submodules |
||||
---------- |
||||
|
||||
mythril.ethereum.interface.leveldb.accountindexing module |
||||
--------------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.ethereum.interface.leveldb.accountindexing |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.ethereum.interface.leveldb.client module |
||||
------------------------------------------------ |
||||
|
||||
.. automodule:: mythril.ethereum.interface.leveldb.client |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.ethereum.interface.leveldb.eth\_db module |
||||
------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.ethereum.interface.leveldb.eth_db |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.ethereum.interface.leveldb.state module |
||||
----------------------------------------------- |
||||
|
||||
.. automodule:: mythril.ethereum.interface.leveldb.state |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
|
||||
Module contents |
||||
--------------- |
||||
|
||||
.. automodule:: mythril.ethereum.interface.leveldb |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
@ -0,0 +1,29 @@ |
||||
mythril.laser.ethereum.function\_managers package |
||||
================================================= |
||||
|
||||
Submodules |
||||
---------- |
||||
|
||||
mythril.laser.ethereum.function\_managers.exponent\_function\_manager module |
||||
---------------------------------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.ethereum.function_managers.exponent_function_manager |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.laser.ethereum.function\_managers.keccak\_function\_manager module |
||||
-------------------------------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.ethereum.function_managers.keccak_function_manager |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
Module contents |
||||
--------------- |
||||
|
||||
.. automodule:: mythril.laser.ethereum.function_managers |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
@ -0,0 +1,21 @@ |
||||
mythril.laser.ethereum.strategy.extensions package |
||||
================================================== |
||||
|
||||
Submodules |
||||
---------- |
||||
|
||||
mythril.laser.ethereum.strategy.extensions.bounded\_loops module |
||||
---------------------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.ethereum.strategy.extensions.bounded_loops |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
Module contents |
||||
--------------- |
||||
|
||||
.. automodule:: mythril.laser.ethereum.strategy.extensions |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
@ -0,0 +1,29 @@ |
||||
mythril.laser.plugin.plugins.coverage package |
||||
============================================= |
||||
|
||||
Submodules |
||||
---------- |
||||
|
||||
mythril.laser.plugin.plugins.coverage.coverage\_plugin module |
||||
------------------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.plugin.plugins.coverage.coverage_plugin |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.laser.plugin.plugins.coverage.coverage\_strategy module |
||||
--------------------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.plugin.plugins.coverage.coverage_strategy |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
Module contents |
||||
--------------- |
||||
|
||||
.. automodule:: mythril.laser.plugin.plugins.coverage |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
@ -0,0 +1,70 @@ |
||||
mythril.laser.plugin.plugins package |
||||
==================================== |
||||
|
||||
Subpackages |
||||
----------- |
||||
|
||||
.. toctree:: |
||||
:maxdepth: 4 |
||||
|
||||
mythril.laser.plugin.plugins.coverage |
||||
mythril.laser.plugin.plugins.summary_backup |
||||
|
||||
Submodules |
||||
---------- |
||||
|
||||
mythril.laser.plugin.plugins.benchmark module |
||||
--------------------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.plugin.plugins.benchmark |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.laser.plugin.plugins.call\_depth\_limiter module |
||||
-------------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.plugin.plugins.call_depth_limiter |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.laser.plugin.plugins.dependency\_pruner module |
||||
------------------------------------------------------ |
||||
|
||||
.. automodule:: mythril.laser.plugin.plugins.dependency_pruner |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.laser.plugin.plugins.instruction\_profiler module |
||||
--------------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.plugin.plugins.instruction_profiler |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.laser.plugin.plugins.mutation\_pruner module |
||||
---------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.plugin.plugins.mutation_pruner |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.laser.plugin.plugins.plugin\_annotations module |
||||
------------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.plugin.plugins.plugin_annotations |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
Module contents |
||||
--------------- |
||||
|
||||
.. automodule:: mythril.laser.plugin.plugins |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
@ -0,0 +1,10 @@ |
||||
mythril.laser.plugin.plugins.summary\_backup package |
||||
==================================================== |
||||
|
||||
Module contents |
||||
--------------- |
||||
|
||||
.. automodule:: mythril.laser.plugin.plugins.summary_backup |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
@ -0,0 +1,53 @@ |
||||
mythril.laser.plugin package |
||||
============================ |
||||
|
||||
Subpackages |
||||
----------- |
||||
|
||||
.. toctree:: |
||||
:maxdepth: 4 |
||||
|
||||
mythril.laser.plugin.plugins |
||||
|
||||
Submodules |
||||
---------- |
||||
|
||||
mythril.laser.plugin.builder module |
||||
----------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.plugin.builder |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.laser.plugin.interface module |
||||
------------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.plugin.interface |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.laser.plugin.loader module |
||||
---------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.plugin.loader |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.laser.plugin.signals module |
||||
----------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.plugin.signals |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
Module contents |
||||
--------------- |
||||
|
||||
.. automodule:: mythril.laser.plugin |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
@ -1,38 +1,77 @@ |
||||
mythril.laser.smt package |
||||
========================= |
||||
|
||||
Subpackages |
||||
----------- |
||||
|
||||
.. toctree:: |
||||
:maxdepth: 4 |
||||
|
||||
mythril.laser.smt.solver |
||||
|
||||
Submodules |
||||
---------- |
||||
|
||||
mythril.laser.smt.array module |
||||
------------------------------ |
||||
|
||||
.. automodule:: mythril.laser.smt.array |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.laser.smt.bitvec module |
||||
------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.smt.bitvec |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.laser.smt.bitvec\_helper module |
||||
--------------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.smt.bitvec_helper |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.laser.smt.bool module |
||||
----------------------------- |
||||
|
||||
.. automodule:: mythril.laser.smt.bool |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.laser.smt.expression module |
||||
----------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.smt.expression |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.laser.smt.function module |
||||
--------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.smt.function |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.laser.smt.model module |
||||
------------------------------ |
||||
|
||||
.. automodule:: mythril.laser.smt.model |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
Module contents |
||||
--------------- |
||||
|
||||
.. automodule:: mythril.laser.smt |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
@ -0,0 +1,37 @@ |
||||
mythril.laser.smt.solver package |
||||
================================ |
||||
|
||||
Submodules |
||||
---------- |
||||
|
||||
mythril.laser.smt.solver.independence\_solver module |
||||
---------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.smt.solver.independence_solver |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.laser.smt.solver.solver module |
||||
-------------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.smt.solver.solver |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.laser.smt.solver.solver\_statistics module |
||||
-------------------------------------------------- |
||||
|
||||
.. automodule:: mythril.laser.smt.solver.solver_statistics |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
Module contents |
||||
--------------- |
||||
|
||||
.. automodule:: mythril.laser.smt.solver |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
@ -0,0 +1,37 @@ |
||||
mythril.mythril package |
||||
======================= |
||||
|
||||
Submodules |
||||
---------- |
||||
|
||||
mythril.mythril.mythril\_analyzer module |
||||
---------------------------------------- |
||||
|
||||
.. automodule:: mythril.mythril.mythril_analyzer |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.mythril.mythril\_config module |
||||
-------------------------------------- |
||||
|
||||
.. automodule:: mythril.mythril.mythril_config |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.mythril.mythril\_disassembler module |
||||
-------------------------------------------- |
||||
|
||||
.. automodule:: mythril.mythril.mythril_disassembler |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
Module contents |
||||
--------------- |
||||
|
||||
.. automodule:: mythril.mythril |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
@ -0,0 +1,37 @@ |
||||
mythril.plugin package |
||||
====================== |
||||
|
||||
Submodules |
||||
---------- |
||||
|
||||
mythril.plugin.discovery module |
||||
------------------------------- |
||||
|
||||
.. automodule:: mythril.plugin.discovery |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.plugin.interface module |
||||
------------------------------- |
||||
|
||||
.. automodule:: mythril.plugin.interface |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
mythril.plugin.loader module |
||||
---------------------------- |
||||
|
||||
.. automodule:: mythril.plugin.loader |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
||||
|
||||
Module contents |
||||
--------------- |
||||
|
||||
.. automodule:: mythril.plugin |
||||
:members: |
||||
:undoc-members: |
||||
:show-inheritance: |
@ -1,63 +0,0 @@ |
||||
MythX Analysis |
||||
================= |
||||
|
||||
Run :code:`myth pro` with one of the input options described below will run a `MythX analysis <https://mythx.io>`_ on the desired input. This includes a run of Mythril, the fuzzer Harvey, and the static analysis engine Maru and has some false-positive filtering only possible by combining the tool capabilities. |
||||
|
||||
************** |
||||
Authentication |
||||
************** |
||||
|
||||
In order to authenticate with the MythX API, set the environment variables ``MYTHX_PASSWORD`` and ``MYTHX_ETH_ADDRESS``. |
||||
|
||||
.. code-block:: bash |
||||
|
||||
$ export MYTHX_ETH_ADDRESS='0x0000000000000000000000000000000000000000' |
||||
$ export MYTHX_PASSWORD='password' |
||||
|
||||
*********************** |
||||
Analyzing Solidity Code |
||||
*********************** |
||||
|
||||
The input format is the same as a regular Mythril analysis. |
||||
|
||||
.. code-block:: bash |
||||
|
||||
$ myth pro ether_send.sol |
||||
==== Unprotected Ether Withdrawal ==== |
||||
SWC ID: 105 |
||||
Severity: High |
||||
Contract: Crowdfunding |
||||
Function name: withdrawfunds() |
||||
PC address: 730 |
||||
Anyone can withdraw ETH from the contract account. |
||||
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 a vulnerability. |
||||
-------------------- |
||||
In file: tests/testdata/input_contracts/ether_send.sol:21 |
||||
|
||||
msg.sender.transfer(address(this).balance) |
||||
|
||||
-------------------- |
||||
|
||||
If an input file contains multiple contract definitions, Mythril analyzes the *last* bytecode output produced by solc. You can override this by specifying the contract name explicitly: |
||||
|
||||
.. code-block:: bash |
||||
|
||||
myth pro OmiseGo.sol:OMGToken |
||||
|
||||
To specify a contract address, use :code:`-a <address>` |
||||
|
||||
**************************** |
||||
Analyzing On-Chain Contracts |
||||
**************************** |
||||
|
||||
Analyzing a mainnet contract via INFURA: |
||||
|
||||
.. code-block:: bash |
||||
|
||||
myth pro -a 0x5c436ff914c458983414019195e0f4ecbef9e6dd |
||||
|
||||
Adding the :code:`-l` flag will cause mythril to automatically retrieve dependencies, such as dynamically linked library contracts: |
||||
|
||||
.. code-block:: bash |
||||
|
||||
myth -v4 pro -l -a 0xEbFD99838cb0c132016B9E117563CB41f2B02264 |
@ -0,0 +1,511 @@ |
||||
Tutorial |
||||
====================== |
||||
|
||||
****************************************** |
||||
Executing Mythril on Simple Contracts |
||||
****************************************** |
||||
|
||||
We consider a contract simple if it does not have any imports, like the following contract: |
||||
|
||||
.. code-block:: solidity |
||||
|
||||
contract Exceptions { |
||||
|
||||
uint256[8] myarray; |
||||
uint counter = 0; |
||||
function assert1() public pure { |
||||
uint256 i = 1; |
||||
assert(i == 0); |
||||
} |
||||
function counter_increase() public { |
||||
counter+=1; |
||||
} |
||||
function assert5(uint input_x) public view{ |
||||
require(counter>2); |
||||
assert(input_x > 10); |
||||
} |
||||
function assert2() public pure { |
||||
uint256 i = 1; |
||||
assert(i > 0); |
||||
} |
||||
|
||||
function assert3(uint256 input) public pure { |
||||
assert(input != 23); |
||||
} |
||||
|
||||
function require_is_fine(uint256 input) public pure { |
||||
require(input != 23); |
||||
} |
||||
|
||||
function this_is_fine(uint256 input) public pure { |
||||
if (input > 0) { |
||||
uint256 i = 1/input; |
||||
} |
||||
} |
||||
|
||||
function this_is_find_2(uint256 index) public view { |
||||
if (index < 8) { |
||||
uint256 i = myarray[index]; |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
We can execute such a contract by directly using the following command: |
||||
|
||||
.. code-block:: bash |
||||
|
||||
$ myth analyze <file_path> |
||||
|
||||
This execution can give the following output: |
||||
|
||||
.. code-block:: none |
||||
|
||||
==== Exception State ==== |
||||
SWC ID: 110 |
||||
Severity: Medium |
||||
Contract: Exceptions |
||||
Function name: assert1() |
||||
PC address: 708 |
||||
Estimated Gas Usage: 207 - 492 |
||||
An assertion violation was triggered. |
||||
It is possible to trigger an assertion violation. Note that Solidity assert() statements should only be used to check invariants. Review the transaction trace generated for this issue and either make sure your program logic is correct, or use require() instead of assert() if your goal is to constrain user inputs or enforce preconditions. Remember to validate inputs from both callers (for instance, via passed arguments) and callees (for instance, via return values). |
||||
-------------------- |
||||
In file: solidity_examples/exceptions.sol:7 |
||||
|
||||
assert(i == 0) |
||||
|
||||
-------------------- |
||||
Initial State: |
||||
|
||||
Account: [CREATOR], balance: 0x2, nonce:0, storage:{} |
||||
Account: [ATTACKER], balance: 0x0, nonce:0, storage:{} |
||||
|
||||
Transaction Sequence: |
||||
|
||||
Caller: [CREATOR], calldata: , value: 0x0 |
||||
Caller: [ATTACKER], function: assert1(), txdata: 0xb34c3610, value: 0x0 |
||||
|
||||
==== Exception State ==== |
||||
SWC ID: 110 |
||||
Severity: Medium |
||||
Contract: Exceptions |
||||
Function name: assert3(uint256) |
||||
PC address: 708 |
||||
Estimated Gas Usage: 482 - 767 |
||||
An assertion violation was triggered. |
||||
It is possible to trigger an assertion violation. Note that Solidity assert() statements should only be used to check invariants. Review the transaction trace generated for this issue and either make sure your program logic is correct, or use require() instead of assert() if your goal is to constrain user inputs or enforce preconditions. Remember to validate inputs from both callers (for instance, via passed arguments) and callees (for instance, via return values). |
||||
-------------------- |
||||
In file: solidity_examples/exceptions.sol:20 |
||||
|
||||
assert(input != 23) |
||||
|
||||
-------------------- |
||||
Initial State: |
||||
|
||||
Account: [CREATOR], balance: 0x40207f9b0, nonce:0, storage:{} |
||||
Account: [ATTACKER], balance: 0x0, nonce:0, storage:{} |
||||
|
||||
Transaction Sequence: |
||||
|
||||
Caller: [CREATOR], calldata: , value: 0x0 |
||||
Caller: [SOMEGUY], function: assert3(uint256), txdata: 0x546455b50000000000000000000000000000000000000000000000000000000000000017, value: 0x0 |
||||
|
||||
|
||||
We can observe that the function ``assert5(uint256)`` should have an assertion failure |
||||
with the assertion ``assert(input_x > 10)`` which is missing from our output. This can be attributed to |
||||
Mythril's default configuration of running three transactions. We can increase the transaction count to 4 |
||||
using the ``-t <tx_count>``. |
||||
|
||||
.. code-block:: bash |
||||
|
||||
$ myth analyze <file_path> -t 4 |
||||
|
||||
This gives the following execution output: |
||||
|
||||
.. code-block:: none |
||||
|
||||
==== Exception State ==== |
||||
SWC ID: 110 |
||||
Severity: Medium |
||||
Contract: Exceptions |
||||
Function name: assert1() |
||||
PC address: 731 |
||||
Estimated Gas Usage: 207 - 492 |
||||
An assertion violation was triggered. |
||||
It is possible to trigger an assertion violation. Note that Solidity assert() statements should only be used to check invariants. Review the transaction trace generated for this issue and either make sure your program logic is correct, or use require() instead of assert() if your goal is to constrain user inputs or enforce preconditions. Remember to validate inputs from both callers (for instance, via passed arguments) and callees (for instance, via return values). |
||||
-------------------- |
||||
In file: solidity_examples/exceptions.sol:7 |
||||
|
||||
assert(i == 0) |
||||
|
||||
-------------------- |
||||
Initial State: |
||||
|
||||
Account: [CREATOR], balance: 0x2, nonce:0, storage:{} |
||||
Account: [ATTACKER], balance: 0x0, nonce:0, storage:{} |
||||
|
||||
Transaction Sequence: |
||||
|
||||
Caller: [CREATOR], calldata: , value: 0x0 |
||||
Caller: [ATTACKER], function: assert1(), txdata: 0xb34c3610, value: 0x0 |
||||
|
||||
==== Exception State ==== |
||||
SWC ID: 110 |
||||
Severity: Medium |
||||
Contract: Exceptions |
||||
Function name: assert3(uint256) |
||||
PC address: 731 |
||||
Estimated Gas Usage: 504 - 789 |
||||
An assertion violation was triggered. |
||||
It is possible to trigger an assertion violation. Note that Solidity assert() statements should only be used to check invariants. Review the transaction trace generated for this issue and either make sure your program logic is correct, or use require() instead of assert() if your goal is to constrain user inputs or enforce preconditions. Remember to validate inputs from both callers (for instance, via passed arguments) and callees (for instance, via return values). |
||||
-------------------- |
||||
In file: solidity_examples/exceptions.sol:22 |
||||
|
||||
assert(input != 23) |
||||
|
||||
-------------------- |
||||
Initial State: |
||||
|
||||
Account: [CREATOR], balance: 0x3, nonce:0, storage:{} |
||||
Account: [ATTACKER], balance: 0x0, nonce:0, storage:{} |
||||
|
||||
Transaction Sequence: |
||||
|
||||
Caller: [CREATOR], calldata: , value: 0x0 |
||||
Caller: [ATTACKER], function: assert3(uint256), txdata: 0x546455b50000000000000000000000000000000000000000000000000000000000000017, value: 0x0 |
||||
|
||||
==== Exception State ==== |
||||
SWC ID: 110 |
||||
Severity: Medium |
||||
Contract: Exceptions |
||||
Function name: assert5(uint256) |
||||
PC address: 731 |
||||
Estimated Gas Usage: 1302 - 1587 |
||||
An assertion violation was triggered. |
||||
It is possible to trigger an assertion violation. Note that Solidity assert() statements should only be used to check invariants. Review the transaction trace generated for this issue and either make sure your program logic is correct, or use require() instead of assert() if your goal is to constrain user inputs or enforce preconditions. Remember to validate inputs from both callers (for instance, via passed arguments) and callees (for instance, via return values). |
||||
-------------------- |
||||
In file: solidity_examples/exceptions.sol:14 |
||||
|
||||
assert(input_x > 10) |
||||
|
||||
-------------------- |
||||
Initial State: |
||||
|
||||
Account: [CREATOR], balance: 0x20000000, nonce:0, storage:{} |
||||
Account: [ATTACKER], balance: 0x1000000, nonce:0, storage:{} |
||||
|
||||
Transaction Sequence: |
||||
|
||||
Caller: [CREATOR], calldata: , value: 0x0 |
||||
Caller: [ATTACKER], function: counter_increase(), txdata: 0xe47b0253, value: 0x0 |
||||
Caller: [CREATOR], function: counter_increase(), txdata: 0xe47b0253, value: 0x0 |
||||
Caller: [CREATOR], function: counter_increase(), txdata: 0xe47b0253, value: 0x0 |
||||
Caller: [ATTACKER], function: assert5(uint256), txdata: 0x1d5d53dd0000000000000000000000000000000000000000000000000000000000000003, value: 0x0 |
||||
|
||||
|
||||
For the violation in the 4th transaction, the input value should be less than 10. The transaction data generated by Mythril for the |
||||
4th transaction is ``0x1d5d53dd0000000000000000000000000000000000000000000000000000000000000003``, the first 4 bytes ``1d5d53dd`` |
||||
correspond to the function signature hence the input generated by Mythril is ``0000000000000000000000000000000000000000000000000000000000000003`` |
||||
in hex, which is 3. For automated resolution of the input try using a different output format such as JSON. |
||||
|
||||
.. code-block:: bash |
||||
|
||||
$ myth analyze <file_path> -o json |
||||
|
||||
This leads to the following output: |
||||
|
||||
.. code-block:: json |
||||
|
||||
{ |
||||
"error": null, |
||||
"issues": [{ |
||||
"address": 731, |
||||
"code": "assert(i == 0)", |
||||
"contract": "Exceptions", |
||||
"description": "An assertion violation was triggered.\nIt is possible to trigger an assertion violation. Note that Solidity assert() statements should only be used to check invariants. Review the transaction trace generated for this issue and either make sure your program logic is correct, or use require() instead of assert() if your goal is to constrain user inputs or enforce preconditions. Remember to validate inputs from both callers (for instance, via passed arguments) and callees (for instance, via return values).", |
||||
"filename": "solidity_examples/exceptions.sol", |
||||
"function": "assert1()", |
||||
"lineno": 7, |
||||
"max_gas_used": 492, |
||||
"min_gas_used": 207, |
||||
"severity": "Medium", |
||||
"sourceMap": ":::i", |
||||
"swc-id": "110", |
||||
"title": "Exception State", |
||||
"tx_sequence": { |
||||
"initialState": { |
||||
"accounts": { |
||||
"0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe": { |
||||
"balance": "0x2", |
||||
"code": "", |
||||
"nonce": 0, |
||||
"storage": "{}" |
||||
}, |
||||
"0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef": { |
||||
"balance": "0x0", |
||||
"code": "", |
||||
"nonce": 0, |
||||
"storage": "{}" |
||||
} |
||||
} |
||||
}, |
||||
"steps": [{ |
||||
"address": "", |
||||
"calldata": "", |
||||
"input": "0x6080604052600060085534801561001557600080fd5b506103f7806100256000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063b34c36101161005b578063b34c3610146100fd578063b630d70614610107578063e47b025314610123578063f44f13d81461012d57610088565b806301d4277c1461008d5780631d5d53dd146100a9578063546455b5146100c557806378375f14146100e1575b600080fd5b6100a760048036038101906100a29190610251565b610137565b005b6100c360048036038101906100be9190610251565b61015e565b005b6100df60048036038101906100da9190610251565b610181565b005b6100fb60048036038101906100f69190610251565b610196565b005b6101056101a7565b005b610121600480360381019061011c9190610251565b6101c1565b005b61012b6101e0565b005b6101356101fc565b005b600881101561015b5760008082600881106101555761015461027e565b5b01549050505b50565b60026008541161016d57600080fd5b600a811161017e5761017d6102ad565b5b50565b6017811415610193576101926102ad565b5b50565b60178114156101a457600080fd5b50565b600060019050600081146101be576101bd6102ad565b5b50565b60008111156101dd5760008160016101d9919061033a565b9050505b50565b6001600860008282546101f3919061036b565b92505081905550565b60006001905060008111610213576102126102ad565b5b50565b600080fd5b6000819050919050565b61022e8161021b565b811461023957600080fd5b50565b60008135905061024b81610225565b92915050565b60006020828403121561026757610266610216565b5b60006102758482850161023c565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006103458261021b565b91506103508361021b565b9250826103605761035f6102dc565b5b828204905092915050565b60006103768261021b565b91506103818361021b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156103b6576103b561030b565b5b82820190509291505056fea2646970667358221220b474c01fa60d997027e1ceb779bcb2b34b6752282e0ea3a038a08b889fe0163f64736f6c634300080c0033", |
||||
"name": "unknown", |
||||
"origin": "0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe", |
||||
"value": "0x0" |
||||
}, { |
||||
"address": "0x901d12ebe1b195e5aa8748e62bd7734ae19b51f", |
||||
"calldata": "0xb34c3610", |
||||
"input": "0xb34c3610", |
||||
"name": "assert1()", |
||||
"origin": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", |
||||
"resolved_input": null, |
||||
"value": "0x0" |
||||
}] |
||||
} |
||||
}, { |
||||
"address": 731, |
||||
"code": "assert(input != 23)", |
||||
"contract": "Exceptions", |
||||
"description": "An assertion violation was triggered.\nIt is possible to trigger an assertion violation. Note that Solidity assert() statements should only be used to check invariants. Review the transaction trace generated for this issue and either make sure your program logic is correct, or use require() instead of assert() if your goal is to constrain user inputs or enforce preconditions. Remember to validate inputs from both callers (for instance, via passed arguments) and callees (for instance, via return values).", |
||||
"filename": "solidity_examples/exceptions.sol", |
||||
"function": "assert3(uint256)", |
||||
"lineno": 22, |
||||
"max_gas_used": 789, |
||||
"min_gas_used": 504, |
||||
"severity": "Medium", |
||||
"sourceMap": ":::i", |
||||
"swc-id": "110", |
||||
"title": "Exception State", |
||||
"tx_sequence": { |
||||
"initialState": { |
||||
"accounts": { |
||||
"0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe": { |
||||
"balance": "0x3", |
||||
"code": "", |
||||
"nonce": 0, |
||||
"storage": "{}" |
||||
}, |
||||
"0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef": { |
||||
"balance": "0x0", |
||||
"code": "", |
||||
"nonce": 0, |
||||
"storage": "{}" |
||||
} |
||||
} |
||||
}, |
||||
"steps": [{ |
||||
"address": "", |
||||
"calldata": "", |
||||
"input": "0x6080604052600060085534801561001557600080fd5b506103f7806100256000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063b34c36101161005b578063b34c3610146100fd578063b630d70614610107578063e47b025314610123578063f44f13d81461012d57610088565b806301d4277c1461008d5780631d5d53dd146100a9578063546455b5146100c557806378375f14146100e1575b600080fd5b6100a760048036038101906100a29190610251565b610137565b005b6100c360048036038101906100be9190610251565b61015e565b005b6100df60048036038101906100da9190610251565b610181565b005b6100fb60048036038101906100f69190610251565b610196565b005b6101056101a7565b005b610121600480360381019061011c9190610251565b6101c1565b005b61012b6101e0565b005b6101356101fc565b005b600881101561015b5760008082600881106101555761015461027e565b5b01549050505b50565b60026008541161016d57600080fd5b600a811161017e5761017d6102ad565b5b50565b6017811415610193576101926102ad565b5b50565b60178114156101a457600080fd5b50565b600060019050600081146101be576101bd6102ad565b5b50565b60008111156101dd5760008160016101d9919061033a565b9050505b50565b6001600860008282546101f3919061036b565b92505081905550565b60006001905060008111610213576102126102ad565b5b50565b600080fd5b6000819050919050565b61022e8161021b565b811461023957600080fd5b50565b60008135905061024b81610225565b92915050565b60006020828403121561026757610266610216565b5b60006102758482850161023c565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006103458261021b565b91506103508361021b565b9250826103605761035f6102dc565b5b828204905092915050565b60006103768261021b565b91506103818361021b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156103b6576103b561030b565b5b82820190509291505056fea2646970667358221220b474c01fa60d997027e1ceb779bcb2b34b6752282e0ea3a038a08b889fe0163f64736f6c634300080c0033", |
||||
"name": "unknown", |
||||
"origin": "0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe", |
||||
"value": "0x0" |
||||
}, { |
||||
"address": "0x901d12ebe1b195e5aa8748e62bd7734ae19b51f", |
||||
"calldata": "0x546455b50000000000000000000000000000000000000000000000000000000000000017", |
||||
"input": "0x546455b50000000000000000000000000000000000000000000000000000000000000017", |
||||
"name": "assert3(uint256)", |
||||
"origin": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", |
||||
"resolved_input": [23], |
||||
"value": "0x0" |
||||
}] |
||||
} |
||||
}, { |
||||
"address": 731, |
||||
"code": "assert(input_x > 10)", |
||||
"contract": "Exceptions", |
||||
"description": "An assertion violation was triggered.\nIt is possible to trigger an assertion violation. Note that Solidity assert() statements should only be used to check invariants. Review the transaction trace generated for this issue and either make sure your program logic is correct, or use require() instead of assert() if your goal is to constrain user inputs or enforce preconditions. Remember to validate inputs from both callers (for instance, via passed arguments) and callees (for instance, via return values).", |
||||
"filename": "solidity_examples/exceptions.sol", |
||||
"function": "assert5(uint256)", |
||||
"lineno": 14, |
||||
"max_gas_used": 1587, |
||||
"min_gas_used": 1302, |
||||
"severity": "Medium", |
||||
"sourceMap": ":::i", |
||||
"swc-id": "110", |
||||
"title": "Exception State", |
||||
"tx_sequence": { |
||||
"initialState": { |
||||
"accounts": { |
||||
"0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe": { |
||||
"balance": "0x0", |
||||
"code": "", |
||||
"nonce": 0, |
||||
"storage": "{}" |
||||
}, |
||||
"0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef": { |
||||
"balance": "0x0", |
||||
"code": "", |
||||
"nonce": 0, |
||||
"storage": "{}" |
||||
} |
||||
} |
||||
}, |
||||
"steps": [{ |
||||
"address": "", |
||||
"calldata": "", |
||||
"input": "0x6080604052600060085534801561001557600080fd5b506103f7806100256000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063b34c36101161005b578063b34c3610146100fd578063b630d70614610107578063e47b025314610123578063f44f13d81461012d57610088565b806301d4277c1461008d5780631d5d53dd146100a9578063546455b5146100c557806378375f14146100e1575b600080fd5b6100a760048036038101906100a29190610251565b610137565b005b6100c360048036038101906100be9190610251565b61015e565b005b6100df60048036038101906100da9190610251565b610181565b005b6100fb60048036038101906100f69190610251565b610196565b005b6101056101a7565b005b610121600480360381019061011c9190610251565b6101c1565b005b61012b6101e0565b005b6101356101fc565b005b600881101561015b5760008082600881106101555761015461027e565b5b01549050505b50565b60026008541161016d57600080fd5b600a811161017e5761017d6102ad565b5b50565b6017811415610193576101926102ad565b5b50565b60178114156101a457600080fd5b50565b600060019050600081146101be576101bd6102ad565b5b50565b60008111156101dd5760008160016101d9919061033a565b9050505b50565b6001600860008282546101f3919061036b565b92505081905550565b60006001905060008111610213576102126102ad565b5b50565b600080fd5b6000819050919050565b61022e8161021b565b811461023957600080fd5b50565b60008135905061024b81610225565b92915050565b60006020828403121561026757610266610216565b5b60006102758482850161023c565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006103458261021b565b91506103508361021b565b9250826103605761035f6102dc565b5b828204905092915050565b60006103768261021b565b91506103818361021b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156103b6576103b561030b565b5b82820190509291505056fea2646970667358221220b474c01fa60d997027e1ceb779bcb2b34b6752282e0ea3a038a08b889fe0163f64736f6c634300080c0033", |
||||
"name": "unknown", |
||||
"origin": "0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe", |
||||
"value": "0x0" |
||||
}, { |
||||
"address": "0x901d12ebe1b195e5aa8748e62bd7734ae19b51f", |
||||
"calldata": "0xe47b0253", |
||||
"input": "0xe47b0253", |
||||
"name": "counter_increase()", |
||||
"origin": "0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe", |
||||
"resolved_input": null, |
||||
"value": "0x0" |
||||
}, { |
||||
"address": "0x901d12ebe1b195e5aa8748e62bd7734ae19b51f", |
||||
"calldata": "0xe47b0253", |
||||
"input": "0xe47b0253", |
||||
"name": "counter_increase()", |
||||
"origin": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", |
||||
"resolved_input": null, |
||||
"value": "0x0" |
||||
}, { |
||||
"address": "0x901d12ebe1b195e5aa8748e62bd7734ae19b51f", |
||||
"calldata": "0xe47b0253", |
||||
"input": "0xe47b0253", |
||||
"name": "counter_increase()", |
||||
"origin": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", |
||||
"resolved_input": null, |
||||
"value": "0x0" |
||||
}, { |
||||
"address": "0x901d12ebe1b195e5aa8748e62bd7734ae19b51f", |
||||
"calldata": "0x1d5d53dd0000000000000000000000000000000000000000000000000000000000000003", |
||||
"input": "0x1d5d53dd0000000000000000000000000000000000000000000000000000000000000003", |
||||
"name": "assert5(uint256)", |
||||
"origin": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", |
||||
"resolved_input": [3], |
||||
"value": "0x0" |
||||
}] |
||||
} |
||||
}], |
||||
"success": true |
||||
} |
||||
|
||||
We can observe that the "resolved_input" field for the final transaction resolves to ``[3]``. Although this resolution |
||||
fails in some circumstances where output generated by Mythril is although executable on the bytecode, it cannot be decoded due |
||||
to not being a valid ABI. |
||||
|
||||
There are interesting options such as ``--execution-timeout <seconds>`` and ``--solver-timeout <milliseconds>`` |
||||
which can be increased for better results. The default execution-timeout and solver-timeout are 86400 seconds and |
||||
25000 milliseconds respectively. |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
******************************************************** |
||||
Executing Mythril on Contracts with Imports |
||||
******************************************************** |
||||
|
||||
Consider the following contract: |
||||
|
||||
.. code-block:: solidity |
||||
|
||||
import "@openzeppelin/contracts/token/PRC20/PRC20.sol"; |
||||
|
||||
contract Nothing is PRC20{ |
||||
string x_0 = ""; |
||||
|
||||
bytes3 x_1 = "A"; |
||||
|
||||
bytes5 x_2 = "E"; |
||||
|
||||
bytes5 x_3 = ""; |
||||
|
||||
bytes3 x_4 = "I"; |
||||
|
||||
bytes3 x_5 = "U"; |
||||
|
||||
bytes3 x_6 = "O"; |
||||
|
||||
bytes3 x_7 = "0"; |
||||
|
||||
bytes3 x_8 = "U"; |
||||
|
||||
bytes3 x_9 = "U"; |
||||
function stringCompare(string memory a, string memory b) internal pure returns (bool) { |
||||
if(bytes(a).length != bytes(b).length) { |
||||
return false; |
||||
} else { |
||||
return keccak256(bytes(a)) == keccak256(bytes(b)); |
||||
} |
||||
} |
||||
|
||||
function nothing(string memory g_0, bytes3 g_1, bytes5 g_2, bytes5 g_3, bytes3 g_4, bytes3 g_5, bytes3 g_6, bytes3 g_7, bytes3 g_8, bytes3 g_9, bytes3 g_10, bytes3 g_11) public view returns (bool){ |
||||
if (!stringCompare(g_0, x_0)) return false; |
||||
|
||||
if (g_1 != x_1) return false; |
||||
|
||||
if (g_2 != x_2) return false; |
||||
|
||||
if (g_3 != x_3) return false; |
||||
|
||||
if (g_4 != x_4) return false; |
||||
|
||||
if (g_5 != x_5) return false; |
||||
|
||||
if (g_6 != x_6) return false; |
||||
|
||||
if (g_7 != x_7) return false; |
||||
|
||||
if (g_8 != x_8) return false; |
||||
|
||||
if (g_9 != x_9) return false; |
||||
|
||||
if (g_10 != x_9) return false; |
||||
|
||||
if (g_11 != x_9) return false; |
||||
|
||||
return true; |
||||
|
||||
} |
||||
} |
||||
|
||||
|
||||
When this contract is directly executed, by using the following command: |
||||
|
||||
.. code-block:: bash |
||||
|
||||
$ myth analyze <file_path> |
||||
|
||||
We encounter the following error: |
||||
|
||||
.. code-block:: none |
||||
|
||||
mythril.interfaces.cli [ERROR]: Solc experienced a fatal error. |
||||
|
||||
ParserError: Source "@openzeppelin/contracts/token/PRC20/PRC20.sol" not found: File not found. Searched the following locations: "". |
||||
--> <file_path>:1:1: |
||||
| |
||||
1 | import "@openzeppelin/contracts/token/PRC20/PRC20.sol"; |
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
||||
|
||||
This is because Mythril uses Solidity to compile the program, to circumvent this issue we can use the following solc-json file: |
||||
|
||||
.. code-block:: json |
||||
|
||||
{ |
||||
"remappings": [ "@openzeppelin/contracts/token/PRC20/=node_modules/PRC20" ], |
||||
} |
||||
|
||||
Here we are mapping the import ``@openzeppelin/contracts/token/PRC20/`` to the path which contains ``PRC20.sol`` which in this case |
||||
is ``node_modules/PRC20``. This instructs the compiler to search for anything with the prefix ``@openzeppelin/contracts/token/PRC20/` ` |
||||
in the path ``node_modules/PRC20`` in our file system. We feed to file to Mythril using ``--solc-json`` argument. |
||||
|
||||
.. code-block:: bash |
||||
|
||||
$ myth analyze {file_path} --solc-json {json_file_path} |
||||
|
||||
|
||||
This can effectively execute the file since the Solidity compiler can locate `PRC20.sol`. For more information on remappings, you can |
||||
refer to `Solc docs <https://docs.soliditylang.org/en/v0.8.14/using-the-compiler.html#base-path-and-import-remapping>`_. |
@ -0,0 +1,34 @@ |
||||
from typing import List |
||||
|
||||
from mythril.analysis.report import Issue |
||||
from mythril.laser.ethereum.state.annotation import StateAnnotation |
||||
from mythril.laser.smt import Bool |
||||
from copy import deepcopy |
||||
|
||||
|
||||
class IssueAnnotation(StateAnnotation): |
||||
def __init__(self, conditions: List[Bool], issue: Issue, detector): |
||||
""" |
||||
Issue Annotation to propogate issues |
||||
- conditions: A list of independent conditions [a, b, c, ...] |
||||
Each of these have to be independently be satisfied |
||||
- issue: The issue of the annotation |
||||
- detector: The detection module |
||||
""" |
||||
self.conditions = conditions |
||||
self.issue = issue |
||||
self.detector = detector |
||||
|
||||
def persist_to_world_state(self) -> bool: |
||||
return True |
||||
|
||||
@property |
||||
def persist_over_calls(self) -> bool: |
||||
return True |
||||
|
||||
def __copy__(self): |
||||
return IssueAnnotation( |
||||
conditions=deepcopy(self.conditions), |
||||
issue=self.issue, |
||||
detector=self.detector, |
||||
) |
@ -0,0 +1,2 @@ |
||||
from mythril.concolic.concolic_execution import concolic_execution |
||||
from mythril.concolic.find_trace import concrete_execution |
@ -0,0 +1,85 @@ |
||||
import json |
||||
import binascii |
||||
|
||||
from datetime import datetime, timedelta |
||||
from typing import Dict, List, Any |
||||
from copy import deepcopy |
||||
|
||||
from mythril.concolic.concrete_data import ConcreteData |
||||
from mythril.concolic.find_trace import concrete_execution |
||||
from mythril.disassembler.disassembly import Disassembly |
||||
from mythril.laser.ethereum.strategy.concolic import ConcolicStrategy |
||||
from mythril.laser.ethereum.svm import LaserEVM |
||||
from mythril.laser.ethereum.state.world_state import WorldState |
||||
from mythril.laser.ethereum.state.account import Account |
||||
from mythril.laser.ethereum.transaction.symbolic import execute_transaction |
||||
from mythril.laser.ethereum.transaction.transaction_models import tx_id_manager |
||||
from mythril.laser.smt import Expression, BitVec, symbol_factory |
||||
from mythril.laser.ethereum.time_handler import time_handler |
||||
from mythril.support.support_args import args |
||||
|
||||
|
||||
def flip_branches( |
||||
init_state: WorldState, |
||||
concrete_data: ConcreteData, |
||||
jump_addresses: List[str], |
||||
trace: List, |
||||
) -> List[Dict[str, Dict[str, Any]]]: |
||||
""" |
||||
Flips branches and prints the input required for branch flip |
||||
|
||||
:param concrete_data: Concrete data |
||||
:param jump_addresses: Jump addresses to flip |
||||
:param trace: trace to follow |
||||
""" |
||||
tx_id_manager.restart_counter() |
||||
output_list = [] |
||||
laser_evm = LaserEVM( |
||||
execution_timeout=600, use_reachability_check=False, transaction_count=10 |
||||
) |
||||
laser_evm.open_states = [deepcopy(init_state)] |
||||
laser_evm.strategy = ConcolicStrategy( |
||||
work_list=laser_evm.work_list, |
||||
max_depth=100, |
||||
trace=trace, |
||||
flip_branch_addresses=jump_addresses, |
||||
) |
||||
|
||||
time_handler.start_execution(laser_evm.execution_timeout) |
||||
laser_evm.time = datetime.now() |
||||
|
||||
for transaction in concrete_data["steps"]: |
||||
execute_transaction( |
||||
laser_evm, |
||||
callee_address=transaction["address"], |
||||
caller_address=symbol_factory.BitVecVal( |
||||
int(transaction["origin"], 16), 256 |
||||
), |
||||
data=transaction["input"][2:], |
||||
) |
||||
|
||||
if laser_evm.strategy.results: |
||||
for addr in jump_addresses: |
||||
output_list.append(laser_evm.strategy.results[addr]) |
||||
return output_list |
||||
|
||||
|
||||
def concolic_execution( |
||||
concrete_data: ConcreteData, jump_addresses: List, solver_timeout=100000 |
||||
) -> List[Dict[str, Dict[str, Any]]]: |
||||
""" |
||||
Executes codes and prints input required to cover the branch flips |
||||
:param input_file: Input file |
||||
:param jump_addresses: Jump addresses to flip |
||||
:param solver_timeout: Solver timeout |
||||
|
||||
""" |
||||
init_state, trace = concrete_execution(concrete_data) |
||||
args.solver_timeout = solver_timeout |
||||
output_list = flip_branches( |
||||
init_state=init_state, |
||||
concrete_data=concrete_data, |
||||
jump_addresses=jump_addresses, |
||||
trace=trace, |
||||
) |
||||
return output_list |
@ -0,0 +1,34 @@ |
||||
from typing import Dict, List |
||||
from typing_extensions import TypedDict |
||||
|
||||
|
||||
class AccountData(TypedDict): |
||||
balance: str |
||||
code: str |
||||
nonce: int |
||||
storage: dict |
||||
|
||||
|
||||
class InitialState(TypedDict): |
||||
accounts: Dict[str, AccountData] |
||||
|
||||
|
||||
class TransactionData(TypedDict): |
||||
address: str |
||||
blockCoinbase: str |
||||
blockDifficulty: str |
||||
blockGasLimit: str |
||||
blockNumber: str |
||||
blockTime: str |
||||
calldata: str |
||||
gasLimit: str |
||||
gasPrice: str |
||||
input: str |
||||
name: str |
||||
origin: str |
||||
value: str |
||||
|
||||
|
||||
class ConcreteData(TypedDict): |
||||
initialState: InitialState |
||||
steps: List[TransactionData] |
@ -0,0 +1,78 @@ |
||||
import json |
||||
import binascii |
||||
|
||||
from copy import deepcopy |
||||
from datetime import datetime |
||||
from typing import Dict, List, Tuple |
||||
|
||||
from mythril.concolic.concrete_data import ConcreteData |
||||
|
||||
from mythril.disassembler.disassembly import Disassembly |
||||
from mythril.laser.ethereum.svm import LaserEVM |
||||
from mythril.laser.ethereum.state.world_state import WorldState |
||||
from mythril.laser.ethereum.state.account import Account |
||||
from mythril.laser.ethereum.transaction.concolic import execute_transaction |
||||
from mythril.laser.plugin.loader import LaserPluginLoader |
||||
from mythril.laser.smt import Expression, BitVec, symbol_factory |
||||
from mythril.laser.ethereum.transaction.transaction_models import tx_id_manager |
||||
from mythril.plugin.discovery import PluginDiscovery |
||||
|
||||
|
||||
def setup_concrete_initial_state(concrete_data: ConcreteData) -> WorldState: |
||||
""" |
||||
Sets up concrete initial state |
||||
:param concrete_data: Concrete data |
||||
:return: initialised world state |
||||
""" |
||||
world_state = WorldState() |
||||
for address, details in concrete_data["initialState"]["accounts"].items(): |
||||
account = Account(address, concrete_storage=True) |
||||
account.code = Disassembly(details["code"][2:]) |
||||
account.nonce = details["nonce"] |
||||
if type(details["storage"]) == str: |
||||
details["storage"] = eval(details["storage"]) # type: ignore |
||||
for key, value in details["storage"].items(): |
||||
key_bitvec = symbol_factory.BitVecVal(int(key, 16), 256) |
||||
account.storage[key_bitvec] = symbol_factory.BitVecVal(int(value, 16), 256) |
||||
|
||||
world_state.put_account(account) |
||||
account.set_balance(int(details["balance"], 16)) |
||||
return world_state |
||||
|
||||
|
||||
def concrete_execution(concrete_data: ConcreteData) -> Tuple[WorldState, List]: |
||||
""" |
||||
Executes code concretely to find the path to be followed by concolic executor |
||||
:param concrete_data: Concrete data |
||||
:return: path trace |
||||
""" |
||||
tx_id_manager.restart_counter() |
||||
init_state = setup_concrete_initial_state(concrete_data) |
||||
laser_evm = LaserEVM(execution_timeout=1000) |
||||
laser_evm.open_states = [deepcopy(init_state)] |
||||
plugin_loader = LaserPluginLoader() |
||||
assert PluginDiscovery().is_installed("myth_concolic_execution") |
||||
trace_plugin = PluginDiscovery().installed_plugins["myth_concolic_execution"]() |
||||
|
||||
plugin_loader.load(trace_plugin) |
||||
laser_evm.time = datetime.now() |
||||
plugin_loader.instrument_virtual_machine(laser_evm, None) |
||||
for transaction in concrete_data["steps"]: |
||||
execute_transaction( |
||||
laser_evm, |
||||
callee_address=transaction["address"], |
||||
caller_address=symbol_factory.BitVecVal( |
||||
int(transaction["origin"], 16), 256 |
||||
), |
||||
origin_address=symbol_factory.BitVecVal( |
||||
int(transaction["origin"], 16), 256 |
||||
), |
||||
gas_limit=int(transaction.get("gasLimit", "0x9999999999999999999999"), 16), |
||||
data=binascii.a2b_hex(transaction["input"][2:]), |
||||
gas_price=int(transaction.get("gasPrice", "0x773594000"), 16), |
||||
value=int(transaction["value"], 16), |
||||
track_gas=False, |
||||
) |
||||
|
||||
tx_id_manager.restart_counter() |
||||
return init_state, plugin_loader.plugin_list["MythX Trace Finder"].tx_trace # type: ignore |
@ -1,177 +0,0 @@ |
||||
"""This module contains account indexing functionality. |
||||
|
||||
This includes a sedes class for lists, account storage receipts for |
||||
LevelDB and a class for updating account addresses. |
||||
""" |
||||
import logging |
||||
import time |
||||
|
||||
import rlp |
||||
from ethereum import utils |
||||
from ethereum.messages import Log |
||||
from ethereum.utils import address, hash32, int256 |
||||
from rlp.sedes import big_endian_int, binary |
||||
|
||||
from mythril import ethereum |
||||
from mythril.exceptions import AddressNotFoundError |
||||
|
||||
log = logging.getLogger(__name__) |
||||
|
||||
BATCH_SIZE = 8 * 4096 |
||||
|
||||
|
||||
class CountableList(object): |
||||
"""A sedes for lists of arbitrary length. |
||||
|
||||
:param element_sedes: when (de-)serializing a list, this sedes will be applied to all of its elements |
||||
""" |
||||
|
||||
def __init__(self, element_sedes): |
||||
self.element_sedes = element_sedes |
||||
|
||||
def serialize(self, obj): |
||||
""" |
||||
|
||||
:param obj: |
||||
:return: |
||||
""" |
||||
return [self.element_sedes.serialize(e) for e in obj] |
||||
|
||||
def deserialize(self, serial): |
||||
""" |
||||
|
||||
:param serial: |
||||
:return: |
||||
""" |
||||
# needed for 2 reasons: |
||||
# 1. empty lists are not zero elements |
||||
# 2. underlying logs are stored as list - if empty will also except and receipts will be lost |
||||
try: |
||||
return [self.element_sedes.deserialize(e) for e in serial] |
||||
except: |
||||
return [] |
||||
|
||||
|
||||
class ReceiptForStorage(rlp.Serializable): |
||||
"""Receipt format stored in levelDB.""" |
||||
|
||||
fields = [ |
||||
("state_root", binary), |
||||
("cumulative_gas_used", big_endian_int), |
||||
("bloom", int256), |
||||
("tx_hash", hash32), |
||||
("contractAddress", address), |
||||
("logs", CountableList(Log)), |
||||
("gas_used", big_endian_int), |
||||
] |
||||
|
||||
|
||||
class AccountIndexer(object): |
||||
"""Updates address index.""" |
||||
|
||||
def __init__(self, ethDB): |
||||
self.db = ethDB |
||||
self.lastBlock = None |
||||
self.lastProcessedBlock = None |
||||
|
||||
self.updateIfNeeded() |
||||
|
||||
def get_contract_by_hash(self, contract_hash): |
||||
"""get mapped contract_address by its hash, if not found try |
||||
indexing.""" |
||||
contract_address = self.db.reader._get_address_by_hash(contract_hash) |
||||
if contract_address is not None: |
||||
return contract_address |
||||
|
||||
else: |
||||
raise AddressNotFoundError |
||||
|
||||
def _process(self, startblock): |
||||
"""Processesing method.""" |
||||
log.debug("Processing blocks %d to %d" % (startblock, startblock + BATCH_SIZE)) |
||||
|
||||
addresses = [] |
||||
|
||||
for blockNum in range(startblock, startblock + BATCH_SIZE): |
||||
block_hash = self.db.reader._get_block_hash(blockNum) |
||||
if block_hash is not None: |
||||
receipts = self.db.reader._get_block_receipts(block_hash, blockNum) |
||||
|
||||
for receipt in receipts: |
||||
if receipt.contractAddress is not None and not all( |
||||
b == 0 for b in receipt.contractAddress |
||||
): |
||||
addresses.append(receipt.contractAddress) |
||||
else: |
||||
if len(addresses) == 0: |
||||
raise Exception() |
||||
|
||||
return addresses |
||||
|
||||
def updateIfNeeded(self): |
||||
"""update address index.""" |
||||
headBlock = self.db.reader._get_head_block() |
||||
if headBlock is not None: |
||||
# avoid restarting search if head block is same & we already initialized |
||||
# this is required for fastSync handling |
||||
if self.lastBlock is not None: |
||||
self.lastBlock = max(self.lastBlock, headBlock.number) |
||||
else: |
||||
self.lastBlock = headBlock.number |
||||
lastProcessed = self.db.reader._get_last_indexed_number() |
||||
if lastProcessed is not None: |
||||
self.lastProcessedBlock = utils.big_endian_to_int(lastProcessed) |
||||
|
||||
# in fast sync head block is at 0 (e.g. in fastSync), we can't use it to determine length |
||||
if self.lastBlock is not None and self.lastBlock == 0: |
||||
self.lastBlock = 2e9 |
||||
|
||||
if self.lastBlock is None or ( |
||||
self.lastProcessedBlock is not None |
||||
and self.lastBlock <= self.lastProcessedBlock |
||||
): |
||||
return |
||||
|
||||
blockNum = 0 |
||||
if self.lastProcessedBlock is not None: |
||||
blockNum = self.lastProcessedBlock + 1 |
||||
print( |
||||
"Updating hash-to-address index from block " |
||||
+ str(self.lastProcessedBlock) |
||||
) |
||||
else: |
||||
print("Starting hash-to-address index") |
||||
|
||||
count = 0 |
||||
processed = 0 |
||||
|
||||
while blockNum <= self.lastBlock: |
||||
# leveldb cannot be accessed on multiple processes (not even readonly) |
||||
# multithread version performs significantly worse than serial |
||||
try: |
||||
results = self._process(blockNum) |
||||
except: |
||||
break |
||||
|
||||
# store new mappings |
||||
self.db.writer._start_writing() |
||||
count += len(results) |
||||
for addr in results: |
||||
self.db.writer._store_account_address(addr) |
||||
|
||||
self.db.writer._commit_batch() |
||||
|
||||
processed += BATCH_SIZE |
||||
blockNum = min(blockNum + BATCH_SIZE, self.lastBlock + 1) |
||||
|
||||
cost_time = time.time() - ethereum.start_time |
||||
print( |
||||
"%d blocks processed (in %d seconds), %d unique addresses found, next block: %d" |
||||
% (processed, cost_time, count, min(self.lastBlock, blockNum)) |
||||
) |
||||
|
||||
self.lastProcessedBlock = blockNum - 1 |
||||
self.db.writer._set_last_indexed_number(self.lastProcessedBlock) |
||||
|
||||
print("Finished indexing") |
||||
self.lastBlock = self.lastProcessedBlock |
@ -1,314 +0,0 @@ |
||||
"""This module contains a LevelDB client.""" |
||||
import binascii |
||||
import rlp |
||||
from mythril.ethereum.interface.leveldb.accountindexing import CountableList |
||||
from mythril.ethereum.interface.leveldb.accountindexing import ( |
||||
ReceiptForStorage, |
||||
AccountIndexer, |
||||
) |
||||
import logging |
||||
from ethereum import utils |
||||
from ethereum.block import BlockHeader, Block |
||||
from mythril.ethereum.interface.leveldb.state import State |
||||
from mythril.ethereum.interface.leveldb.eth_db import ETH_DB |
||||
from mythril.ethereum.evmcontract import EVMContract |
||||
from mythril.exceptions import AddressNotFoundError |
||||
|
||||
log = logging.getLogger(__name__) |
||||
|
||||
# Per https://github.com/ethereum/go-ethereum/blob/master/core/rawdb/schema.go |
||||
# prefixes and suffixes for keys in geth |
||||
header_prefix = b"h" # header_prefix + num (uint64 big endian) + hash -> header |
||||
body_prefix = b"b" # body_prefix + num (uint64 big endian) + hash -> block body |
||||
num_suffix = b"n" # header_prefix + num (uint64 big endian) + num_suffix -> hash |
||||
block_hash_prefix = b"H" # block_hash_prefix + hash -> num (uint64 big endian) |
||||
block_receipts_prefix = ( |
||||
b"r" # block_receipts_prefix + num (uint64 big endian) + hash -> block receipts |
||||
) |
||||
# known geth keys |
||||
head_header_key = b"LastBlock" # head (latest) header hash |
||||
# custom prefixes |
||||
address_prefix = b"AM" # address_prefix + hash -> address |
||||
# custom keys |
||||
address_mapping_head_key = b"accountMapping" # head (latest) number of indexed block |
||||
|
||||
|
||||
def _format_block_number(number): |
||||
"""Format block number to uint64 big endian.""" |
||||
return utils.zpad(utils.int_to_big_endian(number), 8) |
||||
|
||||
|
||||
def _encode_hex(v): |
||||
"""Encode a hash string as hex.""" |
||||
return "0x" + utils.encode_hex(v) |
||||
|
||||
|
||||
class LevelDBReader(object): |
||||
"""LevelDB reading interface, can be used with snapshot.""" |
||||
|
||||
def __init__(self, db): |
||||
""" |
||||
|
||||
:param db: |
||||
""" |
||||
self.db = db |
||||
self.head_block_header = None |
||||
self.head_state = None |
||||
|
||||
def _get_head_state(self): |
||||
"""Get head state. |
||||
|
||||
:return: |
||||
""" |
||||
if not self.head_state: |
||||
root = self._get_head_block().state_root |
||||
self.head_state = State(self.db, root) |
||||
return self.head_state |
||||
|
||||
def _get_account(self, address): |
||||
"""Get account by address. |
||||
|
||||
:param address: |
||||
:return: |
||||
""" |
||||
state = self._get_head_state() |
||||
account_address = binascii.a2b_hex(utils.remove_0x_head(address)) |
||||
return state.get_and_cache_account(account_address) |
||||
|
||||
def _get_block_hash(self, number): |
||||
"""Get block hash by block number. |
||||
|
||||
:param number: |
||||
:return: |
||||
""" |
||||
num = _format_block_number(number) |
||||
hash_key = header_prefix + num + num_suffix |
||||
return self.db.get(hash_key) |
||||
|
||||
def _get_head_block(self): |
||||
"""Get head block header. |
||||
|
||||
:return: |
||||
""" |
||||
if not self.head_block_header: |
||||
block_hash = self.db.get(head_header_key) |
||||
num = self._get_block_number(block_hash) |
||||
self.head_block_header = self._get_block_header(block_hash, num) |
||||
# find header with valid state |
||||
while ( |
||||
not self.db.get(self.head_block_header.state_root) |
||||
and self.head_block_header.prevhash is not None |
||||
): |
||||
block_hash = self.head_block_header.prevhash |
||||
num = self._get_block_number(block_hash) |
||||
self.head_block_header = self._get_block_header(block_hash, num) |
||||
|
||||
return self.head_block_header |
||||
|
||||
def _get_block_number(self, block_hash): |
||||
"""Get block number by its hash. |
||||
|
||||
:param block_hash: |
||||
:return: |
||||
""" |
||||
number_key = block_hash_prefix + block_hash |
||||
return self.db.get(number_key) |
||||
|
||||
def _get_block_header(self, block_hash, num): |
||||
"""Get block header by block header hash & number. |
||||
|
||||
:param block_hash: |
||||
:param num: |
||||
:return: |
||||
""" |
||||
header_key = header_prefix + num + block_hash |
||||
|
||||
block_header_data = self.db.get(header_key) |
||||
header = rlp.decode(block_header_data, sedes=BlockHeader) |
||||
return header |
||||
|
||||
def _get_address_by_hash(self, block_hash): |
||||
"""Get mapped address by its hash. |
||||
|
||||
:param block_hash: |
||||
:return: |
||||
""" |
||||
address_key = address_prefix + block_hash |
||||
return self.db.get(address_key) |
||||
|
||||
def _get_last_indexed_number(self): |
||||
"""Get latest indexed block number. |
||||
|
||||
:return: |
||||
""" |
||||
return self.db.get(address_mapping_head_key) |
||||
|
||||
def _get_block_receipts(self, block_hash, num): |
||||
"""Get block transaction receipts by block header hash & number. |
||||
|
||||
:param block_hash: |
||||
:param num: |
||||
:return: |
||||
""" |
||||
number = _format_block_number(num) |
||||
receipts_key = block_receipts_prefix + number + block_hash |
||||
receipts_data = self.db.get(receipts_key) |
||||
receipts = rlp.decode(receipts_data, sedes=CountableList(ReceiptForStorage)) |
||||
return receipts |
||||
|
||||
|
||||
class LevelDBWriter(object): |
||||
"""level db writing interface.""" |
||||
|
||||
def __init__(self, db): |
||||
""" |
||||
|
||||
:param db: |
||||
""" |
||||
self.db = db |
||||
self.wb = None |
||||
|
||||
def _set_last_indexed_number(self, number): |
||||
"""Set latest indexed block number. |
||||
|
||||
:param number: |
||||
:return: |
||||
""" |
||||
return self.db.put(address_mapping_head_key, _format_block_number(number)) |
||||
|
||||
def _start_writing(self): |
||||
"""Start writing a batch.""" |
||||
self.wb = self.db.write_batch() |
||||
|
||||
def _commit_batch(self): |
||||
"""Commit a batch.""" |
||||
self.wb.write() |
||||
|
||||
def _store_account_address(self, address): |
||||
"""Get block transaction receipts by block header hash & number. |
||||
|
||||
:param address: |
||||
""" |
||||
address_key = address_prefix + utils.sha3(address) |
||||
self.wb.put(address_key, address) |
||||
|
||||
|
||||
class EthLevelDB(object): |
||||
"""Go-Ethereum LevelDB client class.""" |
||||
|
||||
def __init__(self, path): |
||||
""" |
||||
|
||||
:param path: |
||||
""" |
||||
self.path = path |
||||
self.db = ETH_DB(path) |
||||
self.reader = LevelDBReader(self.db) |
||||
self.writer = LevelDBWriter(self.db) |
||||
|
||||
def get_contracts(self): |
||||
"""Iterate through all contracts.""" |
||||
for account in self.reader._get_head_state().get_all_accounts(): |
||||
if account.code is not None: |
||||
code = _encode_hex(account.code) |
||||
contract = EVMContract(code, enable_online_lookup=False) |
||||
|
||||
yield contract, account.address, account.balance |
||||
|
||||
def search(self, expression, callback_func): |
||||
"""Search through all contract accounts. |
||||
|
||||
:param expression: |
||||
:param callback_func: |
||||
""" |
||||
cnt = 0 |
||||
indexer = AccountIndexer(self) |
||||
|
||||
for contract, address_hash, balance in self.get_contracts(): |
||||
|
||||
if contract.matches_expression(expression): |
||||
|
||||
try: |
||||
address = _encode_hex(indexer.get_contract_by_hash(address_hash)) |
||||
except AddressNotFoundError: |
||||
"""The hash->address mapping does not exist in our index. |
||||
|
||||
If the index is up-to-date, this likely means that |
||||
the contract was created by an internal transaction. |
||||
Skip this contract as right now we don't have a good |
||||
solution for this. |
||||
""" |
||||
|
||||
continue |
||||
|
||||
callback_func(contract, address, balance) |
||||
|
||||
cnt += 1 |
||||
|
||||
if not cnt % 1000: |
||||
log.info("Searched %d contracts" % cnt) |
||||
|
||||
def contract_hash_to_address(self, contract_hash): |
||||
"""Try to find corresponding account address. |
||||
|
||||
:param contract_hash: |
||||
:return: |
||||
""" |
||||
|
||||
address_hash = binascii.a2b_hex(utils.remove_0x_head(contract_hash)) |
||||
indexer = AccountIndexer(self) |
||||
|
||||
return _encode_hex(indexer.get_contract_by_hash(address_hash)) |
||||
|
||||
def eth_getBlockHeaderByNumber(self, number): |
||||
"""Get block header by block number. |
||||
|
||||
:param number: |
||||
:return: |
||||
""" |
||||
block_hash = self.reader._get_block_hash(number) |
||||
block_number = _format_block_number(number) |
||||
return self.reader._get_block_header(block_hash, block_number) |
||||
|
||||
def eth_getBlockByNumber(self, number): |
||||
"""Get block body by block number. |
||||
|
||||
:param number: |
||||
:return: |
||||
""" |
||||
block_hash = self.reader._get_block_hash(number) |
||||
block_number = _format_block_number(number) |
||||
body_key = body_prefix + block_number + block_hash |
||||
block_data = self.db.get(body_key) |
||||
body = rlp.decode(block_data, sedes=Block) |
||||
return body |
||||
|
||||
def eth_getCode(self, address): |
||||
"""Get account code. |
||||
|
||||
:param address: |
||||
:return: |
||||
""" |
||||
account = self.reader._get_account(address) |
||||
return _encode_hex(account.code) |
||||
|
||||
def eth_getBalance(self, address): |
||||
"""Get account balance. |
||||
|
||||
:param address: |
||||
:return: |
||||
""" |
||||
account = self.reader._get_account(address) |
||||
return account.balance |
||||
|
||||
def eth_getStorageAt(self, address, position): |
||||
"""Get account storage data at position. |
||||
|
||||
:param address: |
||||
:param position: |
||||
:return: |
||||
""" |
||||
account = self.reader._get_account(address) |
||||
return _encode_hex( |
||||
utils.zpad(utils.encode_int(account.get_storage_data(position)), 32) |
||||
) |
@ -1,23 +0,0 @@ |
||||
"""This module contains the ETH_DB class, which the base database used by |
||||
pyethereum.""" |
||||
import plyvel |
||||
from ethereum.db import BaseDB |
||||
|
||||
|
||||
class ETH_DB(BaseDB): |
||||
"""Adopts pythereum BaseDB using plyvel.""" |
||||
|
||||
def __init__(self, path): |
||||
self.db = plyvel.DB(path) |
||||
|
||||
def get(self, key): |
||||
"""gets value for key.""" |
||||
return self.db.get(key) |
||||
|
||||
def put(self, key, value): |
||||
"""puts value for key.""" |
||||
self.db.put(key, value) |
||||
|
||||
def write_batch(self): |
||||
"""start writing a batch.""" |
||||
return self.db.write_batch() |
@ -1,165 +0,0 @@ |
||||
"""This module implements wrappers around the pyethereum state for LevelDB.""" |
||||
import rlp |
||||
import binascii |
||||
from ethereum.utils import ( |
||||
normalize_address, |
||||
hash32, |
||||
trie_root, |
||||
big_endian_int, |
||||
address, |
||||
int256, |
||||
encode_hex, |
||||
encode_int, |
||||
big_endian_to_int, |
||||
int_to_addr, |
||||
zpad, |
||||
parse_as_bin, |
||||
parse_as_int, |
||||
decode_hex, |
||||
sha3, |
||||
is_string, |
||||
is_numeric, |
||||
) |
||||
from rlp.sedes import big_endian_int, Binary, binary, CountableList |
||||
from ethereum import utils |
||||
from ethereum import trie |
||||
from ethereum.trie import Trie |
||||
from ethereum.securetrie import SecureTrie |
||||
|
||||
BLANK_HASH = utils.sha3(b"") |
||||
BLANK_ROOT = utils.sha3rlp(b"") |
||||
|
||||
STATE_DEFAULTS = { |
||||
"txindex": 0, |
||||
"gas_used": 0, |
||||
"gas_limit": 3141592, |
||||
"block_number": 0, |
||||
"block_coinbase": "\x00" * 20, |
||||
"block_difficulty": 1, |
||||
"timestamp": 0, |
||||
"logs": [], |
||||
"receipts": [], |
||||
"bloom": 0, |
||||
"suicides": [], |
||||
"recent_uncles": {}, |
||||
"prev_headers": [], |
||||
"refunds": 0, |
||||
} |
||||
|
||||
|
||||
class Account(rlp.Serializable): |
||||
"""adjusted account from ethereum.state.""" |
||||
|
||||
fields = [ |
||||
("nonce", big_endian_int), |
||||
("balance", big_endian_int), |
||||
("storage", trie_root), |
||||
("code_hash", hash32), |
||||
] |
||||
|
||||
def __init__(self, nonce, balance, storage, code_hash, db, addr): |
||||
""" |
||||
|
||||
:param nonce: |
||||
:param balance: |
||||
:param storage: |
||||
:param code_hash: |
||||
:param db: |
||||
:param addr: |
||||
""" |
||||
self.db = db |
||||
self.address = addr |
||||
super(Account, self).__init__(nonce, balance, storage, code_hash) |
||||
self.storage_cache = {} |
||||
self.storage_trie = SecureTrie(Trie(self.db)) |
||||
self.storage_trie.root_hash = self.storage |
||||
self.touched = False |
||||
self.existent_at_start = True |
||||
self._mutable = True |
||||
self.deleted = False |
||||
|
||||
@property |
||||
def code(self): |
||||
"""code rlp data.""" |
||||
return self.db.get(self.code_hash) |
||||
|
||||
def get_storage_data(self, key): |
||||
"""get storage data. |
||||
|
||||
:param key: |
||||
:return: |
||||
""" |
||||
if key not in self.storage_cache: |
||||
v = self.storage_trie.get(utils.encode_int32(key)) |
||||
self.storage_cache[key] = utils.big_endian_to_int( |
||||
rlp.decode(v) if v else b"" |
||||
) |
||||
return self.storage_cache[key] |
||||
|
||||
@classmethod |
||||
def blank_account(cls, db, addr, initial_nonce=0): |
||||
"""creates a blank account. |
||||
|
||||
:param db: |
||||
:param addr: |
||||
:param initial_nonce: |
||||
:return: |
||||
""" |
||||
db.put(BLANK_HASH, b"") |
||||
o = cls(initial_nonce, 0, trie.BLANK_ROOT, BLANK_HASH, db, addr) |
||||
o.existent_at_start = False |
||||
return o |
||||
|
||||
def is_blank(self): |
||||
"""checks if is a blank account. |
||||
|
||||
:return: |
||||
""" |
||||
return self.nonce == 0 and self.balance == 0 and self.code_hash == BLANK_HASH |
||||
|
||||
|
||||
class State: |
||||
"""adjusted state from ethereum.state.""" |
||||
|
||||
def __init__(self, db, root): |
||||
""" |
||||
|
||||
:param db: |
||||
:param root: |
||||
""" |
||||
self.db = db |
||||
self.trie = Trie(self.db, root) |
||||
self.secure_trie = SecureTrie(self.trie) |
||||
self.journal = [] |
||||
self.cache = {} |
||||
|
||||
def get_and_cache_account(self, addr): |
||||
"""Gets and caches an account for an addres, creates blank if not |
||||
found. |
||||
|
||||
:param addr: |
||||
:return: |
||||
""" |
||||
|
||||
if addr in self.cache: |
||||
return self.cache[addr] |
||||
rlpdata = self.secure_trie.get(addr) |
||||
if ( |
||||
rlpdata == trie.BLANK_NODE and len(addr) == 32 |
||||
): # support for hashed addresses |
||||
rlpdata = self.trie.get(addr) |
||||
|
||||
if rlpdata != trie.BLANK_NODE: |
||||
o = rlp.decode(rlpdata, Account, db=self.db, addr=addr) |
||||
else: |
||||
o = Account.blank_account(self.db, addr, 0) |
||||
self.cache[addr] = o |
||||
o._mutable = True |
||||
o._cached_rlp = None |
||||
return o |
||||
|
||||
def get_all_accounts(self): |
||||
"""iterates through trie to and yields non-blank leafs as accounts.""" |
||||
for address_hash, rlpdata in self.secure_trie.trie.iter_branch(): |
||||
if rlpdata != trie.BLANK_NODE: |
||||
yield rlp.decode(rlpdata, Account, db=self.db, addr=address_hash) |
@ -1,2 +1,2 @@ |
||||
from .exponent_function_manager import exponent_function_manager |
||||
from .keccak_function_manager import keccak_function_manager |
||||
from .keccak_function_manager import keccak_function_manager, KeccakFunctionManager |
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue