Docs·Metrics reference
Metrics reference
Holders
The on-chain census, what it excludes, why an uncounted token is unknown rather than zero, and the log-derived fallback.
holders — the counted census#
| unit | count |
|---|---|
| derivation | HolderCensus.verifiedHolders(token) → (uint32 holders, uint256 countedSupply, uint256 totalSupply, uint64 countedAt) |
| source | contracts/src/predict/HolderCensus.sol |
| freshness | countedAt and Census.countedAtBlock. Publish both. |
| coverage | FULL when countedAt != 0 |
A holder is counted when its balance is at least Census.floor — floorBps of supply at the census’s opening, 1 bp (0.01%) by default — and it is not excluded. Balances are re-read during the sweep, so a submitted address that has since sold does not count. The sweep is atomic by design; a paged sweep was an audit finding and is gone.
What a census excludes#
| Excluded | countability() answers |
|---|---|
address(0), and any address holding nothing | "zero" |
0x…dEaD | "burn" |
| An owner-set global exclusion — venue and locker contracts | "global" |
| A per-token exclusion | "token" |
The token itself, its BondingCurve and that curve’s graduationAdapter() are excluded too. HolderCensus.countability(token, account) answers why in one word, which is what a published exclusion list should be built from rather than a reimplementation of the rule.
Caveats#
| Caveat | Detail |
|---|---|
countedAt == 0 means unknown, not zero | Publish null with coverage: "PARTIAL" and a scope saying no census has completed. Rendering it as 0 holders states a fact nobody measured. |
There is no MAX_CENSUS_AGE | It does not exist in any contract. The census carries no age bound at all, so the consumer decides what is too old — which is why countedAt must be published beside every count. |
| Nothing settles on the census | The settlement registry does not read HolderCensus. It is a standalone published metric, and a currency listing that uses a holder bar checks it separately. |
holdersDerived — the fallback#
| unit | count |
|---|---|
| derivation | Balances rebuilt from ERC-20 Transfer logs on the token, applying the same exclusion list |
| source | The token’s own Transfer logs |
| freshness | Indexed. Carries asOfBlock. |
| coverage | Always PARTIAL, with scope: "derived from Transfer logs from block N; not a HolderCensus sweep" |
The two are never mixed in one figure. A census is a set of addresses the chain checked against a floor at one instant; a log-derived count is a reconstruction that applies the same rule to a different data source. Presenting them as the same field would make a token’s holder count change meaning depending on whether anyone had run a sweep. See trust model on why neither is sybil-proof.