In our previous event we delved into “How to To Become A Smart Contract Engineer” in a somewhat high level perspective, focusing on how it resembles and differs from any other form of software development.
In this event, we’ll focus on Solidity, the prevailing framework for Ethereum smart contracts, diving a little deeper by iterating and elaborating on famous bugs that were reported by the developer community as well as during the professional experience of the speaker.
We hope that by combining the theoretical high level accounts with low level failure case-studies we’ll be able to adequately educate newcomers as well as seasoned developers on what to watch out for and how to correctly develop a smart contract.
2. Blockchain Academy
A community for technologists looking to learn more
about Crypto and Blockchain technology
Blockchain AcademyLeonid Beder April 24, 2018
3. About Me
April 24, 2018Blockchain Academy
leonid@orbs.com PGP Key:
leonid@kik.com D749 1F09 3721 0A31 72B5
@LeonidBeder DBF3 7F35 EBC3 E4B2 44B4
@lbeder
Leonid Beder
4. Agenda
1.Introduction to smart contracts
2.Introduction to Solidity
3.(In)famous bugs and issues
4.Additional tools and techniques
7. Nick Szabo, Smart Contracts: Building Blocks for Digital Markets, 1996
“A smart contract is a set of promises, specified in
digital form, including protocols within which the parties
perform on these promises.”
8.
9. What is a Smart
Contract?
“A smart contract is a set of promises, specified in
digital form, including protocols within which the parties
perform on these promises.”
• Example: a sales contract.
• The seller promises to deliver the goods in exchange for the buyer.
• The buyer promises to pay the desired price.
10. What is a Smart
Contract?
“A smart contract is a set of promises, specified in
digital form, including protocols within which the
parties perform on these promises.”
• Digital form means that the contract has to be programmed in machine
readable code.
11. What is a Smart
Contract?
“A smart contract is a set of promises, specified in
digital form, including protocols within which the
parties perform on these promises.”
• For example, say the parties agree that the purchased good is to be paid in
Bitcoin. The obvious protocol of choice would then be the Bitcoin protocol
(Bitcoin scripting language).
12. What is a Smart
Contract?
“A smart contract is a set of promises, specified in
digital form, including protocols within which the parties
perform on these promises.”
13. Popular
Implementations
• Ethereum implements a (nearly) Turing-complete language on its
blockchain, a prominent smart contract framework.
• Bitcoin implements a Turing-incomplete Script language that
allows the creation of limited smart contracts, such as:
multisignature accounts, payment channels, escrows, time locks,
atomic cross-chain trading, oracles, etc.
15. What is Solidity?
• Solidity is an OOP language for writing smart contracts (mostly?) on Ethereum
• It was originally developed by Dr. Gavin Wood, Dr. Christian Reitwiessner,
Alex Beregszaszi, Liana Husikyan, Yoichi Hirai and several former Ethereum
core contributors.
Dr. Gavin Wood Dr. Christian Reitwiessner Alex Beregszaszi Yoichi HiraiLiana Husikyan
16. An example
• Let’s start with a simple example of a smart contract named Greeter, which will:
• Initialized with a greeting message (e.g., “Hello World!”).
• Provide a method to read/query the greeting message.
• Provide a method to write/modify the greeting message.
• For this talk, we will use the official online Remix IDE:
https://remix.ethereum.org.
• You can find all the code here: https://github.com/blockchain-academy/how-
not-to-destroy-your-ether
17. Solidity version to use
Contract name
public state variable of type string
Constructor, receiving a single
argument of type string
public method, receiving a single
argument of type string
18. Fundamentals: Execution Model
• Every smart contract needs to be compiled and deployed to the network.
• Every transaction or message call in Ethereum is executed by the Ethereum Virtual
Machine (EVM) on every Ethereum node (miner or a just a full node).
• Since that every smart contract is running on the EVM, and every single operation is
actually executed simultaneously by every node in the network - there should be a
mechanism to limit the resources used by each contract.
• Such mechanism is implemented in Ethereum via gas:
• Every operation has a deterministic (yet, hard to sometimes predict) cost measured in
quantifying units of gas.
• Every gas unit consumed by a transaction must be paid for in Ether, based on a
gas/Ether price which is set by the sender of the original sender of transaction.
19. Fundamentals: Execution Model
• Transactions have also a gas limit parameter that is an upper
bound on how much gas the transaction can consume.
❏Why is the gas limit parameter needed?
❏There is also a block gas limit (i.e., an upper bound to the total
amount of gas consumed by all the transaction in a block. Why
is it needed?
❏The protocol allows the miner of a block to adjust the block
gas limit by a factor of 1/1024 (0.0976%) in either direction.
20.
21.
22.
23.
24.
25.
26. Fundamentals: Special Variables and
Functions
• There are special variables and functions which always exist in
the global namespace.
• For our talk, we (mostly) need to know:
• msg.sender (address): sender of the message (current call).
• msg.value (uint): number of wei sent with the message.
27. Fundamentals: Function and State
Variables Visibility
• In Solidity, there are four types of visibilities:
• For functions:
• external: can be called externally from other accounts/contracts.
• public (default): can be called by everyone.
• internal: can only be called internally.
• private: can only be called internally and only from the contract itself.
28. Fundamentals: Function and State
Variables Visibility
• For state variables:
• external: N/A
• public: can be accessed by everyone.
• internal (default): can only be accessed internally.
• private: can only be accessed internally and only from the
contract itself.
29.
30.
31. Fundamentals: Function
Modifiers• Modifiers can be used to modify the behaviour of functions.
• For example, a very common use case is by checking a pre- or post-conditions.
• They are very similar to before/after/around filters/hooks in other programming
languages.
• For example, let’s augment our Greeter smart contract to:
• Have an owner (in our case, the deployer of the smart contract).
• Make sure than only the owner can further modify the greeting.
32.
33.
34.
35.
36.
37.
38.
39. Fundamentals: Fallback
Function
• A smart contract can have exactly one unnamed function.
• It’s executed on a call to the contract if none of the other
functions match the given function identifier.
• For example, when Ether is being transferred to the contract.
40. Fundamentals: Payable
ModifierIn order to receive Ether, every function must be marked as payable:
• When sending Ether as part of a function call, the function must be
marked as payable.
• When sending Ether directly to a contract, its fallback function must be
marked as payable.
If no such function exists, the contract cannot receive Ether through regular
transactions.
58. Bugs: Overflow/Underflow
• Solidity can handle (up to) 256 bit numbers (values up to 2²⁵⁶-1).
• Overflow is when a number gets incremented above its maximum value:
• Adding 1 to 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF results in 0.
• Underflow is the inverse case, when the number is unsigned,
decrementing will underflow the number:
• Subtracting 1 from 0x000000000000000000000000000000000000
results in 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.
59. Mitigation #1: Test for
Correctness• Test for correctness before performing any operations:
60.
61.
62.
63. Mitigation #2: SafeMath
• Always use the (de-facto) standard SafeMath library.
• You can it and many other nice, relatively stable, smart contracts
in OpenZeppelin’s Github repo:
https://github.com/OpenZeppelin/zeppelin-solidity
80. Use Case: Parity “hack” #1
• TL;DR: A vulnerability was found on the Parity Multisig
Wallet version 1.5+, that allowed an attacker to steal over
150,000 Ether ($30,000,000, at the time; $105,000,000 today
[ETH/USD 700]).
• A white hat hacker group subsequently drained other Parity
wallets to protect funds worth 377,105 ETH ($85,000,000, at
the time; ~$264,000,000 today [ETH/USD 700]).
81. Use Case: Parity “hack” #1
• So what’s happened there?
• You can find the original code here:
https://raw.githubusercontent.com/paritytech/parity/4d08e7b0ae
c46443bf26547b17d10cb302672835/js/src/contracts/snippets/
enhanced-wallet.sol
82.
83.
84.
85.
86.
87. Use Case: Parity “hack” #1
But, wait… how does WalletLibrary work with the Wallet
contract?
90. Use Case: Parity “hack” #1
• The attacker exploited this and simply changed the contract’s
m_owners state variable to a list containing only their address,
and requiring just one confirmation to execute any transaction:
https://etherscan.io/tx/0x9dbf0326a03a2a3719c27be4fa69aacc
9857fd231a8d9dcaede4bb083def75ec
92. Mitigation
• Complexity is a vulnerability. Keep It Simple Stupid.
• Always define visibility explicitly.
• Don’t extract the constructor logic into the library contract.
Avoid premature optimizations!
• Don’t use delegatecall as a catch-all forwarding mechanism.
93. Mitigation: Parity Developers’
Fix
• Parity has quickly fixed the issue here:
https://github.com/paritytech/parity/commit/e06a1e8dd9cfd8bf5
d87d24b11aee0e8f6ff9aeb
97. Use Case: Rubixi
• Rubixi is a contract which implements a pyramid scheme (allegedly).
• Investors can deposit funds.
• The owner can collect all of the funds.
98.
99.
100.
101. Mitigation
• Well, for starters, try not to misname functions…
• Stay vigilant! The scammers are getting better and better…
• Starting from 0.4.22, you can now use the safe constructor
method instead:
102.
103. Leonid Beder
Example #4
“It will be like a taco inside a taco
within a Taco Bell that’s inside a KFC,
within a bowl, that’s inside your
brain...” / South Park S14E10
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114. Mitigation #1: Checks-Effects-
InteractionsChecks-Effects-Interactions Pattern:
1.Perform checks (who called the function, are the arguments in range,
did they send enough Ether, does the person have tokens, etc.).
1.If all checks passed, effects to the state variables of the current
contract should be made.
1.Lastly, perform any interaction with other accounts/contracts.
115.
116. Mitigation #2: Avoid call.value()()
When sending Ether, be aware of the relative tradeoffs between the use of:
1.address.call.value()(): will send the provided Ether and trigger code
execution given all available gas.
1.address.send(): will send the provided Ether and trigger code execution given
a limited stipend of 2,300 gas.
1.address.transfer(): is equivalent to require(address.send()). It will
automatically revert if the send fails.
117.
118. Use Case: “The DAO”
• “The DAO” is the name of a particular DAO (Decentralized Autonomous
Organization), conceived of and programmed by the team behind German
startup Slock.it a company building "smart locks" that let people share
their things (cars, boats, apartments) in a decentralized version of Airbnb.
• It was launched on 30th April, 2016, with a 28-day funding window.
• It was the largest crowdfunding in history, having raised over
$150,000,000 from more than 11,000 enthusiastic members.
119. Use Case: “The DAO”
• On 18th June, the attacker started to drain “The DAO” using a
(relatively) sophisticated reentrancy attack.
• The attacker has managed to drain more than 3,600,000 Ether
($72,000,000, at that time; astounding $2,520,000,000 today
[ETH/USD 700]).
• How did the Ethereum community responded?
138. “Alternative” Ether Transfer
• In addition to the regular means to send Ether (e.g., call, send/transfer), there are two
more ways which will bypass the fallback function:
1.selfdestruct: The only possibility that code is removed from the blockchain is when a
contract at that address performs the selfdestruct operation.
• If the receiving address is a contract, its fallback function does not get executed.
1.As a miner, set the target address as the coinbase address in order for it to receive
block mining awards.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151. Mitigation: Beware of
Assumptions
• Never use a contract’s balance as a guard.
• In general, be mindful of language/framework specific features and updates.
1.Beware of compiler optimizations bugs and test accordingly
2.Beware of compiler specific bugs and always use strict compiler version.
3.Beware of potential miners’ intervention (e.g., front-running, chain re-org, etc.).
• 0.4.21 compiler version... Ethereum is still an alpha.
154. (Similar) Use Case: Parity
“hack” #2• Approximately 513,000 ETH ($154,000,000, at that time; $359,100,000
today [ETH/USD 700]) has been locked in the affected contracts.
• No funds were “stolen” per-say; only made unreachable, by an accident.
• There are few proposals for methods to restore the lost funds (e.g., the
very recent EIP999) and even for a new ERP (Ethereum Recovery
Proposal) governance model, but it’s unlikely to happen any time soon.
159. (Similar) Use Case: Parity
“hack” #2• The WalletLibrary contract contains a state variables that it expects to be
shadowed by the calling contract’s own state.
• Once deployed, the WalletLibrary contract is simply uninitialized, so
m_numOwners is 0.
• If the WalletLibrary isn’t executed in a Wallet contract’s context,
m_numOwners is 0, allowing anyone to call methods that this modifier guards,
one of which is initWallet.
160. (Similar) Use Case: Parity
“hack” #2• So what did devops199 has done exactly?
• Nov 06, 2017 14:33:47 (UTC):
https://etherscan.io/tx/0x05f71e1b2cb4f03e547739db15d080fd30c989eda
04d37ce6264c5686e0722c9
• Called the initWallet method against the deployed WalletLibrary.
• Set 0xae7168deb525862f4fee37d987a971b385b96952 as its only
owner.
161.
162. (Similar) Use Case: Parity
“hack” #2• Nov 06, 2017 15:25:21 (UTC) (51 minutes from previous tx):
https://etherscan.io/tx/0x47f7cff7a5e671884629c93b368cb18f58a993f4
b19c2a53a8662e3f1482f690
• Called the kill method with
0xae7168deb525862f4fee37d987a971b385b96952 as the
beneficiary address.
177. Mitigation #1: Favor Pull over
Push• Always remembers that you’re not only interacting with human
beings, but also with other contracts.
• Favor pull over push for external calls.
178.
179. Mitigation #2: Ignore
Contracts• It’s usually not recommended or desired, but it’s also possible to opt-out
from interacting with contract using the following check:
181. Testing and Development
• Truffle (http://truffleframework.com/) is the most popular development
framework for Ethereum.
• Reuse existing libraries, such as OpenZeppelin
(https://github.com/OpenZeppelin/zeppelin-solidity)
• Ganache (http://truffleframework.com/ganache/) is a tool which allows you
to quickly fire up a personal Ethereum blockchain which you can use to run
tests, execute commands, and inspect state while controlling how the chain
operates.
182.
183.
184. Testing and Development
• solidity-coverage (https://github.com/sc-forks/solidity-coverage)
code coverage for Solidity smart-contracts.
190. Oyente
• Oyente (https://oyente.melon.fund) another analysis tool for
smart contracts with both CLI and a GUI similar interface to
Remix.
• At the moment, the latest supported compiler is 0.4.17.