On today’s internet: about fifty cents. Corroborate reads every proof-of-personhood
protocol a wallet holds and prices each credential at what an adversary would actually
pay to fake it — then tells you which ones are the same evidence wearing different
names.
one passport ≠ three credentials$0.50 — the going rate for an orb-verified human40 protocols studied · 30 catalogued · 9 probed livesaturate within a root · sum across rootsrent beats forgenobody holds the join keythe caveats are the result
Forty protocols will swear a wallet is human.
They collapse into nineteen trust roots. One passport, read by four protocols, is one
credential — not four.
Every scorer that adds them up pays the sybil farm.
We price what the fraud would cost instead.
Ask it about a wallet. Right now.
Everything below runs in your browser against fourteen live chains — World Chain
and Gnosis to Celo, BNB and Idena. No server of ours, no account, nothing
precomputed. A subject can be several wallets, because real people spread
credentials across them.
Try:
Put it where you work
The MCP server
Four tools — look up a subject, check a threshold, explain the trust roots,
audit any weight’s history. One line, then ask your agent about any address.
The SDK
Typed, client-side, no key. Ontology from the public registry, credentials from
public chains, scoring in your process.
npm install @corroborate/sdk
import { Corroborate, Thresholds } from'@corroborate/sdk'const person = await new Corroborate().resolve('name.eth')
person.score // log₁₀ of adversary cost
person.independentRoots // uncorrelated evidence
person.isHuman(Thresholds.standard)
Within a trust root the strongest credential counts and the rest are the same
evidence again — across roots they add. Correlation is a property of the
credential class, a public fact about protocols, so we never need to
link a person’s credentials to each other. That link is exactly what we refuse
to hold.
Price at min(forge, rent)
A credential is worth the cheaper of faking one and renting one, because a
holder willing to rent theirs out defeats any amount of cryptography. Every
weight is a dated, sourced judgment that lives on-chain — every change is an
auditable event, and “why did my score move” is a GraphQL query.
The caveats are the result
There is no default threshold: isHuman(threshold) throws unless you
choose one, because at realistic sybil rates a strong classifier is wrong about
most of the people it flags. And no protocol proves a human acts for themselves
— so that caveat is permanent, on every result, including perfect ones.
The reading
Everything here is downstream of someone else's fieldwork
The saturation rule is not a clever idea we had. It is the conclusion of a decade of
people watching personhood systems get captured and writing down exactly how. Below
are the cases that shaped the design, the papers worth your evening, and two
instruments you can operate yourself — because a claim you can test beats a claim
you have to accept.
The most damaging criticisms of a product like ours are included, quoted, and
unanswered where we cannot answer them. That is not modesty. A scorer that hides its
strongest counter-argument is exactly the thing this field keeps producing.
Instrument 01
Try to buy a high score
Eleven real credentials, priced at what the deployed registry says an adversary pays
for each — min(forge, rent), because a holder willing to rent theirs out
defeats any amount of cryptography. Switch them on and watch two scorers disagree.
Then try to work out which number a consumer should actually gate on.
Additive — what ships today0.00
no evidence
Root-cost — saturate, then sum0.00
no evidence
0independent trust roots — the number that actually separates a person from a farm
Three protocols that taught us something
Case 01 — Idena
Idena did the hard thing. It filtered bots with a synchronous cognitive ceremony,
and — uniquely — it beat account trading, using identity staking and
periodic re-authentication. It still collapsed. Not into sybils: into
puppets. Real, verified, unique humans paid a few dollars an epoch
to perform ceremonies while an operator held the keys and took the rewards.
Peak network, Apr 202215,778 accounts
Human identities, Jul 202698
Large pools, Jun 2021 → May 202222% → 61%
23 entities (<0.6%) controlled~40% of accounts
The bribe that did it$2–$14 / epoch
Two findings changed our design. First, the operators' on-chain signature —
simultaneous one-way transfers to one wallet — is identical for
puppeteering and for voluntary cooperation. They differ only in the off-chain
distribution of power, so no amount of chain analysis can separate them. Someone
even shipped a
forked client
whose purpose was to hide a user's own private key from them.
Second, the accident that saved the network. Voting was one-node-one-vote and pools
had consolidated onto single nodes, so by May 2022 large pools held 61% of accounts
but only ~2.4% of votes, while solo accounts held 27% of accounts and ~89% of votes.
An unintended correlation discount let the honest minority fork the protocol
out of the crisis. That is the single most constructive datum in the
literature for anyone building a scoring system, and it is why we discount
correlation rather than try to detect fraud.
The fix that came next is a warning of its own. Sublinear identity staking
(IIP-5,
stake^0.9) did kill the puppet pools — and human identities fell 97.6%
from the fork to today. Concave weighting is a tax on your honest users too, and the
exponent decides who leaves.
Case 02 — Circles
Circles is the only genuinely biometric-free, document-free trust root in the
landscape: no passport, no iris, no liveness check anywhere in the protocol. Every
registered human mints their own token at 1 CRC/hour, and a public directed trust
graph decides whose money you will accept.
Which makes the registration bit close to worthless as evidence, and the arithmetic
is in Hub.sol:
an invite burns 96 CRC from the inviter and mints a 48 CRC welcome bonus to the
invitee. At 24 CRC/day of issuance that is a net two days of freely-minted
currency per new node, plus gas. A rate limiter with a two-day doubling
time, not a sybil barrier.
v2 humans (Jul 2026)26,040
v2 trust edges~473,000
Cost to add a node~2 days of CRC
Documents / biometrics requirednone
The FAQ's “one human, one
account” is a norm, not an invariant — enforced by the team's discretion, with
no technical mechanism in the contract. There is on-chain evidence of a
5,000-account farm run by a single maintainer.
So we do not score the boolean. The signal is position in the trust graph,
and the
whitepaper
supplies the right metric itself: max-flow to a seed set. That is a traversal over a
large event history — a question about relationships, not a storage slot — which is
precisely why an indexer is load-bearing here and an eth_call is not.
Case 03 — World, and the market that shouldn't exist
An Orb enrolment costs an adversary about fifty cents to rent and hundreds
of dollars to forge. We score the fifty. Every protocol that hardened, hardened
against sale — user-presence checks, identity staking — and none against
rental, because the human stays willing.
There is a counter-intuitive lesson buried in the credential black markets that
followed World's 2023 launch: a protocol with no observable credential
market may be further along the corruption curve, not safer. Idena beat trading, and
the displaced demand reappeared as puppeteering. Hardening one channel
prices the adjacent channel in.
“Illicit account trading in protocols should not be treated as evidence of advanced
mechanisms or protections; to the contrary, illicit trading may signal a lack of
them and be a precursor to puppeteering.”
Ohlhaver, Nikulin & Berman — Compressed to 0 (2024)
Instrument 02
Why age cuts both ways
Most scorers decay every credential uniformly. That is wrong for vouching registries,
and wrong in the attacker's favour. Proof of Humanity took roughly 95% of its lifetime
registrations inside a four-month airdrop window — so there, the fresh cohort
is the suspect one. Drag the age and watch two curves disagree.
One consequence worth stating: when we cannot learn a credential's age, a Ramp
credential is held at the 0.5 midpoint and never granted full weight. Otherwise an
attacker profits from making our indexer unreachable.
Lineage
The argument we are standing on, including where it cuts against us
Puja Ohlhaver's corpus is three papers in four years, and each is load-bearing. In
2022 she was first author on Decentralized Society, which proposed discounting
the votes of participants whose credentials correlate — without deciding
whether they are colluding:
“A vote supported by many Souls who all share the same SBT(s) is more likely to be a
Sybil attack and — even if not a Sybil attack — such a vote is more likely to be a
group of Souls who are making the same error in judgment or who share the same bias.”
Ohlhaver, Weyl & Buterin — Decentralized Society (2022), §4.5
That move is the ancestor of our saturation rule, and it is why we never try to
classify anyone. Fraud and shared bias do the same damage, so they get the same
treatment. The appendix's pairwise formula bounds an attacker's gain at
M(N² − N) without requiring you to correctly identify who is colluding —
which is precisely our epistemic situation.
Two years later she audited her own proposal against Idena's wreckage and found the
load-bearing assumption false: non-transferability cannot be enforced when the
human is willing. And in 2025 she wrote the sentence that does the most damage
to a product like ours:
“Ironically, whereas global sybil resistance makes participants the same and reduces
the cost of influence, the pursuit of local sybil resistance makes participants more
unique, raising the cost of influence.”
Ohlhaver — Community Currencies (2025), p.27
We have no rebuttal to that, and we are not going to pretend to one. If a universal
credential standardises people, and standardised things are cheaper to buy in bulk,
then aggregating credentials into one number is a step in the wrong direction — and her
answer is locality: one person cannot physically show up as two. That is a
property a global, remote, API-mediated aggregator structurally cannot have.
What we take from it is a boundary rather than a defence. We refuse to be the party
that holds the join key, we publish a threshold-free API so no one inherits our
judgment as a default, and we carry a permanent caveat saying no protocol here proves a
human acts for themselves. Her critique is the reason those three choices are
load-bearing rather than decorative.
One encouraging note from the same lineage: correlation discounting is not theoretical.
Gitcoin's
Connection-Oriented Cluster Matching
is a direct descendant of that 2022 appendix, live across 20+ rounds and $5.5M+ of
real money. Its worked example of a caught attack — wallets with identical donation
amounts and near-simultaneous creation dates — is the same co-movement
signature Ohlhaver found on Idena, discovered independently, on a different chain,
against a different attack.
The reading list
Primary sources, deep-linked. Where a paper has a free PDF we link that too, because
a paywall is a bad reason to lose an argument.
The empirical heart of this whole field. Idena filtered bots successfully and
was captured anyway, by puppeteers renting verified humans. Read §IV.D for the
“silent strings” argument — inference from the absence of the artefacts
an accountable custody market would have produced. Note the authors' own
disclosure: two of three hold IDNA, and the findings are unflattering to Idena.
Puja Ohlhaver, E. Glen Weyl, Vitalik Buterin — Ohlhaver is first author
Remembered for soulbound tokens; the part that matters is §4.5 and Appendix A —
correlation-discounted governance and the pairwise matching formula. Also §4.3,
where identity is the intersection of groups and a credential is made unsellable
by rooting it in relationships that cannot themselves be transferred.
Her most recent paper, and not a personhood paper at all — which is the point.
Contains the strongest argument against what we are building (p.27), plus a neat
unification: a plain airdrop and a soulbound token are the two endpoints of one
dial. Names our exact attack surface as “account splitting.”
Where she applies correlation discounting to identity directly — “followers with
similar behavior are grouped as the same entity” — and warns that no single actor
should have totalistic access to a feed. An aggregator with cross-protocol
visibility is exactly the actor being warned about. Worth reading as a
specification of what we must not become.
Why credential rental is structural rather than incidental. Pair it with
Complete Knowledge,
which proves unencumbered key access — and with Ohlhaver's objection that a
puppeteer holding the key produces a perfectly valid proof. Cryptography binds a
key to access, never a key to a person.
§4.2–4.3 formalise the trust graph and give the attack-resistant metric —
max-flow to a seed set — that the boolean “is registered” throws away. A protocol
supplying the correct way to read it is rarer than it should be.
Our own working notes — protocol-by-protocol, with what we could and could not verify,
and every claim date-stamped — live in research/ in the repository. Where
a source contradicted a project's own marketing, the notes say so and side with the
contract.
ETHGlobal Lisbon · 2026
Built in Lisbon, over one weekend
Every line of this was written at ETHGlobal Lisbon 2026 — the contracts, the
subgraphs, the SDK, the MCP server, the agent flow. It is a hackathon project and
we will not pretend otherwise.
But the problem is not a hackathon problem. Proof of personhood is being wired into
airdrops, governance and agent permissions right now, and almost every deployed
scorer adds credentials together — which means a sybil farm holding one passport
read by four protocols outranks a real person holding four unrelated ones. That
failure is live, it is in production, and it fails in the attacker's favour. We
think it is worth getting right in public, with the weights on-chain and the sources
attached, whatever happens to us on Sunday.
The azulejo tilework and the calçada wave in these pages are drawn, not
photographed — like the fingerprint they sit beside.
The three sponsors we are submitting to
Three is the limit, and we chose the three whose products are load-bearing here — take
any one of them out and this stops working, rather than losing a feature.
World
AgentKit — New Use Cases
A counterparty that refuses to trade with an agent unless a real human stands
behind it — and refuses the second agent backed by that same human.
Why we qualify
AgentKit runs on both sides of the flow, not as a decorative import: the agent
uses createAgentkitClient, the counterparty is a real AgentKit
resource server, and the full handshake executes live — request, HTTP 402, a
signed CAIP-122 challenge, retry. Human backing is then read from AgentBook.
Three agents, three outcomes: unregistered is denied, human-backed with
independent evidence is allowed, and a third is denied
because it is registered to the same human as the second. A
fleet of agents is still one person.
Why World is load-bearing
AgentBook is the only permissionless read of Orb-verified personhood that
exists. lookupHuman is a plain eth_call — no API key,
no relying-party registration, no user interaction, nothing that can rate-limit
us or be switched off. That is the whole reason World is in our roster: we can
read it without World's cooperation, which is the constraint every adapter here
has to satisfy.
What we do not claim
We prove a human exists behind the agent. We do not prove that human controls
it — on-chain, puppeteering and voluntary delegation are the same signature. No
protocol can do this today, so we ship it as a permanent caveat on every result
instead of quietly implying otherwise.
The Graph
Best AI Tooling for The Graph
Also a direct fit for Best Use of Composable or Standardized Graph
Products — we compose two Graph products across four chains.
Reusable personhood infrastructure any agent can call: an MCP server, a typed
SDK, and subgraphs that answer the questions a contract call cannot.
Why we qualify
An MCP server with four tools — look up a subject, test a threshold, explain the
trust roots, audit any weight's full history — so an agent can reason about
personhood conversationally, over live chain data. Underneath it, an
open-source SDK anyone can install. Two Graph products in one stack: a protocol
subgraph on Subgraph Studio, and a self-hosted graph-node indexing
our own registry.
Why an indexer, and not just an RPC
Three questions an eth_call cannot answer, all of which change the
score. When was this credential issued — a contract boolean has
no timestamp, and for a registry where roughly 95% of lifetime registrations
arrived in one four-month airdrop window, age is the signal.
Where does this account sit in a trust graph — a traversal over
a large event history, not a storage slot. And what did it look like
then — the history that lets us re-score a subject by the rules as they
stood at a past block.
Circles: the clearest case for indexing
Circles registration on its own is close to worthless as evidence of personhood.
A sybil costs about two days of freely-minted CRC, and the project's own public
indexer carries event namespaces named BotCreated and
FarmGrown — the farms are not hypothetical, they are a documented
schema. So the boolean "is registered" tells you almost nothing. What carries
signal is position in the trust graph: who vouched for this account, how
long ago, and how far the edges reach. That is a question about a large volume of
historical events and their relationships — exactly and only what an indexer can
answer. Circles is where The Graph stops being convenience and becomes the
difference between a number that means something and a number that does not.
Accountability, as a query
Our weights are curated human judgments, so the least a subject is owed is the
full history of those judgments. Every registry mutation emits an immutable
record with its source URI, block and transaction. "Why did my score change?" is
a GraphQL query with a block number in the answer.
ENS
Best ENS Integration for AI Agents
Also submitted against Most Creative Use of ENS, if the sponsor reads it
that way.
An ENS name is where an agent declares which human stands behind it — and where a
human declares which wallets are theirs.
Why we qualify
Agent identity and discoverability, resolved rather than configured. A
counterparty is handed an agent's ENS name, resolves the records that name the
backing human, and checks that human's personhood before agreeing to anything —
no registry of ours, no API, no allowlist. The same mechanism serves people: the
corroborate.subjects text record lets someone declare their own set
of wallets, and the SDK reads it live from any name.
Why ENS is load-bearing
Real people are plural. Proof of Humanity's own Circles proxy puts a person's PoH
registration on one address and their Circles avatar on another, so a
single-address lookup systematically undercounts actual humans while
undercounting no farms at all. Fixing that needs somewhere a person can say
"these wallets are mine" that is user-controlled, on-chain, revocable, readable
by anyone, and hosted by nobody. ENS is the only thing that is all five. The
alternative is a server of ours holding the mapping — which is precisely the
correlation this entire design exists to avoid.
What we do not claim
The record is self-asserted. A name owner can list any address they like and the
listed addresses have not countersigned, so every result built from one carries a
caveat saying exactly that. Correlated credentials still saturate across
the declared set, so listing more wallets cannot inflate a score.
What is finished, and what is not
Working and live: the registry contract, eighteen credential probes reading fourteen
chains — from World Chain, Gnosis and Base to Celo, BNB, Lens Chain, IDChain,
Humanode and Idena (plus Sepolia for the registry itself), both
subgraphs, the SDK, the MCP server, the agent flow, this page, and a test suite that
runs against real chains rather than mocks. Honest gaps: eighteen probes against thirty-two
catalogued adapters, so most of the ontology is priced but not yet readable; the
weights are judgments rather than measurements; and no amount of this proves the
human behind a credential is acting for themselves.
None of that is hidden in a footnote. It is in the API — as caveats you have to
receive before you get a verdict, and a isHuman(threshold) that throws
unless you choose the threshold yourself.