From ef37b97c2582cafd6d06443b5db29acc70cee499 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Sun, 21 Oct 2018 19:10:45 +0530 Subject: [PATCH 01/20] Add sha3 tests --- .../VMTests/vmSha3Test/sha3_0.json | 52 +++++++++++++++++++ .../VMTests/vmSha3Test/sha3_1.json | 52 +++++++++++++++++++ .../VMTests/vmSha3Test/sha3_2.json | 52 +++++++++++++++++++ .../VMTests/vmSha3Test/sha3_3.json | 37 +++++++++++++ .../VMTests/vmSha3Test/sha3_4.json | 37 +++++++++++++ .../VMTests/vmSha3Test/sha3_5.json | 37 +++++++++++++ .../VMTests/vmSha3Test/sha3_6.json | 37 +++++++++++++ .../VMTests/vmSha3Test/sha3_bigOffset.json | 37 +++++++++++++ .../VMTests/vmSha3Test/sha3_bigOffset2.json | 52 +++++++++++++++++++ .../VMTests/vmSha3Test/sha3_bigSize.json | 37 +++++++++++++ .../sha3_memSizeNoQuadraticCost31.json | 52 +++++++++++++++++++ .../sha3_memSizeQuadraticCost32.json | 52 +++++++++++++++++++ .../sha3_memSizeQuadraticCost32_zeroSize.json | 52 +++++++++++++++++++ .../sha3_memSizeQuadraticCost33.json | 52 +++++++++++++++++++ .../sha3_memSizeQuadraticCost63.json | 52 +++++++++++++++++++ .../sha3_memSizeQuadraticCost64.json | 52 +++++++++++++++++++ .../sha3_memSizeQuadraticCost64_2.json | 52 +++++++++++++++++++ .../sha3_memSizeQuadraticCost65.json | 52 +++++++++++++++++++ tests/laser/evm_testsuite/evm_test.py | 12 +++-- 19 files changed, 853 insertions(+), 5 deletions(-) create mode 100644 tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_0.json create mode 100644 tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_1.json create mode 100644 tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_2.json create mode 100644 tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_3.json create mode 100644 tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_4.json create mode 100644 tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_5.json create mode 100644 tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_6.json create mode 100644 tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_bigOffset.json create mode 100644 tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_bigOffset2.json create mode 100644 tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_bigSize.json create mode 100644 tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeNoQuadraticCost31.json create mode 100644 tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost32.json create mode 100644 tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost32_zeroSize.json create mode 100644 tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost33.json create mode 100644 tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost63.json create mode 100644 tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost64.json create mode 100644 tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost64_2.json create mode 100644 tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost65.json diff --git a/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_0.json b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_0.json new file mode 100644 index 00000000..1bfb0c2f --- /dev/null +++ b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_0.json @@ -0,0 +1,52 @@ +{ + "sha3_0" : { + "_info" : { + "comment" : "", + "filledwith" : "cpp-1.3.0+commit.6e0ce939.Linux.g++", + "lllcversion" : "Version: 0.4.18-develop.2017.9.25+commit.a72237f2.Linux.g++", + "source" : "src/VMTestsFiller/vmSha3Test/sha3_0Filler.json", + "sourceHash" : "843009e4e97d7dd905578ea884db6d80c07f57d58679ec181dc761e1e51ae035" + }, + "callcreates" : [ + ], + "env" : { + "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }, + "exec" : { + "address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "code" : "0x6000600020600055", + "data" : "0x", + "gas" : "0x174876e800", + "gasPrice" : "0x3b9aca00", + "origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "0x0de0b6b3a7640000" + }, + "gas" : "0x17487699b9", + "logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "out" : "0x", + "post" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0x152d02c7e14af6800000", + "code" : "0x6000600020600055", + "nonce" : "0x00", + "storage" : { + "0x00" : "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" + } + } + }, + "pre" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0x152d02c7e14af6800000", + "code" : "0x6000600020600055", + "nonce" : "0x00", + "storage" : { + } + } + } + } +} \ No newline at end of file diff --git a/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_1.json b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_1.json new file mode 100644 index 00000000..0b2986d7 --- /dev/null +++ b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_1.json @@ -0,0 +1,52 @@ +{ + "sha3_1" : { + "_info" : { + "comment" : "", + "filledwith" : "cpp-1.3.0+commit.6e0ce939.Linux.g++", + "lllcversion" : "Version: 0.4.18-develop.2017.9.25+commit.a72237f2.Linux.g++", + "source" : "src/VMTestsFiller/vmSha3Test/sha3_1Filler.json", + "sourceHash" : "5f786aded76570c96466f5a4c4632a5a0b362ffc1e4124667cdb1e9328d1d81d" + }, + "callcreates" : [ + ], + "env" : { + "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }, + "exec" : { + "address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "code" : "0x6005600420600055", + "data" : "0x", + "gas" : "0x0186a0", + "gasPrice" : "0x5af3107a4000", + "origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "0x0de0b6b3a7640000" + }, + "gas" : "0x013850", + "logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "out" : "0x", + "post" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0x152d02c7e14af6800000", + "code" : "0x6005600420600055", + "nonce" : "0x00", + "storage" : { + "0x00" : "0xc41589e7559804ea4a2080dad19d876a024ccb05117835447d72ce08c1d020ec" + } + } + }, + "pre" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0x152d02c7e14af6800000", + "code" : "0x6005600420600055", + "nonce" : "0x00", + "storage" : { + } + } + } + } +} \ No newline at end of file diff --git a/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_2.json b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_2.json new file mode 100644 index 00000000..b1e526af --- /dev/null +++ b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_2.json @@ -0,0 +1,52 @@ +{ + "sha3_2" : { + "_info" : { + "comment" : "", + "filledwith" : "cpp-1.3.0+commit.6e0ce939.Linux.g++", + "lllcversion" : "Version: 0.4.18-develop.2017.9.25+commit.a72237f2.Linux.g++", + "source" : "src/VMTestsFiller/vmSha3Test/sha3_2Filler.json", + "sourceHash" : "bb3f59dc995c834eaf315b4819900c30ba4e97ef60163aed05946c70e841691f" + }, + "callcreates" : [ + ], + "env" : { + "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }, + "exec" : { + "address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "code" : "0x600a600a20600055", + "data" : "0x", + "gas" : "0x0186a0", + "gasPrice" : "0x5af3107a4000", + "origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "0x0de0b6b3a7640000" + }, + "gas" : "0x013850", + "logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "out" : "0x", + "post" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0x152d02c7e14af6800000", + "code" : "0x600a600a20600055", + "nonce" : "0x00", + "storage" : { + "0x00" : "0x6bd2dd6bd408cbee33429358bf24fdc64612fbf8b1b4db604518f40ffd34b607" + } + } + }, + "pre" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0x152d02c7e14af6800000", + "code" : "0x600a600a20600055", + "nonce" : "0x00", + "storage" : { + } + } + } + } +} \ No newline at end of file diff --git a/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_3.json b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_3.json new file mode 100644 index 00000000..447b0cd0 --- /dev/null +++ b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_3.json @@ -0,0 +1,37 @@ +{ + "sha3_3" : { + "_info" : { + "comment" : "", + "filledwith" : "cpp-1.3.0+commit.6e0ce939.Linux.g++", + "lllcversion" : "Version: 0.4.18-develop.2017.9.25+commit.a72237f2.Linux.g++", + "source" : "src/VMTestsFiller/vmSha3Test/sha3_3Filler.json", + "sourceHash" : "1f474f7dac8971615e641354d809db332975d1ea5ca589d855fb02a1da559033" + }, + "env" : { + "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }, + "exec" : { + "address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "code" : "0x620fffff6103e820600055", + "data" : "0x", + "gas" : "0x0186a0", + "gasPrice" : "0x5af3107a4000", + "origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "0x0de0b6b3a7640000" + }, + "pre" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0x152d02c7e14af6800000", + "code" : "0x620fffff6103e820600055", + "nonce" : "0x00", + "storage" : { + } + } + } + } +} \ No newline at end of file diff --git a/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_4.json b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_4.json new file mode 100644 index 00000000..265cbbfa --- /dev/null +++ b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_4.json @@ -0,0 +1,37 @@ +{ + "sha3_4" : { + "_info" : { + "comment" : "", + "filledwith" : "cpp-1.3.0+commit.6e0ce939.Linux.g++", + "lllcversion" : "Version: 0.4.18-develop.2017.9.25+commit.a72237f2.Linux.g++", + "source" : "src/VMTestsFiller/vmSha3Test/sha3_4Filler.json", + "sourceHash" : "100da75ff0b63159ca86aa4ef7457a956027af5c6c1ed1f0fa894aaa63849887" + }, + "env" : { + "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }, + "exec" : { + "address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "code" : "0x6064640fffffffff20600055", + "data" : "0x", + "gas" : "0x0186a0", + "gasPrice" : "0x5af3107a4000", + "origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "0x0de0b6b3a7640000" + }, + "pre" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0x152d02c7e14af6800000", + "code" : "0x6064640fffffffff20600055", + "nonce" : "0x00", + "storage" : { + } + } + } + } +} \ No newline at end of file diff --git a/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_5.json b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_5.json new file mode 100644 index 00000000..86d87942 --- /dev/null +++ b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_5.json @@ -0,0 +1,37 @@ +{ + "sha3_5" : { + "_info" : { + "comment" : "", + "filledwith" : "cpp-1.3.0+commit.6e0ce939.Linux.g++", + "lllcversion" : "Version: 0.4.18-develop.2017.9.25+commit.a72237f2.Linux.g++", + "source" : "src/VMTestsFiller/vmSha3Test/sha3_5Filler.json", + "sourceHash" : "066bcf3a8e9e7b4c15ec2240c8e1bb0d53de0230c76989e21e4b6aaac83f577d" + }, + "env" : { + "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }, + "exec" : { + "address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "code" : "0x640fffffffff61271020600055", + "data" : "0x", + "gas" : "0x0186a0", + "gasPrice" : "0x5af3107a4000", + "origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "0x0de0b6b3a7640000" + }, + "pre" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0x152d02c7e14af6800000", + "code" : "0x640fffffffff61271020600055", + "nonce" : "0x00", + "storage" : { + } + } + } + } +} \ No newline at end of file diff --git a/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_6.json b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_6.json new file mode 100644 index 00000000..97a6788e --- /dev/null +++ b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_6.json @@ -0,0 +1,37 @@ +{ + "sha3_6" : { + "_info" : { + "comment" : "", + "filledwith" : "cpp-1.3.0+commit.6e0ce939.Linux.g++", + "lllcversion" : "Version: 0.4.18-develop.2017.9.25+commit.a72237f2.Linux.g++", + "source" : "src/VMTestsFiller/vmSha3Test/sha3_6Filler.json", + "sourceHash" : "c360c6583bf965674d153f11c243c1e0807e95e99bc9bcb684a7ad2c7155dd40" + }, + "env" : { + "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }, + "exec" : { + "address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff20600055", + "data" : "0x", + "gas" : "0x0186a0", + "gasPrice" : "0x5af3107a4000", + "origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "0x0de0b6b3a7640000" + }, + "pre" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0x152d02c7e14af6800000", + "code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff20600055", + "nonce" : "0x00", + "storage" : { + } + } + } + } +} \ No newline at end of file diff --git a/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_bigOffset.json b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_bigOffset.json new file mode 100644 index 00000000..940cff9b --- /dev/null +++ b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_bigOffset.json @@ -0,0 +1,37 @@ +{ + "sha3_bigOffset" : { + "_info" : { + "comment" : "", + "filledwith" : "cpp-1.3.0+commit.6e0ce939.Linux.g++", + "lllcversion" : "Version: 0.4.18-develop.2017.9.25+commit.a72237f2.Linux.g++", + "source" : "src/VMTestsFiller/vmSha3Test/sha3_bigOffsetFiller.json", + "sourceHash" : "1ae2cdfa2e3ab1cac89d8b3d535c3ee50601ebc6098fdbddadca74980eec6382" + }, + "env" : { + "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }, + "exec" : { + "address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "code" : "0x60027e0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff20600055", + "data" : "0x", + "gas" : "0x010000000000", + "gasPrice" : "0x01", + "origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + }, + "pre" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x60027e0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff20600055", + "nonce" : "0x00", + "storage" : { + } + } + } + } +} \ No newline at end of file diff --git a/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_bigOffset2.json b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_bigOffset2.json new file mode 100644 index 00000000..d5ab8ebc --- /dev/null +++ b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_bigOffset2.json @@ -0,0 +1,52 @@ +{ + "sha3_bigOffset2" : { + "_info" : { + "comment" : "", + "filledwith" : "cpp-1.3.0+commit.6e0ce939.Linux.g++", + "lllcversion" : "Version: 0.4.18-develop.2017.9.25+commit.a72237f2.Linux.g++", + "source" : "src/VMTestsFiller/vmSha3Test/sha3_bigOffset2Filler.json", + "sourceHash" : "2bf8d14886b1001b266c29bd9f9e764f7e6965e851bfe1440e536735fca993dc" + }, + "callcreates" : [ + ], + "env" : { + "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }, + "exec" : { + "address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "code" : "0x6002630100000020600055", + "data" : "0x", + "gas" : "0x0100000000", + "gasPrice" : "0x01", + "origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + }, + "gas" : "0xdfe7a9b0", + "logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "out" : "0x", + "post" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x6002630100000020600055", + "nonce" : "0x00", + "storage" : { + "0x00" : "0x54a8c0ab653c15bfb48b47fd011ba2b9617af01cb45cab344acd57c924d56798" + } + } + }, + "pre" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x6002630100000020600055", + "nonce" : "0x00", + "storage" : { + } + } + } + } +} \ No newline at end of file diff --git a/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_bigSize.json b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_bigSize.json new file mode 100644 index 00000000..b859b929 --- /dev/null +++ b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_bigSize.json @@ -0,0 +1,37 @@ +{ + "sha3_bigSize" : { + "_info" : { + "comment" : "", + "filledwith" : "cpp-1.3.0+commit.6e0ce939.Linux.g++", + "lllcversion" : "Version: 0.4.18-develop.2017.9.25+commit.a72237f2.Linux.g++", + "source" : "src/VMTestsFiller/vmSha3Test/sha3_bigSizeFiller.json", + "sourceHash" : "571bfd9a15c6b0e317f96a92f745aee1d800aa4486c1a101b3e016120ffb5415" + }, + "env" : { + "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }, + "exec" : { + "address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "code" : "0x7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff20600055", + "data" : "0x", + "gas" : "0x010000000000", + "gasPrice" : "0x01", + "origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + }, + "pre" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff20600055", + "nonce" : "0x00", + "storage" : { + } + } + } + } +} \ No newline at end of file diff --git a/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeNoQuadraticCost31.json b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeNoQuadraticCost31.json new file mode 100644 index 00000000..8d6caa4a --- /dev/null +++ b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeNoQuadraticCost31.json @@ -0,0 +1,52 @@ +{ + "sha3_memSizeNoQuadraticCost31" : { + "_info" : { + "comment" : "", + "filledwith" : "cpp-1.3.0+commit.6e0ce939.Linux.g++", + "lllcversion" : "Version: 0.4.18-develop.2017.9.25+commit.a72237f2.Linux.g++", + "source" : "src/VMTestsFiller/vmSha3Test/sha3_memSizeNoQuadraticCost31Filler.json", + "sourceHash" : "04553284981ef7338bdeac0e029652313a2643169833e386ca34bfa3d5e5942a" + }, + "callcreates" : [ + ], + "env" : { + "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }, + "exec" : { + "address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "code" : "0x60016103c020600055", + "data" : "0x", + "gas" : "0x0100000000", + "gasPrice" : "0x01", + "origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + }, + "gas" : "0xffffb155", + "logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "out" : "0x", + "post" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x60016103c020600055", + "nonce" : "0x00", + "storage" : { + "0x00" : "0xbc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a" + } + } + }, + "pre" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x60016103c020600055", + "nonce" : "0x00", + "storage" : { + } + } + } + } +} \ No newline at end of file diff --git a/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost32.json b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost32.json new file mode 100644 index 00000000..6374c1cc --- /dev/null +++ b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost32.json @@ -0,0 +1,52 @@ +{ + "sha3_memSizeQuadraticCost32" : { + "_info" : { + "comment" : "", + "filledwith" : "cpp-1.3.0+commit.6e0ce939.Linux.g++", + "lllcversion" : "Version: 0.4.18-develop.2017.9.25+commit.a72237f2.Linux.g++", + "source" : "src/VMTestsFiller/vmSha3Test/sha3_memSizeQuadraticCost32Filler.json", + "sourceHash" : "70f68e0328222cc2c995bf932f2f8f65f5d4c7e9f040a51bbf4dae3cad9110cf" + }, + "callcreates" : [ + ], + "env" : { + "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }, + "exec" : { + "address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "code" : "0x60016103e020600055", + "data" : "0x", + "gas" : "0x0100000000", + "gasPrice" : "0x01", + "origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + }, + "gas" : "0xffffb151", + "logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "out" : "0x", + "post" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x60016103e020600055", + "nonce" : "0x00", + "storage" : { + "0x00" : "0xbc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a" + } + } + }, + "pre" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x60016103e020600055", + "nonce" : "0x00", + "storage" : { + } + } + } + } +} \ No newline at end of file diff --git a/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost32_zeroSize.json b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost32_zeroSize.json new file mode 100644 index 00000000..fb0c70dc --- /dev/null +++ b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost32_zeroSize.json @@ -0,0 +1,52 @@ +{ + "sha3_memSizeQuadraticCost32_zeroSize" : { + "_info" : { + "comment" : "", + "filledwith" : "cpp-1.3.0+commit.6e0ce939.Linux.g++", + "lllcversion" : "Version: 0.4.18-develop.2017.9.25+commit.a72237f2.Linux.g++", + "source" : "src/VMTestsFiller/vmSha3Test/sha3_memSizeQuadraticCost32_zeroSizeFiller.json", + "sourceHash" : "96094eee3e3fcd478fe3780ff053e64bf5391616bfdc6c2017bf12dcc5d30366" + }, + "callcreates" : [ + ], + "env" : { + "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }, + "exec" : { + "address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "code" : "0x600061040020600055", + "data" : "0x", + "gas" : "0x0100000000", + "gasPrice" : "0x01", + "origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + }, + "gas" : "0xffffb1b9", + "logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "out" : "0x", + "post" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x600061040020600055", + "nonce" : "0x00", + "storage" : { + "0x00" : "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" + } + } + }, + "pre" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x600061040020600055", + "nonce" : "0x00", + "storage" : { + } + } + } + } +} \ No newline at end of file diff --git a/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost33.json b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost33.json new file mode 100644 index 00000000..71034990 --- /dev/null +++ b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost33.json @@ -0,0 +1,52 @@ +{ + "sha3_memSizeQuadraticCost33" : { + "_info" : { + "comment" : "", + "filledwith" : "cpp-1.3.0+commit.6e0ce939.Linux.g++", + "lllcversion" : "Version: 0.4.18-develop.2017.9.25+commit.a72237f2.Linux.g++", + "source" : "src/VMTestsFiller/vmSha3Test/sha3_memSizeQuadraticCost33Filler.json", + "sourceHash" : "2fc9e00a7759c4271b6897b285ae437f6484281e9113e82a8252afbe16e85841" + }, + "callcreates" : [ + ], + "env" : { + "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }, + "exec" : { + "address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "code" : "0x600161040020600055", + "data" : "0x", + "gas" : "0x0100000000", + "gasPrice" : "0x01", + "origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + }, + "gas" : "0xffffb14e", + "logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "out" : "0x", + "post" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x600161040020600055", + "nonce" : "0x00", + "storage" : { + "0x00" : "0xbc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a" + } + } + }, + "pre" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x600161040020600055", + "nonce" : "0x00", + "storage" : { + } + } + } + } +} \ No newline at end of file diff --git a/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost63.json b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost63.json new file mode 100644 index 00000000..a32d5cdd --- /dev/null +++ b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost63.json @@ -0,0 +1,52 @@ +{ + "sha3_memSizeQuadraticCost63" : { + "_info" : { + "comment" : "", + "filledwith" : "cpp-1.3.0+commit.6e0ce939.Linux.g++", + "lllcversion" : "Version: 0.4.18-develop.2017.9.25+commit.a72237f2.Linux.g++", + "source" : "src/VMTestsFiller/vmSha3Test/sha3_memSizeQuadraticCost63Filler.json", + "sourceHash" : "b81dd9fc94929d24f6a06dac81abb0099b969086ecf83326ecb4d6c98fc36f39" + }, + "callcreates" : [ + ], + "env" : { + "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }, + "exec" : { + "address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "code" : "0x60016107c020600055", + "data" : "0x", + "gas" : "0x0100000000", + "gasPrice" : "0x01", + "origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + }, + "gas" : "0xffffb0ef", + "logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "out" : "0x", + "post" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x60016107c020600055", + "nonce" : "0x00", + "storage" : { + "0x00" : "0xbc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a" + } + } + }, + "pre" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x60016107c020600055", + "nonce" : "0x00", + "storage" : { + } + } + } + } +} \ No newline at end of file diff --git a/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost64.json b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost64.json new file mode 100644 index 00000000..d9ea26cc --- /dev/null +++ b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost64.json @@ -0,0 +1,52 @@ +{ + "sha3_memSizeQuadraticCost64" : { + "_info" : { + "comment" : "", + "filledwith" : "cpp-1.3.0+commit.6e0ce939.Linux.g++", + "lllcversion" : "Version: 0.4.18-develop.2017.9.25+commit.a72237f2.Linux.g++", + "source" : "src/VMTestsFiller/vmSha3Test/sha3_memSizeQuadraticCost64Filler.json", + "sourceHash" : "9f1ae20cc7b481e84732b835af1d284c815d79a470ceb1094f0cf9e765a64b8d" + }, + "callcreates" : [ + ], + "env" : { + "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }, + "exec" : { + "address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "code" : "0x60016107e020600055", + "data" : "0x", + "gas" : "0x0100000000", + "gasPrice" : "0x01", + "origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + }, + "gas" : "0xffffb0eb", + "logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "out" : "0x", + "post" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x60016107e020600055", + "nonce" : "0x00", + "storage" : { + "0x00" : "0xbc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a" + } + } + }, + "pre" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x60016107e020600055", + "nonce" : "0x00", + "storage" : { + } + } + } + } +} \ No newline at end of file diff --git a/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost64_2.json b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost64_2.json new file mode 100644 index 00000000..b7dc0bc3 --- /dev/null +++ b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost64_2.json @@ -0,0 +1,52 @@ +{ + "sha3_memSizeQuadraticCost64_2" : { + "_info" : { + "comment" : "", + "filledwith" : "cpp-1.3.0+commit.6e0ce939.Linux.g++", + "lllcversion" : "Version: 0.4.18-develop.2017.9.25+commit.a72237f2.Linux.g++", + "source" : "src/VMTestsFiller/vmSha3Test/sha3_memSizeQuadraticCost64_2Filler.json", + "sourceHash" : "4d313aaddd74f092eae5089cce1aef3aadc74b019f617fdf24acedd8fb26300b" + }, + "callcreates" : [ + ], + "env" : { + "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }, + "exec" : { + "address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "code" : "0x60206107e020600055", + "data" : "0x", + "gas" : "0x0100000000", + "gasPrice" : "0x01", + "origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + }, + "gas" : "0xffffb0eb", + "logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "out" : "0x", + "post" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x60206107e020600055", + "nonce" : "0x00", + "storage" : { + "0x00" : "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563" + } + } + }, + "pre" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x60206107e020600055", + "nonce" : "0x00", + "storage" : { + } + } + } + } +} \ No newline at end of file diff --git a/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost65.json b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost65.json new file mode 100644 index 00000000..733a1776 --- /dev/null +++ b/tests/laser/evm_testsuite/VMTests/vmSha3Test/sha3_memSizeQuadraticCost65.json @@ -0,0 +1,52 @@ +{ + "sha3_memSizeQuadraticCost65" : { + "_info" : { + "comment" : "", + "filledwith" : "cpp-1.3.0+commit.6e0ce939.Linux.g++", + "lllcversion" : "Version: 0.4.18-develop.2017.9.25+commit.a72237f2.Linux.g++", + "source" : "src/VMTestsFiller/vmSha3Test/sha3_memSizeQuadraticCost65Filler.json", + "sourceHash" : "28d6ebfb32dd2c00c629fe373fe58fd83466484d6022cd476ca63981ffaa950a" + }, + "callcreates" : [ + ], + "env" : { + "currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "0x0100", + "currentGasLimit" : "0x0f4240", + "currentNumber" : "0x00", + "currentTimestamp" : "0x01" + }, + "exec" : { + "address" : "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "code" : "0x600161080020600055", + "data" : "0x", + "gas" : "0x0100000000", + "gasPrice" : "0x01", + "origin" : "0xcd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + }, + "gas" : "0xffffb0e8", + "logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "out" : "0x", + "post" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x600161080020600055", + "nonce" : "0x00", + "storage" : { + "0x00" : "0xbc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a" + } + } + }, + "pre" : { + "0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "code" : "0x600161080020600055", + "nonce" : "0x00", + "storage" : { + } + } + } + } +} \ No newline at end of file diff --git a/tests/laser/evm_testsuite/evm_test.py b/tests/laser/evm_testsuite/evm_test.py index 82c2c973..e0f5ebf0 100644 --- a/tests/laser/evm_testsuite/evm_test.py +++ b/tests/laser/evm_testsuite/evm_test.py @@ -12,7 +12,7 @@ import pytest evm_test_dir = Path(__file__).parent / 'VMTests' -test_types = ['vmArithmeticTest', 'vmBitwiseLogicOperation', 'vmPushDupSwapTest', 'vmTests'] +test_types = ['vmArithmeticTest', 'vmBitwiseLogicOperation', 'vmPushDupSwapTest', 'vmTests', 'vmSha3Test'] def load_test_data(designations): @@ -52,6 +52,11 @@ def test_vmtest(test_name: str, pre_condition: dict, action: dict, post_conditio # Act laser_evm.time = datetime.now() + + # TODO: move this line below and check for VmExceptions when gas has been implemented + if post_condition == {}: + return + execute_message_call( laser_evm, callee_address=action['address'], @@ -66,10 +71,7 @@ def test_vmtest(test_name: str, pre_condition: dict, action: dict, post_conditio # Assert - if post_condition != {}: - assert len(laser_evm.open_states) == 1 - else: - return + assert len(laser_evm.open_states) == 1 world_state = laser_evm.open_states[0] From b30430252e30fad55e1a80dcb5f9a4b70e408227 Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Mon, 22 Oct 2018 23:22:41 +0200 Subject: [PATCH 02/20] Move asm to disassembler + cleanup --- mythril/{ether => disassembler}/asm.py | 66 ++++++++++++-------------- mythril/disassembler/disassembly.py | 3 +- 2 files changed, 32 insertions(+), 37 deletions(-) rename mythril/{ether => disassembler}/asm.py (57%) diff --git a/mythril/ether/asm.py b/mythril/disassembler/asm.py similarity index 57% rename from mythril/ether/asm.py rename to mythril/disassembler/asm.py index 985b2f07..80623061 100644 --- a/mythril/ether/asm.py +++ b/mythril/disassembler/asm.py @@ -1,51 +1,46 @@ import sys import re +from typing import Pattern, Match + from ethereum.opcodes import opcodes from mythril.ether import util -regex_PUSH = re.compile('^PUSH(\d*)$') +regex_PUSH = re.compile("^PUSH(\d*)$") # Additional mnemonic to catch failed assertions - -opcodes[254] = ['ASSERT_FAIL', 0, 0, 0] +opcodes[254] = ["ASSERT_FAIL", 0, 0, 0] def instruction_list_to_easm(instruction_list): - easm = "" + result = "" for instruction in instruction_list: + result += "{} {}".format(instruction["address"], instruction["opcode"]) + if "argument" in instruction: + result += " " + instruction["argument"] + result += "\n" - easm += str(instruction['address']) + " " + instruction['opcode'] - - if 'argument' in instruction: - easm += " " + instruction['argument'] - - easm += "\n" + return result - return easm - -def easm_to_instruction_list(easm): - - regex_CODELINE = re.compile('^([A-Z0-9]+)(?:\s+([0-9a-fA-Fx]+))?$') +def easm_to_instruction_list(evm_assembly): + regex_CODELINE: Pattern[str] = re.compile("^([A-Z0-9]+)(?:\s+([0-9a-fA-Fx]+))?$") instruction_list = [] - codelines = easm.split('\n') + for line in evm_assembly.split("\n"): - for line in codelines: + match: Match[str] = re.search(regex_CODELINE, line) - m = re.search(regex_CODELINE, line) - - if not m: + if not match: # Invalid code line continue - instruction = {'opcode': m.group(1)} + instruction = {"opcode": match.group(1)} - if m.group(2): - instruction['argument'] = m.group(2)[2:] + if match.group(2): + instruction["argument"] = match.group(2)[2:] instruction_list.append(instruction) @@ -70,13 +65,13 @@ def find_opcode_sequence(pattern, instruction_list): for i in range(0, len(instruction_list) - pattern_length + 1): - if instruction_list[i]['opcode'] in pattern[0]: + if instruction_list[i]["opcode"] in pattern[0]: matched = True for j in range(1, len(pattern)): - if not (instruction_list[i + j]['opcode'] in pattern[j]): + if not (instruction_list[i + j]["opcode"] in pattern[j]): matched = False break @@ -99,7 +94,7 @@ def disassemble(bytecode): while addr < length: - instruction = {'address': addr} + instruction = {"address": addr} try: if sys.version_info > (3, 0): @@ -110,21 +105,20 @@ def disassemble(bytecode): except KeyError: # invalid opcode - instruction_list.append({'address': addr, 'opcode': "INVALID"}) + instruction_list.append({"address": addr, "opcode": "INVALID"}) addr += 1 continue - instruction['opcode'] = opcode[0] + instruction["opcode"] = opcode[0] m = re.search(regex_PUSH, opcode[0]) if m: - argument = bytecode[addr+1:addr+1+int(m.group(1))] - instruction['argument'] = "0x" + argument.hex() + argument = bytecode[addr + 1 : addr + 1 + int(m.group(1))] + instruction["argument"] = "0x" + argument.hex() addr += int(m.group(1)) - instruction_list.append(instruction) addr += 1 @@ -139,14 +133,14 @@ def assemble(instruction_list): for instruction in instruction_list: try: - opcode = get_opcode_from_name(instruction['opcode']) + opcode = get_opcode_from_name(instruction["opcode"]) except RuntimeError: - opcode = 0xbb + opcode = 0xBB - bytecode += opcode.to_bytes(1, byteorder='big') + bytecode += opcode.to_bytes(1, byteorder="big") - if 'argument' in instruction: + if "argument" in instruction: - bytecode += util.safe_decode(instruction['argument']) + bytecode += util.safe_decode(instruction["argument"]) return bytecode diff --git a/mythril/disassembler/disassembly.py b/mythril/disassembler/disassembly.py index e28a4d73..7163f241 100644 --- a/mythril/disassembler/disassembly.py +++ b/mythril/disassembler/disassembly.py @@ -1,4 +1,5 @@ -from mythril.ether import asm, util +from mythril.ether import util +from mythril.disassembler import asm from mythril.support.signatures import SignatureDb import logging From 76b9d46cd8670c15252fe1bd93b478a99083e13c Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Mon, 22 Oct 2018 23:22:57 +0200 Subject: [PATCH 03/20] Remove unused function --- mythril/disassembler/asm.py | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/mythril/disassembler/asm.py b/mythril/disassembler/asm.py index 80623061..89e2e389 100644 --- a/mythril/disassembler/asm.py +++ b/mythril/disassembler/asm.py @@ -24,29 +24,6 @@ def instruction_list_to_easm(instruction_list): return result -def easm_to_instruction_list(evm_assembly): - regex_CODELINE: Pattern[str] = re.compile("^([A-Z0-9]+)(?:\s+([0-9a-fA-Fx]+))?$") - - instruction_list = [] - - for line in evm_assembly.split("\n"): - - match: Match[str] = re.search(regex_CODELINE, line) - - if not match: - # Invalid code line - continue - - instruction = {"opcode": match.group(1)} - - if match.group(2): - instruction["argument"] = match.group(2)[2:] - - instruction_list.append(instruction) - - return instruction_list - - def get_opcode_from_name(name): for opcode, value in opcodes.items(): From 428504196b6a39b2e3d45240491a6bf433417c3a Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Mon, 22 Oct 2018 23:36:33 +0200 Subject: [PATCH 04/20] Clean up sequence code --- mythril/disassembler/asm.py | 57 +++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/mythril/disassembler/asm.py b/mythril/disassembler/asm.py index 89e2e389..16477efe 100644 --- a/mythril/disassembler/asm.py +++ b/mythril/disassembler/asm.py @@ -24,38 +24,39 @@ def instruction_list_to_easm(instruction_list): return result -def get_opcode_from_name(name): - - for opcode, value in opcodes.items(): - - if name == value[0]: - - return opcode - +def get_opcode_from_name(operation_name): + for op_code, value in opcodes.items(): + if operation_name == value[0]: + return op_code raise RuntimeError("Unknown opcode") def find_opcode_sequence(pattern, instruction_list): - match_indexes = [] - - pattern_length = len(pattern) - - for i in range(0, len(instruction_list) - pattern_length + 1): - - if instruction_list[i]["opcode"] in pattern[0]: - - matched = True - - for j in range(1, len(pattern)): - - if not (instruction_list[i + j]["opcode"] in pattern[j]): - matched = False - break - - if matched: - match_indexes.append(i) - - return match_indexes + """ + Returns all indices in instruction_list that point to instruction sequences following a pattern + :param pattern: The pattern to look for. + Example: [["PUSH1", "PUSH2"], ["EQ"]] where ["PUSH1", "EQ"] satisfies the pattern + :param instruction_list: List of instructions to look in + :return: Indices to the instruction sequences + """ + for i in range(0, len(instruction_list) - len(pattern) + 1): + if is_sequence_match(pattern, instruction_list, i): + yield i + + +def is_sequence_match(pattern, instruction_list, index): + """ + Checks if the instructions starting at index follow a pattern + :param pattern: List of lists describing a pattern. + Example: [["PUSH1", "PUSH2"], ["EQ"]] where ["PUSH1", "EQ"] satisfies the pattern + :param instruction_list: List of instructions + :param index: Index to check for + :return: Pattern matched + """ + for index, pattern_slot in enumerate(pattern, start=index): + if not instruction_list[index] in pattern_slot: + return False + return True def disassemble(bytecode): From 057457373c60f2706d0d2fda1fe7f94c997cb280 Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Mon, 22 Oct 2018 23:57:38 +0200 Subject: [PATCH 05/20] Disassemble refactor --- mythril/disassembler/asm.py | 86 ++++++++++++++----------------------- 1 file changed, 32 insertions(+), 54 deletions(-) diff --git a/mythril/disassembler/asm.py b/mythril/disassembler/asm.py index 16477efe..91d63162 100644 --- a/mythril/disassembler/asm.py +++ b/mythril/disassembler/asm.py @@ -1,10 +1,6 @@ -import sys import re -from typing import Pattern, Match from ethereum.opcodes import opcodes -from mythril.ether import util - regex_PUSH = re.compile("^PUSH(\d*)$") @@ -12,6 +8,20 @@ regex_PUSH = re.compile("^PUSH(\d*)$") opcodes[254] = ["ASSERT_FAIL", 0, 0, 0] +class EvmInstruction: + """ Model to hold the information of the disassembly """ + def __init__(self, address, op_code, argument=None): + self.address = address + self.op_code = op_code + self.argument = argument + + def to_dict(self): + result = {"address": self.address, "opcode": self.op_code} + if self.argument: + result["argument"] = self.argument + return result + + def instruction_list_to_easm(instruction_list): result = "" @@ -44,7 +54,7 @@ def find_opcode_sequence(pattern, instruction_list): yield i -def is_sequence_match(pattern, instruction_list, index): +def is_sequence_match(pattern: list, instruction_list, index: int) -> bool: """ Checks if the instructions starting at index follow a pattern :param pattern: List of lists describing a pattern. @@ -59,66 +69,34 @@ def is_sequence_match(pattern, instruction_list, index): return True -def disassemble(bytecode): - +def disassemble(bytecode: str) -> list: + """Disassembles evm bytecode and returns a list of instructions""" instruction_list = [] - addr = 0 - + address = 0 length = len(bytecode) - if "bzzr" in str(bytecode[-43:]): # ignore swarm hash length -= 43 - while addr < length: - - instruction = {"address": addr} - + while address < length: try: - if sys.version_info > (3, 0): - opcode = opcodes[bytecode[addr]] - else: - opcode = opcodes[ord(bytecode[addr])] - + op_code = opcodes[bytecode[address]] except KeyError: - - # invalid opcode - instruction_list.append({"address": addr, "opcode": "INVALID"}) - addr += 1 + instruction_list.append(EvmInstruction(address, "INVALID")) + address += 1 continue - instruction["opcode"] = opcode[0] - - m = re.search(regex_PUSH, opcode[0]) - - if m: - argument = bytecode[addr + 1 : addr + 1 + int(m.group(1))] - instruction["argument"] = "0x" + argument.hex() + op_code_name = op_code[0] + current_instruction = EvmInstruction(address, op_code_name) - addr += int(m.group(1)) + match = re.search(regex_PUSH, op_code_name) + if match: + argument_bytes: bytes = bytecode[address + 1: address + 1 + int(match.group(1))] + current_instruction.argument = "0x" + argument_bytes.hex() + address += int(match.group(1)) - instruction_list.append(instruction) - - addr += 1 + # We use a to_dict() here for compatibility reasons + instruction_list.append(current_instruction.to_dict()) + address += 1 return instruction_list - - -def assemble(instruction_list): - - bytecode = b"" - - for instruction in instruction_list: - - try: - opcode = get_opcode_from_name(instruction["opcode"]) - except RuntimeError: - opcode = 0xBB - - bytecode += opcode.to_bytes(1, byteorder="big") - - if "argument" in instruction: - - bytecode += util.safe_decode(instruction["argument"]) - - return bytecode From 275cbe30aa04820f37c42bc19ab0aca39c21cd14 Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Tue, 23 Oct 2018 00:00:36 +0200 Subject: [PATCH 06/20] fix typo --- mythril/disassembler/asm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mythril/disassembler/asm.py b/mythril/disassembler/asm.py index 91d63162..0c246954 100644 --- a/mythril/disassembler/asm.py +++ b/mythril/disassembler/asm.py @@ -41,7 +41,7 @@ def get_opcode_from_name(operation_name): raise RuntimeError("Unknown opcode") -def find_opcode_sequence(pattern, instruction_list): +def find_op_code_sequence(pattern, instruction_list): """ Returns all indices in instruction_list that point to instruction sequences following a pattern :param pattern: The pattern to look for. From c161b90c865613984f991aedf5d399e63acf8f5f Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Tue, 23 Oct 2018 00:02:39 +0200 Subject: [PATCH 07/20] add typehint --- mythril/disassembler/asm.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mythril/disassembler/asm.py b/mythril/disassembler/asm.py index 0c246954..8eca0c8e 100644 --- a/mythril/disassembler/asm.py +++ b/mythril/disassembler/asm.py @@ -1,4 +1,5 @@ import re +from collections import Generator from ethereum.opcodes import opcodes @@ -41,7 +42,7 @@ def get_opcode_from_name(operation_name): raise RuntimeError("Unknown opcode") -def find_op_code_sequence(pattern, instruction_list): +def find_op_code_sequence(pattern, instruction_list) -> Generator[int, None, None]: """ Returns all indices in instruction_list that point to instruction sequences following a pattern :param pattern: The pattern to look for. From 0fa27b8e213000e47072e63413d1c3522217d216 Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Tue, 23 Oct 2018 00:24:31 +0200 Subject: [PATCH 08/20] Remove generator type and add asm get opcode tests --- mythril/disassembler/asm.py | 2 +- tests/disassembler/__init__.py | 0 tests/disassembler/asm.py | 20 ++++++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 tests/disassembler/__init__.py create mode 100644 tests/disassembler/asm.py diff --git a/mythril/disassembler/asm.py b/mythril/disassembler/asm.py index 8eca0c8e..6308b5d8 100644 --- a/mythril/disassembler/asm.py +++ b/mythril/disassembler/asm.py @@ -42,7 +42,7 @@ def get_opcode_from_name(operation_name): raise RuntimeError("Unknown opcode") -def find_op_code_sequence(pattern, instruction_list) -> Generator[int, None, None]: +def find_op_code_sequence(pattern, instruction_list): """ Returns all indices in instruction_list that point to instruction sequences following a pattern :param pattern: The pattern to look for. diff --git a/tests/disassembler/__init__.py b/tests/disassembler/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/disassembler/asm.py b/tests/disassembler/asm.py new file mode 100644 index 00000000..4eaada3f --- /dev/null +++ b/tests/disassembler/asm.py @@ -0,0 +1,20 @@ +from mythril.disassembler.asm import * +import pytest + +valid_names = [("PUSH1", 0x60), ("STOP", 0x0), ("RETURN", 0xf3)] + + +@pytest.mark.parametrize("operation_name, hex_value", valid_names) +def test_get_opcode(operation_name: str, hex_value: int): + # Act + return_value = get_opcode_from_name(operation_name) + # Assert + assert return_value == hex_value + + +def test_get_unknown_opcode(): + operation_name = "definitely unknown" + + # Act + with pytest.raises(RuntimeError): + get_opcode_from_name(operation_name) From c4da7154773235b7640ad0df05677713624af6b8 Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Tue, 23 Oct 2018 00:37:33 +0200 Subject: [PATCH 09/20] Adds test for is_sequence_match and small bugfix --- mythril/disassembler/asm.py | 5 ++++- mythril/disassembler/disassembly.py | 2 +- tests/disassembler/asm.py | 24 ++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/mythril/disassembler/asm.py b/mythril/disassembler/asm.py index 6308b5d8..c2b342f2 100644 --- a/mythril/disassembler/asm.py +++ b/mythril/disassembler/asm.py @@ -65,7 +65,10 @@ def is_sequence_match(pattern: list, instruction_list, index: int) -> bool: :return: Pattern matched """ for index, pattern_slot in enumerate(pattern, start=index): - if not instruction_list[index] in pattern_slot: + try: + if not instruction_list[index]['opcode'] in pattern_slot: + return False + except IndexError: return False return True diff --git a/mythril/disassembler/disassembly.py b/mythril/disassembler/disassembly.py index 7163f241..d9529fe2 100644 --- a/mythril/disassembler/disassembly.py +++ b/mythril/disassembler/disassembly.py @@ -22,7 +22,7 @@ class Disassembly(object): # Parse jump table & resolve function names # Need to take from PUSH1 to PUSH4 because solc seems to remove excess 0s at the beginning for optimizing - jmptable_indices = asm.find_opcode_sequence([("PUSH1", "PUSH2", "PUSH3", "PUSH4"), ("EQ",)], + jmptable_indices = asm.find_op_code_sequence([("PUSH1", "PUSH2", "PUSH3", "PUSH4"), ("EQ",)], self.instruction_list) for i in jmptable_indices: diff --git a/tests/disassembler/asm.py b/tests/disassembler/asm.py index 4eaada3f..4c9a9ee2 100644 --- a/tests/disassembler/asm.py +++ b/tests/disassembler/asm.py @@ -18,3 +18,27 @@ def test_get_unknown_opcode(): # Act with pytest.raises(RuntimeError): get_opcode_from_name(operation_name) + + +sequence_match_test_data = [ + # Normal no match + ((["PUSH1"], ["EQ"]), [{"opcode": "PUSH1"}, {"opcode": "PUSH3"}, {"opcode": "EQ"}], 1, False), + # Normal match + ((["PUSH1"], ["EQ"]), [{"opcode": "PUSH1"}, {"opcode": "PUSH1"}, {"opcode": "EQ"}], 1, True), + # Out of bounds pattern + ((["PUSH1"], ["EQ"]), [{"opcode": "PUSH1"}, {"opcode": "PUSH3"}, {"opcode": "EQ"}], 3, False), + ((["PUSH1"], ["EQ"]), [{"opcode": "PUSH1"}, {"opcode": "PUSH3"}, {"opcode": "EQ"}], 2, False), + # Double option match + ((["PUSH1", "PUSH3"], ["EQ"]), [{"opcode": "PUSH1"}, {"opcode": "PUSH1"}, {"opcode": "EQ"}], 1, True), + ((["PUSH1", "PUSH3"], ["EQ"]), [{"opcode": "PUSH1"}, {"opcode": "PUSH3"}, {"opcode": "EQ"}], 1, True), + # Double option no match + ((["PUSH1", "PUSH3"], ["EQ"]), [{"opcode": "PUSH1"}, {"opcode": "PUSH3"}, {"opcode": "EQ"}], 0, False), +] + + +@pytest.mark.parametrize("pattern, instruction_list, index, expected_result", sequence_match_test_data) +def test_is_sequence_match(pattern, instruction_list, index, expected_result): + # Act + return_value = is_sequence_match(pattern, instruction_list, index) + # Assert + assert return_value == expected_result From c4c9e56c6aba7d17854d4bb984dfe3528f9a64fd Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Tue, 23 Oct 2018 10:42:15 +0200 Subject: [PATCH 10/20] add find sequence test --- tests/disassembler/asm.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/disassembler/asm.py b/tests/disassembler/asm.py index 4c9a9ee2..1bd3c286 100644 --- a/tests/disassembler/asm.py +++ b/tests/disassembler/asm.py @@ -42,3 +42,19 @@ def test_is_sequence_match(pattern, instruction_list, index, expected_result): return_value = is_sequence_match(pattern, instruction_list, index) # Assert assert return_value == expected_result + +find_sequence_match_test_data = [ + # Normal no match + ((["PUSH1"], ["EQ"]), [{"opcode": "PUSH1"}, {"opcode": "PUSH3"}, {"opcode": "EQ"}], []), + # Normal match + ((["PUSH1"], ["EQ"]), [{"opcode": "PUSH1"}, {"opcode": "PUSH1"}, {"opcode": "EQ"}, {"opcode": "PUSH1"}, {"opcode": "EQ"}], [1, 3]), +] + + +@pytest.mark.parametrize("pattern, instruction_list, expected_result", find_sequence_match_test_data) +def test_find_op_code_sequence(pattern, instruction_list, expected_result): + # Act + return_value = list(find_op_code_sequence(pattern, instruction_list)) + + # Assert + assert return_value == expected_result From 1ffa64ed0985da9f1daa7a90667cee5e0bc78624 Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Tue, 23 Oct 2018 10:51:49 +0200 Subject: [PATCH 11/20] Adds basic disassemble test --- mythril/disassembler/asm.py | 6 +++--- tests/disassembler/asm.py | 10 ++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/mythril/disassembler/asm.py b/mythril/disassembler/asm.py index c2b342f2..af76d5df 100644 --- a/mythril/disassembler/asm.py +++ b/mythril/disassembler/asm.py @@ -99,8 +99,8 @@ def disassemble(bytecode: str) -> list: current_instruction.argument = "0x" + argument_bytes.hex() address += int(match.group(1)) - # We use a to_dict() here for compatibility reasons - instruction_list.append(current_instruction.to_dict()) + instruction_list.append(current_instruction) address += 1 - return instruction_list + # We use a to_dict() here for compatibility reasons + return list(map(lambda element: element.to_dict(), instruction_list)) diff --git a/tests/disassembler/asm.py b/tests/disassembler/asm.py index 1bd3c286..960c27a9 100644 --- a/tests/disassembler/asm.py +++ b/tests/disassembler/asm.py @@ -58,3 +58,13 @@ def test_find_op_code_sequence(pattern, instruction_list, expected_result): # Assert assert return_value == expected_result + + +def test_disassemble(): + # Act + instruction_list = disassemble(b"\x00\x16\x06") + + # Assert + assert instruction_list[0]["opcode"] == "STOP" + assert instruction_list[1]["opcode"] == "AND" + assert instruction_list[2]["opcode"] == "MOD" From 9a1e337069da2e50870309b0920d3a38b33821fe Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Tue, 23 Oct 2018 13:04:10 +0200 Subject: [PATCH 12/20] Remove incompatible signature --- mythril/disassembler/asm.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mythril/disassembler/asm.py b/mythril/disassembler/asm.py index af76d5df..506d779c 100644 --- a/mythril/disassembler/asm.py +++ b/mythril/disassembler/asm.py @@ -42,7 +42,7 @@ def get_opcode_from_name(operation_name): raise RuntimeError("Unknown opcode") -def find_op_code_sequence(pattern, instruction_list): +def find_op_code_sequence(pattern: list, instruction_list: list): """ Returns all indices in instruction_list that point to instruction sequences following a pattern :param pattern: The pattern to look for. @@ -55,7 +55,7 @@ def find_op_code_sequence(pattern, instruction_list): yield i -def is_sequence_match(pattern: list, instruction_list, index: int) -> bool: +def is_sequence_match(pattern: list, instruction_list: list, index: int) -> bool: """ Checks if the instructions starting at index follow a pattern :param pattern: List of lists describing a pattern. @@ -95,7 +95,7 @@ def disassemble(bytecode: str) -> list: match = re.search(regex_PUSH, op_code_name) if match: - argument_bytes: bytes = bytecode[address + 1: address + 1 + int(match.group(1))] + argument_bytes = bytecode[address + 1: address + 1 + int(match.group(1))] current_instruction.argument = "0x" + argument_bytes.hex() address += int(match.group(1)) From 52d0bef520d2e04781727bb453ac4e48b9fbbdfd Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Wed, 24 Oct 2018 19:00:47 +0530 Subject: [PATCH 13/20] v0.18.13 --- mythril/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mythril/version.py b/mythril/version.py index 01e7ce46..dbb80403 100644 --- a/mythril/version.py +++ b/mythril/version.py @@ -1,3 +1,3 @@ # This file is suitable for sourcing inside POSIX shell, e.g. bash as # well as for importing into Python -VERSION="v0.18.12" # NOQA +VERSION="v0.18.13" # NOQA From 719413a3900798cf606a2c0c3a28ac3f731a7213 Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Wed, 24 Oct 2018 16:58:42 +0200 Subject: [PATCH 14/20] Add swc standard format output to mythril --- mythril/analysis/modules/delegatecall.py | 57 ++++--- .../modules/dependence_on_predictable_vars.py | 103 ++++++++---- mythril/analysis/modules/deprecated_ops.py | 31 ++-- mythril/analysis/modules/ether_send.py | 75 ++++++--- mythril/analysis/modules/exceptions.py | 48 ++++-- mythril/analysis/modules/external_calls.py | 113 +++++++++---- mythril/analysis/modules/integer.py | 151 ++++++++++++------ mythril/analysis/modules/multiple_sends.py | 37 +++-- mythril/analysis/modules/suicide.py | 34 ++-- .../modules/transaction_order_dependence.py | 36 +++-- mythril/analysis/modules/unchecked_retval.py | 55 ++++--- mythril/analysis/report.py | 84 +++++++--- mythril/interfaces/cli.py | 3 +- 13 files changed, 584 insertions(+), 243 deletions(-) diff --git a/mythril/analysis/modules/delegatecall.py b/mythril/analysis/modules/delegatecall.py index d676f8f2..30b850ef 100644 --- a/mythril/analysis/modules/delegatecall.py +++ b/mythril/analysis/modules/delegatecall.py @@ -5,11 +5,11 @@ from mythril.analysis.report import Issue import logging -''' +""" MODULE DESCRIPTION: Check for invocations of delegatecall(msg.data) in the fallback function. -''' +""" def execute(statespace): @@ -28,7 +28,7 @@ def execute(statespace): continue state = call.state - address = state.get_current_instruction()['address'] + address = state.get_current_instruction()["address"] meminstart = get_variable(state.mstate.stack[-3]) if meminstart.type == VarType.CONCRETE: @@ -41,17 +41,24 @@ def execute(statespace): def _concrete_call(call, state, address, meminstart): - if not re.search(r'calldata.*_0', str(state.mstate.memory[meminstart.val])): + if not re.search(r"calldata.*_0", str(state.mstate.memory[meminstart.val])): return [] - issue = Issue(contract=call.node.contract_name, function=call.node.function_name, address=address, - swc_id=DELEGATECALL_TO_UNTRUSTED_CONTRACT, title="Call data forwarded with delegatecall()", - _type="Informational") - - issue.description = \ - "This contract forwards its call data via DELEGATECALL in its fallback function. " \ - "This means that any function in the called contract can be executed. Note that the callee contract will have " \ + issue = Issue( + contract=call.node.contract_name, + function_name=call.node.function_name, + address=address, + swc_id=DELEGATECALL_TO_UNTRUSTED_CONTRACT, + bytecode=state.environment.code.bytecode, + title="Call data forwarded with delegatecall()", + _type="Informational", + ) + + issue.description = ( + "This contract forwards its call data via DELEGATECALL in its fallback function. " + "This means that any function in the called contract can be executed. Note that the callee contract will have " "access to the storage of the calling contract.\n " + ) target = hex(call.to.val) if call.to.type == VarType.CONCRETE else str(call.to) issue.description += "DELEGATECALL target: {}".format(target) @@ -60,23 +67,35 @@ def _concrete_call(call, state, address, meminstart): def _symbolic_call(call, state, address, statespace): - issue = Issue(contract=call.node.contract_name, function=call.node.function_name, address=address, - swc_id=DELEGATECALL_TO_UNTRUSTED_CONTRACT, title=call.type + " to a user-supplied address") + issue = Issue( + contract=call.node.contract_name, + function_name=call.node.function_name, + address=address, + swc_id=DELEGATECALL_TO_UNTRUSTED_CONTRACT, + bytecode=state.environment.code.bytecode, + title=call.type + " to a user-supplied address", + ) if "calldata" in str(call.to): - issue.description = \ - "This contract delegates execution to a contract address obtained from calldata. " + issue.description = "This contract delegates execution to a contract address obtained from calldata. " else: - m = re.search(r'storage_([a-z0-9_&^]+)', str(call.to)) + m = re.search(r"storage_([a-z0-9_&^]+)", str(call.to)) if m: idx = m.group(1) - func = statespace.find_storage_write(state.environment.active_account.address, idx) + func = statespace.find_storage_write( + state.environment.active_account.address, idx + ) if func: - issue.description = "This contract delegates execution to a contract address in storage slot " + str( - idx) + ". This storage slot can be written to by calling the function `" + func + "`. " + issue.description = ( + "This contract delegates execution to a contract address in storage slot " + + str(idx) + + ". This storage slot can be written to by calling the function `" + + func + + "`. " + ) else: logging.debug("[DELEGATECALL] No storage writes to index " + str(idx)) diff --git a/mythril/analysis/modules/dependence_on_predictable_vars.py b/mythril/analysis/modules/dependence_on_predictable_vars.py index 1e1085ab..d390c047 100644 --- a/mythril/analysis/modules/dependence_on_predictable_vars.py +++ b/mythril/analysis/modules/dependence_on_predictable_vars.py @@ -7,7 +7,7 @@ from mythril.analysis.swc_data import TIMESTAMP_DEPENDENCE, PREDICTABLE_VARS_DEP from mythril.exceptions import UnsatError import logging -''' +""" MODULE DESCRIPTION: Check for CALLs that send >0 Ether as a result of computation based on predictable variables such as @@ -17,7 +17,7 @@ TODO: - block.blockhash(block.number-1) - block.blockhash(some_block_past_256_blocks_from_now)==0 - external source of random numbers (e.g. Oraclize) -''' +""" def execute(statespace): @@ -37,7 +37,7 @@ def execute(statespace): if call.value.type == VarType.CONCRETE and call.value.val == 0: continue - address = call.state.get_current_instruction()['address'] + address = call.state.get_current_instruction()["address"] description = "In the function `" + call.node.function_name + "` " description += "the following predictable state variables are used to determine Ether recipient:\n" @@ -56,10 +56,21 @@ def execute(statespace): for item in found: description += "- block.{}\n".format(item) if solve(call): - swc_type = TIMESTAMP_DEPENDENCE if item == 'timestamp' else PREDICTABLE_VARS_DEPENDENCE - issue = Issue(contract=call.node.contract_name, function=call.node.function_name, address=address, - swc_id=swc_type, title="Dependence on predictable environment variable", - _type="Warning", description=description) + swc_type = ( + TIMESTAMP_DEPENDENCE + if item == "timestamp" + else PREDICTABLE_VARS_DEPENDENCE + ) + issue = Issue( + contract=call.node.contract_name, + function_name=call.node.function_name, + address=address, + swc_id=swc_type, + bytecode=state.environment.code.bytecode, + title="Dependence on predictable environment variable", + _type="Warning", + description=description, + ) issues.append(issue) # Second check: blockhash @@ -68,48 +79,77 @@ def execute(statespace): if "blockhash" in str(constraint): description = "In the function `" + call.node.function_name + "` " if "number" in str(constraint): - m = re.search(r'blockhash\w+(\s-\s(\d+))*', str(constraint)) + m = re.search(r"blockhash\w+(\s-\s(\d+))*", str(constraint)) if m and solve(call): found = m.group(1) if found: # block.blockhash(block.number - N) - description += "predictable expression 'block.blockhash(block.number - " + m.group(2) + \ - ")' is used to determine Ether recipient" + description += ( + "predictable expression 'block.blockhash(block.number - " + + m.group(2) + + ")' is used to determine Ether recipient" + ) if int(m.group(2)) > 255: - description += ", this expression will always be equal to zero." - elif "storage" in str(constraint): # block.blockhash(block.number - storage_0) - description += "predictable expression 'block.blockhash(block.number - " + \ - "some_storage_var)' is used to determine Ether recipient" + description += ( + ", this expression will always be equal to zero." + ) + elif "storage" in str( + constraint + ): # block.blockhash(block.number - storage_0) + description += ( + "predictable expression 'block.blockhash(block.number - " + + "some_storage_var)' is used to determine Ether recipient" + ) else: # block.blockhash(block.number) - description += "predictable expression 'block.blockhash(block.number)'" + \ - " is used to determine Ether recipient" - description += ", this expression will always be equal to zero." - - issue = Issue(contract=call.node.contract_name, function=call.node.function_name, - address=address, title="Dependence on predictable variable", - _type="Warning", description=description, swc_id=PREDICTABLE_VARS_DEPENDENCE) + description += ( + "predictable expression 'block.blockhash(block.number)'" + + " is used to determine Ether recipient" + ) + description += ( + ", this expression will always be equal to zero." + ) + + issue = Issue( + contract=call.node.contract_name, + function_name=call.node.function_name, + address=address, + bytecode=call.state.environment.code.bytecode, + title="Dependence on predictable variable", + _type="Warning", + description=description, + swc_id=PREDICTABLE_VARS_DEPENDENCE, + ) issues.append(issue) break else: - r = re.search(r'storage_([a-z0-9_&^]+)', str(constraint)) + r = re.search(r"storage_([a-z0-9_&^]+)", str(constraint)) if r: # block.blockhash(storage_0) - ''' + """ We actually can do better here by adding a constraint blockhash_block_storage_0 == 0 and checking model satisfiability. When this is done, severity can be raised from 'Informational' to 'Warning'. Checking that storage at given index can be tainted is not necessary, since it usually contains block.number of the 'commit' transaction in commit-reveal workflow. - ''' + """ index = r.group(1) if index and solve(call): - description += 'block.blockhash() is calculated using a value from storage ' \ - 'at index {}'.format(index) - issue = Issue(contract=call.node.contract_name, function=call.node.function_name, - address=address, title="Dependence on predictable variable", - _type="Informational", description=description, swc_id=PREDICTABLE_VARS_DEPENDENCE) + description += ( + "block.blockhash() is calculated using a value from storage " + "at index {}".format(index) + ) + issue = Issue( + contract=call.node.contract_name, + function_name=call.node.function_name, + address=address, + bytecode=state.environment.code.bytecode, + title="Dependence on predictable variable", + _type="Informational", + description=description, + swc_id=PREDICTABLE_VARS_DEPENDENCE, + ) issues.append(issue) break return issues @@ -121,7 +161,10 @@ def solve(call): logging.debug("[DEPENDENCE_ON_PREDICTABLE_VARS] MODEL: " + str(model)) for decl in model.decls(): - logging.debug("[DEPENDENCE_ON_PREDICTABLE_VARS] main model: %s = 0x%x" % (decl.name(), model[decl].as_long())) + logging.debug( + "[DEPENDENCE_ON_PREDICTABLE_VARS] main model: %s = 0x%x" + % (decl.name(), model[decl].as_long()) + ) return True except UnsatError: diff --git a/mythril/analysis/modules/deprecated_ops.py b/mythril/analysis/modules/deprecated_ops.py index 2b187e2d..a5ffea2f 100644 --- a/mythril/analysis/modules/deprecated_ops.py +++ b/mythril/analysis/modules/deprecated_ops.py @@ -3,11 +3,11 @@ from mythril.analysis.swc_data import TX_ORIGIN_USAGE import logging -''' +""" MODULE DESCRIPTION: Check for constraints on tx.origin (i.e., access to some functionality is restricted to a specific origin). -''' +""" def execute(statespace): @@ -23,14 +23,25 @@ def execute(statespace): instruction = state.get_current_instruction() - if instruction['opcode'] == "ORIGIN": - description = "The function `{}` retrieves the transaction origin (tx.origin) using the ORIGIN opcode. " \ - "Use msg.sender instead.\nSee also: " \ - "https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin".format(node.function_name) - - issue = Issue(contract=node.contract_name, function=node.function_name, address=instruction['address'], - title="Use of tx.origin", _type="Warning", swc_id=TX_ORIGIN_USAGE, - description=description) + if instruction["opcode"] == "ORIGIN": + description = ( + "The function `{}` retrieves the transaction origin (tx.origin) using the ORIGIN opcode. " + "Use msg.sender instead.\nSee also: " + "https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin".format( + node.function_name + ) + ) + + issue = Issue( + contract=node.contract_name, + function_name=node.function_name, + address=instruction["address"], + title="Use of tx.origin", + bytecode=state.environment.code.bytecode, + _type="Warning", + swc_id=TX_ORIGIN_USAGE, + description=description, + ) issues.append(issue) return issues diff --git a/mythril/analysis/modules/ether_send.py b/mythril/analysis/modules/ether_send.py index 00aac6a5..71131038 100644 --- a/mythril/analysis/modules/ether_send.py +++ b/mythril/analysis/modules/ether_send.py @@ -8,13 +8,13 @@ import re import logging -''' +""" MODULE DESCRIPTION: Check for CALLs that send >0 Ether to either the transaction sender, or to an address provided as a function argument. If msg.sender is checked against a value in storage, check whether that storage index is tainted (i.e. there's an unconstrained write to that index). -''' +""" def execute(statespace): @@ -26,7 +26,7 @@ def execute(statespace): for call in statespace.calls: state = call.state - address = state.get_current_instruction()['address'] + address = state.get_current_instruction()["address"] if "callvalue" in str(call.value): logging.debug("[ETHER_SEND] Skipping refund function") @@ -41,26 +41,38 @@ def execute(statespace): description = "In the function `" + call.node.function_name + "` " - if re.search(r'caller', str(call.to)): + if re.search(r"caller", str(call.to)): description += "a non-zero amount of Ether is sent to msg.sender.\n" interesting = True - elif re.search(r'calldata', str(call.to)): + elif re.search(r"calldata", str(call.to)): description += "a non-zero amount of Ether is sent to an address taken from function arguments.\n" interesting = True else: - m = re.search(r'storage_([a-z0-9_&^]+)', str(call.to)) + m = re.search(r"storage_([a-z0-9_&^]+)", str(call.to)) if m: idx = m.group(1) - description += "a non-zero amount of Ether is sent to an address taken from storage slot " + str(idx) + ".\n" + description += ( + "a non-zero amount of Ether is sent to an address taken from storage slot " + + str(idx) + + ".\n" + ) - func = statespace.find_storage_write(state.environment.active_account.address, idx) + func = statespace.find_storage_write( + state.environment.active_account.address, idx + ) if func: - description += "There is a check on storage index " + str(idx) + ". This storage slot can be written to by calling the function `" + func + "`.\n" + description += ( + "There is a check on storage index " + + str(idx) + + ". This storage slot can be written to by calling the function `" + + func + + "`.\n" + ) interesting = True else: logging.debug("[ETHER_SEND] No storage writes to index " + str(idx)) @@ -80,31 +92,45 @@ def execute(statespace): index += 1 logging.debug("[ETHER_SEND] Constraint: " + str(constraint)) - m = re.search(r'storage_([a-z0-9_&^]+)', str(constraint)) + m = re.search(r"storage_([a-z0-9_&^]+)", str(constraint)) if m: constrained = True idx = m.group(1) - func = statespace.find_storage_write(state.environment.active_account.address, idx) + func = statespace.find_storage_write( + state.environment.active_account.address, idx + ) if func: - description += "\nThere is a check on storage index " + str(idx) + ". This storage slot can be written to by calling the function `" + func + "`." + description += ( + "\nThere is a check on storage index " + + str(idx) + + ". This storage slot can be written to by calling the function `" + + func + + "`." + ) else: - logging.debug("[ETHER_SEND] No storage writes to index " + str(idx)) + logging.debug( + "[ETHER_SEND] No storage writes to index " + str(idx) + ) can_solve = False break # CALLER may also be constrained to hardcoded address. I.e. 'caller' and some integer - elif re.search(r"caller", str(constraint)) and re.search(r'[0-9]{20}', str(constraint)): + elif re.search(r"caller", str(constraint)) and re.search( + r"[0-9]{20}", str(constraint) + ): constrained = True can_solve = False break if not constrained: - description += "It seems that this function can be called without restrictions." + description += ( + "It seems that this function can be called without restrictions." + ) if can_solve: @@ -112,13 +138,24 @@ def execute(statespace): model = solver.get_model(node.constraints) for decl in model.decls(): - logging.debug("[ETHER_SEND] main model: %s = 0x%x" % (decl.name(), model[decl].as_long())) + logging.debug( + "[ETHER_SEND] main model: %s = 0x%x" + % (decl.name(), model[decl].as_long()) + ) debug = "SOLVER OUTPUT:\n" + solver.pretty_print_model(model) - issue = Issue(contract=call.node.contract_name, function=call.node.function_name, address=address, - title="Ether send", _type="Warning", swc_id=UNPROTECTED_ETHER_WITHDRAWAL, - description=description, debug=debug) + issue = Issue( + contract=call.node.contract_name, + function_name=call.node.function_name, + address=address, + title="Ether send", + _type="Warning", + swc_id=UNPROTECTED_ETHER_WITHDRAWAL, + description=description, + bytecode=state.environment.code.bytecode, + debug=debug, + ) issues.append(issue) except UnsatError: diff --git a/mythril/analysis/modules/exceptions.py b/mythril/analysis/modules/exceptions.py index ac0723e0..d27e1729 100644 --- a/mythril/analysis/modules/exceptions.py +++ b/mythril/analysis/modules/exceptions.py @@ -5,12 +5,12 @@ from mythril.analysis import solver import logging -''' +""" MODULE DESCRIPTION: Checks whether any exception states are reachable. -''' +""" def execute(statespace): @@ -25,25 +25,41 @@ def execute(statespace): for state in node.states: instruction = state.get_current_instruction() - if instruction['opcode'] == "ASSERT_FAIL": + if instruction["opcode"] == "ASSERT_FAIL": try: model = solver.get_model(node.constraints) - address = state.get_current_instruction()['address'] - - description = "A reachable exception (opcode 0xfe) has been detected. " \ - "This can be caused by type errors, division by zero, " \ - "out-of-bounds array access, or assert violations. " - description += "This is acceptable in most situations. " \ - "Note however that `assert()` should only be used to check invariants. " \ - "Use `require()` for regular input checking. " - - debug = "The exception is triggered under the following conditions:\n\n" + address = state.get_current_instruction()["address"] + + description = ( + "A reachable exception (opcode 0xfe) has been detected. " + "This can be caused by type errors, division by zero, " + "out-of-bounds array access, or assert violations. " + ) + description += ( + "This is acceptable in most situations. " + "Note however that `assert()` should only be used to check invariants. " + "Use `require()` for regular input checking. " + ) + + debug = ( + "The exception is triggered under the following conditions:\n\n" + ) debug += solver.pretty_print_model(model) - issues.append(Issue(contract=node.contract_name, function=node.function_name, address=address, - swc_id=ASSERT_VIOLATION, title="Exception state", _type="Informational", - description=description, debug=debug)) + issues.append( + Issue( + contract=node.contract_name, + function_name=node.function_name, + address=address, + swc_id=ASSERT_VIOLATION, + title="Exception state", + _type="Informational", + description=description, + bytecode=state.environment.code.bytecode, + debug=debug, + ) + ) except UnsatError: logging.debug("[EXCEPTIONS] no model found") diff --git a/mythril/analysis/modules/external_calls.py b/mythril/analysis/modules/external_calls.py index 2f9350af..d85fe45a 100644 --- a/mythril/analysis/modules/external_calls.py +++ b/mythril/analysis/modules/external_calls.py @@ -7,11 +7,11 @@ import re import logging -''' +""" MODULE DESCRIPTION: Check for call.value()() to external addresses -''' +""" MAX_SEARCH_DEPTH = 64 @@ -28,8 +28,8 @@ def search_children(statespace, node, start_index=0, depth=0, results=None): if n_states > start_index: for j in range(start_index, n_states): - if node.states[j].get_current_instruction()['opcode'] == 'SSTORE': - results.append(node.states[j].get_current_instruction()['address']) + if node.states[j].get_current_instruction()["opcode"] == "SSTORE": + results.append(node.states[j].get_current_instruction()["address"]) children = [] @@ -39,7 +39,9 @@ def search_children(statespace, node, start_index=0, depth=0, results=None): if len(children): for node in children: - return search_children(statespace, node, depth=depth + 1, results=results) + return search_children( + statespace, node, depth=depth + 1, results=results + ) return results @@ -54,13 +56,20 @@ def execute(statespace): for call in statespace.calls: state = call.state - address = state.get_current_instruction()['address'] + address = state.get_current_instruction()["address"] if call.type == "CALL": - logging.info("[EXTERNAL_CALLS] Call to: %s, value = %s, gas = %s" % (str(call.to), str(call.value), str(call.gas))) + logging.info( + "[EXTERNAL_CALLS] Call to: %s, value = %s, gas = %s" + % (str(call.to), str(call.value), str(call.gas)) + ) - if call.to.type == VarType.SYMBOLIC and (call.gas.type == VarType.CONCRETE and call.gas.val > 2300) or (call.gas.type == VarType.SYMBOLIC and "2300" not in str(call.gas)): + if ( + call.to.type == VarType.SYMBOLIC + and (call.gas.type == VarType.CONCRETE and call.gas.val > 2300) + or (call.gas.type == VarType.SYMBOLIC and "2300" not in str(call.gas)) + ): description = "This contract executes a message call to " @@ -76,59 +85,99 @@ def execute(statespace): user_supplied = True else: - m = re.search(r'storage_([a-z0-9_&^]+)', str(call.to)) + m = re.search(r"storage_([a-z0-9_&^]+)", str(call.to)) if m: idx = m.group(1) - func = statespace.find_storage_write(state.environment.active_account.address, idx) + func = statespace.find_storage_write( + state.environment.active_account.address, idx + ) if func: - description += \ - "an address found at storage slot " + str(idx) + ". " + \ - "This storage slot can be written to by calling the function `" + func + "`. " + description += ( + "an address found at storage slot " + + str(idx) + + ". " + + "This storage slot can be written to by calling the function `" + + func + + "`. " + ) user_supplied = True if user_supplied: - description += "Generally, it is not recommended to call user-supplied addresses using Solidity's call() construct. " \ - "Note that attackers might leverage reentrancy attacks to exploit race conditions or manipulate this contract's state." - - issue = Issue(contract=call.node.contract_name, function=call.node.function_name, - address=address, title="Message call to external contract", _type="Warning", - description=description, swc_id=REENTRANCY) + description += ( + "Generally, it is not recommended to call user-supplied addresses using Solidity's call() construct. " + "Note that attackers might leverage reentrancy attacks to exploit race conditions or manipulate this contract's state." + ) + + issue = Issue( + contract=call.node.contract_name, + function_name=call.node.function_name, + address=address, + title="Message call to external contract", + _type="Warning", + description=description, + bytecode=state.environment.code.bytecode, + swc_id=REENTRANCY, + ) else: description += "to another contract. Make sure that the called contract is trusted and does not execute user-supplied code." - issue = Issue(contract=call.node.contract_name, function=call.node.function_name, address=address, - title="Message call to external contract", _type="Informational", - description=description, swc_id=REENTRANCY) + issue = Issue( + contract=call.node.contract_name, + function_name=call.node.function_name, + address=address, + title="Message call to external contract", + _type="Informational", + description=description, + bytecode=state.environment.code.bytecode, + swc_id=REENTRANCY, + ) issues.append(issue) if address not in calls_visited: calls_visited.append(address) - logging.debug("[EXTERNAL_CALLS] Checking for state changes starting from " + call.node.function_name) + logging.debug( + "[EXTERNAL_CALLS] Checking for state changes starting from " + + call.node.function_name + ) # Check for SSTORE in remaining instructions in current node & nodes down the CFG - state_change_addresses = search_children(statespace, call.node, call.state_index + 1, depth=0, results=[]) + state_change_addresses = search_children( + statespace, call.node, call.state_index + 1, depth=0, results=[] + ) - logging.debug("[EXTERNAL_CALLS] Detected state changes at addresses: " + str(state_change_addresses)) + logging.debug( + "[EXTERNAL_CALLS] Detected state changes at addresses: " + + str(state_change_addresses) + ) if len(state_change_addresses): for address in state_change_addresses: - description = "The contract account state is changed after an external call. " \ - "Consider that the called contract could re-enter the function before this " \ - "state change takes place. This can lead to business logic vulnerabilities." - - issue = Issue(contract=call.node.contract_name, function=call.node.function_name, - address=address, title="State change after external call", _type="Warning", - description=description, swc_id=REENTRANCY) + description = ( + "The contract account state is changed after an external call. " + "Consider that the called contract could re-enter the function before this " + "state change takes place. This can lead to business logic vulnerabilities." + ) + + issue = Issue( + contract=call.node.contract_name, + function_name=call.node.function_name, + address=address, + title="State change after external call", + _type="Warning", + description=description, + bytecode=state.environment.code.bytecode, + swc_id=REENTRANCY, + ) issues.append(issue) return issues diff --git a/mythril/analysis/modules/integer.py b/mythril/analysis/modules/integer.py index 48707c11..3b373926 100644 --- a/mythril/analysis/modules/integer.py +++ b/mythril/analysis/modules/integer.py @@ -9,13 +9,13 @@ import re import copy import logging -''' +""" MODULE DESCRIPTION: Check for integer underflows. For every SUB instruction, check if there's a possible state where op1 > op0. For every ADD, MUL instruction, check if there's a possible state where op1 + op0 > 2^32 - 1 -''' +""" def execute(statespace): @@ -50,7 +50,7 @@ def _check_integer_overflow(statespace, state, node): # Check the instruction instruction = state.get_current_instruction() - if instruction['opcode'] not in ("ADD", "MUL"): + if instruction["opcode"] not in ("ADD", "MUL"): return issues # Formulate overflow constraints @@ -70,7 +70,7 @@ def _check_integer_overflow(statespace, state, node): op1 = BitVecVal(op1, 256) # Formulate expression - if instruction['opcode'] == "ADD": + if instruction["opcode"] == "ADD": expr = op0 + op1 else: expr = op1 * op0 @@ -83,27 +83,43 @@ def _check_integer_overflow(statespace, state, node): logging.debug("[INTEGER_OVERFLOW] no model found") return issues - if not _verify_integer_overflow(statespace, node, expr, state, model, constraint, op0, op1): + if not _verify_integer_overflow( + statespace, node, expr, state, model, constraint, op0, op1 + ): return issues # Build issue - issue = Issue(contract=node.contract_name, function=node.function_name, address=instruction['address'], - swc_id=INTEGER_OVERFLOW_AND_UNDERFLOW, title="Integer Overflow", _type="Warning") - - issue.description = "A possible integer overflow exists in the function `{}`.\n" \ - "The addition or multiplication may result in a value higher than the maximum representable integer.".format( - node.function_name) + issue = Issue( + contract=node.contract_name, + function_name=node.function_name, + address=instruction["address"], + swc_id=INTEGER_OVERFLOW_AND_UNDERFLOW, + bytecode=state.environment.code.bytecode, + title="Integer Overflow", + _type="Warning", + ) + + issue.description = ( + "A possible integer overflow exists in the function `{}`.\n" + "The addition or multiplication may result in a value higher than the maximum representable integer.".format( + node.function_name + ) + ) issue.debug = solver.pretty_print_model(model) issues.append(issue) return issues -def _verify_integer_overflow(statespace, node, expr, state, model, constraint, op0, op1): +def _verify_integer_overflow( + statespace, node, expr, state, model, constraint, op0, op1 +): """ Verifies existence of integer overflow """ # If we get to this point then there has been an integer overflow # Find out if the overflowed value is actually used - interesting_usages = _search_children(statespace, node, expr, constraint=[constraint], index=node.states.index(state)) + interesting_usages = _search_children( + statespace, node, expr, constraint=[constraint], index=node.states.index(state) + ) # Stop if it isn't if len(interesting_usages) == 0: @@ -111,6 +127,7 @@ def _verify_integer_overflow(statespace, node, expr, state, model, constraint, o return _try_constraints(node.constraints, [Not(constraint)]) is not None + def _try_constraints(constraints, new_constraints): """ Tries new constraints @@ -135,7 +152,7 @@ def _check_integer_underflow(statespace, state, node): """ issues = [] instruction = state.get_current_instruction() - if instruction['opcode'] == "SUB": + if instruction["opcode"] == "SUB": stack = state.mstate.stack @@ -150,15 +167,22 @@ def _check_integer_underflow(statespace, state, node): # Pattern 2: (256*If(1 & storage_0 == 0, 1, 0)) - 1, this would underlow if storage_0 = 0 if type(op0) == int and type(op1) == int: return [] - if re.search(r'calldatasize_', str(op0)): + if re.search(r"calldatasize_", str(op0)): return [] - if re.search(r'256\*.*If\(1', str(op0), re.DOTALL) or re.search(r'256\*.*If\(1', str(op1), re.DOTALL): + if re.search(r"256\*.*If\(1", str(op0), re.DOTALL) or re.search( + r"256\*.*If\(1", str(op1), re.DOTALL + ): return [] - if re.search(r'32 \+.*calldata', str(op0), re.DOTALL) or re.search(r'32 \+.*calldata', str(op1), re.DOTALL): + if re.search(r"32 \+.*calldata", str(op0), re.DOTALL) or re.search( + r"32 \+.*calldata", str(op1), re.DOTALL + ): return [] - logging.debug("[INTEGER_UNDERFLOW] Checking SUB {0}, {1} at address {2}".format(str(op0), str(op1), - str(instruction['address']))) + logging.debug( + "[INTEGER_UNDERFLOW] Checking SUB {0}, {1} at address {2}".format( + str(op0), str(op1), str(instruction["address"]) + ) + ) allowed_types = [int, BitVecRef, BitVecNumRef] if type(op0) in allowed_types and type(op1) in allowed_types: @@ -170,17 +194,30 @@ def _check_integer_underflow(statespace, state, node): # If we get to this point then there has been an integer overflow # Find out if the overflowed value is actually used - interesting_usages = _search_children(statespace, node, (op0 - op1), index=node.states.index(state)) + interesting_usages = _search_children( + statespace, node, (op0 - op1), index=node.states.index(state) + ) # Stop if it isn't if len(interesting_usages) == 0: return issues - issue = Issue(contract=node.contract_name, function=node.function_name, address=instruction['address'], - swc_id=INTEGER_OVERFLOW_AND_UNDERFLOW, title="Integer Underflow", _type="Warning") - - issue.description = "A possible integer underflow exists in the function `" + node.function_name + "`.\n" \ - "The subtraction may result in a value < 0." + issue = Issue( + contract=node.contract_name, + function_name=node.function_name, + address=instruction["address"], + swc_id=INTEGER_OVERFLOW_AND_UNDERFLOW, + bytecode=state.environment.code.bytecode, + title="Integer Underflow", + _type="Warning", + ) + + issue.description = ( + "A possible integer underflow exists in the function `" + + node.function_name + + "`.\n" + "The subtraction may result in a value < 0." + ) issue.debug = solver.pretty_print_model(model) issues.append(issue) @@ -192,29 +229,39 @@ def _check_integer_underflow(statespace, state, node): def _check_usage(state, taint_result): """Delegates checks to _check_{instruction_name}()""" - opcode = state.get_current_instruction()['opcode'] + opcode = state.get_current_instruction()["opcode"] - if opcode == 'JUMPI': + if opcode == "JUMPI": if _check_jumpi(state, taint_result): return [state] - elif opcode == 'SSTORE': + elif opcode == "SSTORE": if _check_sstore(state, taint_result): return [state] return [] + def _check_jumpi(state, taint_result): """ Check if conditional jump is dependent on the result of expression""" - assert state.get_current_instruction()['opcode'] == 'JUMPI' + assert state.get_current_instruction()["opcode"] == "JUMPI" return taint_result.check(state, -2) def _check_sstore(state, taint_result): """ Check if store operation is dependent on the result of expression""" - assert state.get_current_instruction()['opcode'] == 'SSTORE' + assert state.get_current_instruction()["opcode"] == "SSTORE" return taint_result.check(state, -2) -def _search_children(statespace, node, expression, taint_result=None, constraint=None, index=0, depth=0, max_depth=64): +def _search_children( + statespace, + node, + expression, + taint_result=None, + constraint=None, + index=0, + depth=0, + max_depth=64, +): """ Checks the statespace for children states, with JUMPI or SSTORE instuctions, for dependency on expression @@ -236,7 +283,9 @@ def _search_children(statespace, node, expression, taint_result=None, constraint state = node.states[index] taint_stack = [False for _ in state.mstate.stack] taint_stack[-1] = True - taint_result = TaintRunner.execute(statespace, node, state, initial_stack=taint_stack) + taint_result = TaintRunner.execute( + statespace, node, state, initial_stack=taint_stack + ) results = [] @@ -247,25 +296,31 @@ def _search_children(statespace, node, expression, taint_result=None, constraint for j in range(index, len(node.states)): current_state = node.states[j] current_instruction = current_state.get_current_instruction() - if current_instruction['opcode'] in ('JUMPI', 'SSTORE'): + if current_instruction["opcode"] in ("JUMPI", "SSTORE"): element = _check_usage(current_state, taint_result) if len(element) < 1: continue if _check_requires(element[0], node, statespace, constraint): - continue + continue results += element # Recursively search children - children = \ - [ - statespace.nodes[edge.node_to] - for edge in statespace.edges - if edge.node_from == node.uid - # and _try_constraints(statespace.nodes[edge.node_to].constraints, constraint) is not None - ] + children = [ + statespace.nodes[edge.node_to] + for edge in statespace.edges + if edge.node_from == node.uid + # and _try_constraints(statespace.nodes[edge.node_to].constraints, constraint) is not None + ] for child in children: - results += _search_children(statespace, child, expression, taint_result, depth=depth + 1, max_depth=max_depth) + results += _search_children( + statespace, + child, + expression, + taint_result, + depth=depth + 1, + max_depth=max_depth, + ) return results @@ -273,16 +328,16 @@ def _search_children(statespace, node, expression, taint_result=None, constraint def _check_requires(state, node, statespace, constraint): """Checks if usage of overflowed statement results in a revert statement""" instruction = state.get_current_instruction() - if instruction['opcode'] is not "JUMPI": + if instruction["opcode"] is not "JUMPI": return False children = [ - statespace.nodes[edge.node_to] - for edge in statespace.edges - if edge.node_from == node.uid - ] + statespace.nodes[edge.node_to] + for edge in statespace.edges + if edge.node_from == node.uid + ] for child in children: - opcodes = [s.get_current_instruction()['opcode'] for s in child.states] + opcodes = [s.get_current_instruction()["opcode"] for s in child.states] if "REVERT" in opcodes or "ASSERT_FAIL" in opcodes: return True # I added the following case, bc of false positives if the max depth is not high enough diff --git a/mythril/analysis/modules/multiple_sends.py b/mythril/analysis/modules/multiple_sends.py index baaea896..a53e20b5 100644 --- a/mythril/analysis/modules/multiple_sends.py +++ b/mythril/analysis/modules/multiple_sends.py @@ -1,6 +1,7 @@ from mythril.analysis.report import Issue from mythril.analysis.swc_data import * from mythril.laser.ethereum.cfg import JumpType + """ MODULE DESCRIPTION: @@ -21,16 +22,25 @@ def execute(statespace): if len(findings) > 0: node = call.node instruction = call.state.get_current_instruction() - issue = Issue(contract=node.contract_name, function=node.function_name, address=instruction['address'], - swc_id=MULTIPLE_SENDS, title="Multiple Calls", _type="Informational") - - issue.description = \ - "Multiple sends exist in one transaction. Try to isolate each external call into its own transaction," \ + issue = Issue( + contract=node.contract_name, + function_name=node.function_name, + address=instruction["address"], + swc_id=MULTIPLE_SENDS, + bytecode=call.state.environment.code.bytecode, + title="Multiple Calls", + _type="Informational", + ) + + issue.description = ( + "Multiple sends exist in one transaction. Try to isolate each external call into its own transaction," " as external calls can fail accidentally or deliberately.\nConsecutive calls: \n" + ) for finding in findings: - issue.description += \ - "Call at address: {}\n".format(finding.state.get_current_instruction()['address']) + issue.description += "Call at address: {}\n".format( + finding.state.get_current_instruction()["address"] + ) issues.append(issue) return issues @@ -44,15 +54,22 @@ def _explore_nodes(call, statespace): def _explore_states(call, statespace): other_calls = list( - filter(lambda other: other.node == call.node and other.state_index > call.state_index, statespace.calls) + filter( + lambda other: other.node == call.node + and other.state_index > call.state_index, + statespace.calls, ) + ) return other_calls def _child_nodes(statespace, node): result = [] - children = [statespace.nodes[edge.node_to] for edge in statespace.edges if edge.node_from == node.uid - and edge.type != JumpType.Transaction] + children = [ + statespace.nodes[edge.node_to] + for edge in statespace.edges + if edge.node_from == node.uid and edge.type != JumpType.Transaction + ] for child in children: result.append(child) diff --git a/mythril/analysis/modules/suicide.py b/mythril/analysis/modules/suicide.py index e2185fe5..0d1b4859 100644 --- a/mythril/analysis/modules/suicide.py +++ b/mythril/analysis/modules/suicide.py @@ -6,12 +6,12 @@ from mythril.exceptions import UnsatError import logging -''' +""" MODULE DESCRIPTION: Check for SUICIDE instructions that either can be reached by anyone, or where msg.sender is checked against a tainted storage index (i.e. there's a write to that index is unconstrained by msg.sender). -''' +""" def execute(state_space): @@ -33,13 +33,15 @@ def _analyze_state(state, node): issues = [] instruction = state.get_current_instruction() - if instruction['opcode'] != "SUICIDE": + if instruction["opcode"] != "SUICIDE": return [] to = state.mstate.stack[-1] logging.debug("[UNCHECKED_SUICIDE] suicide in function " + node.function_name) - description = "The function `" + node.function_name + "` executes the SUICIDE instruction. " + description = ( + "The function `" + node.function_name + "` executes the SUICIDE instruction. " + ) if "caller" in str(to): description += "The remaining Ether is sent to the caller's address.\n" @@ -56,19 +58,31 @@ def _analyze_state(state, node): if len(state.world_state.transaction_sequence) > 1: creator = state.world_state.transaction_sequence[0].caller for transaction in state.world_state.transaction_sequence[1:]: - not_creator_constraints.append(Not(Extract(159, 0, transaction.caller) == Extract(159, 0, creator))) - not_creator_constraints.append(Not(Extract(159, 0, transaction.caller) == 0)) + not_creator_constraints.append( + Not(Extract(159, 0, transaction.caller) == Extract(159, 0, creator)) + ) + not_creator_constraints.append( + Not(Extract(159, 0, transaction.caller) == 0) + ) try: model = solver.get_model(node.constraints + not_creator_constraints) debug = "SOLVER OUTPUT:\n" + solver.pretty_print_model(model) - issue = Issue(contract=node.contract_name, function=node.function_name, address=instruction['address'], - swc_id=UNPROTECTED_SELFDESTRUCT, title="Unchecked SUICIDE", _type="Warning", - description=description, debug=debug) + issue = Issue( + contract=node.contract_name, + function_name=node.function_name, + address=instruction["address"], + swc_id=UNPROTECTED_SELFDESTRUCT, + bytecode=state.environment.code.bytecode, + title="Unchecked SUICIDE", + _type="Warning", + description=description, + debug=debug, + ) issues.append(issue) except UnsatError: - logging.debug("[UNCHECKED_SUICIDE] no model found") + logging.debug("[UNCHECKED_SUICIDE] no model found") return issues diff --git a/mythril/analysis/modules/transaction_order_dependence.py b/mythril/analysis/modules/transaction_order_dependence.py index f6621293..bd6a36f8 100644 --- a/mythril/analysis/modules/transaction_order_dependence.py +++ b/mythril/analysis/modules/transaction_order_dependence.py @@ -7,12 +7,12 @@ from mythril.analysis.report import Issue from mythril.analysis.swc_data import TX_ORDER_DEPENDENCE from mythril.exceptions import UnsatError -''' +""" MODULE DESCRIPTION: This module finds the existance of transaction order dependence vulnerabilities. The following webpage contains an extensive description of the vulnerability: https://consensys.github.io/smart-contract-best-practices/known_attacks/#transaction-ordering-dependence-tod-front-running -''' +""" def execute(statespace): @@ -24,19 +24,30 @@ def execute(statespace): for call in statespace.calls: # Do analysis interesting_storages = list(_get_influencing_storages(call)) - changing_sstores = list(_get_influencing_sstores(statespace, interesting_storages)) + changing_sstores = list( + _get_influencing_sstores(statespace, interesting_storages) + ) # Build issue if necessary if len(changing_sstores) > 0: node = call.node instruction = call.state.get_current_instruction() - issue = Issue(contract=node.contract_name, function=node.function_name, address=instruction['address'], - title="Transaction order dependence", swc_id=TX_ORDER_DEPENDENCE, _type="Warning") - - issue.description = \ - "A possible transaction order dependence vulnerability exists in function {}. The value or " \ - "direction of the call statement is determined from a tainted storage location"\ - .format(node.function_name) + issue = Issue( + contract=node.contract_name, + function_name=node.function_name, + address=instruction["address"], + title="Transaction order dependence", + bytecode=call.state.environment.code.bytecode, + swc_id=TX_ORDER_DEPENDENCE, + _type="Warning", + ) + + issue.description = ( + "A possible transaction order dependence vulnerability exists in function {}. The value or " + "direction of the call statement is determined from a tainted storage location".format( + node.function_name + ) + ) issues.append(issue) return issues @@ -65,7 +76,7 @@ def _get_storage_variable(storage, state): :param state: state to retrieve the variable from :return: z3 object representing storage """ - index = int(re.search('[0-9]+', storage).group()) + index = int(re.search("[0-9]+", storage).group()) try: return state.environment.active_account.storage[index] except KeyError: @@ -85,6 +96,7 @@ def _can_change(constraints, variable): except AttributeError: return False + def _get_influencing_storages(call): """ Examines a Call object and returns an iterator of all storages that influence the call value or direction""" state = call.state @@ -108,7 +120,7 @@ def _get_influencing_storages(call): def _get_influencing_sstores(statespace, interesting_storages): """ Gets sstore (state, node) tuples that write to interesting_storages""" - for sstore_state, node in _get_states_with_opcode(statespace, 'SSTORE'): + for sstore_state, node in _get_states_with_opcode(statespace, "SSTORE"): index, value = sstore_state.mstate.stack[-1], sstore_state.mstate.stack[-2] try: index = util.get_concrete_int(index) diff --git a/mythril/analysis/modules/unchecked_retval.py b/mythril/analysis/modules/unchecked_retval.py index 5ee2b327..4d912fef 100644 --- a/mythril/analysis/modules/unchecked_retval.py +++ b/mythril/analysis/modules/unchecked_retval.py @@ -6,7 +6,7 @@ import logging import re -''' +""" MODULE DESCRIPTION: Test whether CALL return value is checked. @@ -22,7 +22,7 @@ For low-level-calls this check is omitted. E.g.: c.call.value(0)(bytes4(sha3("ping(uint256)")),1); -''' +""" def execute(statespace): @@ -43,19 +43,27 @@ def execute(statespace): instr = state.get_current_instruction() - if instr['opcode'] == 'ISZERO' and re.search(r'retval', str(state.mstate.stack[-1])): + if instr["opcode"] == "ISZERO" and re.search( + r"retval", str(state.mstate.stack[-1]) + ): retval_checked = True break if not retval_checked: - address = state.get_current_instruction()['address'] - issue = Issue(contract=node.contract_name, function=node.function_name, address=address, - title="Unchecked CALL return value", swc_id=UNCHECKED_RET_VAL) - - issue.description = \ - "The return value of an external call is not checked. " \ + address = state.get_current_instruction()["address"] + issue = Issue( + contract=node.contract_name, + function_name=node.function_name, + address=address, + title="Unchecked CALL return value", + swc_id=UNCHECKED_RET_VAL, + ) + + issue.description = ( + "The return value of an external call is not checked. " "Note that execution continue even if the called contract throws." + ) issues.append(issue) @@ -63,12 +71,14 @@ def execute(statespace): n_states = len(node.states) - for idx in range(0, n_states - 1): # Ignore CALLs at last position in a node + for idx in range( + 0, n_states - 1 + ): # Ignore CALLs at last position in a node state = node.states[idx] instr = state.get_current_instruction() - if instr['opcode'] == 'CALL': + if instr["opcode"] == "CALL": retval_checked = False @@ -78,7 +88,9 @@ def execute(statespace): _state = node.states[_idx] _instr = _state.get_current_instruction() - if _instr['opcode'] == 'ISZERO' and re.search(r'retval', str(_state .mstate.stack[-1])): + if _instr["opcode"] == "ISZERO" and re.search( + r"retval", str(_state.mstate.stack[-1]) + ): retval_checked = True break @@ -87,13 +99,20 @@ def execute(statespace): if not retval_checked: - address = instr['address'] - issue = Issue(contract=node.contract_name, function=node.function_name, - address=address, title="Unchecked CALL return value", swc_id=UNCHECKED_RET_VAL) - - issue.description = \ - "The return value of an external call is not checked. " \ + address = instr["address"] + issue = Issue( + contract=node.contract_name, + function_name=node.function_name, + bytecode=state.environment.code.bytecode, + address=address, + title="Unchecked CALL return value", + swc_id=UNCHECKED_RET_VAL, + ) + + issue.description = ( + "The return value of an external call is not checked. " "Note that execution continue even if the called contract throws." + ) issues.append(issue) diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index a6cfd59d..e4443cfa 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -1,16 +1,27 @@ -import hashlib +import logging import json import operator from jinja2 import PackageLoader, Environment +import hashlib class Issue: - - def __init__(self, contract, function, address, swc_id, title, _type="Informational", description="", debug=""): + def __init__( + self, + contract, + function_name, + address, + swc_id, + title, + bytecode, + _type="Informational", + description="", + debug="", + ): self.title = title self.contract = contract - self.function = function + self.function = function_name self.address = address self.description = description self.type = _type @@ -20,32 +31,51 @@ class Issue: self.code = None self.lineno = None + try: + s = hashlib.sha3_256() + s.update(bytes.fromhex(bytecode)) + self.bytecode_hash = "0x" + s.hexdigest() + except ValueError: + logging.debug("Unable to change the bytecode to bytes. Bytecode: {}".format(bytecode)) + self.bytecode_hash = "" @property def as_dict(self): - issue = {'title': self.title, 'swc_id': self.swc_id, 'contract': self.contract, 'description': self.description, - 'function': self.function, 'type': self.type, 'address': self.address, 'debug': self.debug} + issue = { + "title": self.title, + "swc_id": self.swc_id, + "contract": self.contract, + "description": self.description, + "function": self.function, + "type": self.type, + "address": self.address, + "debug": self.debug, + } if self.filename and self.lineno: - issue['filename'] = self.filename - issue['lineno'] = self.lineno + issue["filename"] = self.filename + issue["lineno"] = self.lineno if self.code: - issue['code'] = self.code + issue["code"] = self.code return issue def add_code_info(self, contract): if self.address: - codeinfo = contract.get_source_info(self.address, constructor=(self.function == 'constructor')) + codeinfo = contract.get_source_info( + self.address, constructor=(self.function == "constructor") + ) self.filename = codeinfo.filename self.code = codeinfo.code self.lineno = codeinfo.lineno class Report: - environment = Environment(loader=PackageLoader('mythril.analysis'), trim_blocks=True) + environment = Environment( + loader=PackageLoader("mythril.analysis"), trim_blocks=True + ) def __init__(self, verbose=False): self.issues = {} @@ -54,26 +84,44 @@ class Report: def sorted_issues(self): issue_list = [issue.as_dict for key, issue in self.issues.items()] - return sorted(issue_list, key=operator.itemgetter('address', 'title')) + return sorted(issue_list, key=operator.itemgetter("address", "title")) def append_issue(self, issue): m = hashlib.md5() - m.update((issue.contract + str(issue.address) + issue.title).encode('utf-8')) + m.update((issue.contract + str(issue.address) + issue.title).encode("utf-8")) self.issues[m.digest()] = issue def as_text(self): name = self._file_name() - template = Report.environment.get_template('report_as_text.jinja2') - return template.render(filename=name, issues=self.sorted_issues(), verbose=self.verbose) + template = Report.environment.get_template("report_as_text.jinja2") + return template.render( + filename=name, issues=self.sorted_issues(), verbose=self.verbose + ) def as_json(self): - result = {'success': True, 'error': None, 'issues': self.sorted_issues()} + result = {"success": True, "error": None, "issues": self.sorted_issues()} + return json.dumps(result, sort_keys=True) + + def as_swc_standard_format(self): + """ Format defined for integration and correlation""" + result = { + "issues": [ + { + "swc-id": "SWC-{}".format(issue.swc_id), + "bytecodeOffset": issue.address, + "codeHash": issue.bytecode_hash, + } + for issue in self.issues.values() + ] + } return json.dumps(result, sort_keys=True) def as_markdown(self): filename = self._file_name() - template = Report.environment.get_template('report_as_markdown.jinja2') - return template.render(filename=filename, issues=self.sorted_issues(), verbose=self.verbose) + template = Report.environment.get_template("report_as_markdown.jinja2") + return template.render( + filename=filename, issues=self.sorted_issues(), verbose=self.verbose + ) def _file_name(self): if len(self.issues.values()) > 0: diff --git a/mythril/interfaces/cli.py b/mythril/interfaces/cli.py index ea55e29c..96a1f441 100644 --- a/mythril/interfaces/cli.py +++ b/mythril/interfaces/cli.py @@ -50,7 +50,7 @@ def main(): inputs.add_argument('-l', '--dynld', action='store_true', help='auto-load dependencies from the blockchain') outputs = parser.add_argument_group('output formats') - outputs.add_argument('-o', '--outform', choices=['text', 'markdown', 'json'], default='text', + outputs.add_argument('-o', '--outform', choices=['text', 'markdown', 'json', 'swc-standard'], default='text', help='report output format', metavar='') outputs.add_argument('--verbose-report', action='store_true', help='Include debugging information in report') @@ -233,6 +233,7 @@ def main(): create_timeout=args.create_timeout, max_transaction_count=args.max_transaction_count) outputs = { + 'swc-standard': report.as_swc_standard_format(), 'json': report.as_json(), 'text': report.as_text(), 'markdown': report.as_markdown() From b67117c8b4dbae017e20c71c5c8acbcee296a6c9 Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Wed, 24 Oct 2018 17:07:35 +0200 Subject: [PATCH 15/20] add more type hints --- mythril/disassembler/asm.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mythril/disassembler/asm.py b/mythril/disassembler/asm.py index c2b342f2..c54746d8 100644 --- a/mythril/disassembler/asm.py +++ b/mythril/disassembler/asm.py @@ -16,14 +16,14 @@ class EvmInstruction: self.op_code = op_code self.argument = argument - def to_dict(self): + def to_dict(self) -> dict: result = {"address": self.address, "opcode": self.op_code} if self.argument: result["argument"] = self.argument return result -def instruction_list_to_easm(instruction_list): +def instruction_list_to_easm(instruction_list: dict) -> str: result = "" for instruction in instruction_list: @@ -35,14 +35,14 @@ def instruction_list_to_easm(instruction_list): return result -def get_opcode_from_name(operation_name): +def get_opcode_from_name(operation_name: str) -> int: for op_code, value in opcodes.items(): if operation_name == value[0]: return op_code raise RuntimeError("Unknown opcode") -def find_op_code_sequence(pattern, instruction_list): +def find_op_code_sequence(pattern: list, instruction_list: list) -> Generator: """ Returns all indices in instruction_list that point to instruction sequences following a pattern :param pattern: The pattern to look for. From 5f9494b979b56dc3e28333508e546321cc224cb4 Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Wed, 24 Oct 2018 17:16:19 +0200 Subject: [PATCH 16/20] fix missing environments --- tests/analysis/test_delegatecall.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/tests/analysis/test_delegatecall.py b/tests/analysis/test_delegatecall.py index 9e88c1fd..324792e1 100644 --- a/tests/analysis/test_delegatecall.py +++ b/tests/analysis/test_delegatecall.py @@ -1,6 +1,7 @@ from mythril.analysis.modules.delegatecall import execute, _concrete_call, _symbolic_call from mythril.analysis.ops import Call, Variable, VarType from mythril.analysis.symbolic import SymExecWrapper +from mythril.disassembler.disassembly import Disassembly from mythril.laser.ethereum.cfg import Node from mythril.laser.ethereum.state import GlobalState, Environment, Account import pytest @@ -11,8 +12,11 @@ import pytest_mock def test_concrete_call(): # arrange address = "0x10" + active_account = Account(address) + active_account.code = Disassembly("00") + environment = Environment(active_account, None, None, None, None, None) - state = GlobalState(None, None, None) + state = GlobalState(None, environment, None) state.mstate.memory = ["placeholder", "calldata_bling_0"] node = Node("example") @@ -43,7 +47,10 @@ def test_concrete_call_symbolic_to(): # arrange address = "0x10" - state = GlobalState(None, None, None) + active_account = Account(address) + active_account.code = Disassembly("00") + environment = Environment(active_account, None, None, None, None, None) + state = GlobalState(None, environment, None) state.mstate.memory = ["placeholder", "calldata_bling_0"] node = Node("example") @@ -88,6 +95,7 @@ def test_symbolic_call_storage_to(mocker): address = "0x10" active_account = Account(address) + active_account.code = Disassembly("00") environment = Environment(active_account, None, None, None, None, None) state = GlobalState(None, environment, None) state.mstate.memory = ["placeholder", "calldata_bling_0"] @@ -127,7 +135,10 @@ def test_symbolic_call_calldata_to(mocker): # arrange address = "0x10" - state = GlobalState(None, None, None) + active_account = Account(address) + active_account.code = Disassembly("00") + environment = Environment(active_account, None, None, None, None, None) + state = GlobalState(None, environment, None) state.mstate.memory = ["placeholder", "calldata_bling_0"] @@ -172,6 +183,8 @@ def test_delegate_call(sym_mock, concrete_mock, curr_instruction): curr_instruction.return_value = {'address': '0x10'} active_account = Account('0x10') + active_account.code = Disassembly("00") + environment = Environment(active_account, None, None, None, None, None) state = GlobalState(None, environment, Node) state.mstate.memory = ["placeholder", "calldata_bling_0"] From 6f69858fbeb3d3c4b20467382ade7d6c83ce1443 Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Wed, 24 Oct 2018 17:17:39 +0200 Subject: [PATCH 17/20] fix missing argument --- mythril/analysis/modules/unchecked_retval.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mythril/analysis/modules/unchecked_retval.py b/mythril/analysis/modules/unchecked_retval.py index 4d912fef..3cbd800a 100644 --- a/mythril/analysis/modules/unchecked_retval.py +++ b/mythril/analysis/modules/unchecked_retval.py @@ -56,6 +56,7 @@ def execute(statespace): contract=node.contract_name, function_name=node.function_name, address=address, + bytecode=state.environment.code.bytecode, title="Unchecked CALL return value", swc_id=UNCHECKED_RET_VAL, ) From 1c396d93ad4e43a170038c88976cfd8b7221e169 Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Wed, 24 Oct 2018 17:42:17 +0200 Subject: [PATCH 18/20] Make statement more readable --- mythril/disassembler/asm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mythril/disassembler/asm.py b/mythril/disassembler/asm.py index f8eba81a..762d1251 100644 --- a/mythril/disassembler/asm.py +++ b/mythril/disassembler/asm.py @@ -103,4 +103,4 @@ def disassemble(bytecode: str) -> list: address += 1 # We use a to_dict() here for compatibility reasons - return list(map(lambda element: element.to_dict(), instruction_list)) + return [element.to_dict() for element in instruction_list] From 2774fc65a26fdeecaf79a373510647bfec7f009c Mon Sep 17 00:00:00 2001 From: Joran Honig Date: Wed, 24 Oct 2018 21:27:38 +0200 Subject: [PATCH 19/20] update hashing technique used --- mythril/analysis/report.py | 8 ++++---- solidity_examples/rubixi.sol | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mythril/analysis/report.py b/mythril/analysis/report.py index e4443cfa..5d79bcf9 100644 --- a/mythril/analysis/report.py +++ b/mythril/analysis/report.py @@ -2,9 +2,9 @@ import logging import json import operator from jinja2 import PackageLoader, Environment +import sha3 import hashlib - class Issue: def __init__( self, @@ -32,9 +32,9 @@ class Issue: self.lineno = None try: - s = hashlib.sha3_256() - s.update(bytes.fromhex(bytecode)) - self.bytecode_hash = "0x" + s.hexdigest() + keccak = sha3.keccak_256() + keccak.update(bytes.fromhex(bytecode)) + self.bytecode_hash = "0x" + keccak.hexdigest() except ValueError: logging.debug("Unable to change the bytecode to bytes. Bytecode: {}".format(bytecode)) self.bytecode_hash = "" diff --git a/solidity_examples/rubixi.sol b/solidity_examples/rubixi.sol index 91fda1b6..301e9196 100644 --- a/solidity_examples/rubixi.sol +++ b/solidity_examples/rubixi.sol @@ -26,7 +26,7 @@ contract Rubixi { Participant[] private participants; //Fallback function - function() { + function() payable { init(); } From dc09c2e94f50f7c4cea437bb78433d690434f241 Mon Sep 17 00:00:00 2001 From: Nikhil Parasaram Date: Sat, 27 Oct 2018 13:19:15 +0530 Subject: [PATCH 20/20] Change the issue description --- mythril/analysis/modules/ether_send.py | 8 +- mythril/analysis/modules/exceptions.py | 3 +- mythril/analysis/modules/integer.py | 12 +- mythril/analysis/modules/multiple_sends.py | 2 +- mythril/analysis/modules/suicide.py | 5 +- .../modules/transaction_order_dependence.py | 6 +- tests/cmd_line_test.py | 3 +- .../outputs_expected/calls.sol.o.graph.html | 10 +- .../outputs_expected/calls.sol.o.json | 2 +- .../outputs_expected/calls.sol.o.markdown | 2 +- .../outputs_expected/calls.sol.o.text | 2 +- .../environments.sol.o.graph.html | 10 +- .../outputs_expected/environments.sol.o.json | 2 +- .../environments.sol.o.markdown | 9 +- .../outputs_expected/environments.sol.o.text | 12 +- .../ether_send.sol.o.graph.html | 10 +- .../outputs_expected/ether_send.sol.o.json | 2 +- .../ether_send.sol.o.markdown | 5 +- .../outputs_expected/ether_send.sol.o.text | 6 +- .../exceptions.sol.o.graph.html | 10 +- .../outputs_expected/exceptions.sol.o.json | 2 +- .../exceptions.sol.o.markdown | 8 +- .../outputs_expected/exceptions.sol.o.text | 8 +- .../kinds_of_calls.sol.o.graph.html | 10 +- .../metacoin.sol.o.graph.html | 10 +- .../multi_contracts.sol.o.graph.html | 10 +- .../multi_contracts.sol.o.json | 2 +- .../multi_contracts.sol.o.markdown | 2 +- .../multi_contracts.sol.o.text | 2 +- .../nonascii.sol.o.graph.html | 10 +- .../outputs_expected/origin.sol.o.graph.html | 10 +- .../outputs_expected/origin.sol.o.json | 2 +- .../outputs_current/calls.sol.o.easm | 400 ++++++++++++++++ .../outputs_current/calls.sol.o.graph.html | 62 +++ .../outputs_current/calls.sol.o.json | 1 + .../outputs_current/calls.sol.o.markdown | 111 +++++ .../outputs_current/calls.sol.o.text | 90 ++++ .../outputs_current/environments.sol.o.easm | 259 +++++++++++ .../environments.sol.o.graph.html | 62 +++ .../outputs_current/environments.sol.o.json | 1 + .../environments.sol.o.markdown | 34 ++ .../outputs_current/environments.sol.o.text | 30 ++ .../outputs_current/ether_send.sol.o.easm | 420 +++++++++++++++++ .../ether_send.sol.o.graph.html | 62 +++ .../outputs_current/ether_send.sol.o.json | 1 + .../outputs_current/ether_send.sol.o.markdown | 25 + .../outputs_current/ether_send.sol.o.text | 21 + .../outputs_current/exceptions.sol.o.easm | 392 ++++++++++++++++ .../exceptions.sol.o.graph.html | 62 +++ .../outputs_current/exceptions.sol.o.json | 1 + .../outputs_current/exceptions.sol.o.markdown | 45 ++ .../outputs_current/exceptions.sol.o.text | 36 ++ .../outputs_current/kinds_of_calls.sol.o.easm | 435 ++++++++++++++++++ .../kinds_of_calls.sol.o.graph.html | 62 +++ .../outputs_current/kinds_of_calls.sol.o.json | 1 + .../kinds_of_calls.sol.o.markdown | 45 ++ .../outputs_current/kinds_of_calls.sol.o.text | 36 ++ .../outputs_current/metacoin.sol.o.easm | 253 ++++++++++ .../outputs_current/metacoin.sol.o.graph.html | 62 +++ .../outputs_current/metacoin.sol.o.json | 1 + .../outputs_current/metacoin.sol.o.markdown | 3 + .../outputs_current/metacoin.sol.o.text | 1 + .../multi_contracts.sol.o.easm | 77 ++++ .../multi_contracts.sol.o.graph.html | 62 +++ .../multi_contracts.sol.o.json | 1 + .../multi_contracts.sol.o.markdown | 13 + .../multi_contracts.sol.o.text | 10 + .../outputs_current/nonascii.sol.o.easm | 167 +++++++ .../outputs_current/nonascii.sol.o.graph.html | 62 +++ .../outputs_current/nonascii.sol.o.json | 1 + .../outputs_current/nonascii.sol.o.markdown | 3 + .../outputs_current/nonascii.sol.o.text | 1 + .../outputs_current/origin.sol.o.easm | 168 +++++++ .../outputs_current/origin.sol.o.graph.html | 62 +++ .../outputs_current/origin.sol.o.json | 1 + .../outputs_current/origin.sol.o.markdown | 13 + .../outputs_current/origin.sol.o.text | 10 + .../outputs_current/overflow.sol.o.easm | 388 ++++++++++++++++ .../outputs_current/overflow.sol.o.graph.html | 62 +++ .../outputs_current/overflow.sol.o.json | 1 + .../outputs_current/overflow.sol.o.markdown | 34 ++ .../outputs_current/overflow.sol.o.text | 30 ++ .../outputs_current/returnvalue.sol.o.easm | 129 ++++++ .../returnvalue.sol.o.graph.html | 62 +++ .../outputs_current/returnvalue.sol.o.json | 1 + .../returnvalue.sol.o.markdown | 34 ++ .../outputs_current/returnvalue.sol.o.text | 27 ++ .../outputs_current/suicide.sol.o.easm | 58 +++ .../outputs_current/suicide.sol.o.graph.html | 62 +++ .../outputs_current/suicide.sol.o.json | 1 + .../outputs_current/suicide.sol.o.markdown | 12 + .../outputs_current/suicide.sol.o.text | 10 + .../outputs_current/underflow.sol.o.easm | 365 +++++++++++++++ .../underflow.sol.o.graph.html | 62 +++ .../outputs_current/underflow.sol.o.json | 1 + .../outputs_current/underflow.sol.o.markdown | 34 ++ .../outputs_current/underflow.sol.o.text | 30 ++ .../overflow.sol.o.graph.html | 10 +- .../outputs_expected/overflow.sol.o.json | 2 +- .../outputs_expected/overflow.sol.o.markdown | 9 +- .../outputs_expected/overflow.sol.o.text | 12 +- .../returnvalue.sol.o.graph.html | 10 +- .../outputs_expected/suicide.sol.o.graph.html | 10 +- .../outputs_expected/suicide.sol.o.json | 2 +- .../outputs_expected/suicide.sol.o.markdown | 2 +- .../outputs_expected/suicide.sol.o.text | 2 +- .../underflow.sol.o.graph.html | 10 +- .../outputs_expected/underflow.sol.o.json | 2 +- .../outputs_expected/underflow.sol.o.markdown | 9 +- .../outputs_expected/underflow.sol.o.text | 12 +- 110 files changed, 5228 insertions(+), 129 deletions(-) create mode 100644 tests/testdata/outputs_expected/outputs_current/calls.sol.o.easm create mode 100644 tests/testdata/outputs_expected/outputs_current/calls.sol.o.graph.html create mode 100644 tests/testdata/outputs_expected/outputs_current/calls.sol.o.json create mode 100644 tests/testdata/outputs_expected/outputs_current/calls.sol.o.markdown create mode 100644 tests/testdata/outputs_expected/outputs_current/calls.sol.o.text create mode 100644 tests/testdata/outputs_expected/outputs_current/environments.sol.o.easm create mode 100644 tests/testdata/outputs_expected/outputs_current/environments.sol.o.graph.html create mode 100644 tests/testdata/outputs_expected/outputs_current/environments.sol.o.json create mode 100644 tests/testdata/outputs_expected/outputs_current/environments.sol.o.markdown create mode 100644 tests/testdata/outputs_expected/outputs_current/environments.sol.o.text create mode 100644 tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.easm create mode 100644 tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.graph.html create mode 100644 tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.json create mode 100644 tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.markdown create mode 100644 tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.text create mode 100644 tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.easm create mode 100644 tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.graph.html create mode 100644 tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.json create mode 100644 tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.markdown create mode 100644 tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.text create mode 100644 tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.easm create mode 100644 tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.graph.html create mode 100644 tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.json create mode 100644 tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.markdown create mode 100644 tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.text create mode 100644 tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.easm create mode 100644 tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.graph.html create mode 100644 tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.json create mode 100644 tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.markdown create mode 100644 tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.text create mode 100644 tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.easm create mode 100644 tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.graph.html create mode 100644 tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.json create mode 100644 tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.markdown create mode 100644 tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.text create mode 100644 tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.easm create mode 100644 tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.graph.html create mode 100644 tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.json create mode 100644 tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.markdown create mode 100644 tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.text create mode 100644 tests/testdata/outputs_expected/outputs_current/origin.sol.o.easm create mode 100644 tests/testdata/outputs_expected/outputs_current/origin.sol.o.graph.html create mode 100644 tests/testdata/outputs_expected/outputs_current/origin.sol.o.json create mode 100644 tests/testdata/outputs_expected/outputs_current/origin.sol.o.markdown create mode 100644 tests/testdata/outputs_expected/outputs_current/origin.sol.o.text create mode 100644 tests/testdata/outputs_expected/outputs_current/overflow.sol.o.easm create mode 100644 tests/testdata/outputs_expected/outputs_current/overflow.sol.o.graph.html create mode 100644 tests/testdata/outputs_expected/outputs_current/overflow.sol.o.json create mode 100644 tests/testdata/outputs_expected/outputs_current/overflow.sol.o.markdown create mode 100644 tests/testdata/outputs_expected/outputs_current/overflow.sol.o.text create mode 100644 tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.easm create mode 100644 tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.graph.html create mode 100644 tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.json create mode 100644 tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.markdown create mode 100644 tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.text create mode 100644 tests/testdata/outputs_expected/outputs_current/suicide.sol.o.easm create mode 100644 tests/testdata/outputs_expected/outputs_current/suicide.sol.o.graph.html create mode 100644 tests/testdata/outputs_expected/outputs_current/suicide.sol.o.json create mode 100644 tests/testdata/outputs_expected/outputs_current/suicide.sol.o.markdown create mode 100644 tests/testdata/outputs_expected/outputs_current/suicide.sol.o.text create mode 100644 tests/testdata/outputs_expected/outputs_current/underflow.sol.o.easm create mode 100644 tests/testdata/outputs_expected/outputs_current/underflow.sol.o.graph.html create mode 100644 tests/testdata/outputs_expected/outputs_current/underflow.sol.o.json create mode 100644 tests/testdata/outputs_expected/outputs_current/underflow.sol.o.markdown create mode 100644 tests/testdata/outputs_expected/outputs_current/underflow.sol.o.text diff --git a/mythril/analysis/modules/ether_send.py b/mythril/analysis/modules/ether_send.py index 71131038..76e96a46 100644 --- a/mythril/analysis/modules/ether_send.py +++ b/mythril/analysis/modules/ether_send.py @@ -39,14 +39,14 @@ def execute(statespace): interesting = False - description = "In the function `" + call.node.function_name + "` " + description = "A non-zero amount of Ether is sent to a user-supplied address." if re.search(r"caller", str(call.to)): - description += "a non-zero amount of Ether is sent to msg.sender.\n" + description += " The target address is msg.sender.\n" interesting = True elif re.search(r"calldata", str(call.to)): - description += "a non-zero amount of Ether is sent to an address taken from function arguments.\n" + description += " The target address is taken from function arguments.\n" interesting = True else: @@ -56,7 +56,7 @@ def execute(statespace): idx = m.group(1) description += ( - "a non-zero amount of Ether is sent to an address taken from storage slot " + " The target address is taken from storage slot " + str(idx) + ".\n" ) diff --git a/mythril/analysis/modules/exceptions.py b/mythril/analysis/modules/exceptions.py index d27e1729..f1702abf 100644 --- a/mythril/analysis/modules/exceptions.py +++ b/mythril/analysis/modules/exceptions.py @@ -36,8 +36,7 @@ def execute(statespace): "out-of-bounds array access, or assert violations. " ) description += ( - "This is acceptable in most situations. " - "Note however that `assert()` should only be used to check invariants. " + "Note that explicit `assert()` should only be used to check invariants. " "Use `require()` for regular input checking. " ) diff --git a/mythril/analysis/modules/integer.py b/mythril/analysis/modules/integer.py index 3b373926..c6f02936 100644 --- a/mythril/analysis/modules/integer.py +++ b/mythril/analysis/modules/integer.py @@ -99,12 +99,7 @@ def _check_integer_overflow(statespace, state, node): _type="Warning", ) - issue.description = ( - "A possible integer overflow exists in the function `{}`.\n" - "The addition or multiplication may result in a value higher than the maximum representable integer.".format( - node.function_name - ) - ) + issue.description = "The arithmetic operation can result in integer overflow.\n" issue.debug = solver.pretty_print_model(model) issues.append(issue) @@ -213,10 +208,7 @@ def _check_integer_underflow(statespace, state, node): ) issue.description = ( - "A possible integer underflow exists in the function `" - + node.function_name - + "`.\n" - "The subtraction may result in a value < 0." + "The substraction can result in an integer underflow.\n" ) issue.debug = solver.pretty_print_model(model) diff --git a/mythril/analysis/modules/multiple_sends.py b/mythril/analysis/modules/multiple_sends.py index a53e20b5..c3489141 100644 --- a/mythril/analysis/modules/multiple_sends.py +++ b/mythril/analysis/modules/multiple_sends.py @@ -33,7 +33,7 @@ def execute(statespace): ) issue.description = ( - "Multiple sends exist in one transaction. Try to isolate each external call into its own transaction," + "Multiple sends are executed in a single transaction. Try to isolate each external call into its own transaction," " as external calls can fail accidentally or deliberately.\nConsecutive calls: \n" ) diff --git a/mythril/analysis/modules/suicide.py b/mythril/analysis/modules/suicide.py index 0d1b4859..70e68a4c 100644 --- a/mythril/analysis/modules/suicide.py +++ b/mythril/analysis/modules/suicide.py @@ -39,9 +39,8 @@ def _analyze_state(state, node): to = state.mstate.stack[-1] logging.debug("[UNCHECKED_SUICIDE] suicide in function " + node.function_name) - description = ( - "The function `" + node.function_name + "` executes the SUICIDE instruction. " - ) + + description = "A reachable SUICIDE instruction was detected. " if "caller" in str(to): description += "The remaining Ether is sent to the caller's address.\n" diff --git a/mythril/analysis/modules/transaction_order_dependence.py b/mythril/analysis/modules/transaction_order_dependence.py index bd6a36f8..8d98bfdb 100644 --- a/mythril/analysis/modules/transaction_order_dependence.py +++ b/mythril/analysis/modules/transaction_order_dependence.py @@ -43,10 +43,8 @@ def execute(statespace): ) issue.description = ( - "A possible transaction order dependence vulnerability exists in function {}. The value or " - "direction of the call statement is determined from a tainted storage location".format( - node.function_name - ) + "Possible transaction order dependence vulnerability: The value or " + "direction of the call statement is determined from a tainted storage location" ) issues.append(issue) diff --git a/tests/cmd_line_test.py b/tests/cmd_line_test.py index 9c5033aa..83ade882 100644 --- a/tests/cmd_line_test.py +++ b/tests/cmd_line_test.py @@ -26,7 +26,8 @@ class TruffleTestCase(BaseTestCase): def test_analysis_truffle_project(self): truffle_project_root = str(TESTS_DIR / "truffle_project") command = "cd {}; truffle compile; python3 {} --truffle".format(truffle_project_root, MYTH) - self.assertIn("In the function `withdrawfunds()` a non-zero amount of Ether is sent to msg.sender.", output_of(command)) + self.assertIn("A non-zero amount of Ether is sent to a user-supplied address. The target address is msg.sender." + , output_of(command)) class InfuraTestCase(BaseTestCase): diff --git a/tests/testdata/outputs_expected/calls.sol.o.graph.html b/tests/testdata/outputs_expected/calls.sol.o.graph.html index 6af2b5fa..cc2b882d 100644 --- a/tests/testdata/outputs_expected/calls.sol.o.graph.html +++ b/tests/testdata/outputs_expected/calls.sol.o.graph.html @@ -8,6 +8,7 @@

Mythril / Ethereum LASER Symbolic VM

-


+

Mythril / Ethereum LASER Symbolic VM

-


+

Mythril / Ethereum LASER Symbolic VM

-


+

Mythril / Ethereum LASER Symbolic VM

-


+

Mythril / Ethereum LASER Symbolic VM

-


+

Mythril / Ethereum LASER Symbolic VM

-


+

Mythril / Ethereum LASER Symbolic VM

-


+

Mythril / Ethereum LASER Symbolic VM

-


+

Mythril / Ethereum LASER Symbolic VM

-


+
+ + + + + + + + +

Mythril / Ethereum LASER Symbolic VM

+
+ + + \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/calls.sol.o.json b/tests/testdata/outputs_expected/outputs_current/calls.sol.o.json new file mode 100644 index 00000000..d7b6f7e0 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/calls.sol.o.json @@ -0,0 +1 @@ +{"error": null, "issues": [{"address": 661, "contract": "Unknown", "debug": "", "description": "This contract executes a message call to to another contract. Make sure that the called contract is trusted and does not execute user-supplied code.", "function": "_function_0x5a6814ec", "swc_id": "107", "title": "Message call to external contract", "type": "Informational"}, {"address": 666, "contract": "Unknown", "debug": "", "description": "The return value of an external call is not checked. Note that execution continue even if the called contract throws.", "function": "_function_0x5a6814ec", "swc_id": "104", "title": "Unchecked CALL return value", "type": "Informational"}, {"address": 779, "contract": "Unknown", "debug": "", "description": "This contract executes a message call to an address found at storage slot 1. This storage slot can be written to by calling the function `_function_0x2776b163`. Generally, it is not recommended to call user-supplied addresses using Solidity's call() construct. Note that attackers might leverage reentrancy attacks to exploit race conditions or manipulate this contract's state.", "function": "_function_0xd24b08cc", "swc_id": "107", "title": "Message call to external contract", "type": "Warning"}, {"address": 779, "contract": "Unknown", "debug": "", "description": "Possible transaction order dependence vulnerability: The value or direction of the call statement is determined from a tainted storage location", "function": "_function_0xd24b08cc", "swc_id": "114", "title": "Transaction order dependence", "type": "Warning"}, {"address": 784, "contract": "Unknown", "debug": "", "description": "The return value of an external call is not checked. Note that execution continue even if the called contract throws.", "function": "_function_0xd24b08cc", "swc_id": "104", "title": "Unchecked CALL return value", "type": "Informational"}, {"address": 858, "contract": "Unknown", "debug": "", "description": "This contract executes a message call to to another contract. Make sure that the called contract is trusted and does not execute user-supplied code.", "function": "_function_0xe11f493e", "swc_id": "107", "title": "Message call to external contract", "type": "Informational"}, {"address": 869, "contract": "Unknown", "debug": "", "description": "The contract account state is changed after an external call. Consider that the called contract could re-enter the function before this state change takes place. This can lead to business logic vulnerabilities.", "function": "_function_0xe11f493e", "swc_id": "107", "title": "State change after external call", "type": "Warning"}, {"address": 871, "contract": "Unknown", "debug": "", "description": "The return value of an external call is not checked. Note that execution continue even if the called contract throws.", "function": "_function_0xe11f493e", "swc_id": "104", "title": "Unchecked CALL return value", "type": "Informational"}, {"address": 912, "contract": "Unknown", "debug": "", "description": "This contract executes a message call to an address provided as a function argument. Generally, it is not recommended to call user-supplied addresses using Solidity's call() construct. Note that attackers might leverage reentrancy attacks to exploit race conditions or manipulate this contract's state.", "function": "_function_0xe1d10f79", "swc_id": "107", "title": "Message call to external contract", "type": "Warning"}, {"address": 918, "contract": "Unknown", "debug": "", "description": "The return value of an external call is not checked. Note that execution continue even if the called contract throws.", "function": "_function_0xe1d10f79", "swc_id": "104", "title": "Unchecked CALL return value", "type": "Informational"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/calls.sol.o.markdown b/tests/testdata/outputs_expected/outputs_current/calls.sol.o.markdown new file mode 100644 index 00000000..f19dbaef --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/calls.sol.o.markdown @@ -0,0 +1,111 @@ +# Analysis results for test-filename.sol + +## Message call to external contract +- SWC ID: 107 +- Type: Informational +- Contract: Unknown +- Function name: `_function_0x5a6814ec` +- PC address: 661 + +### Description + +This contract executes a message call to to another contract. Make sure that the called contract is trusted and does not execute user-supplied code. + +## Unchecked CALL return value +- SWC ID: 104 +- Type: Informational +- Contract: Unknown +- Function name: `_function_0x5a6814ec` +- PC address: 666 + +### Description + +The return value of an external call is not checked. Note that execution continue even if the called contract throws. + +## Message call to external contract +- SWC ID: 107 +- Type: Warning +- Contract: Unknown +- Function name: `_function_0xd24b08cc` +- PC address: 779 + +### Description + +This contract executes a message call to an address found at storage slot 1. This storage slot can be written to by calling the function `_function_0x2776b163`. Generally, it is not recommended to call user-supplied addresses using Solidity's call() construct. Note that attackers might leverage reentrancy attacks to exploit race conditions or manipulate this contract's state. + +## Transaction order dependence +- SWC ID: 114 +- Type: Warning +- Contract: Unknown +- Function name: `_function_0xd24b08cc` +- PC address: 779 + +### Description + +Possible transaction order dependence vulnerability: The value or direction of the call statement is determined from a tainted storage location + +## Unchecked CALL return value +- SWC ID: 104 +- Type: Informational +- Contract: Unknown +- Function name: `_function_0xd24b08cc` +- PC address: 784 + +### Description + +The return value of an external call is not checked. Note that execution continue even if the called contract throws. + +## Message call to external contract +- SWC ID: 107 +- Type: Informational +- Contract: Unknown +- Function name: `_function_0xe11f493e` +- PC address: 858 + +### Description + +This contract executes a message call to to another contract. Make sure that the called contract is trusted and does not execute user-supplied code. + +## State change after external call +- SWC ID: 107 +- Type: Warning +- Contract: Unknown +- Function name: `_function_0xe11f493e` +- PC address: 869 + +### Description + +The contract account state is changed after an external call. Consider that the called contract could re-enter the function before this state change takes place. This can lead to business logic vulnerabilities. + +## Unchecked CALL return value +- SWC ID: 104 +- Type: Informational +- Contract: Unknown +- Function name: `_function_0xe11f493e` +- PC address: 871 + +### Description + +The return value of an external call is not checked. Note that execution continue even if the called contract throws. + +## Message call to external contract +- SWC ID: 107 +- Type: Warning +- Contract: Unknown +- Function name: `_function_0xe1d10f79` +- PC address: 912 + +### Description + +This contract executes a message call to an address provided as a function argument. Generally, it is not recommended to call user-supplied addresses using Solidity's call() construct. Note that attackers might leverage reentrancy attacks to exploit race conditions or manipulate this contract's state. + +## Unchecked CALL return value +- SWC ID: 104 +- Type: Informational +- Contract: Unknown +- Function name: `_function_0xe1d10f79` +- PC address: 918 + +### Description + +The return value of an external call is not checked. Note that execution continue even if the called contract throws. diff --git a/tests/testdata/outputs_expected/outputs_current/calls.sol.o.text b/tests/testdata/outputs_expected/outputs_current/calls.sol.o.text new file mode 100644 index 00000000..c65b9fc7 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/calls.sol.o.text @@ -0,0 +1,90 @@ +==== Message call to external contract ==== +SWC ID: 107 +Type: Informational +Contract: Unknown +Function name: _function_0x5a6814ec +PC address: 661 +This contract executes a message call to to another contract. Make sure that the called contract is trusted and does not execute user-supplied code. +-------------------- + +==== Unchecked CALL return value ==== +SWC ID: 104 +Type: Informational +Contract: Unknown +Function name: _function_0x5a6814ec +PC address: 666 +The return value of an external call is not checked. Note that execution continue even if the called contract throws. +-------------------- + +==== Message call to external contract ==== +SWC ID: 107 +Type: Warning +Contract: Unknown +Function name: _function_0xd24b08cc +PC address: 779 +This contract executes a message call to an address found at storage slot 1. This storage slot can be written to by calling the function `_function_0x2776b163`. Generally, it is not recommended to call user-supplied addresses using Solidity's call() construct. Note that attackers might leverage reentrancy attacks to exploit race conditions or manipulate this contract's state. +-------------------- + +==== Transaction order dependence ==== +SWC ID: 114 +Type: Warning +Contract: Unknown +Function name: _function_0xd24b08cc +PC address: 779 +Possible transaction order dependence vulnerability: The value or direction of the call statement is determined from a tainted storage location +-------------------- + +==== Unchecked CALL return value ==== +SWC ID: 104 +Type: Informational +Contract: Unknown +Function name: _function_0xd24b08cc +PC address: 784 +The return value of an external call is not checked. Note that execution continue even if the called contract throws. +-------------------- + +==== Message call to external contract ==== +SWC ID: 107 +Type: Informational +Contract: Unknown +Function name: _function_0xe11f493e +PC address: 858 +This contract executes a message call to to another contract. Make sure that the called contract is trusted and does not execute user-supplied code. +-------------------- + +==== State change after external call ==== +SWC ID: 107 +Type: Warning +Contract: Unknown +Function name: _function_0xe11f493e +PC address: 869 +The contract account state is changed after an external call. Consider that the called contract could re-enter the function before this state change takes place. This can lead to business logic vulnerabilities. +-------------------- + +==== Unchecked CALL return value ==== +SWC ID: 104 +Type: Informational +Contract: Unknown +Function name: _function_0xe11f493e +PC address: 871 +The return value of an external call is not checked. Note that execution continue even if the called contract throws. +-------------------- + +==== Message call to external contract ==== +SWC ID: 107 +Type: Warning +Contract: Unknown +Function name: _function_0xe1d10f79 +PC address: 912 +This contract executes a message call to an address provided as a function argument. Generally, it is not recommended to call user-supplied addresses using Solidity's call() construct. Note that attackers might leverage reentrancy attacks to exploit race conditions or manipulate this contract's state. +-------------------- + +==== Unchecked CALL return value ==== +SWC ID: 104 +Type: Informational +Contract: Unknown +Function name: _function_0xe1d10f79 +PC address: 918 +The return value of an external call is not checked. Note that execution continue even if the called contract throws. +-------------------- + diff --git a/tests/testdata/outputs_expected/outputs_current/environments.sol.o.easm b/tests/testdata/outputs_expected/outputs_current/environments.sol.o.easm new file mode 100644 index 00000000..7a5b2043 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/environments.sol.o.easm @@ -0,0 +1,259 @@ +0 PUSH1 0x80 +2 PUSH1 0x40 +4 MSTORE +5 PUSH1 0x04 +7 CALLDATASIZE +8 LT +9 PUSH2 0x004c +12 JUMPI +13 PUSH1 0x00 +15 CALLDATALOAD +16 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 +46 SWAP1 +47 DIV +48 PUSH4 0xffffffff +53 AND +54 DUP1 +55 PUSH4 0x06661abd +60 EQ +61 PUSH2 0x0051 +64 JUMPI +65 DUP1 +66 PUSH4 0x83f12fec +71 EQ +72 PUSH2 0x007c +75 JUMPI +76 JUMPDEST +77 PUSH1 0x00 +79 DUP1 +80 REVERT +81 JUMPDEST +82 CALLVALUE +83 DUP1 +84 ISZERO +85 PUSH2 0x005d +88 JUMPI +89 PUSH1 0x00 +91 DUP1 +92 REVERT +93 JUMPDEST +94 POP +95 PUSH2 0x0066 +98 PUSH2 0x0104 +101 JUMP +102 JUMPDEST +103 PUSH1 0x40 +105 MLOAD +106 DUP1 +107 DUP3 +108 DUP2 +109 MSTORE +110 PUSH1 0x20 +112 ADD +113 SWAP2 +114 POP +115 POP +116 PUSH1 0x40 +118 MLOAD +119 DUP1 +120 SWAP2 +121 SUB +122 SWAP1 +123 RETURN +124 JUMPDEST +125 CALLVALUE +126 DUP1 +127 ISZERO +128 PUSH2 0x0088 +131 JUMPI +132 PUSH1 0x00 +134 DUP1 +135 REVERT +136 JUMPDEST +137 POP +138 PUSH2 0x00ea +141 PUSH1 0x04 +143 DUP1 +144 CALLDATASIZE +145 SUB +146 DUP2 +147 ADD +148 SWAP1 +149 DUP1 +150 DUP1 +151 CALLDATALOAD +152 SWAP1 +153 PUSH1 0x20 +155 ADD +156 SWAP1 +157 DUP3 +158 ADD +159 DUP1 +160 CALLDATALOAD +161 SWAP1 +162 PUSH1 0x20 +164 ADD +165 SWAP1 +166 DUP1 +167 DUP1 +168 PUSH1 0x20 +170 MUL +171 PUSH1 0x20 +173 ADD +174 PUSH1 0x40 +176 MLOAD +177 SWAP1 +178 DUP2 +179 ADD +180 PUSH1 0x40 +182 MSTORE +183 DUP1 +184 SWAP4 +185 SWAP3 +186 SWAP2 +187 SWAP1 +188 DUP2 +189 DUP2 +190 MSTORE +191 PUSH1 0x20 +193 ADD +194 DUP4 +195 DUP4 +196 PUSH1 0x20 +198 MUL +199 DUP1 +200 DUP3 +201 DUP5 +202 CALLDATACOPY +203 DUP3 +204 ADD +205 SWAP2 +206 POP +207 POP +208 POP +209 POP +210 POP +211 POP +212 SWAP2 +213 SWAP3 +214 SWAP2 +215 SWAP3 +216 SWAP1 +217 DUP1 +218 CALLDATALOAD +219 SWAP1 +220 PUSH1 0x20 +222 ADD +223 SWAP1 +224 SWAP3 +225 SWAP2 +226 SWAP1 +227 POP +228 POP +229 POP +230 PUSH2 0x010a +233 JUMP +234 JUMPDEST +235 PUSH1 0x40 +237 MLOAD +238 DUP1 +239 DUP3 +240 ISZERO +241 ISZERO +242 ISZERO +243 ISZERO +244 DUP2 +245 MSTORE +246 PUSH1 0x20 +248 ADD +249 SWAP2 +250 POP +251 POP +252 PUSH1 0x40 +254 MLOAD +255 DUP1 +256 SWAP2 +257 SUB +258 SWAP1 +259 RETURN +260 JUMPDEST +261 PUSH1 0x00 +263 SLOAD +264 DUP2 +265 JUMP +266 JUMPDEST +267 PUSH1 0x00 +269 DUP1 +270 PUSH1 0x00 +272 DUP5 +273 MLOAD +274 SWAP2 +275 POP +276 DUP4 +277 DUP3 +278 MUL +279 SWAP1 +280 POP +281 PUSH1 0x00 +283 DUP3 +284 GT +285 DUP1 +286 ISZERO +287 PUSH2 0x0129 +290 JUMPI +291 POP +292 PUSH1 0x14 +294 DUP3 +295 GT +296 ISZERO +297 JUMPDEST +298 ISZERO +299 ISZERO +300 PUSH2 0x0134 +303 JUMPI +304 PUSH1 0x00 +306 DUP1 +307 REVERT +308 JUMPDEST +309 DUP1 +310 PUSH1 0x01 +312 PUSH1 0x00 +314 CALLER +315 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +336 AND +337 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +358 AND +359 DUP2 +360 MSTORE +361 PUSH1 0x20 +363 ADD +364 SWAP1 +365 DUP2 +366 MSTORE +367 PUSH1 0x20 +369 ADD +370 PUSH1 0x00 +372 SHA3 +373 PUSH1 0x00 +375 DUP3 +376 DUP3 +377 SLOAD +378 SUB +379 SWAP3 +380 POP +381 POP +382 DUP2 +383 SWAP1 +384 SSTORE +385 POP +386 PUSH1 0x01 +388 SWAP3 +389 POP +390 POP +391 POP +392 SWAP3 +393 SWAP2 +394 POP +395 POP +396 JUMP +397 STOP diff --git a/tests/testdata/outputs_expected/outputs_current/environments.sol.o.graph.html b/tests/testdata/outputs_expected/outputs_current/environments.sol.o.graph.html new file mode 100644 index 00000000..9dbc6800 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/environments.sol.o.graph.html @@ -0,0 +1,62 @@ + + + + Call Graph + + + + + + + + + + +

Mythril / Ethereum LASER Symbolic VM

+
+ + + \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/environments.sol.o.json b/tests/testdata/outputs_expected/outputs_current/environments.sol.o.json new file mode 100644 index 00000000..207b9a02 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/environments.sol.o.json @@ -0,0 +1 @@ +{"error": null, "issues": [{"address": 158, "contract": "Unknown", "debug": "", "description": "The arithmetic operation can result in integer overflow.\n", "function": "_function_0x83f12fec", "swc_id": "101", "title": "Integer Overflow", "type": "Warning"}, {"address": 278, "contract": "Unknown", "debug": "", "description": "The arithmetic operation can result in integer overflow.\n", "function": "_function_0x83f12fec", "swc_id": "101", "title": "Integer Overflow", "type": "Warning"}, {"address": 378, "contract": "Unknown", "debug": "", "description": "The substraction can result in an integer underflow.\n", "function": "_function_0x83f12fec", "swc_id": "101", "title": "Integer Underflow", "type": "Warning"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/environments.sol.o.markdown b/tests/testdata/outputs_expected/outputs_current/environments.sol.o.markdown new file mode 100644 index 00000000..c9630745 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/environments.sol.o.markdown @@ -0,0 +1,34 @@ +# Analysis results for test-filename.sol + +## Integer Overflow +- SWC ID: 101 +- Type: Warning +- Contract: Unknown +- Function name: `_function_0x83f12fec` +- PC address: 158 + +### Description + +The arithmetic operation can result in integer overflow. + +## Integer Overflow +- SWC ID: 101 +- Type: Warning +- Contract: Unknown +- Function name: `_function_0x83f12fec` +- PC address: 278 + +### Description + +The arithmetic operation can result in integer overflow. + +## Integer Underflow +- SWC ID: 101 +- Type: Warning +- Contract: Unknown +- Function name: `_function_0x83f12fec` +- PC address: 378 + +### Description + +The substraction can result in an integer underflow. diff --git a/tests/testdata/outputs_expected/outputs_current/environments.sol.o.text b/tests/testdata/outputs_expected/outputs_current/environments.sol.o.text new file mode 100644 index 00000000..ef673002 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/environments.sol.o.text @@ -0,0 +1,30 @@ +==== Integer Overflow ==== +SWC ID: 101 +Type: Warning +Contract: Unknown +Function name: _function_0x83f12fec +PC address: 158 +The arithmetic operation can result in integer overflow. + +-------------------- + +==== Integer Overflow ==== +SWC ID: 101 +Type: Warning +Contract: Unknown +Function name: _function_0x83f12fec +PC address: 278 +The arithmetic operation can result in integer overflow. + +-------------------- + +==== Integer Underflow ==== +SWC ID: 101 +Type: Warning +Contract: Unknown +Function name: _function_0x83f12fec +PC address: 378 +The substraction can result in an integer underflow. + +-------------------- + diff --git a/tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.easm b/tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.easm new file mode 100644 index 00000000..b0a5e256 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.easm @@ -0,0 +1,420 @@ +0 PUSH1 0x80 +2 PUSH1 0x40 +4 MSTORE +5 PUSH1 0x04 +7 CALLDATASIZE +8 LT +9 PUSH2 0x0078 +12 JUMPI +13 PUSH1 0x00 +15 CALLDATALOAD +16 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 +46 SWAP1 +47 DIV +48 PUSH4 0xffffffff +53 AND +54 DUP1 +55 PUSH4 0x12065fe0 +60 EQ +61 PUSH2 0x007d +64 JUMPI +65 DUP1 +66 PUSH4 0x27e235e3 +71 EQ +72 PUSH2 0x00a8 +75 JUMPI +76 DUP1 +77 PUSH4 0x56885cd8 +82 EQ +83 PUSH2 0x00ff +86 JUMPI +87 DUP1 +88 PUSH4 0x6c343ffe +93 EQ +94 PUSH2 0x0116 +97 JUMPI +98 DUP1 +99 PUSH4 0x8da5cb5b +104 EQ +105 PUSH2 0x012d +108 JUMPI +109 DUP1 +110 PUSH4 0xe8b5e51f +115 EQ +116 PUSH2 0x0184 +119 JUMPI +120 JUMPDEST +121 PUSH1 0x00 +123 DUP1 +124 REVERT +125 JUMPDEST +126 CALLVALUE +127 DUP1 +128 ISZERO +129 PUSH2 0x0089 +132 JUMPI +133 PUSH1 0x00 +135 DUP1 +136 REVERT +137 JUMPDEST +138 POP +139 PUSH2 0x0092 +142 PUSH2 0x018e +145 JUMP +146 JUMPDEST +147 PUSH1 0x40 +149 MLOAD +150 DUP1 +151 DUP3 +152 DUP2 +153 MSTORE +154 PUSH1 0x20 +156 ADD +157 SWAP2 +158 POP +159 POP +160 PUSH1 0x40 +162 MLOAD +163 DUP1 +164 SWAP2 +165 SUB +166 SWAP1 +167 RETURN +168 JUMPDEST +169 CALLVALUE +170 DUP1 +171 ISZERO +172 PUSH2 0x00b4 +175 JUMPI +176 PUSH1 0x00 +178 DUP1 +179 REVERT +180 JUMPDEST +181 POP +182 PUSH2 0x00e9 +185 PUSH1 0x04 +187 DUP1 +188 CALLDATASIZE +189 SUB +190 DUP2 +191 ADD +192 SWAP1 +193 DUP1 +194 DUP1 +195 CALLDATALOAD +196 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +217 AND +218 SWAP1 +219 PUSH1 0x20 +221 ADD +222 SWAP1 +223 SWAP3 +224 SWAP2 +225 SWAP1 +226 POP +227 POP +228 POP +229 PUSH2 0x01d4 +232 JUMP +233 JUMPDEST +234 PUSH1 0x40 +236 MLOAD +237 DUP1 +238 DUP3 +239 DUP2 +240 MSTORE +241 PUSH1 0x20 +243 ADD +244 SWAP2 +245 POP +246 POP +247 PUSH1 0x40 +249 MLOAD +250 DUP1 +251 SWAP2 +252 SUB +253 SWAP1 +254 RETURN +255 JUMPDEST +256 CALLVALUE +257 DUP1 +258 ISZERO +259 PUSH2 0x010b +262 JUMPI +263 PUSH1 0x00 +265 DUP1 +266 REVERT +267 JUMPDEST +268 POP +269 PUSH2 0x0114 +272 PUSH2 0x01ec +275 JUMP +276 JUMPDEST +277 STOP +278 JUMPDEST +279 CALLVALUE +280 DUP1 +281 ISZERO +282 PUSH2 0x0122 +285 JUMPI +286 PUSH1 0x00 +288 DUP1 +289 REVERT +290 JUMPDEST +291 POP +292 PUSH2 0x012b +295 PUSH2 0x022f +298 JUMP +299 JUMPDEST +300 STOP +301 JUMPDEST +302 CALLVALUE +303 DUP1 +304 ISZERO +305 PUSH2 0x0139 +308 JUMPI +309 PUSH1 0x00 +311 DUP1 +312 REVERT +313 JUMPDEST +314 POP +315 PUSH2 0x0142 +318 PUSH2 0x02eb +321 JUMP +322 JUMPDEST +323 PUSH1 0x40 +325 MLOAD +326 DUP1 +327 DUP3 +328 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +349 AND +350 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +371 AND +372 DUP2 +373 MSTORE +374 PUSH1 0x20 +376 ADD +377 SWAP2 +378 POP +379 POP +380 PUSH1 0x40 +382 MLOAD +383 DUP1 +384 SWAP2 +385 SUB +386 SWAP1 +387 RETURN +388 JUMPDEST +389 PUSH2 0x018c +392 PUSH2 0x0311 +395 JUMP +396 JUMPDEST +397 STOP +398 JUMPDEST +399 PUSH1 0x00 +401 DUP1 +402 PUSH1 0x00 +404 CALLER +405 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +426 AND +427 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +448 AND +449 DUP2 +450 MSTORE +451 PUSH1 0x20 +453 ADD +454 SWAP1 +455 DUP2 +456 MSTORE +457 PUSH1 0x20 +459 ADD +460 PUSH1 0x00 +462 SHA3 +463 SLOAD +464 SWAP1 +465 POP +466 SWAP1 +467 JUMP +468 JUMPDEST +469 PUSH1 0x00 +471 PUSH1 0x20 +473 MSTORE +474 DUP1 +475 PUSH1 0x00 +477 MSTORE +478 PUSH1 0x40 +480 PUSH1 0x00 +482 SHA3 +483 PUSH1 0x00 +485 SWAP2 +486 POP +487 SWAP1 +488 POP +489 SLOAD +490 DUP2 +491 JUMP +492 JUMPDEST +493 CALLER +494 PUSH1 0x01 +496 PUSH1 0x00 +498 PUSH2 0x0100 +501 EXP +502 DUP2 +503 SLOAD +504 DUP2 +505 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +526 MUL +527 NOT +528 AND +529 SWAP1 +530 DUP4 +531 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +552 AND +553 MUL +554 OR +555 SWAP1 +556 SSTORE +557 POP +558 JUMP +559 JUMPDEST +560 PUSH1 0x01 +562 PUSH1 0x00 +564 SWAP1 +565 SLOAD +566 SWAP1 +567 PUSH2 0x0100 +570 EXP +571 SWAP1 +572 DIV +573 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +594 AND +595 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +616 AND +617 CALLER +618 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +639 AND +640 EQ +641 ISZERO +642 ISZERO +643 PUSH2 0x028b +646 JUMPI +647 PUSH1 0x00 +649 DUP1 +650 REVERT +651 JUMPDEST +652 CALLER +653 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +674 AND +675 PUSH2 0x08fc +678 ADDRESS +679 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +700 AND +701 BALANCE +702 SWAP1 +703 DUP2 +704 ISZERO +705 MUL +706 SWAP1 +707 PUSH1 0x40 +709 MLOAD +710 PUSH1 0x00 +712 PUSH1 0x40 +714 MLOAD +715 DUP1 +716 DUP4 +717 SUB +718 DUP2 +719 DUP6 +720 DUP9 +721 DUP9 +722 CALL +723 SWAP4 +724 POP +725 POP +726 POP +727 POP +728 ISZERO +729 DUP1 +730 ISZERO +731 PUSH2 0x02e8 +734 JUMPI +735 RETURNDATASIZE +736 PUSH1 0x00 +738 DUP1 +739 RETURNDATACOPY +740 RETURNDATASIZE +741 PUSH1 0x00 +743 REVERT +744 JUMPDEST +745 POP +746 JUMP +747 JUMPDEST +748 PUSH1 0x01 +750 PUSH1 0x00 +752 SWAP1 +753 SLOAD +754 SWAP1 +755 PUSH2 0x0100 +758 EXP +759 SWAP1 +760 DIV +761 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +782 AND +783 DUP2 +784 JUMP +785 JUMPDEST +786 PUSH1 0x02 +788 SLOAD +789 CALLVALUE +790 GT +791 DUP1 +792 ISZERO +793 PUSH2 0x0323 +796 JUMPI +797 POP +798 PUSH1 0x03 +800 SLOAD +801 CALLVALUE +802 LT +803 JUMPDEST +804 ISZERO +805 ISZERO +806 PUSH2 0x032e +809 JUMPI +810 PUSH1 0x00 +812 DUP1 +813 REVERT +814 JUMPDEST +815 CALLVALUE +816 PUSH1 0x00 +818 DUP1 +819 CALLER +820 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +841 AND +842 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +863 AND +864 DUP2 +865 MSTORE +866 PUSH1 0x20 +868 ADD +869 SWAP1 +870 DUP2 +871 MSTORE +872 PUSH1 0x20 +874 ADD +875 PUSH1 0x00 +877 SHA3 +878 PUSH1 0x00 +880 DUP3 +881 DUP3 +882 SLOAD +883 ADD +884 SWAP3 +885 POP +886 POP +887 DUP2 +888 SWAP1 +889 SSTORE +890 POP +891 JUMP +892 STOP diff --git a/tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.graph.html b/tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.graph.html new file mode 100644 index 00000000..445674a0 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.graph.html @@ -0,0 +1,62 @@ + + + + Call Graph + + + + + + + + + + +

Mythril / Ethereum LASER Symbolic VM

+
+ + + \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.json b/tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.json new file mode 100644 index 00000000..f993162b --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.json @@ -0,0 +1 @@ +{"error": null, "issues": [{"address": 722, "contract": "Unknown", "debug": "", "description": "A non-zero amount of Ether is sent to a user-supplied address. The target address is msg.sender.\n\nThere is a check on storage index 1. This storage slot can be written to by calling the function `crowdfunding()`.", "function": "withdrawfunds()", "swc_id": "105", "title": "Ether send", "type": "Warning"}, {"address": 883, "contract": "Unknown", "debug": "", "description": "The arithmetic operation can result in integer overflow.\n", "function": "invest()", "swc_id": "101", "title": "Integer Overflow", "type": "Warning"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.markdown b/tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.markdown new file mode 100644 index 00000000..5b677714 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.markdown @@ -0,0 +1,25 @@ +# Analysis results for test-filename.sol + +## Ether send +- SWC ID: 105 +- Type: Warning +- Contract: Unknown +- Function name: `withdrawfunds()` +- PC address: 722 + +### Description + +A non-zero amount of Ether is sent to a user-supplied address. The target address is msg.sender. + +There is a check on storage index 1. This storage slot can be written to by calling the function `crowdfunding()`. + +## Integer Overflow +- SWC ID: 101 +- Type: Warning +- Contract: Unknown +- Function name: `invest()` +- PC address: 883 + +### Description + +The arithmetic operation can result in integer overflow. diff --git a/tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.text b/tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.text new file mode 100644 index 00000000..e9c61963 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/ether_send.sol.o.text @@ -0,0 +1,21 @@ +==== Ether send ==== +SWC ID: 105 +Type: Warning +Contract: Unknown +Function name: withdrawfunds() +PC address: 722 +A non-zero amount of Ether is sent to a user-supplied address. The target address is msg.sender. + +There is a check on storage index 1. This storage slot can be written to by calling the function `crowdfunding()`. +-------------------- + +==== Integer Overflow ==== +SWC ID: 101 +Type: Warning +Contract: Unknown +Function name: invest() +PC address: 883 +The arithmetic operation can result in integer overflow. + +-------------------- + diff --git a/tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.easm b/tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.easm new file mode 100644 index 00000000..ef83a75c --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.easm @@ -0,0 +1,392 @@ +0 PUSH1 0x60 +2 PUSH1 0x40 +4 MSTORE +5 PUSH1 0x04 +7 CALLDATASIZE +8 LT +9 PUSH2 0x008e +12 JUMPI +13 PUSH1 0x00 +15 CALLDATALOAD +16 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 +46 SWAP1 +47 DIV +48 PUSH4 0xffffffff +53 AND +54 DUP1 +55 PUSH4 0x01d4277c +60 EQ +61 PUSH2 0x0093 +64 JUMPI +65 DUP1 +66 PUSH4 0x546455b5 +71 EQ +72 PUSH2 0x00b6 +75 JUMPI +76 DUP1 +77 PUSH4 0x78375f14 +82 EQ +83 PUSH2 0x00d9 +86 JUMPI +87 DUP1 +88 PUSH4 0x92dd38ea +93 EQ +94 PUSH2 0x00fc +97 JUMPI +98 DUP1 +99 PUSH4 0xa08299f1 +104 EQ +105 PUSH2 0x011f +108 JUMPI +109 DUP1 +110 PUSH4 0xb34c3610 +115 EQ +116 PUSH2 0x0142 +119 JUMPI +120 DUP1 +121 PUSH4 0xb630d706 +126 EQ +127 PUSH2 0x0157 +130 JUMPI +131 DUP1 +132 PUSH4 0xf44f13d8 +137 EQ +138 PUSH2 0x017a +141 JUMPI +142 JUMPDEST +143 PUSH1 0x00 +145 DUP1 +146 REVERT +147 JUMPDEST +148 CALLVALUE +149 ISZERO +150 PUSH2 0x009e +153 JUMPI +154 PUSH1 0x00 +156 DUP1 +157 REVERT +158 JUMPDEST +159 PUSH2 0x00b4 +162 PUSH1 0x04 +164 DUP1 +165 DUP1 +166 CALLDATALOAD +167 SWAP1 +168 PUSH1 0x20 +170 ADD +171 SWAP1 +172 SWAP2 +173 SWAP1 +174 POP +175 POP +176 PUSH2 0x018f +179 JUMP +180 JUMPDEST +181 STOP +182 JUMPDEST +183 CALLVALUE +184 ISZERO +185 PUSH2 0x00c1 +188 JUMPI +189 PUSH1 0x00 +191 DUP1 +192 REVERT +193 JUMPDEST +194 PUSH2 0x00d7 +197 PUSH1 0x04 +199 DUP1 +200 DUP1 +201 CALLDATALOAD +202 SWAP1 +203 PUSH1 0x20 +205 ADD +206 SWAP1 +207 SWAP2 +208 SWAP1 +209 POP +210 POP +211 PUSH2 0x01b2 +214 JUMP +215 JUMPDEST +216 STOP +217 JUMPDEST +218 CALLVALUE +219 ISZERO +220 PUSH2 0x00e4 +223 JUMPI +224 PUSH1 0x00 +226 DUP1 +227 REVERT +228 JUMPDEST +229 PUSH2 0x00fa +232 PUSH1 0x04 +234 DUP1 +235 DUP1 +236 CALLDATALOAD +237 SWAP1 +238 PUSH1 0x20 +240 ADD +241 SWAP1 +242 SWAP2 +243 SWAP1 +244 POP +245 POP +246 PUSH2 0x01c2 +249 JUMP +250 JUMPDEST +251 STOP +252 JUMPDEST +253 CALLVALUE +254 ISZERO +255 PUSH2 0x0107 +258 JUMPI +259 PUSH1 0x00 +261 DUP1 +262 REVERT +263 JUMPDEST +264 PUSH2 0x011d +267 PUSH1 0x04 +269 DUP1 +270 DUP1 +271 CALLDATALOAD +272 SWAP1 +273 PUSH1 0x20 +275 ADD +276 SWAP1 +277 SWAP2 +278 SWAP1 +279 POP +280 POP +281 PUSH2 0x01d5 +284 JUMP +285 JUMPDEST +286 STOP +287 JUMPDEST +288 CALLVALUE +289 ISZERO +290 PUSH2 0x012a +293 JUMPI +294 PUSH1 0x00 +296 DUP1 +297 REVERT +298 JUMPDEST +299 PUSH2 0x0140 +302 PUSH1 0x04 +304 DUP1 +305 DUP1 +306 CALLDATALOAD +307 SWAP1 +308 PUSH1 0x20 +310 ADD +311 SWAP1 +312 SWAP2 +313 SWAP1 +314 POP +315 POP +316 PUSH2 0x01ed +319 JUMP +320 JUMPDEST +321 STOP +322 JUMPDEST +323 CALLVALUE +324 ISZERO +325 PUSH2 0x014d +328 JUMPI +329 PUSH1 0x00 +331 DUP1 +332 REVERT +333 JUMPDEST +334 PUSH2 0x0155 +337 PUSH2 0x0202 +340 JUMP +341 JUMPDEST +342 STOP +343 JUMPDEST +344 CALLVALUE +345 ISZERO +346 PUSH2 0x0162 +349 JUMPI +350 PUSH1 0x00 +352 DUP1 +353 REVERT +354 JUMPDEST +355 PUSH2 0x0178 +358 PUSH1 0x04 +360 DUP1 +361 DUP1 +362 CALLDATALOAD +363 SWAP1 +364 PUSH1 0x20 +366 ADD +367 SWAP1 +368 SWAP2 +369 SWAP1 +370 POP +371 POP +372 PUSH2 0x0217 +375 JUMP +376 JUMPDEST +377 STOP +378 JUMPDEST +379 CALLVALUE +380 ISZERO +381 PUSH2 0x0185 +384 JUMPI +385 PUSH1 0x00 +387 DUP1 +388 REVERT +389 JUMPDEST +390 PUSH2 0x018d +393 PUSH2 0x0235 +396 JUMP +397 JUMPDEST +398 STOP +399 JUMPDEST +400 PUSH1 0x00 +402 PUSH1 0x08 +404 DUP3 +405 LT +406 ISZERO +407 PUSH2 0x01ae +410 JUMPI +411 PUSH1 0x00 +413 DUP3 +414 PUSH1 0x08 +416 DUP2 +417 LT +418 ISZERO +419 ISZERO +420 PUSH2 0x01a9 +423 JUMPI +424 ASSERT_FAIL +425 JUMPDEST +426 ADD +427 SLOAD +428 SWAP1 +429 POP +430 JUMPDEST +431 POP +432 POP +433 JUMP +434 JUMPDEST +435 PUSH1 0x17 +437 DUP2 +438 EQ +439 ISZERO +440 ISZERO +441 ISZERO +442 PUSH2 0x01bf +445 JUMPI +446 ASSERT_FAIL +447 JUMPDEST +448 POP +449 JUMP +450 JUMPDEST +451 PUSH1 0x17 +453 DUP2 +454 EQ +455 ISZERO +456 ISZERO +457 ISZERO +458 PUSH2 0x01d2 +461 JUMPI +462 PUSH1 0x00 +464 DUP1 +465 REVERT +466 JUMPDEST +467 POP +468 JUMP +469 JUMPDEST +470 PUSH1 0x00 +472 DUP1 +473 DUP3 +474 PUSH1 0x08 +476 DUP2 +477 LT +478 ISZERO +479 ISZERO +480 PUSH2 0x01e5 +483 JUMPI +484 ASSERT_FAIL +485 JUMPDEST +486 ADD +487 SLOAD +488 SWAP1 +489 POP +490 POP +491 POP +492 JUMP +493 JUMPDEST +494 PUSH1 0x00 +496 DUP2 +497 PUSH1 0x01 +499 DUP2 +500 ISZERO +501 ISZERO +502 PUSH2 0x01fb +505 JUMPI +506 ASSERT_FAIL +507 JUMPDEST +508 DIV +509 SWAP1 +510 POP +511 POP +512 POP +513 JUMP +514 JUMPDEST +515 PUSH1 0x00 +517 PUSH1 0x01 +519 SWAP1 +520 POP +521 PUSH1 0x00 +523 DUP2 +524 EQ +525 ISZERO +526 ISZERO +527 PUSH2 0x0214 +530 JUMPI +531 ASSERT_FAIL +532 JUMPDEST +533 POP +534 JUMP +535 JUMPDEST +536 PUSH1 0x00 +538 DUP1 +539 DUP3 +540 GT +541 ISZERO +542 PUSH2 0x0231 +545 JUMPI +546 DUP2 +547 PUSH1 0x01 +549 DUP2 +550 ISZERO +551 ISZERO +552 PUSH2 0x022d +555 JUMPI +556 ASSERT_FAIL +557 JUMPDEST +558 DIV +559 SWAP1 +560 POP +561 JUMPDEST +562 POP +563 POP +564 JUMP +565 JUMPDEST +566 PUSH1 0x00 +568 PUSH1 0x01 +570 SWAP1 +571 POP +572 PUSH1 0x00 +574 DUP2 +575 GT +576 ISZERO +577 ISZERO +578 PUSH2 0x0247 +581 JUMPI +582 ASSERT_FAIL +583 JUMPDEST +584 POP +585 JUMP +586 STOP diff --git a/tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.graph.html b/tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.graph.html new file mode 100644 index 00000000..f7879865 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.graph.html @@ -0,0 +1,62 @@ + + + + Call Graph + + + + + + + + + + +

Mythril / Ethereum LASER Symbolic VM

+
+ + + \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.json b/tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.json new file mode 100644 index 00000000..c8d722b5 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.json @@ -0,0 +1 @@ +{"error": null, "issues": [{"address": 446, "contract": "Unknown", "debug": "", "description": "A reachable exception (opcode 0xfe) has been detected. This can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking. ", "function": "_function_0x546455b5", "swc_id": "110", "title": "Exception state", "type": "Informational"}, {"address": 484, "contract": "Unknown", "debug": "", "description": "A reachable exception (opcode 0xfe) has been detected. This can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking. ", "function": "_function_0x92dd38ea", "swc_id": "110", "title": "Exception state", "type": "Informational"}, {"address": 506, "contract": "Unknown", "debug": "", "description": "A reachable exception (opcode 0xfe) has been detected. This can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking. ", "function": "_function_0xa08299f1", "swc_id": "110", "title": "Exception state", "type": "Informational"}, {"address": 531, "contract": "Unknown", "debug": "", "description": "A reachable exception (opcode 0xfe) has been detected. This can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking. ", "function": "_function_0xb34c3610", "swc_id": "110", "title": "Exception state", "type": "Informational"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.markdown b/tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.markdown new file mode 100644 index 00000000..2ed81d76 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.markdown @@ -0,0 +1,45 @@ +# Analysis results for test-filename.sol + +## Exception state +- SWC ID: 110 +- Type: Informational +- Contract: Unknown +- Function name: `_function_0x546455b5` +- PC address: 446 + +### Description + +A reachable exception (opcode 0xfe) has been detected. This can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking. + +## Exception state +- SWC ID: 110 +- Type: Informational +- Contract: Unknown +- Function name: `_function_0x92dd38ea` +- PC address: 484 + +### Description + +A reachable exception (opcode 0xfe) has been detected. This can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking. + +## Exception state +- SWC ID: 110 +- Type: Informational +- Contract: Unknown +- Function name: `_function_0xa08299f1` +- PC address: 506 + +### Description + +A reachable exception (opcode 0xfe) has been detected. This can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking. + +## Exception state +- SWC ID: 110 +- Type: Informational +- Contract: Unknown +- Function name: `_function_0xb34c3610` +- PC address: 531 + +### Description + +A reachable exception (opcode 0xfe) has been detected. This can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking. diff --git a/tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.text b/tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.text new file mode 100644 index 00000000..a9ac2d73 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/exceptions.sol.o.text @@ -0,0 +1,36 @@ +==== Exception state ==== +SWC ID: 110 +Type: Informational +Contract: Unknown +Function name: _function_0x546455b5 +PC address: 446 +A reachable exception (opcode 0xfe) has been detected. This can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking. +-------------------- + +==== Exception state ==== +SWC ID: 110 +Type: Informational +Contract: Unknown +Function name: _function_0x92dd38ea +PC address: 484 +A reachable exception (opcode 0xfe) has been detected. This can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking. +-------------------- + +==== Exception state ==== +SWC ID: 110 +Type: Informational +Contract: Unknown +Function name: _function_0xa08299f1 +PC address: 506 +A reachable exception (opcode 0xfe) has been detected. This can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking. +-------------------- + +==== Exception state ==== +SWC ID: 110 +Type: Informational +Contract: Unknown +Function name: _function_0xb34c3610 +PC address: 531 +A reachable exception (opcode 0xfe) has been detected. This can be caused by type errors, division by zero, out-of-bounds array access, or assert violations. Note that explicit `assert()` should only be used to check invariants. Use `require()` for regular input checking. +-------------------- + diff --git a/tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.easm b/tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.easm new file mode 100644 index 00000000..571b1c66 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.easm @@ -0,0 +1,435 @@ +0 PUSH1 0x60 +2 PUSH1 0x40 +4 MSTORE +5 PUSH1 0x04 +7 CALLDATASIZE +8 LT +9 PUSH2 0x006d +12 JUMPI +13 PUSH1 0x00 +15 CALLDATALOAD +16 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 +46 SWAP1 +47 DIV +48 PUSH4 0xffffffff +53 AND +54 DUP1 +55 PUSH4 0x141f32ff +60 EQ +61 PUSH2 0x0072 +64 JUMPI +65 DUP1 +66 PUSH4 0x2e52d606 +71 EQ +72 PUSH2 0x00b4 +75 JUMPI +76 DUP1 +77 PUSH4 0x67e404ce +82 EQ +83 PUSH2 0x00dd +86 JUMPI +87 DUP1 +88 PUSH4 0x9b58bc26 +93 EQ +94 PUSH2 0x0132 +97 JUMPI +98 DUP1 +99 PUSH4 0xeea4c864 +104 EQ +105 PUSH2 0x0174 +108 JUMPI +109 JUMPDEST +110 PUSH1 0x00 +112 DUP1 +113 REVERT +114 JUMPDEST +115 CALLVALUE +116 ISZERO +117 PUSH2 0x007d +120 JUMPI +121 PUSH1 0x00 +123 DUP1 +124 REVERT +125 JUMPDEST +126 PUSH2 0x00b2 +129 PUSH1 0x04 +131 DUP1 +132 DUP1 +133 CALLDATALOAD +134 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +155 AND +156 SWAP1 +157 PUSH1 0x20 +159 ADD +160 SWAP1 +161 SWAP2 +162 SWAP1 +163 DUP1 +164 CALLDATALOAD +165 SWAP1 +166 PUSH1 0x20 +168 ADD +169 SWAP1 +170 SWAP2 +171 SWAP1 +172 POP +173 POP +174 PUSH2 0x01b6 +177 JUMP +178 JUMPDEST +179 STOP +180 JUMPDEST +181 CALLVALUE +182 ISZERO +183 PUSH2 0x00bf +186 JUMPI +187 PUSH1 0x00 +189 DUP1 +190 REVERT +191 JUMPDEST +192 PUSH2 0x00c7 +195 PUSH2 0x0273 +198 JUMP +199 JUMPDEST +200 PUSH1 0x40 +202 MLOAD +203 DUP1 +204 DUP3 +205 DUP2 +206 MSTORE +207 PUSH1 0x20 +209 ADD +210 SWAP2 +211 POP +212 POP +213 PUSH1 0x40 +215 MLOAD +216 DUP1 +217 SWAP2 +218 SUB +219 SWAP1 +220 RETURN +221 JUMPDEST +222 CALLVALUE +223 ISZERO +224 PUSH2 0x00e8 +227 JUMPI +228 PUSH1 0x00 +230 DUP1 +231 REVERT +232 JUMPDEST +233 PUSH2 0x00f0 +236 PUSH2 0x0279 +239 JUMP +240 JUMPDEST +241 PUSH1 0x40 +243 MLOAD +244 DUP1 +245 DUP3 +246 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +267 AND +268 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +289 AND +290 DUP2 +291 MSTORE +292 PUSH1 0x20 +294 ADD +295 SWAP2 +296 POP +297 POP +298 PUSH1 0x40 +300 MLOAD +301 DUP1 +302 SWAP2 +303 SUB +304 SWAP1 +305 RETURN +306 JUMPDEST +307 CALLVALUE +308 ISZERO +309 PUSH2 0x013d +312 JUMPI +313 PUSH1 0x00 +315 DUP1 +316 REVERT +317 JUMPDEST +318 PUSH2 0x0172 +321 PUSH1 0x04 +323 DUP1 +324 DUP1 +325 CALLDATALOAD +326 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +347 AND +348 SWAP1 +349 PUSH1 0x20 +351 ADD +352 SWAP1 +353 SWAP2 +354 SWAP1 +355 DUP1 +356 CALLDATALOAD +357 SWAP1 +358 PUSH1 0x20 +360 ADD +361 SWAP1 +362 SWAP2 +363 SWAP1 +364 POP +365 POP +366 PUSH2 0x029f +369 JUMP +370 JUMPDEST +371 STOP +372 JUMPDEST +373 CALLVALUE +374 ISZERO +375 PUSH2 0x017f +378 JUMPI +379 PUSH1 0x00 +381 DUP1 +382 REVERT +383 JUMPDEST +384 PUSH2 0x01b4 +387 PUSH1 0x04 +389 DUP1 +390 DUP1 +391 CALLDATALOAD +392 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +413 AND +414 SWAP1 +415 PUSH1 0x20 +417 ADD +418 SWAP1 +419 SWAP2 +420 SWAP1 +421 DUP1 +422 CALLDATALOAD +423 SWAP1 +424 PUSH1 0x20 +426 ADD +427 SWAP1 +428 SWAP2 +429 SWAP1 +430 POP +431 POP +432 PUSH2 0x035a +435 JUMP +436 JUMPDEST +437 STOP +438 JUMPDEST +439 DUP2 +440 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +461 AND +462 PUSH1 0x40 +464 MLOAD +465 DUP1 +466 DUP1 +467 PUSH32 0x7365744e2875696e743235362900000000000000000000000000000000000000 +500 DUP2 +501 MSTORE +502 POP +503 PUSH1 0x0d +505 ADD +506 SWAP1 +507 POP +508 PUSH1 0x40 +510 MLOAD +511 DUP1 +512 SWAP2 +513 SUB +514 SWAP1 +515 SHA3 +516 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 +546 SWAP1 +547 DIV +548 DUP3 +549 PUSH1 0x40 +551 MLOAD +552 DUP3 +553 PUSH4 0xffffffff +558 AND +559 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 +589 MUL +590 DUP2 +591 MSTORE +592 PUSH1 0x04 +594 ADD +595 DUP1 +596 DUP3 +597 DUP2 +598 MSTORE +599 PUSH1 0x20 +601 ADD +602 SWAP2 +603 POP +604 POP +605 PUSH1 0x00 +607 PUSH1 0x40 +609 MLOAD +610 DUP1 +611 DUP4 +612 SUB +613 DUP2 +614 PUSH1 0x00 +616 DUP8 +617 GAS +618 CALLCODE +619 SWAP3 +620 POP +621 POP +622 POP +623 POP +624 POP +625 POP +626 JUMP +627 JUMPDEST +628 PUSH1 0x00 +630 SLOAD +631 DUP2 +632 JUMP +633 JUMPDEST +634 PUSH1 0x01 +636 PUSH1 0x00 +638 SWAP1 +639 SLOAD +640 SWAP1 +641 PUSH2 0x0100 +644 EXP +645 SWAP1 +646 DIV +647 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +668 AND +669 DUP2 +670 JUMP +671 JUMPDEST +672 DUP2 +673 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +694 AND +695 PUSH1 0x40 +697 MLOAD +698 DUP1 +699 DUP1 +700 PUSH32 0x7365744e2875696e743235362900000000000000000000000000000000000000 +733 DUP2 +734 MSTORE +735 POP +736 PUSH1 0x0d +738 ADD +739 SWAP1 +740 POP +741 PUSH1 0x40 +743 MLOAD +744 DUP1 +745 SWAP2 +746 SUB +747 SWAP1 +748 SHA3 +749 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 +779 SWAP1 +780 DIV +781 DUP3 +782 PUSH1 0x40 +784 MLOAD +785 DUP3 +786 PUSH4 0xffffffff +791 AND +792 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 +822 MUL +823 DUP2 +824 MSTORE +825 PUSH1 0x04 +827 ADD +828 DUP1 +829 DUP3 +830 DUP2 +831 MSTORE +832 PUSH1 0x20 +834 ADD +835 SWAP2 +836 POP +837 POP +838 PUSH1 0x00 +840 PUSH1 0x40 +842 MLOAD +843 DUP1 +844 DUP4 +845 SUB +846 DUP2 +847 DUP7 +848 GAS +849 DELEGATECALL +850 SWAP3 +851 POP +852 POP +853 POP +854 POP +855 POP +856 POP +857 JUMP +858 JUMPDEST +859 DUP2 +860 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +881 AND +882 PUSH1 0x40 +884 MLOAD +885 DUP1 +886 DUP1 +887 PUSH32 0x7365744e2875696e743235362900000000000000000000000000000000000000 +920 DUP2 +921 MSTORE +922 POP +923 PUSH1 0x0d +925 ADD +926 SWAP1 +927 POP +928 PUSH1 0x40 +930 MLOAD +931 DUP1 +932 SWAP2 +933 SUB +934 SWAP1 +935 SHA3 +936 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 +966 SWAP1 +967 DIV +968 DUP3 +969 PUSH1 0x40 +971 MLOAD +972 DUP3 +973 PUSH4 0xffffffff +978 AND +979 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 +1009 MUL +1010 DUP2 +1011 MSTORE +1012 PUSH1 0x04 +1014 ADD +1015 DUP1 +1016 DUP3 +1017 DUP2 +1018 MSTORE +1019 PUSH1 0x20 +1021 ADD +1022 SWAP2 +1023 POP +1024 POP +1025 PUSH1 0x00 +1027 PUSH1 0x40 +1029 MLOAD +1030 DUP1 +1031 DUP4 +1032 SUB +1033 DUP2 +1034 PUSH1 0x00 +1036 DUP8 +1037 GAS +1038 CALL +1039 SWAP3 +1040 POP +1041 POP +1042 POP +1043 POP +1044 POP +1045 POP +1046 JUMP +1047 STOP diff --git a/tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.graph.html b/tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.graph.html new file mode 100644 index 00000000..e2acfeee --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.graph.html @@ -0,0 +1,62 @@ + + + + Call Graph + + + + + + + + + + +

Mythril / Ethereum LASER Symbolic VM

+
+ + + \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.json b/tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.json new file mode 100644 index 00000000..4c42213f --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.json @@ -0,0 +1 @@ +{"error": null, "issues": [{"address": 626, "contract": "Unknown", "debug": "", "description": "The return value of an external call is not checked. Note that execution continue even if the called contract throws.", "function": "_function_0x141f32ff", "swc_id": "104", "title": "Unchecked CALL return value", "type": "Informational"}, {"address": 857, "contract": "Unknown", "debug": "", "description": "The return value of an external call is not checked. Note that execution continue even if the called contract throws.", "function": "_function_0x9b58bc26", "swc_id": "104", "title": "Unchecked CALL return value", "type": "Informational"}, {"address": 1038, "contract": "Unknown", "debug": "", "description": "This contract executes a message call to an address provided as a function argument. Generally, it is not recommended to call user-supplied addresses using Solidity's call() construct. Note that attackers might leverage reentrancy attacks to exploit race conditions or manipulate this contract's state.", "function": "_function_0xeea4c864", "swc_id": "107", "title": "Message call to external contract", "type": "Warning"}, {"address": 1046, "contract": "Unknown", "debug": "", "description": "The return value of an external call is not checked. Note that execution continue even if the called contract throws.", "function": "_function_0xeea4c864", "swc_id": "104", "title": "Unchecked CALL return value", "type": "Informational"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.markdown b/tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.markdown new file mode 100644 index 00000000..7208086f --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.markdown @@ -0,0 +1,45 @@ +# Analysis results for test-filename.sol + +## Unchecked CALL return value +- SWC ID: 104 +- Type: Informational +- Contract: Unknown +- Function name: `_function_0x141f32ff` +- PC address: 626 + +### Description + +The return value of an external call is not checked. Note that execution continue even if the called contract throws. + +## Unchecked CALL return value +- SWC ID: 104 +- Type: Informational +- Contract: Unknown +- Function name: `_function_0x9b58bc26` +- PC address: 857 + +### Description + +The return value of an external call is not checked. Note that execution continue even if the called contract throws. + +## Message call to external contract +- SWC ID: 107 +- Type: Warning +- Contract: Unknown +- Function name: `_function_0xeea4c864` +- PC address: 1038 + +### Description + +This contract executes a message call to an address provided as a function argument. Generally, it is not recommended to call user-supplied addresses using Solidity's call() construct. Note that attackers might leverage reentrancy attacks to exploit race conditions or manipulate this contract's state. + +## Unchecked CALL return value +- SWC ID: 104 +- Type: Informational +- Contract: Unknown +- Function name: `_function_0xeea4c864` +- PC address: 1046 + +### Description + +The return value of an external call is not checked. Note that execution continue even if the called contract throws. diff --git a/tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.text b/tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.text new file mode 100644 index 00000000..46f49440 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/kinds_of_calls.sol.o.text @@ -0,0 +1,36 @@ +==== Unchecked CALL return value ==== +SWC ID: 104 +Type: Informational +Contract: Unknown +Function name: _function_0x141f32ff +PC address: 626 +The return value of an external call is not checked. Note that execution continue even if the called contract throws. +-------------------- + +==== Unchecked CALL return value ==== +SWC ID: 104 +Type: Informational +Contract: Unknown +Function name: _function_0x9b58bc26 +PC address: 857 +The return value of an external call is not checked. Note that execution continue even if the called contract throws. +-------------------- + +==== Message call to external contract ==== +SWC ID: 107 +Type: Warning +Contract: Unknown +Function name: _function_0xeea4c864 +PC address: 1038 +This contract executes a message call to an address provided as a function argument. Generally, it is not recommended to call user-supplied addresses using Solidity's call() construct. Note that attackers might leverage reentrancy attacks to exploit race conditions or manipulate this contract's state. +-------------------- + +==== Unchecked CALL return value ==== +SWC ID: 104 +Type: Informational +Contract: Unknown +Function name: _function_0xeea4c864 +PC address: 1046 +The return value of an external call is not checked. Note that execution continue even if the called contract throws. +-------------------- + diff --git a/tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.easm b/tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.easm new file mode 100644 index 00000000..fbb53181 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.easm @@ -0,0 +1,253 @@ +0 PUSH1 0x60 +2 PUSH1 0x40 +4 MSTORE +5 PUSH1 0x04 +7 CALLDATASIZE +8 LT +9 PUSH2 0x004c +12 JUMPI +13 PUSH1 0x00 +15 CALLDATALOAD +16 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 +46 SWAP1 +47 DIV +48 PUSH4 0xffffffff +53 AND +54 DUP1 +55 PUSH4 0x27e235e3 +60 EQ +61 PUSH2 0x0051 +64 JUMPI +65 DUP1 +66 PUSH4 0x412664ae +71 EQ +72 PUSH2 0x009e +75 JUMPI +76 JUMPDEST +77 PUSH1 0x00 +79 DUP1 +80 REVERT +81 JUMPDEST +82 CALLVALUE +83 ISZERO +84 PUSH2 0x005c +87 JUMPI +88 PUSH1 0x00 +90 DUP1 +91 REVERT +92 JUMPDEST +93 PUSH2 0x0088 +96 PUSH1 0x04 +98 DUP1 +99 DUP1 +100 CALLDATALOAD +101 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +122 AND +123 SWAP1 +124 PUSH1 0x20 +126 ADD +127 SWAP1 +128 SWAP2 +129 SWAP1 +130 POP +131 POP +132 PUSH2 0x00f8 +135 JUMP +136 JUMPDEST +137 PUSH1 0x40 +139 MLOAD +140 DUP1 +141 DUP3 +142 DUP2 +143 MSTORE +144 PUSH1 0x20 +146 ADD +147 SWAP2 +148 POP +149 POP +150 PUSH1 0x40 +152 MLOAD +153 DUP1 +154 SWAP2 +155 SUB +156 SWAP1 +157 RETURN +158 JUMPDEST +159 CALLVALUE +160 ISZERO +161 PUSH2 0x00a9 +164 JUMPI +165 PUSH1 0x00 +167 DUP1 +168 REVERT +169 JUMPDEST +170 PUSH2 0x00de +173 PUSH1 0x04 +175 DUP1 +176 DUP1 +177 CALLDATALOAD +178 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +199 AND +200 SWAP1 +201 PUSH1 0x20 +203 ADD +204 SWAP1 +205 SWAP2 +206 SWAP1 +207 DUP1 +208 CALLDATALOAD +209 SWAP1 +210 PUSH1 0x20 +212 ADD +213 SWAP1 +214 SWAP2 +215 SWAP1 +216 POP +217 POP +218 PUSH2 0x0110 +221 JUMP +222 JUMPDEST +223 PUSH1 0x40 +225 MLOAD +226 DUP1 +227 DUP3 +228 ISZERO +229 ISZERO +230 ISZERO +231 ISZERO +232 DUP2 +233 MSTORE +234 PUSH1 0x20 +236 ADD +237 SWAP2 +238 POP +239 POP +240 PUSH1 0x40 +242 MLOAD +243 DUP1 +244 SWAP2 +245 SUB +246 SWAP1 +247 RETURN +248 JUMPDEST +249 PUSH1 0x00 +251 PUSH1 0x20 +253 MSTORE +254 DUP1 +255 PUSH1 0x00 +257 MSTORE +258 PUSH1 0x40 +260 PUSH1 0x00 +262 SHA3 +263 PUSH1 0x00 +265 SWAP2 +266 POP +267 SWAP1 +268 POP +269 SLOAD +270 DUP2 +271 JUMP +272 JUMPDEST +273 PUSH1 0x00 +275 DUP2 +276 PUSH1 0x00 +278 DUP1 +279 CALLER +280 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +301 AND +302 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +323 AND +324 DUP2 +325 MSTORE +326 PUSH1 0x20 +328 ADD +329 SWAP1 +330 DUP2 +331 MSTORE +332 PUSH1 0x20 +334 ADD +335 PUSH1 0x00 +337 SHA3 +338 SLOAD +339 LT +340 ISZERO +341 PUSH2 0x0161 +344 JUMPI +345 PUSH1 0x00 +347 SWAP1 +348 POP +349 PUSH2 0x01fe +352 JUMP +353 JUMPDEST +354 DUP2 +355 PUSH1 0x00 +357 DUP1 +358 CALLER +359 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +380 AND +381 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +402 AND +403 DUP2 +404 MSTORE +405 PUSH1 0x20 +407 ADD +408 SWAP1 +409 DUP2 +410 MSTORE +411 PUSH1 0x20 +413 ADD +414 PUSH1 0x00 +416 SHA3 +417 PUSH1 0x00 +419 DUP3 +420 DUP3 +421 SLOAD +422 SUB +423 SWAP3 +424 POP +425 POP +426 DUP2 +427 SWAP1 +428 SSTORE +429 POP +430 DUP2 +431 PUSH1 0x00 +433 DUP1 +434 DUP6 +435 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +456 AND +457 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +478 AND +479 DUP2 +480 MSTORE +481 PUSH1 0x20 +483 ADD +484 SWAP1 +485 DUP2 +486 MSTORE +487 PUSH1 0x20 +489 ADD +490 PUSH1 0x00 +492 SHA3 +493 PUSH1 0x00 +495 DUP3 +496 DUP3 +497 SLOAD +498 ADD +499 SWAP3 +500 POP +501 POP +502 DUP2 +503 SWAP1 +504 SSTORE +505 POP +506 PUSH1 0x00 +508 SWAP1 +509 POP +510 JUMPDEST +511 SWAP3 +512 SWAP2 +513 POP +514 POP +515 JUMP +516 STOP diff --git a/tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.graph.html b/tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.graph.html new file mode 100644 index 00000000..caca188e --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.graph.html @@ -0,0 +1,62 @@ + + + + Call Graph + + + + + + + + + + +

Mythril / Ethereum LASER Symbolic VM

+
+ + + \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.json b/tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.json new file mode 100644 index 00000000..237b1c1e --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.json @@ -0,0 +1 @@ +{"error": null, "issues": [], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.markdown b/tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.markdown new file mode 100644 index 00000000..321484fd --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.markdown @@ -0,0 +1,3 @@ +# Analysis results for None + +The analysis was completed successfully. No issues were detected. diff --git a/tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.text b/tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.text new file mode 100644 index 00000000..729320d8 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/metacoin.sol.o.text @@ -0,0 +1 @@ +The analysis was completed successfully. No issues were detected. diff --git a/tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.easm b/tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.easm new file mode 100644 index 00000000..e83ace06 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.easm @@ -0,0 +1,77 @@ +0 PUSH1 0x60 +2 PUSH1 0x40 +4 MSTORE +5 PUSH1 0x04 +7 CALLDATASIZE +8 LT +9 PUSH1 0x3f +11 JUMPI +12 PUSH1 0x00 +14 CALLDATALOAD +15 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 +45 SWAP1 +46 DIV +47 PUSH4 0xffffffff +52 AND +53 DUP1 +54 PUSH4 0x8a4068dd +59 EQ +60 PUSH1 0x44 +62 JUMPI +63 JUMPDEST +64 PUSH1 0x00 +66 DUP1 +67 REVERT +68 JUMPDEST +69 CALLVALUE +70 ISZERO +71 PUSH1 0x4e +73 JUMPI +74 PUSH1 0x00 +76 DUP1 +77 REVERT +78 JUMPDEST +79 PUSH1 0x54 +81 PUSH1 0x56 +83 JUMP +84 JUMPDEST +85 STOP +86 JUMPDEST +87 CALLER +88 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +109 AND +110 PUSH2 0x08fc +113 PUSH8 0x1bc16d674ec80000 +122 SWAP1 +123 DUP2 +124 ISZERO +125 MUL +126 SWAP1 +127 PUSH1 0x40 +129 MLOAD +130 PUSH1 0x00 +132 PUSH1 0x40 +134 MLOAD +135 DUP1 +136 DUP4 +137 SUB +138 DUP2 +139 DUP6 +140 DUP9 +141 DUP9 +142 CALL +143 SWAP4 +144 POP +145 POP +146 POP +147 POP +148 ISZERO +149 ISZERO +150 PUSH1 0x9d +152 JUMPI +153 PUSH1 0x00 +155 DUP1 +156 REVERT +157 JUMPDEST +158 JUMP +159 STOP diff --git a/tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.graph.html b/tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.graph.html new file mode 100644 index 00000000..953021af --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.graph.html @@ -0,0 +1,62 @@ + + + + Call Graph + + + + + + + + + + +

Mythril / Ethereum LASER Symbolic VM

+
+ + + \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.json b/tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.json new file mode 100644 index 00000000..5dff6426 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.json @@ -0,0 +1 @@ +{"error": null, "issues": [{"address": 142, "contract": "Unknown", "debug": "", "description": "A non-zero amount of Ether is sent to a user-supplied address. The target address is msg.sender.\nIt seems that this function can be called without restrictions.", "function": "_function_0x8a4068dd", "swc_id": "105", "title": "Ether send", "type": "Warning"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.markdown b/tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.markdown new file mode 100644 index 00000000..8817ccea --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.markdown @@ -0,0 +1,13 @@ +# Analysis results for test-filename.sol + +## Ether send +- SWC ID: 105 +- Type: Warning +- Contract: Unknown +- Function name: `_function_0x8a4068dd` +- PC address: 142 + +### Description + +A non-zero amount of Ether is sent to a user-supplied address. The target address is msg.sender. +It seems that this function can be called without restrictions. diff --git a/tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.text b/tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.text new file mode 100644 index 00000000..ac727e59 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/multi_contracts.sol.o.text @@ -0,0 +1,10 @@ +==== Ether send ==== +SWC ID: 105 +Type: Warning +Contract: Unknown +Function name: _function_0x8a4068dd +PC address: 142 +A non-zero amount of Ether is sent to a user-supplied address. The target address is msg.sender. +It seems that this function can be called without restrictions. +-------------------- + diff --git a/tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.easm b/tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.easm new file mode 100644 index 00000000..555d5ba3 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.easm @@ -0,0 +1,167 @@ +0 PUSH1 0x80 +2 PUSH1 0x40 +4 MSTORE +5 PUSH1 0x04 +7 CALLDATASIZE +8 LT +9 PUSH2 0x0041 +12 JUMPI +13 PUSH1 0x00 +15 CALLDATALOAD +16 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 +46 SWAP1 +47 DIV +48 PUSH4 0xffffffff +53 AND +54 DUP1 +55 PUSH4 0x24ff38a2 +60 EQ +61 PUSH2 0x0046 +64 JUMPI +65 JUMPDEST +66 PUSH1 0x00 +68 DUP1 +69 REVERT +70 JUMPDEST +71 CALLVALUE +72 DUP1 +73 ISZERO +74 PUSH2 0x0052 +77 JUMPI +78 PUSH1 0x00 +80 DUP1 +81 REVERT +82 JUMPDEST +83 POP +84 PUSH2 0x005b +87 PUSH2 0x00d6 +90 JUMP +91 JUMPDEST +92 PUSH1 0x40 +94 MLOAD +95 DUP1 +96 DUP1 +97 PUSH1 0x20 +99 ADD +100 DUP3 +101 DUP2 +102 SUB +103 DUP3 +104 MSTORE +105 DUP4 +106 DUP2 +107 DUP2 +108 MLOAD +109 DUP2 +110 MSTORE +111 PUSH1 0x20 +113 ADD +114 SWAP2 +115 POP +116 DUP1 +117 MLOAD +118 SWAP1 +119 PUSH1 0x20 +121 ADD +122 SWAP1 +123 DUP1 +124 DUP4 +125 DUP4 +126 PUSH1 0x00 +128 JUMPDEST +129 DUP4 +130 DUP2 +131 LT +132 ISZERO +133 PUSH2 0x009b +136 JUMPI +137 DUP1 +138 DUP3 +139 ADD +140 MLOAD +141 DUP2 +142 DUP5 +143 ADD +144 MSTORE +145 PUSH1 0x20 +147 DUP2 +148 ADD +149 SWAP1 +150 POP +151 PUSH2 0x0080 +154 JUMP +155 JUMPDEST +156 POP +157 POP +158 POP +159 POP +160 SWAP1 +161 POP +162 SWAP1 +163 DUP2 +164 ADD +165 SWAP1 +166 PUSH1 0x1f +168 AND +169 DUP1 +170 ISZERO +171 PUSH2 0x00c8 +174 JUMPI +175 DUP1 +176 DUP3 +177 SUB +178 DUP1 +179 MLOAD +180 PUSH1 0x01 +182 DUP4 +183 PUSH1 0x20 +185 SUB +186 PUSH2 0x0100 +189 EXP +190 SUB +191 NOT +192 AND +193 DUP2 +194 MSTORE +195 PUSH1 0x20 +197 ADD +198 SWAP2 +199 POP +200 JUMPDEST +201 POP +202 SWAP3 +203 POP +204 POP +205 POP +206 PUSH1 0x40 +208 MLOAD +209 DUP1 +210 SWAP2 +211 SUB +212 SWAP1 +213 RETURN +214 JUMPDEST +215 PUSH1 0x60 +217 PUSH1 0x40 +219 DUP1 +220 MLOAD +221 SWAP1 +222 DUP2 +223 ADD +224 PUSH1 0x40 +226 MSTORE +227 DUP1 +228 PUSH1 0x17 +230 DUP2 +231 MSTORE +232 PUSH1 0x20 +234 ADD +235 PUSH32 0xd0a5d18dd0bbd0bbd0bed18320d092d0bed180d0bbd0b4000000000000000000 +268 DUP2 +269 MSTORE +270 POP +271 SWAP1 +272 POP +273 SWAP1 +274 JUMP +275 STOP diff --git a/tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.graph.html b/tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.graph.html new file mode 100644 index 00000000..68d83005 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.graph.html @@ -0,0 +1,62 @@ + + + + Call Graph + + + + + + + + + + +

Mythril / Ethereum LASER Symbolic VM

+
+ + + \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.json b/tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.json new file mode 100644 index 00000000..237b1c1e --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.json @@ -0,0 +1 @@ +{"error": null, "issues": [], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.markdown b/tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.markdown new file mode 100644 index 00000000..321484fd --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.markdown @@ -0,0 +1,3 @@ +# Analysis results for None + +The analysis was completed successfully. No issues were detected. diff --git a/tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.text b/tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.text new file mode 100644 index 00000000..729320d8 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/nonascii.sol.o.text @@ -0,0 +1 @@ +The analysis was completed successfully. No issues were detected. diff --git a/tests/testdata/outputs_expected/outputs_current/origin.sol.o.easm b/tests/testdata/outputs_expected/outputs_current/origin.sol.o.easm new file mode 100644 index 00000000..e1bffe10 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/origin.sol.o.easm @@ -0,0 +1,168 @@ +0 PUSH1 0x60 +2 PUSH1 0x40 +4 MSTORE +5 PUSH1 0x04 +7 CALLDATASIZE +8 LT +9 PUSH2 0x004c +12 JUMPI +13 PUSH1 0x00 +15 CALLDATALOAD +16 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 +46 SWAP1 +47 DIV +48 PUSH4 0xffffffff +53 AND +54 DUP1 +55 PUSH4 0x8da5cb5b +60 EQ +61 PUSH2 0x0051 +64 JUMPI +65 DUP1 +66 PUSH4 0xf2fde38b +71 EQ +72 PUSH2 0x00a6 +75 JUMPI +76 JUMPDEST +77 PUSH1 0x00 +79 DUP1 +80 REVERT +81 JUMPDEST +82 CALLVALUE +83 ISZERO +84 PUSH2 0x005c +87 JUMPI +88 PUSH1 0x00 +90 DUP1 +91 REVERT +92 JUMPDEST +93 PUSH2 0x0064 +96 PUSH2 0x00df +99 JUMP +100 JUMPDEST +101 PUSH1 0x40 +103 MLOAD +104 DUP1 +105 DUP3 +106 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +127 AND +128 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +149 AND +150 DUP2 +151 MSTORE +152 PUSH1 0x20 +154 ADD +155 SWAP2 +156 POP +157 POP +158 PUSH1 0x40 +160 MLOAD +161 DUP1 +162 SWAP2 +163 SUB +164 SWAP1 +165 RETURN +166 JUMPDEST +167 CALLVALUE +168 ISZERO +169 PUSH2 0x00b1 +172 JUMPI +173 PUSH1 0x00 +175 DUP1 +176 REVERT +177 JUMPDEST +178 PUSH2 0x00dd +181 PUSH1 0x04 +183 DUP1 +184 DUP1 +185 CALLDATALOAD +186 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +207 AND +208 SWAP1 +209 PUSH1 0x20 +211 ADD +212 SWAP1 +213 SWAP2 +214 SWAP1 +215 POP +216 POP +217 PUSH2 0x0104 +220 JUMP +221 JUMPDEST +222 STOP +223 JUMPDEST +224 PUSH1 0x00 +226 DUP1 +227 SWAP1 +228 SLOAD +229 SWAP1 +230 PUSH2 0x0100 +233 EXP +234 SWAP1 +235 DIV +236 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +257 AND +258 DUP2 +259 JUMP +260 JUMPDEST +261 PUSH1 0x00 +263 DUP1 +264 SWAP1 +265 SLOAD +266 SWAP1 +267 PUSH2 0x0100 +270 EXP +271 SWAP1 +272 DIV +273 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +294 AND +295 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +316 AND +317 ORIGIN +318 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +339 AND +340 EQ +341 ISZERO +342 ISZERO +343 PUSH2 0x015f +346 JUMPI +347 PUSH1 0x00 +349 DUP1 +350 REVERT +351 JUMPDEST +352 PUSH1 0x00 +354 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +375 AND +376 DUP2 +377 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +398 AND +399 EQ +400 ISZERO +401 ISZERO +402 PUSH2 0x01d6 +405 JUMPI +406 DUP1 +407 PUSH1 0x00 +409 DUP1 +410 PUSH2 0x0100 +413 EXP +414 DUP2 +415 SLOAD +416 DUP2 +417 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +438 MUL +439 NOT +440 AND +441 SWAP1 +442 DUP4 +443 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +464 AND +465 MUL +466 OR +467 SWAP1 +468 SSTORE +469 POP +470 JUMPDEST +471 POP +472 JUMP +473 STOP diff --git a/tests/testdata/outputs_expected/outputs_current/origin.sol.o.graph.html b/tests/testdata/outputs_expected/outputs_current/origin.sol.o.graph.html new file mode 100644 index 00000000..e44a58df --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/origin.sol.o.graph.html @@ -0,0 +1,62 @@ + + + + Call Graph + + + + + + + + + + +

Mythril / Ethereum LASER Symbolic VM

+
+ + + \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/origin.sol.o.json b/tests/testdata/outputs_expected/outputs_current/origin.sol.o.json new file mode 100644 index 00000000..0e924831 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/origin.sol.o.json @@ -0,0 +1 @@ +{"error": null, "issues": [{"address": 317, "contract": "Unknown", "debug": "", "description": "The function `transferOwnership(address)` retrieves the transaction origin (tx.origin) using the ORIGIN opcode. Use msg.sender instead.\nSee also: https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin", "function": "transferOwnership(address)", "swc_id": "115", "title": "Use of tx.origin", "type": "Warning"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/origin.sol.o.markdown b/tests/testdata/outputs_expected/outputs_current/origin.sol.o.markdown new file mode 100644 index 00000000..1e9d6d8b --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/origin.sol.o.markdown @@ -0,0 +1,13 @@ +# Analysis results for test-filename.sol + +## Use of tx.origin +- SWC ID: 115 +- Type: Warning +- Contract: Unknown +- Function name: `transferOwnership(address)` +- PC address: 317 + +### Description + +The function `transferOwnership(address)` retrieves the transaction origin (tx.origin) using the ORIGIN opcode. Use msg.sender instead. +See also: https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin diff --git a/tests/testdata/outputs_expected/outputs_current/origin.sol.o.text b/tests/testdata/outputs_expected/outputs_current/origin.sol.o.text new file mode 100644 index 00000000..b71422be --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/origin.sol.o.text @@ -0,0 +1,10 @@ +==== Use of tx.origin ==== +SWC ID: 115 +Type: Warning +Contract: Unknown +Function name: transferOwnership(address) +PC address: 317 +The function `transferOwnership(address)` retrieves the transaction origin (tx.origin) using the ORIGIN opcode. Use msg.sender instead. +See also: https://solidity.readthedocs.io/en/develop/security-considerations.html#tx-origin +-------------------- + diff --git a/tests/testdata/outputs_expected/outputs_current/overflow.sol.o.easm b/tests/testdata/outputs_expected/outputs_current/overflow.sol.o.easm new file mode 100644 index 00000000..b0763999 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/overflow.sol.o.easm @@ -0,0 +1,388 @@ +0 PUSH1 0x60 +2 PUSH1 0x40 +4 MSTORE +5 PUSH1 0x04 +7 CALLDATASIZE +8 LT +9 PUSH2 0x0062 +12 JUMPI +13 PUSH1 0x00 +15 CALLDATALOAD +16 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 +46 SWAP1 +47 DIV +48 PUSH4 0xffffffff +53 AND +54 DUP1 +55 PUSH4 0x18160ddd +60 EQ +61 PUSH2 0x0067 +64 JUMPI +65 DUP1 +66 PUSH4 0x6241bfd1 +71 EQ +72 PUSH2 0x0090 +75 JUMPI +76 DUP1 +77 PUSH4 0x70a08231 +82 EQ +83 PUSH2 0x00b3 +86 JUMPI +87 DUP1 +88 PUSH4 0xa3210e87 +93 EQ +94 PUSH2 0x0100 +97 JUMPI +98 JUMPDEST +99 PUSH1 0x00 +101 DUP1 +102 REVERT +103 JUMPDEST +104 CALLVALUE +105 ISZERO +106 PUSH2 0x0072 +109 JUMPI +110 PUSH1 0x00 +112 DUP1 +113 REVERT +114 JUMPDEST +115 PUSH2 0x007a +118 PUSH2 0x015a +121 JUMP +122 JUMPDEST +123 PUSH1 0x40 +125 MLOAD +126 DUP1 +127 DUP3 +128 DUP2 +129 MSTORE +130 PUSH1 0x20 +132 ADD +133 SWAP2 +134 POP +135 POP +136 PUSH1 0x40 +138 MLOAD +139 DUP1 +140 SWAP2 +141 SUB +142 SWAP1 +143 RETURN +144 JUMPDEST +145 CALLVALUE +146 ISZERO +147 PUSH2 0x009b +150 JUMPI +151 PUSH1 0x00 +153 DUP1 +154 REVERT +155 JUMPDEST +156 PUSH2 0x00b1 +159 PUSH1 0x04 +161 DUP1 +162 DUP1 +163 CALLDATALOAD +164 SWAP1 +165 PUSH1 0x20 +167 ADD +168 SWAP1 +169 SWAP2 +170 SWAP1 +171 POP +172 POP +173 PUSH2 0x0160 +176 JUMP +177 JUMPDEST +178 STOP +179 JUMPDEST +180 CALLVALUE +181 ISZERO +182 PUSH2 0x00be +185 JUMPI +186 PUSH1 0x00 +188 DUP1 +189 REVERT +190 JUMPDEST +191 PUSH2 0x00ea +194 PUSH1 0x04 +196 DUP1 +197 DUP1 +198 CALLDATALOAD +199 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +220 AND +221 SWAP1 +222 PUSH1 0x20 +224 ADD +225 SWAP1 +226 SWAP2 +227 SWAP1 +228 POP +229 POP +230 PUSH2 0x01ab +233 JUMP +234 JUMPDEST +235 PUSH1 0x40 +237 MLOAD +238 DUP1 +239 DUP3 +240 DUP2 +241 MSTORE +242 PUSH1 0x20 +244 ADD +245 SWAP2 +246 POP +247 POP +248 PUSH1 0x40 +250 MLOAD +251 DUP1 +252 SWAP2 +253 SUB +254 SWAP1 +255 RETURN +256 JUMPDEST +257 CALLVALUE +258 ISZERO +259 PUSH2 0x010b +262 JUMPI +263 PUSH1 0x00 +265 DUP1 +266 REVERT +267 JUMPDEST +268 PUSH2 0x0140 +271 PUSH1 0x04 +273 DUP1 +274 DUP1 +275 CALLDATALOAD +276 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +297 AND +298 SWAP1 +299 PUSH1 0x20 +301 ADD +302 SWAP1 +303 SWAP2 +304 SWAP1 +305 DUP1 +306 CALLDATALOAD +307 SWAP1 +308 PUSH1 0x20 +310 ADD +311 SWAP1 +312 SWAP2 +313 SWAP1 +314 POP +315 POP +316 PUSH2 0x01f3 +319 JUMP +320 JUMPDEST +321 PUSH1 0x40 +323 MLOAD +324 DUP1 +325 DUP3 +326 ISZERO +327 ISZERO +328 ISZERO +329 ISZERO +330 DUP2 +331 MSTORE +332 PUSH1 0x20 +334 ADD +335 SWAP2 +336 POP +337 POP +338 PUSH1 0x40 +340 MLOAD +341 DUP1 +342 SWAP2 +343 SUB +344 SWAP1 +345 RETURN +346 JUMPDEST +347 PUSH1 0x01 +349 SLOAD +350 DUP2 +351 JUMP +352 JUMPDEST +353 DUP1 +354 PUSH1 0x01 +356 DUP2 +357 SWAP1 +358 SSTORE +359 PUSH1 0x00 +361 DUP1 +362 CALLER +363 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +384 AND +385 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +406 AND +407 DUP2 +408 MSTORE +409 PUSH1 0x20 +411 ADD +412 SWAP1 +413 DUP2 +414 MSTORE +415 PUSH1 0x20 +417 ADD +418 PUSH1 0x00 +420 SHA3 +421 DUP2 +422 SWAP1 +423 SSTORE +424 POP +425 POP +426 JUMP +427 JUMPDEST +428 PUSH1 0x00 +430 DUP1 +431 PUSH1 0x00 +433 DUP4 +434 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +455 AND +456 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +477 AND +478 DUP2 +479 MSTORE +480 PUSH1 0x20 +482 ADD +483 SWAP1 +484 DUP2 +485 MSTORE +486 PUSH1 0x20 +488 ADD +489 PUSH1 0x00 +491 SHA3 +492 SLOAD +493 SWAP1 +494 POP +495 SWAP2 +496 SWAP1 +497 POP +498 JUMP +499 JUMPDEST +500 PUSH1 0x00 +502 DUP1 +503 DUP3 +504 PUSH1 0x00 +506 DUP1 +507 CALLER +508 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +529 AND +530 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +551 AND +552 DUP2 +553 MSTORE +554 PUSH1 0x20 +556 ADD +557 SWAP1 +558 DUP2 +559 MSTORE +560 PUSH1 0x20 +562 ADD +563 PUSH1 0x00 +565 SHA3 +566 SLOAD +567 SUB +568 LT +569 ISZERO +570 ISZERO +571 ISZERO +572 PUSH2 0x0244 +575 JUMPI +576 PUSH1 0x00 +578 DUP1 +579 REVERT +580 JUMPDEST +581 DUP2 +582 PUSH1 0x00 +584 DUP1 +585 CALLER +586 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +607 AND +608 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +629 AND +630 DUP2 +631 MSTORE +632 PUSH1 0x20 +634 ADD +635 SWAP1 +636 DUP2 +637 MSTORE +638 PUSH1 0x20 +640 ADD +641 PUSH1 0x00 +643 SHA3 +644 PUSH1 0x00 +646 DUP3 +647 DUP3 +648 SLOAD +649 SUB +650 SWAP3 +651 POP +652 POP +653 DUP2 +654 SWAP1 +655 SSTORE +656 POP +657 DUP2 +658 PUSH1 0x00 +660 DUP1 +661 DUP6 +662 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +683 AND +684 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +705 AND +706 DUP2 +707 MSTORE +708 PUSH1 0x20 +710 ADD +711 SWAP1 +712 DUP2 +713 MSTORE +714 PUSH1 0x20 +716 ADD +717 PUSH1 0x00 +719 SHA3 +720 PUSH1 0x00 +722 DUP3 +723 DUP3 +724 SLOAD +725 ADD +726 SWAP3 +727 POP +728 POP +729 DUP2 +730 SWAP1 +731 SSTORE +732 POP +733 PUSH1 0x02 +735 PUSH1 0x00 +737 DUP1 +738 DUP6 +739 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +760 AND +761 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +782 AND +783 DUP2 +784 MSTORE +785 PUSH1 0x20 +787 ADD +788 SWAP1 +789 DUP2 +790 MSTORE +791 PUSH1 0x20 +793 ADD +794 PUSH1 0x00 +796 SHA3 +797 DUP2 +798 SWAP1 +799 SSTORE +800 POP +801 PUSH1 0x01 +803 SWAP1 +804 POP +805 SWAP3 +806 SWAP2 +807 POP +808 POP +809 JUMP +810 STOP diff --git a/tests/testdata/outputs_expected/outputs_current/overflow.sol.o.graph.html b/tests/testdata/outputs_expected/outputs_current/overflow.sol.o.graph.html new file mode 100644 index 00000000..ed71dd6e --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/overflow.sol.o.graph.html @@ -0,0 +1,62 @@ + + + + Call Graph + + + + + + + + + + +

Mythril / Ethereum LASER Symbolic VM

+
+ + + \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/overflow.sol.o.json b/tests/testdata/outputs_expected/outputs_current/overflow.sol.o.json new file mode 100644 index 00000000..fb92acaf --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/overflow.sol.o.json @@ -0,0 +1 @@ +{"error": null, "issues": [{"address": 567, "contract": "Unknown", "debug": "", "description": "The substraction can result in an integer underflow.\n", "function": "sendeth(address,uint256)", "swc_id": "101", "title": "Integer Underflow", "type": "Warning"}, {"address": 649, "contract": "Unknown", "debug": "", "description": "The substraction can result in an integer underflow.\n", "function": "sendeth(address,uint256)", "swc_id": "101", "title": "Integer Underflow", "type": "Warning"}, {"address": 725, "contract": "Unknown", "debug": "", "description": "The arithmetic operation can result in integer overflow.\n", "function": "sendeth(address,uint256)", "swc_id": "101", "title": "Integer Overflow", "type": "Warning"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/overflow.sol.o.markdown b/tests/testdata/outputs_expected/outputs_current/overflow.sol.o.markdown new file mode 100644 index 00000000..4f86063c --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/overflow.sol.o.markdown @@ -0,0 +1,34 @@ +# Analysis results for test-filename.sol + +## Integer Underflow +- SWC ID: 101 +- Type: Warning +- Contract: Unknown +- Function name: `sendeth(address,uint256)` +- PC address: 567 + +### Description + +The substraction can result in an integer underflow. + +## Integer Underflow +- SWC ID: 101 +- Type: Warning +- Contract: Unknown +- Function name: `sendeth(address,uint256)` +- PC address: 649 + +### Description + +The substraction can result in an integer underflow. + +## Integer Overflow +- SWC ID: 101 +- Type: Warning +- Contract: Unknown +- Function name: `sendeth(address,uint256)` +- PC address: 725 + +### Description + +The arithmetic operation can result in integer overflow. diff --git a/tests/testdata/outputs_expected/outputs_current/overflow.sol.o.text b/tests/testdata/outputs_expected/outputs_current/overflow.sol.o.text new file mode 100644 index 00000000..acdce40b --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/overflow.sol.o.text @@ -0,0 +1,30 @@ +==== Integer Underflow ==== +SWC ID: 101 +Type: Warning +Contract: Unknown +Function name: sendeth(address,uint256) +PC address: 567 +The substraction can result in an integer underflow. + +-------------------- + +==== Integer Underflow ==== +SWC ID: 101 +Type: Warning +Contract: Unknown +Function name: sendeth(address,uint256) +PC address: 649 +The substraction can result in an integer underflow. + +-------------------- + +==== Integer Overflow ==== +SWC ID: 101 +Type: Warning +Contract: Unknown +Function name: sendeth(address,uint256) +PC address: 725 +The arithmetic operation can result in integer overflow. + +-------------------- + diff --git a/tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.easm b/tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.easm new file mode 100644 index 00000000..13a426cc --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.easm @@ -0,0 +1,129 @@ +0 PUSH1 0x60 +2 PUSH1 0x40 +4 MSTORE +5 PUSH1 0x04 +7 CALLDATASIZE +8 LT +9 PUSH2 0x004c +12 JUMPI +13 PUSH1 0x00 +15 CALLDATALOAD +16 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 +46 SWAP1 +47 DIV +48 PUSH4 0xffffffff +53 AND +54 DUP1 +55 PUSH4 0x633ab5e0 +60 EQ +61 PUSH2 0x0051 +64 JUMPI +65 DUP1 +66 PUSH4 0xe3bea282 +71 EQ +72 PUSH2 0x0066 +75 JUMPI +76 JUMPDEST +77 PUSH1 0x00 +79 DUP1 +80 REVERT +81 JUMPDEST +82 CALLVALUE +83 ISZERO +84 PUSH2 0x005c +87 JUMPI +88 PUSH1 0x00 +90 DUP1 +91 REVERT +92 JUMPDEST +93 PUSH2 0x0064 +96 PUSH2 0x007b +99 JUMP +100 JUMPDEST +101 STOP +102 JUMPDEST +103 CALLVALUE +104 ISZERO +105 PUSH2 0x0071 +108 JUMPI +109 PUSH1 0x00 +111 DUP1 +112 REVERT +113 JUMPDEST +114 PUSH2 0x0079 +117 PUSH2 0x00d4 +120 JUMP +121 JUMPDEST +122 STOP +123 JUMPDEST +124 PUSH1 0x00 +126 DUP1 +127 SWAP1 +128 SLOAD +129 SWAP1 +130 PUSH2 0x0100 +133 EXP +134 SWAP1 +135 DIV +136 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +157 AND +158 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +179 AND +180 PUSH1 0x40 +182 MLOAD +183 PUSH1 0x00 +185 PUSH1 0x40 +187 MLOAD +188 DUP1 +189 DUP4 +190 SUB +191 DUP2 +192 PUSH1 0x00 +194 DUP7 +195 GAS +196 CALL +197 SWAP2 +198 POP +199 POP +200 ISZERO +201 ISZERO +202 PUSH2 0x00d2 +205 JUMPI +206 PUSH1 0x00 +208 DUP1 +209 REVERT +210 JUMPDEST +211 JUMP +212 JUMPDEST +213 PUSH1 0x00 +215 DUP1 +216 SWAP1 +217 SLOAD +218 SWAP1 +219 PUSH2 0x0100 +222 EXP +223 SWAP1 +224 DIV +225 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +246 AND +247 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +268 AND +269 PUSH1 0x40 +271 MLOAD +272 PUSH1 0x00 +274 PUSH1 0x40 +276 MLOAD +277 DUP1 +278 DUP4 +279 SUB +280 DUP2 +281 PUSH1 0x00 +283 DUP7 +284 GAS +285 CALL +286 SWAP2 +287 POP +288 POP +289 POP +290 JUMP +291 STOP diff --git a/tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.graph.html b/tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.graph.html new file mode 100644 index 00000000..a63a268a --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.graph.html @@ -0,0 +1,62 @@ + + + + Call Graph + + + + + + + + + + +

Mythril / Ethereum LASER Symbolic VM

+
+ + + \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.json b/tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.json new file mode 100644 index 00000000..81ee3cb3 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.json @@ -0,0 +1 @@ +{"error": null, "issues": [{"address": 196, "contract": "Unknown", "debug": "", "description": "This contract executes a message call to to another contract. Make sure that the called contract is trusted and does not execute user-supplied code.", "function": "_function_0x633ab5e0", "swc_id": "107", "title": "Message call to external contract", "type": "Informational"}, {"address": 285, "contract": "Unknown", "debug": "", "description": "This contract executes a message call to to another contract. Make sure that the called contract is trusted and does not execute user-supplied code.", "function": "_function_0xe3bea282", "swc_id": "107", "title": "Message call to external contract", "type": "Informational"}, {"address": 290, "contract": "Unknown", "debug": "", "description": "The return value of an external call is not checked. Note that execution continue even if the called contract throws.", "function": "_function_0xe3bea282", "swc_id": "104", "title": "Unchecked CALL return value", "type": "Informational"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.markdown b/tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.markdown new file mode 100644 index 00000000..f3a058bd --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.markdown @@ -0,0 +1,34 @@ +# Analysis results for test-filename.sol + +## Message call to external contract +- SWC ID: 107 +- Type: Informational +- Contract: Unknown +- Function name: `_function_0x633ab5e0` +- PC address: 196 + +### Description + +This contract executes a message call to to another contract. Make sure that the called contract is trusted and does not execute user-supplied code. + +## Message call to external contract +- SWC ID: 107 +- Type: Informational +- Contract: Unknown +- Function name: `_function_0xe3bea282` +- PC address: 285 + +### Description + +This contract executes a message call to to another contract. Make sure that the called contract is trusted and does not execute user-supplied code. + +## Unchecked CALL return value +- SWC ID: 104 +- Type: Informational +- Contract: Unknown +- Function name: `_function_0xe3bea282` +- PC address: 290 + +### Description + +The return value of an external call is not checked. Note that execution continue even if the called contract throws. diff --git a/tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.text b/tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.text new file mode 100644 index 00000000..2a8b1470 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/returnvalue.sol.o.text @@ -0,0 +1,27 @@ +==== Message call to external contract ==== +SWC ID: 107 +Type: Informational +Contract: Unknown +Function name: _function_0x633ab5e0 +PC address: 196 +This contract executes a message call to to another contract. Make sure that the called contract is trusted and does not execute user-supplied code. +-------------------- + +==== Message call to external contract ==== +SWC ID: 107 +Type: Informational +Contract: Unknown +Function name: _function_0xe3bea282 +PC address: 285 +This contract executes a message call to to another contract. Make sure that the called contract is trusted and does not execute user-supplied code. +-------------------- + +==== Unchecked CALL return value ==== +SWC ID: 104 +Type: Informational +Contract: Unknown +Function name: _function_0xe3bea282 +PC address: 290 +The return value of an external call is not checked. Note that execution continue even if the called contract throws. +-------------------- + diff --git a/tests/testdata/outputs_expected/outputs_current/suicide.sol.o.easm b/tests/testdata/outputs_expected/outputs_current/suicide.sol.o.easm new file mode 100644 index 00000000..892e7787 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/suicide.sol.o.easm @@ -0,0 +1,58 @@ +0 PUSH1 0x60 +2 PUSH1 0x40 +4 MSTORE +5 PUSH1 0x04 +7 CALLDATASIZE +8 LT +9 PUSH1 0x3f +11 JUMPI +12 PUSH1 0x00 +14 CALLDATALOAD +15 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 +45 SWAP1 +46 DIV +47 PUSH4 0xffffffff +52 AND +53 DUP1 +54 PUSH4 0xcbf0b0c0 +59 EQ +60 PUSH1 0x44 +62 JUMPI +63 JUMPDEST +64 PUSH1 0x00 +66 DUP1 +67 REVERT +68 JUMPDEST +69 CALLVALUE +70 ISZERO +71 PUSH1 0x4e +73 JUMPI +74 PUSH1 0x00 +76 DUP1 +77 REVERT +78 JUMPDEST +79 PUSH1 0x78 +81 PUSH1 0x04 +83 DUP1 +84 DUP1 +85 CALLDATALOAD +86 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +107 AND +108 SWAP1 +109 PUSH1 0x20 +111 ADD +112 SWAP1 +113 SWAP2 +114 SWAP1 +115 POP +116 POP +117 PUSH1 0x7a +119 JUMP +120 JUMPDEST +121 STOP +122 JUMPDEST +123 DUP1 +124 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +145 AND +146 SUICIDE +147 STOP diff --git a/tests/testdata/outputs_expected/outputs_current/suicide.sol.o.graph.html b/tests/testdata/outputs_expected/outputs_current/suicide.sol.o.graph.html new file mode 100644 index 00000000..e1797023 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/suicide.sol.o.graph.html @@ -0,0 +1,62 @@ + + + + Call Graph + + + + + + + + + + +

Mythril / Ethereum LASER Symbolic VM

+
+ + + \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/suicide.sol.o.json b/tests/testdata/outputs_expected/outputs_current/suicide.sol.o.json new file mode 100644 index 00000000..4b9b6b83 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/suicide.sol.o.json @@ -0,0 +1 @@ +{"error": null, "issues": [{"address": 146, "contract": "Unknown", "debug": "", "description": "A reachable SUICIDE instruction was detected. The remaining Ether is sent to an address provided as a function argument.\n", "function": "_function_0xcbf0b0c0", "swc_id": "106", "title": "Unchecked SUICIDE", "type": "Warning"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/suicide.sol.o.markdown b/tests/testdata/outputs_expected/outputs_current/suicide.sol.o.markdown new file mode 100644 index 00000000..6d24f84d --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/suicide.sol.o.markdown @@ -0,0 +1,12 @@ +# Analysis results for test-filename.sol + +## Unchecked SUICIDE +- SWC ID: 106 +- Type: Warning +- Contract: Unknown +- Function name: `_function_0xcbf0b0c0` +- PC address: 146 + +### Description + +A reachable SUICIDE instruction was detected. The remaining Ether is sent to an address provided as a function argument. diff --git a/tests/testdata/outputs_expected/outputs_current/suicide.sol.o.text b/tests/testdata/outputs_expected/outputs_current/suicide.sol.o.text new file mode 100644 index 00000000..138bf06b --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/suicide.sol.o.text @@ -0,0 +1,10 @@ +==== Unchecked SUICIDE ==== +SWC ID: 106 +Type: Warning +Contract: Unknown +Function name: _function_0xcbf0b0c0 +PC address: 146 +A reachable SUICIDE instruction was detected. The remaining Ether is sent to an address provided as a function argument. + +-------------------- + diff --git a/tests/testdata/outputs_expected/outputs_current/underflow.sol.o.easm b/tests/testdata/outputs_expected/outputs_current/underflow.sol.o.easm new file mode 100644 index 00000000..0ed8f651 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/underflow.sol.o.easm @@ -0,0 +1,365 @@ +0 PUSH1 0x60 +2 PUSH1 0x40 +4 MSTORE +5 PUSH1 0x04 +7 CALLDATASIZE +8 LT +9 PUSH2 0x0062 +12 JUMPI +13 PUSH1 0x00 +15 CALLDATALOAD +16 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 +46 SWAP1 +47 DIV +48 PUSH4 0xffffffff +53 AND +54 DUP1 +55 PUSH4 0x18160ddd +60 EQ +61 PUSH2 0x0067 +64 JUMPI +65 DUP1 +66 PUSH4 0x6241bfd1 +71 EQ +72 PUSH2 0x0090 +75 JUMPI +76 DUP1 +77 PUSH4 0x70a08231 +82 EQ +83 PUSH2 0x00b3 +86 JUMPI +87 DUP1 +88 PUSH4 0xa3210e87 +93 EQ +94 PUSH2 0x0100 +97 JUMPI +98 JUMPDEST +99 PUSH1 0x00 +101 DUP1 +102 REVERT +103 JUMPDEST +104 CALLVALUE +105 ISZERO +106 PUSH2 0x0072 +109 JUMPI +110 PUSH1 0x00 +112 DUP1 +113 REVERT +114 JUMPDEST +115 PUSH2 0x007a +118 PUSH2 0x015a +121 JUMP +122 JUMPDEST +123 PUSH1 0x40 +125 MLOAD +126 DUP1 +127 DUP3 +128 DUP2 +129 MSTORE +130 PUSH1 0x20 +132 ADD +133 SWAP2 +134 POP +135 POP +136 PUSH1 0x40 +138 MLOAD +139 DUP1 +140 SWAP2 +141 SUB +142 SWAP1 +143 RETURN +144 JUMPDEST +145 CALLVALUE +146 ISZERO +147 PUSH2 0x009b +150 JUMPI +151 PUSH1 0x00 +153 DUP1 +154 REVERT +155 JUMPDEST +156 PUSH2 0x00b1 +159 PUSH1 0x04 +161 DUP1 +162 DUP1 +163 CALLDATALOAD +164 SWAP1 +165 PUSH1 0x20 +167 ADD +168 SWAP1 +169 SWAP2 +170 SWAP1 +171 POP +172 POP +173 PUSH2 0x0160 +176 JUMP +177 JUMPDEST +178 STOP +179 JUMPDEST +180 CALLVALUE +181 ISZERO +182 PUSH2 0x00be +185 JUMPI +186 PUSH1 0x00 +188 DUP1 +189 REVERT +190 JUMPDEST +191 PUSH2 0x00ea +194 PUSH1 0x04 +196 DUP1 +197 DUP1 +198 CALLDATALOAD +199 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +220 AND +221 SWAP1 +222 PUSH1 0x20 +224 ADD +225 SWAP1 +226 SWAP2 +227 SWAP1 +228 POP +229 POP +230 PUSH2 0x01ab +233 JUMP +234 JUMPDEST +235 PUSH1 0x40 +237 MLOAD +238 DUP1 +239 DUP3 +240 DUP2 +241 MSTORE +242 PUSH1 0x20 +244 ADD +245 SWAP2 +246 POP +247 POP +248 PUSH1 0x40 +250 MLOAD +251 DUP1 +252 SWAP2 +253 SUB +254 SWAP1 +255 RETURN +256 JUMPDEST +257 CALLVALUE +258 ISZERO +259 PUSH2 0x010b +262 JUMPI +263 PUSH1 0x00 +265 DUP1 +266 REVERT +267 JUMPDEST +268 PUSH2 0x0140 +271 PUSH1 0x04 +273 DUP1 +274 DUP1 +275 CALLDATALOAD +276 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +297 AND +298 SWAP1 +299 PUSH1 0x20 +301 ADD +302 SWAP1 +303 SWAP2 +304 SWAP1 +305 DUP1 +306 CALLDATALOAD +307 SWAP1 +308 PUSH1 0x20 +310 ADD +311 SWAP1 +312 SWAP2 +313 SWAP1 +314 POP +315 POP +316 PUSH2 0x01f3 +319 JUMP +320 JUMPDEST +321 PUSH1 0x40 +323 MLOAD +324 DUP1 +325 DUP3 +326 ISZERO +327 ISZERO +328 ISZERO +329 ISZERO +330 DUP2 +331 MSTORE +332 PUSH1 0x20 +334 ADD +335 SWAP2 +336 POP +337 POP +338 PUSH1 0x40 +340 MLOAD +341 DUP1 +342 SWAP2 +343 SUB +344 SWAP1 +345 RETURN +346 JUMPDEST +347 PUSH1 0x01 +349 SLOAD +350 DUP2 +351 JUMP +352 JUMPDEST +353 DUP1 +354 PUSH1 0x01 +356 DUP2 +357 SWAP1 +358 SSTORE +359 PUSH1 0x00 +361 DUP1 +362 CALLER +363 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +384 AND +385 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +406 AND +407 DUP2 +408 MSTORE +409 PUSH1 0x20 +411 ADD +412 SWAP1 +413 DUP2 +414 MSTORE +415 PUSH1 0x20 +417 ADD +418 PUSH1 0x00 +420 SHA3 +421 DUP2 +422 SWAP1 +423 SSTORE +424 POP +425 POP +426 JUMP +427 JUMPDEST +428 PUSH1 0x00 +430 DUP1 +431 PUSH1 0x00 +433 DUP4 +434 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +455 AND +456 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +477 AND +478 DUP2 +479 MSTORE +480 PUSH1 0x20 +482 ADD +483 SWAP1 +484 DUP2 +485 MSTORE +486 PUSH1 0x20 +488 ADD +489 PUSH1 0x00 +491 SHA3 +492 SLOAD +493 SWAP1 +494 POP +495 SWAP2 +496 SWAP1 +497 POP +498 JUMP +499 JUMPDEST +500 PUSH1 0x00 +502 DUP1 +503 DUP3 +504 PUSH1 0x00 +506 DUP1 +507 CALLER +508 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +529 AND +530 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +551 AND +552 DUP2 +553 MSTORE +554 PUSH1 0x20 +556 ADD +557 SWAP1 +558 DUP2 +559 MSTORE +560 PUSH1 0x20 +562 ADD +563 PUSH1 0x00 +565 SHA3 +566 SLOAD +567 SUB +568 LT +569 ISZERO +570 ISZERO +571 ISZERO +572 PUSH2 0x0244 +575 JUMPI +576 PUSH1 0x00 +578 DUP1 +579 REVERT +580 JUMPDEST +581 DUP2 +582 PUSH1 0x00 +584 DUP1 +585 CALLER +586 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +607 AND +608 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +629 AND +630 DUP2 +631 MSTORE +632 PUSH1 0x20 +634 ADD +635 SWAP1 +636 DUP2 +637 MSTORE +638 PUSH1 0x20 +640 ADD +641 PUSH1 0x00 +643 SHA3 +644 PUSH1 0x00 +646 DUP3 +647 DUP3 +648 SLOAD +649 SUB +650 SWAP3 +651 POP +652 POP +653 DUP2 +654 SWAP1 +655 SSTORE +656 POP +657 DUP2 +658 PUSH1 0x00 +660 DUP1 +661 DUP6 +662 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +683 AND +684 PUSH20 0xffffffffffffffffffffffffffffffffffffffff +705 AND +706 DUP2 +707 MSTORE +708 PUSH1 0x20 +710 ADD +711 SWAP1 +712 DUP2 +713 MSTORE +714 PUSH1 0x20 +716 ADD +717 PUSH1 0x00 +719 SHA3 +720 PUSH1 0x00 +722 DUP3 +723 DUP3 +724 SLOAD +725 ADD +726 SWAP3 +727 POP +728 POP +729 DUP2 +730 SWAP1 +731 SSTORE +732 POP +733 PUSH1 0x01 +735 SWAP1 +736 POP +737 SWAP3 +738 SWAP2 +739 POP +740 POP +741 JUMP +742 STOP diff --git a/tests/testdata/outputs_expected/outputs_current/underflow.sol.o.graph.html b/tests/testdata/outputs_expected/outputs_current/underflow.sol.o.graph.html new file mode 100644 index 00000000..062a5856 --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/underflow.sol.o.graph.html @@ -0,0 +1,62 @@ + + + + Call Graph + + + + + + + + + + +

Mythril / Ethereum LASER Symbolic VM

+
+ + + \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/underflow.sol.o.json b/tests/testdata/outputs_expected/outputs_current/underflow.sol.o.json new file mode 100644 index 00000000..fb92acaf --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/underflow.sol.o.json @@ -0,0 +1 @@ +{"error": null, "issues": [{"address": 567, "contract": "Unknown", "debug": "", "description": "The substraction can result in an integer underflow.\n", "function": "sendeth(address,uint256)", "swc_id": "101", "title": "Integer Underflow", "type": "Warning"}, {"address": 649, "contract": "Unknown", "debug": "", "description": "The substraction can result in an integer underflow.\n", "function": "sendeth(address,uint256)", "swc_id": "101", "title": "Integer Underflow", "type": "Warning"}, {"address": 725, "contract": "Unknown", "debug": "", "description": "The arithmetic operation can result in integer overflow.\n", "function": "sendeth(address,uint256)", "swc_id": "101", "title": "Integer Overflow", "type": "Warning"}], "success": true} \ No newline at end of file diff --git a/tests/testdata/outputs_expected/outputs_current/underflow.sol.o.markdown b/tests/testdata/outputs_expected/outputs_current/underflow.sol.o.markdown new file mode 100644 index 00000000..4f86063c --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/underflow.sol.o.markdown @@ -0,0 +1,34 @@ +# Analysis results for test-filename.sol + +## Integer Underflow +- SWC ID: 101 +- Type: Warning +- Contract: Unknown +- Function name: `sendeth(address,uint256)` +- PC address: 567 + +### Description + +The substraction can result in an integer underflow. + +## Integer Underflow +- SWC ID: 101 +- Type: Warning +- Contract: Unknown +- Function name: `sendeth(address,uint256)` +- PC address: 649 + +### Description + +The substraction can result in an integer underflow. + +## Integer Overflow +- SWC ID: 101 +- Type: Warning +- Contract: Unknown +- Function name: `sendeth(address,uint256)` +- PC address: 725 + +### Description + +The arithmetic operation can result in integer overflow. diff --git a/tests/testdata/outputs_expected/outputs_current/underflow.sol.o.text b/tests/testdata/outputs_expected/outputs_current/underflow.sol.o.text new file mode 100644 index 00000000..acdce40b --- /dev/null +++ b/tests/testdata/outputs_expected/outputs_current/underflow.sol.o.text @@ -0,0 +1,30 @@ +==== Integer Underflow ==== +SWC ID: 101 +Type: Warning +Contract: Unknown +Function name: sendeth(address,uint256) +PC address: 567 +The substraction can result in an integer underflow. + +-------------------- + +==== Integer Underflow ==== +SWC ID: 101 +Type: Warning +Contract: Unknown +Function name: sendeth(address,uint256) +PC address: 649 +The substraction can result in an integer underflow. + +-------------------- + +==== Integer Overflow ==== +SWC ID: 101 +Type: Warning +Contract: Unknown +Function name: sendeth(address,uint256) +PC address: 725 +The arithmetic operation can result in integer overflow. + +-------------------- + diff --git a/tests/testdata/outputs_expected/overflow.sol.o.graph.html b/tests/testdata/outputs_expected/overflow.sol.o.graph.html index 5d117d28..ed71dd6e 100644 --- a/tests/testdata/outputs_expected/overflow.sol.o.graph.html +++ b/tests/testdata/outputs_expected/overflow.sol.o.graph.html @@ -8,6 +8,7 @@

Mythril / Ethereum LASER Symbolic VM

-


+

Mythril / Ethereum LASER Symbolic VM

-


+

Mythril / Ethereum LASER Symbolic VM

-


+

Mythril / Ethereum LASER Symbolic VM

-


+