Penetration Test Report (TrailOfBits): EIP 1283

1/17/2019 EIP-1283 - Recommendations - Google Docs
EIP-1283 Incident Report
Background and Lessons Learned
Prepared For:
Hudson Jameson | E thereum Foundation
hudson@ethereum.org
Martin Swende | E thereum Foundation
martin.swende@ethereum.org
Prepared By:
Dan Guido | T rail of Bits Petar Tsankov | C hainSecurity
dan@trailofbits.com petar@chainsecurity.com
Josselin Feist | T rail of Bits Matthias Egli | C hainSecurity
josselin@trailofbits.com matthias@chainsecurity.com
David Pokora | T rail of Bits Hubert Ritzdorf | C hainSecurity
david.pokora@trailofbits.com hubert@chainsecurity.com
Evan Sultanik | T rail of Bits Tomasz Kolinko | E veem
evan.sultanik@trailofbits.com kolinko@gmail.com
Gustavo Grieco | T rail of Bits
gustavo.grieco@trailofbits.com
https://docs.google.com/document/d/15Qk_k2ebY0EQsJe63USJ_Prn1r-MRN0IKLbMEgvuKgc/edit# 1/10
1/17/2019 EIP-1283 - Recommendations - Google Docs
EIP-1283 Gas Calculation Security Incident 3
Background 3
Vulnerability Description 3
Exploit Scenario 3
Recommendations 4
Short-term 4
Long-term 4
Appendix A. List of vulnerable contracts 6
Appendix B. Review of proposed remediations 7
Proposal 1: Add a condition to SSTORE that reverts if less than 2300 gas remains 8
Proposal 2: Add a new call context that permits LOG opcodes but not changes to
state 8
Proposal 3: Raise the cost of SSTORE to dirty slots to >=2300 gas 8
Proposal 4: Reduce the gas stipend sent 8
Proposal 5: Increase the cost of writes to dirty slots back to 5000 gas, and add 4800
gas to the refund counter 9
Proposal 6: Add contract metadata specifying per-contract EVM version, and only
apply SSTORE changes to contracts deployed with the new version. 9
Appendix C. Proposal #7: Refund difference of intended cost of writes 10
Date of Report: January 17th, 2019
Document Version: 1.2
Changelog
1.0 (January 16, 2018): Initial release
1.1 (January 16, 2018): Added further detail to recommendations
1.2 (January 17, 2018): Added A ppendix B and A ppendix C
https://docs.google.com/document/d/15Qk_k2ebY0EQsJe63USJ_Prn1r-MRN0IKLbMEgvuKgc/edit# 2/10
1/17/2019 EIP-1283 - Recommendations - Google Docs
EIP-1283 Gas Calculation Security Incident
Background
EIP-1283 was i nitially proposed on August 1, 2018. It was a ccepted on November 28, 2018.
On January 14th, 2018, two days before the C onstantinople hard fork, a security i ssue in
EIP-1283 was discovered and detailed by ChainSecurity. The fork’s modification to gas
computation would have led previously safe contracts to become vulnerable to a
reentrancy attack. For approximately 24 hours spanning January 15th to 16th, 2018, Trail of
Bits, ChainSecurity, and Eveem proceeded to assess the number of vulnerable contracts on
Ethereum mainnet, considered potential mitigations, and reflected on how the situation
could have been avoided.
The current EIP process depends on one of a few security experts dedicating enough of her
time to fully review each modification. Security review may not always occur for EIPs that
need it.
The security of Ethereum smart contracts relies on the immutability of the blockchain. A
contract’s properties are typically proven safe for only a single specification of the EVM. Any
change to the EVM specification can lead to a violation of an existing contract’s general
semantics, and thereby its security properties. EIP-1283 constituted such a change.
Vulnerability Description
A common reentrancy mitigation relies on the use of the Solidity s end and t ransfer
functions. These functions limit the gas given to a call to 2300. It is assumed that it is not
possible to change a state variable with this gas limitation. EIP-1283 introduces a new gas
computation which allows for cheaper state variable modifications. This makes it possible
to change a state variable with less than 2300 gas, breaking the reentrancy mitigation used
by already deployed contracts.
See ChainSecurity’s a nnouncement for further explanation, including a proof-of-concept
exploit.
Exploit Scenario
Alice develops a smart contract and ensures the safety of the code through formal
methods. The contract is proved reentrancy-safe. Alice deploys the contract and transfers
100 ethers to it. The Constantinople hard fork occurs. Gas computation rules change.
Alice’s contract becomes vulnerable to a reentrancy attack. Bob takes advantage of the
reentrancy and steals the 100 ethers.
https://docs.google.com/document/d/15Qk_k2ebY0EQsJe63USJ_Prn1r-MRN0IKLbMEgvuKgc/edit# 3/10
1/17/2019 EIP-1283 - Recommendations - Google Docs
Recommendations
Short-term
Do not implement EIP-1283. Low gas cost for storage changes can break the implicit
assumption that C ALL instructions with the 2300 gas stipend are safe from reentrancies.
If EIP-1283 is implemented as originally specified, ensure that dirty storage is tracked per
call, not per transaction. This will ensure that any call causing reentrancy will not be given a
gas discount. Consider using a new opcode to prevent changing the behavior of existing
contracts.
Consider refunding the difference of the intended cost of writes, detailed in A ppendix C.
Long-term
Explicitly define which parts of Ethereum are considered immutable and which ones may
change in future network upgrades. For example:
Component Mutability Discussion
Instruction Semantics Immutable? Instruction semantics must be immutable.
Available instructions Mutable? Instructions can be added but must not be
removed.
Gas cost of instructions Immutable? Consider denial-of-service attacks, and whether
gas costs could be restricted to move only in a
single direction (e .g., up).
Favor new opcodes rather than changing the gas
cost of existing ones.
Changing the gas cost of instructions would not
be a problem if developers did not assume they
are invariant from one version of EVM to
another.
Gas limit per Mutable? Can this decrease over time?
transaction/block
Define a set of criteria to determine “high-risk” EIPs. For any high-risk EIPs, allocate
specialized security resources to fully review their ramifications prior to approval. Consider
https://docs.google.com/document/d/15Qk_k2ebY0EQsJe63USJ_Prn1r-MRN0IKLbMEgvuKgc/edit# 4/10
1/17/2019 EIP-1283 - Recommendations - Google Docs
as high-risk any EIP that changes existing contract behavior. In particular, flag for security
review EIPs that reference the following:
● Modifications to gas computation
● Contract upgradability
● New instructions that lower gas usage for existing functionality1
● New instructions that introduce a new calling convention
● Change to value transactions, especially Ether
Consider creating a reentrancy-safe CALL instruction that can be used when reentrancy is
undesired. This instruction would allow a contract to send ethers to another contract,
execute some instructions (such as LOG), but prevent a reentrancy attack. A
reentrancy-mitigation at the EVM level would prevent incorrect assumptions from
high-level languages, such as Solidity and Vyper. Alternatively, consider adding a
recursion-limiting opcode that prevents a contract from recurring on the call stack
thereafter.2
Review and update documentation to underscore sensitive areas of Ethereum that could
retroactively change how earlier deployed smart contracts behave. For instance,
developers are often told to assume that transfer/send operations are reentrancy-safe due
to gas costs, when gas cost is a property of Ethereum that could be subject to change.
Consider specifying a “constitution” that defines what can be changed between different
versions of the EVM. This would allow developers to begin using patterns that are
future-proofed.
1 This may enable contracts to conduct attacks that were previously impossible, e .g., "C ALL_CHEAP" .
2 Recursion in this context is meant on a contract-level, not a function-level.
https://docs.google.com/document/d/15Qk_k2ebY0EQsJe63USJ_Prn1r-MRN0IKLbMEgvuKgc/edit# 5/10
1/17/2019 EIP-1283 - Recommendations - Google Docs
Appendix A. List of vulnerable contracts
This non-exhaustive list