Uniswap: Pool Contracts


Uniswap v3 Pool Contracts

The Pool Contracts are the core of Uniswap v3. They manage liquidity, swaps, fees, and price oracles. Each pool is specific to a token pair and fee tier. Below, I’ll walk you through the key functions and components, including code snippets.


1. Swap Function

Code:

function swap(
    address recipient,
    bool zeroForOne,
    int256 amountSpecified,
    uint160 sqrtPriceLimitX96,
    bytes calldata data
) external returns (int256 amount0, int256 amount1)
  • Location: UniswapV3Pool.sol

  • Explanation:

    • Purpose: Executes token swaps within the pool.
    • Parameters:
      • recipient: Address receiving the output tokens.
      • zeroForOne: Direction of the swap (true for token0 -> token1, false for token1 -> token0).
      • amountSpecified: Swap amount (positive for exact input, negative for exact output).
      • sqrtPriceLimitX96: Price limit for the swap, in sqrt format.
      • data: Optional callback data for custom logic.
    • Returns:
      • amount0 and amount1: The token amounts swapped.

2. Mint Function

Code:

function mint(
    address owner,
    int24 tickLower,
    int24 tickUpper,
    uint128 amount,
    bytes calldata data
) external returns (uint256 amount0, uint256 amount1)
  • Location: Same file.

  • Explanation:

    • Purpose: Adds liquidity to the pool.
    • Parameters:
      • owner: Address of the liquidity provider.
      • tickLower and tickUpper: Price range for liquidity.
      • amount: Liquidity amount to add.
      • data: Optional callback data.
    • Returns:
      • amount0 and amount1: Token amounts deposited into the pool.

3. Collect Function

Code:

function collect(
    address recipient,
    int24 tickLower,
    int24 tickUpper,
    uint128 amount0Requested,
    uint128 amount1Requested
) external returns (uint128 amount0, uint128 amount1)
  • Explanation:
    • Purpose: Collects fees earned by liquidity positions.
    • Parameters:
      • recipient: Address receiving the fees.
      • tickLower and tickUpper: Position range to collect fees from.
      • amount0Requested and amount1Requested: Maximum fees to withdraw.
    • Returns:
      • amount0 and amount1: Fees collected.

How It All Works Together

  1. Adding Liquidity (Mint): Liquidity providers use the mint function to contribute tokens and define a price range. This creates or increases their position in the pool.

    pool.mint(
        msg.sender, 
        tickLower, 
        tickUpper, 
        1000, 
        abi.encode("callback data")
    );
    
  2. Swapping Tokens: Traders call the swap function to exchange tokens. For example, swapping token0 for token1:

    pool.swap(
        msg.sender, 
        true, // token0 -> token1
        1000, // exact input
        sqrtPriceLimitX96, 
        "callback data"
    );
    
  3. Collecting Fees: LPs call collect to claim the fees they’ve earned from swaps in their price range:

    pool.collect(
        msg.sender, 
        tickLower, 
        tickUpper, 
        type(uint128).max, // collect all available
        type(uint128).max
    );