Istanbul Gas Reprice Breaks Contract Interactions

By Chris Whinfrey and Shane Fontaine

Description

The proposed change in the Istanbul hardfork (EIP 1884) to raise the price of SLOAD from 200 gas to 800 gas will result in broken contract interactions across a broad set of contracts. In Solidity, it is considered a best practice to transfer ether using the send and transfer functions which include a gas stipend of 2,300 gas to be used by the receiving contract in its fallback function. Any contract that executes at least one SLOAD in its fallback function may break by going over the 2,300 gas limit with the new SLOAD pricing. This implies that after the Istanbul hardfork, affected contracts will no longer be able to receive ether from other contracts that use send and transfer . In cases where ether can only be withdrawn by the affected contract, that ether will be locked indefinitely. Furthermore, future contract designs now have more limitations when attempting to operate within the 2,300 stipend. This limitation is public but many Solidity developers are not yet taking the changes into consideration and contracts that will be broken by this change are still being discovered.

Types of Affected Contracts

Upgradable Contracts

Contracts that use the proxy-delegate pattern for upgradability are particularly susceptible to being affected by this change. These types of contracts always contain a fallback function in the proxy that executes at least one SLOAD to look up the address of the delegate contract (also called the implementation contract). They also use a non-trivial amount of gas executing the delegation logic. For example, a basic proxy implementation, uses 1,073 gas¹ to receive ether today and will use 1,673 gas¹ to receive ether after the Istanbul hard fork when its implementation contract contains no functionality. Emitting a simple event in the fallback function of the implementation contract would put the gas cost over the 2,300 gas limit, preventing it from receiving ether. More complicated proxy contracts such as OpenZeppelin’s AdminUpgradeabilityProxy, which executes two SLOAD s, will go over the 2,300 gas stipend¹ even when the implementation contract’s fallback function does not contain any functionality.

Consequences

The full consequences of this upgrade are unknown and will include failed contract interactions that worked prior to the fork and possibly loss of funds. A user may attempt to use and an affected contract that is on the receiving end of a send or transfer after the fork and may find that their funds are stuck, or that their contract interactions cannot be executed. One such example would be a user with an upgradeable contract-based account who attempts to trade on Uniswap.

The “Vulnerable Contracts” section below outlines some of the contracts that will be affected by this change. Furthermore, the “Additional Comments” section explains that further upgrades to the prices, as suggested in the EIP, will cause breaking changes to even more contracts.

Some Known Affected Contracts

Aragon

The change will break 860 of Aragon’s contracts on the mainnet.

OpenZeppelin Admin Upgradeability Contracts

All deployed instances of the OpenZeppelin Admin Upgradeability contracts that implement a fallback will be broken. The only option would be to not implement a payable fallback function in the logic contract, but this then limits the abilities of the contract and its interactions with other contracts.

Hubert Ritzdorf of ChainSecurity put together a comprehensive list of other affected contracts here.

Additional Comments

Consensys Diligence recently advocated to stop using the transfer() function for exactly this reason.