Arkiv Ideathon · DeFi track · idea sketch
Last Look
A trader can promise you a price, watch you accept it, and then walk away — and by the time you object, the price they broke has already vanished. Make the offer expire on schedule and the receipt outlive it, and refusing stops being free.
Start here
Picture a currency exchange counter at an airport. The board says £1 = $1.25, good for the next 12 seconds. You walk up and say yes. The man behind the counter glances at his screen, sees the rate has just moved, and says: sorry, that one's gone.
If it had moved the other way he would have taken your money without a word. He wins in both directions.
And you cannot even complain, because the price he offered was only on the board for 12 seconds and it is already gone. There is no record of what he promised. It is your word against his.
That counter is a market maker. The board is a quote. Walking up is a trader taking it. And "sorry, that one's gone" happens billions of dollars a day under the name last look — the maker's right to see that you want to trade and only then decide whether to honour the price.
The fix, in one move
Write four kinds of note, and give them deliberately different lifespans. The offer is allowed to die. The evidence that someone accepted it is not.
| In plain words | Called | How long it lives | Who writes it |
| The price on the board | Quote | exactly as long as it is binding — 12s | the maker |
| "I accept, at these terms" | Hit | 7 days | the trader |
| Honoured it / walked away | Settle | 7 days | the maker |
| "I was at the counter" | Heartbeat | 30 days | the maker |
Green is the offer, and it is short. Blue is the acceptance and the outcome, and they run a full week. That difference in length is the entire idea.
Ask the same question twice
This is the whole product in one screen. You ask the system what is on the board right now.
At 8 seconds
1 offer — firm for 4 more seconds
Anything the system hands you is binding. You never have to check whether a price is stale, because a stale price cannot be returned to you.
At 20 seconds
0 results
The expired offer is not shown to you greyed out. It does not exist any more. Firmness stops being a promise the maker makes and becomes a property of the database.
Now ask a different question — show me the times this maker walked away — and it all comes back. The offer vanished on schedule. The receipt is still sitting there, six days from now, written by the person who was refused.
A maker who sees intent and then declines holds a free option on every quote they publish. Today the refusal leaves no trace, because the quote it broke has already expired.
The four records
| Entity | Lifetime | Attributes |
| Quote |
expiresIn = firmFor |
quoteId · pair "cow:WETH/USDC" · side 1 bid / 2 ask · priceMinor (the range attribute) · priceTier, a log10 band · sizeMinor · firmFor, even, since lifetimes count in 2s blocks · termsHash · $creator = maker |
| Hit |
expiresIn = disputeWindow, 7d |
quoteId · quoteHash, the exact terms the taker saw · makerRef · takenMinor · $creator = taker |
| Settle |
expiresIn = disputeWindow |
quoteId · outcome 1 filled / 2 REFUSED / 3 partial · filledMinor · txRef · $creator = maker |
| Heartbeat |
30d |
quoteId · $creator = maker. Append-only, so there is no counter to overwrite and nothing to race. |
Range-queried attributes are integers; strings match by equality only. Money is carried in minor units, never floats. Every entity carries quoteId because Arkiv has no joins — the client fetches by that key. There is no updateEntity anywhere: it replaces the whole entity and races concurrent writers, which is the wrong primitive for two-party evidence. Only extendEntity, so a re-quote is a change of lifetime rather than a new signed blob.
The four queries it lives on
| Question | Predicate |
| What is actually on the board? | eq(pair,…) AND eq(side,2) AND lt(priceMinor,…) |
| What am I bound to right now? (maker) | eq($creator,me) over live Quotes |
| Who took my price and must be honoured? | eq(makerRef,me) over live Hits |
| How often does this maker actually fill? | count() eq($creator,maker) AND eq(outcome,1) vs eq(outcome,2) |
There is no server-side ORDER BY, so sorting after a limit gives you the top of a page rather than the best price. priceTier narrows the filter until the candidates fit one fetch and the client sorts them.
Why it cannot be the venue's database
Fill rate becomes a number anyone can count: honoured against refused, computed from records the maker never wrote alone. Reputation is a query, not a badge, and never one the maker issues about themselves.
The three records are written by different parties in turn — maker, then trader, then maker — and the chain stamps who wrote each one. So neither side can forge the half they did not write, and neither can the venue.
Which is the point. The venue takes a cut of the flow it would be reporting on. Trust us, this maker fills 99% of the time is exactly the claim you should not accept from whoever is being paid for the trade. A venue that can forge a quote can forge the refusal record for it.
What deliberately stays off Arkiv
Matching, routing and settlement: the hot path is untouched. Arkiv holds the offer and the evidence; the venue reads and acts. Funds are never custodied — a Settle records an outcome, nothing more. The signed quote payload stays off-chain behind termsHash. Maker inventory, hedge state and reserves stay off entirely, because anything whose value depends on secrecy cannot live in a publicly queryable store.
Accepted openly: anyone can read the whole live book, competing makers included. For price discovery that is a feature, and it is why the quote is written down and the strategy behind it never is.