├── LICENSE └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | Solidity Security: Comprehensive list of known attack vectors and common 2 | anti-patterns (c) by Adrian Manning 3 | 4 | Solidity Security: Comprehensive list of known attack vectors and common 5 | anti-patterns is licensed under a 6 | Creative Commons Attribution 4.0 International License. 7 | 8 | A copy of this licence is given below and can also be found at 9 | . 10 | 11 | Attribution 4.0 International 12 | 13 | ======================================================================= 14 | 15 | Creative Commons Corporation ("Creative Commons") is not a law firm and 16 | does not provide legal services or legal advice. Distribution of 17 | Creative Commons public licenses does not create a lawyer-client or 18 | other relationship. Creative Commons makes its licenses and related 19 | information available on an "as-is" basis. Creative Commons gives no 20 | warranties regarding its licenses, any material licensed under their 21 | terms and conditions, or any related information. Creative Commons 22 | disclaims all liability for damages resulting from their use to the 23 | fullest extent possible. 24 | 25 | Using Creative Commons Public Licenses 26 | 27 | Creative Commons public licenses provide a standard set of terms and 28 | conditions that creators and other rights holders may use to share 29 | original works of authorship and other material subject to copyright 30 | and certain other rights specified in the public license below. The 31 | following considerations are for informational purposes only, are not 32 | exhaustive, and do not form part of our licenses. 33 | 34 | Considerations for licensors: Our public licenses are 35 | intended for use by those authorized to give the public 36 | permission to use material in ways otherwise restricted by 37 | copyright and certain other rights. Our licenses are 38 | irrevocable. Licensors should read and understand the terms 39 | and conditions of the license they choose before applying it. 40 | Licensors should also secure all rights necessary before 41 | applying our licenses so that the public can reuse the 42 | material as expected. Licensors should clearly mark any 43 | material not subject to the license. This includes other CC- 44 | licensed material, or material used under an exception or 45 | limitation to copyright. More considerations for licensors: 46 | wiki.creativecommons.org/Considerations_for_licensors 47 | 48 | Considerations for the public: By using one of our public 49 | licenses, a licensor grants the public permission to use the 50 | licensed material under specified terms and conditions. If 51 | the licensor's permission is not necessary for any reason--for 52 | example, because of any applicable exception or limitation to 53 | copyright--then that use is not regulated by the license. Our 54 | licenses grant only permissions under copyright and certain 55 | other rights that a licensor has authority to grant. Use of 56 | the licensed material may still be restricted for other 57 | reasons, including because others have copyright or other 58 | rights in the material. A licensor may make special requests, 59 | such as asking that all changes be marked or described. 60 | Although not required by our licenses, you are encouraged to 61 | respect those requests where reasonable. More considerations 62 | for the public: 63 | wiki.creativecommons.org/Considerations_for_licensees 64 | 65 | ======================================================================= 66 | 67 | Creative Commons Attribution 4.0 International Public License 68 | 69 | By exercising the Licensed Rights (defined below), You accept and agree 70 | to be bound by the terms and conditions of this Creative Commons 71 | Attribution 4.0 International Public License ("Public License"). To the 72 | extent this Public License may be interpreted as a contract, You are 73 | granted the Licensed Rights in consideration of Your acceptance of 74 | these terms and conditions, and the Licensor grants You such rights in 75 | consideration of benefits the Licensor receives from making the 76 | Licensed Material available under these terms and conditions. 77 | 78 | 79 | Section 1 -- Definitions. 80 | 81 | a. Adapted Material means material subject to Copyright and Similar 82 | Rights that is derived from or based upon the Licensed Material 83 | and in which the Licensed Material is translated, altered, 84 | arranged, transformed, or otherwise modified in a manner requiring 85 | permission under the Copyright and Similar Rights held by the 86 | Licensor. For purposes of this Public License, where the Licensed 87 | Material is a musical work, performance, or sound recording, 88 | Adapted Material is always produced where the Licensed Material is 89 | synched in timed relation with a moving image. 90 | 91 | b. Adapter's License means the license You apply to Your Copyright 92 | and Similar Rights in Your contributions to Adapted Material in 93 | accordance with the terms and conditions of this Public License. 94 | 95 | c. Copyright and Similar Rights means copyright and/or similar rights 96 | closely related to copyright including, without limitation, 97 | performance, broadcast, sound recording, and Sui Generis Database 98 | Rights, without regard to how the rights are labeled or 99 | categorized. For purposes of this Public License, the rights 100 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 101 | Rights. 102 | 103 | d. Effective Technological Measures means those measures that, in the 104 | absence of proper authority, may not be circumvented under laws 105 | fulfilling obligations under Article 11 of the WIPO Copyright 106 | Treaty adopted on December 20, 1996, and/or similar international 107 | agreements. 108 | 109 | e. Exceptions and Limitations means fair use, fair dealing, and/or 110 | any other exception or limitation to Copyright and Similar Rights 111 | that applies to Your use of the Licensed Material. 112 | 113 | f. Licensed Material means the artistic or literary work, database, 114 | or other material to which the Licensor applied this Public 115 | License. 116 | 117 | g. Licensed Rights means the rights granted to You subject to the 118 | terms and conditions of this Public License, which are limited to 119 | all Copyright and Similar Rights that apply to Your use of the 120 | Licensed Material and that the Licensor has authority to license. 121 | 122 | h. Licensor means the individual(s) or entity(ies) granting rights 123 | under this Public License. 124 | 125 | i. Share means to provide material to the public by any means or 126 | process that requires permission under the Licensed Rights, such 127 | as reproduction, public display, public performance, distribution, 128 | dissemination, communication, or importation, and to make material 129 | available to the public including in ways that members of the 130 | public may access the material from a place and at a time 131 | individually chosen by them. 132 | 133 | j. Sui Generis Database Rights means rights other than copyright 134 | resulting from Directive 96/9/EC of the European Parliament and of 135 | the Council of 11 March 1996 on the legal protection of databases, 136 | as amended and/or succeeded, as well as other essentially 137 | equivalent rights anywhere in the world. 138 | 139 | k. You means the individual or entity exercising the Licensed Rights 140 | under this Public License. Your has a corresponding meaning. 141 | 142 | 143 | Section 2 -- Scope. 144 | 145 | a. License grant. 146 | 147 | 1. Subject to the terms and conditions of this Public License, 148 | the Licensor hereby grants You a worldwide, royalty-free, 149 | non-sublicensable, non-exclusive, irrevocable license to 150 | exercise the Licensed Rights in the Licensed Material to: 151 | 152 | a. reproduce and Share the Licensed Material, in whole or 153 | in part; and 154 | 155 | b. produce, reproduce, and Share Adapted Material. 156 | 157 | 2. Exceptions and Limitations. For the avoidance of doubt, where 158 | Exceptions and Limitations apply to Your use, this Public 159 | License does not apply, and You do not need to comply with 160 | its terms and conditions. 161 | 162 | 3. Term. The term of this Public License is specified in Section 163 | 6(a). 164 | 165 | 4. Media and formats; technical modifications allowed. The 166 | Licensor authorizes You to exercise the Licensed Rights in 167 | all media and formats whether now known or hereafter created, 168 | and to make technical modifications necessary to do so. The 169 | Licensor waives and/or agrees not to assert any right or 170 | authority to forbid You from making technical modifications 171 | necessary to exercise the Licensed Rights, including 172 | technical modifications necessary to circumvent Effective 173 | Technological Measures. For purposes of this Public License, 174 | simply making modifications authorized by this Section 2(a) 175 | (4) never produces Adapted Material. 176 | 177 | 5. Downstream recipients. 178 | 179 | a. Offer from the Licensor -- Licensed Material. Every 180 | recipient of the Licensed Material automatically 181 | receives an offer from the Licensor to exercise the 182 | Licensed Rights under the terms and conditions of this 183 | Public License. 184 | 185 | b. No downstream restrictions. You may not offer or impose 186 | any additional or different terms or conditions on, or 187 | apply any Effective Technological Measures to, the 188 | Licensed Material if doing so restricts exercise of the 189 | Licensed Rights by any recipient of the Licensed 190 | Material. 191 | 192 | 6. No endorsement. Nothing in this Public License constitutes or 193 | may be construed as permission to assert or imply that You 194 | are, or that Your use of the Licensed Material is, connected 195 | with, or sponsored, endorsed, or granted official status by, 196 | the Licensor or others designated to receive attribution as 197 | provided in Section 3(a)(1)(A)(i). 198 | 199 | b. Other rights. 200 | 201 | 1. Moral rights, such as the right of integrity, are not 202 | licensed under this Public License, nor are publicity, 203 | privacy, and/or other similar personality rights; however, to 204 | the extent possible, the Licensor waives and/or agrees not to 205 | assert any such rights held by the Licensor to the limited 206 | extent necessary to allow You to exercise the Licensed 207 | Rights, but not otherwise. 208 | 209 | 2. Patent and trademark rights are not licensed under this 210 | Public License. 211 | 212 | 3. To the extent possible, the Licensor waives any right to 213 | collect royalties from You for the exercise of the Licensed 214 | Rights, whether directly or through a collecting society 215 | under any voluntary or waivable statutory or compulsory 216 | licensing scheme. In all other cases the Licensor expressly 217 | reserves any right to collect such royalties. 218 | 219 | 220 | Section 3 -- License Conditions. 221 | 222 | Your exercise of the Licensed Rights is expressly made subject to the 223 | following conditions. 224 | 225 | a. Attribution. 226 | 227 | 1. If You Share the Licensed Material (including in modified 228 | form), You must: 229 | 230 | a. retain the following if it is supplied by the Licensor 231 | with the Licensed Material: 232 | 233 | i. identification of the creator(s) of the Licensed 234 | Material and any others designated to receive 235 | attribution, in any reasonable manner requested by 236 | the Licensor (including by pseudonym if 237 | designated); 238 | 239 | ii. a copyright notice; 240 | 241 | iii. a notice that refers to this Public License; 242 | 243 | iv. a notice that refers to the disclaimer of 244 | warranties; 245 | 246 | v. a URI or hyperlink to the Licensed Material to the 247 | extent reasonably practicable; 248 | 249 | b. indicate if You modified the Licensed Material and 250 | retain an indication of any previous modifications; and 251 | 252 | c. indicate the Licensed Material is licensed under this 253 | Public License, and include the text of, or the URI or 254 | hyperlink to, this Public License. 255 | 256 | 2. You may satisfy the conditions in Section 3(a)(1) in any 257 | reasonable manner based on the medium, means, and context in 258 | which You Share the Licensed Material. For example, it may be 259 | reasonable to satisfy the conditions by providing a URI or 260 | hyperlink to a resource that includes the required 261 | information. 262 | 263 | 3. If requested by the Licensor, You must remove any of the 264 | information required by Section 3(a)(1)(A) to the extent 265 | reasonably practicable. 266 | 267 | 4. If You Share Adapted Material You produce, the Adapter's 268 | License You apply must not prevent recipients of the Adapted 269 | Material from complying with this Public License. 270 | 271 | 272 | Section 4 -- Sui Generis Database Rights. 273 | 274 | Where the Licensed Rights include Sui Generis Database Rights that 275 | apply to Your use of the Licensed Material: 276 | 277 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 278 | to extract, reuse, reproduce, and Share all or a substantial 279 | portion of the contents of the database; 280 | 281 | b. if You include all or a substantial portion of the database 282 | contents in a database in which You have Sui Generis Database 283 | Rights, then the database in which You have Sui Generis Database 284 | Rights (but not its individual contents) is Adapted Material; and 285 | 286 | c. You must comply with the conditions in Section 3(a) if You Share 287 | all or a substantial portion of the contents of the database. 288 | 289 | For the avoidance of doubt, this Section 4 supplements and does not 290 | replace Your obligations under this Public License where the Licensed 291 | Rights include other Copyright and Similar Rights. 292 | 293 | 294 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 295 | 296 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 297 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 298 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 299 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 300 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 301 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 302 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 303 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 304 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 305 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 306 | 307 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 308 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 309 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 310 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 311 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 312 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 313 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 314 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 315 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 316 | 317 | c. The disclaimer of warranties and limitation of liability provided 318 | above shall be interpreted in a manner that, to the extent 319 | possible, most closely approximates an absolute disclaimer and 320 | waiver of all liability. 321 | 322 | 323 | Section 6 -- Term and Termination. 324 | 325 | a. This Public License applies for the term of the Copyright and 326 | Similar Rights licensed here. However, if You fail to comply with 327 | this Public License, then Your rights under this Public License 328 | terminate automatically. 329 | 330 | b. Where Your right to use the Licensed Material has terminated under 331 | Section 6(a), it reinstates: 332 | 333 | 1. automatically as of the date the violation is cured, provided 334 | it is cured within 30 days of Your discovery of the 335 | violation; or 336 | 337 | 2. upon express reinstatement by the Licensor. 338 | 339 | For the avoidance of doubt, this Section 6(b) does not affect any 340 | right the Licensor may have to seek remedies for Your violations 341 | of this Public License. 342 | 343 | c. For the avoidance of doubt, the Licensor may also offer the 344 | Licensed Material under separate terms or conditions or stop 345 | distributing the Licensed Material at any time; however, doing so 346 | will not terminate this Public License. 347 | 348 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 349 | License. 350 | 351 | 352 | Section 7 -- Other Terms and Conditions. 353 | 354 | a. The Licensor shall not be bound by any additional or different 355 | terms or conditions communicated by You unless expressly agreed. 356 | 357 | b. Any arrangements, understandings, or agreements regarding the 358 | Licensed Material not stated herein are separate from and 359 | independent of the terms and conditions of this Public License. 360 | 361 | 362 | Section 8 -- Interpretation. 363 | 364 | a. For the avoidance of doubt, this Public License does not, and 365 | shall not be interpreted to, reduce, limit, restrict, or impose 366 | conditions on any use of the Licensed Material that could lawfully 367 | be made without permission under this Public License. 368 | 369 | b. To the extent possible, if any provision of this Public License is 370 | deemed unenforceable, it shall be automatically reformed to the 371 | minimum extent necessary to make it enforceable. If the provision 372 | cannot be reformed, it shall be severed from this Public License 373 | without affecting the enforceability of the remaining terms and 374 | conditions. 375 | 376 | c. No term or condition of this Public License will be waived and no 377 | failure to comply consented to unless expressly agreed to by the 378 | Licensor. 379 | 380 | d. Nothing in this Public License constitutes or may be interpreted 381 | as a limitation upon, or waiver of, any privileges and immunities 382 | that apply to the Licensor or You, including from the legal 383 | processes of any jurisdiction or authority. 384 | 385 | 386 | ======================================================================= 387 | 388 | Creative Commons is not a party to its public 389 | licenses. Notwithstanding, Creative Commons may elect to apply one of 390 | its public licenses to material it publishes and in those instances 391 | will be considered the “Licensor.” The text of the Creative Commons 392 | public licenses is dedicated to the public domain under the CC0 Public 393 | Domain Dedication. Except for the limited purpose of indicating that 394 | material is shared under a Creative Commons public license or as 395 | otherwise permitted by the Creative Commons policies published at 396 | creativecommons.org/policies, Creative Commons does not authorize the 397 | use of the trademark "Creative Commons" or any other trademark or logo 398 | of Creative Commons without its prior written consent including, 399 | without limitation, in connection with any unauthorized modifications 400 | to any of its public licenses or any other arrangements, 401 | understandings, or agreements concerning use of licensed material. For 402 | the avoidance of doubt, this paragraph does not form part of the 403 | public licenses. 404 | 405 | Creative Commons may be contacted at creativecommons.org. 406 | 407 | 408 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Context 2 | 3 | This repository is the basis for the blog post found here: https://blog.sigmaprime.io/solidity-security.html. 4 | 5 | It forms the basis of the Smart Contract Security section in the Mastering Ethereum book: https://github.com/ethereumbook/ethereumbook 6 | 7 | # Summary 8 | 9 | This post aims to be a relatively in-depth and up-to-date introductory post detailing the past mistakes that have been made by Solidity developers in an effort to prevent future devs from repeating history. 10 | 11 | Although in its infancy, Solidity has had widespread adoption and is used to compile the byte-code in many Ethereum smart contracts we see today. There have been a number of harsh lessons learnt by developers and users alike in discovering the nuances of the language and the EVM. This post aims to be a relatively in-depth and up-to-date introductory post detailing the past mistakes that have been made by Solidity developers in an effort to prevent future devs from repeating history. 12 | 13 | *As this is a rapidly changing area, I've put this post on [Github](https://github.com/sigp/solidity-security-blog) to encourage anyone/everyone to contribute to this post or submit issues for the errors that I've surely made.* 14 | 15 | # Table of Contents 16 | 17 | #### [1. Re-Entrancy](#reentrancy) 18 | * [The Vulnerability](#re-vuln) 19 | * [Preventative Techniques](#re-prev) 20 | * [Real-World Example: The DAO](#re-example) 21 | 22 | #### [2. Arithmetic Over/Under Flows](#ouflow) 23 | * [The Vulnerability](#ou-vuln) 24 | * [Preventative Techniques](#ou-prev) 25 | * [Real-World Examples: PoWHC and Batch Transfer Overflow (CVE-2018-10299)](#ou-example) 26 | 27 | #### [3. Unexpected Ether](#ether) 28 | * [The Vulnerability](#ether-vuln) 29 | * [Preventative Techniques](#ether-prev) 30 | * [Real-World Examples: Unknown](#ether-example) 31 | 32 | #### [4. Delegatecall](#delegatecall) 33 | * [The Vulnerability](#dc-vuln) 34 | * [Preventative Techniques](#dc-prev) 35 | * [Real-World Examples: Parity Multisig Wallet (Second Hack)](#dc-example) 36 | 37 | #### [5. Default Visibilities](#visibility) 38 | * [The Vulnerability](#visibility-vuln) 39 | * [Preventative Techniques](#visibility-prev) 40 | * [Real-World Example: Parity MultiSig Wallet (First Hack)](#visibility-example) 41 | 42 | #### [6. Entropy Illusion](#entropy) 43 | * [The Vulnerability](#entropy-vuln) 44 | * [Preventative Techniques](#entropy-prev) 45 | * [Real-World Example: PRNG Contracts](#entropy-example) 46 | 47 | #### [7. External Contract Referencing](#contract-reference) 48 | * [The Vulnerability](#cr-vuln) 49 | * [Preventative Techniques](#cr-prev) 50 | * [Real-World Example: Re-Entrancy Honey Pot](#cr-example) 51 | 52 | #### [8. Short Address/Parameter Attack](#short-address) 53 | * [The Vulnerability](#short-vuln) 54 | * [Preventative Techniques](#short-prev) 55 | * [Real-World Example: Unknown](#short-example) 56 | 57 | #### [9. Unchecked CALL Return Values](#unchecked-calls) 58 | * [The Vulnerability](#unchecked-calls-vuln) 59 | * [Preventative Techniques](#unchecked-calls-prev) 60 | * [Real-World Examples: Etherpot and King of the Ether](#unchecked-calls-example) 61 | 62 | #### [10. Race Conditions / Front Running](#race-conditions) 63 | * [The Vulnerability](#race-conditions-vuln) 64 | * [Preventative Techniques](#race-conditions-prev) 65 | * [Real-World Examples: ERC20 and Bancor](#race-conditions-example) 66 | 67 | #### [11. Denial Of Service (DOS)](#dos) 68 | * [The Vulnerability](#dos-vuln) 69 | * [Preventative Techniques](#dos-prev) 70 | * [Real-World Example: GovernMental](#dos-example) 71 | 72 | #### [12. Block Timestamp Manipulation](#block-timestamp) 73 | * [The Vulnerability](#block-timestamp-vuln) 74 | * [Preventative Techniques](#block-timestamp-prev) 75 | * [Real-World Example: GovernMental](#block-timestamp-example) 76 | 77 | #### [13. Constructors with Care](#constructors) 78 | * [The Vulnerability](#constructors-vuln) 79 | * [Preventative Techniques](#constructors-prev) 80 | * [Real-World Example: Rubixi](#constructors-example) 81 | 82 | #### [14. Uninitialised Storage Pointers](#storage) 83 | * [The Vulnerability](#storage-vuln) 84 | * [Preventative Techniques](#storage-prev) 85 | * [Real-World Examples: Honey Pots: OpenAddressLottery and CryptoRoulette](#storage-example) 86 | 87 | #### [15. Floating Points and Numerical Precision](#precision) 88 | * [The Vulnerability](#precision-vuln) 89 | * [Preventative Techniques](#precision-prev) 90 | * [Real-World Example: Ethstick](#precision-example) 91 | 92 | #### [16. tx.origin Authentication](#tx-origin) 93 | * [The Vulnerability](#tx-origin-vuln) 94 | * [Preventative Techniques](#tx-origin-prev) 95 | * [Real-World Example: Unknown](#tx-origin-example) 96 | 97 | ## [Ethereum Quirks](#ethereum-quirks) 98 | * [Keyless Ether](#keyless-eth) 99 | * [One Time Addresses](#one-time-addresses) 100 | * [Single Transaction Airdrops](#single-transaction-airdrops) 101 | 102 | ## [List of Interesting Crypto Related Hacks/Bugs](#hacks) 103 | 104 | 105 | ## References / Further Reading List 106 | 107 | - [Ethereum Wiki - Safety](https://github.com/ethereum/wiki/wiki/Safety) 108 | - [Solidity Docs - Security Considerations](solidity.readthedocs.io/en/latest/security-considerations.html) 109 | - [Consensus - Ethereum Smart Contract Best Practices](https://consensys.github.io/smart-contract-best-practices) 110 | - [History of Ethereum Security Vulnerabilities, Hacks and Their Fixes](https://applicature.com/blog/history-of-ethereum-security-vulnerabilities-hacks-and-their-fixes) 111 | - [Decentralized Application Security Project (DASP) Top 10 of 2018](http://www.dasp.co/) 112 | - [A Survey of attacks on Ethereum Smart Contracts](https://eprint.iacr.org/2016/1007.pdf) 113 | - [Ethereum Smart Contract Security](https://medium.com/cryptronics/ethereum-smart-contract-security-73b0ede73fa8) 114 | - [Lessons Learnt from the Underhanded Solidity Contest](https://medium.com/@chriseth/lessons-learnt-from-the-underhanded-solidity-contest-8388960e09b1) 115 | 116 |

1. Re-Entrancy

117 | 118 | One of the features of Ethereum smart contracts is the ability to call and utilise code of other external contracts. Contracts also typically handle ether, and as such often send ether to various external user addresses. The operation of calling external contracts, or sending ether to an address, requires the contract to submit an external call. These external calls can be hijacked by attackers whereby they force the contract to execute further code (i.e. through a fallback function) , including calls back into itself. Thus the code execution "*re-enters*" the contract. Attacks of this kind were used in the infamous DAO hack. 119 | 120 | For further reading on re-entrancy attacks, see [Reentrancy Attack On Smart Contracts](https://medium.com/@gus_tavo_guim/reentrancy-attack-on-smart-contracts-how-to-identify-the-exploitable-and-an-example-of-an-attack-4470a2d8dfe4) and [Consensus - Ethereum Smart Contract Best Practices](https://consensys.github.io/smart-contract-best-practices/known_attacks/#reentrancy). 121 | 122 |

The Vulnerability

123 | 124 | This attack can occur when a contract sends ether to an unknown address. An attacker can carefully construct a contract at an external address which contains malicious code in the [fallback function](https://solidity.readthedocs.io/en/latest/contracts.html?highlight=fallback#fallback-function). Thus, when a contract sends ether to this address, it will invoke the malicious code. Typically the malicious code executes a function on the vulnerable contract, performing operations not expected by the developer. The name "re-entrancy" comes from the fact that the external malicious contract calls back a function on the vulnerable contract and "*re-enters*" code execution at an arbitrary location on the vulnerable contract. 125 | 126 | To clarify this, consider the simple vulnerable contract, which acts as an Ethereum vault that allows depositors to only withdraw 1 ether per week. 127 | 128 | EtherStore.sol: 129 | ```solidity 130 | contract EtherStore { 131 | 132 | uint256 public withdrawalLimit = 1 ether; 133 | mapping(address => uint256) public lastWithdrawTime; 134 | mapping(address => uint256) public balances; 135 | 136 | function depositFunds() public payable { 137 | balances[msg.sender] += msg.value; 138 | } 139 | 140 | function withdrawFunds (uint256 _weiToWithdraw) public { 141 | require(balances[msg.sender] >= _weiToWithdraw); 142 | // limit the withdrawal 143 | require(_weiToWithdraw <= withdrawalLimit); 144 | // limit the time allowed to withdraw 145 | require(now >= lastWithdrawTime[msg.sender] + 1 weeks); 146 | require(msg.sender.call.value(_weiToWithdraw)()); 147 | balances[msg.sender] -= _weiToWithdraw; 148 | lastWithdrawTime[msg.sender] = now; 149 | } 150 | } 151 | ``` 152 | 153 | This contract has two public functions. `depositFunds()` and `withdrawFunds()`. The `depositFunds()` function simply increments the senders balances. The `withdrawFunds()` function allows the sender to specify the amount of wei to withdraw. It will only succeed if the requested amount to withdraw is less than 1 ether and a withdrawal hasn't occurred in the last week. Or does it?... 154 | 155 | The vulnerability comes on line \[17\] where we send the user their requested amount of ether. Consider a malicious attacker creating the following contract, 156 | 157 | Attack.sol: 158 | ```solidity 159 | import "EtherStore.sol"; 160 | 161 | contract Attack { 162 | EtherStore public etherStore; 163 | 164 | // initialise the etherStore variable with the contract address 165 | constructor(address _etherStoreAddress) { 166 | etherStore = EtherStore(_etherStoreAddress); 167 | } 168 | 169 | function pwnEtherStore() public payable { 170 | // attack to the nearest ether 171 | require(msg.value >= 1 ether); 172 | // send eth to the depositFunds() function 173 | etherStore.depositFunds.value(1 ether)(); 174 | // start the magic 175 | etherStore.withdrawFunds(1 ether); 176 | } 177 | 178 | function collectEther() public { 179 | msg.sender.transfer(this.balance); 180 | } 181 | 182 | // fallback function - where the magic happens 183 | function () payable { 184 | if (etherStore.balance > 1 ether) { 185 | etherStore.withdrawFunds(1 ether); 186 | } 187 | } 188 | } 189 | ``` 190 | 191 | Let us see how this malicious contract can exploit our `EtherStore` contract. The attacker would create the above contract (let's say at the address `0x0...123`) with the `EtherStore`'s contract address as the constructor parameter. This will initialize and point the public variable `etherStore` to the contract we wish to attack. 192 | 193 | The attacker would then call the `pwnEtherStore()` function, with some amount of ether (greater than or equal to 1), let's say `1 ether` for this example. In this example we assume a number of other users have deposited ether into this contract, such that it's current balance is `10 ether`. The following would then occur: 194 | 195 | 1. **Attack.sol - Line \[15\]** - The `depositFunds()` function of the EtherStore contract will be called with a `msg.value` of `1 ether` (and a lot of gas). The sender (`msg.sender`) will be our malicious contract (`0x0...123`). Thus, `balances[0x0..123] = 1 ether`. 196 | 197 | 2. **Attack.sol - Line \[17\]** - The malicious contract will then call the `withdrawFunds()` function of the `EtherStore` contract with a parameter of `1 ether`. This will pass all the requirements (Lines \[12\]-\[16\] of the `EtherStore` contract) as we have made no previous withdrawals. 198 | 199 | 3. **EtherStore.sol - Line \[17\]** - The contract will then send `1 ether` back to the malicious contract. 200 | 201 | 4. **Attack.sol - Line \[25\]** - The ether sent to the malicious contract will then execute the fallback function. 202 | 203 | 5. **Attack.sol - Line \[26\]** - The total balance of the EtherStore contract was `10 ether` and is now `9 ether` so this if statement passes. 204 | 205 | 6. **Attack.sol - Line \[27\]** - The fallback function then calls the `EtherStore` `withdrawFunds()` function again and "*re-enters*" the `EtherStore` contract. 206 | 207 | 7. **EtherStore.sol - Line \[11\]** - In this second call to `withdrawFunds()`, our balance is still `1 ether` as line \[18\] has not yet been executed. Thus, we still have `balances[0x0..123] = 1 ether`. This is also the case for the `lastWithdrawTime` variable. Again, we pass all the requirements. 208 | 209 | 8. **EtherStore.sol - Line \[17\]** - We withdraw another `1 ether`. 210 | 211 | 9. **Steps 4-8 will repeat** - until `EtherStore.balance >= 1` as dictated by line \[26\] in `Attack.sol`. 212 | 213 | 10. **Attack.sol - Line \[26\]** - Once there less 1 (or less) ether left in the `EtherStore` contract, this if statement will fail. This will then allow lines \[18\] and \[19\] of the `EtherStore` contract to be executed (for each call to the `withdrawFunds()` function). 214 | 215 | 11. **EtherStore.sol - Lines \[18\] and \[19\]** - The `balances` and `lastWithdrawTime` mappings will be set and the execution will end. 216 | 217 | The final result, is that the attacker has withdrawn all (bar 1) ether from the `EtherStore` contract, instantaneously with a single transaction. 218 | 219 |

Preventative Techniques

220 | 221 | There are a number of common techniques which help avoid potential re-entrancy vulnerabilities in smart contracts. The first is to ( whenever possible) use the built-in [transfer()](http://solidity.readthedocs.io/en/latest/units-and-global-variables.html#address-related) function when sending ether to external contracts. The transfer function only sends `2300 gas` with the external call, which isn't enough for the destination address/contract to call another contract (i.e. re-enter the sending contract). 222 | 223 | The second technique is to ensure that all logic that changes state variables happen before ether is sent out of the contract (or any external call). In the `EtherStore` example, lines \[18\] and \[19\] of `EtherStore.sol` should be put before line \[17\]. It is good practice to place any code that performs external calls to unknown addresses as the last operation in a localised function or piece of code execution. This is known as the [checks-effects-interactions](http://solidity.readthedocs.io/en/latest/security-considerations.html#use-the-checks-effects-interactions-pattern) pattern. 224 | 225 | A third technique is to introduce a mutex. That is, to add a state variable which locks the contract during code execution, preventing reentrancy calls. 226 | 227 | Applying all of these techniques (all three are unnecessary, but is done for demonstrative purposes) to `EtherStore.sol`, gives the re-entrancy-free contract: 228 | ```solidity 229 | contract EtherStore { 230 | 231 | // initialise the mutex 232 | bool reEntrancyMutex = false; 233 | uint256 public withdrawalLimit = 1 ether; 234 | mapping(address => uint256) public lastWithdrawTime; 235 | mapping(address => uint256) public balances; 236 | 237 | function depositFunds() public payable { 238 | balances[msg.sender] += msg.value; 239 | } 240 | 241 | function withdrawFunds (uint256 _weiToWithdraw) public { 242 | require(!reEntrancyMutex); 243 | require(balances[msg.sender] >= _weiToWithdraw); 244 | // limit the withdrawal 245 | require(_weiToWithdraw <= withdrawalLimit); 246 | // limit the time allowed to withdraw 247 | require(now >= lastWithdrawTime[msg.sender] + 1 weeks); 248 | balances[msg.sender] -= _weiToWithdraw; 249 | lastWithdrawTime[msg.sender] = now; 250 | // set the reEntrancy mutex before the external call 251 | reEntrancyMutex = true; 252 | msg.sender.transfer(_weiToWithdraw); 253 | // release the mutex after the external call 254 | reEntrancyMutex = false; 255 | } 256 | } 257 | ``` 258 | 259 |

Real-World Example: The DAO

260 | 261 | [The DAO](https://en.wikipedia.org/wiki/The_DAO_(organization)) (Decentralized Autonomous Organization) was one of the major hacks that occurred in the early development of Ethereum. At the time, the contract held over $150 million USD. Re-entrancy played a major role in the attack which ultimately lead to the hard-fork that created Ethereum Classic (ETC). For a good analysis of the DAO exploit, see [Phil Daian's post](http://hackingdistributed.com/2016/06/18/analysis-of-the-dao-exploit/). 262 | 263 |

2. Arithmetic Over/Under Flows

264 | 265 | The Ethereum Virtual Machine (EVM) specifies fixed-size data types for integers. This means that an integer variable, only has a certain range of numbers it can represent. A `uint8` for example, can only store numbers in the range \[0,255\]. Trying to store `256` into a `uint8` will result in `0`. If care is not taken, variables in Solidity can be exploited if user input is unchecked and calculations are performed which result in numbers that lie outside the range of the data type that stores them. 266 | 267 | For further reading on arithmetic over/under flows, see [How to Secure Your Smart Contracts](https://medium.com/loom-network/how-to-secure-your-smart-contracts-6-solidity-vulnerabilities-and-how-to-avoid-them-part-1-c33048d4d17d), [Ethereum Smart Contract Best Practices](https://consensys.github.io/smart-contract-best-practices/known_attacks/#integer-overflow-and-underflow) and [Ethereum, Solidity and integer overflows: programming blockchains like 1970](https://randomoracle.wordpress.com/2018/04/27/ethereum-solidity-and-integer-overflows-programming-blockchains-like-1970/) 268 | 269 |

The Vulnerability

270 | 271 | An over/under flow occurs when an operation is performed that requires a fixed size variable to store a number (or piece of data) that is outside the range of the variable's data type. 272 | 273 | For example, subtracting `1` from a `uint8` (unsigned integer of 8 bits, i.e. only positive) variable that stores `0` as it's value, will result in the number `255`. This is an underflow. We have assigned a number below the range of the `uint8`, the result *wraps around* and gives the largest number a `uint8` can store. Similarly, adding `2^8=256` to a `uint8` will leave the variable unchanged as we have wrapped around the entire length of the `uint` (for the mathematicians, this is similar to adding $2\pi$ to the angle of a trigonometric function, $\sin(x) = \sin(x+2\pi)$). Adding numbers larger than the data type's range is called an overflow. For clarity, adding `257` to a `uint8` that currently has a zero value will result in the number `1`. It's sometimes instructive to think of fixed type variables being cyclic, where we start again from zero if we add numbers above the largest possible stored number, and vice-versa for zero (where we start counting down from the largest number the more we subtract from 0). 274 | 275 | These kinds of numerical caveats allow attackers to misuse code and create unexpected logic flows. For example, consider the time locking contract below. 276 | 277 | TimeLock.sol: 278 | ```solidity 279 | contract TimeLock { 280 | 281 | mapping(address => uint) public balances; 282 | mapping(address => uint) public lockTime; 283 | 284 | function deposit() public payable { 285 | balances[msg.sender] += msg.value; 286 | lockTime[msg.sender] = now + 1 weeks; 287 | } 288 | 289 | function increaseLockTime(uint _secondsToIncrease) public { 290 | lockTime[msg.sender] += _secondsToIncrease; 291 | } 292 | 293 | function withdraw() public { 294 | require(balances[msg.sender] > 0); 295 | require(now > lockTime[msg.sender]); 296 | uint transferValue = balances[msg.sender]; 297 | balances[msg.sender] = 0; 298 | msg.sender.transfer(transferValue); 299 | } 300 | } 301 | ``` 302 | 303 | This contract is designed to act like a time vault, where users can deposit ether into the contract and it will be locked there for at least a week. The user may extend the wait time to longer than 1 week if they choose, but once deposited, the user can be sure their ether is locked in safely for at least a week. Or can they?... 304 | 305 | In the event a user is forced to hand over their private key (think hostage situation) a contract such as this may be handy to ensure ether is unobtainable in short periods of time. If a user had locked in `100 ether` in this contract and handed their keys over to an attacker, an attacker could use an overflow to receive the ether, regardless of the `lockTime`. 306 | 307 | The attacker could determine the current `lockTime` for the address they now hold the key for (its a public variable). Let's call this `userLockTime`. They could then call the `increaseLockTime` function and pass as an argument the number `2^256 - userLockTime`. This number would be added to the current `userLockTime` and cause an overflow, resetting `lockTime[msg.sender]` to `0`. The attacker could then simply call the `withdraw` function to obtain their reward. 308 | 309 | Let's look at another example, this one from the [Ethernaut Challanges](https://github.com/OpenZeppelin/ethernaut). 310 | 311 | **SPOILER ALERT:** *If you've not yet done the Ethernaut challenges, this gives a solution to one of the levels*. 312 | 313 | ```solidity 314 | pragma solidity ^0.4.18; 315 | 316 | contract Token { 317 | 318 | mapping(address => uint) balances; 319 | uint public totalSupply; 320 | 321 | function Token(uint _initialSupply) { 322 | balances[msg.sender] = totalSupply = _initialSupply; 323 | } 324 | 325 | function transfer(address _to, uint _value) public returns (bool) { 326 | require(balances[msg.sender] - _value >= 0); 327 | balances[msg.sender] -= _value; 328 | balances[_to] += _value; 329 | return true; 330 | } 331 | 332 | function balanceOf(address _owner) public constant returns (uint balance) { 333 | return balances[_owner]; 334 | } 335 | } 336 | ``` 337 | 338 | This is a simple token contract which employs a `transfer()` function, allowing participants to move their tokens around. Can you see the error in this contract? 339 | 340 | The flaw comes in the `transfer()` function. The require statement on line \[13\] can be bypassed using an underflow. Consider a user that has no balance. They could call the `transfer()` function with any non-zero `_value` and pass the require statement on line \[13\]. This is because `balances[msg.sender]` is zero (and a `uint256`) so subtracting any positive amount (excluding `2^256`) will result in a positive number due to the underflow we described above. This is also true for line \[14\], where our balance will be credited with a positive number. Thus, in this example, we have achieved free tokens due to an underflow vulnerability. 341 | 342 |

Preventative Techniques

343 | 344 | The (currently) conventional technique to guard against under/overflow vulnerabilities is to use or build mathematical libraries which replace the standard math operators; addition, subtraction and multiplication (division is excluded as it doesn't cause over/under flows and the EVM reverts on division by 0). 345 | 346 | [OppenZepplin](https://github.com/OpenZeppelin/zeppelin-solidity) have done a great job in building and auditing secure libraries which can be leveraged by the Ethereum community. In particular, their [Safe Math Library](https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/math/SafeMath.sol) is a reference or library to use to avoid under/over flow vulnerabilities. 347 | 348 | To demonstrate how these libraries are used in Solidity, let us correct the `TimeLock` contract, using Open Zepplin's `SafeMath` library. The over flow-free contract would become: 349 | 350 | ```solidity 351 | library SafeMath { 352 | 353 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 354 | if (a == 0) { 355 | return 0; 356 | } 357 | uint256 c = a * b; 358 | assert(c / a == b); 359 | return c; 360 | } 361 | 362 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 363 | // assert(b > 0); // Solidity automatically throws when dividing by 0 364 | uint256 c = a / b; 365 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 366 | return c; 367 | } 368 | 369 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 370 | assert(b <= a); 371 | return a - b; 372 | } 373 | 374 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 375 | uint256 c = a + b; 376 | assert(c >= a); 377 | return c; 378 | } 379 | } 380 | 381 | contract TimeLock { 382 | using SafeMath for uint; // use the library for uint type 383 | mapping(address => uint256) public balances; 384 | mapping(address => uint256) public lockTime; 385 | 386 | function deposit() public payable { 387 | balances[msg.sender] = balances[msg.sender].add(msg.value); 388 | lockTime[msg.sender] = now.add(1 weeks); 389 | } 390 | 391 | function increaseLockTime(uint256 _secondsToIncrease) public { 392 | lockTime[msg.sender] = lockTime[msg.sender].add(_secondsToIncrease); 393 | } 394 | 395 | function withdraw() public { 396 | require(balances[msg.sender] > 0); 397 | require(now > lockTime[msg.sender]); 398 | uint transferValue = balances[msg.sender]; 399 | balances[msg.sender] = 0; 400 | msg.sender.transfer(transferValue); 401 | } 402 | } 403 | ``` 404 | 405 | Notice that all standard math operations have been replaced by the those defined in the `SafeMath` library. The `TimeLock` contract no longer performs any operation which is capable of doing an under/over flow. 406 | 407 |

Real-World Examples: PoWHC and Batch Transfer Overflow (CVE-2018–10299)

408 | 409 | A 4chan group decided it was a great idea to build a ponzi scheme on Ethereum, written in Solidity. They called it the Proof of Weak Hands Coin (PoWHC). Unfortunately it seems that the author(s) of the contract hadn't seen over/under flows before and consequently, 866 ether was liberated from its contract. A good overview of how the underflow occurs (which is not too dissimilar to the Ethernaut challenge above) is given in [Eric Banisadar's post](https://blog.goodaudience.com/how-800k-evaporated-from-the-powh-coin-ponzi-scheme-overnight-1b025c33b530). 410 | 411 | Some developers also implemented a `batchTransfer()` function into some [ERC20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) token contracts. The implementation contained an overflow. [This post](https://medium.com/@peckshield/alert-new-batchoverflow-bug-in-multiple-erc20-smart-contracts-cve-2018-10299-511067db6536) explains it, however I think the title is misleading, in that it has nothing to do with the ERC20 standard, rather some ERC20 token contracts have a vulnerable `batchTransfer()` function implemented. 412 | 413 |

3. Unexpected Ether

414 | 415 | Typically when ether is sent to a contract, it must execute either the fallback function, or another function described in the contract. There are two exceptions to this, where ether can exist in a contract without having executed any code. Contracts which rely on code execution for every ether sent to the contract can be vulnerable to attacks where ether is forcibly sent to a contract. 416 | 417 | For further reading on this, see [How to Secure Your Smart Contracts: 6](https://medium.com/loom-network/how-to-secure-your-smart-contracts-6-solidity-vulnerabilities-and-how-to-avoid-them-part-2-730db0aa4834) and [ Solidity security patterns - forcing ether to a contract ](http://danielszego.blogspot.com.au/2018/03/solidity-security-patterns-forcing.html). 418 | 419 |

The Vulnerability

420 | 421 | A common defensive programming technique that is useful in enforcing correct state transitions or validating operations is *invariant-checking*. This technique involves defining a set of invariants (metrics or parameters that should not change) and checking these invariants remain unchanged after a single (or many) operation(s). This is typically good design, provided the invariants being checked are in fact invariants. One example of an invariant is the `totalSupply` of a fixed issuance [ERC20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) token. As no functions should modify this invariant, one could add a check to the `transfer()` function that ensures the `totalSupply` remains unmodified to ensure the function is working as expected. 422 | 423 | In particular, there is one apparent *invariant*, that may be tempting to use 424 | but can in fact be manipulated by external users (regardless of the rules put 425 | in place in the smart contract) .This is the current ether stored in the 426 | contract. Often when developers first learn Solidity they have the 427 | misconception that a contract can only accept or obtain ether via payable 428 | functions. This misconception can lead to contracts that have false 429 | assumptions about the ether balance within them which can lead to a range of 430 | vulnerabilities. The smoking gun for this vulnerability is the (incorrect) use 431 | of `this.balance`. As we will see, incorrect uses of `this.balance` can lead to 432 | serious vulnerabilities of this type. 433 | 434 | There are two ways in which ether can (forcibly) be sent to a contract without using a `payable` function or executing any code on the contract. These are listed below. 435 | 436 | #### Self Destruct / Suicide 437 | 438 | Any contract is able to implement the [`selfdestruct(address)`](http://solidity.readthedocs.io/en/latest/introduction-to-smart-contracts.html#self-destruct) function, which removes all bytecode from the contract address and sends all ether stored there to the parameter-specified address. If this specified address is also a contract, no functions (including the fallback) get called. Therefore, the `selfdestruct()` function can be used to forcibly send ether to any contract regardless of any code that may exist in the contract. This is inclusive of contracts without any payable functions. This means, any attacker can create a contract with a `selfdestruct()` function, send ether to it, call `selfdestruct(target)` and force ether to be sent to a `target` contract. Martin Swende has an excellent [blog post](http://martin.swende.se/blog/Ethereum_quirks_and_vulns.html) describing some quirks of the self-destruct opcode (Quirk #2) along with a description of how client nodes were checking incorrect invariants which could have lead to a rather catastrophic nuking of clients. 439 | 440 | #### Pre-sent Ether 441 | 442 | The second way a contract can obtain ether without using a `selfdestruct()` function or calling any payable functions is to pre-load the contract address with ether. Contract addresses are deterministic, in fact the address is calculated from the keccak256 (sometimes synonomous with SHA3) hash of the address creating the contract and the transaction nonce which creates the contract. Specifically, it is of the form: `address = sha3(rlp.encode([account_address,transaction_nonce]))` (see [Keyless Ether](#keyless-eth) for some fun use cases of this). This means, anyone can calculate what a contract address will be before it is created and thus send ether to that address. When the contract does get created it will have a non-zero ether balance. 443 | 444 | Let's explore some pitfalls that can arise given the above knowledge. 445 | 446 | Consider the overly-simple contract, 447 | 448 | EtherGame.sol: 449 | ```solidity 450 | contract EtherGame { 451 | 452 | uint public payoutMileStone1 = 3 ether; 453 | uint public mileStone1Reward = 2 ether; 454 | uint public payoutMileStone2 = 5 ether; 455 | uint public mileStone2Reward = 3 ether; 456 | uint public finalMileStone = 10 ether; 457 | uint public finalReward = 5 ether; 458 | 459 | mapping(address => uint) redeemableEther; 460 | // users pay 0.5 ether. At specific milestones, credit their accounts 461 | function play() public payable { 462 | require(msg.value == 0.5 ether); // each play is 0.5 ether 463 | uint currentBalance = this.balance + msg.value; 464 | // ensure no players after the game as finished 465 | require(currentBalance <= finalMileStone); 466 | // if at a milestone credit the players account 467 | if (currentBalance == payoutMileStone1) { 468 | redeemableEther[msg.sender] += mileStone1Reward; 469 | } 470 | else if (currentBalance == payoutMileStone2) { 471 | redeemableEther[msg.sender] += mileStone2Reward; 472 | } 473 | else if (currentBalance == finalMileStone ) { 474 | redeemableEther[msg.sender] += finalReward; 475 | } 476 | return; 477 | } 478 | 479 | function claimReward() public { 480 | // ensure the game is complete 481 | require(this.balance == finalMileStone); 482 | // ensure there is a reward to give 483 | require(redeemableEther[msg.sender] > 0); 484 | uint transferValue = redeemableEther[msg.sender]; 485 | redeemableEther[msg.sender] = 0; 486 | msg.sender.transfer(transferValue); 487 | } 488 | } 489 | ``` 490 | 491 | This contract represents a simple game (which would naturally invoke [race-conditions](#race-conditions)) whereby players send `0.5 ether` quanta to the contract in hope to be the player that reaches one of three milestones first. Milestone's are denominated in ether. The first to reach the milestone may claim a portion of the ether when the game has ended. The game ends when the final milestone (`10 ether`) is reached and users can claim their rewards. 492 | 493 | The issues with the `EtherGame` contract come from the poor use of `this.balance` in both lines \[14\] (and by association \[16\]) and \[32\]. A mischievous attacker could forcibly send a small amount of ether, let's say `0.1 ether` via the `selfdestruct()` function (discussed above) to prevent any future players from reaching a milestone. As all legitimate players can only send `0.5 ether` increments, `this.balance` would no longer be half integer numbers, as it would also have the `0.1 ether` contribution. This prevents all the if conditions on lines \[18\], \[21\] and \[24\] from being true. 494 | 495 | Even worse, a vengeful attacker who missed a milestone, could forcibly send `10 ether` (or an equivalent amount of ether that pushes the contract's balance above the `finalMileStone`) which would lock all rewards in the contract forever. This is because the `claimReward()` function will always revert, due to the require on line \[32\] (i.e. `this.balance` is greater than `finalMileStone`). 496 | 497 |

Preventative Techniques

498 | 499 | This vulnerability typically arises from the misuse of `this.balance`. Contract logic, when possible, should avoid being dependent on exact values of the balance of the contract because it can be artificially manipulated. If applying logic based on `this.balance`, ensure to account for unexpected balances. 500 | 501 | If exact values of deposited ether are required, a self-defined variable should be used that gets incremented in payable functions, to safely track the deposited ether. This variable will not be influenced by the forced ether sent via a `selfdestruct()` call. 502 | 503 | With this in mind, a corrected version of the `EtherGame` contract could look like: 504 | ```solidity 505 | contract EtherGame { 506 | 507 | uint public payoutMileStone1 = 3 ether; 508 | uint public mileStone1Reward = 2 ether; 509 | uint public payoutMileStone2 = 5 ether; 510 | uint public mileStone2Reward = 3 ether; 511 | uint public finalMileStone = 10 ether; 512 | uint public finalReward = 5 ether; 513 | uint public depositedWei; 514 | 515 | mapping (address => uint) redeemableEther; 516 | 517 | function play() public payable { 518 | require(msg.value == 0.5 ether); 519 | uint currentBalance = depositedWei + msg.value; 520 | // ensure no players after the game as finished 521 | require(currentBalance <= finalMileStone); 522 | if (currentBalance == payoutMileStone1) { 523 | redeemableEther[msg.sender] += mileStone1Reward; 524 | } 525 | else if (currentBalance == payoutMileStone2) { 526 | redeemableEther[msg.sender] += mileStone2Reward; 527 | } 528 | else if (currentBalance == finalMileStone ) { 529 | redeemableEther[msg.sender] += finalReward; 530 | } 531 | depositedWei += msg.value; 532 | return; 533 | } 534 | 535 | function claimReward() public { 536 | // ensure the game is complete 537 | require(depositedWei == finalMileStone); 538 | // ensure there is a reward to give 539 | require(redeemableEther[msg.sender] > 0); 540 | uint transferValue = redeemableEther[msg.sender]; 541 | redeemableEther[msg.sender] = 0; 542 | msg.sender.transfer(transferValue); 543 | } 544 | } 545 | ``` 546 | Here, we have just created a new variable, `depositedWei` which keeps track of the known ether deposited, and it is this variable to which we perform our requirements and tests. Notice, that we no longer have any reference to `this.balance`. 547 | 548 |

Real-World Example: Unknown

549 | 550 | I'm yet to find an example of this that has been exploited in the wild. However, a few examples of exploitable contracts were given in the [Underhanded Solidity Contest](https://github.com/Arachnid/uscc/tree/master/submissions-2017/). 551 | 552 |

4. Delegatecall

553 | 554 | The `CALL` and `DELEGATECALL` opcodes are useful in allowing Ethereum developers to modularise their code. Standard external message calls to contracts are handled by the `CALL` opcode whereby code is run in the context of the external contract/function. The `DELEGATECALL` opcode is identical to the standard message call, except that the code executed at the targeted address is run in the context of the calling contract along with the fact that `msg.sender` and `msg.value` remain unchanged. This feature enables the implementation of *libraries* whereby developers can create reusable code for future contracts. 555 | 556 | Although the differences between these two opcodes are simple and intuitive, the use of `DELEGATECALL` can lead to unexpected code execution. 557 | 558 | For further reading, see [Ethereum Stack Exchange Question](https://ethereum.stackexchange.com/questions/3667/difference-between-call-callcode-and-delegatecall), [Solidity Docs](http://solidity.readthedocs.io/en/latest/introduction-to-smart-contracts.html#delegatecall-callcode-and-libraries) and [How to Secure Your Smart Contracts: 6](https://medium.com/loom-network/how-to-secure-your-smart-contracts-6-solidity-vulnerabilities-and-how-to-avoid-them-part-1-c33048d4d17d). 559 | 560 |

The Vulnerability

561 | 562 | The context preserving nature of `DELEGATECALL` has proved that building vulnerability-free custom libraries is not as easy as one might think. The code in libraries themselves can be secure and vulnerability-free however when run in the context of another application new vulnerabilities can arise. Let's see a fairly complex example of this, using Fibonacci numbers. 563 | 564 | Consider the following library which can generate the Fibonacci sequence and sequences of similar form. 565 | `FibonacciLib.sol`[^1] 566 | ```solidity 567 | // library contract - calculates fibonacci-like numbers; 568 | contract FibonacciLib { 569 | // initializing the standard fibonacci sequence; 570 | uint public start; 571 | uint public calculatedFibNumber; 572 | 573 | // modify the zeroth number in the sequence 574 | function setStart(uint _start) public { 575 | start = _start; 576 | } 577 | 578 | function setFibonacci(uint n) public { 579 | calculatedFibNumber = fibonacci(n); 580 | } 581 | 582 | function fibonacci(uint n) internal returns (uint) { 583 | if (n == 0) return start; 584 | else if (n == 1) return start + 1; 585 | else return fibonacci(n - 1) + fibonacci(n - 2); 586 | } 587 | } 588 | ``` 589 | This library provides a function which can generate the *n*-th Fibonacci number in the sequence. It allows users to change the starting number of the sequence (`start`) and calculate the *n*-th Fibonacci-like numbers in this new sequence. 590 | 591 | Let's now consider a contract that utilises this library. 592 | 593 | 594 | `FibonacciBalance.sol`: 595 | ```solidity 596 | contract FibonacciBalance { 597 | 598 | address public fibonacciLibrary; 599 | // the current fibonacci number to withdraw 600 | uint public calculatedFibNumber; 601 | // the starting fibonacci sequence number 602 | uint public start = 3; 603 | uint public withdrawalCounter; 604 | // the fibonancci function selector 605 | bytes4 constant fibSig = bytes4(sha3("setFibonacci(uint256)")); 606 | 607 | // constructor - loads the contract with ether 608 | constructor(address _fibonacciLibrary) public payable { 609 | fibonacciLibrary = _fibonacciLibrary; 610 | } 611 | 612 | function withdraw() { 613 | withdrawalCounter += 1; 614 | // calculate the fibonacci number for the current withdrawal user 615 | // this sets calculatedFibNumber 616 | require(fibonacciLibrary.delegatecall(fibSig, withdrawalCounter)); 617 | msg.sender.transfer(calculatedFibNumber * 1 ether); 618 | } 619 | 620 | // allow users to call fibonacci library functions 621 | function() public { 622 | require(fibonacciLibrary.delegatecall(msg.data)); 623 | } 624 | } 625 | 626 | ``` 627 | This contract allows a participant to withdraw ether from the contract, with the amount of ether being equal to the Fibonacci number corresponding to the participants withdrawal order; i.e., the first participant gets 1 ether, the second also gets 1, the third gets 2, the forth gets 3, the fifth 5 and so on (until the balance of the contract is less than the Fibonacci number being withdrawn). 628 | 629 | There are a number of elements in this contract that may require some explanation. Firstly, there is an interesting-looking variable, `fibSig`. This holds the first 4 bytes of the Keccak (SHA-3) hash of the string "setFibonacci(uint256)". This is known as the [function selector](https://solidity.readthedocs.io/en/latest/abi-spec.html#function-selector) and is put into `calldata` to specify which function of a smart contract will be called. It is used in the `delegatecall` function on line \[21\] to specify that we wish to run the `setFibonacci(uint256)` function. The second argument in `delegatecall` is the parameter we are passing to the function. Secondly, we assume that the address for the `FibonacciLib` library is correctly referenced in the constructor (section [External Contract Referencing](#contract-reference) discuss some potential vulnerabilities relating to this kind of contract reference initialisation). 630 | 631 | Can you spot any error(s) in this contract? If you put this into remix, fill it with ether and call `withdraw()`, it will likely revert. 632 | 633 | You may have noticed that the state variable `start` is used in both the library and the main calling contract. In the library contract, `start` is used to specify the beginning of the Fibonacci sequence and is set to `0`, whereas it is set to `3` in the `FibonacciBalance` contract. You may also have noticed that the fallback function in the `FibonacciBalance` contract allows all calls to be passed to the library contract, which allows for the `setStart()` function of the library contract to be called also. Recalling that we preserve the state of the contract, it may seem that this function would allow you to change the state of the `start` variable in the local `FibonnacciBalance` contract. If so, this would allow one to withdraw more ether, as the resulting `calculatedFibNumber` is dependent on the `start` variable (as seen in the library contract). In actual fact, the `setStart()` function does not (and cannot) modify the `start` variable in the `FibonacciBalance` contract. The underlying vulnerability in this contract is significantly worse than just modifying the `start` variable. 634 | 635 | Before discussing the actual issue, we take a quick detour to understanding how state variables (`storage` variables) actually get stored in contracts. State or `storage` variables (variables that persist over individual transactions) are placed into `slots` sequentially as they are introduced in the contract. (There are some complexities here, and I encourage the reader to read [Layout of State Variables in Storage](http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage) for a more thorough understanding). 636 | 637 | As an example, let's look at the library contract. It has two state variables, `start` and `calculatedFibNumber`. The first variable is `start`, as such it gets stored into the contract's storage at `slot[0]` (i.e. the first slot). The second variable, `calculatedFibNumber`, gets placed in the next available storage slot, `slot[1]`. If we look at the function `setStart()`, it takes an input and sets `start` to whatever the input was. This function is therefore setting `slot[0]` to whatever input we provide in the `setStart()` function. Similarly, the `setFibonacci()` function sets `calculatedFibNumber` to the result of `fibonacci(n)`. Again, this is simply setting storage `slot[1]` to the value of `fibonacci(n)`. 638 | 639 | Now let's look at the `FibonacciBalance` contract. Storage `slot[0]` now corresponds to `fibonacciLibrary` address and `slot[1]` corresponds to `calculatedFibNumber`. It is in this incorrect mapping that the vulnerability occurs. `delegatecall` **preserves contract context**. This means that code that is executed via `delegatecall` will act on the state (i.e. storage) of the calling contract. 640 | 641 | Now notice that in `withdraw()` on line \[21\] we execute, `fibonacciLibrary.delegatecall(fibSig,withdrawalCounter)`. This calls the `setFibonacci()` function, which as we discussed, modifies storage `slot[1]`, which in our current context is `calculatedFibNumber`. This is as expected (i.e. after execution, `calculatedFibNumber` gets adjusted). However, recall that the `start` variable in the `FibonacciLib` contract is located in storage `slot[0]`, which is the `fibonacciLibrary` address in the current contract. This means that the function `fibonacci()` will give an unexpected result. This is because it references `start` (`slot[0]`) which in the current calling context is the `fibonacciLibrary` address (which will often be quite large, when interpreted as a `uint`). Thus it is likely that the `withdraw()` function will revert as it will not contain `uint(fibonacciLibrary)` amount of ether, which is what `calculatedFibNumber` will return. 642 | 643 | Even worse, the `FibonacciBalance` contract allows users to call all of the `fibonacciLibrary` functions via the fallback function on line \[26\]. As we discussed earlier, this includes the `setStart()` function. We discussed that this function allows anyone to modify or set storage `slot[0]`. In this case, storage `slot[0]` is the `fibonacciLibrary` address. Therefore, an attacker could create a malicious contract (an example of one is given below), convert the address to a `uint` (this can be done in python easily using `int('
',16)`) and then call `setStart()`. This will change `fibonacciLibrary` to the address of the attack contract. Then, whenever a user calls `withdraw()` or the fallback function, the malicious contract will run (which can steal the entire balance of the contract) because we've modified the actual address for `fibonacciLibrary`. An example of such an attack contract would be, 644 | 645 | ```solidity 646 | contract Attack { 647 | uint storageSlot0; // corresponds to fibonacciLibrary 648 | uint storageSlot1; // corresponds to calculatedFibNumber 649 | 650 | // fallback - this will run if a specified function is not found 651 | function() public { 652 | storageSlot1 = 0; // we set calculatedFibNumber to 0, so that if withdraw 653 | // is called we don't send out any ether. 654 | .transfer(this.balance); // we take all the ether 655 | } 656 | } 657 | ``` 658 | Notice that this attack contract modifies the `calculatedFibNumber` by changing storage `slot[1]`. In principle, an attacker could modify any other storage slots they choose to perform all kinds of attacks on this contract. I encourage all readers to put these contracts into [Remix](https://remix.ethereum.org) and experiment with different attack contracts and state changes through these `delegatecall` functions. 659 | 660 | It is also important to notice that when we say that `delegatecall` is state-preserving, we are not talking about the variable names of the contract, rather the actual storage slots to which those names point. As you can see from this example, a simple mistake, can lead to an attacker hijacking the entire contract and its ether. 661 | 662 |

Preventative Techniques

663 | 664 | Solidity provides the `library` keyword for implementing library contracts (see the [Solidity Docs](http://solidity.readthedocs.io/en/latest/contracts.html?highlight=library#libraries) for further details). This ensures the library contract is stateless and non-self-destructable. Forcing libraries to be stateless mitigates the complexities of storage context demonstrated in this section. Stateless libraries also prevent attacks whereby attackers modify the state of the library directly in order to affect the contracts that depend on the library's code. 665 | As a general rule of thumb, when using `DELEGATECALL` pay careful attention to the possible calling context of both the library contract and the calling contract, and whenever possible, build state-less libraries. 666 | 667 |

Real-World Example: Parity Multisig Wallet (Second Hack)

668 | 669 | The Second Parity Multisig Wallet hack is an example of how the context of well-written library code can be exploited if run in its non-intended context. There are a number of good explanations of this hack, such as this overview: [Parity MultiSig Hacked. Again](https://medium.com/chain-cloud-company-blog/parity-multisig-hack-again-b46771eaa838) by Anthony Akentiev, this [stack exchange question](https://ethereum.stackexchange.com/questions/30128/explanation-of-parity-library-suicide/30130) and [An In-Depth Look at the Parity Multisig Bug](http://hackingdistributed.com/2017/07/22/deep-dive-parity-bug/). 670 | 671 | To add to these references, let's explore the contracts that were exploited. The library and wallet contract can be found on the parity github [here](https://github.com/paritytech/parity/blob/b640df8fbb964da7538eef268dffc125b081a82f/js/src/contracts/snippets/enhanced-wallet.sol). 672 | 673 | Let's look at the relevant aspects of this contract. There are two contracts of interest contained here, the library contract and the wallet contract. 674 | 675 | The library contract, 676 | ```solidity 677 | contract WalletLibrary is WalletEvents { 678 | 679 | ... 680 | 681 | // throw unless the contract is not yet initialized. 682 | modifier only_uninitialized { if (m_numOwners > 0) throw; _; } 683 | 684 | // constructor - just pass on the owner array to the multiowned and 685 | // the limit to daylimit 686 | function initWallet(address[] _owners, uint _required, uint _daylimit) only_uninitialized { 687 | initDaylimit(_daylimit); 688 | initMultiowned(_owners, _required); 689 | } 690 | 691 | // kills the contract sending everything to `_to`. 692 | function kill(address _to) onlymanyowners(sha3(msg.data)) external { 693 | suicide(_to); 694 | } 695 | 696 | ... 697 | 698 | } 699 | ``` 700 | 701 | and the wallet contract, 702 | 703 | ```solidity 704 | contract Wallet is WalletEvents { 705 | 706 | ... 707 | 708 | // METHODS 709 | 710 | // gets called when no other function matches 711 | function() payable { 712 | // just being sent some cash? 713 | if (msg.value > 0) 714 | Deposit(msg.sender, msg.value); 715 | else if (msg.data.length > 0) 716 | _walletLibrary.delegatecall(msg.data); 717 | } 718 | 719 | ... 720 | 721 | // FIELDS 722 | address constant _walletLibrary = 0xcafecafecafecafecafecafecafecafecafecafe; 723 | } 724 | ``` 725 | Notice that the `Wallet` contract essentially passes all calls to the `WalletLibrary` contract via a delegate call. The constant `_walletLibrary` address in this code snippet acts as a placeholder for the actually deployed `WalletLibrary` contract (which was at `0x863DF6BFa4469f3ead0bE8f9F2AAE51c91A907b4`). 726 | 727 | The intended operation of these contracts was to have a simple low-cost deployable `Wallet` contract whose code base and main functionality was in the `WalletLibrary` contract. Unfortunately, the `WalletLibrary` contract is itself a contract and maintains it's own state. Can you see why this might be an issue? 728 | 729 | It is possible to send calls to the `WalletLibrary` contract itself. Specifically, the `WalletLibrary` contract could be initialised, and become owned. A user did this, by calling `initWallet()` function on the `WalletLibrary` contract, becoming an owner of the library contract. The same user, subsequently called the `kill()` function. Because the user was an owner of the Library contract, the modifier passed and the library contract suicided. As all `Wallet` contracts in existence refer to this library contract and contain no method to change this reference, all of their functionality, including the ability to withdraw ether is lost along with the `WalletLibrary` contract. More directly, all ether in all parity multi-sig wallets of this type instantly become lost or permanently unrecoverable. 730 | 731 |

5. Default Visibilities

732 | 733 | Functions in Solidity have visibility specifiers which dictate how functions are allowed to be called. The visibility determines whether a function can be called externally by users, by other derived contracts, only internally or only externally. There are four visibility specifiers, which are described in detail in the [Solidity Docs](http://solidity.readthedocs.io/en/latest/contracts.html?highlight=library#visibility-and-getters). Functions default to `public` allowing users to call them externally. Incorrect use of visibility specifiers can lead to some devestating vulernabilities in smart contracts as will be discussed in this section. 734 | 735 |

The Vulnerability

736 | 737 | The default visibility for functions is `public`. Therefore functions that do not specify any visibility will be callable by external users. The issue comes when developers mistakenly ignore visibility specifiers on functions which should be private (or only callable within the contract itself). 738 | 739 | Let's quickly explore a trivial example. 740 | 741 | ```solidity 742 | contract HashForEther { 743 | 744 | function withdrawWinnings() { 745 | // Winner if the last 8 hex characters of the address are 0. 746 | require(uint32(msg.sender) == 0); 747 | _sendWinnings(); 748 | } 749 | 750 | function _sendWinnings() { 751 | msg.sender.transfer(this.balance); 752 | } 753 | } 754 | ``` 755 | 756 | This simple contract is designed to act as an address guessing bounty game. To win the balance of the contract, a user must generate an Ethereum address whose last 8 hex characters are 0. Once obtained, they can call the `WithdrawWinnings()` function to obtain their bounty. 757 | 758 | Unfortunately, the visibility of the functions have not been specified. In particular, the `_sendWinnings()` function is `public` and thus any address can call this function to steal the bounty. 759 | 760 |

Preventative Techniques

761 | 762 | It is good practice to always specify the visibility of all functions in a contract, even if they are intentionally `public`. Recent versions of Solidity will now show warnings during compilation for functions that have no explicit visibility set, to help encourage this practice. 763 | 764 |

Real-World Example: Parity MultiSig Wallet (First Hack)

765 | 766 | In the first Parity multi-sig hack, about \$31M worth of Ether was stolen from primarily three wallets. A good recap of exactly how this was done is given by Haseeb Qureshi in [this post](https://medium.freecodecamp.org/a-hacker-stole-31m-of-ether-how-it-happened-and-what-it-means-for-ethereum-9e5dc29e33ce). 767 | 768 | Essentially, the multi-sig wallet (which can be found [here](https://github.com/paritytech/parity/blob/4d08e7b0aec46443bf26547b17d10cb302672835/js/src/contracts/snippets/enhanced-wallet.sol)) is constructed from a base `Wallet` contract which calls a library contract containing the core functionality (as was described in [Real-World Example: Parity Multisig (Second Hack)](#dc-example)). The library contract contains the code to initialise the wallet as can be seen from the following snippet 769 | ```solidity 770 | contract WalletLibrary is WalletEvents { 771 | 772 | ... 773 | 774 | // METHODS 775 | 776 | ... 777 | 778 | // constructor is given number of sigs required to do protected "onlymanyowners" transactions 779 | // as well as the selection of addresses capable of confirming them. 780 | function initMultiowned(address[] _owners, uint _required) { 781 | m_numOwners = _owners.length + 1; 782 | m_owners[1] = uint(msg.sender); 783 | m_ownerIndex[uint(msg.sender)] = 1; 784 | for (uint i = 0; i < _owners.length; ++i) 785 | { 786 | m_owners[2 + i] = uint(_owners[i]); 787 | m_ownerIndex[uint(_owners[i])] = 2 + i; 788 | } 789 | m_required = _required; 790 | } 791 | 792 | ... 793 | 794 | // constructor - just pass on the owner array to the multiowned and 795 | // the limit to daylimit 796 | function initWallet(address[] _owners, uint _required, uint _daylimit) { 797 | initDaylimit(_daylimit); 798 | initMultiowned(_owners, _required); 799 | } 800 | } 801 | ``` 802 | 803 | Notice that neither of the functions have explicitly specified a visibility. Both functions default to `public`. The `initWallet()` function is called in the wallets constructor and sets the owners for the multi-sig wallet as can be seen in the `initMultiowned()` function. Because these functions were accidentally left `public`, an attacker was able to call these functions on deployed contracts, resetting the ownership to the attackers address. Being the owner, the attacker then drained the wallets of all their ether, to the tune of \$31M. 804 | 805 |

6. Entropy Illusion

806 | 807 | All transactions on the Ethereum blockchain are deterministic state transition operations. Meaning that every transaction modifies the global state of the Ethereum ecosystem and it does so in a calculable way with no uncertainty. This ultimately means that inside the blockchain ecosystem there is no source of entropy or randomness. There is no `rand()` function in Solidity. Achieving decentralised entropy (randomness) is a well established problem and many ideas have been proposed to address this (see for example, [RandDAO](https://github.com/randao/randao) or using a chain of Hashes as described by Vitalik in this [post](https://vitalik.ca/files/randomness.html)). 808 | 809 |

The Vulnerability

810 | 811 | Some of the first contracts built on the Ethereum platform were based around gambling. Fundamentally, gambling requires uncertainty (something to bet on), which makes building a gambling system on the blockchain (a deterministic system) rather difficult. It is clear that the uncertainty must come from a source external to the blockchain. This is possible for bets amongst peers (see for example the [commit-reveal technique](https://ethereum.stackexchange.com/questions/191/how-can-i-securely-generate-a-random-number-in-my-smart-contract)), however, it is significantly more difficult if you want to implement a contract to act as *the house* (like in blackjack our roulette). A common pitfall is to use future block variables, such as hashes, timestamps, blocknumber or gas limit. The issue with these are that they are controlled by the miner who mines the block and as such are not truly random. Consider, for example, a roulette smart contract with logic that returns a black number if the next block hash ends in an even number. A miner (or miner pool) could bet \\$1M on black. If they solve the next block and find the hash ends in an odd number, they would happily not publish their block and mine another until they find a solution with the block hash being an even number (assuming the block reward and fees are less than $1M). Using past or present variables can be even more devastating as Martin Swende demonstrates in his excellent [blog post](http://martin.swende.se/blog/Breaking_the_house.html). Furthermore, using solely block variables mean that the pseudo-random number will be the same for all transactions in a block, so an attacker can multiply their wins by doing many transactions within a block (should there be a maximum bet). 812 | 813 |

Preventative Techniques

814 | 815 | The source of entropy (randomness) must be external to the blockchain. This can be done amongst peers with systems such as [commit-reveal](https://ethereum.stackexchange.com/questions/191/how-can-i-securely-generate-a-random-number-in-my-smart-contract), or via changing the trust model to a group of participants (such as in [RandDAO](https://github.com/randao/randao)). This can also be done via a centralised entity, which acts as a randomness oracle. Block variables (in general, there are some exceptions) should not be used to source entropy as they can be manipulated by miners. 816 | 817 |

Real-World Example: PRNG Contracts

818 | 819 | Arseny Reutov wrote a [blog post](https://blog.positive.com/predicting-random-numbers-in-ethereum-smart-contracts-e5358c6b8620) after he analysed 3649 live smart contracts which were using some sort of pseudo random number generator (PRNG) and found 43 contracts which could be exploited. 820 | 821 |

7. External Contract Referencing

822 | 823 | One of the benefits of the Ethereum *global computer* is the ability to re-use code and interact with contracts already deployed on the network. As a result, a large number of contracts reference external contracts and in general operation use external message calls to interact with these contracts. These external message calls can mask malicious actors intentions in some non-obvious ways, which we will discuss. 824 | 825 |

The Vulnerability

826 | 827 | In Solidity, any address can be cast as a contract regardless of whether the code at the address represents the contract type being cast. This can be deceiving, especially when the author of the contract is trying to hide malicious code. Let us illustrate this with an example: 828 | 829 | Consider a piece of code which rudimentarily implements the [Rot13](www.wikipedia.com/rot13) cipher. 830 | 831 | `Rot13Encryption.sol`: 832 | ```solidity 833 | //encryption contract 834 | contract Rot13Encryption { 835 | 836 | event Result(string convertedString); 837 | 838 | //rot13 encrypt a string 839 | function rot13Encrypt (string text) public { 840 | uint256 length = bytes(text).length; 841 | for (var i = 0; i < length; i++) { 842 | byte char = bytes(text)[i]; 843 | //inline assembly to modify the string 844 | assembly { 845 | char := byte(0,char) // get the first byte 846 | if and(gt(char,0x6D), lt(char,0x7B)) // if the character is in [n,z], i.e. wrapping. 847 | { char:= sub(0x60, sub(0x7A,char)) } // subtract from the ascii number a by the difference char is from z. 848 | if iszero(eq(char, 0x20)) // ignore spaces 849 | {mstore8(add(add(text,0x20), mul(i,1)), add(char,13))} // add 13 to char. 850 | } 851 | } 852 | emit Result(text); 853 | } 854 | 855 | // rot13 decrypt a string 856 | function rot13Decrypt (string text) public { 857 | uint256 length = bytes(text).length; 858 | for (var i = 0; i < length; i++) { 859 | byte char = bytes(text)[i]; 860 | assembly { 861 | char := byte(0,char) 862 | if and(gt(char,0x60), lt(char,0x6E)) 863 | { char:= add(0x7B, sub(char,0x61)) } 864 | if iszero(eq(char, 0x20)) 865 | {mstore8(add(add(text,0x20), mul(i,1)), sub(char,13))} 866 | } 867 | } 868 | emit Result(text); 869 | } 870 | } 871 | ``` 872 | This code simply takes a string (letters a-z, without validation) and *encrypts* it by shifting each character 13 places to the right (wrapping around 'z'); i.e. 'a' shifts to 'n' and 'x' shifts to 'k'. The assembly in here is not important, so don't worry if it doesn't make any sense at this stage. 873 | 874 | Consider the following contract which uses this code for its encryption, 875 | ```solidity 876 | import "Rot13Encryption.sol"; 877 | 878 | // encrypt your top secret info 879 | contract EncryptionContract { 880 | // library for encryption 881 | Rot13Encryption encryptionLibrary; 882 | 883 | // constructor - initialise the library 884 | constructor(Rot13Encryption _encryptionLibrary) { 885 | encryptionLibrary = _encryptionLibrary; 886 | } 887 | 888 | function encryptPrivateData(string privateInfo) { 889 | // potentially do some operations here 890 | encryptionLibrary.rot13Encrypt(privateInfo); 891 | } 892 | } 893 | ``` 894 | 895 | 896 | The issue with this contract is that the `encryptionLibrary` address is not public or constant. Thus the deployer of the contract could have given an address in the constructor which points to this contract: 897 | 898 | 899 | 900 | 901 | ```solidity 902 | //encryption contract 903 | contract Rot26Encryption { 904 | 905 | event Result(string convertedString); 906 | 907 | //rot13 encrypt a string 908 | function rot13Encrypt (string text) public { 909 | uint256 length = bytes(text).length; 910 | for (var i = 0; i < length; i++) { 911 | byte char = bytes(text)[i]; 912 | //inline assembly to modify the string 913 | assembly { 914 | char := byte(0,char) // get the first byte 915 | if and(gt(char,0x6D), lt(char,0x7B)) // if the character is in [n,z], i.e. wrapping. 916 | { char:= sub(0x60, sub(0x7A,char)) } // subtract from the ascii number a by the difference char is from z. 917 | if iszero(eq(char, 0x20)) // ignore spaces 918 | {mstore8(add(add(text,0x20), mul(i,1)), add(char,26))} // add 13 to char. 919 | } 920 | } 921 | emit Result(text); 922 | } 923 | 924 | // rot13 decrypt a string 925 | function rot13Decrypt (string text) public { 926 | uint256 length = bytes(text).length; 927 | for (var i = 0; i < length; i++) { 928 | byte char = bytes(text)[i]; 929 | assembly { 930 | char := byte(0,char) 931 | if and(gt(char,0x60), lt(char,0x6E)) 932 | { char:= add(0x7B, sub(char,0x61)) } 933 | if iszero(eq(char, 0x20)) 934 | {mstore8(add(add(text,0x20), mul(i,1)), sub(char,26))} 935 | } 936 | } 937 | emit Result(text); 938 | } 939 | } 940 | ``` 941 | which implements the rot26 cipher (shifts each character by 26 places, get it? :p). Again, there is no need to understand the assembly in this contract. The deployer could have also linked the following contract: 942 | 943 | ```solidity 944 | contract Print{ 945 | event Print(string text); 946 | 947 | function rot13Encrypt(string text) public { 948 | emit Print(text); 949 | } 950 | } 951 | 952 | ``` 953 | If the address of either of these contracts were given in the constructor, the `encryptPrivateData()` function would simply produce an event which prints the unencrypted private data. Although in this example a library-like contract was set in the constructor, it is often the case that a privileged user (such as an `owner`) can change library contract addresses. If a linked contract doesn't contain the function being called, the fallback function will execute. For example, with the line `encryptionLibrary.rot13Encrypt()`, if the contract specified by `encryptionLibrary` was: 954 | ```solidity 955 | contract Blank { 956 | event Print(string text); 957 | function () { 958 | emit Print("Here"); 959 | //put malicious code here and it will run 960 | } 961 | } 962 | ``` 963 | then an event with the text "Here" would be emitted. Thus if users can alter contract libraries, they can in principle get users to unknowingly run arbitrary code. 964 | 965 | *Note: Don't use encryption contracts such as these, as the input parameters to smart contracts are visible on the blockchain. Also the Rot cipher is not a recommended encryption technique :p* 966 | 967 | 968 |

Preventative Techniques

969 | 970 | As demonstrated above, vulnerability free contracts can (in some cases) be deployed in such a way that they behave maliciously. An auditor could publicly verify a contract and have it's owner deploy it in a malicious way, resulting in a publicly audited contract which has vulnerabilities or malicious intent. 971 | 972 | There are a number of techniques which prevent these scenarios. 973 | 974 | One technique, is to use the `new` keyword to create contracts. In the example above, the constructor could be written like: 975 | 976 | ```solidity 977 | constructor() { 978 | encryptionLibrary = new Rot13Encryption(); 979 | } 980 | ``` 981 | This way an instance of the referenced contract is created at deployment time and the deployer cannot replace the `Rot13Encryption` contract with anything else without modifying the smart contract. 982 | 983 | Another solution is to hard code any external contract addresses if they are known. 984 | 985 | In general, code that calls external contracts should always be looked at carefully. As a developer, when defining external contracts, it can be a good idea to make the contract addresses public (which is not the case in the honey-pot example given below) to allow users to easily examine which code is being referenced by the contract. Conversely, if a contract has a private variable contract address it can be a sign of someone behaving maliciously (as shown in the real-world example). If a privileged (or any) user is capable of changing a contract address which is used to call external functions, it can be important (in a decentralised system context) to implement a time-lock or voting mechanism to allow users to see which code is being changed or to give participants a chance to opt in/out with the new contract address. 986 | 987 | 988 |

Real-World Example: Re-Entrancy Honey Pot

989 | 990 | A number of recent honey pots have been released on the mainnet. These contracts try to outsmart Ethereum hackers who try to exploit the contracts, but who in turn end up getting ether lost to the contract they expect to exploit. One example employs the above attack by replacing an expected contract with a malicious one in the constructor. The code can be found [here](https://etherscan.io/address/0x95d34980095380851902ccd9a1fb4c813c2cb639#code): 991 | ```solidity 992 | pragma solidity ^0.4.19; 993 | 994 | contract Private_Bank 995 | { 996 | mapping (address => uint) public balances; 997 | uint public MinDeposit = 1 ether; 998 | Log TransferLog; 999 | 1000 | function Private_Bank(address _log) 1001 | { 1002 | TransferLog = Log(_log); 1003 | } 1004 | 1005 | function Deposit() 1006 | public 1007 | payable 1008 | { 1009 | if(msg.value >= MinDeposit) 1010 | { 1011 | balances[msg.sender]+=msg.value; 1012 | TransferLog.AddMessage(msg.sender,msg.value,"Deposit"); 1013 | } 1014 | } 1015 | 1016 | function CashOut(uint _am) 1017 | { 1018 | if(_am<=balances[msg.sender]) 1019 | { 1020 | if(msg.sender.call.value(_am)()) 1021 | { 1022 | balances[msg.sender]-=_am; 1023 | TransferLog.AddMessage(msg.sender,_am,"CashOut"); 1024 | } 1025 | } 1026 | } 1027 | 1028 | function() public payable{} 1029 | 1030 | } 1031 | 1032 | contract Log 1033 | { 1034 | struct Message 1035 | { 1036 | address Sender; 1037 | string Data; 1038 | uint Val; 1039 | uint Time; 1040 | } 1041 | 1042 | Message[] public History; 1043 | Message LastMsg; 1044 | 1045 | function AddMessage(address _adr,uint _val,string _data) 1046 | public 1047 | { 1048 | LastMsg.Sender = _adr; 1049 | LastMsg.Time = now; 1050 | LastMsg.Val = _val; 1051 | LastMsg.Data = _data; 1052 | History.push(LastMsg); 1053 | } 1054 | } 1055 | 1056 | ``` 1057 | 1058 | This [post](https://www.reddit.com/r/ethdev/comments/7x5rwr/tricked_by_a_honeypot_contract_or_beaten_by/) by one reddit user explains how they lost 1 ether to this contract by trying to exploit the re-entrancy bug they expected to be present in the contract. 1059 | 1060 | 1061 | 1062 |

8. Short Address/Parameter Attack

1063 | 1064 | 1065 | This attack is not specifically performed on Solidity contracts themselves but on third party applications that may interact with them. I add this attack for completeness and to be aware of how parameters can be manipulated in contracts. 1066 | 1067 | For further reading, see [The ERC20 Short Address Attack Explained](https://vessenes.com/the-erc20-short-address-attack-explained/), [ICO Smart contract Vulnerability: Short Address Attack](https://medium.com/huzzle/ico-smart-contract-vulnerability-short-address-attack-31ac9177eb6b) or this [reddit post](https://www.reddit.com/r/ethereum/comments/6r9nhj/cant_understand_the_erc20_short_address_attack/). 1068 | 1069 | 1070 |

The Vulnerability

1071 | 1072 | When passing parameters to a smart contract, the parameters are encoded according to the [ABI specification](https://solidity.readthedocs.io/en/latest/abi-spec.html). It is possible to send encoded parameters that are shorter than the expected parameter length (for example, sending an address that is only 38 hex chars (19 bytes) instead of the standard 40 hex chars (20 bytes)). In such a scenario, the EVM will pad 0's to the end of the encoded parameters to make up the expected length. 1073 | 1074 | This becomes an issue when third party applications do not validate inputs. The clearest example is an exchange which doesn't verify the address of an [ERC20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) token when a user requests a withdrawal. This example is covered in more detail in Peter Venesses' post, [The ERC20 Short Address Attack Explained](http://vessenes.com/the-erc20-short-address-attack-explained/) mentioned above. 1075 | 1076 | Consider, the standard [ERC20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) transfer function interface, noting the order of the parameters, 1077 | ```solidity 1078 | function transfer(address to, uint tokens) public returns (bool success); 1079 | ``` 1080 | Now consider, an exchange, holding a large amount of a token (let's say `REP`) and a user wishes to withdraw their share of 100 tokens. The user would submit their address, `0xdeaddeaddeaddeaddeaddeaddeaddeaddeaddead` and the number of tokens, `100`. The exchange would encode these parameters in the order specified by the `transfer()` function, i.e. `address` then `tokens`. The encoded result would be `a9059cbb000000000000000000000000deaddeaddeaddeaddeaddeaddeaddeaddeaddead0000000000000` `000000000000000000000000000000000056bc75e2d63100000`. The first four bytes (`a9059cbb`) are the `transfer()` [function signature/selector](https://solidity.readthedocs.io/en/latest/abi-spec.html#function-selector), the second 32 bytes are the address, followed by the final 32 bytes which represent the `uint256` number of tokens. Notice that the hex `56bc75e2d63100000` at the end corresponds to 100 tokens (with 18 decimal places, as specified by the `REP` token contract). 1081 | 1082 | Ok, so now let's look at what happens if we were to send an address that was missing 1 byte (2 hex digits). Specifically, let's say an attacker sends `0xdeaddeaddeaddeaddeaddeaddeaddeaddeadde`as an address (missing the last two digits) and the same `100` tokens to withdraw. If the exchange doesn't validate this input, it would get encoded as `a9059cbb000000000000000000000000deaddeaddeaddeaddeaddeaddeaddeaddeadde00000000000000` `00000000000000000000000000000000056bc75e2d6310000000`. The difference is subtle. Note that `00` has been padded to the end of the encoding, to make up for the short address that was sent. When this gets sent to the smart contract, the `address` parameters will read as `0xdeaddeaddeaddeaddeaddeaddeaddeaddeadde00` and the value will be read as `56bc75e2d6310000000` (notice the two extra `0`'s). This value is now, `25600` tokens (the value has been multiplied by `256`). In this example, if the exchange held this many tokens, the user would withdraw `25600` tokens (whilst the exchange thinks the user is only withdrawing `100`) to the modified address. Obviously the attacker won't possess the modified address in this example, but if the attacker were to generate any address which ended in `0`'s (which can be easily brute forced) and used this generated address, they could easily steal tokens from the unsuspecting exchange. 1083 | 1084 |

Preventative Techniques

1085 | 1086 | I suppose it is obvious to say that validating all inputs before sending them to the blockchain will prevent these kinds of attacks. It should also be noted that parameter ordering plays an important role here. As padding only occurs at the end, careful ordering of parameters in the smart contract can potentially mitigate some forms of this attack. 1087 | 1088 |

Real-World Example: Unknown

1089 | 1090 | I do not know of any publicised attack of this kind in the wild. 1091 | 1092 |

9. Unchecked CALL Return Values

1093 | 1094 | There a number of ways of performing external calls in solidity. Sending ether to external accounts is commonly performed via the `transfer()` method. However, the `send()` function can also be used and, for more versatile external calls, the `CALL` opcode can be directly employed in solidity. The `call()` and `send()` functions return a boolean indicating if the call succeeded or failed. Thus these functions have a simple caveat, in that the transaction that executes these functions will not revert if the external call (initialised by `call()` or `send()`) fails, rather the `call()` or `send()` will simply return `false`. A common pitfall arises when the return value is not checked, rather the developer expects a revert to occur. 1095 | 1096 | For further reading, see [DASP Top 10](http://www.dasp.co/#item-4) and [Scanning Live Ethereum Contracts for the "Unchecked-Send" Bug](http://hackingdistributed.com/2016/06/16/scanning-live-ethereum-contracts-for-bugs/). 1097 | 1098 |

The Vulnerability

1099 | 1100 | Consider the following example: 1101 | 1102 | ```solidity 1103 | contract Lotto { 1104 | 1105 | bool public payedOut = false; 1106 | address public winner; 1107 | uint public winAmount; 1108 | 1109 | // ... extra functionality here 1110 | 1111 | function sendToWinner() public { 1112 | require(!payedOut); 1113 | winner.send(winAmount); 1114 | payedOut = true; 1115 | } 1116 | 1117 | function withdrawLeftOver() public { 1118 | require(payedOut); 1119 | msg.sender.send(this.balance); 1120 | } 1121 | } 1122 | ``` 1123 | 1124 | This contract represents a Lotto-like contract, where a `winner` receives `winAmount` of ether, which typically leaves a little left over for anyone to withdraw. 1125 | 1126 | The bug exists on line \[11\] where a `send()` is used without checking the response. In this trivial example, a `winner` whose transaction fails (either by running out of gas or being a contract that intentionally throws in the fallback function) allows `payedOut` to be set to `true` (regardless of whether ether was sent or not). In this case, the public can withdraw the `winner`'s winnings via the `withdrawLeftOver()` function. 1127 | 1128 |

Preventative Techniques

1129 | 1130 | Whenever possible, use the `transfer()` function rather than `send()` as `transfer()` will `revert` if the external transaction reverts. If `send()` is required, always ensure to check the return value. 1131 | 1132 | An even more robust [recommendation](http://solidity.readthedocs.io/en/latest/common-patterns.html#withdrawal-from-contracts) is to adopt a *withdrawal pattern*. In this solution, each user is burdened with calling an isolated function (i.e. a *withdraw* function) which handles the sending of ether out of the contract and therefore independently deals with the consequences of failed send transactions. The idea is to logically isolate the external send functionality from the rest of the code base and place the burden of potentially failed transaction to the end-user who is calling the *withdraw* function. 1133 | 1134 |

Real-World Example: Etherpot and King of the Ether

1135 | 1136 | [Etherpot](https://github.com/etherpot) was a smart contract lottery, not too dissimilar to the example contract mentioned above. The solidity code for etherpot, can be found here: [lotto.sol](https://github.com/etherpot/contract/blob/master/app/contracts/lotto.sol). The primary downfall of this contract was due to an incorrect use of block hashes (only the last 256 block hashes are useable, see Aakil Fernandes's [post](http://aakilfernandes.github.io/blockhashes-are-only-good-for-256-blocks) about how Etherpot failed to implement this correctly). However this contract also suffered from an unchecked call value. Notice the function, `cash()` on line \[80\] of lotto.sol: 1137 | 1138 | ```solidity 1139 | ... 1140 | function cash(uint roundIndex, uint subpotIndex){ 1141 | 1142 | var subpotsCount = getSubpotsCount(roundIndex); 1143 | 1144 | if(subpotIndex>=subpotsCount) 1145 | return; 1146 | 1147 | var decisionBlockNumber = getDecisionBlockNumber(roundIndex,subpotIndex); 1148 | 1149 | if(decisionBlockNumber>block.number) 1150 | return; 1151 | 1152 | if(rounds[roundIndex].isCashed[subpotIndex]) 1153 | return; 1154 | //Subpots can only be cashed once. This is to prevent double payouts 1155 | 1156 | var winner = calculateWinner(roundIndex,subpotIndex); 1157 | var subpot = getSubpot(roundIndex); 1158 | 1159 | winner.send(subpot); 1160 | 1161 | rounds[roundIndex].isCashed[subpotIndex] = true; 1162 | //Mark the round as cashed 1163 | } 1164 | ... 1165 | ``` 1166 | Notice that on line \[21\] the send function's return value is not checked, and the following line then sets a boolean indicating the winner has been sent their funds. This bug can allow a state where the winner does not receive their ether, but the state of the contract can indicate that the winner has already been paid. 1167 | 1168 | A more serious version of this bug occurred in the [King of the Ether](https://www.kingoftheether.com/thrones/kingoftheether/index.html). An excellent [post-mortem](https://www.kingoftheether.com/postmortem.html) of this contract has been written which details how an unchecked failed `send()` could be used to attack the contract. 1169 | 1170 | 1171 |

10. Race Conditions / Front Running

1172 | 1173 | The combination of external calls to other contracts and the multi-user nature of the underlying blockchain gives rise to a variety of potential Solidity pitfalls whereby users *race* code execution to obtain unexpected states. [Re-Entrancy](#reentrancy) is one example of such a race condition. In this section we will talk more generally about different kinds of race conditions that can occur on the Ethereum blockchain. There is a variety of good posts on this subject, a few are: [Ethereum Wiki - Safety](https://github.com/ethereum/wiki/wiki/Safety#race-conditions), [DASP - Front-Running](http://www.dasp.co/#item-7) and the [Consensus - Smart Contract Best Practices](https://consensys.github.io/smart-contract-best-practices/known_attacks/#race-conditions). 1174 | 1175 |

The Vulnerability

1176 | 1177 | As with most blockchains, Ethereum nodes pool transactions and form them into blocks. The transactions are only considered valid once a miner has solved a consensus mechanism (currently [ETHASH](https://github.com/ethereum/wiki/wiki/Ethash) PoW for Ethereum). The miner who solves the block also chooses which transactions from the pool will be included in the block, this is typically ordered by the `gasPrice` of a transaction. In here lies a potential attack vector. An attacker can watch the transaction pool for transactions which may contain solutions to problems, modify or revoke the attacker's permissions or change a state in a contract which is undesirable for the attacker. The attacker can then get the data from this transaction and create a transaction of their own with a higher `gasPrice` and get their transaction included in a block before the original. 1178 | 1179 | Let's see how this could work with a simple example. Consider the contract `FindThisHash.sol`: 1180 | 1181 | ```solidity 1182 | contract FindThisHash { 1183 | bytes32 constant public hash = 0xb5b5b97fafd9855eec9b41f74dfb6c38f5951141f9a3ecd7f44d5479b630ee0a; 1184 | 1185 | constructor() public payable {} // load with ether 1186 | 1187 | function solve(string solution) public { 1188 | // If you can find the pre image of the hash, receive 1000 ether 1189 | require(hash == sha3(solution)); 1190 | msg.sender.transfer(1000 ether); 1191 | } 1192 | } 1193 | ``` 1194 | Imagine this contract contains 1000 ether. The user who can find the pre-image of the sha3 hash `0xb5b5b97fafd9855eec9b41f74dfb6c38f5951141f9a3ecd7f44d5479b630ee0a` can submit the solution and retrieve the 1000 ether. Let's say one user figures out the solution is `Ethereum!`. They call `solve()` with `Ethereum!` as the parameter. Unfortunately an attacker has been clever enough to watch the transaction pool for anyone submitting a solution. They see this solution, check it's validity, and then submit an equivalent transaction with a much higher `gasPrice` than the original transaction. The miner who solves the block will likely give the attacker preference due to the higher `gasPrice` and accept their transaction before the original solver. The attacker will take the 1000 ether and the user who solved the problem will get nothing (there is no ether left in the contract). 1195 | 1196 | A more realistic problem comes in the design of the future Casper implementation. The Casper proof of stake contracts invoke slashing conditions where users who notice validators double-voting or misbehaving are incentivised to submit proof that they have done so. The validator will be punished and the user rewarded. In such a scenario, it is expected that miners and users will front-run all such submissions of proof, and this issue must be addressed before the final release. 1197 | 1198 |

Preventative Techniques

1199 | 1200 | There are two classes of users who can perform these kinds of front-running attacks. Users (who modify the `gasPrice` of their transactions) and miners themselves (who can re-order the transactions in a block how they see fit). A contract that is vulnerable to the first class (users), is significantly worse-off than one vulnerable to the second (miners) as miner's can only perform the attack when they solve a block, which is unlikely for any individual miner targeting a specific block. Here I'll list a few mitigation measures with relation to which class of attackers they may prevent. 1201 | 1202 | One method that can be employed is to create logic in the contract that places an upper bound on the `gasPrice`. This prevents users from increasing the `gasPrice` and getting preferential transaction ordering beyond the upper-bound. This preventative measure only mitigates the first class of attackers (arbitrary users). Miners in this scenario can still attack the contract as they can order the transactions in their block however they like, regardless of gas price. 1203 | 1204 | A more robust method is to use a [commit-reveal](https://ethereum.stackexchange.com/questions/191/how-can-i-securely-generate-a-random-number-in-my-smart-contract) scheme, whenever possible. Such a scheme dictates users send transactions with hidden information (typically a hash). After the transaction has been included in a block, the user sends a transaction revealing the data that was sent (the reveal phase). This method prevents both miners and users from frontrunning transactions as they cannot determine the contents of the transaction. This method however, cannot conceal the transaction value (which in some cases is the valuable information that needs to be hidden). The [ENS](https://ens.domains/) smart contract allowed users to send transactions, whose committed data included the amount of ether they were willing to spend. Users could then send transactions of arbitrary value. During the reveal phase, users were refunded the difference between the amount sent in the transaction and the amount they were willing to spend. 1205 | 1206 | 1207 | 1208 | A further suggestion by Lorenz, Phil, Ari and Florian is to use [Submarine Sends](http://hackingdistributed.com/2017/08/28/submarine-sends/). An efficient implementation of this idea requires the `CREATE2` opcode, which currently hasn't been adopted, but seems likely in upcoming hard forks. 1209 | 1210 |

Real-World Examples: ERC20 and Bancor

1211 | 1212 | The [ERC20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) standard is quite well-known for building tokens on Ethereum. This standard has a potential frontrunning vulnerability which comes about due to the `approve()` function. A good explanation of this vulnerability can be found [here](https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/edit). 1213 | 1214 | The standard specifies the `approve()` function as: 1215 | ```solidity 1216 | function approve(address _spender, uint256 _value) returns (bool success) 1217 | ``` 1218 | This function allows a user to permit other users to transfer tokens on their behalf. The frontrunning vulnerability comes in the scenario when a user, Alice, *approves* her friend, `Bob` to spend `100 tokens`. Alice later decides that she wants to revoke `Bob`'s approval to spend `100 tokens`, so she creates a transaction that sets `Bob`'s allocation to `50 tokens`. `Bob`, who has been carefully watching the chain, sees this transaction and builds a transaction of his own spending the `100 tokens`. He puts a higher `gasPrice` on his transaction than `Alice`'s and gets his transaction prioritised over hers. Some implementations of `approve()` would allow `Bob` to transfer his `100 tokens`, then when `Alice`'s transaction gets committed, resets `Bob`'s approval to `50 tokens`, in effect giving `Bob` access to `150 tokens`. The mitigation strategies of this attack are given [here](https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/edit) in the document linked above. 1219 | 1220 | Another prominent, real-world example is [Bancor](https://www.bancor.network/). Ivan Bogatty and his team documented a profitable attack on the initial Bancor implementation. His [blog post](https://hackernoon.com/front-running-bancor-in-150-lines-of-python-with-ethereum-api-d5e2bfd0d798) and [Devon 3 talk](https://www.youtube.com/watch?v=RL2nE3huNiI) discuss in detail how this was done. Essentially, prices of tokens are determined based on transaction value, users can watch the transaction pool for Bancor transactions and front run them to profit from the price differences. This attack has been addressed by the Bancor team. 1221 | 1222 |

11. Denial Of Service (DOS)

1223 | 1224 | This category is very broad, but fundamentally consists of attacks where users can leave the contract inoperable for a small period of time, or in some cases, permanently. This can trap ether in these contracts forever, as was the case with the [Second Parity MultiSig hack](#dc-example) 1225 | 1226 |

The Vulnerability

1227 | 1228 | There are various ways a contract can become inoperable. Here I will only highlight some potentially less-obvious Blockchain nuanced Solidity coding patterns that can lead to attackers performing DOS attacks. 1229 | 1230 | **1. External calls without gas stipends** - It may be the case that you wish 1231 | to make an external call to an unknown contract and continue processing the 1232 | transaction regardless whether that call fails or not. Typically this is 1233 | achieved by using the `CALL` opcode, which does not revert the transaction 1234 | if the call fails (see [Unchecked CALL Return Values](#unchecked-calls) for further details and examples). 1235 | Let us consider a simple example, where we have a contract wallet, that slowly 1236 | trickles out ether when the `withdraw()` function is called. A `partner` can 1237 | add their address and spend gas to call the withdraw, giving both the 1238 | `partner` and the `owner` 1% of the total contract balance. 1239 | 1240 | ```solidity 1241 | contract TrickleWallet { 1242 | 1243 | address public partner; // withdrawal partner - pay the gas, split the withdraw 1244 | address public constant owner = 0xA9E; 1245 | uint timeLastWithdrawn; 1246 | mapping(address => uint) withdrawPartnerBalances; // keep track of partners balances 1247 | 1248 | function setWithdrawPartner(address _partner) public { 1249 | require(partner == '0x0' || msg.sender == partner); 1250 | partner = _partner; 1251 | } 1252 | 1253 | // withdraw 1% to recipient and 1% to owner 1254 | function withdraw() public { 1255 | uint amountToSend = address(this).balance/100; 1256 | // perform a call without checking return 1257 | // the recipient can revert, the owner will still get their share 1258 | partner.call.value(amountToSend)(); 1259 | owner.transfer(amountToSend); 1260 | // keep track of last withdrawal time 1261 | timeLastWithdrawn = now; 1262 | withdrawPartnerBalances[partner] += amountToSend; 1263 | } 1264 | 1265 | // allow deposit of funds 1266 | function() payable {} 1267 | 1268 | // convenience function 1269 | function contractBalance() view returns (uint) { 1270 | return address(this).balance; 1271 | } 1272 | } 1273 | ``` 1274 | 1275 | Notice that on line \[17\] we perform an external call sending 1% of the 1276 | contract balance to a user-specified account. The reason the `CALL` opcode is used, is to ensure that 1277 | the owner still gets paid, even if the external call reverts. The issue is that 1278 | the transaction will send all of its gas (in reality, only most of the transaction gas is sent, some is left to finish processing the call) to the external call. If the user were malicious they could create a contract that would consume all the gas, and force all transactions to `withdraw()` to fail, due to running out of gas. 1279 | 1280 | For example, consider the following malicious contract that consumes all gas, 1281 | ```solidity 1282 | contract ConsumeAllGas { 1283 | function () payable { 1284 | // an assert consumes all transaction gas, unlike a 1285 | //revert which returns the remaining gas 1286 | assert(1==2); 1287 | } 1288 | } 1289 | ``` 1290 | If a withdrawal partner decided they didn't like the owner of the contract. 1291 | They could set the partner address to this contract and lock all the funds in 1292 | the `TrickleWallet` contract forever. 1293 | 1294 | To prevent such DOS attack vectors, ensure a gas stipend is specified in an 1295 | external call, to limit the amount of gas that that transaction can use. In our 1296 | example, we could remedy this attack by changing line \[17\] to: 1297 | ```solidity 1298 | partner.call.gas(50000).value(amountToSend)(); 1299 | ``` 1300 | This modification allows only 50,000 gas to be spent on the external 1301 | transaction. The `owner` may set a gas price larger than this, in order to have 1302 | their transaction complete, regardless of how much the external transaction 1303 | uses. 1304 | 1305 | **2. Looping through externally manipulated mappings or arrays** - In my adventures I've seen various forms of this kind of pattern. Typically it appears in scenarios where an `owner` wishes to distribute tokens amongst their investors, and do so with a `distribute()`-like function as can be seen in the example contract: 1306 | 1307 | ```solidity 1308 | contract DistributeTokens { 1309 | address public owner; // gets set somewhere 1310 | address[] investors; // array of investors 1311 | uint[] investorTokens; // the amount of tokens each investor gets 1312 | 1313 | // ... extra functionality, including transfertoken() 1314 | 1315 | function invest() public payable { 1316 | investors.push(msg.sender); 1317 | investorTokens.push(msg.value * 5); // 5 times the wei sent 1318 | } 1319 | 1320 | function distribute() public { 1321 | require(msg.sender == owner); // only owner 1322 | for(uint i = 0; i < investors.length; i++) { 1323 | // here transferToken(to,amount) transfers "amount" of tokens to the address "to" 1324 | transferToken(investors[i],investorTokens[i]); 1325 | } 1326 | } 1327 | } 1328 | ``` 1329 | 1330 | Notice that the loop in this contract runs over an array which can be artificially inflated. An attacker can create many user accounts making the `investor` array large. In principle this can be done such that the gas required to execute the for loop exceeds the block gas limit, essentially making the `distribute()` function inoperable. 1331 | 1332 | **3. Owner operations** - Another common pattern is where owners have specific privileges in contracts and must perform some task in order for the contract to proceed to the next state. One example would be an ICO contract that requires the owner to `finalize()` the contract which then allows tokens to be transferable, i.e. 1333 | ``` solidity 1334 | bool public isFinalized = false; 1335 | address public owner; // gets set somewhere 1336 | 1337 | function finalize() public { 1338 | require(msg.sender == owner); 1339 | isFinalized == true; 1340 | } 1341 | 1342 | // ... extra ICO functionality 1343 | 1344 | // overloaded transfer function 1345 | function transfer(address _to, uint _value) returns (bool) { 1346 | require(isFinalized); 1347 | super.transfer(_to,_value) 1348 | } 1349 | 1350 | ... 1351 | 1352 | ``` 1353 | In such cases, if a privileged user loses their private keys, or becomes inactive, the entire token contract becomes inoperable. In this case, if the `owner` cannot call `finalize()` no tokens can be transferred; i.e. the entire operation of the token ecosystem hinges on a single address. 1354 | 1355 | **4. Progressing state based on external calls** - Contracts are sometimes written such that in order to progress to a new state 1356 | requires sending ether to an address, or waiting for some input from an 1357 | external source. These patterns can lead to DOS attacks, when the external 1358 | call fails or is prevented for external reasons. In the example of sending 1359 | ether, a user can create a contract which does not accept ether. If a contract 1360 | requires ether to be withdrawn (consider a time-locking contract that requires all 1361 | ether to be withdrawn before being useable again) in order to progress to a new state, the 1362 | contract will never achieve the new state as ether can never be sent to the 1363 | user's contract which does not accept ether. 1364 | 1365 |

Preventative Techniques

1366 | 1367 | In the first example, contracts should not loop through data structures that can be artificially manipulated by external users. A withdrawal pattern is recommended, whereby each of the investors call a withdraw function to claim tokens independently. 1368 | 1369 | In the second example a privileged user was required to change the state of the contract. In such examples (wherever possible) a fail-safe can be used in the event that the `owner` becomes incapacitated. One solution could be setting up the `owner` as a multisig contract. Another solution is to use a timelock, where the require on line \[13\] could include a time-based mechanism, such as `require(msg.sender == owner || now > unlockTime)` which allows any user to finalise after a period of time, specified by `unlockTime`. This kind of mitigation technique can be used in the third example also. If external calls are required to progress to a new state, account for their possible failure and potentially add a time-based state progression in the event that the desired call never comes. 1370 | 1371 | *Note: Of course there are centralised alternatives to these suggestions where one can add a `maintenanceUser` who can come along and fix problems with DOS-based attack vectors if need be. Typically these kinds of contracts contain trust issues over the power of such an entity, but that is not a conversation for this section.* 1372 | 1373 |

Real-World Examples: GovernMental

1374 | 1375 | [GovernMental](http://governmental.github.io/GovernMental/) was an old Ponzi scheme that accumulated quite a large amount of ether. In fact, at one point it had accumulated 1100 ether. Unfortunately, it was susceptible to the DOS vulnerabilities mentioned in this section. [This Reddit Post](https://www.reddit.com/r/ethereum/comments/4ghzhv/governmentals_1100_eth_jackpot_payout_is_stuck/) describes how the contract required the deletion of a large mapping in order to withdraw the ether. The deletion of this mapping had a gas cost that exceeded the block gas limit at the time, and thus was not possible to withdraw the 1100 ether. The contract address is [0xF45717552f12Ef7cb65e95476F217Ea008167Ae3](https://etherscan.io/address/0xf45717552f12ef7cb65e95476f217ea008167ae3) and you can see from transaction [0x0d80d67202bd9cb6773df8dd2020e7190a1b0793e8ec4fc105257e8128f0506b](https://etherscan.io/tx/0x0d80d67202bd9cb6773df8dd2020e7190a1b0793e8ec4fc105257e8128f0506b) that the 1100 ether was finally obtained with a transaction that used 2.5M gas (after the block gas limit allowed such a transaction). 1376 | 1377 | 1378 |

12. Block Timestamp Manipulation

1379 | 1380 | Block timestamps have historically been used for a variety of applications, such as entropy for random numbers (see the [Entropy Illusion](#entropy) section for further details), locking funds for periods of time and various state-changing conditional statements that are time-dependent. Miner's have the ability to adjust timestamps slightly which can prove to be quite dangerous if block timestamps are used incorrectly in smart contracts. 1381 | 1382 | Some useful references for this are: [The Solidity Docs](http://solidity.readthedocs.io/en/latest/units-and-global-variables.html#block-and-transaction-properties), this [Stack Exchange Question](https://ethereum.stackexchange.com/questions/413/can-a-contract-safely-rely-on-block-timestamp?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa). 1383 | 1384 | 1385 |

The Vulnerability

1386 | 1387 | `block.timestamp` or its alias `now` can be manipulated by miners if they have some incentive to do so. Let's construct a simple game, which would be vulnerable to miner exploitation, 1388 | 1389 | `roulette.sol`: 1390 | ```solidity 1391 | contract Roulette { 1392 | uint public pastBlockTime; // Forces one bet per block 1393 | 1394 | constructor() public payable {} // initially fund contract 1395 | 1396 | // fallback function used to make a bet 1397 | function () public payable { 1398 | require(msg.value == 10 ether); // must send 10 ether to play 1399 | require(now != pastBlockTime); // only 1 transaction per block 1400 | pastBlockTime = now; 1401 | if(now % 15 == 0) { // winner 1402 | msg.sender.transfer(this.balance); 1403 | } 1404 | } 1405 | } 1406 | ``` 1407 | 1408 | This contract behaves like a simple lottery. One transaction per block can bet `10 ether` for a chance to win the balance of the contract. The assumption here is that, `block.timestamp` is uniformly distributed about the last two digits. If that were the case, there would be a 1/15 chance of winning this lottery. 1409 | 1410 | However, as we know, miners can adjust the timestamp, should they need to. In this particular case, if enough ether pooled in the contract, a miner who solves a block is incentivised to choose a timestamp such that `block.timestamp` or `now` modulo 15 is `0`. In doing so they may win the ether locked in this contract along with the block reward. As there is only one person allowed to bet per block, this is also vulnerable to [front-running](#race-conditions) attacks. 1411 | 1412 | In practice, block timestamps are monotonically increasing and so miners cannot choose arbitrary block timestamps (they must be larger than their predecessors). They are also limited to setting blocktimes not too far in the future as these blocks will likely be rejected by the network (nodes will not validate blocks whose timestamps are in the future). 1413 | 1414 |

Preventative Techniques

1415 | 1416 | Block timestamps should not be used for entropy or generating random numbers - i.e. they should not be the deciding factor (either directly or through some derivation) for winning a game or changing an important state (if assumed to be random). 1417 | 1418 | Time-sensitive logic is sometimes required; i.e. unlocking contracts (timelocking), completing an ICO after a few weeks or enforcing expiry dates. It is sometimes recommend to use `block.number` (see the [Solidity docs](http://solidity.readthedocs.io/en/latest/units-and-global-variables.html#block-and-transaction-properties)) and an average block time to estimate times; .i.e. `1 week` with a `10 second` block time, equates to approximately, `60480 blocks`. Thus, specifying a block number at which to change a contract state can be more secure as miners are unable to manipulate the block number as easily. The [BAT ICO](https://etherscan.io/address/0x0d8775f648430679a709e98d2b0cb6250d2887ef#code) contract employed this strategy. 1419 | 1420 | This can be unnecessary if contracts aren't particularly concerned with miner manipulations of the block timestamp, but it is something to be aware of when developing contracts. 1421 | 1422 |

Real-World Example: GovernMental

1423 | 1424 | [GovernMental](http://governmental.github.io/GovernMental/) was an old Ponzi scheme that accumulated quite a large amount of ether. It was also vulnerable to a timestamp-based attack. The contract payed out to the player who was the last player to join (for at least one minute) in a round. Thus, a miner who was a player, could adjust the timestamp (to a future time, to make it look like a minute had elapsed) to make it appear that the player was the last to join for over a minute (even though this is not true in reality). More detail on this can be found in the [History of Ethereum Security Vulnerabilities Post](https://applicature.com/blog/history-of-ethereum-security-vulnerabilities-hacks-and-their-fixes) by Tanya Bahrynovska. 1425 | 1426 |

13. Constructors with Care

1427 | 1428 | Constructors are special functions which often perform critical, privileged tasks when initialising contracts. Before solidity `v0.4.22` constructors were defined as functions that had the same name as the contract that contained them. Thus, when a contract name gets changed in development, if the constructor name isn't changed, it becomes a normal, callable function. As you can imagine, this can (and has) lead to some interesting contract hacks. 1429 | 1430 | For further reading, I suggest the reader attempt the [Ethernaught Challenges](https://github.com/OpenZeppelin/ethernaut) (in particular the Fallout level). 1431 | 1432 |

The Vulnerability

1433 | 1434 | If the contract name gets modified, or there is a typo in the constructor's name such that it no longer matches the name of the contract, the constructor will behave like a normal function. This can lead to dire consequences, especially if the constructor is performing privileged operations. Consider the following contract 1435 | 1436 | ```solidity 1437 | contract OwnerWallet { 1438 | address public owner; 1439 | 1440 | //constructor 1441 | function ownerWallet(address _owner) public { 1442 | owner = _owner; 1443 | } 1444 | 1445 | // fallback. Collect ether. 1446 | function () payable {} 1447 | 1448 | function withdraw() public { 1449 | require(msg.sender == owner); 1450 | msg.sender.transfer(this.balance); 1451 | } 1452 | } 1453 | ``` 1454 | 1455 | This contract collects ether and only allows the owner to withdraw all the ether by calling the `withdraw()` function. The issue arises due to the fact that the constructor is not exactly named after the contract. Specifically, `ownerWallet` is not the same as `OwnerWallet`. Thus, any user can call the `ownerWallet()` function, set themselves as the owner and then take all the ether in the contract by calling `withdraw()`. 1456 | 1457 | 1458 |

Preventative Techniques

1459 | 1460 | This issue has been primarily addressed in the Solidity compiler in version `0.4.22`. This version introduced a `constructor` keyword which specifies the constructor, rather than requiring the name of the function to match the contract name. Using this keyword to specify constructors is recommended to prevent naming issues as highlighted above. 1461 | 1462 |

Real-World Example: Rubixi

1463 | 1464 | Rubixi ([contract code](https://etherscan.io/address/0xe82719202e5965Cf5D9B6673B7503a3b92DE20be#code)) was another pyramid scheme that exhibited this kind of vulnerability. It was originally called `DynamicPyramid` but the contract name was changed before deployment to `Rubixi`. The constructor's name wasn't changed, allowing any user to become the `creator`. Some interesting discussion related to this bug can be found on this [Bitcoin Thread](https://bitcointalk.org/index.php?topic=1400536.60). Ultimately, it allowed users to fight for `creator` status to claim the fees from the pyramid scheme. More detail on this particular bug can be found [here](https://applicature.com/blog/history-of-ethereum-security-vulnerabilities-hacks-and-their-fixes). 1465 | 1466 | 1467 |

14. Uninitialised Storage Pointers

1468 | 1469 | The EVM stores data either as `storage` or as `memory`. Understanding exactly how this is done and the default types for local variables of functions is highly recommended when developing contracts. This is because it is possible to produce vulnerable contracts by inappropriately initialising variables. 1470 | 1471 | To read more about `storage` and `memory` in the EVM, see the [Solidity Docs: Data Location](http://solidity.readthedocs.io/en/latest/types.html#data-location), [Solidity Docs: Layout of State Variables in Storage](http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage), [Solidity Docs: Layout in Memory](http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-in-memory). 1472 | 1473 | *This section is based off the excellent [post by Stefan Beyer](https://medium.com/cryptronics/storage-allocation-exploits-in-ethereum-smart-contracts-16c2aa312743). Further reading on this topic can be found from Sefan's inspiration, which is this [reddit thread](https://www.reddit.com/r/ethdev/comments/7wp363/how_does_this_honeypot_work_it_seems_like_a/).* 1474 | 1475 |

The Vulnerability

1476 | 1477 | Local variables within functions default to `storage` or `memory` depending on their type. Uninitialised local `storage` variables can point to other unexpected storage variables in the contract, leading to intentional (i.e. the developer intentionally puts them there to attack later) or unintentional vulnerabilities. 1478 | 1479 | Let's consider the following, relatively simple name registrar contract: 1480 | 1481 | ```solidity 1482 | // A Locked Name Registrar 1483 | contract NameRegistrar { 1484 | 1485 | bool public unlocked = false; // registrar locked, no name updates 1486 | 1487 | struct NameRecord { // map hashes to addresses 1488 | bytes32 name; 1489 | address mappedAddress; 1490 | } 1491 | 1492 | mapping(address => NameRecord) public registeredNameRecord; // records who registered names 1493 | mapping(bytes32 => address) public resolve; // resolves hashes to addresses 1494 | 1495 | function register(bytes32 _name, address _mappedAddress) public { 1496 | // set up the new NameRecord 1497 | NameRecord newRecord; 1498 | newRecord.name = _name; 1499 | newRecord.mappedAddress = _mappedAddress; 1500 | 1501 | resolve[_name] = _mappedAddress; 1502 | registeredNameRecord[msg.sender] = newRecord; 1503 | 1504 | require(unlocked); // only allow registrations if contract is unlocked 1505 | } 1506 | } 1507 | 1508 | ``` 1509 | 1510 | This simple name registrar has only one function. When the contract is `unlocked`, it allows anyone to register a name (as a `bytes32` hash) and map that name to an address. Unfortunately, this registrar is initially locked and the `require` on line \[23\] prevents `register()` from adding name records. There is however a vulnerability in this contract, that allows name registration regardless of the `unlocked` variable. 1511 | 1512 | To discuss this vulnerability, first we need to understand how storage works in Solidity. As a high level overview (without any proper technical detail - I suggest reading the Solidity docs for a proper review), state variables are stored sequentially in *slots* as they appear in the contract (they can be grouped together, but not in this example, so we won't worry about that). Thus, `unlocked` exists in `slot 0`, `registeredNameRecord` exists in `slot 1` and `resolve` in `slot 2` etc. Each of these slots are of byte size 32 (there are added complexities with mappings which we ignore for now). The boolean `unlocked` will look like `0x000...0` (64 `0`'s, excluding the `0x`) for `false` or `0x000...1`(63 `0`'s) for `true`. As you can see, there is a significant waste of storage in this particular example. 1513 | 1514 | The next piece of information that we need, is that Solidity defaults complex data types, such as `structs`, to `storage` when initialising them as local variables. Therefore, `newRecord` on line \[16\] defaults to `storage`. The vulnerability is caused by the fact that `newRecord` is not initialised. Because it defaults to storage, it becomes a pointer to storage and because it is uninitialised, it points to slot `0` (i.e. where `unlocked` is stored). Notice that on lines \[17\] and \[18\] we then set `nameRecord.name` to `_name` and `nameRecord.mappedAddress` to `_mappedAddress`, this in effect changes the storage location of slot 0 and slot 1 which modifies both `unlocked` and the storage slot associated with `registeredNameRecord`. 1515 | 1516 | This means that `unlocked` can be directly modified, simply by the `bytes32 _name` parameter of the `register()` function. Therefore, if the last byte of `_name` is non-zero, it will modify the last byte of storage `slot 0` and directly change `unlocked` to `true`. Such `_name` values will pass the `require()` on line \[23\] as we are setting `unlocked` to `true`. Try this in Remix. Notice the function will pass if you use a `_name` of the form: `0x0000000000000000000000000000000000000000000000000000000000000001` 1517 | 1518 |

Preventative Techniques

1519 | 1520 | The Solidity compiler raises uninitialised storage variables as warnings, thus developers should pay careful attention to these warnings when building smart contracts. The current version of mist (0.10), doesn't allow these contracts to be compiled. It is good practice to explicitly use the `memory` or `storage` keywords when dealing with complex types to ensure they behave as expected. As of Solidity version `0.5.0` use of `memory` and `storage` are mandatory. 1521 | 1522 |

Real-World Examples: Honey Pots: OpenAddressLottery and CryptoRoulette

1523 | 1524 | A honey pot named OpenAddressLottery ([contract code](https://etherscan.io/address/0x741f1923974464efd0aa70e77800ba5d9ed18902#code)) was deployed that used this uninitialised storage variable querk to collect ether from some would-be hackers. The contract is rather in-depth, so I will leave the discussion to this [reddit thread](https://www.reddit.com/r/ethdev/comments/7wp363/how_does_this_honeypot_work_it_seems_like_a/) where the attack is quite clearly explained. 1525 | 1526 | Another honey pot, CryptoRoulette ([contract code](https://etherscan.io/address/0x8685631276cfcf17a973d92f6dc11645e5158c0c#code)) also utilises this trick to try and collect some ether. If you can't figure out how the attack works, see [An analysis of a couple Ethereum honeypot contracts](https://medium.com/@jsanjuas/an-analysis-of-a-couple-ethereum-honeypot-contracts-5c07c95b0a8d) for an overview of this contract and others. 1527 | 1528 | 1529 |

15. Floating Points and Precision

1530 | 1531 | As of this writing (Solidity v0.4.24), fixed point or floating point numbers are not supported. This means that floating point representations must be made with the integer types in Solidity. This can lead to errors/vulnerabilities if not implemented correctly. 1532 | 1533 | For further reading, see [Ethereum Contract Security Techniques and Tips - Rounding with Integer Division](https://github.com/ethereum/wiki/wiki/Safety#beware-rounding-with-integer-division), 1534 | 1535 |

The Vulnerability

1536 | 1537 | As there is no fixed point type in Solidity, developers are required to implement their own using the standard integer data types. There are a number of pitfalls developers can run into during this process. I will try to highlight some of these in this section. 1538 | 1539 | Let's begin with a code example (let's ignore any over/under flow issues for simplicity). 1540 | 1541 | ```solidity 1542 | contract FunWithNumbers { 1543 | uint constant public tokensPerEth = 10; 1544 | uint constant public weiPerEth = 1e18; 1545 | mapping(address => uint) public balances; 1546 | 1547 | function buyTokens() public payable { 1548 | uint tokens = msg.value/weiPerEth*tokensPerEth; // convert wei to eth, then multiply by token rate 1549 | balances[msg.sender] += tokens; 1550 | } 1551 | 1552 | function sellTokens(uint tokens) public { 1553 | require(balances[msg.sender] >= tokens); 1554 | uint eth = tokens/tokensPerEth; 1555 | balances[msg.sender] -= tokens; 1556 | msg.sender.transfer(eth*weiPerEth); // 1557 | } 1558 | } 1559 | ``` 1560 | 1561 | This simple token buying/selling contract has some obvious problems in the buying and selling of tokens. Although the mathematical calculations for buying and selling tokens are correct, the lack of floating point numbers will give erroneous results. For example, when buying tokens on line \[7\], if the value is less than `1 ether` the initial division will result in `0`, leaving the final multiplication `0` (i.e. `200 wei` divided by `1e18` `weiPerEth` equals `0`). Similarly, when selling tokens, any tokens less than `10` will also result in `0 ether`. In fact, rounding here is always down, so selling `29 tokens`, will result in `2 ether`. 1562 | 1563 | The issue with this contract is that the precision is only to the nearest `ether` (i.e. `1e18 wei`). This can sometimes get tricky when dealing with `decimals` in [ERC20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) tokens when you need higher precisions. 1564 | 1565 |

Preventative Techniques

1566 | 1567 | Keeping the right precision in your smart contracts is very important, especially when dealing ratios and rates which reflect economic decisions. 1568 | 1569 | You should ensure that any ratios or rates you are using allow for large numerators in fractions. For example, we used the rate `tokensPerEth` in our example. It would have been better to use `weiPerTokens` which would be a large number. To solve for the amount of tokens we could do `msg.value/weiPerTokens`. This would give a more precise result. 1570 | 1571 | Another tactic to keep in mind, is to be mindful of order of operations. In the above example, the calculation to purchase tokens was `msg.value/weiPerEth*tokenPerEth`. Notice that the division occurs before the multiplication. This example would have achieved a greater precision if the calculation performed the multiplication first and then the division, i.e. `msg.value*tokenPerEth/weiPerEth`. 1572 | 1573 | Finally, when defining arbitrary precision for numbers it can be a good idea to convert variables into higher precision, perform all mathematical operations, then finally when needed, convert back down to the precision for output. Typically `uint256`'s are used (as they are optimal for gas usage) which give approximately 60 orders of magnitude in their range, some of which can be dedicated to the precision of mathematical operations. It may be the case that it is better to keep all variables in high precision in solidity and convert back to lower precisions in external apps (this is essentially how the `decimals` variable works in [ERC20 Token](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) contracts). To see examples of how this can be done and the libraries to do this, I recommend looking at the [Maker DAO DSMath](https://github.com/dapphub/ds-math). They use some funky naming, `WAD`s and `RAY`s but the concept is useful. 1574 | 1575 |

Real-World Example: Ethstick

1576 | 1577 | I couldn't find a good example where rounding has caused a severe issue in a contract, but I'm sure there are plenty out there. Feel free to update this if you have a good one in mind. 1578 | 1579 | For lack of a good example, I want to draw your attention to [Ethstick](https://etherscan.io/address/0xbA6284cA128d72B25f1353FadD06Aa145D9095Af#code) mainly because I like the cool naming within the contract. This contract doesn't use any extended precision, however, it deals with `wei`. So this contract will have issues of rounding, but only at the `wei` level of precision. It has some more serious flaws, but these are relating back to the difficulty in getting entropy on the blockchain (see [Entropy Illusion](#entropy-illusion)). For a further discussion on the Ethstick contract, I'll refer you to another post of Peter Venesses, [Ethereum Contracts Are Going to be Candy For Hackers](https://vessenes.com/ethereum-contracts-are-going-to-be-candy-for-hackers/). 1580 | 1581 | 1582 |

16. Tx.Origin Authentication

1583 | 1584 | Solidity has a global variable, `tx.origin` which traverses the entire call stack and returns the address of the account that originally sent the call (or transaction). Using this variable for authentication in smart contracts leaves the contract vulnerable to a phishing-like attack. 1585 | 1586 | For further reading, see [Stack Exchange Question](https://ethereum.stackexchange.com/questions/1891/whats-the-difference-between-msg-sender-and-tx-origin), [Peter Venesses's Blog](https://vessenes.com/tx-origin-and-ethereum-oh-my/) and [Solidity - Tx.Origin attacks](https://medium.com/coinmonks/solidity-tx-origin-attacks-58211ad95514). 1587 | 1588 |

The Vulnerability

1589 | 1590 | Contracts that authorise users using the `tx.origin` variable are typically vulnerable to phishing attacks which can trick users into performing authenticated actions on the vulnerable contract. 1591 | 1592 | Consider the simple contract, 1593 | 1594 | ```solidity 1595 | contract Phishable { 1596 | address public owner; 1597 | 1598 | constructor (address _owner) { 1599 | owner = _owner; 1600 | } 1601 | 1602 | function () public payable {} // collect ether 1603 | 1604 | function withdrawAll(address _recipient) public { 1605 | require(tx.origin == owner); 1606 | _recipient.transfer(this.balance); 1607 | } 1608 | } 1609 | ``` 1610 | 1611 | Notice that on line \[11\] this contract authorises the `withdrawAll()` function using `tx.origin`. This contract allows for an attacker to create an attacking contract of the form, 1612 | 1613 | ```solidity 1614 | import "Phishable.sol"; 1615 | 1616 | contract AttackContract { 1617 | 1618 | Phishable phishableContract; 1619 | address attacker; // The attackers address to receive funds. 1620 | 1621 | constructor (Phishable _phishableContract, address _attackerAddress) { 1622 | phishableContract = _phishableContract; 1623 | attacker = _attackerAddress; 1624 | } 1625 | 1626 | function () payable { 1627 | phishableContract.withdrawAll(attacker); 1628 | } 1629 | } 1630 | ``` 1631 | To utilise this contract, an attacker would deploy it, and then convince the owner of the `Phishable` contract to send this contract some amount of ether. The attacker may disguise this contract as their own private address and social engineer the victim to send some form of transaction to the address. The victim, unless being careful, may not notice that there is code at the attacker's address, or the attacker may pass it off as being a multisignature wallet or some advanced storage wallet (remember 1632 | source code of public contracts is not available by default). 1633 | 1634 | In any case, if the victim sends a transaction (with enough gas) to the `AttackContract` address, it will invoke the fallback function, which in turn calls the `withdrawAll()` function of the `Phishable` contract, with the parameter `attacker`. This will result in the withdrawal of all funds from the `Phishable` contract to the `attacker` address. This is because the address that first initialised the call was the victim (i.e. the `owner` of the `Phishable` contract). Therefore, `tx.origin` will be equal to `owner` and the `require` on line \[11\] of the `Phishable` contract will pass. 1635 | 1636 |

Preventative Techniques

1637 | 1638 | `tx.origin` should not be used for authorisation in smart contracts. This isn't to say that the `tx.origin` variable should never be used. It does have some legitimate use cases in smart contracts. For example, if one wanted to deny external contracts from calling the current contract, they could implement a `require` of the from `require(tx.origin == msg.sender)`. This prevents intermediate contracts being used to call the current contract, limiting the contract to regular code-less addresses. 1639 | 1640 |

Real-World Example: Not Known

1641 | 1642 | I do not know of any publicised exploits of this form in the wild. 1643 | 1644 |

Ethereum Quirks

1645 | 1646 | I intend to populate this section with various interesting quirks that get discovered by the community. These are kept in this blog as they may aid in smart contract development if one were to utilize these quirks in practice. 1647 | 1648 |

Keyless Ether

1649 | 1650 | Contract addresses are deterministic, meaning that they can be calculated prior to actually creating the address. This is the case for addresses creating contracts and also for contracts spawning other contracts. In fact, a created contract's address is determined by: 1651 | 1652 | `keccak256(rlp.encode([, ])` 1653 | 1654 | Essentially, a contract's address is just the `keccak256` hash of the account that created it concatenated with the accounts transaction nonce[^2]. The same is true for contracts, except contracts nonce's start at `1` whereas address's transaction nonce's start at `0`. 1655 | 1656 | This means that given an Ethereum address, we can calculate all the possible contract addresses that this address can spawn. For example, if the address `0x123000...000` were to create a contract on its 100th transaction, it would create the contract address `keccak256(rlp.encode[0x123...000, 100])`, which would give the contract address, `0xed4cafc88a13f5d58a163e61591b9385b6fe6d1a`. 1657 | 1658 | What does this all mean? This means that you can send ether to a pre-determined address (one which you don't own the private key to, but know that one of your accounts can create a contract to). You can send ether to that address and then retrieve the ether by later creating a contract which gets spawned over the same address. The constructor could be used to return all your pre-sent ether. Thus if someone were to obtain all your Ethereum private keys, it would be difficult for the attacker to discover that your Ethereum addresses also have access to this *hidden* ether. In fact, if the attacker spent too many transaction such that the nonce required to access your ether is used, it is impossible to recover your hidden ether. 1659 | 1660 | Let me clarify this with a contract. 1661 | 1662 | ```solidity 1663 | contract KeylessHiddenEthCreator { 1664 | uint public currentContractNonce = 1; // keep track of this contracts nonce publicly (it's also found in the contracts state) 1665 | 1666 | // determine future addresses which can hide ether. 1667 | function futureAddresses(uint8 nonce) public view returns (address) { 1668 | if(nonce == 0) { 1669 | return address(keccak256(0xd6, 0x94, this, 0x80)); 1670 | } 1671 | return address(keccak256(0xd6, 0x94, this, nonce)); 1672 | // need to implement rlp encoding properly for a full range of nonces 1673 | } 1674 | 1675 | // increment the contract nonce or retrieve ether from a hidden/key-less account 1676 | // provided the nonce is correct 1677 | function retrieveHiddenEther(address beneficiary) public returns (address) { 1678 | currentContractNonce +=1; 1679 | return new RecoverContract(beneficiary); 1680 | } 1681 | 1682 | function () payable {} // Allow ether transfers (helps for playing in remix) 1683 | } 1684 | 1685 | contract RecoverContract { 1686 | constructor(address beneficiary) { 1687 | selfdestruct(beneficiary); // don't deploy code. Return the ether stored here to the beneficiary. 1688 | } 1689 | } 1690 | ``` 1691 | This contract allows you to store keyless ether (relatively safely, in the sense you can't accidentally miss the nonce)[^3]. The `futureAddresses()` function can be used to calculate the first 127 contract addresses that this contract can spawn, by specifying the `nonce`. If you send ether to one of these addresses, it can be later recovered by calling the `retrieveHiddenEther()` enough times. For example, if you choose `nonce=4` (and send ether to the associated address), you will need to call `retrieveHiddenEther()` four times and it will recover the ether to the `beneficiary` address. 1692 | 1693 | This can be done without a contract. You can send ether to addresses that can be created from one of your standard Ethereum accounts and recover it later, at the correct nonce. Be careful however, if you accidentally surpass the transaction nonce that is required to recover your ether, your funds will be lost forever. 1694 | 1695 | For more information on some more advanced tricks you can do with this quirk, I recommend reading [Martin Swende's post](http://martin.swende.se/blog/Ethereum_quirks_and_vulns.html). 1696 | 1697 | 1698 |

One Time Addresses

1699 | 1700 | Ethereum transaction signing uses the Elliptic Curve Digital Signing Algorithm (ECDSA). Conventionally, in order to send a verified transaction on Ethereum, you sign a message with your Ethereum private key, which authorises spending from your account. In slightly more detail, the message that you sign is the components of the Ethereum transaction, specifically, the `to`, `value`, `gas`, `gasPrice`, `nonce` and `data` fields. The result of an Ethereum signature is three numbers, `v`, `r` and `s`. I won't go into detail about what each of these represent, instead I refer the interested readers to the [ECDSA wiki page](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm) (which describes `r` and `s`) and the [Ethereum Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf) (Appendix F - which describes `v`) and finally [EIP155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md) for the current use of `v`. 1701 | 1702 | So we know that an Ethereum transaction signature consists of a message and the numbers `v`, `r` and `s`. We can check if a signature is valid, by using the message (i.e. transaction details), `r` and `s` to derive an Ethereum address. If the derived Ethereum address matches the `from` field of the transaction, then we know that `r` and `s` were created by someone who owns (or has access to) the private key for the `from` field and thus the signature is valid. 1703 | 1704 | Consider now, that we don't own a private key, but instead make up values for `r` and `s` for an arbitrary transaction. Consider we have a transaction, with the parameters: 1705 | 1706 | ```javascript 1707 | {to: "0xa9e", value: 10e18, nonce: 0} 1708 | ``` 1709 | 1710 | I've ignored the other parameters. This transaction will send 10 ether to the `0xa9e` address. Now let's say we make up some numbers `r` and `s` (these have specific ranges) and a `v`. If we derive the Ethereum address related to these made up numbers we will get a random Ethereum address, let's call it `0x54321`. Knowing this address, we could send 10 ether to the `0x54321` address (without owning the private key for the address). At any point in the future, we could send the transaction, 1711 | ```javascript 1712 | {to: "0xa9e", value: 10e18, nonce: 0, from: "0x54321"} 1713 | ``` 1714 | along with the signature, i.e. the `v`, `r` and `s` we made up. This will be a valid transaction, because the derived address will match our `from` field. This allows us to spend our money from this random address (`0x54321`) to the address we chose `0xa9e`. Thus we have managed to store ether in an address that we do not have the private key and used a one-time transaction to recover the ether. 1715 | 1716 | This quirk can also be used to send ether to a large number of people in a trustless manner, as Nick Johnson describes in [How to send Ether to 11,440 people](https://medium.com/@weka/how-to-send-ether-to-11-440-people-187e332566b7). 1717 | 1718 |

Single Transaction Airdrops

1719 | 1720 | An Airdrop refers to the process of distributing tokens amongst a large 1721 | group of people. Traditionally, airdrops have been processed via a large number 1722 | of transactions where each transaction updates either a single or a batch of 1723 | user's balances. This can be costly and strenuous on the Ethereum blockchain. 1724 | There is an alternative method, in which many users balances can be credited 1725 | with tokens using a single transaction. 1726 | 1727 | This technique is explained in more detail by its proposer, RicMoo in his post: 1728 | [Merkle Air-Drops: Make Love, Not War](https://blog.ricmoo.com/merkle-air-drops-e6406945584d). 1729 | 1730 | The idea is to create a [Merkle Tree](https://en.wikipedia.org/wiki/Merkle_tree) 1731 | which contains (as leaf nodes) all the addresses and balances of users to be credited tokens. 1732 | This will be done off-chain. The merkle tree can be given out 1733 | publicly (again off-chain). A smart contract can then be created containing the 1734 | root hash of the merkle tree which allows users to submit [merkle-proofs](https://www.quora.com/Cryptography-How-does-a-Merkle-proof-actually-work) to obtain 1735 | their tokens. Thus a single transaction (the one used to create the contract, 1736 | or to simply store the Merkle tree root hash), allows all credited users to redeem 1737 | their airdropped tokens. 1738 | 1739 | RicMoo in his [post](https://blog.ricmoo.com/merkle-air-drops-e6406945584d) also provides an example of a function which can accept Merkle Proofs 1740 | and credit a user's balance: 1741 | ```solidity 1742 | function redeem(uint256 index, address recipient, 1743 | uint256 amount, bytes32[] merkleProof) public { 1744 | 1745 | // Make sure this has not been redeemed 1746 | uint256 redeemedBlock = _redeemed[index / 256]; 1747 | uint256 redeemedMask = (uint256(1) << uint256(index % 256)); 1748 | require((redeemedBlock & redeemedMask) == 0); 1749 | 1750 | // Mark it as redeemed (if we fail, we revert) 1751 | _redeemed[index / 256] = redeemedBlock | redeemedMask; 1752 | 1753 | // Compute the merkle root from the merkle proof 1754 | bytes32 node = keccak256(index, recipient, amount); 1755 | uint256 path = index; 1756 | for (uint16 i = 0; i < merkleProof.length; i++) { 1757 | if ((path & 0x01) == 1) { 1758 | node = keccak256(merkleProof[i], node); 1759 | } else { 1760 | node = keccak256(node, merkleProof[i]); 1761 | } 1762 | path /= 2; 1763 | } 1764 | 1765 | // Check the resolved merkle proof matches our merkle root 1766 | require(node == _rootHash); 1767 | 1768 | // Redeem! 1769 | _balances[recipient] += amount; 1770 | _totalSupply += amount; 1771 | Transfer(0, recipient, amount); 1772 | } 1773 | ``` 1774 | This function could be built into a token contract to allow future airdrops. 1775 | The only transaction required to credit all user's balances, would be the 1776 | transaction that sets the Merkle tree root. 1777 | 1778 | 1779 |

List of Interesting Crypto Related Hacks/Bugs

1780 | 1781 | * [SpankChain](https://medium.com/spankchain/we-got-spanked-what-we-know-so-far-d5ed3a0f38fe) 1782 | * [CoinDash](https://www.theregister.co.uk/2017/07/18/coindash_hack/) 1783 | * [SmartBillions](https://www.reddit.com/r/ethereum/comments/74d3dc/smartbillions_lottery_contract_just_got_hacked/) 1784 | * [Exchange Didn't add "0x" to payload](https://steemit.com/cryptocurrency/@barrydutton/breaking-the-biggest-canadian-coin-exchange-quadrigacx-loses-67-000-usdeth-due-to-coding-error-funds-locked-in-an-executable) 1785 | 1786 | 1787 | [^1]: This code was modified from [web3j](https://github.com/web3j/web3j/blob/master/codegen/src/test/resources/solidity/fibonacci/Fibonacci.sol) 1788 | 1789 | [^2]: A transaction nonce is like a transaction counter. It increments ever time a transaction is sent from your account. 1790 | 1791 | [^3]: Do not deploy this contract to store any real ether. It is for demonstrative purposes only. It has no inherent privileges, anyone can recover your ether if you deploy and use it. 1792 | --------------------------------------------------------------------------------