Find and prove code that breaks under Ethereum's Glamsterdam gas repricing (EIP-8037, EIP-8038, EIP-2780). Static rules find the call sites; a Foundry test diff and a transaction replay show whether they actually fail, with the exact command and its output.
Glamsterdam went live on Sepolia on 2026-10-06 at 13:53:36 UTC. Mainnet is not scheduled yet.
Every number below was measured, not taken from the EIP tables.
| what | measured | where |
|---|---|---|
| ETH transfer to an address that does not exist yet | uses 204,600 gas | real client, Platåberget devnet (Glamsterdam since genesis) |
| the same transfer sent with a 21,000 gas limit | included and fails (status 0): the sender pays the fee, the recipient gets nothing; it is not rejected at submission | real client, Platåberget devnet |
| ETH transfer to an existing account | 21,000 (unchanged) | Sepolia node, eth_estimateGas |
| zero-value transfer (existing or fresh address) | 15,000 | Sepolia node, eth_estimateGas |
| self-transfer | 12,000 | Sepolia node and Platåberget |
| each additional new storage slot written in a call | 110,026 gas in total | Sepolia node, eth_estimateGas |
| ERC-4337: first use of a nonce key (EntryPoint v0.7 nonce update) vs a reused key | 98,657 more (17,134 more before the fork) | Sepolia node, eth_estimateGas of incrementNonce |
| a 175,000-gas contract deployment that used 141,905 before the fork | estimates at 629,945 now | Sepolia node, eth_estimateGas |
| cold SLOAD / warm SLOAD / cold BALANCE | 2,100 / 100 / 3,000 | Sepolia node opcode trace; same on Foundry 1.8.3 |
| updating an existing storage slot (SSTORE, warm / cold) | 10,100 / 12,100 (was 2,900 / 5,000) | Sepolia node opcode trace |
| Sepolia, same-length windows before vs after the fork | tx failure rate 1.91% to 10.97%; txs that burned their whole gas limit 0.15% to 2.02% | all Sepolia transactions, the first 10.5 hours after the fork against the 10.5 hours before |
What tends to break:
- Fixed gas limits on state-creating transactions: deployments, factory calls, first writes to new storage.
- ETH sends with a fixed 21,000 gas limit to addresses that may not exist yet (faucets, payouts, airdrops).
- ERC-4337 apps that hardcode
verificationGasLimitand open a new nonce key per userOp: in EntryPoint v0.7 the first use of a key writes a new storage slot inside the verification gas window, and the op fails withAA26 over verificationGasLimit. - Hardcoded gas forwarded to calls (
{gas: N}) whose callee writes new storage or deploys. - Fixed gas limits on calls that update existing storage: under EIP-8038 each update of an existing slot costs about 7,200 more (10,100 instead of 2,900 warm), so calls with many writes outgrow limits that fit before (DEX swaps, Bee redistribution, bond claims).
- Token transfers sent with a fixed per-token gas limit: they fail when the recipient has never held the token, because the transfer writes a new balance slot (about 110,000 gas instead of 22,100). Transfers to existing holders still fit, so this only shows up for first-time recipients.
Not seen to break: .transfer()/.send() to receivers that fit inside the 2,300 stipend today. Cold SLOAD did not change, and no such case flipped in our runs. The rule for it is kept for review only.
- anvil's
eth_estimateGason an Amsterdam fork returned 21,000 for a transfer to a new account (which needs 204,600). Reported in foundry-rs/foundry#17428 and fixed within a day in foundry-rs/foundry#17432 (merged Oct 7): anvil now estimates transfers by executing them. Until your Foundry build includes the fix, check estimates against a real Glamsterdam node, or measure by submitting. cast runbefore Foundry 1.8.5 replays post-fork Sepolia transactions under the previous rules unless you pass--evm-version amsterdam. Fixed in 1.8.5.- For a transaction that already failed on a Glamsterdam chain, the node's own
debug_traceTransactionis the source of truth for where it ran out of gas.
- Foundry 1.8.5 or later (
forge test --hardfork amsterdam,cast run --evm-version amsterdam). SetFOUNDRY_BINif forge is not on PATH. - semgrep Community Edition (the Solidity rules are tested with 1.177.0, the version the GitHub Action pins).
- Node 20 or later, then
npm install.
-
Static scan (Solidity, TypeScript/JavaScript, Python, Go):
npx tsx src/rules/semgrep.ts /path/to/your/repoHits are candidates. Confirm them with step 2 or 3 before acting.
-
Foundry suite under Amsterdam execution rules (only the runtime changes; the compile target does not):
npx tsx src/runner/diff.ts /path/to/your/foundry/projectLists tests that pass today and fail under Amsterdam, and traces each one to the call that ran out of gas. Runs with
FOUNDRY_FFI=false. -
Replay a mined pre-fork transaction under Amsterdam rules and measure the gas it would need:
SEPOLIA_RPC=https://your-sepolia-rpc npx tsx src/replay/replay.ts 0x<txhash>Writes the commands and output to
glamcheck-out/. -
Settle the new-account question on a devnet yourself (sends three tiny transactions from a throwaway testnet keystore account; dry run by default):
bash scripts/probe-new-account.sh # dry run bash scripts/probe-new-account.sh --send --account <keystore account>
Scanning or building someone else's repository runs their code: do it in a sandbox or VM, never on a machine with real keys.
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with:
submodules: recursive
- uses: PyraVim/glamcheck@v0.1.1
with:
fail-on: flipsWhat it does:
- Runs the static rules on
pathand adds a warning annotation on each hit. - If
pathhas afoundry.toml(orfoundry-diff: true), runs your suite under today's rules and under Amsterdam execution rules (forge test --hardfork amsterdam), withFOUNDRY_FFI=false, and adds an error annotation for each test that flips. - Writes a job summary,
glamcheck-results.json, and optionally SARIF for GitHub code scanning.
| input | default | meaning |
|---|---|---|
path |
. |
directory to check |
foundry-diff |
auto |
auto runs the diff when foundry.toml exists; true or false to force |
forge-args |
extra forge test arguments |
|
fail-on |
flips |
flips, hits (any static hit or flip) or none |
sarif-file |
write SARIF here (upload with github/codeql-action/upload-sarif) |
|
foundry-version |
v1.8.5 |
needs 1.8.5 or later |
semgrep-version |
1.177.0 |
Outputs: hits, flips, results-file. A full example workflow, with the SARIF upload, is in docs/example-workflow.yml.
Static hits are candidates, not proof; the default fail-on: flips only fails the job on a measured flip. The Foundry diff runs your own tests in your own CI, with FFI off. Every third-party action this one uses is pinned to a commit.
| rule | pattern | EIP |
|---|---|---|
glamcheck.fixed-tx-gas-limit (Go, TS/JS, Python) |
fixed gas limit on a transaction or network config | EIP-8037 |
glamcheck.eth-send-21000 (Go, TS/JS, Python) |
exactly 21,000 gas for an ETH send | EIP-8037 / EIP-2780 |
glamcheck.solidity-call-gas |
hardcoded {gas: N} forwarded to a call |
EIP-8037 / EIP-8038 |
glamcheck.gasleft-logic |
logic built on gasleft() |
EIP-8037 |
glamcheck.one-dim-gas-constant |
round gas constants in fee or verification models | EIP-8037 |
glamcheck.solidity-transfer-send |
.transfer() / .send() (review only) |
EIP-8038 |
Each rule has positive and negative fixtures in fixtures/rules/. npm test runs the rule tests and the Foundry diff tests.
Status checked on 2026-10-26. These are issue and upstream merge statuses; they do not establish that every fix is in a published release or deployed by operators.
| Report | Status | Upstream update |
|---|---|---|
| Foundry #17428: anvil gas estimates for transfers to new accounts | Fixed; closed Oct 7 | #17432 merged Oct 7; transfers are executed during estimation so new-account state gas is included. |
| Bee #5650: fixed 175,000 chequebook deployment gas | Open; assigned | Assigned to sbackend123; no comments or fix confirmation on the issue as of the check date. |
PoWFaucet #540: example config ethTxGasLimit: 21000 |
Fixed; closed Oct 17 | Config updates merged in #541 on Oct 12. The maintainer confirmed the Sepolia instance was also fixed. |
| Bee #5652: redistribution commit/reveal 500,000 gas floor | Closed Oct 10; maintainer reports fixed | The maintainer confirmed the fix was merged to master. |
OP Succinct #1016: fixed 200,000 gas for claimCredit |
Fixed; closed Oct 14 | Gas estimation fixes merged Oct 14 into main (#1018) and release/v3.x (#1019). |
Related discussion: wevm/viem #5198, the default nonce key opens a new EntryPoint nonce slot on every userOp.
Need your code checked before mainnet? I do fixed-price Glamsterdam readiness checks: I find what breaks in your contracts, scripts and gas settings, measure it on a real node, and send the fix with tests.
- Email: pyravim.dev@gmail.com
MIT, see LICENSE.