Introduction to Smart Contract Security
Yajin Zhou (http://yajin.org)
Zhejiang University
Credits: Campbell R. Harvey, Ashwin Ramachandran, Brent Xu, Anastasia Mavridou, Aron Laszka
Background: Ethereum
Ethereum
It’s more than
cryptocurrency.
Basic Concepts
• Ethereum node
• Ethereum
• Accounts (Two types) and Wallets
• Transactions
• Smart Contracts
• Solidity: Language used for smart contract development
Ethereum Node
• Full node: Validate all transactions and new blocks
• Operate in a P2P fashion
• Each contains a copy of the entire Blockchain
• Light clients - store only block headers
• Provide easy verification through tree data structure
• Don’t execute transactions, used primarily for balance validation
• Implemented in a variety of languages (Go, Rust, etc.)
Accounts and Wallets
• Accounts:
• Two Kinds:
• External Owned Accounts - (EOA, most common account)
• Contract Accounts
• Allow for interaction with the blockchain
• Wallets:
• A set of one or more external accounts
• Used to store/transfer Ether
Accounts and Wallets
• External Account (EOA, Valid Ethereum Address)
• Consist of a public/private key-pair
• Can have a balance
• Has an associated nonce (amount of transactions sent from the
account) and a balance
• codeHash - Hash of associated account code, i.e. a computer
program for a smart contract (hash of an empty string for external
accounts, EOAs)
Accounts and Wallets
• Contract Account: Ethereum account that can store and
execute code
• Has an associated nonce and balance
• codeHash - hash of associated account code
• storageRoot contains Merkle tree of associated storage data
Examples
Transactions
• A request to modify the state of the blockchain
• Can run code (contracts) which change global state (storage)
• Launched by an EOA or Contract account (internal transaction)
• Types
• Fund Transfer Between EOA
• Deploy a Contract on Ethereum Network (discuss later)
• Execute a Function on a Deployed Contract (discuss later)
Transactions: Fund Transfer Between EOA
Transactions: Fund Transfer Between EOA
Smart Contracts
• Function like an external account
• Hold funds
• Can interact with other accounts and smart contracts
• Contain code
• Can be called through transactions
Code Execution
• Every Ethereum node contains a virtual machine (similar to Java)
• Called the Ethereum Virtual Machine (EVM)
• Compiles code from high-level language to bytecode
• Executes smart contract code and broadcasts state
• Every full-node on the blockchain processes every transaction
and stores the entire state
• What’s the problem here: consumes resources but gets nothing!
Gas
• Halting problem (infinite loop - consume resources) – reason for
Gas
• Problem: Cannot tell whether or not a program will run infinitely
from compiled code - why?
• Solution: charge fee per computational step to limit infinite loops
and stop flawed code from executing
• Every transaction needs to specify an estimate of the amount of
gas it will spend - gas Limit
• Essentially a measure of how much one is willing to spend on a
transaction, even if buggy
Gas Cost
• Gas Price: current market price of a unit of Gas (in Wei)
• Check gas price here: https://ethgasstation.info/
• Is always set before a transaction by user
• Gas Limit: maximum amount of Gas user is willing to spend
• Gas Cost (used when sending transactions) is calculated by gas used*gasPrice
• Gas used
• normal transaction - 21,000
• smart contracts: depends on resources consumed - instructions executed and
storage used
• What if gas limit < gas cost?
Gas Cost
Quick quiz: who will get the transaction fee?
A Normal Transaction
Gas Limit: Maximum amount of gas that a user will pay
for this transaction. The default amount for a standard
Gastransfer
ETH Used byisTxn: Actual
21,000 gas amount of gas used to execute the
transaction. Since this is a standard transfer, the gas used is
also 21,000
Gas Price: Amount of ETH a user is prepared to pay for each unit of gas.
The user chose to pay 8 Gwei for every gas unit, which is considered a
Eth Gas Station
Miner
• Miner is responsible for creating new block and packing
transactions
• They are rewarded by the network, and transaction fee
• They tend to pack the transactions with higher transaction fee
Background: Smart Contract
Smart contracts are widely used
• Voting systems
• Cryptocurrencies
• Gaming
• Lottery
• …
EVM: Ethereum Virtual Machine
• “Accounts” have code and storage
• Send each other “messages” (transactions)
• “Contracts” receive messages -> run code (function call)
• Stack-based language: 56 opcodes, arithmetic, boolean, control
flow, crypto
• New: gas, create, suicide
Ethereum Virtual Machine
• Stack based: Rather than relying on registers, any operation
will be entirely contained within the stack. Operands, operators,
and function calls all get placed on the stack, and the EVM
understands how act on that data and make the smart contract
execute.
• Ethereum uses Postfix Notation to implement its stack-based
implementation. What this means, in very simplified terms, is that
the last operator to get pushed on the stack will act on the data
pushed onto the stack before it.
• Example: if we want to perform 2 + 2, then we could just as easily
represent this as 2 2 +, which is Postfix
+
2
2
stack
How to Program a smart contract
solc --bin SimpleStorage.sol Contract bytecode
solc --bin-runtime SimpleStorage.sol Runtime bytecode
Bytecode vs. Runtime Bytecode
• The contract bytecode is the bytecode of what will actually end up
sitting on the blockchain PLUS the bytecode needed for the
transaction of placing that bytecode on the blockchain, and
initializing the smart contract (running the constructor).
• The runtime bytecode, on the other hand, is just the bytecode that
ends up sitting on the blockchain. This does not include the bytecode
needed to initialize the contract and place it on the blockchain.
Bytecode vs. Runtime Bytecode
• https://ethervm.io/decompile
Deploy a Contract on Ethereum Network
https://medium.com/coinmonks/transactions-in-ethereum-e85a73068f74
https://medium.com/coinmonks/transactions-in-ethereum-e85a73068f74
https://medium.com/coinmonks/transactions-in-ethereum-e85a73068f74
https://medium.com/coinmonks/transactions-in-ethereum-e85a73068f74
Deploy Smart Contracts
• In the transaction, the to is left empty (‘0x0’ is shown).
• In the input, we only place the bytecode. It is because our SimpleStorage
contract does not have a constructor that requires arguments. If arguments
are needed in constructor, they are encoded according to the type and
appended after the bytecode.
• The Contract address is found in Transaction Receipt.
• The default Gas Limit (gas) is 90,000 gas. If you do not specify the gas, you
will encounter “out of gas” as it takes more than 90,000 gas for processing
this transaction. Therefore we specify 200,000 gas for this transaction.
• It turns out the transaction processing only takes 112,213 gas. The remain
is returned to transaction sender.
https://medium.com/coinmonks/transactions-in-ethereum-e85a73068f74
Execute a Function on a Deployed Contract
Function Selectors: which function to call
• In the Solidity code above, two functions are
defined: get() and set(uint).
• When contract code is compiled, these functions are processed
through a hashing function (keccak256, implemented as sha3 in
web3 library) and the first four bytes are taken out as the function
selectors.
• 0x6d4ce63c for get()
• 0x60fe47b1 for set(uint256)
Execute a Function on a Deployed Contract
Reentrancy Attack
https://dasp.co/
Methods of calling functions
• Call——invokes a function and can transfer Ether.
• Direct call——using a function as a method of the contract
Methods of calling functions
• Send——is used to transfer Ether to the recipient r in the form of
r.send(amount) - r is receiver (stranger!)
• send is actually a call
• send passes empty function signature to the recipient
• if the recipient is a contract, its fallback function is executed.
Fallback function
Exception
• In Solidity an exception may be
raised:
• the execution runs out of
gas;
• the call stack reaches its
limit;
• the command throw is
executed.
• If an exception occurs the side
effects of the transaction is
reverted
Exception
• The problem is :call don't
propagate exceptions!
• If c throws exception(direct call
)
• exception properly handled
• the value field of x is 0
• If c throws exception(via call)
• only the side effects of that single
instruction is reverted
• the value field of x is 2
Exception
• Call is like:
• caller makes a phone call to callee
without caring about any response
• Whether the callee throws a
exception does not matter
• Direct call is like:
• caller works with callee in
the same place
• any exception thrown will
be captured immediately
The DAO Attack
• The DAO contract raised
about $150M before being
attacked
• An attacker managed to put
about $60M under his
control
The DAO Attack
• To perform the attack:
• Deploy a contract shown
right
• Donate some Ether for
Mallory
• Call the fallback function
of Mallory
Fallback function
The DAO Attack
• Looping until:
• Out of gas
• Stack limit is reached
• Balance of the DAO is less
than the credit of Mallory
• Exception happens in the
withdraw
• the side effects of this
invocation will be reverted
Access Control
A real example: Rubixi
should be “function Rubixi()”
https://etherscan.io/address/0xe82719202e5965Cf5D9B6673B7503a3b92DE20be#code
Overflow
Background
What’s the problem
Pass a big value _amount!
A Real Example: SMT Token
_feeSmt = 8fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
value = 7000000000000000000000000000000000000000000000000000000000000001
__feeSmt + value = 0
attacker
Short Address Attack
Overview
• Short address attacks are a side-effect of the EVM itself accepting
incorrectly padded arguments. Attackers can exploit this by using
specially-crafted addresses to make poorly coded clients encode
arguments incorrectly before including them in transactions
https://ericrafaloff.com/analyzing-the-erc20-short-address-attack/
https://ericrafaloff.com/analyzing-the-erc20-short-address-attack/
First try
https://ericrafaloff.com/analyzing-the-erc20-short-address-attack/
Second try
EVM will pad zero to the value
512 = 2<<8
https://ericrafaloff.com/analyzing-the-erc20-short-address-attack/