DEV Community

Cover image for Ethereum's next upgrade can break your contracts
Carlos (Bloqarl)
Carlos (Bloqarl)

Posted on Originally published at defiprotocolbycode.substack.com AI-assisted

Ethereum's next upgrade can break your contracts

If you have a transfer(), a call{gas: 50000} or an if (gasleft() < X) somewhere in a contract on mainnet, this one is for you.

On October 6, Ethereum's next upgrade, Glamsterdam, went live on the Sepolia testnet. Most of the coverage is about throughput and block building. The part that matters for deployed contracts is quieter: Glamsterdam reprices state.

  • Creating a new account goes from 25,000 gas to 183,600.
  • A new storage slot goes from 20,000 to 97,920.
  • Every byte of deployed code goes from 200 to 1,530.
  • Changing an existing storage slot goes from 2,900 to 10,100.

The Ethereum Foundation replayed historical mainnet transactions under the new numbers. Most contracts are fine. A small set "may lead to these contracts breaking or degrading without preventative updates." The testnet announcement says it plainly: "Contracts that rely on fixed gas stipends, hardcoded gas limits, or assumptions about remaining gas may need changes." Mainnet has no date yet, and the target is this quarter.

My read

Hard forks rarely break your code. This one can, but only where you wrote down a number. Every transfer(), every hardcoded gas value, every branch on gasleft() is an assumption about what the EVM charges. If your contracts were audited, the audit checked that assumption against today's gas schedule, not the next one. Every hard fork is an audit decay event for someone.

This has happened before. In 2019, Istanbul raised the cost of reading storage from 200 to 800 gas, and the EIP itself warned that fallback functions reading storage "may in some cases require more than" the 2,300 gas a transfer() forwards. That's when the industry started telling developers to stop using transfer(). The difference now is months of warning, a public testnet, and a tool that tells you if your contract is on the list. I don't think this is a reason to panic. But "most contracts are fine" is not a property of your contracts. You have to check.

Where the new numbers bite

  • Hardcoded gas in calls. transfer(), send() and call{gas: N}. The 2,300 stipend stays the same, but what fits inside it changes, because touching state now costs more.
  • Logic that branches on gasleft(). Keepers, relayers, meta-transaction forwarders, batch loops that stop at a gas threshold. EIP-8037 even notes that metering by subtracting two gas readings can now go negative.
  • Anything that creates accounts or contracts. Factories, a clone per user, smart accounts deployed on first use. Account creation and code deposit both get several times more expensive, so re-check your gas budgets and your fee math.
  • Fixed gas limits off-chain. Presigned transactions, bots and frontends that send a hardcoded limit. A plain ETH transfer to an existing account still costs 21,000, but a transfer to a fresh address no longer does.
  • Indexers. Every ETH transfer will emit a log with the same topic as an ERC-20 Transfer, from a system address. If your backend listens for that topic without checking the emitter, check what it does with them.

There's good news too: the contract size limit goes from 24 KiB to 64 KiB, so fewer teams will need to split code across libraries just to deploy.

If one of your contracts is flagged and it's immutable, the fix is a migration, not a patch. If it's behind a proxy, the fix is an upgrade, and upgrades have their own ways to go wrong, so treat that upgrade like any other change that needs review.

If you have contracts on mainnet, before the fork date is set

Three things I'd do this month:

  1. Paste your addresses into the Ethereum Foundation's repricing impact dashboard. It's free. It replays real mainnet transactions under the new schedule and tells you if yours still work, need a higher gas limit, or might be broken.
  2. Grep for written-down gas. Search your contracts for .transfer(, .send(, gas: and gasleft(), then do the same in your frontend, bots and deploy scripts for hardcoded gas limits. Every hit is a question to answer.
  3. Run your critical flows on Sepolia. Deposits, withdrawals, liquidations, anything a keeper triggers. A fix costs a conversation now. After the fork it costs an incident.

If you're deploying new contracts before the fork, the simplest rule is not to write gas down at all. Send ETH with a plain call behind a reentrancy guard, check the return value, and let your frontend estimate gas against the network it's actually talking to instead of shipping a constant.

One more date: the repricing EIPs are in Last Call until Sunday, November 1. If the dashboard shows your contracts breaking, now is the time to say it in the EIP-8037 and EIP-8038 threads on Ethereum Magicians, not after mainnet.

Have you run your contracts through the dashboard yet? Curious if anyone found something flagged.

Sources: EF testnet announcement, EF repricing testing post, EIP-8037, EIP-8038, EIP-7954, EIP-7708, EIP-1884.


Originally published in my newsletter, DeFi Protocol by code.

I wrote this with help from AI for drafting and editing. The opinions and the audit experience are mine.

Top comments (0)