What volume would it take?

Annual buyback if volume and the captured take rate scale from today's observed values, against a market cap held at today's. NEAR's captured revenue funds a buyback of $NEAR (not a burn) since 2026-02-23.

What volume would it take?

Window 2026-09-29 → 2026-10-28. Gross fees 15.9 bps of reported volume; NEAR captures 34% (5.4 bps). Annual buyback if volume and take rate scale as shown, with market cap held at today’s.

Take rate caseVolume vs nowTake (bps)Annual buyback% of mcap
current observed0.5×5.4$13.1M0.21%
current observed1×5.4$26.2M0.43%
current observed2×5.4$52.3M0.86%
current observed5×5.4$130.8M2.14%
current observed10×5.4$261.6M4.28%
half of observed0.5×2.7$6.5M0.11%
half of observed1×2.7$13.1M0.21%
half of observed2×2.7$26.2M0.43%
half of observed5×2.7$65.4M1.07%
half of observed10×2.7$130.8M2.14%
double observed0.5×10.8$26.2M0.43%
double observed1×10.8$52.3M0.86%
double observed2×10.8$104.6M1.71%
double observed5×10.8$261.6M4.28%
double observed10×10.8$523.2M8.57%

Source: pipeline/model.py. Observed inputs are computed; multiples are assumptions in data/reference/model_assumptions.json.

How it is computed

  1. Observed: 30-day window of reported volume, gross fees and captured revenue from DefiLlama (fetched at build, not stored), gas burned from the pipeline, spot price and total supply from chain state.
  2. Scenarios multiply annualized volume and take rate by the multiples in model_assumptions.json.
  3. Market cap uses total supply, so yields are conservative.

Read this before quoting it

  • Fees and revenue come from DefiLlama; they cannot be derived from on-chain events (the protocol fee is about 0.0001%).
  • Scenario multiples are assumptions, not forecasts.

Runs in DuckDB over the local cache of BigQuery logs. Metric queries read the base tables built by 00_setup.sql.

pipeline/model.py
pipeline/model.py
1"""Simple value-capture model: Intents volume -> NEAR captured revenue (buyback) -> yield on NEAR market cap.
2
3 python -m pipeline.model
4
5Observed side (computed): trailing-window public volume from the pipeline, total volume / fees / captured revenue
6from the DefiLlama snapshot, gas burned by intents.near, NEAR price and total supply.
7Scenario side: data/reference/model_assumptions.json (volume multiples, take-rate multiples).
8Writes data/metrics/model_observed.csv and data/metrics/model_scenarios.csv.
9"""
10import json
11
12import pandas as pd
13
14from pipeline import config
15from pipeline.assets import REF
16
17M = config.ROOT / "data" / "metrics"
18
19
20def confidential_residual(vol: pd.DataFrame, dl: pd.DataFrame, end: pd.Timestamp) -> None:
21 """Implied confidential share = 1 - public on-chain leg-sum / DefiLlama reported volume (a residual, not a measurement).
22
23 Writes derived ratios only (never DefiLlama's own series): weekly share, and one row of facts about where the share
24 breaks out of its pre-September level, so the thesis can test the "migration to Confidential Intents" explanation.
25 """
26 v = vol[vol["date"] <= end].copy()
27 v["pub"] = v["leg_sum_priced_usd"] + v["leg_sum_imputed_usd"].fillna(0)
28 df = v.merge(dl[["date", "volume_usd"]], on="date").query("volume_usd > 0").set_index("date").sort_index()
29 wk = df.groupby(df.index - pd.to_timedelta(df.index.weekday, unit="D")).agg(days=("pub", "size"), pub=("pub", "sum"), dl=("volume_usd", "sum"))
30 wk = wk[wk["days"] == 7]
31 pd.DataFrame({"week_start": wk.index.date, "days": wk["days"], "implied_confidential_share": 1 - wk["pub"] / wk["dl"]}) \
32 .to_csv(M / "confidential_weekly.csv", index=False, float_format="%.6g")
33
34 share = lambda x: 1 - x["pub"].sum() / x["volume_usd"].sum()
35 daily = 1 - df["pub"] / df["volume_usd"]
36 brk = None
37 for d in df.index[df.index >= df.index.min() + pd.Timedelta(days=14)]:
38 before, after = df.loc[d - pd.Timedelta(days=14): d - pd.Timedelta(days=1)], df.loc[d: d + pd.Timedelta(days=13)]
39 if len(after) == 14 and daily[d] >= 0.05 and abs(share(before)) < 0.02 and share(after) >= 0.05:
40 brk = (d, before, after)
41 break
42 rows = {}
43 if brk:
44 d, before, after = brk
45 later = df.loc[d + pd.Timedelta(days=14): d + pd.Timedelta(days=41)]
46 rows = {
47 "break_date": d.date(), "share_14d_before": share(before), "share_14d_after": share(after),
48 "public_per_day_change": after["pub"].mean() / before["pub"].mean() - 1,
49 "reported_per_day_change": after["volume_usd"].mean() / before["volume_usd"].mean() - 1,
50 "intents_per_day_14d_before": before["intents"].mean(), "intents_per_day_14d_after": after["intents"].mean(),
51 "intents_per_day_days_15_to_42": later["intents"].mean(),
52 "share_month_before_break": share(df[df.index.strftime("%Y-%m") == (d - pd.Timedelta(days=1)).strftime("%Y-%m")]),
53 }
54 pd.Series(rows, name="value").to_frame().to_csv(M / "confidential_break.csv", float_format="%.6g", index_label="key")
55
56
57def main() -> None:
58 a = json.loads((REF / "model_assumptions.json").read_text())
59 vol = pd.read_csv(M / "daily_volume.csv", parse_dates=["date"])
60 gas = pd.read_csv(M / "fees_and_gas.csv", parse_dates=["date"])
61 dl = pd.read_csv(REF / "defillama_near_intents.csv", parse_dates=["date"])
62 sup = json.loads((REF / "near_supply.json").read_text())
63 supply = sup["total_supply_near"]
64
65 end = vol["date"].max() - pd.Timedelta(days=1) # last cache day is partial; drop it
66 start = end - pd.Timedelta(days=a["window_days"] - 1)
67 win = lambda d: d[(d["date"] >= start) & (d["date"] <= end)]
68 v, g, d = win(vol), win(gas), win(dl)
69 n = a["window_days"]
70 near_px = sup["near_price_usd"] # DefiLlama price at the window end (see near_price_date)
71 mcap = near_px * supply
72
73 pipe_public_legsum = v["leg_sum_priced_usd"].sum() + v["leg_sum_imputed_usd"].fillna(0).sum()
74 dl_total = d["volume_usd"].sum()
75 fees, rev = d["fees_usd"].sum(), d["revenue_usd"].sum()
76 obs = {
77 "window_start": start.date(), "window_end": end.date(), "days": n,
78 "pipeline_public_legsum_usd": pipe_public_legsum,
79 "pipeline_public_net_swap_usd": pipe_public_legsum / 2,
80 "defillama_total_volume_usd": dl_total,
81 "implied_confidential_share": 1 - pipe_public_legsum / dl_total,
82 "gross_fees_usd": fees, "captured_revenue_usd": rev,
83 "gross_fee_bps_of_reported_volume": 1e4 * fees / dl_total,
84 "captured_share_of_gross_fees": rev / fees,
85 "captured_bps_of_reported_volume": 1e4 * rev / dl_total,
86 "gas_burned_near": g["tokens_burnt_near"].sum(), "gas_burned_usd": g["tokens_burnt_usd"].sum(),
87 "near_price_usd": near_px, "near_total_supply": supply, "near_mcap_usd": mcap,
88 "annualized_revenue_usd": rev * 365 / n,
89 "annualized_buyback_yield_on_mcap": rev * 365 / n / mcap,
90 "annualized_gas_burn_usd": g["tokens_burnt_usd"].sum() * 365 / n,
91 }
92 pd.DataFrame([obs]).T.rename(columns={0: "value"}).to_csv(M / "model_observed.csv", float_format="%.8g")
93
94 rows = []
95 base_vol = dl_total * 365 / n
96 base_take = rev / dl_total
97 for name, mult in a["revenue_take_rate_scenarios"].items():
98 take = base_take * (1.0 if mult is None else mult)
99 for vm in a["volume_multiples"]:
100 for pm in a["near_price_multiples"]:
101 annual_rev = base_vol * vm * take
102 rows.append({"take_rate_case": name, "volume_multiple": vm, "near_price_multiple": pm,
103 "annual_volume_usd": base_vol * vm, "take_bps": 1e4 * take,
104 "annual_buyback_usd": annual_rev,
105 "buyback_pct_of_mcap": annual_rev / (mcap * pm)})
106 pd.DataFrame(rows).to_csv(M / "model_scenarios.csv", index=False, float_format="%.8g")
107 confidential_residual(vol, dl, end)
108 print(pd.DataFrame([obs]).T.to_string(header=False))
109
110
111if __name__ == "__main__":
112 main()
data/reference/model_assumptions.json
data/reference/model_assumptions.json
1{
2 "_note": "Editable scenario inputs for pipeline/model.py. These are ASSUMPTIONS, not measurements; everything else in the model is computed from pipeline output.",
3 "window_days": 30,
4 "volume_multiples": [0.5, 1.0, 2.0, 5.0, 10.0],
5 "revenue_take_rate_scenarios": {
6 "current_observed": null,
7 "half_of_observed": 0.5,
8 "double_observed": 2.0
9 },
10 "near_price_multiples": [1.0],
11 "note_on_supply": "Total supply from block header is used as the market-cap denominator; circulating supply would be lower, so yields below are conservative."
12}