Pool System
StableFX operates three specialized liquidity pools that work together to ensure trade settlement, risk mitigation, and loss protection. This page explains each pool's role, the data types involved, and how to fetch pool data using the useForexPools hook.
Pool Overview
User Deposits
|
+----------+-----------+
| |
Trading Capital Pool Reserves
(50%) (50%)
|
+--------------+--------------+
| | |
Clearing (50%) Hedging (30%) Insurance (20%)
+-----------+ +-----------+ +-----------+
| Settlement| | Risk | | Loss |
| of trades| | mitigation| | protection|
+-----------+ +-----------+ +-----------+
Clearing Pool
The clearing pool is the largest reserve pool, receiving 50% of pool reserves (25% of total deposits). It holds stablecoins during the trade lifecycle -- from the moment a request-for-quote (RFQ) is issued to final settlement.
Responsibilities:
- Escrow funds during the RFQ-to-settlement window.
- Release settlement amounts to counterparties upon trade completion.
- Return funds to the clearing pool when trades are cancelled before matching.
// Clearing pool transactions follow the trade lifecycle
// RFQ issued -> funds locked in clearing pool
// Trade matched -> funds remain locked
// Trade settled -> funds released to counterparties
// Trade failed -> funds returned to clearing pool
Hedging Pool
The hedging pool receives 30% of pool reserves (15% of total deposits). It absorbs directional risk when the system's net exposure to any currency pair exceeds predefined thresholds.
Responsibilities:
- Automatically rebalance when net exposure to a pair exceeds the threshold.
- Offset losses from adverse currency movements.
- Generate yield by providing liquidity for hedging operations.
Insurance Pool
The insurance pool receives 20% of pool reserves (10% of total deposits). It acts as the last line of defense, covering losses from failed settlements, counterparty defaults, or extreme market events.
Responsibilities:
- Cover shortfalls when the clearing pool cannot fully settle a trade.
- Absorb losses from extreme market events (black swan protection).
- Funded additionally by a portion of trading fees collected across all pools.
Core Types
ForexPool
import type { ForexPool, ForexPoolType } from '@one_deploy/sdk';
type ForexPoolType = 'clearing' | 'hedging' | 'insurance';
interface ForexPool {
/** Unique identifier for this pool. */
id: string;
/** The pool category. */
type: ForexPoolType;
/** Total value locked in the pool (in USDC). */
totalValueLocked: number;
/** Current annualized percentage yield. */
apy: number;
/** Pool utilization as a decimal (0.0 to 1.0). */
utilization: number;
/** The stablecoin denomination. */
currency: string;
/** ISO-8601 creation timestamp. */
createdAt: string;
/** ISO-8601 last-update timestamp. */
updatedAt: string;
}
ForexPoolTransaction
import type { ForexPoolTransaction } from '@one_deploy/sdk';
interface ForexPoolTransaction {
/** Unique transaction identifier. */
id: string;
/** The pool this transaction belongs to. */
poolId: string;
/** Transaction type. */
type: 'deposit' | 'withdrawal' | 'fee' | 'rebalance';
/** Amount in the pool's stablecoin currency. */
amount: number;
/** Stablecoin symbol (e.g. "USDC"). */
currency: string;
/** ISO-8601 timestamp of the transaction. */
timestamp: string;
/** On-chain transaction hash, if applicable. */
txHash?: string;
}
useForexPools Hook
The useForexPools hook fetches all three pools and their current state. It requires that setForexAccessToken and setForexEngineUrl have been called first.
Hook Signature
import { useForexPools } from '@one_deploy/sdk';
function useForexPools(): UseForexPoolsResult;
UseForexPoolsResult
interface UseForexPoolsResult {
/** Array of all forex pools. */
pools: ForexPool[];
/** Whether the initial fetch is in progress. */
isLoading: boolean;
/** Error object if the fetch failed. */
error: Error | null;
/** Re-fetch pool data. */
refetch: () => Promise<void>;
/** Transactions for a specific pool. */
getPoolTransactions: (
poolId: string,
options?: { limit?: number; offset?: number }
) => Promise<ForexPoolTransaction[]>;
}
Fetching Pool Data
Basic Usage
import React from 'react';
import { View, Text, ActivityIndicator } from 'react-native';
import { useForexPools } from '@one_deploy/sdk';
function ForexPoolList() {
const { pools, isLoading, error, refetch } = useForexPools();
if (isLoading) {
return <ActivityIndicator size="large" />;
}
if (error) {
return <Text style={{ color: 'red' }}>Error: {error.message}</Text>;
}
return (
<View>
{pools.map((pool) => (
<View key={pool.id} style={{ marginBottom: 16, padding: 12 }}>
<Text style={{ fontWeight: '700', textTransform: 'capitalize' }}>
{pool.type} Pool
</Text>
<Text>TVL: ${pool.totalValueLocked.toLocaleString()}</Text>
<Text>APY: {(pool.apy * 100).toFixed(2)}%</Text>
<Text>
Utilization: {(pool.utilization * 100).toFixed(1)}%
</Text>
</View>
))}
</View>
);
}
Fetching Pool Transactions
import React, { useEffect, useState } from 'react';
import { View, Text, FlatList } from 'react-native';
import { useForexPools } from '@one_deploy/sdk';
import type { ForexPoolTransaction } from '@one_deploy/sdk';
function PoolTransactions({ poolId }: { poolId: string }) {
const { getPoolTransactions } = useForexPools();
const [transactions, setTransactions] = useState<ForexPoolTransaction[]>([]);
useEffect(() => {
getPoolTransactions(poolId, { limit: 20 }).then(setTransactions);
}, [poolId, getPoolTransactions]);
return (
<FlatList
data={transactions}
keyExtractor={(tx) => tx.id}
renderItem={({ item }) => (
<View style={{ padding: 8, borderBottomWidth: 1, borderColor: '#333' }}>
<Text style={{ color: '#fff' }}>
{item.type.toUpperCase()} -- ${item.amount.toLocaleString()} {item.currency}
</Text>
<Text style={{ color: '#888', fontSize: 12 }}>
{new Date(item.timestamp).toLocaleString()}
</Text>
{item.txHash && (
<Text style={{ color: '#4488ff', fontSize: 12 }}>
Tx: {item.txHash.slice(0, 10)}...{item.txHash.slice(-8)}
</Text>
)}
</View>
)}
/>
);
}
Filtering Pools by Type
import { useForexPools } from '@one_deploy/sdk';
import type { ForexPool, ForexPoolType } from '@one_deploy/sdk';
function usePoolByType(type: ForexPoolType): ForexPool | undefined {
const { pools } = useForexPools();
return pools.find((pool) => pool.type === type);
}
// Usage
function ClearingPoolCard() {
const clearingPool = usePoolByType('clearing');
if (!clearingPool) return null;
return (
<View>
<Text>Clearing Pool</Text>
<Text>TVL: ${clearingPool.totalValueLocked.toLocaleString()}</Text>
</View>
);
}
Pool Lifecycle
1. User deposits $10,000 USDC
|
2. computePoolAllocations splits the deposit
|-- Trading capital: $5,000
|-- Clearing pool: $2,500
|-- Hedging pool: $1,500
|-- Insurance pool: $1,000
|
3. Pools receive deposits (ForexPoolTransaction type: 'deposit')
|
4. Trades execute and settle through the clearing pool
|
5. Hedging pool rebalances when exposure thresholds are hit
|
6. Insurance pool covers any settlement shortfalls
|
7. Trading fees are collected and partially routed to insurance
Next Steps
- Currency Pairs -- the 6 pairs traded through these pools.
- Pool Metrics -- daily snapshots and performance analytics.
- Components: OneForexPoolCard -- React Native pool card component.