Nonfungible Position Manager: Key Functions


Let’s dive into the Uniswap v3 codebase, focusing on actual Solidity code snippets. I’ll highlight where key functions are located, explain their roles, and provide context.

We’ll start with the Nonfungible Position Manager, as it’s one of the most innovative features of Uniswap v3.

Nonfungible Position Manager: Key Functions

1. Mint Function

Code:

function mint(MintParams calldata params)
    external
    payable
    returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1)
  • Location: Uniswap v3 Core Repository - NonfungiblePositionManager.sol

  • Explanation:

    • The mint function creates a new liquidity position. It accepts MintParams as input, including:
      • token0 and token1: The token pair for the liquidity position.
      • fee: The pool’s fee tier.
      • tickLower and tickUpper: Price range for the liquidity.
      • amount0Desired and amount1Desired: Maximum token amounts to deposit.
    • Returns:
      • tokenId: The unique NFT ID representing the position.
      • liquidity: The liquidity added.
      • amount0 and amount1: Actual token amounts deposited.

2. Increase Liquidity Function

Code:

function increaseLiquidity(IncreaseLiquidityParams calldata params)
    external
    payable
    returns (uint128 liquidity, uint256 amount0, uint256 amount1)
  • Location: Same as mint.

  • Explanation:

    • The increaseLiquidity function allows users to add more liquidity to an existing position.
    • Inputs include:
      • tokenId: The ID of the NFT representing the position.
      • amount0Desired and amount1Desired: The maximum amounts of tokens to add.
    • Returns:
      • liquidity: The increased liquidity.
      • amount0 and amount1: The actual tokens added.

3. Collect Function

Code:

function collect(CollectParams calldata params)
    external
    returns (uint256 amount0, uint256 amount1)
  • Location: Same file.

  • Explanation:

    • The collect function allows liquidity providers to claim fees earned by their position.
    • Inputs include:
      • tokenId: The NFT ID.
      • recipient: Address to send the collected fees.
      • amount0Max and amount1Max: Maximum amounts to collect.
    • Returns:
      • amount0 and amount1: The fees collected in tokens 0 and 1.

Example: Adding Liquidity and Collecting Fees

Let’s break it into steps:

1. Minting a Position

NonfungiblePositionManager.mint({
    token0: address(DAI),
    token1: address(USDC),
    fee: 500, // 0.05% fee tier
    tickLower: -10000,
    tickUpper: 10000,
    amount0Desired: 1000 ether,
    amount1Desired: 1000 ether,
    recipient: msg.sender
});
  • Creates a liquidity position for the DAI/USDC pair with a 0.05% fee tier.

2. Collecting Fees

NonfungiblePositionManager.collect({
    tokenId: positionId,
    recipient: msg.sender,
    amount0Max: type(uint128).max,
    amount1Max: type(uint128).max
});
  • Collects all fees accrued by the position and sends them to msg.sender.

How to Explore the Codebase

  1. Navigate to the Uniswap v3 GitHub Repositories:

  2. Search for Contract Files:

    • Core features are in UniswapV3Pool.sol.
    • Auxiliary features, such as the NonfungiblePositionManager, are in the Periphery.
  3. Use Remix IDE or Hardhat:

    • You can clone the repository and deploy the contracts in a local environment for testing and learning.