interface ICellarPoolShare is IERC20 {

    /// @notice Result from mint or add liquidity in Uniswap V3
    /// @dev Used for decrease local memory variables.
    /// @member tokenId minted tokenId
    /// @member liquidity minted liquidity
    /// @member amount0 added amount of token0 into liquidity
    /// @member amount1 added amount of token1 into liquidity
    struct MintResult {
        uint256 tokenId;
        uint128 liquidity;
        uint256 amount0;
        uint256 amount1;
    }

    /**
     * @notice The struct to increase liquidity of a position
     * @member amount0Desired The desired amount of token0 to be spent
     * @member amount1Desired The desired amount of token1 to be spent
     * @member amount0Min The minimum amount of token0 to spend, which serves as a slippage check
     * @member amount1Min The minimum amount of token1 to spend, which serves as a slippage check
     * @member deadline The time by which the transaction must be included to effect the change
     */
    struct CellarAddParams {
        uint256 amount0Desired;
        uint256 amount1Desired;
        uint256 amount0Min;
        uint256 amount1Min;
        uint256 deadline;
    }

    /**
     * @notice The struct to decrease liquidity of a position
     * @member tokenAmount The amount of cellar token amount by which liquidity will be decreased
     * @member amount0Min The minimum amount of token0 that should be accounted for the burned liquidity
     * @member amount1Min The minimum amount of token1 that should be accounted for the burned liquidity
     * @member deadline The time by which the transaction must be included to effect the change
     */
    struct CellarRemoveParams {
        uint256 tokenAmount;
        uint256 amount0Min;
        uint256 amount1Min;
        uint256 deadline;
    }

    /**
     * @notice The struct to decrease liquidity of a position
     * @member tokenId The tokenId of Uniswap V3 NFLP
     * @member tickUpper The higher end of the tick range for the position
     * @member tickLower The lower end of the tick range for the position
     * @member weight The weight of the current Tick in cellar
     */
    struct CellarTickInfo {
        uint184 tokenId;
        int24 tickUpper;
        int24 tickLower;
        uint24 weight;
    }

    /// @notice Used for decrease local memory variables.
    struct UintPair {
        uint256 a;
        uint256 b;
    }

    /**
     * @notice Used for decrease local memory variables.
     * @member collect0 collected token0
     * @member collect1 collected token1
     * @member transaction0 transaction fee of token0
     * @member transaction1 transaction fee of token1
     */
    struct CellarFees {
        uint256 collect0;
        uint256 collect1;
        uint256 transaction0;
        uint256 transaction1;
    }
 
    /// @notice Emitted when liquidity is increased for cellar
    /// @param liquidity The amount by which liquidity for the NFT position was increased
    /// @param amount0 The amount of token0 that was paid for the increase in liquidity
    /// @param amount1 The amount of token1 that was paid for the increase in liquidity
    event AddedLiquidity(
        uint128 liquidity,
        uint256 amount0,
        uint256 amount1
    );

    /// @notice Emitted when liquidity is decreased from cellar
    /// @param liquidity The amount by which liquidity for the NFT position was decreased
    /// @param amount0 The amount of token0 that was collected from the decrease in liquidity
    /// @param amount1 The amount of token1 that was collected from the decrease in liquidity
    event RemovedLiquidity(
        uint128 liquidity,
        uint256 amount0,
        uint256 amount1
    );

    /// @notice Emitted when reinvest swap fees into cellar for checking fees
    /// @param fees0 collected token0
    /// @param fees1 collected token1
    /// @param managementFee0 management fee of token0
    /// @param managementFee1 management fee of token1
    /// @param performanceFee0 performance fee of token0
    /// @param performanceFee1 performance fee of token1
    /// @param amount0 invested amount into liquidity of token0
    /// @param amount1 invested amount into liquidity of token1
    event Reinvest (
        uint256 fees0,
        uint256 fees1,
        uint256 managementFee0,
        uint256 managementFee1,
        uint256 performanceFee0,
        uint256 performanceFee1,
        uint256 amount0,
        uint256 amount1
    );

    /// @notice Emitted when rebalance ticks of cellar for checking fees
    /// @param fees0 collected token0
    /// @param fees1 collected token1
    /// @param managementFee0 management fee of token0
    /// @param managementFee1 management fee of token1
    /// @param performanceFee0 performance fee of token0
    /// @param performanceFee1 performance fee of token1
    /// @param amount0 invested amount into liquidity of token0
    /// @param amount1 invested amount into liquidity of token1
    event Rebalance (
        uint256 fees0,
        uint256 fees1,
        uint256 managementFee0,
        uint256 managementFee1,
        uint256 performanceFee0,
        uint256 performanceFee1,
        uint256 amount0,
        uint256 amount1
    );

    /// @notice Emitted when update validator setting
    /// @param validator validator address to add or remove
    /// @param value true to add, false to remove
    event SetValidator (
        address validator,
        bool value
    );

    event SetAdjuster (
        address adjuster,
        bool value
    );

    /// @notice Emitted when transfer ownership
    /// @param newOwner new owner address
    event TransferOwnership (
        address newOwner
    );

    /// @notice Emitted when update transaction fee
    /// @param newFee new transaction fee
    event SetTransactionFee (
        uint256 newFee
    );

    error OverDeposit();
    error UnsortedTokens();
    error ZeroWeight();
    error NonEmptyTokenId();
    error WrongTickTier();
    error NonPermission();
    error Reentrance();
    error InsufficientAmount();
    error HighSlippage();
    error InvalidTokenId();
    error InvalidInput();
    error TransferToZeroAddress();
    error TransferFromZeroAddress();
    error MintToZeroAddress();
    error BurnFromZeroAddress();
    error ApproveToZeroAddress();
    error ApproveFromZeroAddress();

    /// @notice Adding Liquidity For Uniswap V3 NFLP
    /// @param cellarParams parameter for adding liquidity
    function addLiquidityForUniV3(CellarAddParams calldata cellarParams)
        external
        payable;

    /// @notice Adding Liquidity For Uniswap V3 NFLP
    /// @param cellarParams parameter for removing liquidity
    function removeLiquidityFromUniV3(CellarRemoveParams calldata cellarParams)
        external;

    /// @notice Update cellar tick info
    /// @param _cellarTickInfo new tick tier information
    function rebalance(CellarTickInfo[] memory _cellarTickInfo, uint256 currentPrice) external;

    /// @notice collect fee and reinvest in liquidity
    function reinvest(uint256 currentPriceX96) external;

    /// @notice set validator
    /// @param _validator address to add or remove from validator list
    /// @param value add/remove option
    function setValidator(address _validator, bool value) external;

    /// @notice set adjuster
    /// @param _adjuster address to add or remove from adjuster list
    /// @param value add/remove option
    function setAdjuster(address _adjuster, bool value) external;

    /// @notice transfer ownership to new address
    /// @param newOwner address of new owner
    function transferOwnership(address newOwner) external;

    /// @notice update transaction fee
    /// @param newFee new transaction fee value
    function setTransactionFee(uint256 newFee) external;

    /**
     * @dev Returns owner address
     */
    function owner() external view returns (address);

    /**
     * @dev Returns name of the token as ERC20
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns symbol of the token as ERC20
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns cellar tick info struct array
     */
    function getCellarTickInfo() external view returns (CellarTickInfo[] memory);

    /**
     * @dev Returns decimals of the token as ERC20
     */
    function decimals() external pure returns (uint8);
}
/// @title interface for CellarPoolShare
/// @author Steven Jung
function symbol() external view returns (string memory);

/**
 * @dev Returns symbol of the token as ERC20
 */