Classifying Crypto Assets by How They Extract and Distribute Income

The method, the taxonomy, and its limits
Teaching document · Version 2.0 · universe: CoinGecko Top-1000


1. The question this answers

Price and market cap say nothing about the question that decides an asset's long-run fate:

Does the money a protocol earns reach the token holder — and by what route.

This is called value accrual. Consider an example.

Picture an exchange that charges a fee on every trade and earns $100M a year. It has a token. Does holding that token make you richer because the exchange earned $100M? The answer varies:

All three exchanges look identical in a report: "revenue $100M". To a holder they are three entirely different assets. The method exists to tell them apart.

The question splits into three independent parts that must not be mixed:

  1. Does the protocol earn anything at all?
  2. Is my share being diluted by new issuance?
  3. Does what it earns reach the token?

One protocol earns a lot and returns nothing. Another returns everything it earns, and earns almost nothing. A third "pays yield" by printing new coins — paying the holder with his own dilution. A single "yield" number hides all three cases. Hence three separate axes.


2. Vocabulary

Five concepts, in plain terms.

Fees and revenue are different things

Where the rest goes: on an exchange like Uniswap the user pays a fee, but most of it goes to liquidity providers — people who supplied capital so the trade could happen at all. That is their earning for the capital. It has nothing to do with the protocol's token. Same in lending: the borrower's interest goes mostly to lenders, and the protocol keeps a slice.

Practical consequence. Counting by fees inflates the picture: it credits the token with someone else's income. The whole method counts protocol revenue. The gap is often several-fold.

Market cap and FDV — coins that exist and coins that will

FDV ÷ market cap shows how many times supply can still grow:

This is called the overhang.

Unlocks and cliffs

Team, investor and foundation coins are usually locked and released on a schedule. Each release is an unlock. A cliff is a single large release on one day — more dangerous than a smooth schedule, since the market takes the hit at once.

Issuance, burning and dilution

They run simultaneously, against each other:

Staking — and where the "yield" comes from

Staking means locking a token for a payout. The question almost always skipped: where does the money for that payout come from. Two sources, opposite in meaning:

  1. From protocol revenue. The protocol earned from users and shared with you. Outside money entered the system. This is real income.
  2. From printing new coins. The protocol earned nothing; it minted coins and gave them to you. Not one cent of outside money arrived.

In the second case "12% APR" is an illusion. Stakers were rewarded at the expense of non-stakers, whose share was diluted. The pie did not grow — it was re-cut. Yield dashboards such as StakingRewards show the percentage without separating the source, and that is their central weakness.


3. The three axes

Each axis scores 2 (good) / 1 (middling) / 0 (bad). Absent data yields no score at all (see §8).

Axis A — does the protocol earn

Counted on protocol revenue, not fees (§2).

scorein plain terms
2Earns a lot (from $25M/year), the flow is steady, and revenue does not rest on speculation around the token itself
1Earns moderately ($2–25M/year). Or earns a lot, but the flow is spiky or speculative
0Earns almost nothing (under $2M), or the volumes are untrustworthy

What "steady flow" means. Revenue can be a one-off spike: hype arrives, everyone trades for a week, then silence. We catch this by comparing paces:

Take the last 7 days of revenue and annualise it.
Take the last 30 days and annualise it.
Divide the first by the second.

Up to 2.5 counts as fluctuation. Above that, the top score is withheld.

Axis B — is the holder being diluted

The absolute level of inflation carries no meaning. Printing 9% a year is neither good nor bad by itself — what matters is whether that printing is offset. An asset inflating 9% that returns more to the holder than it prints creates no dilution. An asset inflating 3% that returns nothing dilutes by the full 3%.

So the axis measures a ratio, not a level:

issuance ($/day) = daily growth in circulating supply × price
offset   ($/day) = payouts to the holder per day
coverage         = offset ÷ issuance
scorein plain terms
2Circulating supply is shrinking (more is retired than printed) or payouts fully cover issuance (coverage ≥ 1)
1Issuance is partially offset (coverage 0.3–1)
0Issuance is barely offset (coverage < 0.3) — direct dilution

If issuance cannot be measured, the score is 1. Ignorance is not punished.

What the issuance figure already accounts for. It is taken as the change in circulating supply, which makes it net. Everything that reduces circulation is already subtracted:

Counted separately is only the second kind of offset — compensation in money: payouts that do not shrink supply but return value to the holder.

What does not count as an offset:

Overhang and cliffs: a threat, not dilution

FDV overhang and pending unlocks are excluded from axis B. They are potential, not actual: until coins reach the market, they have diluted no one. Penalising them means scoring something that has not happened.

They appear as a separate threat indicator: FDV overhang, supply outside circulation, absence of a supply cap. And when an unlock does occur, it shows up in the issuance measurement by itself — circulation jumps. No schedule is needed: a realised unlock is indistinguishable from any other issuance, which is correct in substance.

Why we do not use unlock schedules. DefiLlama's schedule moved behind a paid plan
(its endpoints return 402), and no free source exists. The loss is small: a schedule
describes what was promised, the supply measurement describes what happened.

Axis C — does it reach the holder

scorein plain terms
2A real flow reaches holders: at least $1M/year and at least 0.5% of market cap
1A mechanism exists but does not work: nothing to burn (no activity), or the payout comes from printing, or the launch is still ahead
0No mechanism, or the money structurally bypasses the token

Why two conditions. An absolute figure untethered from size deceives. A $1M flow against a $10B cap is 0.01% — a million on paper, nothing in practice.

3.1. How actual issuance is measured

CoinGecko publishes historical price and market cap series for free. Its market cap is price × circulating supply, so circulation follows by division:

circulating(t) = market_cap(t) ÷ price(t)

A 90-day series gives the actual growth in circulation — net issuance after everything that reduces it.

Verifying the source is mandatory. CoinPaprika computes market cap from **total
supply**, not circulating, so the same division returns a false zero there: for Canton
CoinGecko shows +8.3%/year and CoinPaprika 0.0%. The trick works only where market cap
is built on circulating supply.

The example this exists for. Canton:

quantityvalue
supply cap — none
actual inflation+9.0% per year (measured over 90 days)
issuance$1.22M per day
payouts to holders$1.39M per day
coverage×1.14 — issuance is offset

Unlimited issuance looks like a death sentence for any token. Yet Canton prints 9% a year and returns more to the holder than it prints. Under "inflation above 8% scores zero" it would take the worst mark; under the ratio it takes the best — which matches substance.

The opposite case — MORPHO: inflation +103%/year, issuance $2.48M/day, payouts $0, coverage ×0.00. Zero, and deserved.

A third — HYPE: circulation shrinks 25% a year, because buybacks into the reserve withdraw coins from the market. The measurement catches this automatically; no special logic for treasury parking is required.


4. The taxonomy: ten models and one modifier

The axes say how well. The model says by what mechanism value reaches the holder.

Group I. The protocol earns and shares

keywho receivesin what formnote
direct_yieldstakersmoney or another assetclosest to a dividend; independent of the token's price
buyback_to_holdersstakers or treasurythe tokenyour gain depends on the token price, and the buyback supports that price
buyback_burnall holdersa growing sharepassive; no staking required

Examples: Pendle and Maple (direct_yield); Aave, Hyperliquid, Chainlink (buyback_to_holders); PancakeSwap, PUMP (buyback_burn).

Why these three are separated. In a "does it pay" table they look identical. To a holder
they differ: in the first you receive money, in the second a token (your gain tied to its
price), in the third nothing lands in your hands but your share grows. The popular
"real yield" label collapses all three.

Group II. Value returns through burning network fees

Here what burns is not discretionary revenue but the transaction fee inside the network. The difference matters: this is a rule baked into the protocol, not a management decision that can be cancelled next quarter.

keymechanismcondition
base_fee_burnthe base transaction fee is destroyed (EIP-1559)needs real activity
burn_and_mintfees burn the token while new coins are minted to operatorsdeflation only if burning exceeds minting

Examples: Ethereum, TRON, Monad, Plasma (base_fee_burn); Canton, Zama (burn_and_mint).

The fuel check. A burn mechanism can be perfectly written, but an empty network has
nothing to burn. If annual revenue is under 0.1% of market cap, the mechanism is idling:
the burn-no-fuel flag is set and axis C drops to zero.

Group III. Nothing reaches the token

keymeaning
monetaryThe protocol does not capture revenue by design. Value rests on scarcity. Judging it by accrual is meaningless — its thesis is scarcity. Examples: Bitcoin-like assets, TAO
governance_shellThe protocol earns, reports show revenue, but the token only grants a vote

governance_shell is the market's most common trap. Ondo is the reference case: its methodology literally says "yield goes to token holders" — but those are holders of USDY and OUSG, Ondo's stablecoin products. The ONDO token receives nothing. The statement is true; the inference from it is false.

Group IV. Nothing to pay with, or paying by printing

keymeaning
pre_revenue_infraTokenomics written, mechanism specified, protocol earns nothing yet
inflation_stakingStaking pays, but pays in newly printed coins (§2)

The distinction is critical: inflation_staking looks like a yielding asset at 8–15% APR, yet no outside money enters. Non-stakers fund stakers through dilution. Examples: Polymesh, Octra, most young PoS networks.

Group V. Outside the method

wrapper — the token tracks another asset one-to-one: stablecoins, liquid staking (stETH), wrapped coins (WBTC), tokenised stocks and funds. It has no accrual of its own; assigning it a tier would be a category error.

The reflexive modifier

Not an eleventh model — a flag on top of any of them.

Revenue is real, money genuinely arrives, but its volume is created by speculation around the asset itself: memecoin trading, agent tokens, perp venues paying incentives for volume.

An ordinary business earns on outside demand. Reflexive revenue arises from interest in the token itself: people speculate → fees rise → the protocol buys the token → the price rises → more speculators arrive. The loop feeds itself and collapses with attention, because no external demand sits under it.

Effect: caps axis A at 1 and blocks the top tier.

Why a flag. Reflexivity is perpendicular to mechanism. PUMP buys and burns (buyback_burn) and is reflexive. Making reflexive a type would force a choice between two true facts, or double the taxonomy into reflexive_buyback_burn, reflexive_buyback_to_holders, and so on.


5. How the model is determined

Numbers alone cannot separate close models: buyback_burn, buyback_to_holders and direct_yield all show "holders revenue above zero". They are separated by the mechanism description — DefiLlama's methodology string, and where that falls short, the project's own tokenomics documentation.

Strict order:

  1. Wrappers first. A stablecoin, liquid-staking token, wrapped coin or tokenised stock with no protocol revenue → wrapper. Stop.
  2. Something reaches holders → read the mechanism text: burn + mint → burn_and_mint · "base fee"/EIP-1559 → base_fee_burn · "gas fee" + burn → base_fee_burn · explicit "buy back and burn" → buyback_burn · buyback + stakers/reserve → buyback_to_holders · fees to holders without buyback → direct_yield.
  3. Nothing reaches holders and it is a chain: fee burning → base_fee_burn; burn with minting → burn_and_mint; hard cap without revenue capture → monetary.
  4. Revenue exists, holders get zero, not a chaingovernance_shell.
  5. No revenue: a chain with inflationary staking → inflation_staking; otherwise → pre_revenue_infra.
  6. The reflexive flag is set independently of steps 1–5.

Order inside step 2 carries meaning. An explicit "buy back and burn" is checked before "buyback + treasury". PancakeSwap's description mentions both; the treasury rule firing first would yield buyback_to_holders, which is wrong. Burning is the more specific signal.


6. How the tier is assigned

The tier is computed by code, from a formula, not by judgment. The model owns the mechanism; the tier owns quality.

With a, b, c as the axis scores and total = a+b+c:

tierconditionmeaning
T1all three axes = 2Earns, does not dilute, shares
T2c=2, a≥1, b≤1Shares materially, with a flaw in issuance or scale
T3(c≥1 and a≥1 and total ≥3) or (a=2 and c=0)Partial accrual on real revenue, or large revenue bypassing the token
T4c=1, a≤1, and a chain or total ≤3Mechanism present, fuel absent
T5anything elseAccrual absent or token

Plus two rules: a reflexive asset cannot reach T1 (demoted to T2); wrappers, unmeasurable and disputed assets receive no tier at all.

The a=2 and c=0 → T3 branch deserves attention. An asset with large revenue that does not reach the token (a governance_shell) ranks above an asset with no revenue at all. The logic: the business exists and earns; turning on a fee switch is a governance decision. Building a working business is harder than deciding to share.

One model spans tiers, and that is correct. buyback_burn is T1 at PancakeSwap, T2 at PUMP (reflexivity), T3 at Clearpool (thin revenue). Same mechanism, different execution.


7. Manual corrections

A curated layer outside the code catches what sources cannot see. Each flag carries a written reason.

flageffectpurpose
wash-volumeA ≤ 1 and C ≤ 1Volume is fabricated, so both the revenue and the buyback funded by it are unreal
burn-no-fuelC = 0Burning without activity is not accrual
no-accrualC = 0Value structurally bypasses the token
reflexive-cyclicalsets reflexivity, A ≤ 1Revenue driven by a speculative loop
accrual-pendingC ≤ 1Mechanism written, flow not started
post-crash, manipulation-flag, mm-incident→ manual reviewData untrustworthy
dune-burn-candidatechanges nothingMarks a treasury-like burn profile worth reviewing by hand. Does not affect the verdict — see §12.7a

A manual verdict where the sources are blind by construction

One case is not "no data" but "data cannot exist". An exchange token earns its revenue off-chain, and aggregators will never see it. Refusing to judge such assets forever would leave the method silent about a visible part of the market.

So the mark layer allows a manual verdict: a human sets the axis scores and attaches a written justification. The constraints are strict:

The line runs along the nature of the evidence. An issuer's public buyback report is a statement, not a measurement, so it may name the mechanism but not set the axes. That is how LEO, BGB and HTX are handled: the model is stated, the tier is absent.


8. What to do when data is missing

A classifier must distinguish "bad" from "unknown". Merging them produces a tool that lies with confidence. Hence a status on every asset:

statusmeaning
measuredA verdict from data
unmeasurableNo protocol or revenue in the sources → no tier is assigned
out of methodA wrapper
needs reviewSignals conflict, or the text could not be read

Plus a confidence: high (mechanism read from the description, all three axes from data), medium (mechanism from a language model, or an axis from a fallback), low (goes to review).

The method's rule: no data → a mark, not a guess.
An asset without data never receives a tier.

A mechanism without numbers: name the model, withhold the tier

Sometimes the mechanism is known while business data is absent. A token with a hard supply cap and no revenue capture is monetary by definition; a project's documentation saying plainly "we buy back and burn" names the mechanism whether or not we know the revenue.

In such cases the method names the model and assigns no tier. The model answers "by what mechanism", and text can answer that. The tier answers "how well", and that requires numbers on axes A and C, which are missing. Showing the model is useful; deriving quality from it would be invention.

This follows from the rule about the boundary of knowledge rather than excepting it.

What absence of data does not prove

A protocol missing from the sources means "we cannot see the business", not "there is no business". The distinction matters for exchange tokens: an exchange earns its revenue off-chain, where aggregators cannot see it by construction. Labelling such a token monetary would be wrong — Bitget (BGB) runs a working buyback-and-burn funded by off-chain revenue. So for exchange tokens the inference "scarcity bet from a supply cap" is forbidden: they stay unmeasured with the reason stated explicitly.

Results on the Top-1000 (snapshot 2026-07-16)

statuscountshare
measured44044.0%
out of method (wrappers)12512.5%
unmeasurable43443.4%
needs review10.1%

Tiers: T1: 12, T2: 9, T3: 27, T4: 168, T5: 220.

Two figures worth discussing with students:


Observation over time

Every run is stored as a snapshot, and verdicts from past dates are never rewritten. That gives two things a one-off assessment cannot.

What changed, and why. A tier change explains nothing by itself: "the asset became T1" may mean revenue grew, a broken join to the source got fixed, or the mechanism was re-read. So the reason is recorded alongside the fact — which axes moved, whether the model changed, how much revenue grew, whether coverage shifted. A score whose origin is invisible does not deserve trust.

What did NOT change. Stability of a verdict across snapshots is information in itself: a protocol's mechanism is stable for months while the figures move daily.


9. Why the taxonomy is built this way

By mechanism, not by sector. Sector membership predicts nothing about accrual. Two decentralised exchanges can be buyback_burn and governance_shell — opposite assets to a holder, identical by sector.

Three axes, not one score. Collapsing to one number destroys the diagnosis. "Earns but does not share" (a=2, c=0) and "shares all it has, which is little" (a=0, c=2) can sum alike while being opposite in nature.

monetary as a full type. Several of the largest assets capture no revenue by design. Without a type for them they would be labelled "poor accrual", which misdescribes them: their thesis is scarcity, and the method must name that rather than penalise it.

governance_shell separated out. It forces a check of who receives the flow.

Wrappers outside tiers. A one-to-one tracker has no accrual of its own.

Reflexivity as a flag. It is perpendicular to mechanism (§4).

The tier computed by code. Identical inputs must yield an identical tier in any run. A language model would drift between runs, and the ranking would move without any change in the facts.

9.1. What the shift from level to ratio gained

The first version of axis B scored issuance against absolute thresholds: inflation above 8% scored zero, FDV overhang above three scored zero. That construction had three defects, all now removed.

The threshold came from nowhere. Neither 8% nor 3% was derived from anything. The first measurement showed real inflation is bimodal: a dense cluster below ~6% and outliers past 36%. The 8–20% band was empty — the threshold stood in a void and could equally have been 10 or 20. A ratio removes the question: it requires no level, it compares issuance against what opposes it.

A level did not answer the holder's question. A holder is diluted not by the percentage printed but by how much of that printing goes uncompensated. Canton at 9% with ×1.14 coverage and Canton at 3% with zero payouts are opposite situations that an absolute threshold placed side by side.

The axis penalised what had not happened. FDV overhang and pending unlocks are a threat, not dilution. Moving them out of scoring into a separate indicator made the axis measure fact while keeping the threat visible. A realised unlock loses nothing by this: it enters the circulation measurement on its own.

A side gain: refreshing the data acquired a purpose. Previously a re-run changed only revenue figures. Now actual inflation and coverage depend on it, and through them the axes and the tier. An unlock, a change in buyback policy, a revenue decline move the ranking directly.


10. Comparison with other approaches

approachwhat it classifieswhy it does not answer our question
Sector categories (CoinGecko, CMC, Messari)what the project doessays nothing about accrual; two assets in one sector can be opposites
Metric dashboards (Token Terminal, DefiLlama: fees, revenue, P/S, P/E)how much the protocol earnsthey measure flow without classifying mechanism. P/E presumes earnings reach the holder — false for governance_shell. We use them as a data source
The "real yield" label (since 2022)whether a protocol pays "real" yieldbinary and coarse: merges buyback_burn with direct_yield, ignores issuance and reflexivity
Legal classifications (Howey, MiCA)legal statusperpendicular to the economics
Staking yield dashboards (StakingRewards)the APRthey do not separate the source — printing versus revenue. That is precisely the inflation_staking / direct_yield boundary, and it is erased there
Value-capture essays (fat protocol thesis, Multicoin, a16z)how tokens capture value in principlequalitative, without computable thresholds or a "no data" status; not reproducible
This methodthe mechanism by which value reaches the holdercomputable, reproducible, axes separated, the boundary of knowledge stated

The listed approaches answer adjacent questions — what the project does, how much it earns, its legal status, its APR. This scheme answers one: where the money goes — and carries it to a procedure that can be computed.


11. Strengths

  1. Answers the holder's question, not a question about sector or size.
  2. Computable and reproducible. Thresholds live in config, the tier is a formula.
  3. Separates measurement from judgment. Data → axes → code. A language model is used only to read ambiguous text. Human corrections go through an explicit, reasoned layer.
  4. States the boundary of knowledge. "Unmeasurable" and "needs review" instead of plausible invention — 43% of the Top-1000 the method declines to score.
  5. Separates mechanism from quality. The same buyback_burn can be T1 or T3.
  6. Reflexivity as a modifier keeps a perpendicular fact without doubling the types.
  7. Axis B free of invented thresholds. It compares issuance to what offsets it.

12. Limits and weaknesses

  1. The mechanism lives in project documentation, which is usually a JavaScript site. DefiLlama's methodology describes the fee source ("trading fees", "borrow interest"), not the distribution mechanism. Without browser rendering, some mechanisms are out of reach — on the 32-verdict reference set this yields 4 exact matches out of 25.
  2. Dependence on source coverage. 43% of the Top-1000 have no protocol in DefiLlama. The source also splits protocols into children (aave-v2/v3/v4); without aggregation, revenue is understated several-fold.
  3. Thresholds are conventions. $25M on axis A and 0.5% of market cap on axis C are defensible but arbitrary at the boundary. Pendle at $23.9M drops from T1 to T2 over a $1.1M shortfall. Axis B is free of absolute levels; its "partial coverage" boundary (0.3) remains a convention.
  4. Issuance measurement hits source rate limits. The supply series costs one request per asset, and free CoinGecko throttles within the second dozen. A full pass with measurement is practical only with a free CoinGecko Demo key; without one, some assets keep an unmeasured issuance and a neutral axis B.
  5. A net measurement does not distinguish causes. It answers whether coins grew or shrank, not why: a team unlock and a fee burn look identical to it.
  6. buyback_to_holders merges two things. "Distributed to stakers" and "parked in the treasury" differ: the second is not a distribution.
  7. Semantic traps need a human or a strong model. Ondo's "yield to token holders" is a trap. A keyword rule reads it wrong; a local 14-billion-parameter model also erred; only a 120-billion-class model and a manual note read it correctly. 7a. An on-chain burn does not prove accrual. The tempting shortcut is to measure the return to holders straight from the chain: count tokens sent to a burn address. It fails because the same operation means two opposite things. Under buyback-and-burn the protocol bought the token on the market and destroyed it — value reached the holder. In a wrapper or a vault, a burn happens when a user withdraws their own deposit — value reached nobody. On-chain the two are identical.

A check across 154 addresses showed the size of the error: one token's "burn" came to 2178% of its own market capitalisation in a year, another's to 1106%. Returning eleven times your own value is impossible; this is mint-and-redeem mechanics. A burn above roughly 100% of market cap is a reliable sign of it.

Separating the two by the number of burning addresses (a treasury is a handful, users are thousands) works only partly: when a vault contract redeems on users' behalf, the address count is one as well. So on-chain measurement serves as a shortlist for manual review, not as a source for axis C.

  1. Out of scope: a buyback can stop at any moment (it rests on a decision, not an obligation), legal enforceability of accrual, treasury quality, off-chain revenue.
  2. Reflexivity detection is crude — it leans on the asset's category rather than an analysis of its revenue structure.
  3. The method values nothing in money. It classifies accrual quality, not price. T1 does not mean "buy".

13. Summary

Three statements:

  1. One question: where does the money go. Not what the project is, not how much it earns, but whether the earnings reach the holder and by what route.
  2. The answer decomposes into three independent axes (earns / does not dilute / shares) and one of ten mechanism models, optionally carrying the reflexivity flag.
  3. The boundary of knowledge is stated explicitly. An asset without data gets a mark, not a score. Of 1000 assets the method issues a verdict on 44%, calls 12.5% wrappers, and declines to judge 43%.

The lesson for a student: twelve assets out of a thousand reach the top tier. A protocol that genuinely earns, does not dilute its holder, and shares with him is rare on this market. Everything else approximates that pattern to varying degrees, and the method exists precisely to show which element is missing.


This document describes the method implemented in accrual_scanner. Thresholds live in config.py::THRESHOLDS, the taxonomy in models.py::Model, the tier formula in classify/tier.py, the correction layer in overrides.yaml.