Architecture
The 11-layer architecture of the Integra protocol, key design patterns, and how the contract system composes.
The Integra protocol is an 11-layer smart contract system for on-chain record identity. Each layer has a single responsibility and communicates with adjacent layers through immutable contract references set at deployment. Every contract is deployed once and is immutable -- no proxy patterns, no upgradeability.
The 11 Layers
Layer 1: Core
The foundation. Four contracts that have zero protocol dependencies. Every other layer depends on at least one core contract.
IntegraExistenceV1 -- A minimal, write-once registry for content hash proof-of-existence. Permissionless (any address can register), write-once (subsequent registrations revert), and has no admin functions. Supports batch registration.
function register(bytes32 contentHash) external returns (uint64 timestamp);
function exists(bytes32 contentHash) external view returns (bool);CapabilityNamespaceV1 -- A permanent definition of capability bit positions in a 256-bit namespace. Deployed once per chain. All contracts that check capabilities reference these same bit positions, ensuring consistent permission semantics across the entire protocol.
| Bits | Tier | Examples |
|---|---|---|
| 0--7 | Core | CORE_VIEW, CORE_CLAIM, CORE_TRANSFER, CORE_UPDATE, CORE_ADMIN |
| 8--15 | Record Operations | DOC_SIGN, DOC_WITNESS, DOC_NOTARIZE, DOC_VERIFY, DOC_AMEND |
| 16--23 | Financial | FIN_REQUEST_PAYMENT, FIN_APPROVE_PAYMENT, FIN_EXECUTE_PAYMENT |
| 24--31 | Governance | GOV_PROPOSE, GOV_VOTE, GOV_EXECUTE, GOV_VETO |
| 32--255 | Reserved | Future protocol extensions |
IntegraRegistryV1 -- A permissionless component registry. Any address can register a provider, verifier, resolver, tokenizer, or policy contract by paying a fee. Publishers retain control over their records. The registry captures extcodehash at registration time and validates it on every lookup -- if a registered contract is upgraded via proxy, it is silently treated as invalid.
IntegraLedgerV1 -- An on-chain directory of all Integra protocol contracts on a given chain. Supports both bytes32 key lookups (gas-efficient) and human-readable string name lookups. Keys are append-only.
Layer 2: Access Control
Attestation-gated capability verification.
AttestationAccessControlV1 (abstract) -- The base contract that all tokenizers and extensions inherit. Gates operations behind attestation-verified capabilities. Holds immutable references to CapabilityNamespaceV1 and IntegraRegistryV1. Implements progressive ossification and a custom transient storage reentrancy guard.
EASAttestationProviderV1 -- The reference IAttestationProvider implementation backed by the Ethereum Attestation Service. Performs a 13-step verification pipeline including cross-chain replay prevention, schema version validation, attestation expiration checks, issuer authorization, and capability bitmask extraction.
Layer 3: Records
The central contract of the protocol.
IntegraRecordV1 -- Manages record ownership, metadata, tokenizer associations, resolver bindings, policy resolver attachment, and executor authorization. Each record is identified by a globally unique integraHash (bytes32). Registration is a multi-step atomic operation: ensure existence, collect fee, validate inputs, create record, authorize executor, emit events, invoke resolver hooks.
Key features:
- Per-record executor delegation for gasless workflows
- Up to 10 resolvers per record with lifecycle hook notifications
- Per-record transfer policy resolver, validated against
IntegraRegistryV1 - Resolver locking (once locked, resolver configuration is immutable)
- ZK-verified parent references via Groth16 proofs
function register(RegistrationParams calldata params, ProofData calldata proof)
external payable returns (bytes32);
function setPolicyResolver(bytes32 integraHash, address policyAddress) external;Layer 4: Execution
Gas abstraction for end users.
IntegraExecutorV1 -- Enables relayers to execute whitelisted operations on behalf of users. Implements nonce-based replay protection and target+selector pair whitelisting.
IntegraForwarder -- A thin wrapper over OpenZeppelin's ERC2771Forwarder. Serves as the single trusted forwarder for all ERC-2771-compatible contracts. Users sign EIP-712 typed data off-chain; relayers submit the signed request; the target contract extracts the real sender via _msgSender().
Layer 5: Messaging
Token-to-token communication.
IntegraSignalV1 -- Encrypted payment request messaging between token holders. Hybrid encryption (both requestor and payer can decrypt). Configurable timeouts (7--365 days). Three lifecycle states: PENDING, PAID, CANCELLED.
IntegraMessageV1 -- Event-sourced messaging for workflow events. Uses Poseidon hashes for ID generation. Requires ZK proofs for anti-spam protection. No state stored on-chain -- all data is emitted as events for off-chain indexing.
Layer 6: Extensions
Composable building blocks for domain-specific record logic. Extensions compose small, purpose-built building blocks via Solidity inheritance, keeping each component focused and auditable. 14 contracts organized in a strict 3-tier hierarchy.
Tier 1 -- Base + Building Blocks:
RecordExtension-- abstract base withIContractV2, auth helpers, IntegraRecord bridge, transfer policy bridgeCustodyChain-- physical custody transfer trackingDataCommitment-- hash commitment and encrypted blob storageFundsCustody-- ETH and ERC-20 fund escrowPaymentLedger-- payment obligation tracking
Tier 2 -- Token Bindings + Diamond Resolvers:
TokenBinding721,TokenBinding1155,TokenBinding20-- implementITokenizerV1lifecycle for each ERC standardTokenizedExtension721,TokenizedExtension1155,TokenizedExtension20-- resolve Solidity diamond inheritance betweenRecordExtensionandTokenBinding*
Tier 3 -- Concrete Extensions:
OwnershipExtension-- simplest concrete extension, ERC-721 ownership proofEscrowExtension-- full escrow lifecycle withDataCommitment+FundsCustodyApprovalExtension-- multi-party document approval workflow
Layer 7: Lens
Stateless view composition.
IntegraLens -- A stateless, permissionless view contract that composes IContractV2 responses from every contract attached to a record -- tokenizer, policy resolver, and resolvers -- into a single RecordView struct. One off-chain eth_call returns the complete state, all available actions with routing information, and transfer policy status.
IntegraLens holds no state of its own. All IContractV2 calls are wrapped in try/catch for fault tolerance -- if a contract does not implement IContractV2 or reverts, the Lens gracefully returns empty state for that source.
function getRecordView(bytes32 integraHash, address caller)
external view returns (RecordView memory);Layer 8: Policy
Pluggable transfer restrictions for tokenized records. When a token is transferred peer-to-peer (not minted or burned), the tokenizer's _update hook calls the policy resolver to check whether the transfer is allowed, with a 100,000 gas cap.
The ITransferPolicy interface follows the ERC-1404 pattern:
function checkTransfer(bytes32 integraHash, address from, address to, uint256 amount) external view;
function detectTransferRestriction(bytes32 integraHash, address from, address to, uint256 amount)
external view returns (uint8);
function messageForTransferRestriction(uint8 restrictionCode)
external pure returns (string memory);AttestationTransferPolicy -- Requires parties to hold valid CORE_TRANSFER attestations via EAS, with bilateral and recipient-only modes. Implements IContractV2 for Lens visibility.
TransitionPolicy -- Temporary policy for graceful migration between policy resolvers with a deadline-based grace period. Immutable parameters, no admin functions.
Layer 9: Interfaces
Four interfaces that provide universal introspection across the protocol.
| Interface | Functions | Purpose |
|---|---|---|
IContractV2 | getRecordState, getAvailableActions, stateSchema | Universal state and action discovery for any contract |
ITokenParty | isTokenHolder | Cross-standard token holder detection |
ITokenizerV2 | ITokenizerV1 + IContractV2 | Composed interface for v1.7 tokenizers |
IResolverV2 | IResolver + IContractV2 | Composed interface for v1.7 resolvers |
IContractV2 is implemented by all tokenizers, both concrete resolvers, all extensions, and AttestationTransferPolicy. ITokenParty is implemented by all tokenizers via BaseTokenizerV1, providing a single cross-standard query for token holder detection without knowing which token standard the tokenizer uses.
Layer 10: Tokenizers
23 concrete token contracts representing record rights.
| Standard | Contracts | Description |
|---|---|---|
| ERC-721 | OwnershipTokenizerV1, DebtTokenizerV1, EscrowTokenizerV1, InsuranceTokenizerV1, InvoiceTokenizerV1, OptionsTokenizerV1, SupplyChainTokenizerV1, VaultTokenizerV1 | One token per record, transferable |
| Soulbound ERC-721 | SoulboundTokenizerV1, LicenseTokenizerV1, MembershipTokenizerV1 | One token per record, non-transferable |
| ERC-1155 | AgreementTokenizerV1, BadgeTokenizerV1, MultiPartyTokenizerV1, RentalTokenizerV1, RoyaltyTokenizerV1, SemiFungibleTokenizerV1, TrustTokenizerV1 | Multiple tokens per record |
| ERC-20 | FractionalTokenizerV1, GovernanceTokenizerV1, SecurityTokenTokenizerV1, SharesTokenizerV1, StreamTokenizerV1 | Fungible shares per record |
All tokenizers implement IContractV2 for universal state/action discovery and ITokenParty for cross-standard token holder detection.
All tokenizers inherit AttestationAccessControlV1 and hold an immutable reference to IntegraRecordV1. Every tokenizer validates that it is the registered tokenizer for a record before allowing any operation. Transfer policy enforcement is built into all token-standard base contracts via ITransferPolicy.checkTransfer() with a 100,000 gas cap.
Layer 11: Resolvers
Pluggable on-chain logic modules that attach to records. Each record can bind up to 10 resolvers. All resolvers inherit directly from BaseResolver, which provides ERC2771 meta-transaction support, AccessControl, Pausable, ReentrancyGuard, and the _isRecordParty() helper for party detection across owner, executor, and token holder (via ITokenParty).
Two concrete resolvers:
-
ADRResolverV3 -- Alternative Dispute Resolution. A multi-category resolver (Behavioral + Gatekeeper + Automation) implementing a full arbitration lifecycle: arbitration clause anchoring, 11-state dispute state machine, evidence via hash anchors, multi-party settlement, deadline management, automated triggers, and EAS attestation integration. Implements
IContractV2. -
AAAResolverV1 -- Agreement-bound dispute resolution. Structurally similar to ADRResolverV3 but replaces the
ArbitrationClauseprerequisite with agreement binding viaAgreementTokenizerV1. Disputes can be initiated when all three agreement tokens are claimed. Introduces the "commercial party" concept for settlement access control. ImplementsIContractV2.
How Layers Compose
The contract dependency graph is a directed acyclic graph (DAG). Dependencies flow strictly downward:
Layer 11 (Resolvers) → Layer 3 (Records)
Layer 10 (Tokenizers) → Layer 3 (Records), Layer 2 (Access Control)
Layer 9 (Interfaces) → (pure interfaces, no dependencies)
Layer 8 (Policy) → Layer 3 (Records), Layer 2 (Access Control)
Layer 7 (Lens) → Layer 3 (Records), Layer 1 (Core Registries)
Layer 6 (Extensions) → Layer 3 (Records), Layer 2 (Access Control)
Layer 5 (Messaging) → Layer 3 (Records)
Layer 4 (Execution) → targets any contract (via whitelist)
Layer 3 (Records) → Layer 1 (Existence), Layer 1 (Registries)
Layer 2 (Access Control)→ Layer 1 (Capabilities), Layer 1 (Registries)
Layer 1 (Core) → nothing (standalone)Key dependency rules:
- No circular dependencies. The graph is strictly acyclic.
- Lower layers never import upper layers. Core contracts have zero protocol imports.
- Immutable references flow downward. Tokenizers reference
IntegraRecordV1;IntegraRecordV1referencesIntegraExistenceV1andIntegraRegistryV1; never the reverse. - Resolvers reference
IntegraRecordV1only for owner/executor lookups. They do not import tokenizers or access control contracts. - Lens composes without coupling.
IntegraLenscallsIContractV2on tokenizers, resolvers, and policies but never imports their concrete types.
Key Design Patterns
Immutable References
All inter-contract references are set at construction time and stored as immutable state variables. There is no setRecord() or setRegistry() function that could redirect a contract to a malicious target.
// In BaseTokenizerV1
IntegraRecordV1 public immutable RECORD;
// In IntegraRecordV1
IntegraExistenceV1 public immutable EXISTENCE;
IntegraRegistryV1 public immutable REGISTRY;
// In IntegraLens
IntegraRecordV1 public immutable INTEGRA_RECORD;
IntegraRegistryV1 public immutable REGISTRY;The tradeoff: upgrading a referenced contract requires deploying a new version of the referencing contract. This is intentional -- it forces explicit migration rather than silent reference swaps.
Progressive Ossification
Governance evolves through four one-way stages:
BOOTSTRAP → MULTISIG → DAO → OSSIFIED| Stage | Controller | Purpose |
|---|---|---|
BOOTSTRAP | Team EOA | Rapid iteration during launch |
MULTISIG | Guardian multisig (e.g., 3-of-5) | Shared custody, reduced single-point risk |
DAO | On-chain governor (community) | Decentralized governance |
OSSIFIED | Permanently frozen | Governance model locked forever |
Transitions are one-way and require the current controller to initiate. Ossification freezes the governance model (who governs) but does not freeze operational management. The DAO retains the ability to rotate operator keys, update providers, and manage roles.
Zero-Trust Executor Access
Tokenizer operations use a zero-trust model:
- Owner -- always has full access to their records.
- Per-record executor -- a specific address authorized by the owner for a specific record.
- No one else -- there is no global admin, no protocol-wide operator, and no fallback that could bypass per-record authorization.
modifier requireOwnerOrExecutor(bytes32 integraHash) {
(address registeredTokenizer, address owner, address authorizedExecutor) =
RECORD.getAccessInfo(integraHash);
if (registeredTokenizer != address(this)) revert WrongTokenizer(...);
if (_msgSender() != owner && _msgSender() != authorizedExecutor)
revert Unauthorized(...);
_;
}IContractV2 Universal Introspection
All protocol contracts -- tokenizers, resolvers, extensions, and policy contracts -- implement three uniform functions:
getRecordState(integraHash)-- ABI-encoded domain state snapshotgetAvailableActions(integraHash, caller)-- function selectors the caller can invokestateSchema()-- schema identifier string for decoding state
This eliminates the need for per-contract adapters in the service layer. IntegraLens composes these responses into a single RecordView for off-chain consumption.
Capability Bitmask Access Control
Instead of coarse-grained roles, the protocol uses a 256-bit capability bitmask. Each bit represents a specific permission. Capabilities are composed, delegated, and verified through EAS attestations.
// Check: does this user have the CLAIM capability for this record?
if (!NAMESPACE.hasCapability(grantedCapabilities, requiredCapability)) {
revert NoCapability(user, contentHash, requiredCapability);
}Pre-composed role templates combine capabilities into common profiles:
ROLE_VIEWER = CORE_VIEW
ROLE_PARTICIPANT = CORE_VIEW | CORE_CLAIM | CORE_TRANSFER | FIN_REQUEST_PAYMENT
ROLE_MANAGER = ROLE_PARTICIPANT | CORE_UPDATE | FIN_APPROVE_PAYMENT | DOC_SIGN | DOC_WITNESS
ROLE_ADMIN = (1 << 128) - 1 // all bits 0-127ERC-2771 Meta-Transactions
All user-facing contracts accept IntegraForwarder as their trusted forwarder, enabling gasless operation:
- User signs EIP-712 typed data off-chain (no gas needed).
- Relayer submits the signed request to
IntegraForwarder.execute(). - Forwarder validates the signature and forwards the call.
- Target contract uses
_msgSender()to extract the real sender.
Provider Abstraction
Attestation verification is decoupled from specific systems through the IAttestationProvider interface. The reference implementation uses EAS, but the protocol can support Verifiable Credentials, ZK proofs, DID-based systems, or any other attestation mechanism by deploying a new provider and registering it in IntegraRegistryV1.
Summary Table
| # | Layer | Key Contracts | Purpose |
|---|---|---|---|
| 1 | Core | IntegraExistenceV1, CapabilityNamespaceV1, IntegraRegistryV1, IntegraLedgerV1 | Write-once content hash registration; permission bit definitions; component registry; protocol directory |
| 2 | Access Control | AttestationAccessControlV1, EASAttestationProviderV1 | Attestation-gated capability verification |
| 3 | Records | IntegraRecordV1 | Ownership, metadata, tokenizer/resolver/policy binding |
| 4 | Execution | IntegraExecutorV1, IntegraForwarder | Gas abstraction, meta-transaction forwarding |
| 5 | Messaging | IntegraSignalV1, IntegraMessageV1 | Encrypted payment signals, workflow messages |
| 6 | Extensions | RecordExtension, OwnershipExtension, EscrowExtension, ApprovalExtension + 10 building blocks | Composable domain-specific record logic |
| 7 | Lens | IntegraLens | Stateless view composition across all attached contracts |
| 8 | Policy | AttestationTransferPolicy, TransitionPolicy | Pluggable transfer restrictions for tokenized records |
| 9 | Interfaces | IContractV2, ITokenParty, ITokenizerV2, IResolverV2 | Universal introspection and cross-standard abstractions |
| 10 | Tokenizers | 23 contracts (ERC-721, ERC-1155, ERC-20) | Token representations of record rights |
| 11 | Resolvers | ADRResolverV3, AAAResolverV1 | Dispute resolution and agreement-bound arbitration |
Solidity Version and Dependencies
| Dependency | Version |
|---|---|
| Solidity | 0.8.28 (exact, not a range) |
| OpenZeppelin Contracts | v5.x |
| EAS | Ethereum Attestation Service |
All contracts use pragma solidity 0.8.28;. No contracts use proxy patterns or upgradeability.
Next Steps
- What is Integra? -- Protocol overview and key concepts
- Why Real World Contracts? -- The motivation behind RWCs