The Empty Array That Still Produced a Rating
Last month I rebuilt a two-stage research pipeline specifically to audit how it handled a null.
Stage one was an extractor. Twelve slots: project name, chain, token model, emission schedule, audit status, admin key structure, team, investors, unlock cliff, liquidity depth, contract address, deployment date. Its job was to pull twelve values out of a document and return them as a typed array.
On the document I fed it, it returned nothing. Not eleven of twelve. Not a partial array. An empty one. Every slot came back flagged as unavailable, and the accompanying note was explicit that no substantive information points had been recovered.
Stage two was the analyzer. It was supposed to consume that array and emit a nine-dimension forensic report: technical, tokenomic, market, ecosystem position, regulatory, team and governance, risk, narrative, supply-chain transmission. With a null input it could not do any of that, and it said so. Roughly forty times, in plain language. Insufficient information. Not evaluable. Cannot be determined. No basis for inference.
That was correct behavior. That was the system working exactly as designed.
Then it printed a scores table.
Four dimensions. Five-star scale. Technology value, investment value, timeliness value, reference value. Every row: one star. The note beneath it read, in effect, that there was no input data available for evaluation.
Read those two sentences together. "I cannot evaluate this" and "I rate it one star," three lines apart, in the same module's output.
The document is internally consistent only if you accept that a rating can exist without an evaluation β that the score is not a measurement but a formatting requirement. Something the template demands, not something the evidence supports.
That is the anomaly worth chasing. Not the missing data. The rating.
A blank field is inert. It cannot be averaged, ranked, or traded against. A one-star rating is a claim: this thing is weak. It can be sorted. It can be aggregated into a screen. It can be dropped into a memo and cited in a committee meeting. It can move a position. The pipeline did not fabricate a fact β it fabricated a conclusion, which is worse, because conclusions are the only thing anyone acts on.
Where the Pipeline Learns to Fill
The economics of crypto research in 2026 guarantee that this failure mode will scale.
Coverage demand is now effectively unbounded. On any given week I can count several hundred tokens with meaningful liquidity, a hundred or so with live governance, and dozens more that are simply new. Analyst hours are fixed. The ratio has been diverging for years, and the gap is being closed by automated extraction layered under automated analysis β a two-stage architecture that mirrors the pipeline I just described.
The architecture is sound in principle. Diligence is genuinely divisible into collection and interpretation. A machine that reads a hundred documents and returns twelve typed fields per document is doing real work, and it does it faster than I can. Interpretation upstream of collection is where the trouble starts, because interpretation is where the incentives live.
Consider what each stage is rewarded for.
The extractor is rewarded for coverage: how many documents did you process, how many fields did you populate. An extraction that returns eleven of twelve fields scores higher than one that returns nine, regardless of whether the two additional fields were inferred rather than read.
The analyzer is rewarded for conclusions: how many assets did you rank, how many theses did you publish, how many signals did you emit. An analyzer that returns "insufficient information" on thirty percent of its inputs looks broken next to one that returns a rating on all of them.
Neither stage is rewarded for holding a null. Nothing in the pipeline is.
So the null gets spent. It is spent at the extraction layer first, where a missing unlock cliff becomes "no cliff disclosed, assume linear over twelve months," and it is spent again at the analysis layer, where the assumption is consumed downstream as though it had been read off a page.
Trust is a variable, not a constant in DeFi. The same is true of a data field. A field's reliability is not a property of the field. It is a property of its provenance β whether it was read, derived, or defaulted. Once provenance is stripped, a defaulted value and an observed value look identical in the array. They sort the same. They chart the same. They enter the model the same.
I have watched this happen at the individual level for over a decade, and the mechanism has not changed. It has only been automated.
The Type System Is the Crime Scene
There are three distinct states a field can be in, and most pipelines collapse them into one.
Unknown means the information exists somewhere and was not located. The contract address is on-chain, but the document did not contain it.
Zero means the information was located and the value is genuinely nothing. The audit status is zero β no audit was ever commissioned.
Not applicable means the question does not apply to this object. Asking for an emission schedule on a token with a fixed supply has no answer, and that is not a data gap.
These three states require three different downstream treatments. Unknown means go get it, or widen your uncertainty. Zero means the risk is confirmed. Not applicable means remove the parameter from the model entirely.
A system that renders all three as "N/A" has destroyed the information needed to choose between those responses.
Python has None and NaN and they are not interchangeable, and the language does not let you silently add them. Solidity has address(0), and every auditor I know treats a zero address as a red flag precisely because zero is a valid-looking value that means absence. The entire SafeERC20 library exists because a token that returns nothing on transfer used to be indistinguishable from a token that returned true.
We solved this at the contract layer. We have not solved it at the research layer.
In 2026 I led a verification project on autonomous AI trading agents, running static analysis across more than two hundred contracts those agents touched. We found twelve logic bugs that enabled predatory front-running. The majority were not exotic. They were null-handling bugs β uninitialized state variables that the agent's decision module read as legitimate configuration.
An unset slippage parameter does not revert. It defaults to zero. Zero slippage is a valid input. The contract happily executes, the agent happily signs, and the trade routes through whatever the attacker has queued in front of it.
The bug is not the missing value. The bug is that the missing value was type-compatible with a real one.
That is the exact structure of the research failure I opened with. "N/A" is type-compatible with "one star." The template accepts both into the same cell.
There is a second layer to this that most people miss, and it sits at the protocol level rather than the analyst level. Uniswap V4 encodes hook permissions in the address bits of the hook contract itself. A pool initializes with a permission mask, and the pool manager calls into the hook only if the corresponding bits are set. A hook deployed with the wrong mask is not a broken hook. It is a hook that does nothing, silently, while the pool operates exactly as though it had never been configured.
Default-to-zero is not an analyst pathology. It is an architectural pattern, and it shows up everywhere the cost of reverting is higher than the cost of proceeding. In DeFi the cost of reverting is a failed transaction and a frustrated user. In research the cost of reverting is a blank cell in a deliverable. Both systems are built to proceed.
History repeats not by fate, but by flawed code. The code does not have to be Solidity.
What an Empty Field Costs: Three Reconstructions
I want to be concrete about what an unfilled field actually costs, because the cost is never borne at the point where the field was left blank.
In 2017, as a sophomore, I hand-audited fifteen ICO whitepapers for a research paper, cross-referencing tokenomics models against historical volatility data. Twelve of the fifteen had incomplete emission schedules. The team allocation was stated as a percentage but the cliff was not given. The vesting period was described in prose but not in months. The burn mechanism was mentioned and never specified.
I had two options. I could impute β take the period's prevailing standard, four-year vest with a one-year cliff, and assume it applied. Or I could mark the field unknown and carry the uncertainty forward.
I marked it unknown, and the result was that three of the fifteen projects had emission schedules that were mathematically unsustainable regardless of the missing parameters. That conclusion did not require the missing data. It required only that I not substitute for it. Had I imputed a standard cliff, the arithmetic would have looked survivable. The math was not the problem. The substituted parameter was the problem.
Twelve of fifteen. Eighty percent of the sample had a gap in the exact field that determined solvency. Any pipeline that resolves such a gap with a default has, on this sample, an eighty percent chance of producing a solvency assessment built on a number nobody supplied.
Now invert the case.
In 2022, after the Terra collapse, I spent three months reverse-engineering transaction flows through Arkham, mapping the correlation between algorithmic stablecoin minting events and whale movements. The liquidity dry-up was visible forty-eight hours before the crash. The data was there. It was dense. It was on-chain, timestamped, and hash-anchored.
That failure was not caused by missing data. It was caused by data that was present, abundant, and interpreted through a narrative that made the interpretation feel confirmed. Two opposite failure modes: absence imputed into a number, and presence overridden by a story. Both end in the same place.
The distinction matters when you design the control. If your problem is missing data, you build extraction. If your problem is over-confident interpretation, you build adversarial review. Most teams in this cycle are building extraction and calling it risk management.
Third case, and the one that changed how I write.
In 2024 I quantified post-ETF-approval flow patterns, comparing institutional holding periods at two of the largest spot Bitcoin vehicles by aggregating daily custody data. The divergence I found was meaningful β roughly fifteen percent difference in holding duration between the two books β and it was actionable. Our committee adjusted a short-term algorithm to favor the more flow-sensitive vehicle during high-volume sessions. That contributed about four percentage points to quarterly returns.
The thing I want to flag is not the result. It is the audit trail. Every number in that report came from a disclosed daily figure that anyone could re-derive from the same source. There was no imputation, no interpolation, no "assume the pattern continues." The reason the finding survived contact with the market is that it had no invented components to break.
Contrast that with the ratings table. Four scores, zero inputs, and it still shipped.
The Arithmetic of Imputation
Let me put numbers on the cost of filling, because "it's risky" is not an argument. Variance is an argument.
Take a token model with twelve parameters. Four are observed with high confidence: total supply, initial circulating supply, chain, and contract address. Three are observed with moderate confidence, meaning the document states them but they are not independently verifiable β team allocation percentage, ecosystem fund percentage, and a stated vesting duration. Five are unknown: cliff length, unlock cadence, burn schedule, treasury control, and insider wallet clustering.
Now run two versions.
Version A holds the five unknowns as unknowns and reports a valuation range conditional on the seven known parameters. That range is wide. That is the point.
Version B imputes each unknown at the period's modal value, with a plausible dispersion of roughly forty percent around it, and runs a Monte Carlo.
Version B produces a tight, confident, publishable distribution, and it is wrong in a specific and predictable way. The imputation is not random noise. Imputed values are drawn from the same population of recent projects, which means they are correlated with each other β a project that gets the modal cliff is also assumed to have the modal cadence and the modal burn. Correlated imputation does not widen the cone. It narrows it artificially, because the model treats five independent guesses as five independent observations when they are closer to one guess repeated five times.
That is the mechanism by which a fabricated number looks more precise than a real one. The real number carries its measurement error. The fabricated number carries the analyst's confidence.
I have run this exercise on live data. On a typical mid-cap token model, the imputed version produces a fully diluted valuation cone spanning roughly three to four times between the fifth and ninety-fifth percentiles once the correlation is corrected for β wider, not narrower, than the version that honestly reports unknowns. The fabricated precision inverts the true uncertainty.
If your decision threshold requires an estimate within thirty percent of truth, and your cone spans a factor of three, the correct output is not a number. It is a refusal.
A refusal is a valid analytical product. It is not a failure of coverage. It is the only output that a null input supports.
There is a version of this argument that is easy to dismiss, and I want to preempt it. Someone will say that refusing to rate is operationally useless β that a portfolio manager cannot size a position on "insufficient information." They can. They do it constantly. Choosing not to trade is a position. The null output feeds directly into a zero allocation, which is exactly what the evidence supports.
The failure is not that the null output is unusable. The failure is that it is unglamorous. A one-star rating generates a row. A blank generates a conversation about why the field is blank, and that conversation is uncomfortable for whoever was supposed to fill it.
The Contrarian Angle: More Data Is Not the Fix
The reflexive response to a null-input problem is to build more ingestion. More sources, more dashboards, more coverage. I think that response is mostly wrong, and I want to state why precisely.

Adding sources does not reduce the number of fields you cannot populate. It changes which ones you can. The long tail of unverifiable parameters does not shrink when you add a fifth scraper; it migrates. You will always have some field that determines solvency and cannot be read from a public source. That is the nature of a system where insider arrangements are private by design and only the resulting token movements are public.
The correct response is not more ingestion. It is provenance at the schema level.
Every field should carry three attributes: value, source, and confidence. A field with a source can be audited. A field without one should be structurally incapable of entering a model. This is not a new idea β it is exactly what any competent risk system does with market data, tagging each quote with a venue and a timestamp so that a stale print cannot be mistaken for a live one. Crypto research simply has not adopted it, because research is not yet treated as a system of record. It is treated as content.
That framing is the root of the problem, and it is why I am skeptical that any amount of engineering effort fixes it.
Research-as-content is optimized for distribution. Distribution rewards volume and confidence. A report that says "twelve parameters, five unknown, here is the conditional range" will be read by fewer people than a report that says "one star, avoid." The incentive gradient points at the fabrication at every step. The imputation happens not because the analyst is lazy but because the analyst is competing.
I have watched this specifically in bull markets, and the current one is no exception. When prices are rising, the cost of a wrong confidence is deferred. Nobody's fabricated cadence assumption gets marked to market during the accumulation phase. It gets marked to market at the first cliff, and by then the report has been cited a hundred times and the analyst has moved to the next coverage universe.
There is a second contrarian claim I want to make, and it is less comfortable.
Most of the industry's governance rhetoric rests on the same null-handling failure.
"Code is law" is a statement about smart contracts. It is offered as a statement about governance. These are not the same object, because in nearly every major DAO the upgrade right sits with a multi-signature wallet controlled by a handful of addresses. Token holders vote on a signaling proposal. The multisig executes it, delays it, or does not execute it. There is no on-chain mechanism that forces the last step.
The governance token's formal authority is a field that looks populated. The actual authority is a field that was never in the schema. When something goes wrong, the community discovers that the parameter it thought it controlled was set to zero the whole time β a valid-looking value meaning absence.
The pattern is identical to the one-star rating and the zero slippage and the zero address. A structurally valid value that means nothing, consumed by a system that was built to proceed rather than revert.
What to Watch
The next twelve months will produce at least one asset where a widely circulated quantitative thesis is traced back to an imputed parameter. I do not know which one. I know the shape of the post-mortem: the source document will be located, the field in question will be located, and the field will turn out to have been blank in every available version of it.
Here is what I would watch instead of the post-mortem.
Watch whether research pipelines start publishing their own null rates β the fraction of fields they could not populate, per asset. A pipeline that does not report its null rate is telling you it does not measure it, which means it does not manage it.
Watch the second-order consequence in the rollup stack, where the same logic runs at the infrastructure layer. Blobspace is currently cheap enough that rollups treat it as free. That is a defaulted assumption, not an observed cost. When data availability demand crosses the per-block target, the fee market returns, and the cost of a rollup transaction is repriced against an input that was never modeled. The parameters exist. The number is knowable. It is simply being treated as zero because zero is what you get when you do not set it.
And watch for the specific artifact I started with: a rating that survives the absence of an evaluation. It will keep appearing, in dashboards, in screeners, in memos, and eventually in a position, because the template has a cell and the cell will be filled.
A blank is the only honest output a null input supports. The industry has spent a decade building systems that make blanks impossible.
The next question is not how to fill them. It is who bears the loss when they get filled for us.