Architecture Overview
ALP is built on a modular architecture with several core components that work together to provide a secure and efficient lending protocol.
Core Components
_19graph TB_19 subgraph "ALP Core"_19 Pool[Pool<br/>Central Logic Hub]_19 Position[Position<br/>User Accounts]_19 TokenState[TokenState<br/>Per-Token Metrics]_19 Oracle[Price Oracle<br/>Price Feeds]_19 end_19_19 User[User Wallet] -->|Creates/Manages| Position_19 Position -->|Operations| Pool_19 Pool -->|Tracks| TokenState_19 Pool -->|Queries Prices| Oracle_19 Pool -->|Stores| Reserves[Token Reserves]_19_19 Position -->|Auto-Push| Sink[DrawDownSink<br/>Automated Flows]_19 Position -->|Auto-Pull| Source[TopUpSource<br/>Automated Flows]_19_19 style Pool fill:#f9f,stroke:#333,stroke-width:4px_19 style Position fill:#bbf,stroke:#333,stroke-width:2px
Pool
The Pool is the central smart contract that manages all protocol operations. It serves as the primary logic hub for:
_16graph LR_16 subgraph "Pool Responsibilities"_16 R1[Track All<br/>Positions]_16 R2[Manage Token<br/>Balances]_16 R3[Store<br/>Reserves]_16 R4[Calculate<br/>Interest]_16 R5[Execute<br/>Liquidations]_16 end_16_16 R1 --> Pool[Pool Contract]_16 R2 --> Pool_16 R3 --> Pool_16 R4 --> Pool_16 R5 --> Pool_16_16 style Pool fill:#f9f,stroke:#333,stroke-width:3px
The Pool tracks global state for all positions, manages credit and debit balances for each supported token, stores reserves as they are deposited, coordinates interest rate calculations, and executes liquidations and rebalancing operations. It maintains a global ledger that tracks the state of each token type, including interest indices, total deposits, total borrows, and reserve factors.
Position
A Position represents a user's credit account within the protocol. Each position tracks:
_16graph TD_16 subgraph "Position Components"_16 C[Collateral<br/>Deposits]_16 D[Debt<br/>Obligations]_16 H[Health<br/>Factor]_16 A[DeFi Actions<br/>Connectors]_16 end_16_16 C --> Position[Your Position]_16 D --> Position_16 H --> Position_16 A --> Position_16_16 Position --> Operations[Operations:<br/>Deposit, Borrow<br/>Repay, Withdraw]_16_16 style Position fill:#bbf,stroke:#333,stroke-width:3px
- Collateral deposits: Assets deposited to back borrowing
- Debt obligations: Amount borrowed against collateral
- Health factor: Ratio of collateral value to debt (must stay above 1.0)
- DeFi Actions connectors: Optional Sink and Source for automated flows
Positions are external objects representing ownership of deposited value, with each position capable of holding multiple token balances (both deposits and borrows). They can be configured with different min/max health targets and support composability through DeFi Actions interfaces.
TokenState
Each supported token in the protocol has an associated TokenState that tracks per-token metrics:
_10graph LR_10 Token[Token<br/>e.g., FLOW] --> State[TokenState]_10_10 State --> I[Interest<br/>Indices]_10 State --> TD[Total<br/>Deposits]_10 State --> TB[Total<br/>Borrows]_10 State --> CF[Collateral<br/>Factor 0.8]_10 State --> IR[Interest Rate<br/>Parameters]_10_10 style State fill:#bfb,stroke:#333,stroke-width:2px
TokenState maintains interest indices for scaled balance calculations, tracks total deposits and borrows for each token, stores the collateral factor (percentage of token value usable as collateral, e.g., 0.8 = 80%), applies borrow factors as multipliers to borrowed amounts, and configures interest rate parameters for rate curves.
Scaled Balance System
ALP uses a scaled balance system to track user balances efficiently:
_20sequenceDiagram_20 participant User_20 participant Position_20 participant Pool_20 participant Index_20_20 User->>Position: Borrow 1000 MOET_20 Position->>Pool: Record balance_20 Note over Pool: Index = 1.0<br/>Scaled = 1000 / 1.0 = 1000_20_20 Note over Index: Time passes...<br/>Interest accrues_20_20 Index->>Index: Index grows to 1.05_20_20 User->>Position: Check balance_20 Position->>Pool: Query_20 Pool->>Pool: Calculate: 1000 × 1.05_20 Pool-->>User: Balance = 1050 MOET_20_20 Note over User,Index: No transaction needed<br/>for interest to accrue!
Instead of updating every user's balance when interest accrues, the protocol:
- Tracks each user's "scaled balance" (actual balance / interest index)
- Updates the global interest index as time passes
- Calculates true balance on-demand as: scaled balance × current interest index
This means balances grow automatically without requiring transactions, as the interest index increases over time.
This system is highly gas efficient since it eliminates per-user balance updates, enables automatic compounding for all users simultaneously, provides precise calculations using UFix128 precision, and scales to unlimited users without additional overhead. See FCM Mathematical Foundations for detailed formulas.
Price Oracle
The Price Oracle provides token prices in terms of the default token (MOET):
_19graph TB_19 subgraph "Oracle Safety Features"_19 S1[Staleness Checks<br/>Price not too old]_19 S2[Deviation Guards<br/>Prevent extreme moves]_19 S3[TWAP Support<br/>Time-weighted prices]_19 S4[Fallback Sources<br/>Redundancy]_19 end_19_19 Oracle[Price Oracle] --> S1_19 Oracle --> S2_19 Oracle --> S3_19 Oracle --> S4_19_19 Oracle --> Prices[Token Prices<br/>in MOET terms]_19_19 Prices --> HF[Health Factor<br/>Calculations]_19 Prices --> Liq[Liquidation<br/>Triggers]_19_19 style Oracle fill:#bfb,stroke:#333,stroke-width:3px
The oracle implements the DeFi Actions PriceOracle interface, enabling standardized price queries across the protocol.
The oracle includes multiple safety features: configurable staleness thresholds per token (typically 5 minutes), maximum deviation checks against the last price snapshot, additional DEX price deviation checks during liquidations, and TWAP (Time-Weighted Average Price) support for manipulation resistance.
Key Interfaces
FungibleToken.Vault
_12graph LR_12 Vault[FungibleToken.Vault<br/>Standard Interface] --> Op1[Deposit<br/>Tokens]_12 Vault --> Op2[Withdraw<br/>Tokens]_12 Vault --> Op3[Balance<br/>Queries]_12 Vault --> Op4[Transfer<br/>Tokens]_12_12 Op1 --> Compat[Flow Ecosystem<br/>Compatibility]_12 Op2 --> Compat_12 Op3 --> Compat_12 Op4 --> Compat_12_12 style Compat fill:#bfb,stroke:#333,stroke-width:2px
ALP integrates with Flow's standard FungibleToken.Vault interface for token operations, ensuring compatibility with all Flow fungible tokens and wallets.
DeFi Actions Framework
ALP implements the DeFi Actions framework for protocol composability:
_15graph TB_15 subgraph "Sink Pattern (Push)"_15 S1[Position<br/>Overcollateralized] --> S2[Auto-Borrow<br/>MOET]_15 S2 --> S3[Push to<br/>DrawDownSink]_15 S3 --> S4[User Wallet<br/>or DeFi Protocol]_15 end_15_15 subgraph "Source Pattern (Pull)"_15 P1[Position<br/>Undercollateralized] --> P2[Need to<br/>Repay Debt]_15 P2 --> P3[Pull from<br/>TopUpSource]_15 P3 --> P4[User Wallet<br/>or DeFi Protocol]_15 end_15_15 style S1 fill:#bbf_15 style P1 fill:#fbb
The Sink Interface receives tokens when positions are overcollateralized, automatically pushing borrowed funds to user wallets or other protocols through the drawDownSink configuration on positions, enabling automated value flows out of positions. The Source Interface provides tokens when positions need rebalancing, automatically pulling funds to repay debt when undercollateralized through the topUpSource configuration, enabling automated value flows into positions.
Learn more: DeFi Actions Integration
ViewResolver
The ViewResolver interface provides metadata for wallet integration, including position details and balance sheets, supported token types, protocol parameters and configuration, and user-friendly data formatting. This enables wallets and dApps to display ALP positions with rich, contextual information.
System Architecture Diagram
_13graph TB_13 User[User Wallet] -->|Deposit/Withdraw| Position[Position]_13 Position -->|Manages| Pool[Pool Contract]_13 Pool -->|Stores| Reserves[Token Reserves]_13 Pool -->|Queries| Oracle[Price Oracle]_13 Pool -->|Updates| TokenState[TokenState per Token]_13 Position -->|Auto-Push| Sink[DrawDown Sink]_13 Position -->|Auto-Pull| Source[TopUp Source]_13 Pool -->|Liquidates| Liquidator[Liquidators/Keepers]_13_13 style Pool fill:#f9f,stroke:#333,stroke-width:4px_13 style Position fill:#bbf,stroke:#333,stroke-width:2px_13 style Oracle fill:#bfb,stroke:#333,stroke-width:2px
Data Flow
Deposit Flow
_16sequenceDiagram_16 participant User_16 participant Position_16 participant Pool_16 participant TokenState_16 participant Sink_16_16 User->>Position: deposit()_16 Position->>Pool: Transfer tokens to reserves_16 Pool->>Pool: Update scaled balance_16 Pool->>TokenState: Update totals_16 Pool->>Pool: Check if overcollateralized_16 alt Overcollateralized & DrawDownSink enabled_16 Pool->>Pool: Auto-borrow_16 Pool->>Sink: Push borrowed tokens_16 end
Steps:
- User calls
deposit()on their Position - Position transfers tokens to Pool reserves
- Pool updates user's scaled balance
- Pool updates global TokenState
- If
drawDownSinkenabled and overcollateralized → auto-borrow
Borrow Flow
_16sequenceDiagram_16 participant User_16 participant Position_16 participant Pool_16 participant Reserves_16_16 User->>Position: withdraw(debt token)_16 Position->>Pool: Check health factor_16 alt Health would remain safe_16 Pool->>Pool: Update debt scaled balance_16 Pool->>Reserves: Transfer tokens_16 Reserves-->>User: Receive tokens_16 Pool->>Position: Update health_16 else Health would drop too low_16 Pool-->>User: Revert: Insufficient health_16 end
Steps:
- User calls
withdraw()for debt token - Pool checks health factor would remain above minimum
- Pool updates user's debt scaled balance
- Pool transfers tokens from reserves to user
- Position health is recalculated
Interest Accrual
_10graph LR_10 Time[Time Passes] --> Touch[Any Position<br/>Touched]_10 Touch --> Update[Pool Updates<br/>Interest Index]_10 Update --> Index[Index Increases<br/>Based on Utilization]_10 Index --> All[All Positions'<br/>Balances Grow<br/>Automatically]_10_10 style All fill:#bfb,stroke:#333,stroke-width:2px
Process:
- Time passes, interest accumulates
- When any position is touched, Pool updates interest indices
- Interest index increases based on utilization and rates
- All positions' true balances grow automatically via scaled balance math
Security Architecture
ALP includes multiple layers of security:
_17graph TB_17 subgraph "Security Layers"_17 L1[Health Factor<br/>Monitoring]_17 L2[Oracle<br/>Safety]_17 L3[Liquidation<br/>Mechanisms]_17 L4[Circuit<br/>Breakers]_17 L5[Access<br/>Controls]_17 end_17_17 Protocol[Protocol<br/>Operations] --> L1_17 L1 -->|Pass| L2_17 L2 -->|Pass| L3_17 L3 -->|Pass| L4_17 L4 -->|Pass| L5_17 L5 -->|Pass| Execute[Execute<br/>Operation]_17_17 style Execute fill:#bfb
- Health factor monitoring: Continuous tracking of position solvency
- Oracle safety: Staleness and deviation checks
- Liquidation mechanisms: Multiple paths to resolve undercollateralized positions
- Circuit breakers: Ability to pause operations in emergencies
- Access controls: Permissioned functions for admin operations
Gas Optimization
The architecture is optimized for gas efficiency:
_14graph LR_14 subgraph "Gas Optimizations"_14 O1[Scaled Balances<br/>No per-user updates]_14 O2[Batch Operations<br/>Multiple in one tx]_14 O3[Efficient Storage<br/>Compact structures]_14 O4[Lazy Updates<br/>Calculate on-demand]_14 end_14_14 O1 --> Result[Minimal<br/>Gas Costs]_14 O2 --> Result_14 O3 --> Result_14 O4 --> Result_14_14 style Result fill:#bfb,stroke:#333,stroke-width:3px
The architecture is optimized for gas efficiency through scaled balances that eliminate per-user interest updates, batch operations that allow single transactions to update multiple positions, efficient storage using compact data structures for on-chain state, and lazy updates that only calculate interest when needed.
Upgradability
The protocol includes mechanisms for upgrades and parameter adjustments:
_16graph TD_16 Admin[Protocol Admin] --> Functions[Admin Functions]_16_16 Functions --> Rate[Adjust Interest<br/>Rates]_16 Functions --> Factor[Update Collateral<br/>Factors]_16 Functions --> Token[Add New<br/>Tokens]_16 Functions --> Oracle[Switch Price<br/>Feeds]_16 Functions --> Feature[Enable/Disable<br/>Features]_16_16 Rate --> Protocol[Protocol<br/>Configuration]_16 Factor --> Protocol_16 Token --> Protocol_16 Oracle --> Protocol_16 Feature --> Protocol_16_16 style Protocol fill:#f9f,stroke:#333,stroke-width:2px
The protocol supports admin functions to adjust interest rates and collateral factors, dynamic token addition to support new tokens, oracle updates to switch price feed sources, and feature flags to enable or disable features like liquidations.
Summary
Core Architecture:
- 🏗️ Modular design with Pool, Position, TokenState, and Oracle
- 🔗 DeFi Actions framework for composability
- 📊 Scaled balance system for efficiency
- 🛡️ Multiple security layers
Key Benefits:
- ✅ Gas efficient scaled balance system
- ✅ Automated flows via Sink/Source interfaces
- ✅ Robust oracle safety features
- ✅ Multi-layer security architecture
- ✅ Flexible and upgradable design
Integration Points:
- Flow FungibleToken standard
- DeFi Actions Sink/Source
- ViewResolver for wallets
- Price Oracle interface
Mathematical Foundation
The architecture implements these mathematical principles:
- Scaled Balances: Interest Mathematics
- Health Calculations: Health Factor Formula
- Effective Collateral: Collateral Calculation
- Multi-Token Support: Multi-Collateral Math
See FCM Mathematical Foundations for complete formulas and proofs.
Next Steps
- Understand operations: Credit Market Mechanics
- Learn about safety: Liquidation System
- Explore automation: Position Lifecycle
- See the big picture: FCM Architecture
ALP's modular architecture combines efficiency with security. The scaled balance system eliminates gas overhead, DeFi Actions enable composability, and multiple security layers protect users. This design makes ALP both powerful for developers and accessible for users.