Contract Architecture
The RWT contract is the on-chain engine behind — a vault-backed token that aggregates yield from across the AREAL portfolio. The contract is deployed on Solana and leverages MagicBlock Ephemeral Rollups for real-time per-second yield accumulation.On-Chain Accounts
All core state is stored in owned by the RWT program. This ensures trustless, permissionless access to vault operations.EngineAuthority
Stores the top-level authority address that controls the entire RWT Engine contract. This authority can execute all governance-gated instructions and can be transferred to any address — another DAO, a multisig, or an individual account. Seeds:
["engine_authority"].RwtVault
The main vault PDA. Stores the portfolio of Ownership Tokens, tracks total invested capital, total RWT supply, and current NAV Book Value. Seeds:
["rwt_vault"].RwtMint
The mint authority PDA for the RWT SPL token. Only the vault program can mint new RWT through the
mint_rwt instruction. Seeds: ["rwt_mint"].CapitalAccumulator
Buffer account that holds deposited capital (USDC and other approved tokens) before it is deployed into Ownership Token positions. Receives funds from
mint_rwt and OT sales. Strategy execution draws from this account. Seeds: ["capital_accumulator"].VaultClaimAccount
The vault’s own ClaimAccount in the Yield Distribution contract. Receives per-second RWT yield from every OT held in the vault — just like any regular holder’s ClaimAccount. Seeds:
["claim", rwt_vault] (in the Yield Distribution program).YieldAccumulator
Staging account for yield claimed from
VaultClaimAccount. Holds yield before it is split by distribute_yield (70% book value, 15% liquidity, 5% treasury, 10% reserve). Delegated to MagicBlock ER. Seeds: ["yield_accumulator"].DistributionConfig
Stores the yield distribution ratios (default 70/15/5/10) and destination account references. The DAO can update these ratios at any time via futarchy vote. Seeds:
["distribution_config"].StrategyConfig
Stores the current
strategy_authority, OT whitelist, and portfolio constraints (max trade size, concentration limits, diversification rules). Seeds: ["strategy_config"].AcceptedMints
Registry of tokens approved by the DAO for RWT minting. Each entry maps a token mint to its MagicBlock oracle price feed for USD conversion. Seeds:
["accepted_mints"].MintGuardians
List of guardian wallets authorized to pause/unpause RWT minting for the entire contract. Also stores the current
mint_paused flag. Guardians are appointed by the DAO — any single guardian can trigger an emergency pause. Seeds: ["mint_guardians"].Destination Accounts
Treasury
Receives 5% of distributed yield. Controlled by AREAL DAO.
Reserve Pool
Receives 10% of distributed yield. Safety buffer managed via Reserve Fund.
Liquidity Pool
Receives 15% of distributed yield. Deployed into RWT master pools on the native DEX.
Core Instructions
The RWT program exposes the following instructions that drive the vault lifecycle.initialize_vault
initialize_vault
Creates all core PDAs:
EngineAuthority, RwtVault, RwtMint, CapitalAccumulator, YieldAccumulator, DistributionConfig, StrategyConfig, and AcceptedMints. Sets the initial engine authority, distribution ratios, and registers the initial accepted deposit mints with their oracle feeds.Authority: Governance multisig (one-time call)mint_rwt
mint_rwt
Mints RWT in exchange for any DAO-approved token. The entire operation is atomic within a single Solana block:
- Snapshot NAV — reads the current
rwt_vault.nav_book_value(kept up-to-date by the per-second yield cycle in ER) - Convert deposit to USD — reads oracle price feed for non-USD tokens
- Calculate RWT amount —
rwt_out = net_deposit_usd / nav_book_value - Apply fee — 1% total (0.5% to Capital Accumulator, 0.5% to DAO)
- Transfer deposit to Capital Accumulator
- Mint RWT to user’s wallet
- Update NAV — atomically reflects the new deposit in
total_invested_capital
mint_paused flag in MintGuardians — if any guardian has triggered an emergency pause, all minting is halted globally until unpaused.Authority: Permissionless — anyone can call (unless globally paused)pause_mint
pause_mint
Emergency pause — halts all RWT minting globally. Any single guardian from the
MintGuardians list can trigger this immediately, without a DAO vote. Designed for rapid response to exploits, oracle failures, or market emergencies.Authority: Any guardian from MintGuardiansunpause_mint
unpause_mint
Resumes RWT minting after an emergency pause. Minting continues at the current NAV Book Value — the price is not frozen during the pause, it reflects the latest vault state at the moment of resumption. Only the Engine Authority (DAO) can unpause — ensuring that a single guardian cannot unilaterally resume minting without community consensus.Authority: Engine Authority (DAO governance)
update_mint_guardians
update_mint_guardians
Adds or removes guardian wallets from the
MintGuardians list. The DAO votes (via futarchy) to appoint trusted individuals or entities who can trigger emergency mint pauses.Authority: Engine Authority (DAO governance)update_accepted_mints
update_accepted_mints
Adds or removes tokens from the list of accepted deposit mints for
mint_rwt. Each approved token must have a corresponding MagicBlock oracle price feed. The DAO community votes (via futarchy) to approve new deposit tokens or revoke existing ones.Authority: DAO governance (futarchy vote)accumulate_yield
accumulate_yield
Claims accumulated RWT rewards from the vault’s ClaimAccount (in the Yield Distribution contract) and moves them into the
YieldAccumulator. The RWT Vault has its own ClaimAccount — just like any OT holder — and receives per-second yield from every OT it holds.Runs every second inside the Ephemeral Rollup as part of the atomic yield cycle.Authority: Permissionless (crank)distribute_yield
distribute_yield
Reads the accumulated yield from
YieldAccumulator and splits it according to DistributionConfig ratios: 70% credited to vault book value, 15% to liquidity, 5% to treasury, 10% to reserve.Authority: Permissionless (crank)update_distribution_config
update_distribution_config
Updates the yield distribution ratios and/or destination accounts in
DistributionConfig. The DAO community can vote (via futarchy) to change how yield is split — adjusting percentages, adding new destinations, or redirecting flows at any time. All ratios must sum to 100%.Authority: DAO governance (futarchy vote)update_nav
update_nav
vault_buy_ot
vault_buy_ot
Draws capital from the Capital Accumulator and executes a buy order for a specific Ownership Token on the AREAL native DEX. The vault routes the swap through the DEX. Only callable by the current
strategy_authority.Authority: strategy_authority (governance or AI agent)vault_sell_ot
vault_sell_ot
Sells a specific Ownership Token on the AREAL native DEX and returns the proceeds to the Capital Accumulator. The capital remains in the accumulator until redeployed by the strategy authority. Only callable by the current
strategy_authority.Authority: strategy_authority (governance or AI agent)set_strategy_authority
set_strategy_authority
transfer_engine_authority
transfer_engine_authority
Engine Authority
The RWT Engine contract has a single top-level authority stored in theEngineAuthority PDA. This is the root of trust for the entire contract — it controls all governance-gated operations.
The engine authority can be transferred to any address at any time — enabling the following scenarios:
DAO-to-DAO transfer
The current DAO transfers control of the RWT Engine to another DAO with different governance structure, jurisdiction, or community.
Multisig migration
Authority moves from one multisig to another — for example, when the security council rotates members or upgrades to a different multisig implementation.
Progressive decentralization
Start with a founding team multisig, transition to a community DAO, then to a fully autonomous on-chain governance contract.
Emergency takeover
In case of governance failure, the community can vote to transfer authority to a trusted entity or security council for temporary crisis management.
Portfolio Management
The RWT Vault actively manages a portfolio of Ownership Tokens — buying and selling them exclusively on AREAL’s native DEX. This design ensures all trades are transparent, on-chain, and constrained to the protocol’s own liquidity infrastructure.Capital Accumulator
The Capital Accumulator is the buffer between user deposits and OT positions. Capital never moves directly from a mint into Ownership Tokens — it always passes through the accumulator first. Inflows — capital enters the accumulator from:mint_rwt— user deposit (net amount after DAO fee)mint_rwt— 0.5% vault fee from every mintvault_sell_ot— proceeds from selling Ownership Tokensdistribute_yield— 70% of OT yield credited as book value growth
vault_buy_ot— purchasing Ownership Tokens on the native DEX
The Capital Accumulator balance is always included in
total_invested_capital for NAV Book Value calculation. Whether capital sits as USDC in the accumulator or has been deployed into OT positions — it all backs RWT. Undeployed capital simply hasn’t been converted into OT positions yet, but it still counts toward NAV.Execution Strategies
Capital in the accumulator is deployed into OT positions according to an execution strategy defined by the strategy authority. The contract does not execute a single large buy — instead, it supports gradual deployment patterns to minimize market impact and optimize entry prices.DCA (Dollar-Cost Averaging)
Splits the total capital into equal portions and executes buys over a defined period (e.g., deploy 1,667/day). Reduces timing risk and smooths entry price.
Target Allocation
Defines target portfolio weights per OT (e.g., 30% OT-A, 25% OT-B, 20% OT-C). The strategy authority executes trades to converge toward these targets as capital enters the accumulator.
Opportunistic
The strategy authority (especially an AI agent) deploys capital when market conditions are favorable — buying dips, reacting to yield changes, or capitalizing on liquidity events.
Execution strategies are not hardcoded in the contract. The contract provides the primitives (
vault_buy_ot, vault_sell_ot) and the constraints (StrategyConfig). The strategy logic lives in the strategy authority — whether that’s a DAO proposal, a multisig workflow, or an AI agent’s decision engine.Strategy Authority
Portfolio operations (vault_buy_ot, vault_sell_ot) are gated by a dedicated strategy_authority — a role stored in the StrategyConfig PDA. This role is separate from the governance multisig and can be reassigned via set_strategy_authority.
Phase 1: Governance-driven
Initially,
strategy_authority is held by the DAO. Buy/sell decisions are proposed and voted on through futarchy before execution.Phase 2: AI Agent
Governance transfers
strategy_authority to an autonomous AI agent. The agent executes portfolio strategies within on-chain constraints — no off-chain trust required.StrategyConfig Account
TheStrategyConfig PDA stores parameters that constrain portfolio operations, regardless of who holds the strategy_authority:
| Parameter | Description |
|---|---|
strategy_authority | Current address authorized to execute buy/sell |
allowed_ot_mints | Whitelist of OT mints approved by governance |
max_single_trade_bps | Max trade size as basis points of total vault capital (e.g., 500 = 5%) |
max_daily_volume_bps | Max daily trading volume as bps of vault capital |
min_diversification | Minimum number of distinct OTs the vault must hold |
max_concentration_bps | Max allocation to a single OT as bps of total portfolio |
These constraints are enforced on-chain by the program logic. Even an AI agent with full
strategy_authority cannot exceed these limits — the transaction will simply fail. Governance can update these parameters via update_strategy_config.Trade Execution Flow
Strategy decision
The strategy authority (governance or AI agent) decides to buy or sell a specific OT based on yield performance, diversification targets, or market conditions.
Constraint validation
The contract checks the trade against
StrategyConfig limits: is the OT whitelisted? Does the trade size exceed max_single_trade_bps? Would it violate max_concentration_bps or min_diversification?Capital flow
For buys: capital is drawn from the Capital Accumulator → swapped on native DEX → OT deposited into vault positions. For sells: OT is sold on native DEX → proceeds returned to the Capital Accumulator.
All trades execute exclusively on the AREAL native DEX. The contract has no CPI calls to external DEX programs — this eliminates external dependency risk and ensures all liquidity flows strengthen the protocol’s own markets.
Yield Flow
The RWT Vault receives yield from Ownership Tokens through the Yield Distribution contract. The vault has its own ClaimAccount — just like any OT holder — and receives per-second RWT rewards from every OT it holds.OT yield accrual
The RWT Vault holds OTs across multiple projects. Each OT project distributes yield via the Yield Distribution contract, crediting RWT rewards to the vault’s ClaimAccount every second — just like any regular holder.
Yield collection
The
accumulate_yield instruction claims accumulated RWT from the vault’s ClaimAccount and moves it into the YieldAccumulator. In the Ephemeral Rollup, this happens every second — keeping yield data real-time.Distribution split
The
distribute_yield instruction reads DistributionConfig and splits accumulated yield:- 70% → credited to
rwt_vault.total_invested_capital(grows NAV Book Value) - 15% → transferred to liquidity pool destination
- 5% → transferred to AREAL Treasury
- 10% → transferred to Reserve Pool
The sequence
accumulate_yield → distribute_yield → update_nav runs as an atomic per-second cycle inside the MagicBlock Ephemeral Rollup. NAV Book Value is always current — there is no lag between yield accrual and price update.NAV Book Value Calculation
The on-chain NAV Book Value is a deterministic calculation stored in theRwtVault account, updated every second by the yield cycle in the Ephemeral Rollup:
NAV Book Value = total_invested_capital / total_rwt_supplyWhere
total_invested_capital is the sum of all capital backing RWT, from three sources:
| Source | What it is | How it enters |
|---|---|---|
| Capital Accumulator (USDC) | User deposits from mint_rwt + 0.5% vault fee from minting | Every mint adds to CA balance |
| OT Portfolio (valued in USD) | Ownership Tokens purchased by the strategy authority | vault_buy_ot moves capital from CA → OT positions |
| Yield credits (70%) | 70% of yield from OT distributions, credited to book value | Per-second via accumulate_yield → distribute_yield |
total_rwt_supply = current circulating supply of the RWT mint.
The Capital Accumulator balance (undeployed USDC) is always counted in
total_invested_capital. Whether capital sits in the accumulator or has been deployed into OT positions — it all backs RWT and is reflected in NAV.- Every second: OT yield flows through
accumulate_yield→distribute_yield→ 70% credited tototal_invested_capital→update_nav - On every mint: deposit + vault fee added to Capital Accumulator →
total_invested_capitalupdated atomically
All arithmetic uses fixed-point u128 operations with 12 decimal places of precision to avoid floating-point drift. The NAV is stored as a
u64 value in USDC-equivalent lamports (6 decimals).Mint price derivation (atomic, single block)
The mint price is always expressed in USD. The entire calculation and execution happen atomically in one Solana block — the user cannot be front-run or receive a stale price:For USDC and other USD-pegged stablecoins, the oracle price is effectively $1.00, so the conversion is 1:1. For volatile tokens (e.g., SOL, wBTC), the oracle provides a real-time USD price from MagicBlock’s Ephemeral Rollup, ensuring accurate pricing at the moment of mint.
The NAV update at the end of mint is part of the same transaction. This means the next user who mints will see the updated NAV that includes the previous user’s deposit — zero dilution, zero stale pricing.
MagicBlock Integration
The RWT contract uses for two critical functions: per-second yield accumulation and real-time oracle price feeds.Yield accumulation
The
YieldAccumulator account is delegated to the Ephemeral Rollup. This allows the crank to call accumulate_yield every second with sub-millisecond finality inside the rollup.Oracle price feeds
MagicBlock provides real-time USD price feeds for all accepted deposit tokens. The
mint_rwt instruction reads these oracle accounts to convert any approved token into its USD equivalent at the moment of mint.L1 commits
Periodically (configurable, default every 60 seconds), the accumulated state is committed back to Solana L1. This ensures L1 reflects an up-to-date yield balance for distribution.
Lifecycle
Delegate
The
YieldAccumulator PDA is delegated to MagicBlock via the delegation program. The account becomes writable in the Ephemeral Rollup while remaining readable on L1.Accumulate in ER
The crank service calls
accumulate_yield every second inside the Ephemeral Rollup. Each call reads OT yield sources and increments the accumulator balance.Commit to L1
On a periodic basis, the rollup commits the
YieldAccumulator state back to Solana L1. After commit, distribute_yield can be called on L1 to split and transfer funds.Delegating only the
YieldAccumulator (not the entire vault) minimizes the trust surface. The vault’s core state — balances, NAV, mint authority — remains on Solana L1 at all times.Security Considerations
Authority model
The
EngineAuthority is the root of trust — controls all governance-gated instructions and can be transferred to any address via transfer_engine_authority. Portfolio operations require strategy_authority. All other instructions are permissionless.PDA ownership
All vault accounts are PDAs owned by the program. No external wallet can modify vault state directly. Mint authority is held exclusively by the
RwtMint PDA.Overflow protection
All arithmetic uses checked math (
checked_add, checked_mul, checked_div). Fixed-point u128 operations prevent precision loss. Transactions revert on overflow.Reentrancy safety
Solana’s runtime model prevents reentrancy by design. Account locks ensure no concurrent modification of vault state within the same slot.
Strategy constraints
Portfolio operations are bounded by on-chain limits: OT whitelist, max trade size, concentration caps, diversification minimums. Even an autonomous agent cannot exceed these parameters.
DEX-only execution
All buy/sell operations route exclusively through the AREAL native DEX via CPI. No external DEX integrations — eliminating third-party dependency and exploit surface.