Skip to content

Commit 247af3d

Browse files
committed
Adds numbers to titles
1 parent 52c919b commit 247af3d

File tree

1 file changed

+16
-17
lines changed

1 file changed

+16
-17
lines changed

README.md

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ Although in its infancy, Solidity has had widespread adoption and is used to com
115115
- [Ethereum Smart Contract Security](https://medium.com/cryptronics/ethereum-smart-contract-security-73b0ede73fa8)
116116
- [Lessons Learnt from the Underhanded Solidity Contest](https://medium.com/@chriseth/lessons-learnt-from-the-underhanded-solidity-contest-8388960e09b1)
117117

118-
<h2 id="reentrancy"><span id="SP-1">Re-Entrancy</span></h2>
118+
<h2 id="reentrancy"><span id="SP-1">1. Re-Entrancy</span></h2>
119119

120120
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.
121121

@@ -262,7 +262,7 @@ contract EtherStore {
262262

263263
[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/).
264264

265-
<h2 id="ouflow"><span id="SP-2">Arithmetic Over/Under Flows</span></h2>
265+
<h2 id="ouflow"><span id="SP-2">2. Arithmetic Over/Under Flows</span></h2>
266266

267267
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.
268268

@@ -412,7 +412,7 @@ A 4chan group decided it was a great idea to build a ponzi scheme on Ethereum, w
412412

413413
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.
414414

415-
<h2 id="ether"><span id="SP-3">Unexpected Ether</span></h2>
415+
<h2 id="ether"><span id="SP-3">3. Unexpected Ether</span></h2>
416416

417417
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.
418418

@@ -551,7 +551,7 @@ Here, we have just created a new variable, `depositedEther` which keeps track of
551551

552552
I'm yet to find and 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/).
553553

554-
<h2 id="delegatecall"><span id="SP-4">Delegatecall</span></h2>
554+
<h2 id="delegatecall"><span id="SP-4">4. Delegatecall</span></h2>
555555

556556
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.
557557

@@ -730,7 +730,7 @@ The intended operation of these contracts was to have a simple low-cost deployab
730730

731731
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.
732732

733-
<h2 id="visibility"><span id="SP-5">Default Visibilities</span></h2>
733+
<h2 id="visibility"><span id="SP-5">5. Default Visibilities</span></h2>
734734

735735
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.
736736

@@ -804,7 +804,7 @@ contract WalletLibrary is WalletEvents {
804804

805805
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.
806806

807-
<h2 id="entropy"><span id="SP-6">Entropy Illusion</span></h2>
807+
<h2 id="entropy"><span id="SP-6">6. Entropy Illusion</span></h2>
808808

809809
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)).
810810

@@ -820,8 +820,7 @@ The source of entropy (randomness) must be external to the blockchain. This can
820820

821821
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.
822822

823-
<h2 id="contract-reference"><span id="SP-7">External Contract
824-
Referencing</span></h2>
823+
<h2 id="contract-reference"><span id="SP-7">7. External Contract Referencing</span></h2>
825824

826825
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.
827826

@@ -1062,7 +1061,7 @@ This [post](https://www.reddit.com/r/ethdev/comments/7x5rwr/tricked_by_a_honeypo
10621061

10631062

10641063

1065-
<h2 id="short-address"><span id="SP-8">Short Address/Parameter Attack</span></h2>
1064+
<h2 id="short-address"><span id="SP-8">8. Short Address/Parameter Attack</span></h2>
10661065

10671066

10681067
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.
@@ -1092,7 +1091,7 @@ I suppose it is obvious to say that validating all inputs before sending them to
10921091

10931092
I do not know of any publicised attack of this kind in the wild.
10941093

1095-
<h2 id="unchecked-calls"><span id="SP-9">Unchecked CALL Return Values</span></h2>
1094+
<h2 id="unchecked-calls"><span id="SP-9">9. Unchecked CALL Return Values</span></h2>
10961095

10971096
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 (intialised 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.
10981097

@@ -1171,7 +1170,7 @@ Notice that on line \[21\] the send function's return value is not checked, and
11711170
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.
11721171

11731172

1174-
<h2 id="race-conditions"><span id="SP-10">Race Conditions / Front Running</span></h2>
1173+
<h2 id="race-conditions"><span id="SP-10">10. Race Conditions / Front Running</span></h2>
11751174

11761175
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).
11771176

@@ -1222,7 +1221,7 @@ This function allows a user to permit other users to transfer tokens on their be
12221221

12231222
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.
12241223

1225-
<h2 id="dos"><span id="SP-11">Denial Of Service (DOS)</span></h2>
1224+
<h2 id="dos"><span id="SP-11">11. Denial Of Service (DOS)</span></h2>
12261225

12271226
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)
12281227

@@ -1378,7 +1377,7 @@ In the second example a privileged user was required to change the state of the
13781377
[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).
13791378

13801379

1381-
<h2 id="block-timestamp"><span id="SP-12">Block Timestamp Manipulation</span></h2>
1380+
<h2 id="block-timestamp"><span id="SP-12">12. Block Timestamp Manipulation</span></h2>
13821381

13831382
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.
13841383

@@ -1426,7 +1425,7 @@ This can be unnecessary if contracts aren't particularly concerned with miner ma
14261425

14271426
[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.
14281427

1429-
<h2 id="constructors"><span id="SP-13">Constructors with Care</span></h2>
1428+
<h2 id="constructors"><span id="SP-13">13. Constructors with Care</span></h2>
14301429

14311430
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.
14321431

@@ -1467,7 +1466,7 @@ This issue has been primarily addressed in the Solidity compiler in version `0.4
14671466
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).
14681467

14691468

1470-
<h2 id="storage"><span id="SP-14">Unintialised Storage Pointers</span></h2>
1469+
<h2 id="storage"><span id="SP-14">14. Unintialised Storage Pointers</span></h2>
14711470

14721471
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 intialising variables.
14731472

@@ -1529,7 +1528,7 @@ A honey pot named OpenAddressLottery ([contract code](https://etherscan.io/addre
15291528
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.
15301529

15311530

1532-
<h2 id="precision"><span id="SP-15">Floating Points and Precision</span></h2>
1531+
<h2 id="precision"><span id="SP-15">15. Floating Points and Precision</span></h2>
15331532

15341533
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.
15351534

@@ -1582,7 +1581,7 @@ I couldn't find a good example where rounding has caused a severe issue in a con
15821581
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 [Entropty 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/).
15831582

15841583

1585-
<h2 id="tx-origin"><span id="SP-16">Tx.Origin Authentication<span></h2>
1584+
<h2 id="tx-origin"><span id="SP-16">16. Tx.Origin Authentication<span></h2>
15861585

15871586
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.
15881587

0 commit comments

Comments
 (0)