Factory

Contract designed to deploy and manage multiple instances of `SplitRiskPool`

Overview

The SplitRiskPoolFactory is a factory contract responsible for creating and managing insurance pools in the YieldShield protocol. It ensures that only valid token pairs can be used to create pools and maintains a registry of all created pools.

Purpose

The factory contract serves as the entry point for creating new insurance pools. It handles:

  • Pool Creation: Deploying new SplitRiskPool instances with custom parameters
  • Token Whitelisting: Governance-controlled whitelist for supported tokens
  • Pool Registry: Tracking all created pools for discovery and management
  • Validation: Comprehensive parameter validation before pool creation

Key Concepts

  • Insured Tokens: Yield-bearing tokens that users want to insure (e.g., ERC4626 vault tokens, Aave aTokens)
  • Underwriter Tokens: Collateral tokens provided by underwriters to back insured deposits
  • Token Whitelist: Governance-controlled list of approved tokens that can be used in pools
  • TokenInfo: Struct containing token metadata (address, symbol, vault address, token type)

Contract Details

Inheritance

  • ISplitRiskPoolFactory: Interface implementation
  • Ownable: Access control for owner-only functions
  • ReentrancyGuard: Protection against reentrancy attacks

State Variables

address public governanceTimelock;  // Governance timelock contract address
address public priceOracle;          // Price oracle contract address (optional)
address[] public whitelistedTokens;  // Array of whitelisted token addresses
mapping(address => bool) public isWhitelisted;  // Whitelist status mapping
mapping(address => TokenWhitelistLib.TokenInfo) public tokenInfo;  // Token metadata
address[] public pools;  // Registry of all created pools
mapping(address => ISplitRiskPoolFactory.PoolInfo) private _poolInfo;  // Pool information

Constructor

constructor(
    address _governanceTimelock,
    address _priceOracle
) Ownable(msg.sender)

Parameters:

  • _governanceTimelock: Address of the governance timelock contract (required, cannot be zero)
  • _priceOracle: Address of the price oracle contract (can be address(0) if not using oracle)

Effects:

  • Sets the contract owner to msg.sender
  • Initializes governance timelock and price oracle addresses
  • Reverts if governance timelock is zero address

Core Functions

createPool

Creates a new SplitRiskPool instance with the specified parameters.

function createPool(
    address _insuredToken,
    string memory _insuredTokenSymbol,
    address _underwriteToken,
    string memory _underwriteTokenSymbol,
    uint256 _commissionRate,
    uint256 _poolFee,
    uint256 _colleteralRatio
) external nonReentrant returns (address poolAddress)

Parameters:

  • _insuredToken: Address of the insured yield-bearing token
  • _insuredTokenSymbol: Symbol for the insured token (e.g., "iUSDC")
  • _underwriteToken: Address of the underwriter token
  • _underwriteTokenSymbol: Symbol for the underwriter token (e.g., "uUSDC")
  • _commissionRate: Commission rate in basis points (e.g., 100 = 1%)
  • _poolFee: Pool creator fee rate in basis points (e.g., 50 = 0.5%)
  • _colleteralRatio: Collateral ratio in basis points (e.g., 15000 = 150%)

Returns:

  • poolAddress: Address of the newly created pool

Requirements:

  • Both tokens must be whitelisted (or will use default ERC4626 configuration)
  • Tokens must be different addresses
  • Parameters must be within valid ranges (validated by PoolValidationLib)
  • Symbols must be non-empty

Effects:

  • Deploys a new SplitRiskPool contract
  • Adds pool address to the pools array
  • Stores pool information in _poolInfo mapping
  • Emits PoolCreated event

Example:

address poolAddress = factory.createPool(
    0x123...,  // insuredToken
    "iUSDC",   // insuredTokenSymbol
    0x456...,  // underwriteToken
    "uUSDC",   // underwriteTokenSymbol
    100,       // 1% commission
    50,        // 0.5% pool fee
    15000      // 150% collateral ratio
);

Token Management

addToken (Governance Only)

Adds a token to the whitelist. Only callable by governance timelock.

function addToken(
    address token,
    string memory name,
    string memory symbol,
    address vault,
    uint16 tokenType
) external

Parameters:

  • token: Address of the token to whitelist
  • name: Name of the token
  • symbol: Symbol of the token
  • vault: Vault address (if applicable, can be address(0))
  • tokenType: Type of token (see Token Types below)

Token Types:

  • 0: ERC4626 vault token
  • 1: Aave aToken
  • 2: Other yield-bearing token types

Requirements:

  • Caller must be governance timelock
  • Token must not already be whitelisted

Effects:

  • Adds token to whitelistedTokens array
  • Sets isWhitelisted[token] = true
  • Stores TokenInfo in tokenInfo mapping

removeToken (Governance Only)

Removes a token from the whitelist.

function removeToken(address token) external

Parameters:

  • token: Address of the token to remove

Requirements:

  • Caller must be governance timelock
  • Token must be whitelisted

Effects:

  • Removes token from whitelistedTokens array
  • Sets isWhitelisted[token] = false
  • Does not remove tokenInfo (for historical reference)

addTokenInitial (Owner Only)

Adds a token during initial deployment. Only callable by contract owner.

function addTokenInitial(
    address token,
    string memory name,
    string memory symbol,
    address vault,
    uint16 tokenType
) external onlyOwner

Parameters:

  • Same as addToken

Use Case:

  • Allows owner to bootstrap the whitelist during deployment
  • Useful for initial token setup before governance is fully operational

View Functions

getAllPools

Returns an array of all created pool addresses.

function getAllPools() external view returns (address[] memory)

Returns:

  • Array of pool addresses in creation order

Use Case:

  • Frontend integration for pool discovery
  • Registry queries
  • Analytics and monitoring

getPoolInfo

Returns detailed information about a specific pool.

function getPoolInfo(address _poolAddress) 
    external 
    view 
    returns (ISplitRiskPoolFactory.PoolInfo memory)

Parameters:

  • _poolAddress: Address of the pool to query

Returns:

  • insuredToken: Address of the insured token
  • underwriteToken: Address of the underwriter token
  • insuredTokenSymbol: Symbol of insured token
  • underwriteTokenSymbol: Symbol of underwriter token
  • commissionRate: Commission rate in basis points
  • poolFee: Pool fee in basis points
  • colleteralRatio: Collateral ratio in basis points
  • createdAt: Timestamp of pool creation
  • creator: Address of the pool creator

Reverts:

  • If pool does not exist (PoolDoesNotExist error)

Example:

ISplitRiskPoolFactory.PoolInfo memory info = factory.getPoolInfo(poolAddress);
console.log("Pool creator:", info.creator);
console.log("Commission rate:", info.commissionRate);

getWhitelistedTokens

Returns an array of all whitelisted token addresses.

function getWhitelistedTokens() external view returns (address[] memory)

Returns:

  • Array of whitelisted token addresses

Use Case:

  • Displaying available tokens in UI
  • Validating token eligibility before pool creation

Governance Functions

setGovernanceTimelock (Owner Only)

Updates the governance timelock address.

function setGovernanceTimelock(address newGovernanceTimelock) external onlyOwner

Parameters:

  • newGovernanceTimelock: New governance timelock address

Requirements:

  • Caller must be contract owner
  • New address must not be zero

Effects:

  • Updates governanceTimelock state variable
  • Future governance functions will use the new address

Security Features

Access Control

  • Owner: Can update governance timelock address
  • Governance Timelock: Can add/remove tokens from whitelist
  • Anyone: Can create pools and query information

Reentrancy Protection

The createPool function is protected with nonReentrant modifier to prevent reentrancy attacks.

Input Validation

All functions validate inputs:

  • Addresses are checked for zero address where required
  • Token whitelist status is verified
  • Pool parameters are validated through PoolValidationLib
  • Duplicate tokens are prevented

Events

The contract emits the following events:

  • PoolCreated: Emitted when a new pool is created

    event PoolCreated(
        address indexed pool,
        address indexed insuredToken,
        address indexed underwriteToken,
        uint256 commissionRate,
        uint256 poolFee,
        uint256 colleteralRatio,
        address creator
    );
    
  • TokenAdded: Emitted when a token is added to whitelist

  • TokenRemoved: Emitted when a token is removed from whitelist

Usage Examples

Creating a Pool

// 1. Ensure tokens are whitelisted (or will use defaults)
// 2. Call createPool with desired parameters

address poolAddress = factory.createPool(
    insuredToken,
    "iUSDC",
    underwriterToken,
    "uUSDC",
    100,      // 1% commission
    50,       // 0.5% pool fee
    15000     // 150% collateral ratio
);

console.log("New pool created at:", poolAddress);

Querying Pool Information

// Get all pools
address[] memory allPools = factory.getAllPools();
console.log("Total pools:", allPools.length);

// Get specific pool info
ISplitRiskPoolFactory.PoolInfo memory info = factory.getPoolInfo(allPools[0]);
console.log("Pool creator:", info.creator);
console.log("Commission rate:", info.commissionRate, "basis points");

Managing Token Whitelist (Governance)

// Add a new token (governance only)
factory.addToken(
    0xABC...,  // token address
    "USD Coin",
    "USDC",
    0xDEF...,  // vault address
    0          // ERC4626 type
);

// Remove a token (governance only)
factory.removeToken(0xABC...);

Integration Guide

For Frontend Developers

  1. Discover Pools: Use getAllPools() to get all available pools
  2. Get Pool Details: Use getPoolInfo() for each pool address
  3. Check Token Support: Use getWhitelistedTokens() to show available tokens
  4. Create Pool: Call createPool() after user approval

For Smart Contract Developers

  1. Import Interface:

    import {ISplitRiskPoolFactory} from "./interfaces/ISplitRiskPoolFactory.sol";
    
  2. Get Factory Instance:

    ISplitRiskPoolFactory factory = ISplitRiskPoolFactory(factoryAddress);
    
  3. Create Pool:

    address pool = factory.createPool(...);
    
  4. Interact with Pool:

    ISplitRiskPool poolContract = ISplitRiskPool(pool);
    poolContract.depositInsuredAsset(...);
    

Important Notes

  1. Token Whitelisting: Tokens must be whitelisted before pool creation (or will use default ERC4626 config)
  2. Pool Parameters: Commission rate, pool fee, and collateral ratio are immutable once set
  3. Governance: Token whitelist management is controlled by governance timelock
  4. Pool Registry: All pools are permanently registered and cannot be removed