Executive summary: once the Istanbul hardfork occurs (around early 2020), a very specific interaction with OpenZeppelin/ZeppelinOS upgradeable (proxy) contracts will no longer work (receiving Ether from other contracts via
transfer). Nonetheless, all contract functions and the upgrade system itself will remain functional. This concerns less than 1% of all deployed upgradeable contracts: a list with all affected addresses is included at the end of the article.
Much has been discussed about the upcoming Istanbul hardfork (read @fasteater’s overview of the changes to learn more), specially regarding EIP1884, which will cause some EVM operations to be more expensive. This means the set of rules under which smart contracts operate is about to change, potentially breaking some applications. Unfortunately, a subset of the OpenZeppelin SDK (previously ZeppelinOS) upgradeable (proxy) contracts will be affected by this.
EIP1884 most contentious change is the gas cost increase in
SLOAD from 200 to 800 gas. While most contract operations are constrained only by the transaction’s gas (a user-supplied value), Ether transfers between contracts using Solidity’s
transfer or Vyper’s
send functions forward a fixed amount of gas. This means that a contract that has its gas cost increased by EIP1884 may no longer be able to receive funds in this manner.
send were originally created as a simple way to mitigate reentrancy vulnerabilities. While they successfully fulfill this purpose, their approach is too heavy-handed, leading to issues such as this one. Consensus in the Ethereum security community is that their usage should be discouraged and replaced with either using the checks-effects-interactions pattern, or custom solutions such as our ReentrancyGuard contract. If you want to learn more, the Consensys Diligence team put together a great writeup on this subject.
How upgradeable contracts are affected
All contract functions, as well as the upgrade system, will continue to work. EIP1884 will only affect:
- OpenZeppelin/ZeppelinOS upgradeable (proxy) contracts, e.g. deployed via
$ oz create
- with a
- that receive Ether from other contracts via
This subset represent less than 1% of all upgradeable contracts currently deployed on mainnet. After Istanbul, these contracts will no longer be able to receive Ether this way (reverting the transaction). Note that sending funds from external accounts, or from other contracts via either
payable functions or
call will continue to work correctly.
The reason why this affects proxy contracts more than non-upgradeable contracts is because these must perform an extra
SLOAD to fetch the underlying implementation address (the very operation that EIP1884 makes more expensive). @chris.whinfrey and @shanefontaine from the Authereum team wrote a great in-depth article on the technical details, along with a list of other upgradability solutions that are also affected by the hardfork. They also kindly reached out to us privately before publishing to make sure we were aware of their findings.
We got in contact with the awesome people from the Tenderly team to pinpoint exactly which contracts meet the criteria explained above. They very quickly compiled this list for us, which we expect will help our users prepare for the hardfork and make any necessary adjustments to their applications.
The following upgradeable contracts have received Ether via the methods explained above and will no longer be able to do so come Istanbul. If you control one of these addresses and are unsure of the consequences to your particular contract, get in contact with us! We’ve already identified and contacted the owners of most of them, but some still remain unknown.
0x3e55cbaeaa14765536073c3967f0f990eb4d07f7 // 0xUniverse 0x137ce274199a106b1aa3036241d6757c06968c21 // 0xUniverse 0x2e9a1cfee65b283f5fcfcd84b494c0fc0e0cc486 // 0xUniverse 0xde56eaf3d5a683a386ad9249eb9ea2bc622aae8d // 0xUniverse 0x6d1d7997b2cf32e686ced406e71729d79f2d6419 // Authereum 0x526bdb6bfbb6a5a4e0d73285a7950329d822d95a // Authereum 0xdc4b1f3396325df2cbd853e2bd48acd8d1d7d79b // Authereum 0xc80625a2b9cce29a7eb2c121626ebc0c583294ee 0x7bda753a429502ac7461c9c0de69d50d9940b7a0 0x4206f6463fb047623577c47ec3294f2595ffa0af 0x0f83996b111fd0b317720050a4fa37706edea14b
Best practices moving forward
Istanbul has served as a rude awakening, showing Ethereum developers that having fixed gas allowances at the smart contract level can backfire unexpectedly on protocol upgrades, and is a short-term solution better avoided altogether.
Ways to avoid these sort of issues in the future include:
- removing the fixed gas limit on Ether transfers (we’re including a helper function for this in the next release of the OpenZeppelin Contracts!)
- stop sending funds directly altogether and switch to a PullPayment strategy
Regarding our proxies, we’re currently evaluating changing them to be EIP1822-compatible. Among other improvements, this will make them work under EIP1884, but is not a long-term solution, gas costs will be increased again in the future, and contracts should be robust enough to handle these changes.
Issues in other projects
Istanbul will cause issues in multiple contracts across a number of projects. If you want to learn more about these, Hubert Ritzdorf, CTO at ChainSecurity, put together an awesome list of affected contracts that will in some way or another stop working properly once the hardfork occurs.