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
| Property | Value |
|---|---|
| License | BUSL-1.1 |
| Solidity | ^0.8.25 |
| Inheritance | IPoolFactory, 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:
| Name | Type | Description |
|---|---|---|
| initialOwner | address | Factory 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:
| Name | Type | Description |
|---|---|---|
| tokenA | IFHERC20 | First token address |
| tokenB | IFHERC20 | Second token address |
| swapFee | uint24 | Swap fee in basis points |
Returns:
| Name | Type | Description |
|---|---|---|
| pool | address | Deployed 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:
- Deploys new PrivacyPool
- Deploys new PositionNFT
- Configures pool with PositionNFT
- Transfers ownership to caller
- 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:
| Name | Type | Description |
|---|---|---|
| fee | uint24 | New 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)andcreatePool(tokenB, tokenA)create the same poolgetPool(tokenA, tokenB)returns the same result asgetPool(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