The fee, the hook, what gets refused,
and how to read all of it yourself.

A reference, not a pitch. Every number below is a dollar amount or a block count, and every sentence describes a behaviour you can check against the contract.

POST /swap

What the endpoint answers, in the three ways you can ask it.

one error, both numbers
$ cast send $HOOK "swap(bytes32,uint256)" \
  $(cast --format-bytes32-string "404") \
  4000 \
  --value 0

            

One price. Both directions. No table.

$3 for every $1,000 traded. Buys and sells pay the same amount at the same moment, because direction is not one of the inputs. The mechanism here is the refusal, not the price: once you start pricing the refusal too, the limit is not a limit.

Swap costs

BuySell
Any swap that fits the block$3 / $1,000 traded
A $10,000 swap$30
A refused swap$0
Exit penaltynone
Tier, ladder, discountnone

Liquidity providers

$8 of every $10

To the people who put up the liquidity in that pool. That is where a swap fee normally goes, and this does not change it.

Read the hook

The $404 pool

$2 of every $10

Into the $404 pool, as liquidity, and it stays there. There is no function that removes it.

Read the log

Nobody else

$0

No treasury, no team allocation, no revenue share, no staking, no claim, and no address that can withdraw.

Read open

Two things that only happen at the moment of a swap.

The size is checked before anything is filled, and the budget is spent and refilled with the block. A hook is called with the requested amount in hand, before the pool moves, and it is the only place that can say no in time.

One error, and it carries both numbers.

The revert names what you asked and what was there, so your wallet, your bot, and any simulator can read them and cap your input before you ever sign.

openapi: 3.0.0
info:
  title: 404
paths:
  /swap:
  /available:
  /budget:
  /refusals:
-> cast call available
$5,000

-> cast send swap 8200
NotFound(8200, 5000)

Nothing between filled and refused.

A swap is filled completely or not at all. There is no partial fill, no path where the hook takes something and gives you less, and no state in which the pool stops working.

All or nothingNo partial fill
No 500The pool never fails
No ownerNo pause, no proxy, no admin

Six constants, fixed at deployment.

The whole configuration of the protocol fits in a table you read at a glance, and no address can change a line of it afterwards.

Budget1% per block
Fee$3 per $1,000
Split8 / 2

You will be refused when it matters most.

This is the part that does not work. Read it before you trade.

A crash is when depth disappears and when everybody wants out at once. Both of those shrink the envelope: one percent of a smaller pool is a smaller number, and the block is crowded.

So the refusals cluster exactly where you least want them. A large position that would have exited in one transaction elsewhere will take several blocks here, and in a fast fall, several blocks is expensive.

The other half of that sentence is also true, and we are putting it directly underneath rather than somewhere quieter: the single fill you did not get would have cost you far more than the blocks you waited, because it would have walked the whole book. Both are real, and which one costs you more depends on how fast the price is moving, which we cannot know in advance and neither can you.

What we can promise is narrow and we will not dress it up: you are never locked in.
The envelope is full again in twelve seconds, every time, with no condition attached.

OPEN

Everything the site shows comes from these. No database, no indexer, no key.

read only
available(bytes32 pool) → uint256 what is left to serve in this block budget(bytes32 pool) → uint256 one percent of what the pool holds refusals(bytes32 pool, uint256 from, uint256 count) → Refusal[] the log, paginated. call it with count = 100 and walk error NotFound(uint256 requested, uint256 available) the whole failure surface. there is no other error
hook0x0000…0000
eventRefused(bytes32 pool, uint256 requested, uint256 available)