Skip to main content

PoolFactory

Factory contract for deploying and managing PrivacyPool instances.

Overview

PoolFactory provides a standardized way to create new liquidity pools. It ensures:

  • One pool per token pair
  • Consistent pool configuration
  • Automatic PositionNFT deployment
  • Pool registry for discovery

Contract Details

PropertyValue
LicenseBUSL-1.1
Solidity^0.8.25
InheritanceIPoolFactory, Ownable, ReentrancyGuard

Constants

uint24 public constant MAX_SWAP_FEE = 100_000;    // 10% maximum
uint256 private constant BPS_DENOMINATOR = 1_000_000;

State Variables

uint24 public defaultSwapFee = 3000;              // 0.3% default
address public protocolFeeRecipient; // Protocol fee receiver
address public positionNFTImplementation; // NFT implementation (optional)
mapping(bytes32 => address) private _pools; // Pair hash to pool
mapping(bytes32 => PoolInfo) private _poolInfo; // Pool metadata
address[] private _allPools; // All pool addresses

Structs

PoolInfo

struct PoolInfo {
address pool; // Pool contract address
address tokenA; // First token (sorted)
address tokenB; // Second token (sorted)
uint24 swapFee; // Fee in basis points
uint256 createdAt; // Creation timestamp
bool exists; // Existence flag
}

Constructor

constructor(address initialOwner)

Parameters:

NameTypeDescription
initialOwneraddressFactory owner and initial protocol fee recipient

Functions

Pool Creation

createPool (with fee)

Create a new pool with a custom swap fee.

function createPool(
IFHERC20 tokenA,
IFHERC20 tokenB,
uint24 swapFee
) external nonReentrant returns (address pool)

Parameters:

NameTypeDescription
tokenAIFHERC20First token address
tokenBIFHERC20Second token address
swapFeeuint24Swap fee in basis points

Returns:

NameTypeDescription
pooladdressDeployed pool address

Requirements:

  • Token addresses must be non-zero
  • Tokens must be different
  • Fee must not exceed MAX_SWAP_FEE
  • Pool must not exist for this pair

Effects:

  1. Deploys new PrivacyPool
  2. Deploys new PositionNFT
  3. Configures pool with PositionNFT
  4. Transfers ownership to caller
  5. Registers pool in factory

createPool (default fee)

Create a pool with the default swap fee.

function createPool(
IFHERC20 tokenA,
IFHERC20 tokenB
) external returns (address pool)

Pool Queries

getPool

Get pool address for a token pair.

function getPool(
address tokenA,
address tokenB
) external view returns (address pool)

Note: Returns address(0) if pool doesn't exist.

getPoolInfo

Get detailed pool information.

function getPoolInfo(
address tokenA,
address tokenB
) external view returns (PoolInfo memory info)

Reverts: If pool doesn't exist.

poolExists

Check if a pool exists for a token pair.

function poolExists(
address tokenA,
address tokenB
) external view returns (bool exists)

allPools

Get pool address by index.

function allPools(uint256 index) external view returns (address pool)

allPoolsLength

Get total number of created pools.

function allPoolsLength() external view returns (uint256 count)

getAllPools

Get all pool addresses.

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

Configuration

setDefaultSwapFee

Set the default fee for new pools.

function setDefaultSwapFee(uint24 fee) external onlyOwner

Parameters:

NameTypeDescription
feeuint24New default fee in basis points

Requirements:

  • Fee must not exceed MAX_SWAP_FEE

setProtocolFeeRecipient

Set the protocol fee recipient.

function setProtocolFeeRecipient(address recipient) external onlyOwner

Requirements:

  • Recipient must be non-zero address

setPositionNFTImplementation

Set the position NFT implementation (for future use).

function setPositionNFTImplementation(address implementation) external onlyOwner

Events

event PoolCreated(
address indexed pool,
address indexed tokenA,
address indexed tokenB,
uint24 swapFee,
address creator
);

event DefaultSwapFeeUpdated(uint24 oldFee, uint24 newFee);

event ProtocolFeeRecipientUpdated(
address oldRecipient,
address newRecipient
);

event PositionNFTImplementationUpdated(
address oldImplementation,
address newImplementation
);

Errors

error PoolAlreadyExists(address tokenA, address tokenB);
error IdenticalTokens();
error ZeroAddress();
error SwapFeeTooHigh(uint24 fee, uint24 maxFee);
error PoolDoesNotExist(address tokenA, address tokenB);

Token Ordering

Tokens are automatically sorted by address to ensure consistent pool identification:

function _sortTokens(
IFHERC20 tokenA,
IFHERC20 tokenB
) private pure returns (IFHERC20 token0, IFHERC20 token1) {
(token0, token1) = address(tokenA) < address(tokenB)
? (tokenA, tokenB)
: (tokenB, tokenA);
}

This means:

  • createPool(tokenA, tokenB) and createPool(tokenB, tokenA) create the same pool
  • getPool(tokenA, tokenB) returns the same result as getPool(tokenB, tokenA)

Pool Pair Hash

Pools are indexed by a hash of the sorted token addresses:

function _getPairHash(
address token0,
address token1
) private pure returns (bytes32) {
return keccak256(abi.encodePacked(token0, token1));
}

Usage Example

// Deploy factory
PoolFactory factory = new PoolFactory(owner);

// Create pool with custom fee
address pool = factory.createPool(tokenA, tokenB, 5000); // 0.5% fee

// Create pool with default fee
address pool2 = factory.createPool(tokenC, tokenD);

// Query pool
address existingPool = factory.getPool(tokenA, tokenB);

// Get pool info
IPoolFactory.PoolInfo memory info = factory.getPoolInfo(tokenA, tokenB);

// Check existence
bool exists = factory.poolExists(tokenA, tokenB);

// Get all pools
address[] memory pools = factory.getAllPools();

Deployment Flow

When createPool is called:

1. Validate inputs
- Non-zero addresses
- Different tokens
- Valid fee

2. Sort tokens
- Ensure consistent ordering

3. Check uniqueness
- Verify pool doesn't exist

4. Deploy PrivacyPool
- Factory as temporary owner

5. Deploy PositionNFT
- Factory as owner

6. Configure
- Set pool as PositionNFT manager
- Set PositionNFT on pool

7. Transfer ownership
- Pool to caller
- PositionNFT to caller

8. Register
- Store in _pools mapping
- Store in _poolInfo mapping
- Add to _allPools array

9. Emit event