OCP-0004: On-Chain Entity Registry

Abstract

This OCP extends the crown registry to non-token entity types. It adds two new SymbolType values (NFTCollection, Protocol), defines per-type verification method restrictions enforced on-chain, and establishes the Entity Type Requirements Matrix for future type additions.

Motivation

The Identity Gap

On-chain entities (protocols, NFT collections, DAOs, bridges) lack a standard for verified canonical identity. Each category is developing siloed standards (ERC-4824 for DAOs, ERC-8004 for AI agents) with no unifying layer. CAIP-19 provides asset addressing but not identity, metadata, or ownership verification.

Why OpenCrown

The crown system's architecture is already general-purpose — only the inputs are token-specific:

This OCP extends the registry to additional entity types using the existing storage and verification infrastructure.

Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

Spec 1: Entity Type Taxonomy

Expand the SymbolType enum to include new entity categories. Documentation SHOULD use "entity type" language going forward, while maintaining backwards compatibility in code by keeping the SymbolType name:

// Existing values (unchanged):
// 0: Native     — L1/L2 gas token
// 1: Token      — Fungible token (ERC-20, SPL)
// 2: Wrapped    — Canonical wrapped version
// 3: Bridged    — Cross-chain bridge version
// 4: Synthetic  — Derivative/synthetic asset

// New values introduced by this OCP:
// 5: NFTCollection  — NFT collection (ERC-721, ERC-1155)
// 6: Protocol       — Protocol or DAO identity

Backwards compatibility: The symbolType field is stored as uint8 in the Crown struct. No storage layout change. No upgrade to existing data. Values 0-4 continue to function identically. The SymbolType enum in the interface contract gains two new members.

Future expansion: Values 7-255 are reserved for future entity types. New entity types MAY be added via governance proposal under this framework's Requirements Matrix (Spec 4), without requiring a separate OCP. Only changes to the framework itself require a new OCP.

Spec 2: NFT Collection Crowns (EntityType 5)

What it represents: Verified ownership or stewardship of an NFT collection's identity. The crown is for the collection as a whole, NOT for individual NFTs within it.

Crown struct usage:

Field Usage
symbol Collection ticker/abbreviation (max 20 chars)
chainId Chain where the collection contract is deployed
tokenAddress The ERC-721 or ERC-1155 contract address
symbolType 5 (NFTCollection)

Allowed verification methods:

Method Value Rationale
Deployer 0 Wallet that deployed the collection contract
Owner 1 Ownable.owner() on the collection contract
MintAuthority 2 Program authority patterns relevant for Solana NFT collections
Foundation 3 Domain-verified organization attestation
Governance 4 DAO governance vote

Disallowed verification methods for NFTCollection:

Method Value Rationale
Majority 5 Majority holder verification is undefined for non-fungible collections

Heartbeat scoring methodology (off-chain keeper):

Score Component Weight Methodology
timestampScore 50% Identical to fungible tokens — time since last update
volumeScore 30% 30-day rolling on-chain activity: transfers, mints, and burns, normalized. NOT secondary market sales volume.
holderScore 20% Unique wallets holding 1+ items from the collection over 30-day rolling window

ERC-1155 gap: ERC-1155 contracts that host multiple distinct collections under a single contract address require a collection identifier to disambiguate which collection a crown represents. This capability is under active research and SHOULD be addressed in a future governance proposal. Until resolved, crowns for ERC-1155 contracts MUST represent the contract as a whole. Implementations SHOULD NOT mint NFTCollection crowns for multi-collection ERC-1155 contracts until the collection identifier mechanism is defined.

Anti-squatting: All existing mechanisms apply without modification.

Naming: Collection crowns resolve in the naming service identically to token crowns: collectionname.operator

Spec 3: Protocol Crowns (EntityType 6)

What it represents: Canonical verified identity for a protocol, DAO, or on-chain service. The crown establishes the entity's identity within the registry and naming service.

Crown struct usage:

Field Usage
symbol Protocol name/abbreviation (max 20 chars)
chainId Primary chain of the protocol (or chain where governance contract is deployed)
tokenAddress The protocol's canonical administrative entry point (see below)
symbolType 6 (Protocol)

Token address selection: tokenAddress MUST be set to the contract that serves as the protocol's canonical administrative entry point — specifically, the contract over which the claimant can demonstrate verified authority. This is typically the governance contract, admin multisig, or upgradeability proxy owner. When a protocol has multiple contracts, the claimant MUST specify the one whose ownership or control they can cryptographically prove. The verification proof MUST demonstrate authority over the specific address provided.

Allowed verification methods:

Method Value Rationale
Deployer 0 Wallet that deployed the protocol's primary contract
Owner 1 Ownable.owner() on the primary contract
Foundation 3 Domain-verified organization attestation
Governance 4 DAO governance vote (most appropriate for protocol crowns)

Disallowed verification methods for Protocol:

Method Value Rationale
MintAuthority 2 Token-specific infrastructure
Majority 5 Protocols have no supply

Heartbeat scoring methodology (off-chain keeper):

Score Component Weight Methodology
timestampScore 50% Identical — time since last update
volumeScore 30% 30-day rolling on-chain transaction/interaction count, normalized
holderScore 20% Unique interacting wallets over 30-day rolling window

Special case — Self-referential protocol crown:

The OpenCrown protocol itself MAY hold a Protocol crown on each chain where it is deployed. This crown:

During Phases 1-2 (per OCP-0002 Spec 7), the governance multisig mints and manages the protocol crown via PROTOCOL_ADMIN_ROLE.

Naming: Protocol crowns resolve identically: protocolname.operator

Spec 4: Entity Type Requirements Matrix

Each entity type MUST define the following:

Requirement Description
Allowed verification methods Which VerificationType values are valid for this entity type
Heartbeat scoring methodology How volumeScore and holderScore are computed by the off-chain keeper
Anti-squatting adaptations Any modifications to squatting protections, or confirmation that defaults apply
Naming conventions How the entity type integrates with the naming service
Scope boundaries What the crown represents and what it explicitly does NOT represent
Data source availability Confirmation that data sources exist (or can be built) to feed the heartbeat keeper for this entity type

Future governance proposals adding new entity types MUST include all six requirements. Proposals failing to address any requirement SHOULD be rejected during review. Changes to this framework itself (new requirements, modifications to the matrix) require a new OCP.

Spec 5: Governance Participation

All crown types participate in governance equally per OCP-0002. Governance eligibility is determined by heartbeat composite score (>= 40 = eligible to vote with weight 1.0), regardless of entity type. NFT Collection crowns and Protocol crowns have the same governance rights and weight as fungible token crowns.

Spec 6: Naming Collision Resolution

When multiple crowns share the same symbol across different entity types (e.g., a Token crown and a Protocol crown both using the same symbol), the naming service MUST resolve the bare name (symbol.operator) to the crown with the highest heartbeat composite score.

All crowns remain individually addressable by crown ID regardless of name resolution. Consumers requiring type-specific resolution SHOULD query by crown ID or filter by entity type via the API or SDK.

Scoped naming: Type-qualified names (e.g., symbol.type.operator) MAY be introduced via future governance proposal.

Contract Changes

This section describes the exact smart contract modifications required to implement this OCP. These changes would be presented in governance proposals for crown holder approval per OCP-0002.

Change 1: SymbolType Enum Extension

Contract: IOpenCrownRegistry.sol Type: Interface modification (additive)

// BEFORE (current):
enum SymbolType {
    Native,        // 0
    Token,         // 1
    Wrapped,       // 2
    Bridged,       // 3
    Synthetic      // 4
}

// AFTER (proposed):
enum SymbolType {
    Native,        // 0
    Token,         // 1
    Wrapped,       // 2
    Bridged,       // 3
    Synthetic,     // 4
    NFTCollection, // 5
    Protocol       // 6
}

Storage impact: None. The symbolType field in the Crown struct is already stored as uint8. Existing crowns with values 0-4 are unaffected.

ABI impact: The ABI changes to include new enum members. Consumers using raw uint8 values are unaffected. Consumers using enum names need updated ABIs.

Change 2: Verification Method Validation

Contract: OpenCrownRegistry.sol Type: Logic modification in mintCrown()

Add validation that restricts verification methods by entity type:

// New internal function:
function _isValidVerificationForType(
    uint8 symbolType,
    uint8 verificationMethod
) internal pure returns (bool) {
    // Types 0-4 (fungible): all verification methods allowed (backwards compatible)
    if (symbolType <= 4) return true;

    // Type 5 (NFTCollection): all methods except Majority
    if (symbolType == 5) {
        return verificationMethod != 5; // != Majority
    }

    // Type 6 (Protocol): all methods except MintAuthority and Majority
    if (symbolType == 6) {
        return verificationMethod != 2  // != MintAuthority
            && verificationMethod != 5; // != Majority
    }

    // Unknown types: reject until defined by governance proposal.
    return false;
}

Called from: mintCrown() — reverts with InvalidVerificationForType(symbolType, verificationMethod) if validation fails.

Storage impact: None. Pure function, no state changes.

Change 3: New Error Type

Contract: IOpenCrownRegistry.sol Type: Interface addition

error InvalidVerificationForType(uint8 symbolType, uint8 verificationMethod);

Change 4: New Event for Entity Type Tracking

Contract: IOpenCrownRegistry.sol Type: Interface addition

// Emitted alongside CrownMinted when symbolType >= 5
event EntityCrownMinted(
    uint256 indexed tokenId,
    uint8 indexed symbolType,
    string symbol,
    uint64 chainId,
    address tokenAddress
);

Implementations MUST emit EntityCrownMinted alongside CrownMinted when symbolType >= 5.

Rationale: While CrownMinted already includes all data, a separate indexed event by symbolType makes it efficient for indexers to filter entity-type crowns without scanning all crown events.

Summary of Changes

Change Contract Type Storage Impact Breaking?
SymbolType enum extension IOpenCrownRegistry Additive None No (uint8)
Verification validation OpenCrownRegistry Logic None No
New error type IOpenCrownRegistry Additive None No
Entity event IOpenCrownRegistry Additive None No

Upgrade path: Standard UUPS proxy upgrade. No storage migration required. All changes are additive or logic-only.

Rationale

Why Not Rename SymbolType to EntityType in Code

Backwards compatibility. External integrations, SDKs, indexers, and documentation all reference SymbolType. Renaming in code creates a breaking change with no functional benefit. Documentation and specifications SHOULD use "entity type" language going forward, with a note that the code-level name remains SymbolType.

Why NFT Collections But Not Individual NFTs

Crowns represent entity-level identity, not asset-level identity. An NFT collection is an entity (with a deployer, a community, a brand). An individual NFT is an asset within that entity. Registering individual NFTs would create massive squatting risk, minimal revenue upside, and scope creep toward marketplace functionality.

Why Verification Validation Is On-Chain

On-chain enforcement prevents operators from bypassing per-type verification restrictions. Off-chain validation would rely on operator integrity.

Why All Crown Types Have Equal Governance Weight

The heartbeat score already captures whether an entity is active and well-maintained. Introducing separate governance pools or type-weighted voting adds complexity without clear benefit — a healthy NFT collection crown and a healthy token crown both represent verified, active entities with equal stake in the registry's governance. Simplicity prevents governance gaming through type manipulation.

Why Heartbeat Uses Activity Not Sales

For non-fungible entity types (NFT collections, protocols), heartbeat scoring uses on-chain activity (transfers, mints, interactions) rather than secondary market sales volume. Sales volume is a marketplace metric that measures speculative interest. Activity measures genuine usage — the signal that matters for identity health. This also avoids dependency on off-chain marketplace data sources that may be unreliable or manipulable.

Why Entity Relationships Are Off-Chain First

On-chain relationships are expensive to store, hard to update, and create complex dependency graphs. Starting with off-chain (IPFS metadata + indexer) relationships allows the community to discover which relationships are actually valuable before committing to on-chain storage. The pattern follows the crown metadata model: content-addressed, owner-controlled, indexer-derived.

Backwards Compatibility

This OCP introduces no backwards incompatibilities:

SDKs and indexers will need updates to recognize the new types, but unrecognized types already fall through gracefully (stored as raw uint8).

Security Considerations

Entity Type Validation

The _isValidVerificationForType function prevents minting crowns with inappropriate verification methods. For example, "Majority Holder" verification for an NFT collection could allow a whale to claim a crown that should belong to the collection creator. Restricting methods per type mitigates this.

Squatting on Protocol Names

Protocol names are higher-value targets than token names. The existing anti-squatting mechanisms (verification requirement, heartbeat decay, escalating fees) provide baseline protection. Additionally, protocol crowns typically require Governance verification (a DAO vote), which is the highest-friction verification method and the hardest to fake.

Naming Collision

When multiple entity types claim the same symbol, heartbeat-based resolution determines the bare name winner. This creates an incentive to maintain crown health, which is the desired behavior. Potential gaming (artificially inflating heartbeat to steal a name) is mitigated by the same anti-manipulation measures that protect heartbeat integrity for all crown types.

Future Entity Type Risk

New entity types introduced through future governance proposals could have unanticipated interactions with existing mechanisms. The Entity Type Requirements Matrix (Spec 4) ensures every new type explicitly addresses verification, heartbeat, anti-squatting, naming, scope, and data source availability — preventing under-specified types from entering the system.

Implementation Considerations

Off-Chain Keeper Changes

The heartbeat keeper requires new data source integrations:

These are keeper-side changes and do not affect the on-chain contracts.

SDK Updates

The SDK's SymbolType type union needs two new members: 'nft_collection' and 'protocol'. The VerificationMethod type MAY need filtering helpers per entity type. These are additive, non-breaking changes.

Operator UX

Reference operators will need adapted UI for NFT collection and protocol crown profiles — different display layouts, different metadata fields, different heartbeat visualizations. This is operator-level work outside the scope of this OCP.

Solana Program

The Solana program (programs/opencrown/) requires equivalent changes:

Future Direction: Entity Relationships

This OCP establishes entity identity. A natural next step is entity relationships — formal links between crowns that capture how entities relate to each other:

Relationship Description
issuedBy This token/collection was created by this protocol (linked by crown IDs)
governedBy This protocol is governed by this DAO (linked by crown IDs)
bridgedFrom This bridged asset originates from this native asset (already partially captured by SymbolType 3)

Entity relationships are NOT specified by this OCP. They SHOULD be recorded in crown metadata (IPFS) and indexed off-chain until the community identifies which relationships are valuable enough to warrant on-chain storage. A future governance proposal or OCP MAY formalize on-chain relationship primitives.

Copyright and related rights waived via CC0.