├── src ├── test1.sol ├── test8.sol ├── test8_runner.sol ├── test4.sol ├── test8_cpy.sol ├── test9.sol ├── test4_cpy.sol ├── test6.sol ├── test6_cpy.sol ├── test11.sol ├── test10.sol ├── test10-1.sol ├── test5_cpy.sol ├── test5.sol ├── test7.sol ├── test2_cpy.sol ├── test2.sol ├── test3_cpy.sol ├── test3.sol ├── test12_cpy.sol └── test12.sol ├── LICENSE └── README.md /src/test1.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >=0.4.16 <0.9.0; 3 | 4 | contract SimpleStorage { 5 | uint storedData; 6 | 7 | function set(uint x) public { 8 | storedData = x; 9 | } 10 | 11 | function get() public view returns (uint) { 12 | return storedData; 13 | } 14 | } -------------------------------------------------------------------------------- /src/test8.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >0.5.0 <=0.7.0; 3 | 4 | // tx.origin for authorisation - a vulnerability 5 | 6 | contract TestContract { 7 | address owner; 8 | 9 | constructor() public { 10 | owner = msg.sender; 11 | } 12 | 13 | function transferTo(address payable dest, uint amount) payable public { 14 | require(tx.origin == owner); 15 | dest.transfer(amount); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test8_runner.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity ^0.6.0; 3 | 4 | interface TestContract { 5 | function transferTo(address payable dest, uint amount) external; 6 | } 7 | 8 | contract AttackWallet { 9 | address payable owner; 10 | 11 | constructor() public { 12 | owner = msg.sender; 13 | } 14 | 15 | receive() external payable { 16 | TestContract(msg.sender).transferTo(owner, msg.sender.balance); 17 | } 18 | } -------------------------------------------------------------------------------- /src/test4.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity ^0.6.0; 4 | 5 | contract rngTest { 6 | 7 | uint public rng; 8 | 9 | // Weak RNG functions 10 | function takeAGuess() external{ 11 | rng = uint256(blockhash(10000)) % 10; 12 | } 13 | function takeAnotherGuess() external{ 14 | rng = uint256(block.timestamp) % 50; 15 | } 16 | function takeAGuessNow() external{ 17 | rng = uint256(now) % 99; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test8_cpy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity <0.5.0; 3 | 4 | // tx.origin for authorisation - a vulnerability 5 | // Adapted for Solidity v. 0.4.17 to run Oyente properly 6 | contract TestContract { 7 | address owner; 8 | 9 | function TestContract() public { 10 | owner = msg.sender; 11 | } 12 | 13 | function transferTo(address dest, uint amount) payable public { 14 | require(tx.origin == owner); 15 | dest.transfer(amount); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test9.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >0.4.16 <=0.9.0; 3 | 4 | contract SimpleStorage { 5 | uint storedData; 6 | 7 | function set(uint x) public { 8 | storedData = x; 9 | } 10 | 11 | function get(uint _data) public payable { 12 | payable(msg.sender).transfer(_data); 13 | } 14 | 15 | } 16 | contract LockContract { 17 | 18 | function withdraw() public payable { 19 | uint a; uint b; uint c; 20 | c = a - b; 21 | // No withdrawal capacity to payable function - vulnerability 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test4_cpy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity <0.6.0; 4 | 5 | // Adapted for Solidity v. 0.4.17 to run Oyente properly 6 | contract rngTest { 7 | 8 | uint public rng; 9 | 10 | // Weak RNG functions 11 | function takeAGuess() external{ 12 | rng = uint256(block.blockhash(10000)) % 10; 13 | } 14 | function takeAnotherGuess() external{ 15 | rng = uint256(block.timestamp) % 50; 16 | } 17 | function takeAGuessNow() external{ 18 | rng = uint256(now) % 99; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test6.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | contract outOfGas { 6 | 7 | address payable public owner; 8 | address payable public dest; 9 | 10 | uint counter = 0; 11 | 12 | constructor() public { 13 | owner = payable(msg.sender); 14 | } 15 | 16 | function setDest() public { 17 | dest = payable(msg.sender); 18 | } 19 | 20 | 21 | // Out of gas vulnerability due to infinite loop 22 | 23 | function run() public payable { 24 | for(uint i = 0; i >= 0; i++) { 25 | dest.send(msg.value); 26 | counter++; 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/test6_cpy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity <=0.7.0; 4 | 5 | // Adapted for Solidity v. 0.4.17 to run Oyente properly 6 | contract outOfGas { 7 | 8 | address public owner; 9 | address public dest; 10 | 11 | uint counter = 0; 12 | 13 | function outOfGas() public { 14 | owner = msg.sender; 15 | } 16 | 17 | function setDest() public { 18 | dest = msg.sender; 19 | } 20 | 21 | 22 | // Out of gas vulnerability due to infinite loop 23 | 24 | function run() public payable { 25 | for(uint i = 0; i >= 0; i++) { 26 | dest.send(msg.value); 27 | counter++; 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/test11.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity >=0.4.16 <0.9.0; 3 | 4 | library VectorSum { 5 | function sumSolidity(uint[] memory _data) public pure returns (uint sum) { 6 | for(uint i = 0; i < _data.length; i++) 7 | sum += _data[i]; 8 | } 9 | function sumAsm(uint[] memory _data) public pure returns (uint sum) { 10 | for(uint i = 0; i < _data.length; i++) { 11 | assembly { 12 | sum := add(sum, mload(add(add(_data, 0x20), mul(i, 0x20)))) 13 | } 14 | } 15 | } 16 | function sumPureAsm(uint[] memory _data) public pure returns (uint sum) { 17 | assembly { 18 | let len := mload(_data) 19 | let data := add(_data, 0x20) 20 | for 21 | { let end := add(data, mul(len, 0x20)) } 22 | lt(data, end) 23 | { data := add(data, 0x20) } 24 | { 25 | sum := add(sum, mload(data)) 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test10.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity 0.4.22; 3 | 4 | contract Coin { 5 | address public minter; 6 | mapping (address => uint) public balances; 7 | 8 | event Sent(address from, address to, uint amount); 9 | // Two constructors - old version (pre 0.5) and new version. Using both can lead to some unexpected results. Works only with Solidity v. 0.4.22. 10 | function Coin() public { 11 | minter = msg.sender; 12 | } 13 | constructor() public { 14 | minter = address(0xdeadbeef); 15 | } 16 | 17 | function mint(address receiver, uint amount) public { 18 | require(msg.sender == minter); 19 | require(amount < 1e60); 20 | balances[receiver] += amount; 21 | } 22 | 23 | function send(address receiver, uint amount) public { 24 | if (amount > balances[msg.sender]) 25 | revert("Insufficient balance"); 26 | balances[msg.sender] -= amount; 27 | balances[receiver] += amount; 28 | emit Sent(msg.sender, receiver, amount); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test10-1.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | pragma solidity <0.9.0; 3 | 4 | contract Coin { 5 | address public minter; 6 | mapping (address => uint) public balances; 7 | 8 | event Sent(address from, address to, uint amount); 9 | // Two constructors - old version (pre 0.5) and new version. Using both can lead to some unexpected results 10 | // Same as test10.sol, but the old type constructor contains a typo, meaning that the compiler would not recognise it as a candidate to a constructor. 11 | function coin() public { 12 | minter = msg.sender; 13 | } 14 | constructor() public { 15 | minter = address(0xdeadbeef); 16 | } 17 | 18 | function mint(address receiver, uint amount) public { 19 | require(msg.sender == minter); 20 | require(amount < 1e60); 21 | balances[receiver] += amount; 22 | } 23 | 24 | function send(address receiver, uint amount) public { 25 | if (amount > balances[msg.sender]) 26 | revert("Insufficient balance"); 27 | balances[msg.sender] -= amount; 28 | balances[receiver] += amount; 29 | emit Sent(msg.sender, receiver, amount); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Nedas Matulevicius 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/test5_cpy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity <=0.7.0; 4 | 5 | // Adapted for Solidity v. 0.4.17 to run Oyente properly 6 | contract someContract { 7 | 8 | address public owner; 9 | address dest; 10 | address somewhere; 11 | uint amount = 0; uint answer = 15; 12 | 13 | function someContract() public { 14 | owner = msg.sender; 15 | } 16 | 17 | function setDest() public { 18 | dest = msg.sender; 19 | } 20 | 21 | // Code quality vulnerabilities 22 | 23 | function doSomething() public payable { 24 | 25 | // Tautologies 26 | if(true) { 27 | amount = msg.value; 28 | owner.transfer(amount); 29 | } 30 | if(answer < 25) { 31 | // Arbitrary destinations 32 | dest.transfer(address(this).balance); 33 | } 34 | 35 | } 36 | 37 | // Lost contracts 38 | function transferNowhere() public payable { 39 | somewhere.transfer(msg.value); 40 | } 41 | 42 | // Unprotected self-destruct 43 | function kill() public{ 44 | selfdestruct(msg.sender); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test5.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | contract someContract { 6 | 7 | address payable public owner; 8 | address payable dest; 9 | address payable somewhere; 10 | uint amount = 0; uint answer = 15; 11 | 12 | constructor() public { 13 | owner = payable(msg.sender); 14 | } 15 | 16 | function setDest() public { 17 | dest = payable(msg.sender); 18 | } 19 | 20 | // Code quality vulnerabilities 21 | 22 | function doSomething() public payable { 23 | 24 | // Tautologies 25 | if(true) { 26 | amount = msg.value; 27 | owner.transfer(amount); 28 | } 29 | if(answer < 25) { 30 | // Arbitrary destinations 31 | dest.transfer(address(this).balance); 32 | } 33 | 34 | } 35 | 36 | // Lost contracts 37 | function transferNowhere() public payable { 38 | somewhere.transfer(msg.value); 39 | } 40 | 41 | // Unprotected self-destruct 42 | function kill() public{ 43 | selfdestruct(payable(msg.sender)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test7.sol: -------------------------------------------------------------------------------- 1 | /* 2 | * @source: https://consensys.github.io/smart-contract-best-practices/known_attacks/#insufficient-gas-griefing 3 | * @author: ConsenSys Diligence 4 | * Modified by Kaden Zipfel (adapted Solidity versions by Nedas Matulevicius) 5 | */ 6 | // SPDX-License-Identifier: GPL-3.0 7 | pragma solidity >=0.4.24 <0.9.0; 8 | 9 | contract Relayer { 10 | uint transactionId; 11 | 12 | struct Tx { 13 | bytes data; 14 | bool executed; 15 | } 16 | 17 | mapping (uint => Tx) transactions; 18 | 19 | function relay(Target target, bytes memory _data) public returns(bool) { 20 | // replay protection; do not call the same transaction twice 21 | require(transactions[transactionId].executed == false, 'same transaction twice'); 22 | transactions[transactionId].data = _data; 23 | transactions[transactionId].executed = true; 24 | transactionId += 1; 25 | 26 | (bool success, ) = address(target).call(abi.encodeWithSignature("execute(bytes)", _data)); 27 | return success; 28 | } 29 | } 30 | 31 | // Contract called by Relayer 32 | contract Target { 33 | function execute(bytes memory _data) public { 34 | // Execute contract code 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/test2_cpy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity <=0.7.0; 4 | 5 | // Adapted for Solidity v. 0.4.17 to run Oyente properly 6 | contract Booking { 7 | 8 | enum State {Vacant, Occupied} 9 | State public state; 10 | 11 | address public owner; 12 | 13 | event Booked(address _occupant, uint _amount); 14 | 15 | function Booking() public { 16 | owner = msg.sender; 17 | state = State.Vacant; 18 | } 19 | 20 | modifier onlyIfVacant { 21 | require(state == State.Vacant); 22 | _; 23 | } 24 | 25 | modifier costs(uint _amount) { 26 | require(msg.value >= _amount); 27 | _; 28 | } 29 | 30 | // Double-spend vulnerability due to two functions doing the same thing without protection 31 | // Also, the second function does not check if the room is already occupied 32 | 33 | function book() public payable onlyIfVacant costs(3 ether) { 34 | owner.transfer(msg.value); 35 | state = State.Occupied; 36 | Booked(msg.sender, msg.value); 37 | } 38 | 39 | function receive() external payable costs(3 ether) { 40 | owner.transfer(msg.value); 41 | state = State.Occupied; 42 | Booked(msg.sender, msg.value); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/test2.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | contract Booking { 6 | 7 | enum State {Vacant, Occupied} 8 | State public state; 9 | 10 | address payable public owner; 11 | 12 | event Booked(address _occupant, uint _amount); 13 | 14 | constructor() public { 15 | owner = payable(msg.sender); 16 | state = State.Vacant; 17 | } 18 | 19 | modifier onlyIfVacant { 20 | require(state == State.Vacant, "The room is occupied!"); 21 | _; 22 | } 23 | 24 | modifier costs(uint _amount) { 25 | require(msg.value >= _amount, "Insufficient funds!"); 26 | _; 27 | } 28 | 29 | // Double-spend vulnerability due to two functions doing the same thing without protection 30 | // Also, the second function does not check if the room is already occupied 31 | 32 | function book() public payable onlyIfVacant costs(3 ether) { 33 | owner.transfer(msg.value); 34 | state = State.Occupied; 35 | emit Booked(msg.sender, msg.value); 36 | } 37 | 38 | receive() external payable costs(3 ether) { 39 | owner.transfer(msg.value); 40 | state = State.Occupied; 41 | emit Booked(msg.sender, msg.value); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Solidity smart contract bug detection repository 2 | A repository for Solidity smart contracts acting as security bug tests for static analysis tools. Currently, there are 13 different tests, 11 of them have security vulnerabilities in them, each with different levels of severity. 3 | 4 | The tests were used with 5 Solidity static analysis tools - namely, Remix IDE static analysis plugin, Slither, Oyente, Mythril and SmartCheck. You are more than welcome to use these tests with other static analysis tools for Solidity smart contracts as well. 5 | 6 | Note: tests for Oyente are adapted separately due to the tool using an old solc version. Therefore, use testNumber_cpy.sol files for testing out Oyente. 7 | 8 | The vulnerabilities in tests are as follows: 9 | * Test 1 - canary test, no vulnerabilities; 10 | * Test 2 - re-entrancy vulnerability; 11 | * Test 3 - dead code vulnerability; 12 | * Test 4 - weak PRNG and timestamp dependency vulnerabilities; 13 | * Test 5 - lost contracts and unprotected self-destruction vulnerabilities; 14 | * Test 6 - out-of-gas vulnerability; 15 | * Test 7 - gas griefing vulnerability; 16 | * Test 8 - usage of tx.origin for validation; 17 | * Test 9 - unchecked value transfer and contract locking vulnerabilities; 18 | * Test 10 - double constructor vulnerability; 19 | * Test 10.1 - constructor-like functions; 20 | * Test 11 - inline assembly code usage vulnerability; 21 | * Test 12 - code size test, no vulnerabilities. 22 | -------------------------------------------------------------------------------- /src/test3_cpy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity <=0.7.0; 4 | 5 | // Adapted for Solidity v. 0.4.17 to run Oyente properly 6 | contract Test { 7 | 8 | address public owner; 9 | uint amount = 0; uint answer = 0; 10 | 11 | 12 | event Success(address _from, uint _amount); 13 | 14 | function Test() public { 15 | owner = msg.sender; 16 | } 17 | 18 | // Dead code vulnerability as functions are not checked by the static analysis tool if they contribute to the final answer 19 | 20 | function doSomething() public payable { 21 | 22 | amount = msg.value; 23 | uint val = 2; 24 | 25 | answer = doSomethingElse(amount, val); 26 | 27 | owner.transfer(amount); 28 | Success(msg.sender, amount); 29 | } 30 | 31 | function doSomethingElse(uint a, uint b) private returns (uint value) { 32 | uint c = 0; uint res = 0; 33 | for(uint i = 0; i < b; i++) { 34 | if(i == 0) { 35 | c++; 36 | res += doUselessCalculations(a, b, c); 37 | } 38 | else if(a < b) { 39 | c += a; 40 | res += doUselessCalculations(b, a, c); 41 | } 42 | else { 43 | c++; 44 | res += doUselessCalculations(c, b, a); 45 | } 46 | } 47 | return res; 48 | } 49 | 50 | function doUselessCalculations(uint a, uint b, uint c) private returns (uint res) { 51 | uint someAnswer = 1; 52 | for(uint i = 1; i <= 1000; i++) { 53 | someAnswer += mulmod(a, b, addmod(c, c, a)); 54 | } 55 | for(uint j = 1; j <= 1000; j++) { 56 | someAnswer += mulmod(a, b, addmod(c, 5, a)); 57 | } 58 | for(uint k = 1; k <= 1000; k++) { 59 | someAnswer += mulmod(a, b, addmod(c, 10, a)); 60 | } 61 | return someAnswer; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/test3.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | contract Test { 6 | 7 | address payable public owner; 8 | uint amount = 0; uint answer = 0; 9 | 10 | 11 | event Success(address _from, uint _amount); 12 | 13 | constructor() public { 14 | owner = payable(msg.sender); 15 | } 16 | 17 | // Dead code vulnerability as functions are not checked by the static analysis tool if they contribute to the final answer 18 | 19 | function doSomething() public payable { 20 | 21 | amount = msg.value; 22 | uint val = 2; 23 | 24 | answer = doSomethingElse(amount, val); 25 | 26 | owner.transfer(amount); 27 | emit Success(msg.sender, amount); 28 | } 29 | 30 | function doSomethingElse(uint a, uint b) private returns (uint value) { 31 | uint c = 0; uint res = 0; 32 | for(uint i = 0; i < b; i++) { 33 | if(i == 0) { 34 | c++; 35 | res += doUselessCalculations(a, b, c); 36 | } 37 | else if(a < b) { 38 | c += a; 39 | res += doUselessCalculations(b, a, c); 40 | } 41 | else { 42 | c++; 43 | res += doUselessCalculations(c, b, a); 44 | } 45 | } 46 | return res; 47 | } 48 | 49 | function doUselessCalculations(uint a, uint b, uint c) private returns (uint res) { 50 | uint someAnswer = 1; 51 | for(uint i = 1; i <= 1000; i++) { 52 | someAnswer += mulmod(a, b, addmod(c, c, a)); 53 | } 54 | for(uint j = 1; j <= 1000; j++) { 55 | someAnswer += mulmod(a, b, addmod(c, 5, a)); 56 | } 57 | for(uint k = 1; k <= 1000; k++) { 58 | someAnswer += mulmod(a, b, addmod(c, 10, a)); 59 | } 60 | return someAnswer; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/test12_cpy.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity 0.4.17; 4 | 5 | // Code coverage - test to check if code size affects the performance of static analysis tools 6 | 7 | contract Test { 8 | 9 | address public owner; 10 | uint amount = 0; uint answer = 0; 11 | 12 | 13 | event Success(address _from, uint _amount); 14 | 15 | function Test() public { 16 | owner = msg.sender; 17 | } 18 | 19 | function doSomething() public payable { 20 | 21 | amount = msg.value; 22 | uint val = 2; 23 | 24 | answer = doSomethingElse(amount, val); 25 | 26 | owner.transfer(amount); 27 | Success(msg.sender, amount); 28 | } 29 | 30 | function doSomethingElse(uint a, uint b) private pure returns (uint value) { 31 | uint c = 0; uint res = 0; 32 | for(uint i = 0; i < b; i++) { 33 | if(i == 0) { 34 | c++; 35 | res += doUselessCalculations(a, b, c); 36 | } 37 | else if(a < b) { 38 | c += a; 39 | res += doUselessCalculations(b, a, c); 40 | } 41 | else { 42 | c++; 43 | res += doUselessCalculations(c, b, a); 44 | } 45 | } 46 | return res; 47 | } 48 | 49 | function doUselessCalculations(uint a, uint b, uint c) private pure returns (uint res) { 50 | uint someAnswer = 1; 51 | for(uint i = 1; i <= 1000; i++) { 52 | someAnswer += mulmod(a, b, addmod(c, c, a)); 53 | } 54 | for(uint j = 1; j <= 1000; j++) { 55 | someAnswer += mulmod(a, b, addmod(c, 5, a)); 56 | } 57 | for(uint k = 1; k <= 1000; k++) { 58 | someAnswer += mulmod(a, b, addmod(c, 10, a)); 59 | } 60 | return someAnswer; 61 | } 62 | 63 | function doUselessCalculations2(uint a, uint b, uint c) private pure returns (uint res) { 64 | uint someAnswer = 1; 65 | for(uint i = 1; i <= 1000; i++) { 66 | someAnswer += mulmod(a, b, addmod(c, c, a)); 67 | } 68 | for(uint j = 1; j <= 1000; j++) { 69 | someAnswer += mulmod(a, b, addmod(c, 5, a)); 70 | } 71 | for(uint k = 1; k <= 1000; k++) { 72 | someAnswer += mulmod(a, b, addmod(c, 10, a)); 73 | } 74 | return someAnswer; 75 | } 76 | 77 | function doUselessCalculations3(uint a, uint b, uint c) private pure returns (uint res) { 78 | uint someAnswer = 1; 79 | for(uint i = 1; i <= 1000; i++) { 80 | someAnswer += mulmod(a, b, addmod(c, c, a)); 81 | } 82 | for(uint j = 1; j <= 1000; j++) { 83 | someAnswer += mulmod(a, b, addmod(c, 5, a)); 84 | } 85 | for(uint k = 1; k <= 1000; k++) { 86 | someAnswer += mulmod(a, b, addmod(c, 10, a)); 87 | } 88 | return someAnswer; 89 | } 90 | 91 | function doUselessCalculations4(uint a, uint b, uint c) private pure returns (uint res) { 92 | uint someAnswer = 1; 93 | for(uint i = 1; i <= 1000; i++) { 94 | someAnswer += mulmod(a, b, addmod(c, c, a)); 95 | } 96 | for(uint j = 1; j <= 1000; j++) { 97 | someAnswer += mulmod(a, b, addmod(c, 5, a)); 98 | } 99 | for(uint k = 1; k <= 1000; k++) { 100 | someAnswer += mulmod(a, b, addmod(c, 10, a)); 101 | } 102 | return someAnswer; 103 | } 104 | 105 | function doUselessCalculations5(uint a, uint b, uint c) private pure returns (uint res) { 106 | uint someAnswer = 1; 107 | for(uint i = 1; i <= 1000; i++) { 108 | someAnswer += mulmod(a, b, addmod(c, c, a)); 109 | } 110 | for(uint j = 1; j <= 1000; j++) { 111 | someAnswer += mulmod(a, b, addmod(c, 5, a)); 112 | } 113 | for(uint k = 1; k <= 1000; k++) { 114 | someAnswer += mulmod(a, b, addmod(c, 10, a)); 115 | } 116 | return someAnswer; 117 | } 118 | 119 | function doUselessCalculations6(uint a, uint b, uint c) private pure returns (uint res) { 120 | uint someAnswer = 1; 121 | for(uint i = 1; i <= 1000; i++) { 122 | someAnswer += mulmod(a, b, addmod(c, c, a)); 123 | } 124 | for(uint j = 1; j <= 1000; j++) { 125 | someAnswer += mulmod(a, b, addmod(c, 5, a)); 126 | } 127 | for(uint k = 1; k <= 1000; k++) { 128 | someAnswer += mulmod(a, b, addmod(c, 10, a)); 129 | } 130 | return someAnswer; 131 | } 132 | 133 | function doUselessCalculations7(uint a, uint b, uint c) private pure returns (uint res) { 134 | uint someAnswer = 1; 135 | for(uint i = 1; i <= 1000; i++) { 136 | someAnswer += mulmod(a, b, addmod(c, c, a)); 137 | } 138 | for(uint j = 1; j <= 1000; j++) { 139 | someAnswer += mulmod(a, b, addmod(c, 5, a)); 140 | } 141 | for(uint k = 1; k <= 1000; k++) { 142 | someAnswer += mulmod(a, b, addmod(c, 10, a)); 143 | } 144 | return someAnswer; 145 | } 146 | } 147 | 148 | contract Booking { 149 | 150 | enum State {Vacant, Occupied} 151 | State public state; 152 | 153 | address public owner; 154 | 155 | event Booked(address _occupant, uint _amount); 156 | 157 | function Booking() public { 158 | owner = msg.sender; 159 | state = State.Vacant; 160 | } 161 | 162 | modifier onlyIfVacant { 163 | require(state == State.Vacant); 164 | _; 165 | } 166 | 167 | modifier costs(uint _amount) { 168 | require(msg.value >= _amount); 169 | _; 170 | } 171 | 172 | function book() public payable onlyIfVacant costs(3 ether) { 173 | owner.transfer(msg.value); 174 | state = State.Occupied; 175 | Booked(msg.sender, msg.value); 176 | } 177 | 178 | function receive() external payable costs(3 ether) { 179 | owner.transfer(msg.value); 180 | state = State.Occupied; 181 | Booked(msg.sender, msg.value); 182 | } 183 | 184 | } 185 | 186 | contract Booking2 { 187 | 188 | enum State {Vacant, Occupied} 189 | State public state; 190 | 191 | address public owner; 192 | 193 | event Booked(address _occupant, uint _amount); 194 | 195 | function Booking2() public { 196 | owner = msg.sender; 197 | state = State.Vacant; 198 | } 199 | 200 | modifier onlyIfVacant { 201 | require(state == State.Vacant); 202 | _; 203 | } 204 | 205 | modifier costs(uint _amount) { 206 | require(msg.value >= _amount); 207 | _; 208 | } 209 | 210 | function book() public payable onlyIfVacant costs(3 ether) { 211 | owner.transfer(msg.value); 212 | state = State.Occupied; 213 | Booked(msg.sender, msg.value); 214 | } 215 | 216 | function receive() external payable costs(3 ether) { 217 | owner.transfer(msg.value); 218 | state = State.Occupied; 219 | Booked(msg.sender, msg.value); 220 | } 221 | 222 | } 223 | 224 | contract Booking3 { 225 | 226 | enum State {Vacant, Occupied} 227 | State public state; 228 | 229 | address public owner; 230 | 231 | event Booked(address _occupant, uint _amount); 232 | 233 | function Booking3() public { 234 | owner = msg.sender; 235 | state = State.Vacant; 236 | } 237 | 238 | modifier onlyIfVacant { 239 | require(state == State.Vacant); 240 | _; 241 | } 242 | 243 | modifier costs(uint _amount) { 244 | require(msg.value >= _amount); 245 | _; 246 | } 247 | 248 | function book() public payable onlyIfVacant costs(3 ether) { 249 | owner.transfer(msg.value); 250 | state = State.Occupied; 251 | Booked(msg.sender, msg.value); 252 | } 253 | 254 | function receive() external payable costs(3 ether) { 255 | owner.transfer(msg.value); 256 | state = State.Occupied; 257 | Booked(msg.sender, msg.value); 258 | } 259 | 260 | } 261 | 262 | contract someContract { 263 | 264 | address public owner; 265 | address dest; 266 | address somewhere; 267 | uint amount = 0; uint answer = 15; 268 | 269 | function someContract() public { 270 | owner = msg.sender; 271 | } 272 | 273 | function setDest() public { 274 | dest = msg.sender; 275 | } 276 | 277 | function doSomething() public payable { 278 | if(true) { 279 | amount = msg.value; 280 | owner.transfer(amount); 281 | } 282 | if(answer < 25) { 283 | dest.transfer(address(this).balance); 284 | } 285 | 286 | } 287 | 288 | function transferNowhere() public payable { 289 | somewhere.transfer(msg.value); 290 | } 291 | 292 | function kill() public{ 293 | selfdestruct(msg.sender); 294 | } 295 | } 296 | -------------------------------------------------------------------------------- /src/test12.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0 2 | 3 | pragma solidity <0.9.0; 4 | 5 | // Code coverage - test to check if code size affects the performance of static analysis tools 6 | 7 | contract Test { 8 | 9 | address payable public owner; 10 | uint amount = 0; uint answer = 0; 11 | 12 | 13 | event Success(address _from, uint _amount); 14 | 15 | constructor() public { 16 | owner = payable(msg.sender); 17 | } 18 | 19 | function doSomething() public payable { 20 | 21 | amount = msg.value; 22 | uint val = 2; 23 | 24 | answer = doSomethingElse(amount, val); 25 | 26 | owner.transfer(amount); 27 | emit Success(msg.sender, amount); 28 | } 29 | 30 | function doSomethingElse(uint a, uint b) private pure returns (uint value) { 31 | uint c = 0; uint res = 0; 32 | for(uint i = 0; i < b; i++) { 33 | if(i == 0) { 34 | c++; 35 | res += doUselessCalculations(a, b, c); 36 | } 37 | else if(a < b) { 38 | c += a; 39 | res += doUselessCalculations(b, a, c); 40 | } 41 | else { 42 | c++; 43 | res += doUselessCalculations(c, b, a); 44 | } 45 | } 46 | return res; 47 | } 48 | 49 | function doUselessCalculations(uint a, uint b, uint c) private pure returns (uint res) { 50 | uint someAnswer = 1; 51 | for(uint i = 1; i <= 1000; i++) { 52 | someAnswer += mulmod(a, b, addmod(c, c, a)); 53 | } 54 | for(uint j = 1; j <= 1000; j++) { 55 | someAnswer += mulmod(a, b, addmod(c, 5, a)); 56 | } 57 | for(uint k = 1; k <= 1000; k++) { 58 | someAnswer += mulmod(a, b, addmod(c, 10, a)); 59 | } 60 | return someAnswer; 61 | } 62 | 63 | function doUselessCalculations2(uint a, uint b, uint c) private pure returns (uint res) { 64 | uint someAnswer = 1; 65 | for(uint i = 1; i <= 1000; i++) { 66 | someAnswer += mulmod(a, b, addmod(c, c, a)); 67 | } 68 | for(uint j = 1; j <= 1000; j++) { 69 | someAnswer += mulmod(a, b, addmod(c, 5, a)); 70 | } 71 | for(uint k = 1; k <= 1000; k++) { 72 | someAnswer += mulmod(a, b, addmod(c, 10, a)); 73 | } 74 | return someAnswer; 75 | } 76 | 77 | function doUselessCalculations3(uint a, uint b, uint c) private pure returns (uint res) { 78 | uint someAnswer = 1; 79 | for(uint i = 1; i <= 1000; i++) { 80 | someAnswer += mulmod(a, b, addmod(c, c, a)); 81 | } 82 | for(uint j = 1; j <= 1000; j++) { 83 | someAnswer += mulmod(a, b, addmod(c, 5, a)); 84 | } 85 | for(uint k = 1; k <= 1000; k++) { 86 | someAnswer += mulmod(a, b, addmod(c, 10, a)); 87 | } 88 | return someAnswer; 89 | } 90 | 91 | function doUselessCalculations4(uint a, uint b, uint c) private pure returns (uint res) { 92 | uint someAnswer = 1; 93 | for(uint i = 1; i <= 1000; i++) { 94 | someAnswer += mulmod(a, b, addmod(c, c, a)); 95 | } 96 | for(uint j = 1; j <= 1000; j++) { 97 | someAnswer += mulmod(a, b, addmod(c, 5, a)); 98 | } 99 | for(uint k = 1; k <= 1000; k++) { 100 | someAnswer += mulmod(a, b, addmod(c, 10, a)); 101 | } 102 | return someAnswer; 103 | } 104 | 105 | function doUselessCalculations5(uint a, uint b, uint c) private pure returns (uint res) { 106 | uint someAnswer = 1; 107 | for(uint i = 1; i <= 1000; i++) { 108 | someAnswer += mulmod(a, b, addmod(c, c, a)); 109 | } 110 | for(uint j = 1; j <= 1000; j++) { 111 | someAnswer += mulmod(a, b, addmod(c, 5, a)); 112 | } 113 | for(uint k = 1; k <= 1000; k++) { 114 | someAnswer += mulmod(a, b, addmod(c, 10, a)); 115 | } 116 | return someAnswer; 117 | } 118 | 119 | function doUselessCalculations6(uint a, uint b, uint c) private pure returns (uint res) { 120 | uint someAnswer = 1; 121 | for(uint i = 1; i <= 1000; i++) { 122 | someAnswer += mulmod(a, b, addmod(c, c, a)); 123 | } 124 | for(uint j = 1; j <= 1000; j++) { 125 | someAnswer += mulmod(a, b, addmod(c, 5, a)); 126 | } 127 | for(uint k = 1; k <= 1000; k++) { 128 | someAnswer += mulmod(a, b, addmod(c, 10, a)); 129 | } 130 | return someAnswer; 131 | } 132 | 133 | function doUselessCalculations7(uint a, uint b, uint c) private pure returns (uint res) { 134 | uint someAnswer = 1; 135 | for(uint i = 1; i <= 1000; i++) { 136 | someAnswer += mulmod(a, b, addmod(c, c, a)); 137 | } 138 | for(uint j = 1; j <= 1000; j++) { 139 | someAnswer += mulmod(a, b, addmod(c, 5, a)); 140 | } 141 | for(uint k = 1; k <= 1000; k++) { 142 | someAnswer += mulmod(a, b, addmod(c, 10, a)); 143 | } 144 | return someAnswer; 145 | } 146 | } 147 | 148 | contract Booking { 149 | 150 | enum State {Vacant, Occupied} 151 | State public state; 152 | 153 | address payable public owner; 154 | 155 | event Booked(address _occupant, uint _amount); 156 | 157 | constructor() public { 158 | owner = payable(msg.sender); 159 | state = State.Vacant; 160 | } 161 | 162 | modifier onlyIfVacant { 163 | require(state == State.Vacant, "Room occupied"); 164 | _; 165 | } 166 | 167 | modifier costs(uint _amount) { 168 | require(msg.value >= _amount, "Insufficient funds"); 169 | _; 170 | } 171 | 172 | function book() public payable onlyIfVacant costs(3 ether) { 173 | owner.transfer(msg.value); 174 | state = State.Occupied; 175 | emit Booked(msg.sender, msg.value); 176 | } 177 | 178 | receive() external payable costs(3 ether) { 179 | owner.transfer(msg.value); 180 | state = State.Occupied; 181 | emit Booked(msg.sender, msg.value); 182 | } 183 | 184 | } 185 | 186 | contract Booking2 { 187 | 188 | enum State {Vacant, Occupied} 189 | State public state; 190 | 191 | address payable public owner; 192 | 193 | event Booked(address _occupant, uint _amount); 194 | 195 | constructor() public { 196 | owner = payable(msg.sender); 197 | state = State.Vacant; 198 | } 199 | 200 | modifier onlyIfVacant { 201 | require(state == State.Vacant, "Room occupied"); 202 | _; 203 | } 204 | 205 | modifier costs(uint _amount) { 206 | require(msg.value >= _amount, "Insufficient funds"); 207 | _; 208 | } 209 | 210 | function book() public payable onlyIfVacant costs(3 ether) { 211 | owner.transfer(msg.value); 212 | state = State.Occupied; 213 | emit Booked(msg.sender, msg.value); 214 | } 215 | 216 | receive() external payable costs(3 ether) { 217 | owner.transfer(msg.value); 218 | state = State.Occupied; 219 | emit Booked(msg.sender, msg.value); 220 | } 221 | 222 | } 223 | 224 | contract Booking3 { 225 | 226 | enum State {Vacant, Occupied} 227 | State public state; 228 | 229 | address payable public owner; 230 | 231 | event Booked(address _occupant, uint _amount); 232 | 233 | constructor() public { 234 | owner = payable(msg.sender); 235 | state = State.Vacant; 236 | } 237 | 238 | modifier onlyIfVacant { 239 | require(state == State.Vacant, "Room occupied"); 240 | _; 241 | } 242 | 243 | modifier costs(uint _amount) { 244 | require(msg.value >= _amount, "Insufficient funds"); 245 | _; 246 | } 247 | 248 | function book() public payable onlyIfVacant costs(3 ether) { 249 | owner.transfer(msg.value); 250 | state = State.Occupied; 251 | emit Booked(msg.sender, msg.value); 252 | } 253 | 254 | receive() external payable costs(3 ether) { 255 | owner.transfer(msg.value); 256 | state = State.Occupied; 257 | emit Booked(msg.sender, msg.value); 258 | } 259 | 260 | } 261 | 262 | contract someContract { 263 | 264 | address public owner; 265 | address payable dest; 266 | address payable somewhere; 267 | uint amount = 0; uint answer = 15; 268 | 269 | constructor() public { 270 | owner = msg.sender; 271 | } 272 | 273 | function setDest() public { 274 | dest = payable(msg.sender); 275 | } 276 | 277 | function doSomething() public payable { 278 | if(true) { 279 | amount = msg.value; 280 | payable(owner).transfer(amount); 281 | } 282 | if(answer < 25) { 283 | dest.transfer(address(this).balance); 284 | } 285 | 286 | } 287 | 288 | function transferNowhere() public payable { 289 | somewhere.transfer(msg.value); 290 | } 291 | 292 | function kill() public{ 293 | selfdestruct(payable(msg.sender)); 294 | } 295 | } 296 | --------------------------------------------------------------------------------