Technical Architecture

Deep dive into the program structure, state management, and core algorithms

System Flow Diagram

Meteora DAMM V2 Pool(Generates Quote-Only Fees)Fee AccrualHonorary LP Position (PDA-Owned)[Accumulates Quote Fees]24h Crank (Permissionless)Fee Distribution Smart ContractStreamflow Data(Locked Amounts)locked_i(t) / Y0Pro-Rata Calculation(Based on Lock %)payout_i = allocation × weight_iInvestors(Pro-Rata Distribution)Creator Wallet(Remainder)

Interactive SVG diagram showing the complete fee routing flow from pool to final distribution

Four-Instruction Design

1. initialize_policy

Creates immutable Policy PDA with distribution configuration (Y0, fee shares, caps, thresholds).

2. initialize_progress

Creates mutable Progress PDA for daily distribution tracking and pagination state.

3. initialize_position

Creates honorary DAMM V2 position owned by program PDA. Validates pool configuration and program IDs.

Validation:Pool authority & CP-AMM program
Ownership:PDA-controlled

4. distribute_fees

Permissionless 24h crank that claims fees and executes real SPL token transfers. Distributes quote token (Token B) pro-rata to investors and sends remainder to creator. FAILS deterministically if any Token A (base fees) are detected, ensuring quote-only compliance.

Frequency:Every 24 hours
Transfers:Real SPL token transfers
Pagination:Idempotent & resumable

State Accounts

Policy (Immutable)

seeds = [b"policy"]
• y0: Total allocation at TGE
• investor_fee_share_bps
• daily_cap_lamports
• min_payout_lamports
• quote_mint
• creator_wallet
• authority
• bump

Progress (Mutable)

seeds = [b"progress"]
• last_distribution_ts
• current_day
• daily_distributed_to_investors
• carry_over_lamports
• current_page
• pages_processed_today
• total_investors
• creator_payout_sent
• has_base_fees
• total_rounding_dust
• bump

Why 4 Instructions Instead of 2?

Bounty Requirements Analysis

Bounty specifies:

  • Work Package A: Initialize honorary position (1 instruction)
  • Work Package B: Permissionless distribution crank (1 instruction)
  • → Implied total: 2 functional instructions

BUT bounty also requires (line 96):

  • "Policy PDA (fee share, caps, dust)"
  • "Progress PDA (last ts, daily spent, carry, cursor, day state)"
  • → Must exist BEFORE distribute_fees runs, but HOW to initialize? Not specified!

❌ 2-Instruction Approach (Messy)

  • • Cram Policy init into initialize_position
  • • Cram Progress init into initialize_position
  • • Violates single responsibility principle
  • • initialize_position becomes bloated (3 accounts init)
  • • Less flexible for different setups
  • • Harder to test each component

✅ 4-Instruction Approach (Clean)

  • initialize_policy - Setup config (single purpose)
  • initialize_progress - Setup state (single purpose)
  • initialize_position - Create position (single purpose)
  • distribute_fees - Distribution logic (single purpose)
  • • Modular & maintainable
  • • Easier integration & testing
  • • Follows Anchor best practices

✅ Verdict: 4 Instructions is Superior

✓ Bounty Compliant
Doesn't prohibit helper instructions, only specifies work packages
✓ Better Architecture
Separation of concerns, single responsibility per instruction
✓ Production Ready
Easier to maintain, test, and integrate for real-world usage

PDA Seeds & Derivation

// Core PDA seeds
pub const VAULT_SEED: &[u8] = b"vault";
pub const INVESTOR_FEE_POS_OWNER_SEED: &[u8] = b"investor_fee_pos_owner";
pub const POLICY_SEED: &[u8] = b"policy";
pub const PROGRESS_SEED: &[u8] = b"progress";
pub const TREASURY_SEED: &[u8] = b"treasury";

// Position owner PDA derivation
let (position_owner, bump) = Pubkey::find_program_address(
    &[
        VAULT_SEED,
        vault.key().as_ref(),
        INVESTOR_FEE_POS_OWNER_SEED
    ],
    &fee_routing::ID
);