Introduction
Underpin answers one question about any Solana coin: what would it cost to be allowed to sell this at a fixed price later? That right is a put option. The desk reads a live price, prices the put, and shows you the strike, the premium, the expiry and the breakeven.
The site borrows its picture from construction. The tower is the coin, and its height is the price. The piles underneath are the eight strikes. A strike is how far the tower can fall before it lands on something.
The words
| Word | Meaning |
|---|---|
| Spot | The coin at its live pool price. |
| Put | The right to sell a quantity of the coin at the strike until expiry. |
| Strike K | The USDC price per token you may sell at. |
| Premium p | The USDC per token the right costs today. |
| Cover | q × K, the USDC that has to exist for a seller to honour the put. |
| Breakeven | The price under which exercising pays back premium and fee. |
Quick start
- Open Markets and pick a coin, or press
/and paste a mint. - Move the strike slider and choose an expiry.
- Type the size of the bag you want covered.
- Read You pay and Breakeven, then press Pin on paper.
- Watch it on Positions. Exercise unlocks when the coin is under your strike.
From code
The pricing engine is one small module with no dependencies, served from this site.
import { quote, fmtPrice } from "%ORIGIN%/lib/underpin.js";
const q = quote({ spot: 0.05, strikePct: 0.8, days: 7, sigma: 1.5, q: 10000 });
console.log(fmtPrice(q.K), fmtPrice(q.p), q.maxLoss);
curl -s "https://api.geckoterminal.com/api/v2/networks/solana/trending_pools?include=base_token"
<script type="module">
import { markets, quote } from "%ORIGIN%/lib/underpin.js";
const [c] = await markets("trending");
document.title = c.symbol + " put: " + quote({ spot: c.spot, sigma: c.sigma }).premiumPct;
</script>Try it
How it works
A put pays when the coin ends under the strike. Below K, every token you hold can still be sold at K. Above K, you let the right lapse and your cost was the premium.
Spot
Spot is read from the coin's main pool. Underpin is not in the path of a swap and adds nothing to the price.
Put
At exercise you hand over q tokens and receive q × K in USDC. The desk books the value as q × (K − live price), which is the same trade marked to market.
Profit at expiry
profit = max(K - price, 0) * q - (premium + fee) breakeven = K - p * (1 + 0.02)
The eight piles
Each pile on the home page is one strike on the ladder, from 55% to 90% of spot. The fill height of a pile is K ÷ spot, so a deeper floor needs a shorter column of USDC behind it. The highlighted pile is the default series at 80%.
| Pile | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|---|---|---|---|---|---|---|---|---|
| K ÷ spot | 55% | 60% | 65% | 70% | 75% | 80% | 85% | 90% |
Cover is shown on every ticket as q × K so you can see the size of the promise being priced.
Markets
Three shelves refresh once a minute. New launches and Trending come from GeckoTerminal. Falling is both lists sorted by the worst 24-hour move. Floor watch ranks coins by the premium of the default series as a share of spot.
Search accepts a name, a ticker or a mint and uses the DexScreener search endpoint, keeping the deepest Solana pool for each coin.
Positions
Each open pin is marked against the live price every 30 seconds. Worth now is max(K − live, 0) × q. Exercise is available only while that number is above zero. A pin past its expiry settles once at the live price.
Receipts
Every pin, exercise and expiry is one line with a paper id. Filters narrow the log by flow.
| Flow | Amount |
|---|---|
PIN | −(premium + fee) |
EXERCISE | +(K − live) × q |
EXPIRE | +max(K − live, 0) × q |
Pricing spec
European Black-Scholes put with zero rates. The vol input is an estimate from what the pool reports, so treat the premium as a reference price.
d1 = (ln(S/K) + sigma^2 * T / 2) / (sigma * sqrt(T)) d2 = d1 - sigma * sqrt(T) p = K * N(-d2) - S * N(-d1) sigma = clamp((|h1| * sqrt(8760) + |h6| * sqrt(1460) + |h24| * sqrt(365)) / 300, 0.6, 10) sigma = 4 when the pool reports no moves at all
Constants
| Name | Value | Meaning |
|---|---|---|
SERVICE_FEE | 0.02 | Share of premium added on top |
STRIKES | 0.55 … 0.90 | The eight piles |
EXPIRIES | 1, 3, 7, 14, 30 | Days offered on the ticket |
VOL_MIN / VOL_MAX | 0.6 / 10 | Vol clamp, annualised |
VOL_NEW | 4 | Vol for a pool with no reported moves |
Module
| Export | Returns |
|---|---|
putPrice({S,K,T,sigma}) | Premium per token |
quote({spot,strikePct,days,sigma,q}) | K, p, premium, fee, maxLoss, cover, breakeven, expiry |
payoff({price,K,q,paid}) | Profit at expiry |
estimateVol({h1,h6,h24}) | Annualised vol |
markets(kind) | Live coins, "trending" or "new" |
search(q), coin(mint) | Coin lookup |
Price format
Long runs of zeros are written with a subscript count, so 0.0₅57 is 0.0000057.
Limits
- Pins are local. They live in this browser's storage and disappear if you clear it.
- The premium is a model. Young coins do not have a usable volatility history, and a real seller may charge something very different.
- The feed can lag. Prices come from public APIs and can be a minute behind the pool.
- Coins can go to zero and pools can vanish. A pool with no liquidity has a price nobody can trade at.
$UNDERPIN
The coin of the site. The address appears here once it is live.
| Field | Value |
|---|---|
| Ticker | $UNDERPIN |
| CA | soon |
| Buy | Buy $UNDERPIN |
| Chart | Open chart |
FAQ
Why does a put on a new coin cost so much?
Because new coins move hard, and the vol input follows them. A wide swing in the last hour makes a floor expensive.
Can I lose more than the premium?
A bought put has a known maximum loss: premium and fee. On this desk it is paper either way.
Why eight strikes?
Eight piles fit under the tower.
Do I need a wallet?
No. The desk has no wallet connection.