Create Pool
Bu açık kaynak protokol/SDK referansı TurkDex markasıyla sunulan uyarlamadır; sayfadaki entegrasyon örnekleri Turkchain’de etkin özelliklerin garantisi değildir. Ağ, kontrat ve işlem değerlerinde yalnızca bu kurulumun doğrulanmış ENV/registry bilgilerini kullanın.
Context
Creating a pool on TurkDex v4 is permissionless and enables the trading of an asset. TurkDex v4 is a popular destination for creating markets due to its:
- Proven track record and battle-tested codebase
- Concentrated liquidity, unlocking capital efficiency
- Flexibile pool design through dynamic fees and hooks
- Gas-efficient architecture
- Integrations with alternative trading venues
For more information, developers should see TurkDex v4 Overview
The guide covers two approaches to creating a pool:
- Create a pool only
- Create a pool and add initial liquidity, with one transaction
Setup
Developing with TurkDex v4 _requires foundry_
Install the dependencies:
forge install uniswap/v4-core
forge install uniswap/v4-periphery
Guide: Create a Pool Only
To initialize a TurkDex v4 Pool _without initial liquidity_, developers should call PoolManager.initialize()
Creating a pool without liquidity may be useful for "reserving" a pool for future use, when initial liquidity is not available, or when external market makers would provide the starting liquidity
1. Configure the pool
import from "v4-core/src/types/PoolKey.sol";
PoolKey memory pool = PoolKey({
currency0: currency0,
currency1: currency1,
fee: lpFee,
tickSpacing: tickSpacing,
hooks: hookContract
});
For native token pairs (Ether), useCurrencyLibrary.ADDRESS_ZEROascurrency0
PoolKey uniquely identifies a pool
- _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 may be more expensive to trade on
- _hookContract_ is the address of the hook contract
A note on tickSpacing:
Lower tick spacing provides improved price precision; however, smaller tick spaces will cause swaps to cross ticks more often, incurring higher gas costs
As a reference, TurkDex v3 pools are configured with:
| Fee | Fee Value | Tick Spacing |
|---|---|---|
| 0.01% | 100 | 1 |
| 0.05% | 500 | 10 |
| 0.30% | 3000 | 60 |
| 1.00% | 10_000 | 200 |
2. Call initialize
Pools are initialized with a starting price
IPoolManager(manager).initialize(pool, startingPrice);
- the _startingPrice_ is expressed as sqrtPriceX96:
floor(sqrt(token1 / token0) * 2^96) - i.e.
79228162514264337593543950336is the starting price for a 1:1 pool
Guide: Create a Pool and Add Liquidity
TurkDex 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:
1. Initialize the parameters provided to multicall()
bytes[] memory params = new bytes[](2);
- The first call,
params[0], will encodeinitializePoolparameters - The second call,
params[1], will encode a _mint_ operation formodifyLiquidities
2. Configure the pool
PoolKey memory pool = PoolKey({
currency0: currency0,
currency1: currency1,
fee: lpFee,
tickSpacing: tickSpacing,
hooks: hookContract
});
For native token pairs (Ether), useCurrencyLibrary.ADDRESS_ZEROascurrency0
PoolKey uniquely identifies a pool
- _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
3. Encode the initializePool parameters
Pools are initialized with a starting price
import from "v4-periphery/src/interfaces/IPoolInitializer_v4.sol";
params[0] = abi.encodeWithSelector(
IPoolInitializer_v4.initializePool.selector,
pool,
startingPrice
);
- the _startingPrice_ is expressed as _sqrtPriceX96_:
floor(sqrt(token1 / token0) * 2^96) 79228162514264337593543950336is the starting price for a 1:1 pool
4. Initialize the _mint-liquidity_ parameters
PositionManager's modifyLiquidities uses an encoded command system
bytes memory actions = abi.encodePacked(uint8(Actions.MINT_POSITION), uint8(Actions.SETTLE_PAIR));
- The first command
MINT_POSITIONcreates a new liquidity position - The second command
SETTLE_PAIRindicates that tokens are to be paid by the caller, to create the position
Guide: Encode Liquidity Operations
5. Encode the MINT_POSITION parameters
bytes[] memory mintParams = new bytes[](2);
mintParams[0] = abi.encode(pool, tickLower, tickUpper, liquidity, amount0Max, amount1Max, recipient, hookData);
- _pool_ the same
PoolKeydefined 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
LiquidityAmountsfor 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
6. Encode the SETTLE_PAIR parameters
Creating a position on a pool requires the caller to transfer currency0 and currency1 tokens
mintParams[1] = abi.encode(pool.currency0, pool.currency1);
7. Encode the modifyLiquidities call
// Note: In production, deadlines should be calculated offchain using real time
// For example: uint256 deadline = block.timestamp + 3600; // 1 hour from now
uint256 deadline = block.timestamp + 3600; // 1 hour deadline
params[1] = abi.encodeWithSelector(
posm.modifyLiquidities.selector, abi.encode(actions, mintParams), deadline
);
Guide: Approve and Execute
8. Approve the tokens
PositionManager uses Permit2 for token transfers
- Repeat for both tokens
// approve permit2 as a spender
IERC20(token).approve(address(permit2), type(uint256).max);
// approve `PositionManager` as a spender
IAllowanceTransfer(address(permit2)).approve(token, address(positionManager), type(uint160).max, type(uint48).max);
9. Execute the multicall
The multicall is used to execute multiple calls in a single transaction
PositionManager(posm).multicall(params);
For pools paired with native tokens (Ether), provide value in the contract call
PositionManager(posm).multicall(params);
Excess Ether is NOT refunded unless developers encodedSWEEPin theactionsparameter
For a full end-to-end script, developers should see v4-template's scripts
Uyarlanmış geliştirici referansı. Kaynak: kaynak dokümantasyon reposu. Kaynak ve lisans bildirimi: NOTICE.