Docs

How the guard works, and where it stops.

Siren is a Uniswap v4 hook for pools holding ERC-8056 tokenized equities. It reads the announced corporate action, quotes a surcharge against whichever direction is extracting value, and settles it to the LPs. This page is the mechanism in order, followed by the things we would want a reader to distrust.

!

The guard is not live anywhere.

It is proven on an Ethereum mainnet fork against real PoolManager bytecode, 6 of 6 passing, with a mocked ERC-8056 token. Chain 4663 has the equities but no Uniswap v4 deployment, so there is nothing yet to attach to and no keeper set to bond. Both halves are real. They are not real in the same place. This line stays on the page until that stops being true.

The mechanism

Four callbacks.

The pool is never made un-arbable. Making it un-arbable would mean refusing trades, and a pool that refuses trades is a broken pool. The arb is made to pay the LP for the privilege instead.

beforeInitialize

Bind the token's multiplier source

The hook records which leg of the pair is the rebasing one and where its uiMultiplier() lives. A pool whose token does not implement ERC-8056 is rejected here rather than silently unguarded.

beforeSwap

Measure the step and quote

If an announced window is open, the hook reads the multiplier, sizes the discontinuity against the pool's own reserves, and returns a fee override for the extracting direction only. The override is min(step, ceiling) — it tracks the action, not a governance dial.

afterSwap

Settle to the LPs and decrement

The surcharge accrues to the pool, not to an address of ours. The window carries a budget measured in flow; each guarded swap draws it down, so the guard cannot keep charging after the discontinuity has been priced out.

beforeRemoveLiquidity

Refuse to let the window be dodged

Without this, an LP could withdraw mid-window and leave the remaining LPs carrying the action. Withdrawals inside an armed window are gated until the budget expires.

Hook permissions are encoded in the low bits of the hook's address, so deployment requires salt-mining an address whose flags match exactly these four callbacks. That mining is not done: see the limits below.

The keeper bond

A bond on liveness. Not a claim on the surcharge.

The arbitrage revenue already has a better owner: the LPs, through a fee the hook charges directly. Anything that also claimed it would just be taking the same money twice. So the only thing worth collateralising is the one thing the surcharge cannot reach — whether anybody was awake to arm the guard before the multiplier moved.

what it does

Post it to run a keeper

A keeper watches effectiveAt() and arms the guard before the window lands. Miss an announced window and the bond is slashed to the LPs of the pool you left undefended.

floor $56,715 per pool
how the floor is set

It falls out of the simulation

The floor is not a governance parameter. It is the value the pre-action window preserves for LPs on the 4-for-1 split — the difference between the guarded and unguarded LP columns on the proof table. Below that, sleeping through a window pays.

what it is not

No claim on protocol revenue

The surcharge goes to LPs. It does not route to a keeper, to a treasury, or to us, and no version of this design routes it there. A bond is collateral for a job, and the job only has value while tokenized equities on this chain hold TVL — which is Robinhood's decision rather than ours.

Integrate

What reading the chain yourself looks like.

The boards on this site are one Multicall3 round trip against a CORS-open RPC. There is no API of ours to depend on, and you should not need one.

The three legs

Multiplier stateERC-8056, on the token
uiMultiplier()
The announced stepzero until an action is written
newUIMultiplier()
When it landsa public timestamp, ahead of the step
effectiveAt()
Advisory onlynot enforced on-chain, and still trading
oraclePaused()
The feed legChainlink, 8 decimals
latestRoundData()

Where to point it

Chain
4663
RPCserves access-control-allow-origin: *
rpc.mainnet.chain.robinhood.com
Multicall3canonical address
0xcA11…76CA11
Explorer

The registry of token and feed addresses this site scans ships as /data/registry.json. Verify each pair against the explorer before you trust it — the list is ours, so the scan is auditable rather than trustless.

Stated plainly

What this does not fix.

Every one of these is a reason to distrust the pitch. They are here because a defence you cannot audit is a defence you should not use.

01

The surcharge only recovers 45.6% on a split

The 20% fee ceiling is a deliberate safety valve; uncapped, it would brick the pool on a large action. If an action lands unannounced, the guard degrades to partial recovery, and on a 10-for-1 that is about one part in forty-five.

02

Only 23 tokens can actually be checked

More canonical feeds resolve than there are deployed tokens to pair them with. A feed with no token, or a token with no feed, cannot be cross-checked, so the three-leg invariant is unevaluable for it. Those pairs are excluded from the registry rather than shown as passing, and they should not be curve collateral until both legs exist.

03

The ERC-8056 token in the fork test is a mock

No tokenized-equity token exists on Ethereum mainnet, so the fork proves the hook against real v4 semantics with a faithful mock, not against a real Robinhood token. Chain 4663 has the tokens but no v4 deployment. Both halves are real; they are not yet real in the same place.

04

Not audited

It compiles clean, passes its fork tests, and models the economics exactly. That is not an audit, and the hook address still needs salt-mining so its low bits encode the permission flags.

05

A guarded pool is still an equity position

Siren defends against the accounting discontinuity. It does nothing about the underlying going down.

06

The equity-price leg depends on a source we do not control

Two of the three legs come off the chain, read in your browser. The third cannot be: a quote API is another origin, and this site's own content policy forbids the page reaching it. So the server fetches equity prices every ten minutes and serves them, which makes that leg minutes old rather than days — but it is an endpoint with no stability guarantee behind it. When it fails, the last good price is carried forward with its own timestamp and the board states the real age, because a stale price makes the drift column measure its own staleness rather than the feeds. A keyed provider would be the durable version of this.

License

Licensed permissively.

The hook, the simulator and this page are all covered by the MIT license. Copy any of it.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.