Skip to content

Pool Models

AS_POOL vs FUND_POOL architecture, LP issuance differences, fund flow, yield settings, and per-pool stablecoin configuration.

Pool Type Definitions

🏊 AS_POOL (Platform-Managed)

Aset manages the pool end-to-end. Deposits flow into the Pool Smart Contract. LP tokens are auto-minted on deposit (PLATFORM_ISSUED) — no receipt token, no manual step. Admin/Operator handles yield distribution and redemptions.

Key traits:

  • LP issuance: PLATFORM_ISSUED (auto on deposit)
  • No receipt token needed
  • Deposit split: (amount × (1 - reserve_%)) → Pool Wallet, remainder → contract reserve
  • Yield trigger: Admin or AUTO schedule
  • Fund Wallet: Pool Wallet (Aset-operated)

📁 FUND_POOL (FM-Managed)

Fund Manager operates the pool through the FM Portal. Deposits flow into the Pool Smart Contract. Investor receives a receipt token on deposit. FM reviews and calls mintLP() (FUND_ISSUED), receipt is burned.

Key traits:

  • LP issuance: FUND_ISSUED (FM mints after review)
  • Receipt token (ERC-721) minted on deposit as proof-of-pending
  • Deposit split: (amount × (1 - reserve_%)) → Fund Wallet (FM-controlled), remainder → contract reserve
  • Yield trigger: FM or AUTO schedule
  • Fund assignment: fund_id required (linked via funds table)
  • D+7 safety: if FM doesn't mint LP within 7 days → auto-refund to investor

LP Issuance: PLATFORM_ISSUED vs FUND_ISSUED

AspectPLATFORM_ISSUED (AS_POOL)FUND_ISSUED (FUND_POOL)
LP mint triggerAuto on deposit (instant)FM calls mintLP()
Receipt tokenNot usedMinted on deposit, burned on LP mint
Investor experienceDeposit → LP in wallet (instant)Deposit → receipt → wait for FM → LP in wallet
D+7 auto-refundSafety net only (shouldn't trigger)Protects investor if FM unresponsive
Fund wallet destinationPool Wallet (Aset-operated)Fund Wallet (FM-controlled)

Fund Flow Architecture (Non-Custodial)

🏦 Core Principle

Aset is a facilitator, never a custodian. All investor funds flow through Pool Smart Contracts. Aset has an operator role (can call functions) but never holds funds. No VASP license required.

Where Funds Live

StageLocationControllerCustodial?
Deposit (pending LP)Pool Smart ContractContract code🟢 No
Reserve (post-LP)Pool Smart ContractContract code🟢 No
Fund capital (post-LP)Pool/Fund WalletAset / FMN/A (their wallet)
Yield (pre-claim)Pool Smart ContractContract code🟢 No
Yield (post-claim)Investor walletInvestor🟢 No
Redemption payoutContract → InvestorContract code🟢 No

Yield Settings (Both Pool Types)

All yield is claim-based (MANUAL_CLAIM). DISTRIBUTING deprecated. Settings apply to both AS_POOL and FUND_POOL equally:

SettingOptionsDefaultWho Sets
yield_frequencyMONTHLY, QUARTERLY, CUSTOMMONTHLYAdmin (AS) / FM (Fund)
yield_triggerAUTO, MANUALAUTOAdmin (AS) / FM (Fund)
allow_rollovertrue / falsefalseOriginator / FM at pool creation

⚠️ yield_frequency = public commitment

Even when yield_trigger = MANUAL, the frequency is a committed schedule shown on pool detail to investors. Investor sees: "Yield: Monthly, FM-triggered" or "Yield: Quarterly, Auto". If FM/admin misses the window → yield_overdue = true → alert admin + investors. next_yield_due = last_distribution_date + frequency.

Yield Claim Flow

Aset never touches yield — contract is the custodian. Investor pays gas on claim (not fund paying N push transactions).

Accepted Stablecoins (Per-Pool)

Each pool defines which USD-backed stablecoins it accepts for investment. This is set at pool creation and stored in pools.accepted_currencies (a currency[] array, default '{USDC}').

StablecoinDecimalsNotes
USDC6Default. Circle-issued native USDC preferred (not bridged).
USDT6Tether. Available on most chains.
DAI18MakerDAO. Note: 18 decimals (vs 6 for USDC/USDT).

Per-Pool, Not Platform-Level

Stablecoin configuration is per pool, not a global platform setting. Each pool can accept a different subset. Admin selects accepted currencies during pool creation and can modify them in any lifecycle state (DRAFT, UPCOMING, ACTIVE). Adding a currency opens a new deposit option; removing one prevents new deposits in that currency (existing deposits are unaffected).

How It Works

  1. Pool Create (Admin): Admin selects which stablecoins this pool accepts (checkbox, min 1).
  2. Invest Flow (Investor): Pool detail shows accepted currencies. If multiple, investor picks one before depositing.
  3. Contract Interaction: The selected stablecoin's contract address on the current chain is used for approve() + deposit().
  4. Deposit Record: deposits.currency stores which stablecoin was used (e.g., 'USDC', 'USDT').

Chain-Specific Stablecoin Addresses

Stablecoin contract addresses are chain-specific, not pool-specific — USDC on Base is always the same address regardless of pool. Address lookup: STABLECOIN_ADDRESSES[chainId][symbol].

Only native (issuer-deployed) stablecoins are supported. Bridged versions (e.g., USDC.e) are excluded due to depeg risk.

Reserve Split Logic

On LP mint, contract splits deposit:
  (deposit × (1 - reserve_%)) → Pool Wallet (AS) / Fund Wallet (FM)
  (deposit × reserve_%)       → stays in Pool Contract (reserve)

Example: $10,000 deposit, 10% reserve
  → $9,000 → wallet
  → $1,000 → contract reserve