zkFLO Open app →
Contents

zkFLO docs

How to use the pool, what happens every hour, what the proof does and doesn't tell you, and what can go wrong.

Last updated 14 October 2026 · Describes the v1 design

What zkFLO is

zkFLO is an ETH/USDG pool on Uniswap V4, on Robinhood Chain. You deposit ETH and USDG into a vault, and the vault is the only liquidity provider in the pool, so the swap fees traders pay go to the vault's depositors.

Once an hour, a private model sets two things for the pool: the swap fee, and the price range where the vault's liquidity sits. Every new setting comes with a zero-knowledge proof. The vault checks that proof onchain before it changes anything.

The proof shows that the setting came from the model we committed to, that the model read the pool's own recorded prices and nothing else, and that the result is inside fixed limits. It doesn't show that the model made a good call. The weights stay private, and the proof is what lets you check the model's work without seeing them.

Where things stand

zkFLO isn't live. No contracts are deployed and the vault isn't taking deposits. The app runs on a preview: a made-up pool, made-up prices and a wallet with play money. Nothing you do there touches a real chain.

The guides below describe how things will work once the contracts are live, and point out where the preview behaves differently. The numbers on this page are the values we're starting with. Some of them, such as the length of an epoch, depend on how long a proof takes to make, and we'll confirm them after the proving benchmark. See the roadmap.

Terms

These words mean something specific on this page and in the app.

TermMeaning
EpochOne hour. Each epoch runs on one setting.
SettingThe fee and the liquidity range for one epoch.
ModelThe private machine-learning model that picks each setting.
Model IDA hash of the model's weights. It's public, so anyone can tell if the model changes.
SampleThe 360 prices the pool records during an epoch, one per 10 seconds.
SealingHashing an epoch's sample into one value, sampleRoot, and storing it onchain. After that nobody can change the prices the model reads.
ProverThe operator who runs the model, makes the proofs and submits them. The Prover puts up a bond.
BondUSDG the Prover locks up. Part of it is paid to depositors each time a proof is missed.
Settlement windowThe 5 minutes after an epoch ends, during which its proof has to arrive.
ReceiptAn onchain record the vault writes each time it applies a verified setting.
Fallback modeWhat the pool does without a proof: a flat 0.30% fee, with liquidity spread across the full price range.
ShareAn ERC-20 token you get for depositing. It stands for your part of everything the vault holds.

Guides

Deposit

You deposit ETH and USDG together, in the same proportion the vault already holds them. You type the ETH amount, and the app works out how much USDG goes with it.

  1. Open the Vault page in the app and connect your wallet. Make sure it's on Robinhood Chain.
  2. Enter how much ETH you want to deposit. The app shows the USDG that goes with it and the shares you'll get.
  3. Approve USDG when your wallet asks. This lets the vault take the USDG for this deposit.
  4. Confirm the deposit in your wallet. Your shares show up on the Vault page once the transaction is in.

Deposits are capped while the list of Receipts is short. If your deposit goes over the room left under the cap, the app tells you how much room there is. We raise the cap in stages as the Receipt history grows.

In the preview, choose Use a preview wallet instead of connecting your own. It comes with play ETH and USDG.

Withdraw

You can withdraw at any time. Nobody can pause withdrawals, including us, the Guardian and governance.

  1. On the Vault page, enter how many shares you want to redeem.
  2. Check the ETH and USDG you'll get back. You receive both, in the proportion the vault holds when you withdraw.
  3. Confirm in your wallet.

What you get back is your share of the vault's liquidity position plus your share of anything it's holding to the side. That proportion changes as the price moves, so you may get back more ETH and less USDG than you put in, or the other way round.

The withdrawal transaction includes a minimum ETH and a minimum USDG. If the pool's price moves before your transaction lands and you'd get less than that, the transaction fails and nothing leaves the vault.

Check a Receipt yourself

You don't have to take the app's word that a setting was proven. For any Receipt, the app can run four checks, and your browser sends each question straight to the chain without going through our servers.

  1. Open the Receipts page and pick an epoch.
  2. Choose Run the four checks.
  3. Read the result of each check:
    • The Receipt is in the vault's log. The record exists onchain and was written by the vault.
    • The prices are the ones the hook sealed. The sampleRoot in the Receipt matches the one sealed for that epoch.
    • The model is a registered one. The Model ID in the Receipt is one the model registry knows.
    • The verifier accepts the proof. Your browser hands the proof and its public inputs to the verifier contract and gets back a yes or a no.

If all four pass, that setting came from the registered model, ran on the sealed prices, and passed the same verification the vault did.

In the preview, the answers are simulated, because there's no chain to ask.

Trade against the pool

You swap with zkFLO the same way as with any Uniswap V4 pool. The fee you pay is the one set for the current epoch, which is one of 0.05%, 0.10%, 0.30%, 0.60% or 1.00%, or 0.30% while the pool is in Fallback mode. The Pool page shows the fee in force right now.

The fee changes when a new setting is applied, which happens within 5 minutes of each epoch ending. We're still checking which swap aggregators on Robinhood Chain route through pools with hooks, so until we've confirmed that, a router might not find this pool.

Concepts

One epoch, start to finish

Every epoch goes through the same steps. Times are measured from the start of the epoch.

WhenWhat happensWho does it
0 to 60 minTraders swap at the current fee. The pool records one price for each 10-second slot: the price just before the first swap in that slot. A slot with no swaps takes the last recorded price. That makes 360 prices.The pool's hook, on every swap
60 minThe epoch ends. The 360 prices are hashed into sampleRoot and stored onchain.Anyone can send this transaction
60 to 65 minThe Prover runs the model on the sealed prices and submits the new setting with a proof. The previous setting stays in force meanwhile.Prover
On submissionThe vault checks that the proof's sampleRoot is the one sealed for that epoch, that the Model ID is the active one, that the proof verifies and that the setting is inside the limits. If all of that holds, it changes the fee, moves its liquidity into the new range without swapping, and writes a Receipt.The vault, onchain
65 min, no valid proofThe pool goes into Fallback mode and part of the Prover's bond goes to depositors.Automatic for the fee; anyone can send the transaction that moves the liquidity

The model's range is centred on the epoch's time-weighted average price and is set by two outputs: a fee level and a width. The new setting applies to the next epoch.

You can watch this happen in the app's preview, which can run an hour in 24 seconds and hold back a proof so you can see Fallback mode.

What the proof covers

Each proof makes one statement about values that are public and values that stay private. In short:

public epoch, sampleRoot, modelId, fee, tickLower, tickUpper, prevCenterTick
private the 360 prices, the model's weights

Hash(prices) = sampleRoot
Hash(weights) = modelId
Model(weights, prices) = fee, tickLower, tickUpper
fee and range are inside the limits

What you can rely on

  • The setting came from the model whose weights hash to the public Model ID. Swapping the model would change the Model ID, and every Receipt shows it.
  • The model read the 360 prices the pool recorded and sealed for that epoch, and no other data.
  • The fee is one of the five allowed levels, and the range is inside the width and movement limits. The vault checks those limits again before moving anything.

What it can't tell you

  • Whether the model is any good. A proven setting can still lose money, for example when the price moves out of the range.
  • Whether the Prover acted on the setting first. The Prover knows each new setting before the chain does. A short settlement window, a cap on how far the range can move and no swaps during a rebalance all narrow that advantage. They don't remove it.
  • What the model is. The weights stay private by design.

Fallback mode

Fallback mode is what the pool does when nobody has proven a setting. It's a fixed 0.30% fee with the vault's liquidity spread across the full price range. Liquidity spread over every price earns less in fees than a tight range would, but the price can never move out of it.

When it starts

  • The 5-minute settlement window ends without a valid proof. The fee switches to 0.30% straight away. Moving the liquidity to the full range takes one transaction, which anyone can send, and the sender gets a small tip from the Prover's bond.
  • The Guardian puts the pool into Fallback mode, for example if something looks wrong.

What it costs the Prover

Each missed epoch takes a fixed amount of USDG from the Prover's bond and adds it to the vault, which raises the value of every share. The amount isn't set yet. It has to be large enough that missing on purpose never pays. After three missed epochs in a row the model is suspended, and only governance can bring it back.

When it ends

With the next valid proof. The vault applies that setting as normal and writes a Receipt.

Where the fees go

WhoShare of swap feesNotes
Depositors90%Added to the vault, so the value of each share goes up
Model author10%Out of this, the author pays for making the proofs and for the gas to verify them
Protocol0%Governance can raise it to at most 5%, through a timelock

There's no zkFLO token.

Reference

Limits on the model

The first three limits are part of the proof, so a setting outside them can't be proven, and the vault checks them again before applying a setting. The rest are rules in the vault contract. These are the v1 starting values.

LimitValue
FeeOne of 0.05%, 0.10%, 0.30%, 0.60%, 1.00%
500, 1000, 3000, 6000, 10000 in the contracts, in hundredths of a basis point
Range widthFrom ±2% to ±40% around the epoch's time-weighted average price
Range movementThe centre moves by at most one range width from the previous epoch's centre
Swaps when rebalancingNone. Tokens that don't fit the new range stay in the vault, unused, until a later range takes them
WithdrawalsAlways open
DepositsCapped, with the cap raised in stages

Timing

Valuev1 setting
Epoch length1 hour
Price slot10 seconds, so 360 prices per epoch
Settlement window5 minutes after the epoch ends
Fallback fee0.30%, full range
SuspensionAfter 3 missed epochs in a row

Who can do what

RoleCanCan't
ProverSubmit settings with proofsMove funds, change the model, or skip an epoch without losing bond
GuardianPut the pool into Fallback modeMove funds, change the model, or stop withdrawals
GovernanceRegister a new model, bring back a suspended one, set the protocol fee up to 5%. All through a timelockTouch deposits
AnyoneSeal an epoch's prices, and send the transaction that moves liquidity into Fallback modeAdd liquidity to the pool directly. Only the vault can

Receipt fields

The vault emits a Receipt event each time it applies a setting.

FieldTypeMeaning
epochuint64The epoch whose prices the setting was computed from. Indexed
modelIdbytes32Hash of the model's weights
sampleRootbytes32Hash of the epoch's 360 sealed prices
feeuint24The new fee in hundredths of a basis point. 3000 is 0.30%
tickLowerint24Lower edge of the new range, as a Uniswap tick
tickUpperint24Upper edge of the new range, as a Uniswap tick
proofHashbytes32Hash of the proof that was verified
navuint256The vault's total value when the setting was applied

Contracts and network

ContractWhat it doesAddress
FloVaultTakes deposits, pays withdrawals, applies settings, writes ReceiptsNot deployed
FloHookThe Uniswap V4 hook. Sets the fee on each swap, records prices, lets only the vault add or remove liquidityNot deployed
FloVerifierVerifies the proofs. Generated by EZKL (Halo2 with KZG commitments)Not deployed
ModelRegistryHolds the active Model ID, its author and whether it's suspendedNot deployed
BondManagerHolds the Prover's bond and pays it out for missed epochsNot deployed
NetworkChain ID
Robinhood Chain4663
Robinhood Chain testnet46630

Check token addresses, not names. Robinhood Chain has pools with fake tokens named after real ones, including a fake USDC. The pool only accepts the canonical ETH and USDG, whose addresses are fixed in the hook. We'll list every address here when the contracts are deployed.

More

Risks

Read these before you deposit, once deposits open.

The contracts are new

They haven't been written or audited yet. Even after an audit, a bug could lose funds. That's why deposits start capped.

Providing liquidity can lose money

When the price moves a long way in one direction, the vault ends up holding more of the asset that fell. Fees may not make up for it. This happens with or without a model.

The model can be wrong

The proof shows the model ran as committed, not that its call was right. The price can leave the range, and while it's outside, the vault's liquidity earns no fees.

Some tokens can sit unused

The vault never swaps when it moves its range. Whatever doesn't fit the new range waits in the vault and earns nothing until a later range uses it.

The Prover sees each setting first

Whoever runs the Prover knows the next fee and range before anyone else and could trade on it. The limits narrow that edge. They don't remove it.

Someone could try to move the recorded prices

The model only reads the pool's own prices. Pushing them means trading against the pool in many 10-second slots, which costs money, and the range is centred on an average rather than the last price. While the pool is small, this is cheaper to try, which is another reason deposits start capped.

Fallback mode earns less

If proofs are missed, the pool runs at 0.30% across the full range until the next valid proof. The Prover's bond pays depositors for each missed epoch, but that may not cover the fees a proven range would have earned.

Questions

Is there a zkFLO token?

No. Depositors earn swap fees through their vault shares. That's the only reward.

Can you stop me from withdrawing?

No. No role in the system can pause withdrawals, including ours.

Can you change the model without anyone noticing?

No. A new model has a different Model ID, and it can only be registered through governance's timelock. Every Receipt records the Model ID it was proven against.

Does a proof mean the pool makes money?

No. It means the setting came from the committed model, on the sealed prices, inside the limits. Whether that setting earns more than it loses is down to the model and the market.

What happens if the Prover goes offline?

Five minutes after the epoch ends, the pool switches to Fallback mode and the Prover starts losing bond to depositors. After three missed epochs in a row the model is suspended. The pool keeps working in Fallback mode, and you can still withdraw.

Why can't I see the model?

Its weights are what makes it worth running. If they were public, anyone could copy it. The proof lets you check every setting it makes without seeing them.

Where's the track record?

The list of Receipts is the track record, and it starts when the testnet run does. We won't publish backtests.

Roadmap

This is the order we're working in. We're on step 1.

  1. Measure proving. How long a proof takes, how big it is, and what it costs to verify on Robinhood Chain testnet. This sets the epoch length.
  2. Write the contracts. Hook, vault, verifier, model registry and bond, with tests.
  3. Build the Prover node. It seals, proves and submits every epoch.
  4. Build the indexer and finish the app. A preview of the app is already up.
  5. Run on testnet until there are 30 days of Receipts with no gaps.
  6. Audit, then launch on mainnet with deposits capped.

zkFLO is still in development and isn't taking deposits. Nothing in these docs is an offer or financial advice.
Home · App · X · Terms · Privacy