Verity Protocol
Contracts & networks

Contracts & addresses

Verity Protocol runs on four live smart contracts today, all deployed on Robinhood Chain mainnet. The two anchor contracts (V1 + V2) are unowned aside from a baseTokenURI admin on V2; both have no fees and no upgrade path. The Portal factory + yield distributor are permissionless.

VerityAssetRegistrationV2 · current

The main registration entry point. Called by every new registrant's wallet. The tx anchors the claim and mints the ERC-721 Verity Asset NFT in one call.

Methods

function recordAndMint(bytes32 assetId, bytes32 payloadHash) external
function tokenURI(uint256 tokenId) external view returns (string)
function ownerOf(uint256 tokenId) external view returns (address)
function registrationHashOf(bytes32 assetId) external view returns (bytes32)
function registrantOf(bytes32 assetId) external view returns (address)
function safeTransferFrom(address from, address to, uint256 tokenId) external

Events

event RegistrationAnchored(
    bytes32 indexed assetId,
    bytes32 indexed payloadHash,
    address indexed registrant,
    uint256 timestamp
)
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)
tokenId = uint256(assetId)

Every registration mints a token whose id equals the uint256-cast of the asset's bytes32 id. So ownerOf(uint256(assetId)) is always the current holder of the underlying asset claim.

VerityRegistrationAnchor · legacy V1

The pre-NFT anchor contract. Still live and read-compatible for assets registered before the V2 rollout. New registrations use V2.

Methods

function recordRegistration(bytes32 assetId, bytes32 payloadHash) external
function isRegistered(bytes32 assetId) external view returns (bool)
function registrationHashOf(bytes32 assetId) external view returns (bytes32)
function registrantOf(bytes32 assetId) external view returns (address)
function totalRegistrations() external view returns (uint256)

Event

event RegistrationAnchored(
    bytes32 indexed assetId,
    bytes32 indexed payloadHash,
    address indexed registrant,
    uint256 timestamp
)

Encoding conventions

Off-chain code (the register form and server) computes these deterministically:

// UUID → bytes32: strip dashes, right-pad to 32 bytes
assetId     = "0x" + uuid.replace(/-/g, "") + "0".repeat(32)

// keccak of the canonical registration message text
payloadHash = keccak256(utf8(canonicalRegistrationMessage))
Uniqueness enforced on-chain

recordRegistration reverts with ALREADY_REGISTERED if the assetId already has a non-zero payloadHash. The same UUID cannot be anchored twice.

VerityAnchor

The transfer anchor. Records (assetId → transferHash) for accepted claim transfers, so the chain of custody can be reproduced from the two parties' signatures without trusting our database.

  • Called optionally by either party after a transfer is accepted.
  • Method: recordTransfer(bytes32 assetId, bytes32 transferHash)
  • Reader: transferHashes(bytes32 assetId) returns the full array of anchored hashes.

VerityPortalFactory

The launchpad. Deploys a new ERC-20 backed by a registered asset, spins up a Uniswap V3 pool paired against native ETH, seeds initial liquidity, and locks the LP position.

VerityYieldDistributor

Merkle-drop distributor for asset-backed yield. Token creators deposit ETH and publish a Merkle root over holder balances at a snapshot block; holders claim by presenting a proof. See Yield distribution.

Full source for all contracts lives in the repo under contracts/. The compiled artifacts are bundled into the frontend so you can call these directly from any wallet interface.