How it works
A TAPE2 call has two people and one pool. The writer owns the coins and wants a premium. The buyer wants a 7-day shot at the coin for a known, capped cost. The pool's tape sets the price between them.
The ticket
| Field | Meaning |
|---|---|
| Pool | A Uniswap v3 pool on Robinhood Chain with an observation ring (CASHCAT/WETH and PONS/WETH at launch) |
| Amount | How many coins the writer locks and the holder may buy |
| Strike | The price per coin the holder pays on exercise, in WETH |
| Expiry | A block time at most 7 days after writing |
| Markup | The writer's ask above the chain's price, from 0% to 100% |
| Premium | What the buyer pays, in WETH, at purchase: the chain's price plus the markup |
| Writer | The address that locked the coins |
| Holder | The address that paid the premium (empty until bought) |
Step by step
1. Write
The writer approves the contract for the amount, then calls write(coin, amount, strike, expiry, markupBps). The contract pulls the coins in and holds them. The offer is listed at the chain's price plus the markup; the price itself is computed fresh at every purchase, not frozen at write time.
Guards checked at write time: the strike must sit within 100x of the 30-minute TWAP, the expiry between 1 hour and 7 days ahead, the markup at most 100%, and the coins under live options in that market may not exceed 10% of the pool's coin balance.
2. Read the tape
The contract calls observe() on the pool with a list of secondsAgo values and receives the cumulative tick at each, straight from the pool's ring. Four windows are read: 24 hours in 10-minute steps (145 points), 7 days in hourly steps (169), 21 days in 2-hour steps (253), and the last 6 hours in 10-minute steps (37). The three long windows are cached in the contract and anyone may recompute one with refresh(coin, window); a purchase reverts if any of them is older than 12 hours. The 6-hour window is read fresh inside every quote.
3. Measure the swing
For each window the contract forms the average tick per step (each difference divided by the step), then the log returns (each tick difference times ln 1.0001). The sample standard deviation of those returns, times the square root of the number of steps in a year, is the realized volatility of that window.
The sigma used for pricing is the highest of the four windows plus 20 points of annual vol, so a quiet week does not make calls too cheap. If the 6-hour vol is above 3 times the highest long window, the market is in a storm and purchases revert until it settles.
4. Price
With price S the higher of the 30-minute TWAP and spot, strike K, time T to expiry and volatility sigma, the premium is the Black-Scholes call with zero rate:
d1 = (ln(S / K) + sigma^2 T / 2) / (sigma sqrt(T))
d2 = d1 - sigma sqrt(T)
C = S N(d1) - K N(d2)
On the chain this runs in 18-decimal fixed point (src/lib/Pricing.sol), tested against a floating-point reference at the same block. The number the site shows comes from the same rule in floating point.
5. Buy
The buyer calls buy(offerId, amount, maxPremium) and the contract pulls the premium in WETH: the chain's quote at that moment, times the amount, plus the writer's markup. It keeps 1% as the protocol fee (half into the burn pot, half to the treasury), forwards the rest to the writer at once, and records the buyer as the holder. The premium is the writer's whether or not the ticket is exercised. A buyer can buy part of an offer.
6. Exercise or expire
Before expiry the holder may call exercise(callId) and pay the strike times the amount in WETH. The contract sends the locked coins to the holder and the strike payment to the writer. After expiry anyone may call expire(callId), which returns the coins to the writer; the ticket is finished. An unsold offer, or the unsold part of one, can be taken back with cancel(offerId, amount) at any time.
Settlement never reads a price. The holder decides whether the coins are worth more than the strike, and acts or does not.
Why there is no oracle
Three places usually need a price feed, and TAPE2 needs none of them.
- Pricing uses the pool's own ring through
observe()andslot0(). The ring is written by the pool in every block it trades, and it cannot be rewritten. - Exercise is a decision by the holder, paid in WETH, delivered in the coin.
- Expiry returns the coins. Nothing is marked to a price.
Who does what
| Actor | Does | Gets |
|---|---|---|
| Writer | Locks coins, names strike and expiry | The premium at once, and either the strike (if exercised) or the coins back |
| Buyer | Pays the premium | Up to 7 days of the right to buy at the strike |
| Anyone | Refreshes a vol window, calls expire after expiry, calls the burn crank | Nothing but the chain doing its job |
| The pool | Keeps the tape | Nothing; it was keeping it anyway |
The contract is engine/src/Tape2.sol; its constants (TWAP_WINDOW, VOL_MAX_AGE, VOL_BUFFER, SPIKE_MULTIPLE, OI_CAP_BPS, MIN_EXPIRY, MAX_EXPIRY, STRIKE_BAND, MAX_MARKUP_BPS, FEE_BPS, BURN_SHARE_BPS, CRANK_SLIPPAGE_BPS) are public and readable by anyone.