Everything on chain is visible. Yours isn’t.

Umbra is a dark pool for Uniswap v4. Orders arrive sealed, open together, and cross against each other before anything reaches the curve. Everyone on the same side of a batch fills at the same price.

01 · The gap

Your size. Your direction.
Your stop.

Every order you send on chain is public before it is filled. It sits in the mempool wearing everything it knows about you, and the distance between broadcast and inclusion is where the trade is taken apart. This has been treated as a law of nature. It is a design choice, and it can be made differently.

What leaks

The order, not the trade

A swap is only dangerous to you before it settles. Once filled, the information is worthless. Umbra keeps the order sealed for exactly the window where it matters.

Who profits

Whoever reads first

Sandwiching, front-running and back-running are all the same trade: act on an order you were shown for free. Take the reading away and the trade has no edge left.

The cost

Paid on every fill

It does not arrive as a fee. It arrives as a worse price than the one you saw, on the trades that were worth taking, which is exactly when it hurts.

02 · The batch

Three acts, thirteen minutes.

A batch is a commitment scheme with a settlement at the end of it. Nothing about your order exists on chain until the window where reading it can no longer help anyone.

SEALED ORDERS ARRIVERESIDUE → CURVECOMMIT · 10 MINOPEN · 3 MIN · POOL IS DARKSETTLECLAIM
Commit, open, settle. The pool is closed to everyone but the batch for the three minutes in the middle.
Act one · commit

A hash and a bond

You send keccak256 of your order and a bond that is the same for everybody. No amount, no direction, no funds move. On chain, one commit is indistinguishable from another.

Act two · open

Everyone at once

The window shuts and the pool goes dark. Inside the dark each trader hands over the preimage. A hash that does not match is not an order, and a commit that never opens loses its bond.

Act three · settle

Cross, then residue

Buys and sells are crossed against each other at the pool mid. Only what has no counterparty is sent to the curve, as one swap, with a hard bound on how far it may move the price.

03 · One price per side

A batch has no order of arrival.

Inside a batch there is no first and no last, so there is nothing to pay for position. Every buyer fills at the same price and every seller fills at the same price. Being faster buys you nothing, which is the point.

THE BATCHv4 POOLBUYSSELLSCROSSED INSIDE THE BATCH · NEVER TOUCHES THE CURVETHE ONLY PART THE MARKET SEES
Four buys against two sells. Two pairs settle between themselves and never reach the pool; the two unmatched buys are the only thing the market gets to see.
From the fork testsResult
Two buyers, 1 ETH and 3 ETH, same batchBoth filled at 5367359687735004061440118 UMBRA per ETH, identical to the last digit
A batch where buys and sells cancelPool price moved by 4.0e-10 of itself, which is rounding dust and nothing else
A public swap during the open windowReverted, PoolIsDark()
A revealed order that grew after being sealedReverted, BadPreimage()
04 · The dark

The pool closes while the orders open.

A commitment scheme alone would still leak: preimages are public, and a searcher who watches them open could trade ahead of the settlement. So the hook shuts the door. While a batch is opening, every swap that is not that batch reverts. Nothing can be placed in front of orders it was never allowed to read.

It reopens by itself. If a batch is never settled, a grace period expires and the pool goes back to being an ordinary pool, so a stuck batch can never hold the market shut.

// UmbraHook.beforeSwap
if (sender == address(dark)) return NO_TOLL;      // the batch settles free
if (dark.isDark()) revert PoolIsDark();     // everyone else waits
05 · What this is not

Umbra hides the order, not the wallet.

This is a dark pool, not a mixer and not a privacy chain. Deposits and withdrawals are ordinary transfers and anyone can read them. What Umbra removes is the window in which your intent is public and unfilled: the size, the side and the timing of a trade that has not happened yet. Your balance is visible. Your order is not.

Hidden

Side, size, timing

Until the batch opens, and by then it is being settled. Fills come out as one aggregate, so a single trade has no shape of its own on the curve.

Visible

Deposits and withdrawals

Balances live in the contract and move in the open. Deposit early and unrelated to any order, which costs you nothing and tells watchers nothing.

Deliberate

No limit price per order

Excluding an order that misses its limit means sorting the book, and sorting is a loop. Instead the whole batch is bounded: the residue may not move the price past a fixed cap, and what the cap will not take comes back to you.

06 · Status

Live on Ethereum.

Deployed

Four contracts, verified

Token, hook, LP manager and dark pool are on Ethereum mainnet and verified on Etherscan. The hook is wired to the dark pool and frozen there. Addresses are in the docs.

Open

The ETH/UMBRA pool

Initialised with the hook in its key and seeded single-side, so the whole supply went in and no ETH did. Batches settle into this pool and nowhere else.

Careful

No sale, no allocation

There was no presale and there is no allocation to claim. The only way in is the pool, and 20 of 20 tests are green against the live contracts on a fork.

Read the documentation