ShibaSwap v2’s periphery contracts provide user-friendly interfaces for interacting with the core protocol. These contracts handle complex operations like position management, routing, and simplified interactions.

Non-fungible Position Manager

The Non-fungible Position Manager (NFPM) is an ERC-721 contract that represents liquidity positions as NFTs. It provides a user-friendly interface for creating, managing, and interacting with concentrated liquidity positions.

Overview

Each liquidity position is represented as a unique NFT with metadata including token pair, fee tier, tick range, and liquidity amount.

Core Functions

mint

function mint(MintParams calldata params) external payable returns (
    uint256 tokenId,
    uint128 liquidity,
    uint256 amount0,
    uint256 amount1
)
Creates a new liquidity position and mints an NFT representing it.
params.token0
address
required
First token in the pair
params.token1
address
required
Second token in the pair
params.fee
uint24
required
Fee tier for the pool
params.tickLower
int24
required
Lower tick boundary of the position
params.tickUpper
int24
required
Upper tick boundary of the position
params.amount0Desired
uint256
required
Desired amount of token0
params.amount1Desired
uint256
required
Desired amount of token1
params.amount0Min
uint256
required
Minimum amount of token0 to accept
params.amount1Min
uint256
required
Minimum amount of token1 to accept
params.recipient
address
required
Address to receive the NFT
params.deadline
uint256
required
Unix timestamp deadline
tokenId
uint256
required
Unique identifier for the position NFT
liquidity
uint128
required
Amount of liquidity created
amount0
uint256
required
Amount of token0 used
amount1
uint256
required
Amount of token1 used

increaseLiquidity

function increaseLiquidity(IncreaseLiquidityParams calldata params) external payable returns (
    uint128 liquidity,
    uint256 amount0,
    uint256 amount1
)
Adds more liquidity to an existing position.
params.tokenId
uint256
required
ID of the position to increase liquidity for
params.amount0Desired
uint256
required
Desired amount of token0 to add
params.amount1Desired
uint256
required
Desired amount of token1 to add
params.amount0Min
uint256
required
Minimum amount of token0 to accept
params.amount1Min
uint256
required
Minimum amount of token1 to accept
params.deadline
uint256
required
Unix timestamp deadline

decreaseLiquidity

function decreaseLiquidity(DecreaseLiquidityParams calldata params) external payable returns (
    uint256 amount0,
    uint256 amount1
)
Removes liquidity from a position.
params.tokenId
uint256
required
ID of the position to decrease liquidity for
params.liquidity
uint128
required
Amount of liquidity to remove
params.amount0Min
uint256
required
Minimum amount of token0 to receive
params.amount1Min
uint256
required
Minimum amount of token1 to receive
params.deadline
uint256
required
Unix timestamp deadline

collect

function collect(CollectParams calldata params) external payable returns (
    uint256 amount0,
    uint256 amount1
)
Collects accumulated fees from a position.
params.tokenId
uint256
required
ID of the position to collect fees from
params.recipient
address
required
Address to receive the collected fees
params.amount0Max
uint128
required
Maximum amount of token0 to collect
params.amount1Max
uint128
required
Maximum amount of token1 to collect

burn

function burn(uint256 tokenId) external payable
Burns an NFT position and removes all liquidity.
tokenId
uint256
required
ID of the position to burn
Burning a position will permanently remove all liquidity and fees. Make sure to collect fees first.

Position Information

positions

function positions(uint256 tokenId) external view returns (
    uint96 nonce,
    address operator,
    address token0,
    address token1,
    uint24 fee,
    int24 tickLower,
    int24 tickUpper,
    uint128 liquidity,
    uint256 feeGrowthInside0LastX128,
    uint256 feeGrowthInside1LastX128,
    uint128 tokensOwed0,
    uint128 tokensOwed1
)
Returns detailed information about a position.
tokenId
uint256
required
ID of the position to query
nonce
uint96
required
Position nonce for replay protection
operator
address
required
Address authorized to manage the position
token0
address
required
First token in the pair
token1
address
required
Second token in the pair
fee
uint24
required
Fee tier of the pool
tickLower
int24
required
Lower tick boundary
tickUpper
int24
required
Upper tick boundary
liquidity
uint128
required
Current liquidity amount
feeGrowthInside0LastX128
uint256
required
Last fee growth for token0
feeGrowthInside1LastX128
uint256
required
Last fee growth for token1
tokensOwed0
uint128
required
Unclaimed token0 fees
tokensOwed1
uint128
required
Unclaimed token1 fees

Router Contract

The Router contract provides simplified interfaces for common operations like swaps and liquidity management.

Swap Functions

exactInputSingle

function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut)
Executes a single-hop swap with exact input amount.
params.tokenIn
address
required
Input token address
params.tokenOut
address
required
Output token address
params.fee
uint24
required
Fee tier of the pool
params.recipient
address
required
Address to receive output tokens
params.deadline
uint256
required
Unix timestamp deadline
params.amountIn
uint256
required
Exact input amount
params.amountOutMinimum
uint256
required
Minimum output amount
params.sqrtPriceLimitX96
uint160
required
Price limit for the swap

exactInput

function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut)
Executes a multi-hop swap with exact input amount.
params.path
bytes
required
Encoded path for the swap
params.recipient
address
required
Address to receive output tokens
params.deadline
uint256
required
Unix timestamp deadline
params.amountIn
uint256
required
Exact input amount
params.amountOutMinimum
uint256
required
Minimum output amount

exactOutputSingle

function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn)
Executes a single-hop swap with exact output amount.
params.tokenIn
address
required
Input token address
params.tokenOut
address
required
Output token address
params.fee
uint24
required
Fee tier of the pool
params.recipient
address
required
Address to receive output tokens
params.deadline
uint256
required
Unix timestamp deadline
params.amountOut
uint256
required
Exact output amount
params.amountInMaximum
uint256
required
Maximum input amount
params.sqrtPriceLimitX96
uint160
required
Price limit for the swap

exactOutput

function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn)
Executes a multi-hop swap with exact output amount.
params.path
bytes
required
Encoded path for the swap (in reverse order)
params.recipient
address
required
Address to receive output tokens
params.deadline
uint256
required
Unix timestamp deadline
params.amountOut
uint256
required
Exact output amount
params.amountInMaximum
uint256
required
Maximum input amount

Liquidity Management Functions

mint

function mint(MintParams calldata params) external payable returns (
    uint256 tokenId,
    uint128 liquidity,
    uint256 amount0,
    uint256 amount1
)
Creates a new liquidity position through the router.

increaseLiquidity

function increaseLiquidity(IncreaseLiquidityParams calldata params) external payable returns (
    uint128 liquidity,
    uint256 amount0,
    uint256 amount1
)
Increases liquidity for an existing position through the router.

decreaseLiquidity

function decreaseLiquidity(DecreaseLiquidityParams calldata params) external payable returns (
    uint256 amount0,
    uint256 amount1
)
Decreases liquidity for an existing position through the router.

collect

function collect(CollectParams calldata params) external payable returns (
    uint256 amount0,
    uint256 amount1
)
Collects fees from a position through the router.

Interfaces

INonfungiblePositionManager

interface INonfungiblePositionManager {
    struct MintParams {
        address token0;
        address token1;
        uint24 fee;
        int24 tickLower;
        int24 tickUpper;
        uint256 amount0Desired;
        uint256 amount1Desired;
        uint256 amount0Min;
        uint256 amount1Min;
        address recipient;
        uint256 deadline;
    }
    
    struct IncreaseLiquidityParams {
        uint256 tokenId;
        uint256 amount0Desired;
        uint256 amount1Desired;
        uint256 amount0Min;
        uint256 amount1Min;
        uint256 deadline;
    }
    
    struct DecreaseLiquidityParams {
        uint256 tokenId;
        uint128 liquidity;
        uint256 amount0Min;
        uint256 amount1Min;
        uint256 deadline;
    }
    
    struct CollectParams {
        uint256 tokenId;
        address recipient;
        uint128 amount0Max;
        uint128 amount1Max;
    }
    
    function mint(MintParams calldata params) external payable returns (
        uint256 tokenId,
        uint128 liquidity,
        uint256 amount0,
        uint256 amount1
    );
    
    function increaseLiquidity(IncreaseLiquidityParams calldata params) external payable returns (
        uint128 liquidity,
        uint256 amount0,
        uint256 amount1
    );
    
    function decreaseLiquidity(DecreaseLiquidityParams calldata params) external payable returns (
        uint256 amount0,
        uint256 amount1
    );
    
    function collect(CollectParams calldata params) external payable returns (
        uint256 amount0,
        uint256 amount1
    );
    
    function burn(uint256 tokenId) external payable;
    
    function positions(uint256 tokenId) external view returns (
        uint96 nonce,
        address operator,
        address token0,
        address token1,
        uint24 fee,
        int24 tickLower,
        int24 tickUpper,
        uint128 liquidity,
        uint256 feeGrowthInside0LastX128,
        uint256 feeGrowthInside1LastX128,
        uint128 tokensOwed0,
        uint128 tokensOwed1
    );
}

ISwapRouter

interface ISwapRouter {
    struct ExactInputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
        uint160 sqrtPriceLimitX96;
    }
    
    struct ExactInputParams {
        bytes path;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
    }
    
    struct ExactOutputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 deadline;
        uint256 amountOut;
        uint256 amountInMaximum;
        uint160 sqrtPriceLimitX96;
    }
    
    struct ExactOutputParams {
        bytes path;
        address recipient;
        uint256 deadline;
        uint256 amountOut;
        uint256 amountInMaximum;
    }
    
    function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);
    
    function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);
    
    function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);
    
    function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);
}

Usage Examples

Creating a Position

// Mint a new liquidity position
INonfungiblePositionManager nfpm = INonfungiblePositionManager(NFPM_ADDRESS);

INonfungiblePositionManager.MintParams memory params = INonfungiblePositionManager.MintParams({
    token0: SHIB_ADDRESS,
    token1: WETH_ADDRESS,
    fee: 3000,
    tickLower: -1000,
    tickUpper: 1000,
    amount0Desired: 1000000 * 10**18, // 1M SHIB
    amount1Desired: 1 * 10**18,       // 1 WETH
    amount0Min: 0,
    amount1Min: 0,
    recipient: msg.sender,
    deadline: block.timestamp + 1200
});

(uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1) = nfpm.mint(params);

Executing a Swap

// Single-hop swap
ISwapRouter router = ISwapRouter(ROUTER_ADDRESS);

ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
    tokenIn: SHIB_ADDRESS,
    tokenOut: WETH_ADDRESS,
    fee: 3000,
    recipient: msg.sender,
    deadline: block.timestamp + 1200,
    amountIn: 1000000 * 10**18, // 1M SHIB
    amountOutMinimum: 0,
    sqrtPriceLimitX96: 0
});

uint256 amountOut = router.exactInputSingle(params);

Managing Positions

// Increase liquidity
INonfungiblePositionManager.IncreaseLiquidityParams memory params = INonfungiblePositionManager.IncreaseLiquidityParams({
    tokenId: tokenId,
    amount0Desired: 500000 * 10**18, // 500K SHIB
    amount1Desired: 0.5 * 10**18,    // 0.5 WETH
    amount0Min: 0,
    amount1Min: 0,
    deadline: block.timestamp + 1200
});

(uint128 liquidity, uint256 amount0, uint256 amount1) = nfpm.increaseLiquidity(params);

// Collect fees
INonfungiblePositionManager.CollectParams memory collectParams = INonfungiblePositionManager.CollectParams({
    tokenId: tokenId,
    recipient: msg.sender,
    amount0Max: type(uint128).max,
    amount1Max: type(uint128).max
});

(uint256 amount0, uint256 amount1) = nfpm.collect(collectParams);

Best Practices

1

Always check position ownership

Verify you own the position before performing operations.
Use positions(tokenId).operator to check ownership.
2

Set appropriate deadlines

Use reasonable deadlines to prevent transaction failures.
Too short deadlines may cause transactions to revert.
3

Handle slippage properly

Set minimum amounts to protect against price movements.
Use the SDK to calculate expected amounts and set appropriate minimums.
4

Collect fees regularly

Collect accumulated fees to maximize returns.
Regular fee collection helps compound your earnings.

Error Handling