Appearance
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_idrequired (linked viafundstable) - D+7 safety: if FM doesn't mint LP within 7 days → auto-refund to investor
LP Issuance: PLATFORM_ISSUED vs FUND_ISSUED
| Aspect | PLATFORM_ISSUED (AS_POOL) | FUND_ISSUED (FUND_POOL) |
|---|---|---|
| LP mint trigger | Auto on deposit (instant) | FM calls mintLP() |
| Receipt token | Not used | Minted on deposit, burned on LP mint |
| Investor experience | Deposit → LP in wallet (instant) | Deposit → receipt → wait for FM → LP in wallet |
| D+7 auto-refund | Safety net only (shouldn't trigger) | Protects investor if FM unresponsive |
| Fund wallet destination | Pool 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
| Stage | Location | Controller | Custodial? |
|---|---|---|---|
| Deposit (pending LP) | Pool Smart Contract | Contract code | 🟢 No |
| Reserve (post-LP) | Pool Smart Contract | Contract code | 🟢 No |
| Fund capital (post-LP) | Pool/Fund Wallet | Aset / FM | N/A (their wallet) |
| Yield (pre-claim) | Pool Smart Contract | Contract code | 🟢 No |
| Yield (post-claim) | Investor wallet | Investor | 🟢 No |
| Redemption payout | Contract → Investor | Contract 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:
| Setting | Options | Default | Who Sets |
|---|---|---|---|
yield_frequency | MONTHLY, QUARTERLY, CUSTOM | MONTHLY | Admin (AS) / FM (Fund) |
yield_trigger | AUTO, MANUAL | AUTO | Admin (AS) / FM (Fund) |
allow_rollover | true / false | false | Originator / 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}').
| Stablecoin | Decimals | Notes |
|---|---|---|
| USDC | 6 | Default. Circle-issued native USDC preferred (not bridged). |
| USDT | 6 | Tether. Available on most chains. |
| DAI | 18 | MakerDAO. 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
- Pool Create (Admin): Admin selects which stablecoins this pool accepts (checkbox, min 1).
- Invest Flow (Investor): Pool detail shows accepted currencies. If multiple, investor picks one before depositing.
- Contract Interaction: The selected stablecoin's contract address on the current chain is used for
approve()+deposit(). - Deposit Record:
deposits.currencystores 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