Crypto Training

Gas Griefing and Untrusted Reverts: Liveness Is a Security Property

Most protocol failures aren’t about stealing funds. They’re about stopping progress. This is the gas-side of that story.

Crypto Training2026-02-032 min read

A lot of audits over-focus on “can funds be stolen?”

The uncomfortable truth: many mainnet failures look like this instead:

users can’t withdraw keepers can’t settle liquidations don’t happen queues jam

No one needed a clever exploit. Someone just made progress too expensive or too fragile.

A minimal model: who can veto progress?#

Pick your protocol’s liveness-critical functions. Usually it’s one of:

  • withdraw()
  • settle()
  • liquidate()
  • finalize()

Now list everything they call that isn’t purely internal. Each of those is a potential veto.

Here’s a useful table for reviews:

External interactionHow it failsTypical impact
token transferrevert / hook / gas burnwithdrawals jam
ETH sendrevert fallbackclaims jam
oracle readrevert / staleliquidations freeze
callback hookrevert / reenteraccounting breaks or halts

One concrete footgun: “push ETH or revert”#

SOLIDITY
(bool ok,) = payable(user).call{value: amount}("");
require(ok, "send failed");

If user is a contract that reverts, your function reverts.

If withdraw() requires this send, users can be griefed.

A safer pattern is pull:

  • record what’s owed
  • let the user withdraw separately

Gas griefing as an economic attack#

Gas griefing is when the attacker turns your protocol into a slot machine:

  • they can cause honest actors to waste gas repeatedly
  • the honest actors stop trying
  • liveness becomes optional

It’s not glamorous. It’s effective.

Design rule#

If a function must be live, it must have a bounded-work path.

That often means:

  • chunked processing
  • escape hatches
  • optional hooks
  • “best effort” calls with safe accounting

If you can’t bound the work, you can’t guarantee liveness.

Further reading#