Helpful?
PoolManager
In Uniswap V3, each liquidity pool was represented by a separate smart contract deployed through the UniswapV3Factory contract. While this approach provided flexibility, it also led to increased gas costs for pool creation and multi-hop swaps.
Uniswap V4 addresses this issue by introducing the Singleton design pattern. The PoolManager contract now serves as a single entry point for all liquidity pools. Instead of deploying separate contracts for each pool, the pool state and logic are encapsulated within the PoolManager itself.
Purpose
The primary purpose of the PoolManager is to:
- Efficiently manage liquidity pools
- Facilitate token swaps
- Reduce gas costs compared to the factory-based approach in Uniswap V3
- Enable extensibility through hooks
Architecture
Singleton Design
- Uniswap V4 uses a Singleton design pattern for the PoolManager
- All pool state and logic are encapsulated within the PoolManagercontract
Locking Mechanism
- The PoolManageruses a locking mechanism to allow for flash accounting (also known as deferred balance accounting)
- When unlocked, the calling contract can perform various operations and zero-out outstanding balances before returning control to the PoolManagerfor final solvency checks
Pool State
- The Pool.Statestruct contains information such as:- Current price
- Liquidity
- Tick bitmap
- Fee growth
- Position information
 
Libraries
- The pool logic is implemented using Solidity libraries to keep the PoolManagercontract modular and gas-efficient
- These libraries are:- Pool: Contains core pool functionality, such as swaps and liquidity management
- Hooks: Handles the execution of hook functions
- Position: Manages liquidity positions within a pool
 
Core Functionality
Pool Creation
- New pools are created by calling the initializefunction on thePoolManager
- The pool creator specifies the token pair, fee tier, tick spacing, and optional hook contract address
- The PoolManagerinitializes the pool state and associates it with a uniquePoolId
Swaps
- Swaps are initiated through the swapfunction on thePoolManager, typically via a swap router contract
- The PoolManagerexecutes the following steps:- Checks if the pool is valid and initialized
- Executes the beforeSwaphook, if applicable
- Performs the actual swap, updating the pool state and charging fees
- Executes the afterSwaphook, if applicable
- Calculates the net token amounts owed to the user and the pool, represented by the BalanceDeltastruct
 
- Swaps utilize flash accounting, where tokens are moved into the PoolManager, and only the final output tokens are withdrawn
Liquidity Management
- Liquidity providers can add or remove liquidity using the modifyLiquidityfunction on thePoolManager. However, you wouldn't call this directly from your application, you would call this from a periphery contract to handle the locking & unlocking a particular pool.
- The PoolManagerexecutes the following steps:- Checks if the pool is valid and initialized
- Determines if the modification is an addition or removal of liquidity
- Executes the appropriate beforeAddLiquidityorbeforeRemoveLiquidityhook, if applicable
- Performs the actual liquidity modification and updates the pool state
- Emits the ModifyLiquidityevent
- Executes the appropriate afterAddLiquidityorafterRemoveLiquidityhook, if applicable
- Calculates the balance delta and returns it to the caller
 
Flash Accounting
- The PoolManageremploys flash accounting to reduce gas costs and simplify multi-hop swaps
- Tokens are moved into the PoolManagercontract, and all subsequent actions are performed within the contract's context
- Only the final output tokens are withdrawn from the PoolManagerat the end of the transaction
Transient Storage
- The PoolManagerutilizes transient storage (EIP-1153) to store temporary data during complex operations
- Transient storage reduces gas costs by avoiding regular storage operations for data only needed within a single transaction