The on-chain admission layer for tokenized RWA collateral. Before a lending protocol accepts a tokenized stock or RWA as collateral, Collateral Passport answers one question on-chain — is this asset eligible, attested by a trusted party, fresh, and not already pledged? — and returns a deterministic Allow / Deny / ConditionalAllow. Live on Robinhood Chain testnet.
What it is
Collateral Passport is the on-chain admission layer that lets lending protocols safely accept tokenized real-world-asset
(RWA) collateral. It does not produce compliance decisions, originate market data, or score risk — it records what regulated attestors sign and enforces it on chain.
The problem
Tokenized RWA collateral (e.g. xStocks) is arriving on-chain, but lending protocols have no shared way to decide whether a specific asset is eligible, attested, unexpired, unrevoked, and not already pledged elsewhere. Today this is hardcoded allowlists + per-protocol risk params (e.g. Kamino accepting xStocks). That doesn't compose attestations, doesn't survive revocation or corporate actions, and can't see cross-protocol double-pledging.
How it works
An attestor signs a typed claim about an asset (EIP-712, EIP-1271 multisig supported). An integrator binds a per-integrator policy template to its address. When its vault calls checkAdmission(...), the template composes the claims + cross-protocol encumbrance + optional market signals and returns Allow / Deny / ConditionalAllow with a rationale code — deterministically, on chain.
What's live (Robinhood Chain testnet — primary)
- All core contracts deployed and source-verified on Robinhood Chain testnet (46630), mirrored on Arbitrum Sepolia (421614) as a portability proof.
- 7 reproducible demos run end-to-end against the live deployment.
- TypeScript SDK (viem), 3 live sites (landing / docs / demo console), subgraph, 186 passing tests (fuzz + invariants), Slither in CI.
The hero: value-aware admission + a real attestor trust model
- Value-aware policy (StandardAdmissionTemplateV2): a trusted attestor signing eligibility = Rejected is denied on-chain Deny:ClaimValueNotAllowed), not admitted on presence. Proven live demo6).
- Regulated-attestor trust model: the attestor is modeled as an EIP-1271 multisig MultisigAttestor) — a contract requiring multiple signers, like a regulated entity would use — not a single dev key. Proven live demo7): the multisig signs Rejected → deposit is denied on chain.
Why it's different (not just an allowlist)
- vs ERC-3643 / T-REX: those gate at the token (issuer-controlled permissioned token). We gate at the integrator's policy over shared claim + encumbrance state — different lending protocols can apply different policies to the same asset, and encumbrance is tracked across protocols.
- vs Chainlink ACE: ACE does identity/compliance attestation; it doesn't issue the gating decision or track encumbrance. We compose attestations into a decision + encumbrance.
Built from an empty repo during the buildathon: - 8 core Solidity contracts (PassportRegistry with EIP-712/EIP-1271, ClaimSchemaRegistry, AdmissionController, 3 policy templates, EncumbranceRegistry with invariant tests, PassportGuardedERC4626 adapter) + a value-aware **StandardAdmissionTemplateV2** and an **EIP-1271 MultisigAttestor**. - Deployed + **source-verified on Robinhood Chain testnet** (primary) and Arbitrum Sepolia (mirror). - TypeScript SDK (viem: PassportClient, simulateAdmission, EIP-712 signing, V2 config encoder), wagmi React hooks, subgraph. - 3 live sites (landing, docs, operator demo console), CI (Foundry + Slither + pnpm), **186 tests** incl. fuzz + invariants + an SDK↔Solidity ABI cross-check. - **7 end-to-end demos** on the live deployment, including the value-aware deny path and the EIP-1271 multisig-attestor flow. - SECURITY.md threat model + honest README aligned with the code.
Not actively raising. Testnet research preview, self-funded R&D. Open to design-partner / attestor-integration conversations.