Skip to main content

Contract Architecture

The Ownership Token (OT) contract manages the lifecycle of project-specific tokens that represent real, legally enforceable ownership of assets held by a . Each project deploys its own instance of the OT contract on Solana, with its own mint, governance, and revenue distribution logic.

On-Chain Accounts

OtConfig

Main configuration PDA for the Ownership Token. Stores the project DAO authority, token metadata, total supply cap, and references to revenue and governance accounts. Seeds: ["ot_config", ot_mint].

OtMint

The SPL token mint for this project’s Ownership Token. Mint authority is held by the OtConfig PDA — only the contract can mint new tokens. Each project has a unique mint.

RevenueAccount

Accumulates revenue deposited by the project DAO from real-world operations (rent, fees, royalties). Funds are held here until distributed according to RevenueConfig. Seeds: ["revenue", ot_mint].

RevenueConfig

Stores the list of distribution destinations with their allocation percentages. Each destination has a name, target address, and share in basis points. The project DAO can add, remove, and update destinations at any time. Seeds: ["revenue_config", ot_mint].

OtGovernance

Stores governance parameters for this project’s DAO: proposal thresholds, futarchy market config, voting periods, and the current governance authority. Seeds: ["ot_governance", ot_mint].

Core Instructions

initialize_ot

Deploys a new Ownership Token for a project. Creates the OtConfig, OtMint, RevenueAccount, RevenueConfig, and OtGovernance PDAs. Sets the project DAO authority, token metadata, total supply cap, and initial distribution destinations.Authority: Project deployer (one-time call)
Accounts:
  - deployer:            Signer
  - ot_config:           PDA (init)
  - ot_mint:             Mint (init)
  - revenue_account:     PDA (init)
  - revenue_config:      PDA (init)
  - ot_governance:       PDA (init)
  - system_program
  - token_program

Args:
  - name: String         Token name (e.g., "AREAL Miami Tower")
  - symbol: String       Token symbol (e.g., "AMT")
  - decimals: u8         Token decimals
  - supply_cap: u64      Maximum total supply (0 = unlimited)
Mints new Ownership Tokens to a specified recipient. Enforces the supply cap defined in OtConfig. Typically used during initial token distribution or subsequent fundraising rounds approved by governance.Authority: Project DAO governance
Accounts:
  - governance:          Signer (project DAO authority)
  - ot_config:           PDA
  - ot_mint:             Mint (mut)
  - recipient_ata:       Recipient's token account (mut)
  - token_program

Args:
  - amount: u64          Amount to mint
  - recipient: Pubkey    Destination wallet
Deposits revenue from real-world operations into the RevenueAccount. Called by the project DAO when off-chain revenue is bridged on-chain (rent collected, fees earned, royalties received).This automatically triggers distribute_revenue — as soon as funds land in the RevenueAccount, the contract splits them according to the pre-configured RevenueConfig and forwards the Holders share to the Yield Distribution contract. No additional governance vote is required.Authority: Project DAO governance
Accounts:
  - governance:          Signer (project DAO authority)
  - revenue_account:     PDA (mut)
  - deposit_source_ata:  Source token account (USDC)
  - token_program

Args:
  - amount: u64          Revenue amount in USDC
Triggered automatically when funds are deposited into RevenueAccount via deposit_revenue. Splits the deposited amount according to the pre-configured RevenueConfig — no per-distribution governance vote required.The DAO only votes once — when setting up or modifying the RevenueConfig (via add_destination, update_destination, remove_destination). After that, every revenue deposit automatically flows through the configured destinations.For destinations of type Holders, the contract automatically calls create_distribution on the Yield Distribution contract via CPI — creating a new isolated distribution cycle.A 0.25% AREAL protocol fee is deducted from the total distribution amount.Authority: Automatic (called internally by deposit_revenue)
Accounts:
  - revenue_account:     PDA (mut)
  - revenue_config:      PDA
  - destination_atas:    Destination token accounts (mut, variable)
  - distribution_program: Yield Distribution program
  - distribution_stream: Yield Distribution stream PDA (for Holders type)
  - treasury_ata:        AREAL DAO fee destination
  - token_program
Adds a new distribution destination to RevenueConfig. The project DAO votes (via futarchy) to create new revenue streams — for example, adding a marketing budget, a development fund, or a new team allocation. Total allocation across all destinations must equal 100%.Authority: Project DAO governance
Accounts:
  - governance:          Signer (project DAO authority)
  - revenue_config:      PDA (mut)

Args:
  - name: String         Destination name (e.g., "Team Operations")
  - destination: Pubkey  Target wallet or program address
  - share_bps: u16       Allocation in basis points (e.g., 3000 = 30%)
  - dest_type: enum      { Holders, Wallet, DaoTreasury }
Updates an existing distribution destination — change its name, target address, allocation percentage, or type. The project DAO votes to adjust revenue splits as the project evolves. Total allocation must remain 100% after the update.Authority: Project DAO governance
Accounts:
  - governance:          Signer (project DAO authority)
  - revenue_config:      PDA (mut)

Args:
  - destination_id: u8   Index of the destination to update
  - name: Option<String>
  - destination: Option<Pubkey>
  - share_bps: Option<u16>
  - dest_type: Option<enum>
Removes a distribution destination from RevenueConfig. The freed allocation must be redistributed to remaining destinations so the total remains 100%. Cannot remove the last destination.Authority: Project DAO governance
Accounts:
  - governance:          Signer (project DAO authority)
  - revenue_config:      PDA (mut)

Args:
  - destination_id: u8   Index of the destination to remove
Transfers the project DAO governance authority to a new address. Enables the same flexibility as the RWT Engine — the project can be handed over to a different DAO, multisig, or governance structure.Authority: Current project DAO authority
Accounts:
  - current_authority:   Signer
  - ot_governance:       PDA (mut)

Args:
  - new_authority: Pubkey
Updates token configuration parameters — metadata, supply cap adjustments, or governance parameters. Requires project DAO authority.Authority: Project DAO governance
Accounts:
  - governance:          Signer (project DAO authority)
  - ot_config:           PDA (mut)
  - ot_governance:       PDA (mut, if updating governance params)

Revenue Distribution

How it works

The DAO votes once to configure RevenueConfig — setting the destinations and percentages. After that, everything is automatic: whenever revenue is deposited into the RevenueAccount, distribute_revenue fires immediately and splits funds according to the pre-configured destinations. No per-distribution vote needed.

RevenueConfig Structure

The RevenueConfig stores a list of destinations — each with a name, type, target address, and allocation in basis points. All allocations must sum to 10,000 bps (100%).
FieldTypeDescription
nameStringHuman-readable label (e.g., “Token Holders”, “Team Operations”)
dest_typeenumHolders — forwards to Yield Distribution contract; Wallet — direct transfer; DaoTreasury — project DAO treasury
destinationPubkeyTarget address (Yield Distribution program, team wallet, DAO treasury PDA)
share_bpsu16Allocation in basis points (5000 = 50%)

Example Configuration

1

50% → OT Holders

Type: Holders. The OT contract automatically calls create_distribution on the Yield Distribution contract via CPI — creating a new isolated distribution cycle. Funds are deployed into the RWT/USDY master pool via DCA and distributed per-second to OT holders in RWT. No additional governance vote required.
2

30% → Team Operations

Type: Wallet. Direct transfer to the team’s operational wallet. Covers salaries, maintenance, property management, and day-to-day expenses.
3

20% → Project DAO Treasury

Type: DaoTreasury. Accumulated in the project’s own DAO treasury for future use — reinvestment, asset acquisition, liquidity deepening, or emergency reserves.
This is just an example. The project DAO has full flexibility to create any number of destinations with any allocation. A project might add a “Marketing Fund” at 5%, reduce team allocation, or create a “Buyback Program” destination — all through governance votes.

Destination Management

The project DAO can modify the distribution structure at any time through governance:

Add

add_destination — create a new revenue stream. Example: add a “Sustainability Fund” at 10% and reduce other allocations proportionally.

Update

update_destination — change allocation %, target address, or name. Example: increase holder share from 50% to 60% as the project matures.

Remove

remove_destination — delete a destination and redistribute its share. Example: remove a temporary marketing fund after a campaign ends.
All modifications require a project DAO governance vote (via futarchy). The contract enforces that allocations always sum to exactly 100% — any instruction that would break this invariant is rejected.

Revenue Lifecycle

One-time config (DAO vote)

The DAO votes (via futarchy) to set up or modify the RevenueConfig — defining destinations and percentages. This only happens once (or when the DAO wants to change the split). No per-distribution voting after this.

Revenue generation

Real-world assets held by the DAO Ownership Company generate revenue — rent, service fees, licensing royalties, interest income.

On-chain deposit → automatic distribution

The project DAO bridges revenue on-chain by calling deposit_revenue. As soon as funds land in the RevenueAccount, distribute_revenue fires automatically — splitting funds according to RevenueConfig. No additional vote needed.

Instant execution

Each destination receives its share atomically: Holders → automatic CPI to Yield Distribution (new isolated cycle starts immediately). Wallet → direct transfer to team. DaoTreasury → accumulated for future use. All in one transaction.

Relationship to RWT Vault

Ownership Tokens are the building blocks of the RWT Vault. The RWT Vault’s strategy authority purchases OTs on the native DEX to build a diversified portfolio.
OT contracts are independent from the RWT contract. Each project manages its own token, governance, and revenue. The RWT Vault interacts with OTs only through market operations on the native DEX — there is no privileged access or special relationship.

Security Considerations

Per-project isolation

Each OT contract is a separate deployment with its own PDAs. One project’s contract cannot access another project’s state or funds.

Supply cap enforcement

The supply_cap in OtConfig is enforced on-chain. Once set, it cannot be exceeded — even by the project DAO authority.

100% invariant

The contract enforces that all destination allocations in RevenueConfig always sum to exactly 10,000 bps (100%). Any instruction that breaks this invariant is rejected.

Revenue accounting

All revenue deposits and distributions are tracked on-chain with full audit trail. No off-chain intermediaries handle funds.

Authority transfer

Project governance can be transferred to any address via transfer_ot_authority, enabling progressive decentralization or DAO-to-DAO handover.

Governance-gated changes

All destination modifications (add, update, remove) require a project DAO governance vote. No single actor can redirect revenue without community approval.
The Ownership Token contract is currently in development. This documentation describes the target architecture. Contract code has not yet been audited.