The original case study concerned a 2020 Balancer incident involving a token with transfer fees and incompatible reserve-accounting assumptions. The defensive lesson is to understand supported token behavior and test actual balance changes where the protocol relies on them. The dollar totals and screenshots below are historical context.

Balancer Hack on Etherscan

Now you can see this was a single transaction which resulted in roughly $500K being lost.

Many tokens were transferred in a single transaction. But was there any way to prevent this?

Morpheus Hack Meme

Monitoring and simulation can sometimes create an opportunity to respond, but they do not prove that this incident would have been stopped.

It's still very dark inside the mempool

You may remember the great blogpost about mempool manipulation on Black Thursday of Blocknative. If not, bookmark this now and read it. This issue is still very relevant. In fact one of the exploits used is still an open issue on Github and largely ignored. Since then we've heard many more stories about the mempool, sometimes nicknamed dark forest and how to escape it.

Illuminating this place is not easy. You can run a node like Geth and observe your local mempool. You can also see the mempool source code of Geth here. It gives you some ideas on the behavior. Or you could even create your own node and transaction discovery service with something like ethereumjs-devp2p. But you can already see that this is not only very difficult to do, requiring a lot of computing resources and time, but it's also incredibly difficult to do well.

A mempool is only existing of transactions that the nodes you connected to have seen and told you about. To get a full picture of the whole network's mempool therefore requires being connected to as many nodes as possible. The more nodes we are connected to, the earlier we will be notified of new mempool transactions. Now this is where Mempool Explorer from Blocknative comes to help.

There is no single complete public mempool. Nodes have different views, and private order flow may never reach a public listener. More peer connections do not guarantee the earliest or complete view.

Mempool Explorer

The service of Blocknative goes beyond this:

  • You could actually use the backend API behind this directly.
  • Use the notify frontend lib to greatly improve your DAPP's user experience.
  • Or simulate pending transactions. This is what we need for our hack preventation.

Entering the Matrix

No Neo Bitcoin Meme

Now how does the simulation feature work?

The simulations build upon the mempool service. In general dealing with internal transactions is difficult. Recall our Balancer hack transaction. In the advanced internal transactions tab, you can see the full monstrosity of transactions here. Now imagine you want to keep track of any calls to your smart contract off-chain. This is extremely difficult as you'd also have to find all internal transactions which you can only get by simulating the whole transaction.

Simulations by Blocknative basically take any pending transaction and run it in its their local EVM. They are run using the last known state of the blockchain (state trie). Since the state can change before the transaction is actually added to a block, the simulation is not always 100% accurate, so keep that in mind.

Also note that simulations currently only work for Ethereum mainnet.

The so-called internal transactions are message calls within a transaction, not separate signed transactions. A trace reflects a chosen state and execution context. Blocknative’s old service availability and mainnet-only description are historical: its official notice set June 19, 2026 as the end of API service.

Uniswap Example

The screenshots record the original Blocknative Uniswap simulation demo. Its account/query walkthrough is historical; the API service has been sunset.

You can see an example result on the right. You can click the hash and it will direct you to Etherscan. Since this is a pending transaction, you might have to wait a few minutes for the transaction to be confirmed.

Once finished, you can see the actual token transferred by this Uniswap trade:

Etherscan Simulation Result

It likely won't match the Blocknative balanceChanges perfectly due to the constantly changing states in a Uniswap pool. You can see here instead of 10174 TRU tokens paid to the trader, it actually sent 10346 TRU. Close enough!

Uniswap Simulation Example

Simulations are challenging

The simulations are particularly useful for traders and protocols. They reveal all internal calls and its effects on the state. However, with the current node client implementations, this process can take substantially longer than the actual EVM execution. This time can often be the difference between doing a trade in time or preventing a hack.

To take it from Blocknative directly, the challenges for simulations include:

  1. Ensuring your node remains properly synced at the time of simulation.
  2. Capturing all pending transactions propagating through the mempool. Individual nodes frequently miss pending transactions, particularly during periods of network congestion.
  3. Detecting new pending transactions as rapidly as possible.
  4. Knowing which transactions are likely to be included in the next block – and thus are candidates to be simulated against the current block state.
  5. Performing the simulation quickly to maximize the time the simulation results are actionable.
  6. Interpreting the simulation to see how address balances are shifting.

Getting notified about the hack

The original subscription screenshots illustrate how a monitoring rule was configured. The Blocknative endpoint is retired, and a large balance movement alone does not establish malicious behavior.

Balancer STA Pool

A monitoring design needs clear alert conditions, coverage assumptions and a reviewed response process. The original webhook setup is historical, and an alert may arrive too late or be a false positive.

Simulations Export

Of course creating these subscriptions can all be automated using the API. The 'Export Configuration' function can help you with the setup for this.

Designing an emergency response

An emergency pause can limit damage only if the relevant functions are designed to honor it and an authorized response reaches the chain in time. OpenZeppelin’s Pausable supplies state and modifiers; it does not choose the authorization or decide which operations are safe.

A protocol must define the pause authority, the monitored conditions, review of false positives and a recovery process. A limited guardian or other narrowly scoped role may suit some designs. Neither a single private key nor a particular governance process is universally required.

Withdrawals are not automatically safe during an incident. Decide whether they depend on the affected accounting or external systems, and test the paused state. Likewise, a timer should not automatically re-enable a still-broken operation merely because a fixed period elapsed. Monitoring supplements prevention and review; it cannot guarantee that every harmful transaction will be seen or stopped.