Adding And Removing Liquidity is handled by ConcentratedLiquidityPoolMananger.sol by its mint and burn functions respectively. ConcentratedLiquidityPoolMananger is Dfyn's Concentrated Liquidity Pool periphery contract that combines non-fungible position management and staking. Lets look at mint function first

ConcentratedLiquidityPoolMananger.sol

While adding liquidity Mint function in ConcentratedLiquidityPoolManager is called which mints a new position as a NFT returned as positionId.

The mint function is used to mint a new non-fungible token (NFT) or add liquidity to an existing one. The NFT is associated with a Concentrated Liquidity Pool, and its value is determined by the amount of liquidity it holds and the range of prices it covers.

mint()

/// @notice Mints Position
    /// @param pool address of pool
    /// @param lowerOld tick below lower tick
    /// @param lower lower tick
    /// @param upperOld tick below upper
    /// @param upper upper tick
    /// @param amount0Desired token0 input amount
    /// @param amount1Desired token1 input amount
    /// @param native user wallet/vault
    /// @param minLiquidity min liquidity to mint
    /// @param positionId position nft id

    function mint(
        IConcentratedLiquidityPool pool,
        int24 lowerOld,
        int24 lower,
        int24 upperOld,
        int24 upper,
        uint128 amount0Desired,
        uint128 amount1Desired,
        bool native,
        uint256 minLiquidity,
        uint256 positionId
    ) external payable returns (uint256 _positionId) {

The function takes several parameters:

require(masterDeployer.pools(address(pool)), "INVALID_POOL");
cachedMsgSender = msg.sender;
cachedPool = address(pool);

The code first checks that the address of the provided liquidity pool is in the pools mapping of the masterDeployer contract. If it is not, the function execution is reverted with the error message "INVALID_POOL". The code then saves the caller's address in the cachedMsgSender variable and the pool's address in the cachedPool variable.

uint128 liquidityMinted = uint128(
	pool.mint(
	    IConcentratedLiquidityPoolStruct.MintParams({
	        lowerOld: lowerOld,
	        lower: lower,
	        upperOld: upperOld,
	        upper: upper,
	        amount0Desired: amount0Desired,
	        amount1Desired: amount1Desired,
	        native: native
	    })
		)
);

require(liquidityMinted >= minLiquidity, "TOO_LITTLE_RECEIVED");

The code first calls the mint function on the provided liquidity pool, passing in a MintParams struct with the input values of the mint function as its fields. This mint function on the liquidity pool is responsible for creating the new liquidity tokens and returning the amount of tokens minted.

The code then checks that the amount of tokens minted is greater than or equal to the minLiquidity value provided as input to the mint function. If it is not, the function execution is reverted with the error message "TOO_LITTLE_RECEIVED".