### V4Quoter Contract Example Source: https://context7.com/uniswap/v4-periphery/llms.txt This contract demonstrates how to use the IV4Quoter interface to get price quotes for different swap types. It requires an instance of IV4Quoter to be passed in the constructor. ```Solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {IV4Quoter} from "@uniswap/v4-periphery/src/interfaces/IV4Quoter.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; import {PathKey} from "@uniswap/v4-periphery/src/libraries/PathKey.sol"; import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; contract QuoterExample { IV4Quoter public immutable quoter; constructor(IV4Quoter _quoter) { quoter = _quoter; } // Quote a single-hop exact input swap function quoteExactInputSingle( address tokenIn, address tokenOut, uint24 fee, int24 tickSpacing, uint128 amountIn ) external returns (uint256 amountOut, uint256 gasEstimate) { (Currency currency0, Currency currency1, bool zeroForOne) = tokenIn < tokenOut ? (Currency.wrap(tokenIn), Currency.wrap(tokenOut), true) : (Currency.wrap(tokenOut), Currency.wrap(tokenIn), false); PoolKey memory poolKey = PoolKey({ currency0: currency0, currency1: currency1, fee: fee, tickSpacing: tickSpacing, hooks: IHooks(address(0)) }); IV4Quoter.QuoteExactSingleParams memory params = IV4Quoter.QuoteExactSingleParams({ poolKey: poolKey, zeroForOne: zeroForOne, exactAmount: amountIn, hookData: bytes("") }); // Returns the expected output amount and gas estimate (amountOut, gasEstimate) = quoter.quoteExactInputSingle(params); } // Quote a multi-hop exact input swap function quoteExactInput( address tokenA, address tokenB, address tokenC, uint24 feeAB, uint24 feeBC, int24 tickSpacingAB, int24 tickSpacingBC, uint128 amountIn ) external returns (uint256 amountOut, uint256 gasEstimate) { PathKey[] memory path = new PathKey[](2); path[0] = PathKey({ intermediateCurrency: Currency.wrap(tokenB), fee: feeAB, tickSpacing: tickSpacingAB, hooks: IHooks(address(0)), hookData: bytes("") }); path[1] = PathKey({ intermediateCurrency: Currency.wrap(tokenC), fee: feeBC, tickSpacing: tickSpacingBC, hooks: IHooks(address(0)), hookData: bytes("") }); IV4Quoter.QuoteExactParams memory params = IV4Quoter.QuoteExactParams({ exactCurrency: Currency.wrap(tokenA), path: path, exactAmount: amountIn }); (amountOut, gasEstimate) = quoter.quoteExactInput(params); } // Quote an exact output swap function quoteExactOutputSingle( address tokenIn, address tokenOut, uint24 fee, int24 tickSpacing, uint128 amountOut ) external returns (uint256 amountIn, uint256 gasEstimate) { (Currency currency0, Currency currency1, bool zeroForOne) = tokenIn < tokenOut ? (Currency.wrap(tokenIn), Currency.wrap(tokenOut), true) : (Currency.wrap(tokenOut), Currency.wrap(tokenIn), false); PoolKey memory poolKey = PoolKey({ currency0: currency0, currency1: currency1, fee: fee, tickSpacing: tickSpacing, hooks: IHooks(address(0)) }); IV4Quoter.QuoteExactSingleParams memory params = IV4Quoter.QuoteExactSingleParams({ poolKey: poolKey, zeroForOne: zeroForOne, exactAmount: amountOut, hookData: bytes("") }); (amountIn, gasEstimate) = quoter.quoteExactOutputSingle(params); } } ``` -------------------------------- ### Install v4 Periphery with Forge Source: https://github.com/uniswap/v4-periphery/blob/main/README.md Use this command to install the v4-periphery contracts into your local repository for deployment to a testnet. ```bash forge install https://github.com/Uniswap/v4-periphery ``` -------------------------------- ### V4Router Exact Input Multi-Hop Swap Example Source: https://context7.com/uniswap/v4-periphery/llms.txt Use this function to execute a multi-hop swap where the input amount is exact and the output amount is minimized. It requires specifying intermediate currencies and pool parameters for each hop. ```Solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {IV4Router} from "@uniswap/v4-periphery/src/interfaces/IV4Router.sol"; import {Actions} from "@uniswap/v4-periphery/src/libraries/Actions.sol"; import {ActionConstants} from "@uniswap/v4-periphery/src/libraries/ActionConstants.sol"; import {PathKey} from "@uniswap/v4-periphery/src/libraries/PathKey.sol"; import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; interface IRouter { function executeActions(bytes calldata data) external payable; } contract SwapExactInputMultiHopExample { IRouter public immutable router; constructor(IRouter _router) { router = _router; } // Swap tokenA -> tokenB -> tokenC (2 hops) function swapExactInputMultiHop( address tokenA, address tokenB, address tokenC, uint24 feeAB, uint24 feeBC, int24 tickSpacingAB, int24 tickSpacingBC, uint128 amountIn, uint128 amountOutMinimum ) external { // Build the path: each PathKey specifies the next currency and pool params PathKey[] memory path = new PathKey[](2); // First hop: tokenA -> tokenB path[0] = PathKey({ intermediateCurrency: Currency.wrap(tokenB), fee: feeAB, tickSpacing: tickSpacingAB, hooks: IHooks(address(0)), hookData: bytes("") }); // Second hop: tokenB -> tokenC path[1] = PathKey({ intermediateCurrency: Currency.wrap(tokenC), fee: feeBC, tickSpacing: tickSpacingBC, hooks: IHooks(address(0)), hookData: bytes("") }); // Build swap parameters IV4Router.ExactInputParams memory swapParams = IV4Router.ExactInputParams({ currencyIn: Currency.wrap(tokenA), path: path, minHopPriceX36: new uint256[](0), // No per-hop price limits amountIn: amountIn, amountOutMinimum: amountOutMinimum }); // Build action plan bytes memory actions = abi.encodePacked( uint8(Actions.SWAP_EXACT_IN), uint8(Actions.SETTLE_ALL), uint8(Actions.TAKE_ALL) ); bytes[] memory params = new bytes[](3); params[0] = abi.encode(swapParams); params[1] = abi.encode(Currency.wrap(tokenA), type(uint256).max); params[2] = abi.encode(Currency.wrap(tokenC), 0); router.executeActions(abi.encode(actions, params)); } } ``` -------------------------------- ### V4Router Exact Output Swap Example Source: https://context7.com/uniswap/v4-periphery/llms.txt This contract demonstrates how to execute a single-asset swap with an exact output amount using the V4Router. It requires the token addresses, fee, tick spacing, desired output amount, and maximum input amount for slippage protection. ```Solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {IV4Router} from "@uniswap/v4-periphery/src/interfaces/IV4Router.sol"; import {Actions} from "@uniswap/v4-periphery/src/libraries/Actions.sol"; import {ActionConstants} from "@uniswap/v4-periphery/src/libraries/ActionConstants.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; interface IRouter { function executeActions(bytes calldata data) external payable; } contract SwapExactOutputExample { IRouter public immutable router; constructor(IRouter _router) { router = _router; } function swapExactOutputSingle( address tokenIn, address tokenOut, uint24 fee, int24 tickSpacing, uint128 amountOut, uint128 amountInMaximum ) external { (Currency currency0, Currency currency1, bool zeroForOne) = tokenIn < tokenOut ? (Currency.wrap(tokenIn), Currency.wrap(tokenOut), true) : (Currency.wrap(tokenOut), Currency.wrap(tokenIn), false); PoolKey memory poolKey = PoolKey({ currency0: currency0, currency1: currency1, fee: fee, tickSpacing: tickSpacing, hooks: IHooks(address(0)) }); IV4Router.ExactOutputSingleParams memory swapParams = IV4Router.ExactOutputSingleParams({ poolKey: poolKey, zeroForOne: zeroForOne, amountOut: amountOut, amountInMaximum: amountInMaximum, minHopPriceX36: 0, hookData: bytes("") }); bytes memory actions = abi.encodePacked( uint8(Actions.SWAP_EXACT_OUT_SINGLE), uint8(Actions.SETTLE_ALL), uint8(Actions.TAKE_ALL) ); bytes[] memory params = new bytes[](3); params[0] = abi.encode(swapParams); params[1] = abi.encode(Currency.wrap(tokenIn), amountInMaximum); params[2] = abi.encode(Currency.wrap(tokenOut), 0); router.executeActions(abi.encode(actions, params)); } } ``` -------------------------------- ### Custom Hook Contract Example Source: https://github.com/uniswap/v4-periphery/blob/main/README.md Example of a custom hook contract that inherits from BaseHook. Override hook callbacks like _beforeAddLiquidity to implement custom logic. ```solidity contract CoolHook is BaseHook { // Override the hook callbacks you want on your hook function _beforeAddLiquidity( address, PoolKey calldata key, ModifyLiquidityParams calldata params, bytes calldata hookData ) internal override returns (bytes4) { // hook logic return BaseHook.beforeAddLiquidity.selector; } } ``` -------------------------------- ### Initialize Pool with Sqrt Price Source: https://context7.com/uniswap/v4-periphery/llms.txt Initializes a new pool with a given square root price. Ensure token0 is less than token1. Returns the starting tick or type(int24).max if the pool already exists. ```Solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {IPositionManager} from "@uniswap/v4-periphery/src/interfaces/IPositionManager.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol"; contract PoolInitializerExample { IPositionManager public immutable positionManager; // Common sqrt price values uint160 constant SQRT_PRICE_1_1 = 79228162514264337593543950336; // 1:1 price uint160 constant SQRT_PRICE_1_2 = 56022770974786139918731938227; // 1:2 price uint160 constant SQRT_PRICE_2_1 = 112045541949572279837463876454; // 2:1 price constructor(IPositionManager _positionManager) { positionManager = _positionManager; } function initializePool( address token0, address token1, uint24 fee, int24 tickSpacing, uint160 sqrtPriceX96 ) external returns (int24 tick) { // Ensure token0 < token1 require(token0 < token1, "Token order"); PoolKey memory poolKey = PoolKey({ currency0: Currency.wrap(token0), currency1: Currency.wrap(token1), fee: fee, tickSpacing: tickSpacing, hooks: IHooks(address(0)) }); // Initialize returns the starting tick, or type(int24).max if pool exists tick = positionManager.initializePool(poolKey, sqrtPriceX96); require(tick != type(int24).max, "Pool already exists"); return tick; } // Initialize pool at a specific tick function initializePoolAtTick( address token0, address token1, uint24 fee, int24 tickSpacing, int24 targetTick ) external returns (int24 tick) { require(token0 < token1, "Token order"); // Convert tick to sqrt price uint160 sqrtPriceX96 = TickMath.getSqrtPriceAtTick(targetTick); PoolKey memory poolKey = PoolKey({ currency0: Currency.wrap(token0), currency1: Currency.wrap(token1), fee: fee, tickSpacing: tickSpacing, hooks: IHooks(address(0)) }); tick = positionManager.initializePool(poolKey, sqrtPriceX96); require(tick != type(int24).max, "Pool already exists"); return tick; } } ``` -------------------------------- ### Mint a New Liquidity Position with PositionManager Source: https://context7.com/uniswap/v4-periphery/llms.txt This example demonstrates how to mint a new liquidity position using the PositionManager contract. It encodes MINT_POSITION and SETTLE_PAIR actions, specifying pool details, tick range, liquidity amount, slippage limits, and recipient. Ensure you have the necessary imports and contract instances. ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {IPositionManager} from "@uniswap/v4-periphery/src/interfaces/IPositionManager.sol"; import {Actions} from "@uniswap/v4-periphery/src/libraries/Actions.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; contract MintExample { IPositionManager public immutable positionManager; constructor(IPositionManager _positionManager) { positionManager = _positionManager; } function mintPosition( address token0, address token1, uint24 fee, int24 tickSpacing, int24 tickLower, int24 tickUpper, uint256 liquidity, uint128 amount0Max, uint128 amount1Max ) external returns (uint256 tokenId) { // Define the pool key PoolKey memory poolKey = PoolKey({ currency0: Currency.wrap(token0), currency1: Currency.wrap(token1), fee: fee, tickSpacing: tickSpacing, hooks: IHooks(address(0)) }); // Build the action plan bytes memory actions = abi.encodePacked( uint8(Actions.MINT_POSITION), uint8(Actions.SETTLE_PAIR) ); bytes[] memory params = new bytes[](2); // Encode mint parameters: poolKey, tickLower, tickUpper, liquidity, amount0Max, amount1Max, recipient, hookData params[0] = abi.encode( poolKey, tickLower, tickUpper, liquidity, amount0Max, amount1Max, msg.sender, // recipient of the NFT bytes("") // hookData ); // Encode settle pair parameters params[1] = abi.encode(poolKey.currency0, poolKey.currency1); // Get the next token ID before minting tokenId = positionManager.nextTokenId(); // Execute with deadline uint256 deadline = block.timestamp + 60; positionManager.modifyLiquidities(abi.encode(actions, params), deadline); return tokenId; } } ``` -------------------------------- ### Initialize Pool at Specific Tick Source: https://context7.com/uniswap/v4-periphery/llms.txt Initializes a new pool at a target tick by converting the tick to a square root price. Requires token0 to be less than token1. Returns the starting tick or type(int24).max if the pool already exists. ```Solidity // Initialize pool at a specific tick function initializePoolAtTick( address token0, address token1, uint24 fee, int24 tickSpacing, int24 targetTick ) external returns (int24 tick) { require(token0 < token1, "Token order"); // Convert tick to sqrt price uint160 sqrtPriceX96 = TickMath.getSqrtPriceAtTick(targetTick); PoolKey memory poolKey = PoolKey({ currency0: Currency.wrap(token0), currency1: Currency.wrap(token1), fee: fee, tickSpacing: tickSpacing, hooks: IHooks(address(0)) }); tick = positionManager.initializePool(poolKey, sqrtPriceX96); require(tick != type(int24).max, "Pool already exists"); return tick; } } ``` -------------------------------- ### Get Pool Price and Tick Source: https://context7.com/uniswap/v4-periphery/llms.txt Retrieves the current pool price (sqrtPriceX96), tick, and protocol/liquidity provider fees. Requires pool details like token addresses, fee, and tick spacing. ```Solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {IStateView} from "@uniswap/v4-periphery/src/interfaces/IStateView.sol"; import {PoolId, PoolIdLibrary} from "@uniswap/v4-core/src/types/PoolId.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; contract StateViewExample { using PoolIdLibrary for PoolKey; IStateView public immutable stateView; constructor(IStateView _stateView) { stateView = _stateView; } // Get current pool price and tick function getPoolPrice( address token0, address token1, uint24 fee, int24 tickSpacing ) external view returns ( uint160 sqrtPriceX96, int24 tick, uint24 protocolFee, uint24 lpFee ) { PoolKey memory poolKey = PoolKey({ currency0: Currency.wrap(token0), currency1: Currency.wrap(token1), fee: fee, tickSpacing: tickSpacing, hooks: IHooks(address(0)) }); PoolId poolId = poolKey.toId(); return stateView.getSlot0(poolId); } // Get total pool liquidity function getPoolLiquidity( address token0, address token1, uint24 fee, int24 tickSpacing ) external view returns (uint128 liquidity) { PoolKey memory poolKey = PoolKey({ currency0: Currency.wrap(token0), currency1: Currency.wrap(token1), fee: fee, tickSpacing: tickSpacing, hooks: IHooks(address(0)) }); return stateView.getLiquidity(poolKey.toId()); } // Get tick information function getTickInfo( address token0, address token1, uint24 fee, int24 tickSpacing, int24 tick ) external view returns ( uint128 liquidityGross, int128 liquidityNet, uint256 feeGrowthOutside0X128, uint256 feeGrowthOutside1X128 ) { PoolKey memory poolKey = PoolKey({ currency0: Currency.wrap(token0), currency1: Currency.wrap(token1), fee: fee, tickSpacing: tickSpacing, hooks: IHooks(address(0)) }); return stateView.getTickInfo(poolKey.toId(), tick); } // Get global fee growth function getFeeGrowthGlobals( address token0, address token1, uint24 fee, int24 tickSpacing ) external view returns ( uint256 feeGrowthGlobal0, uint256 feeGrowthGlobal1 ) { PoolKey memory poolKey = PoolKey({ currency0: Currency.wrap(token0), currency1: Currency.wrap(token1), fee: fee, tickSpacing: tickSpacing, hooks: IHooks(address(0)) }); return stateView.getFeeGrowthGlobals(poolKey.toId()); } } ``` -------------------------------- ### Exact Input Single Swap with V4Router Source: https://context7.com/uniswap/v4-periphery/llms.txt Execute a single-hop swap specifying the exact input amount. The V4Router provides slippage protection via `amountOutMinimum` and optional per-hop price protection via `minHopPriceX36`. Ensure `currency0` is less than `currency1` when building the `PoolKey`. ```Solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {IV4Router} from "@uniswap/v4-periphery/src/interfaces/IV4Router.sol"; import {Actions} from "@uniswap/v4-periphery/src/libraries/Actions.sol"; import {ActionConstants} from "@uniswap/v4-periphery/src/libraries/ActionConstants.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {Currency} from "@uniswap/v4-core/src/types/Currency.sol"; import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol"; interface IRouter { function executeActions(bytes calldata data) external payable; } contract SwapExactInputSingleExample { IRouter public immutable router; constructor(IRouter _router) { router = _router; } function swapExactInputSingle( address tokenIn, address tokenOut, uint24 fee, int24 tickSpacing, uint128 amountIn, uint128 amountOutMinimum ) external { // Build pool key (currency0 must be < currency1) (Currency currency0, Currency currency1, bool zeroForOne) = tokenIn < tokenOut ? (Currency.wrap(tokenIn), Currency.wrap(tokenOut), true) : (Currency.wrap(tokenOut), Currency.wrap(tokenIn), false); PoolKey memory poolKey = PoolKey({ currency0: currency0, currency1: currency1, fee: fee, tickSpacing: tickSpacing, hooks: IHooks(address(0)) }); // Build swap parameters IV4Router.ExactInputSingleParams memory swapParams = IV4Router.ExactInputSingleParams({ poolKey: poolKey, zeroForOne: zeroForOne, amountIn: amountIn, amountOutMinimum: amountOutMinimum, minHopPriceX36: 0, // No per-hop price limit hookData: bytes("") }); // Build action plan: swap, settle input, take output bytes memory actions = abi.encodePacked( uint8(Actions.SWAP_EXACT_IN_SINGLE), uint8(Actions.SETTLE_ALL), uint8(Actions.TAKE_ALL) ); bytes[] memory params = new bytes[](3); params[0] = abi.encode(swapParams); params[1] = abi.encode(Currency.wrap(tokenIn), type(uint256).max); // Settle input params[2] = abi.encode(Currency.wrap(tokenOut), 0); // Take all output router.executeActions(abi.encode(actions, params)); } } ``` -------------------------------- ### PositionManager - Decrease Liquidity and Collect Fees Source: https://context7.com/uniswap/v4-periphery/llms.txt Use this function to remove liquidity from a position and collect fees. Provide the token ID and the amount of liquidity to decrease. Slippage protection is available via amount0Min and amount1Min. Calling with zero liquidity decreases will only collect fees. ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {IPositionManager} from "@uniswap/v4-periphery/src/interfaces/IPositionManager.sol"; import {Actions} from "@uniswap/v4-periphery/src/libraries/Actions.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {ActionConstants} from "@uniswap/v4-periphery/src/libraries/ActionConstants.sol"; contract DecreaseLiquidityExample { IPositionManager public immutable positionManager; constructor(IPositionManager _positionManager) { positionManager = _positionManager; } function decreaseLiquidity( uint256 tokenId, uint256 liquidityToRemove, uint128 amount0Min, uint128 amount1Min ) external { (PoolKey memory poolKey, ) = positionManager.getPoolAndPositionInfo(tokenId); // Build action plan: decrease then take the tokens bytes memory actions = abi.encodePacked( uint8(Actions.DECREASE_LIQUIDITY), uint8(Actions.TAKE_PAIR) ); bytes[] memory params = new bytes[](2); // Encode decrease liquidity: tokenId, liquidity, amount0Min, amount1Min, hookData params[0] = abi.encode( tokenId, liquidityToRemove, amount0Min, amount1Min, bytes("") ); // Take both currencies to msg.sender params[1] = abi.encode(poolKey.currency0, poolKey.currency1, msg.sender); uint256 deadline = block.timestamp + 60; positionManager.modifyLiquidities(abi.encode(actions, params), deadline); } // Collect fees only (decrease with 0 liquidity) function collectFees(uint256 tokenId) external { (PoolKey memory poolKey, ) = positionManager.getPoolAndPositionInfo(tokenId); bytes memory actions = abi.encodePacked( uint8(Actions.DECREASE_LIQUIDITY), uint8(Actions.TAKE_PAIR) ); bytes[] memory params = new bytes[](2); // Decrease 0 liquidity to collect only fees params[0] = abi.encode(tokenId, 0, 0, 0, bytes("")); params[1] = abi.encode(poolKey.currency0, poolKey.currency1, msg.sender); positionManager.modifyLiquidities(abi.encode(actions, params), block.timestamp + 60); } } ``` -------------------------------- ### Available Actions in Actions.sol Source: https://context7.com/uniswap/v4-periphery/llms.txt Defines operation codes for various liquidity, swap, settlement, take, and utility operations. Use these constants to construct batched transactions. ```solidity library Actions { // Liquidity operations uint256 constant INCREASE_LIQUIDITY = 0x00; // Add liquidity to existing position uint256 constant DECREASE_LIQUIDITY = 0x01; // Remove liquidity from position uint256 constant MINT_POSITION = 0x02; // Create new position NFT uint256 constant BURN_POSITION = 0x03; // Burn position NFT (removes all liquidity) // Swap operations uint256 constant SWAP_EXACT_IN_SINGLE = 0x06; // Single-hop exact input swap uint256 constant SWAP_EXACT_IN = 0x07; // Multi-hop exact input swap uint256 constant SWAP_EXACT_OUT_SINGLE = 0x08; // Single-hop exact output swap uint256 constant SWAP_EXACT_OUT = 0x09; // Multi-hop exact output swap // Settlement operations uint256 constant SETTLE = 0x0b; // Settle specific amount uint256 constant SETTLE_ALL = 0x0c; // Settle entire debt uint256 constant SETTLE_PAIR = 0x0d; // Settle both currencies in pair // Take operations uint256 constant TAKE = 0x0e; // Take specific amount uint256 constant TAKE_ALL = 0x0f; // Take entire credit uint256 constant TAKE_PORTION = 0x10; // Take percentage (in bips) uint256 constant TAKE_PAIR = 0x11; // Take both currencies in pair // Utility operations uint256 constant CLOSE_CURRENCY = 0x12; // Auto settle or take based on delta uint256 constant CLEAR_OR_TAKE = 0x13; // Forfeit dust or take if > threshold uint256 constant SWEEP = 0x14; // Sweep token balance to recipient // ETH wrapping uint256 constant WRAP = 0x15; // Wrap ETH to WETH uint256 constant UNWRAP = 0x16; // Unwrap WETH to ETH } ``` -------------------------------- ### PositionManager - Increase Liquidity Source: https://context7.com/uniswap/v4-periphery/llms.txt Use this function to add more liquidity to an existing position. Ensure you provide the correct token ID, liquidity amount, and maximum amounts for slippage protection. The position owner or an approved address can call this function. ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {IPositionManager} from "@uniswap/v4-periphery/src/interfaces/IPositionManager.sol"; import {Actions} from "@uniswap/v4-periphery/src/libraries/Actions.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {ActionConstants} from "@uniswap/v4-periphery/src/libraries/ActionConstants.sol"; contract IncreaseLiquidityExample { IPositionManager public immutable positionManager; constructor(IPositionManager _positionManager) { positionManager = _positionManager; } function increaseLiquidity( uint256 tokenId, uint256 liquidityToAdd, uint128 amount0Max, uint128 amount1Max ) external { // Get the pool key for this position (PoolKey memory poolKey, ) = positionManager.getPoolAndPositionInfo(tokenId); // Build action plan bytes memory actions = abi.encodePacked( uint8(Actions.INCREASE_LIQUIDITY), uint8(Actions.SETTLE_PAIR) ); bytes[] memory params = new bytes[](2); // Encode increase liquidity: tokenId, liquidity, amount0Max, amount1Max, hookData params[0] = abi.encode( tokenId, liquidityToAdd, amount0Max, amount1Max, bytes("") // hookData ); // Settle both currencies params[1] = abi.encode(poolKey.currency0, poolKey.currency1); uint256 deadline = block.timestamp + 60; positionManager.modifyLiquidities(abi.encode(actions, params), deadline); } } ``` -------------------------------- ### Action Constants for Special Values Source: https://context7.com/uniswap/v4-periphery/llms.txt Defines special address and amount constants used in actions. MSG_SENDER and ADDRESS_THIS specify recipients, while OPEN_DELTA and CONTRACT_BALANCE refer to specific amounts. ```solidity library ActionConstants { address constant MSG_SENDER = address(1); // Use msg.sender as recipient address constant ADDRESS_THIS = address(2); // Use contract address as recipient uint128 constant OPEN_DELTA = 0; // Use the full open delta amount uint256 constant CONTRACT_BALANCE = 0; // Use contract's token balance } ``` -------------------------------- ### Burn Position NFT with Uniswap V4 Source: https://context7.com/uniswap/v4-periphery/llms.txt Burn a position NFT to remove all liquidity and close the position. The `amount0Min` and `amount1Min` parameters provide slippage protection. This function automatically decreases liquidity to zero before burning if any remains. ```Solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {IPositionManager} from "@uniswap/v4-periphery/src/interfaces/IPositionManager.sol"; import {Actions} from "@uniswap/v4-periphery/src/libraries/Actions.sol"; import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol"; import {ActionConstants} from "@uniswap/v4-periphery/src/libraries/ActionConstants.sol"; contract BurnPositionExample { IPositionManager public immutable positionManager; constructor(IPositionManager _positionManager) { positionManager = _positionManager; } function burnPosition( uint256 tokenId, uint128 amount0Min, uint128 amount1Min ) external { (PoolKey memory poolKey, ) = positionManager.getPoolAndPositionInfo(tokenId); // Build action plan bytes memory actions = abi.encodePacked( uint8(Actions.BURN_POSITION), uint8(Actions.TAKE_PAIR) ); bytes[] memory params = new bytes[](2); // Encode burn: tokenId, amount0Min, amount1Min, hookData params[0] = abi.encode(tokenId, amount0Min, amount1Min, bytes("")); // Take remaining tokens to msg.sender params[1] = abi.encode(poolKey.currency0, poolKey.currency1, msg.sender); positionManager.modifyLiquidities(abi.encode(actions, params), block.timestamp + 60); } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.