Create a Pool
Learn how to create a trading pool on Unichain
Summary
Create a pool and add initial liquidity to enable trading of the token
The guide prioritizes Uniswap v4, however developers can elect to create pools on Uniswap v2 or Uniswap v3
Requirements
ETH on Unichain is required, see Funding a Wallet
-
The guide uses foundry for deployments. Install it by running:
-
Add Unichain to your
foundry.toml
-
Add Uniswap v4 dependencies
For a fully setup repository, see v4-template
For Uniswap contract addresses please see Contract Addresses
Uniswap v4
The guide serves as additional material to Uniswap v4 docs
Create a Pool & Add Liquidity
Uniswap v4's PositionManager
supports atomic creation of a pool and initial liquidity using multicall. Developers can create a trading pool, with liquidity, in a single transaction:
-
Initialize the parameters provided to
multicall()
- The first call,
params[0]
, will encodeinitializePool
parameters - The second call,
params[1]
, will encode a mint operation formodifyLiquidities
- The first call,
-
Configure the pool
For native token pairs (Ether), use
CurrencyLibrary.ADDRESS_ZERO
ascurrency0
- Currencies should be sorted,
uint160(currency0) < uint160(currency1)
- lpFee is the fee expressed in pips, i.e. 3000 = 0.30%
- tickSpacing is the granularity of the pool. Lower values are more precise but more expensive to trade
- hookContract is the address of the hook contract
- Currencies should be sorted,
-
Encode the
initializePool
parametersPools are initialized with a starting price
- the startingPrice is expressed as sqrtPriceX96:
floor(sqrt(token1 / token0) * 2^96)
79228162514264337593543950336
is the starting price for a 1:1 pool
- the startingPrice is expressed as sqrtPriceX96:
-
Initialize the mint-liquidity parameters
PositionManager's
modifyLiquidities
uses an encoded command system- The first command
MINT_POSITION
creates a new liquidity position - The second command
SETTLE_PAIR
indicates that tokens are to be paid by the caller, to create the position
- The first command
-
Encode the
MINT_POSITION
parameters- pool the same
PoolKey
defined above, in pool-creation - tickLower and tickUpper are the range of the position, must be a multiple of
pool.tickSpacing
- liquidity is the amount of liquidity units to add, see
LiquidityAmounts
for converting token amounts to liquidity units - amount0Max and amount1Max are the maximum amounts of token0 and token1 the caller is willing to transfer
- recipient is the address that will receive the liquidity position (ERC-721)
- hookData is the optional hook data
- pool the same
-
Encode the
SETTLE_PAIR
parametersCreating a position on a pool requires the caller to transfer
currency0
andcurrency1
tokens -
Encode the
modifyLiquidites
call -
Approve the tokens
PositionManager
usesPermit2
for token transfers- Repeat for both tokens
-
Execute the multicall
- The
multicall
is used to execute multiple calls in a single transaction
For pools paired with native tokens (Ether), provide
value
in the contract callExcess Ether is NOT refunded unless developers encoded
SWEEP
in theactions
parameter - The
For a full end-to-end script, developers should see v4-template#script
Create a Pool Only
To initialize a Uniswap v4 Pool without initial liquidity, developers should call PoolManager.initialize()
-
Configure the pool
For native token pairs (Ether), use
CurrencyLibrary.ADDRESS_ZERO
ascurrency0
- Currencies should be sorted,
uint160(currency0) < uint160(currency1)
- lpFee is the fee expressed in pips, i.e. 3000 = 0.30%
- tickSpacing is the granularity of the pool. Lower values are more precise but more expensive to trade
- hookContract is the address of the hook contract
- Currencies should be sorted,
-
Call
initialize
Pools are initialized with a starting price- the startingPrice is expressed as sqrtPriceX96:
floor(sqrt(token1 / token0) * 2^96)
79228162514264337593543950336
is the starting price for a 1:1 pool
- the startingPrice is expressed as sqrtPriceX96:
Uniswap v3
Developers can opt for the battle-tested Uniswap v3 and create a pool with the UniswapV3Factory
contract.
- Install Uniswap v3 dependencies
- Create a pool with
UniswapV3Factory
Additional documentation
- tokenA and tokenB are the ERC20 token addresses
- the ordering does not matter, however the alphabetically-lower address is assigned to
token0
- the ordering does not matter, however the alphabetically-lower address is assigned to
- Starting price is determined by the initial liquidity added
- The
pair
address return-value corresponds to aUniswapV3Pool
contract
Valid fee values are:
Fee | Fee Value |
---|---|
0.01% | 100 |
0.05% | 500 |
0.30% | 3000 |
1.00% | 10_000 |
To create a pool with initial liquidity, developers should use multicall PoolInitializer and NonfungiblePositionManager.mint
Uniswap v2
Developers can opt for Uniswap v2's simplicity and create a pool with the UniswapV2Factory
contract. Note that pools on Uniswap v2 trade with a fixed 0.30% fee
- Install Uniswap v2 dependencies
- Create a pool with
UniswapV2Factory
Additional documentation
- tokenA and tokenB are the ERC20 token addresses
- the ordering does not matter, however the alphabetically-lower address is assigned to
token0
- the ordering does not matter, however the alphabetically-lower address is assigned to
- Starting price is determined by the initial liquidity added
- The
pair
address return-value corresponds to aUniswapV2Pair
contract - The pair trades on a fixed 0.30% fee, and is not configurable
To create a pool with initial liquidity, developers should reference addLiquidity. If a pool does not exist, one is automatically created
Last updated on