-
Notifications
You must be signed in to change notification settings - Fork 546
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add PoolManager Concept doc with updated mdx formatting (#753)
- Loading branch information
1 parent
c27116d
commit 28091bd
Showing
1 changed file
with
87 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
--- | ||
title: 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 `PoolManager` contract | ||
|
||
## Locking Mechanism | ||
|
||
- The `PoolManager` uses 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 `PoolManager` for final solvency checks | ||
|
||
## Pool State | ||
|
||
- The `Pool.State` struct 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 `PoolManager` contract 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 `initialize` function on the `PoolManager` | ||
- The pool creator specifies the token pair, fee tier, tick spacing, and optional hook contract address | ||
- The `PoolManager` initializes the pool state and associates it with a unique `PoolId` | ||
|
||
## Swaps | ||
|
||
- Swaps are initiated through the `swap` function on the `PoolManager`, typically via a swap router contract | ||
- The `PoolManager` executes the following steps: | ||
1. Checks if the pool is valid and initialized | ||
2. Executes the `beforeSwap` hook, if applicable | ||
3. Performs the actual swap, updating the pool state and charging fees | ||
4. Executes the `afterSwap` hook, if applicable | ||
5. Calculates the net token amounts owed to the user and the pool, represented by the `BalanceDelta` struct | ||
- 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 `modifyLiquidity` function on the `PoolManager`. 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 `PoolManager` executes the following steps: | ||
1. Checks if the pool is valid and initialized | ||
2. Determines if the modification is an addition or removal of liquidity | ||
3. Executes the appropriate `beforeAddLiquidity` or `beforeRemoveLiquidity` hook, if applicable | ||
4. Performs the actual liquidity modification and updates the pool state | ||
5. Emits the `ModifyLiquidity` event | ||
6. Executes the appropriate `afterAddLiquidity` or `afterRemoveLiquidity` hook, if applicable | ||
7. Calculates the balance delta and returns it to the caller | ||
|
||
## Flash Accounting | ||
|
||
- The `PoolManager` employs flash accounting to reduce gas costs and simplify multi-hop swaps | ||
- Tokens are moved into the `PoolManager` contract, and all subsequent actions are performed within the contract's context | ||
- Only the final output tokens are withdrawn from the `PoolManager` at the end of the transaction | ||
|
||
# Transient Storage | ||
|
||
- The `PoolManager` utilizes 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 |