Algebra Integral
HomepageSocialsIntegrate
  • Overview / FAQ
    • 💡What is Algebra?
    • 🫂The Algebra Ecosystem
    • 🧑‍🔬Algebra Integral
    • 📚Glossary
    • 🪙Tokenomics
    • 📱Social Media & Links
    • 👨‍🎨Brand Assets
    • Partners
      • Algebra V1.0
        • QuickSwap Polygon
        • ZyberSwap
        • Thena
        • StellaSwap
        • QuickSwap Dogechain
        • SkullSwap
        • UbeSwap
        • Litx
      • Algebra V1.9
        • Camelot
        • Lynex
        • Swapbased
        • Synthswap
        • Zyberswap Optimism
        • Hercules
      • Integral 1.0
        • Swapsicle Telos
        • Swapsicle Mantle
        • Kim
        • Fenix
        • Blade
        • SilverSwap Fantom
        • Horizon
        • Glyph Exchange
        • SilverSwap Sonic
        • SwapX
        • Bulla
      • Integral 1.1
        • Scribe
      • Integral 1.2
        • Fibonacci
        • Voltage
        • Henjin
        • Wasabee
        • Holiverse
        • MorFi
        • StellaSwap
        • QuickSwap Soneium
  • Algebra Integral / Technical Reference
    • ℹ️Intro
    • 🔍Audits
    • 🏗️Integration Process
      • Specification and API of contracts
        • Algebra Pool
        • Algebra Factory
        • Swap Router
        • Nonfungible Position Manager
        • Quoter
        • QuoterV2
        • TickLens
      • Interaction with pools
        • Getting data from pools
      • Subgraphs and analytics
        • Examples of queries
      • Technical Guides
        • Intro
        • Swaps
          • Single swaps
          • Multihop swaps
        • Providing liquidity
          • Setting up your contract
          • Mint a new position
          • Collect fees
          • Decrease liquidity
          • Increase liquidity
          • Final Contract
        • Flashloans
          • Setting up your contract
          • Calling flash
          • Flash callback
          • Final contract
      • Migration from UniswapV3
    • 🖲️Core Logic
      • Pool overview
      • Swap calculation
      • Liquidity and positions
      • Ticks
        • Ticks search tree
      • Reserves
      • Flash
      • Plugins
      • AlgebraFactory and roles
    • 🧩Plugins
      • Overview
      • Adaptive Fee
      • Sliding Fee
      • Whitelist Discount Fee
      • Safety Switch
      • Position Limit Orders
      • Managed Swap Fee
      • FAQ
    • 📖Guides
      • 🔨Plugin Development
      • 🔬Plugin Testing
      • ☄️Plugin Deployment
    • ⬆️Changes V1
    • ⬆️Changes V1.1
    • ⬆️Changes v1.2
  • ⬆️Changes v1.2.1
  • Algebra V1 / Technical Reference
    • 🔏Contracts
      • API Reference v1.0
        • V1.0 - Core
          • AlgebraFactory
          • AlgebraPool
          • AlgebraPoolDeployer
          • DataStorage
          • DataStorageOperator
          • IAlgebraFactory
          • IAlgebraFlashCallback
          • IAlgebraMintCallback
          • IAlgebraPoolActions
          • IAlgebraPoolDeployer
          • IAlgebraPoolDerivedState
          • IAlgebraPoolEvents
          • IAlgebraPoolImmutables
          • IAlgebraPoolPermissionedActions
          • IAlgebraPoolState
          • IAlgebraSwapCallback
          • IAlgebraVirtualPool
          • IDataStorageOperator
          • IERC20Minimal
          • PoolImmutables
          • PoolState
        • V1.0 - Periphery
          • AlgebraInterfaceMulticall
          • ERC20
          • ERC20Permit
          • ERC165
          • ERC721
          • ERC721Permit
          • IAlgebraMintCallback
          • IAlgebraFactory
          • IAlgebraPoolDerivedState
          • IAlgebraPoolActions
          • IAlgebraPoolEvents
          • IAlgebraPoolImmutables
          • IAlgebraPoolPermissionedActions
          • IAlgebraPoolState
          • IAlgebraSwapCallback
          • IERC20
          • IDataStorageOperator
          • IERC20Metadata
          • IERC20Permit
          • IERC20PermitAllowed
          • IERC165
          • IERC721
          • IERC721Enumerable
          • IERC721Metadata
          • IERC721Permit
          • IERC721Receiver
          • IERC1271
          • IMulticall
          • INonfungiblePositionManager
          • INonfungibleTokenPositionDescriptor
          • IPeripheryImmutableState
          • IPeripheryPayments
          • IPeripheryPaymentsWithFee
          • IPoolInitializer
          • IQuoter
          • IQuoterV2
          • ISelfPermit
          • ISwapRouter
          • ITickLens
          • IUniswapV2Pair
          • IV3Migrator
          • IWNativeToken
          • LiquidityManagement
          • Multicall
          • NFTDescriptor
          • NonfungiblePositionManager
          • NonfungibleTokenPositionDescriptor
          • PeripheryImmutableState
          • PeripheryPayments
          • PeripheryPaymentsWithFee
          • PoolInitializer
          • Quoter
          • QuoterV2
          • SwapRouter
          • SelfPermit
          • TickLens
          • V3Migrator
        • V1.0 - Tokenomics
          • AlgebraEternalFarming
          • AlgebraFarming
          • AlgebraIncentiveFarming
          • AlgebraLimitFarming
          • AlgebraTokenStaking
          • AlgebraVault
          • AlgebraVirtualPoolBase
          • ERC20
          • ERC165
          • ERC721
          • ERC721Permit
          • EternalVirtualPool
          • FarmingCenter
          • FarmingCenterVault
          • FreezableToken
          • IAlgebraEternalFarming
          • IAlgebraEternalVirtualPool
          • IAlgebraFactory
          • IAlgebraFarming
          • IAlgebraIncentiveFarming
          • IAlgebraIncentiveVirtualPool
          • IAlgebraLimitFarming
          • IAlgebraLimitVirtualPool
          • IAlgebraPoolActions
          • IAlgebraPoolDeployer
          • IAlgebraPoolDerivedState
          • IAlgebraPoolEvents
          • IAlgebraPoolImmutables
          • IAlgebraPoolPermissionedActions
          • IAlgebraPoolState
          • IAlgebraSwapCallback
          • IAlgebraVirtualPool
          • IAlgebraVirtualPoolBase
          • IDataStorageOperator
          • IERC20
          • IERC20Minimal
          • IERC165
          • IERC721
          • IERC721Enumerable
          • IERC721Metadata
          • IERC721Permit
          • IERC721Receiver
          • IERC1271
          • IFarmingCenter
          • IFarmingCenterVault
          • IMulticall
          • IncentiveVirtualPool
          • INonfungiblePositionManager
          • IPeripheryPayments
          • IPeripheryImmutableState
          • IPoolInitializer
          • ISwapRouter
          • IWNativeToken
          • LimitVirtualPool
          • Multicall
          • PeripheryPayments
      • API Reference v1.9
        • V1.9 - Core
          • AlgebraFactory
          • AlgebraPool
          • AlgebraPoolDeployer
          • DataStorage
          • DataStorageOperator
          • IAlgebraFactory
          • IAlgebraFlashCallback
          • IAlgebraMintCallback
          • IAlgebraPoolActions
          • IAlgebraPoolDeployer
          • IAlgebraPoolDerivedState
          • IAlgebraPoolEvents
          • IAlgebraPoolImmutables
          • IAlgebraPoolPermissionedActions
          • IAlgebraPoolState
          • IAlgebraSwapCallback
          • IAlgebraVirtualPool
          • IDataStorageOperator
          • IERC20Minimal
          • PoolImmutables
          • PoolState
        • V1.9 - Periphery
          • ERC721Permit
          • AlgebraInterfaceMulticall
          • IERC20Metadata
          • IERC20PermitAllowed
          • IERC721Permit
          • IERC1271
          • IMulticall
          • INonfungiblePositionManager
          • INonfungibleTokenPositionDescriptor
          • IPeripheryImmutableState
          • IPeripheryPayments
          • IPeripheryPaymentsWithFee
          • IPoolInitializer
          • IQuoter
          • IQuoterV2
          • ISelfPermit
          • ISwapRouter
          • ITickLens
          • IV3Migrator
          • IWNativeToken
          • LiquidityManagement
          • Multicall
          • NFTDescriptor
          • NonfungiblePositionManager
          • NonfungibleTokenPositionDescriptor
          • PeripheryImmutableState
          • PeripheryPayments
          • PoolInitializer
          • PeripheryPaymentsWithFee
          • Quoter
          • QuoterV2
          • SelfPermit
          • SwapRouter
          • TickLens
          • V3Migrator
        • V1.9 - Tokenomics
          • AlgebraFarming
          • AlgebraEternalFarming
          • AlgebraLimitFarming
          • AlgebraTokenStaking
          • AlgebraVault
          • AlgebraVirtualPoolBase
          • ERC20
          • EternalVirtualPool
          • FarmingCenter
          • FarmingCenterVault
          • FreezableToken
          • IAlgebraEternalFarming
          • IAlgebraEternalVirtualPool
          • IAlgebraFarming
          • IAlgebraLimitFarming
          • IAlgebraLimitVirtualPool
          • IAlgebraVirtualPoolBase
          • IERC20Minimal
          • IFarmingCenter
          • IFarmingCenterVault
          • LimitVirtualPool
          • PeripheryPayments
      • API Reference v1.9 - Directional Fees
        • V1.9 (Directional Fees) - Core
          • AlgebraFactory
          • AlgebraPool
          • AlgebraPoolDeployer
          • DataStorage
          • DataStorageOperator
          • IAlgebraFactory
          • IAlgebraFlashCallback
          • IAlgebraMintCallback
          • IAlgebraPoolActions
          • IAlgebraPoolDeployer
          • IAlgebraPoolDerivedState
          • IAlgebraPoolEvents
          • IAlgebraPoolImmutables
          • IAlgebraPoolPermissionedActions
          • IAlgebraSwapCallback
          • IAlgebraPoolState
          • IAlgebraVirtualPool
          • IDataStorageOperator
          • IERC20Minimal
          • PoolImmutables
          • PoolState
        • V1.9 (Directional Fees) - Periphery
          • AlgebraInterfaceMulticall
          • ERC721Permit
          • IERC20Metadata
          • IERC20PermitAllowed
          • IERC721Permit
          • IERC1271
          • IMulticall
          • INonfungiblePositionManager
          • INonfungibleTokenPositionDescriptor
          • IPeripheryImmutableState
          • IPeripheryPayments
          • IPeripheryPaymentsWithFee
          • IPoolInitializer
          • IQuoter
          • IQuoterV2
          • ISelfPermit
          • ISwapRouter
          • ITickLens
          • IV3Migrator
          • IWNativeToken
          • LiquidityManagement
          • Multicall
          • NFTDescriptor
          • NonfungiblePositionManager
          • NonfungibleTokenPositionDescriptor
          • PeripheryImmutableState
          • PeripheryPayments
          • PeripheryPaymentsWithFee
          • PoolInitializer
          • Quoter
          • QuoterV2
          • SelfPermit
          • SwapRouter
          • TickLens
          • V3Migrator
        • V1.9 (Directional Fees) - Tokenomics
          • AlgebraFarming
          • AlgebraEternalFarming
          • AlgebraLimitFarming
          • AlgebraTokenStaking
          • AlgebraVault
          • AlgebraVirtualPoolBase
          • ERC20
          • EternalVirtualPool
          • FarmingCenter
          • FarmingCenterVault
          • FreezableToken
          • IAlgebraEternalFarming
          • IAlgebraEternalVirtualPool
          • IAlgebraFarming
          • IAlgebraLimitVirtualPool
          • IAlgebraLimitFarming
          • IAlgebraVirtualPoolBase
          • IERC20Minimal
          • IFarmingCenterVault
          • IFarmingCenter
          • LimitVirtualPool
          • PeripheryPayments
      • API Reference v2.0
        • V2.0 - Core
          • AlgebraCommunityVault
          • AlgebraFactory
          • AlgebraFeeConfiguration
          • AlgebraPool
          • AlgebraPoolBase
          • AlgebraPoolDeployer
          • DataStorage
          • DataStorageOperator
          • DerivedState
          • IAlgebraFactory
          • IAlgebraFlashCallback
          • IAlgebraMintCallback
          • IAlgebraPoolActions
          • IAlgebraPoolDeployer
          • IAlgebraPoolDerivedState
          • IAlgebraPoolErrors
          • IAlgebraPoolEvents
          • IAlgebraPoolImmutables
          • IAlgebraPoolPermissionedActions
          • IAlgebraPoolState
          • IAlgebraSwapCallback
          • IAlgebraVirtualPool
          • IDataStorageOperator
          • IERC20Minimal
          • Positions
          • ReservesManager
        • V2.0 - Periphery
          • AlgebraInterfaceMulticall
          • ERC721Permit
          • IERC20Metadata
          • IERC20PermitAllowed
          • IERC721Permit
          • IERC1271
          • ILimitOrderManager
          • IMulticall
          • INonfungiblePositionManager
          • INonfungibleTokenPositionDescriptor
          • IPeripheryImmutableState
          • IPeripheryPayments
          • IPeripheryPaymentsWithFee
          • IPoolInitializer
          • IPositionFollower
          • IQuoter
          • IQuoterV2
          • ISelfPermit
          • ISwapRouter
          • ITickLens
          • IV3Migrator
          • IWNativeToken
          • LimitOrderManagement
          • LimitOrderManager
          • LiquidityManagement
          • Multicall
          • NFTDescriptor
          • NonfungiblePositionManager
          • NonfungibleTokenPositionDescriptor
          • PeripheryImmutableState
          • PeripheryPayments
          • PeripheryPaymentsWithFee
          • PoolInitializer
          • Quoter
          • QuoterV2
          • SelfPermit
          • SwapRouter
          • TickLens
          • V3Migrator
        • V2.0 - Tokenomics
          • AlgebraEternalFarming
          • EternalVirtualPool
          • FarmingCenter
          • IAccessControl
          • IAlgebraEternalFarming
          • IAlgebraEternalVirtualPool
          • IFarmingCenter
          • IncentiveKey
          • VirtualTickStructure
      • API Reference v2.0 - Directional Fees
        • V2.0 (Directional Fees) - Core
          • AlgebraCommunityVault
          • AlgebraFactory
          • AlgebraFeeConfiguration
          • AlgebraPool
          • AlgebraPoolBase
          • AlgebraPoolDeployer
          • DataStorage
          • DataStorageOperator
          • DerivedState
          • IAlgebraFactory
          • IAlgebraFlashCallback
          • IAlgebraMintCallback
          • IAlgebraPoolActions
          • IAlgebraPoolDeployer
          • IAlgebraPoolDerivedState
          • IAlgebraPoolErrors
          • IAlgebraPoolEvents
          • IAlgebraPoolImmutables
          • IAlgebraPoolPermissionedActions
          • IAlgebraPoolState
          • IAlgebraSwapCallback
          • IAlgebraVirtualPool
          • IDataStorageOperator
          • IERC20Minimal
          • Positions
          • ReservesManager
        • V2.0 (Directional Fees) - Periphery
          • AlgebraInterfaceMulticall
          • ERC721Permit
          • IERC20Metadata
          • IERC20PermitAllowed
          • IERC721Permit
          • IERC1271
          • ILimitOrderManager
          • IMulticall
          • INonfungiblePositionManager
          • INonfungibleTokenPositionDescriptor
          • IPeripheryImmutableState
          • IPeripheryPayments
          • IPeripheryPaymentsWithFee
          • IPoolInitializer
          • IPositionFollower
          • IQuoter
          • IQuoterV2
          • ISelfPermit
          • ISwapRouter
          • ITickLens
          • IV3Migrator
          • IWNativeToken
          • LimitOrderManagement
          • LimitOrderManager
          • LiquidityManagement
          • Multicall
          • NFTDescriptor
          • NonfungiblePositionManager
          • NonfungibleTokenPositionDescriptor
          • PeripheryImmutableState
          • PeripheryPayments
          • PeripheryPaymentsWithFee
          • PoolInitializer
          • QuoterV2
          • Quoter
          • SelfPermit
          • SwapRouter
          • TickLens
          • V3Migrator
        • V2.0 (Directional Fees) - Tokenomics
          • AlgebraEternalFarming
          • EternalVirtualPool
          • FarmingCenter
          • IAccessControl
          • IAlgebraEternalFarming
          • IAlgebraEternalVirtualPool
          • IFarmingCenter
          • IncentiveKey
          • VirtualTickStructure
      • Adaptive Fee
        • Adaptive Fee
        • How to set up specific formula behaviour
        • How to tweak formula behaviour
      • Contracts Setup
        • Deployment
          • Contracts Deployment
          • Deployment Scripts
        • Misc
          • POOL_INIT_CODE_HASH
          • Code Audits
          • Deployment Addresses
      • The Algebra Guides
        • Flash Integrations
          • The Full Contract
          • Calling Flash
          • Flash Callback
          • Inheritance constructor
        • Liquidity Mining
          • Liquidity Mining Overview
        • Providing Liquidity
          • Collecting fees
          • Decrease liquidity
          • Increase Liquidity Within The Current Range
          • Mint a new position
          • Set up your contract
          • The full contract
        • Swaps
          • Multihop swaps
          • Single swaps
    • 📊Subgraph
      • Query Examples
        • Query Examples
      • GraphQL Schema
        • Farming GraphQL Schema
        • Algebra GraphQL Schema
      • Subgraph Setup
        • Subgraph Settings
        • Subgraph Deployment
    • 🖥️Frontend
      • Admin Panel
        • Contracts
          • Admin Panel
          • Changing Subgraph
        • Eternal Farmings
          • Create Eternal Farming
          • Managing Eternal Farming
        • Limit Farmings
          • Create Limit Farming
    • ⚙️Backend
      • Backend Setup
    • ⛑️Guides
      • Step by Step Deployment
  • Other
    • 📦Archived Documentation
    • ❗Link Awareness Notice
Powered by GitBook
On this page
  1. Algebra Integral / Technical Reference
  2. Integration Process
  3. Technical Guides
  4. Providing liquidity

Final Contract

Below we give an example of a fully functioning code: a contract that can custody the Algebra NFT positions and manipulate positions and liquidity in them by charging fees, increasing or decreasing liquidity and creating new positions.

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.8.20;

import '@cryptoalgebra/integral-core/contracts/interfaces/IAlgebraPool.sol';
import '@cryptoalgebra/integral-core/contracts/libraries/TickMath.sol';

import '@cryptoalgebra/integral-periphery/contracts/libraries/TransferHelper.sol';
import '@cryptoalgebra/integral-periphery/contracts/interfaces/INonfungiblePositionManager.sol';
import '@cryptoalgebra/integral-periphery/contracts/base/LiquidityManagement.sol';

import '@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol';

contract LiquidityExamples is IERC721Receiver, LiquidityManagement {
    address public constant DAI = 0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063;
    address public constant USDC = 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174;

    INonfungiblePositionManager public immutable nonfungiblePositionManager;

    /// @notice Represents the deposit of an NFT
    struct Deposit {
        address owner;
        uint128 liquidity;
        address token0;
        address token1;
    }

    /// @dev deposits[tokenId] => Deposit
    mapping(uint256 tokenId => Deposit) public deposits;

    constructor(
        INonfungiblePositionManager _nonfungiblePositionManager,
        address _factory,
        address _WMATIC,
        address _poolDeployer
    ) PeripheryImmutableState(_factory, _WMATIC, _poolDeployer) {
        nonfungiblePositionManager = _nonfungiblePositionManager;
    }

    // Implementing `onERC721Received` so this contract can receive custody of erc721 tokens
    function onERC721Received(
        address operator,
        address,
        uint256 tokenId,
        bytes calldata
    ) external override returns (bytes4) {
        // get position information

        _createDeposit(operator, tokenId);

        return this.onERC721Received.selector;
    }

    function _createDeposit(address owner, uint256 tokenId) internal {
        (, , address token0, address token1, , , uint128 liquidity, , , , ) =
            nonfungiblePositionManager.positions(tokenId);

        // set the owner and data for position
        // operator is msg.sender
        deposits[tokenId] = Deposit({owner: owner, liquidity: liquidity, token0: token0, token1: token1});
    }

    /// @notice Calls the mint function defined in periphery, mints the same amount of each token.
    /// For this example we are providing 1000 DAI and 1000 USDC in liquidity
    /// @return tokenId The id of the newly minted ERC721
    /// @return liquidity The amount of liquidity for the position
    /// @return amount0 The amount of token0
    /// @return amount1 The amount of token1
    function mintNewPosition()
        external
        returns (
            uint256 tokenId,
            uint128 liquidity,
            uint256 amount0,
            uint256 amount1
        )
    {
        // For this example, we will provide equal amounts of liquidity in both assets.
        // Providing liquidity in both assets means liquidity will be earning fees and is considered in-range.
        uint256 amount0ToMint = 1000;
        uint256 amount1ToMint = 1000;

        // transfer tokens to contract
        TransferHelper.safeTransferFrom(DAI, msg.sender, address(this), amount0ToMint);
        TransferHelper.safeTransferFrom(USDC, msg.sender, address(this), amount1ToMint);

        // Approve the position manager
        TransferHelper.safeApprove(DAI, address(nonfungiblePositionManager), amount0ToMint);
        TransferHelper.safeApprove(USDC, address(nonfungiblePositionManager), amount1ToMint);

        INonfungiblePositionManager.MintParams memory params =
            INonfungiblePositionManager.MintParams({
                token0: DAI,
                token1: USDC,
                tickLower: TickMath.MIN_TICK,
                tickUpper: TickMath.MAX_TICK,
                amount0Desired: amount0ToMint,
                amount1Desired: amount1ToMint,
                amount0Min: 0,
                amount1Min: 0,
                recipient: address(this),
                deadline: block.timestamp
            });

        // Note that the pool defined by DAI/USDC must already be created and initialized in order to mint
        (tokenId, liquidity, amount0, amount1) = nonfungiblePositionManager.mint(params);

        // Create a deposit
        _createDeposit(msg.sender, tokenId);

        // Remove allowance and refund in both assets.
        if (amount0 < amount0ToMint) {
            TransferHelper.safeApprove(DAI, address(nonfungiblePositionManager), 0);
            uint256 refund0 = amount0ToMint - amount0;
            TransferHelper.safeTransfer(DAI, msg.sender, refund0);
        }

        if (amount1 < amount1ToMint) {
            TransferHelper.safeApprove(USDC, address(nonfungiblePositionManager), 0);
            uint256 refund1 = amount1ToMint - amount1;
            TransferHelper.safeTransfer(USDC, msg.sender, refund1);
        }
    }

    /// @notice Collects the fees associated with provided liquidity
    /// @dev The contract must hold the erc721 token before it can collect fees
    /// @param tokenId The id of the erc721 token
    /// @return amount0 The amount of fees collected in token0
    /// @return amount1 The amount of fees collected in token1
    function collectAllFees(uint256 tokenId) external returns (uint256 amount0, uint256 amount1) {
        // Caller must own the ERC721 position, meaning it must be a deposit

        // set amount0Max and amount1Max to uint256.max to collect all fees
        // alternatively can set recipient to msg.sender and avoid another transaction in `sendToOwner`
        INonfungiblePositionManager.CollectParams memory params =
            INonfungiblePositionManager.CollectParams({
                tokenId: tokenId,
                recipient: address(this),
                amount0Max: type(uint128).max,
                amount1Max: type(uint128).max
            });

        (amount0, amount1) = nonfungiblePositionManager.collect(params);

        // send collected feed back to owner
        _sendToOwner(tokenId, amount0, amount1);
    }

    /// @notice A function that decreases the current liquidity by half. An example to show how to call the `decreaseLiquidity` function defined in periphery.
    /// @param tokenId The id of the erc721 token
    /// @return amount0 The amount received back in token0
    /// @return amount1 The amount returned back in token1
    function decreaseLiquidityInHalf(uint256 tokenId) external returns (uint256 amount0, uint256 amount1) {
        // caller must be the owner of the NFT
        require(msg.sender == deposits[tokenId].owner, 'Not the owner');
        // get liquidity data for tokenId
        uint128 liquidity = deposits[tokenId].liquidity;
        uint128 halfLiquidity = liquidity / 2;

        // amount0Min and amount1Min are price slippage checks
        // if the amount received after burning is not greater than these minimums, transaction will fail
        INonfungiblePositionManager.DecreaseLiquidityParams memory params =
            INonfungiblePositionManager.DecreaseLiquidityParams({
                tokenId: tokenId,
                liquidity: halfLiquidity,
                amount0Min: 0,
                amount1Min: 0,
                deadline: block.timestamp
            });

        (amount0, amount1) = nonfungiblePositionManager.decreaseLiquidity(params);

        //send liquidity back to owner
        _sendToOwner(tokenId, amount0, amount1);
    }

    /// @notice Increases liquidity in the current range
    /// @dev Pool must be initialized already to add liquidity
    /// @param tokenId The id of the erc721 token
    /// @param amount0 The amount to add of token0
    /// @param amount1 The amount to add of token1
    function increaseLiquidityCurrentRange(
        uint256 tokenId,
        uint256 amountAdd0,
        uint256 amountAdd1
    )
        external
        returns (
            uint128 liquidity,
            uint256 amount0,
            uint256 amount1
        ) {

        TransferHelper.safeTransferFrom(deposits[tokenId].token0, msg.sender, address(this), amountAdd0);
        TransferHelper.safeTransferFrom(deposits[tokenId].token1, msg.sender, address(this), amountAdd1);

        TransferHelper.safeApprove(deposits[tokenId].token0, address(nonfungiblePositionManager), amountAdd0);
        TransferHelper.safeApprove(deposits[tokenId].token1, address(nonfungiblePositionManager), amountAdd1);

        INonfungiblePositionManager.IncreaseLiquidityParams memory params = INonfungiblePositionManager.IncreaseLiquidityParams({
            tokenId: tokenId,
            amount0Desired: amountAdd0,
            amount1Desired: amountAdd1,
            amount0Min: 0,
            amount1Min: 0,
            deadline: block.timestamp
        });

        (liquidity, amount0, amount1) = nonfungiblePositionManager.increaseLiquidity(params);

    }

    /// @notice Transfers funds to owner of NFT
    /// @param tokenId The id of the erc721
    /// @param amount0 The amount of token0
    /// @param amount1 The amount of token1
    function _sendToOwner(
        uint256 tokenId,
        uint256 amount0,
        uint256 amount1
    ) internal {
        // get owner of contract
        address owner = deposits[tokenId].owner;

        address token0 = deposits[tokenId].token0;
        address token1 = deposits[tokenId].token1;
        // send collected fees to owner
        TransferHelper.safeTransfer(token0, owner, amount0);
        TransferHelper.safeTransfer(token1, owner, amount1);
    }

    /// @notice Transfers the NFT to the owner
    /// @param tokenId The id of the erc721
    function retrieveNFT(uint256 tokenId) external {
        // must be the owner of the NFT
        require(msg.sender == deposits[tokenId].owner, 'Not the owner');
        // transfer ownership to original owner
        nonfungiblePositionManager.safeTransferFrom(address(this), msg.sender, tokenId);
        //remove information related to tokenId
        delete deposits[tokenId];
    }
}
PreviousIncrease liquidityNextFlashloans
🏗️