EIP-8037: State Creation Gas Cost Increase

Hello. We’ve been looking at how EIP-8037 interacts with a common try/catch pattern in production contracts, and want to flag a concern.

contract Outer {
    Inner public inner;
    uint256 public flag;

    constructor(Inner i) { inner = i; }

    function enter() external {
        try inner.run() {} catch {
            flag = 1;
        }
    }
}

contract Inner {
    uint256 constant MIN_GAS = 20_000;

    function run() external view {
        if (gasleft() < MIN_GAS) revert();
    }
}

contract Attacker {
    function strike(Outer o, uint256 innerGas) external {
        o.enter{gas: innerGas}();
    }
}

The pattern: a contract calls a child via try/catch and, on revert, performs state changes.
The catch path cannot distinguish a legitimate revert from an out-of-gas revert.
Today, forcing the catch via OOG also depletes the regular gas that the catch’s SSTOREs need, so the whole tx OOGs and the state change does not persist.

Under EIP-8037 the regular-gas portion of a new-slot SSTORE drops from ~22,100 to ~5,000, with the remainder (64 * CPSB = 97,920 at the current 1,530 CPSB) drawn from the state-gas reservoir filled by overprovisioning gas_limit. Two consequences:

  1. The window for gas-sniping the inner call gets wider. An attacker can land innerGas just below an inner gas-check threshold. The child reverts, and the Outer still has a regular-gas budget for the catch path’s SSTOREs.
  2. Catch paths that previously did not fit within a tx (multi-SSTORE shutdown / liquidation / freeze state changes) now do, because most of their cost is paid from the reservoir rather than the inner-call gas budget.

We have a minimal reproducer that runs the same try/catch + gas-sniped child under PRAGUE and AMSTERDAM+EIP8037 settings.
Let us know if you have done a contract search for this potential issue.

2 Likes