creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/WiseSecurity/WiseSecurity.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\n/**\n * @author Christoph Krpoun\n * @author René Hochmuth\n * @author Vitally Marinchenko\n */\n\nimport \"./WiseSecurityHelper.sol\";\nimport \"../TransferHub/ApprovalHelper.sol\";\n\n/**\n * @dev WiseSecurity is a core contract for wiseLending including most of\n * the performed security checks for withdraws, borrows, paybacks and liquidations.\n * It also has several read only functions providing UI data for a better user\n * experiencne.\n *\n */\n\nerror NotWiseLendingSecurity();\n\ncontract WiseSecurity is WiseSecurityHelper, ApprovalHelper {\n\n    modifier onlyWiseLending() {\n        _onlyWiseLending();\n        _;\n    }\n\n    function _onlyWiseLending()\n        private\n        view\n    {\n        if (msg.sender == address(WISE_LENDING)) {\n            return;\n        }\n\n        revert NotWiseLendingSecurity();\n    }\n\n    constructor(\n        address _master,\n        address _wiseLendingAddress,\n        address _aaveHubAddress\n    )\n        WiseSecurityDeclarations(\n            _master,\n            _wiseLendingAddress,\n            _aaveHubAddress\n        )\n    {}\n\n    /**\n     * @dev View functions returning current\n     * debt ratio of a postion in normal mode.\n     * 1% <=> 1E16\n     */\n    function getLiveDebtRatio(\n        uint256 _nftId\n    )\n        external\n        view\n        returns (uint256)\n    {\n        uint256 overallCollateral = overallETHCollateralsWeighted(\n            _nftId\n        );\n\n        if (overallCollateral == 0) {\n            return 0;\n        }\n\n        return overallETHBorrow(_nftId)\n            * PRECISION_FACTOR_E18\n            / overallCollateral;\n    }\n\n    /**\n     * @dev Set Liquidation incentives and boundaries\n     * for liquidation. Only callable by the master.\n     * Assures liquidation cascade cannot be self imposed\n     * by limiting incentives.\n     */\n    function setLiquidationSettings(\n        uint256 _baseReward,\n        uint256 _baseRewardFarm,\n        uint256 _newMaxFeeETH,\n        uint256 _newMaxFeeFarmETH\n    )\n        external\n        onlyMaster\n    {\n        _setLiquidationSettings(\n            _baseReward,\n            _baseRewardFarm,\n            _newMaxFeeETH,\n            _newMaxFeeFarmETH\n        );\n    }\n\n    /**\n     * @dev Checks for liquidation logic.\n     */\n    function checksLiquidation(\n        uint256 _nftIdLiquidate,\n        address _tokenToPayback,\n        uint256 _shareAmountToPay\n    )\n        external\n        view\n    {\n        (\n            uint256 weightedCollateralETH,\n            uint256 unweightedCollateralETH\n\n        ) = overallETHCollateralsBoth(\n            _nftIdLiquidate\n        );\n\n        uint256 borrowETHTotal = overallETHBorrowHeartbeat(\n            _nftIdLiquidate\n        );\n\n        canLiquidate(\n            borrowETHTotal,\n            weightedCollateralETH\n        );\n\n        checkMaxShares(\n            _nftIdLiquidate,\n            _tokenToPayback,\n            borrowETHTotal,\n            unweightedCollateralETH,\n            _shareAmountToPay\n        );\n    }\n\n    /**\n     * @dev Set function for preparing curve pools.\n     */\n    function prepareCurvePools(\n        address _poolToken,\n        CurveSwapStructData calldata _curveSwapStructData,\n        CurveSwapStructToken calldata _curveSwapStructToken\n    )\n        external\n        onlyWiseLending\n    {\n        curveSwapInfoData[_poolToken] = _curveSwapStructData;\n        curveSwapInfoToken[_poolToken] = _curveSwapStructToken;\n\n        address curvePool = curveSwapInfoData[_poolToken].curvePool;\n        uint256 tokenIndexForApprove = _curveSwapStructToken.curvePoolTokenIndexFrom;\n\n        _safeApprove(\n            ICurve(curvePool).coins(tokenIndexForApprove),\n            curvePool,\n            0\n        );\n\n        _safeApprove(\n            ICurve(curvePool).coins(tokenIndexForApprove),\n            curvePool,\n            UINT256_MAX\n        );\n\n        address curveMetaPool = curveSwapInfoData[_poolToken].curveMetaPool;\n\n        if (curveMetaPool == ZERO_ADDRESS) {\n            return;\n        }\n\n        tokenIndexForApprove = _curveSwapStructToken.curveMetaPoolTokenIndexFrom;\n\n        _safeApprove(\n            ICurve(curveMetaPool).coins(tokenIndexForApprove),\n            curveMetaPool,\n            0\n        );\n\n        _safeApprove(\n            ICurve(curveMetaPool).coins(tokenIndexForApprove),\n            curveMetaPool,\n            UINT256_MAX\n        );\n    }\n\n    /**\n     * @dev Reentrency guard for curve pools. Forces\n     * a swap to update internal curve values.\n     */\n    function curveSecurityCheck(\n        address _poolToken\n    )\n        external\n        onlyWiseLending\n    {\n        address curvePool = curveSwapInfoData[_poolToken].curvePool;\n\n        if (curvePool == ZERO_ADDRESS) {\n            return;\n        }\n\n        (\n            bool success\n            ,\n        ) = curvePool.call{value: 0} (\n            curveSwapInfoData[_poolToken].swapBytesPool\n        );\n\n        _checkSuccess(\n            success\n        );\n\n        address curveMeta = curveSwapInfoData[_poolToken].curveMetaPool;\n\n        if (curveMeta == ZERO_ADDRESS) {\n            return;\n        }\n\n        (\n            success\n            ,\n        ) = curveMeta.call{value: 0} (\n            curveSwapInfoData[_poolToken].swapBytesMeta\n        );\n\n        _checkSuccess(\n            success\n        );\n    }\n\n    /**\n     * @dev Checks for withdraw logic.\n     */\n    function checksWithdraw(\n        uint256 _nftId,\n        address _caller,\n        address _poolToken\n    )\n        external\n        view\n        returns (bool specialCase)\n    {\n        if (_checkBlacklisted(_poolToken) == true) {\n\n            if (overallETHBorrowBare(_nftId) > 0) {\n                revert OpenBorrowPosition();\n            }\n\n            return true;\n        }\n\n        if (WISE_LENDING.verifiedIsolationPool(_caller) == true) {\n            return true;\n        }\n\n        if (WISE_LENDING.positionLocked(_nftId) == true) {\n            return true;\n        }\n\n        if (_isUncollateralized(_nftId, _poolToken) == true) {\n            return true;\n        }\n\n        if (WISE_LENDING.getPositionBorrowTokenLength(_nftId) == 0) {\n            return true;\n        }\n    }\n\n    /**\n     * @dev Checks for solely withdraw logic.\n     */\n    function checksSolelyWithdraw(\n        uint256 _nftId,\n        address _caller,\n        address _poolToken\n    )\n        external\n        view\n        returns (bool specialCase)\n    {\n        if (_checkBlacklisted(_poolToken) == true) {\n\n            if (overallETHBorrowBare(_nftId) > 0) {\n                revert OpenBorrowPosition();\n            }\n\n            return true;\n        }\n\n        if (WISE_LENDING.verifiedIsolationPool(_caller) == true) {\n            return true;\n        }\n\n        if (WISE_LENDING.positionLocked(_nftId) == true) {\n            return true;\n        }\n\n    }\n\n    /**\n     * @dev Checks for borrow logic.\n     */\n    function checksBorrow(\n        uint256 _nftId,\n        address _caller,\n        address _poolToken\n    )\n        external\n        view\n        returns (bool specialCase)\n    {\n        _checkPoolCondition(\n            _poolToken\n        );\n\n        checkTokenAllowed(\n            _poolToken\n        );\n\n        if (WISE_LENDING.verifiedIsolationPool(_caller) == true) {\n            return true;\n        }\n\n        if (WISE_LENDING.positionLocked(_nftId) == true) {\n            return true;\n        }\n    }\n\n    /**\n     * @dev Checks for collateralize deposit logic.\n     */\n    function checksCollateralizeDeposit(\n        uint256 _nftId,\n        address _caller,\n        address _poolAddress\n    )\n        external\n        view\n    {\n        if (checkHeartbeat(_poolAddress) == false) {\n            revert ChainlinkDead();\n        }\n\n        _checkPoolCondition(\n            _poolAddress\n        );\n\n        checkOwnerPosition(\n            _nftId,\n            _caller\n        );\n    }\n\n    /**\n     * @dev Checks for uncollateralized deposit logic.\n     */\n    function checkUncollateralizedDeposit(\n        uint256 _nftId,\n        address _poolToken\n    )\n        external\n        view\n    {\n        if (_checkBlacklisted(_poolToken) == true) {\n\n            if (overallETHBorrowBare(_nftId) > 0) {\n                revert OpenBorrowPosition();\n            }\n\n            return;\n        }\n\n        _checkHealthState(\n            {\n                _nftId: _nftId,\n                _powerFarm: false\n            }\n        );\n    }\n\n    /**\n     * @dev Checks if user has healthy position.\n     */\n\n    function checkHealthState(\n        uint256 _nftId,\n        bool _isPowerFarm\n    )\n        external\n        view\n    {\n        _checkHealthState(\n            _nftId,\n            _isPowerFarm\n        );\n    }\n\n    /**\n     * @dev View function returning weighted\n     * supply APY of a postion. 1% <=> 1E16\n     */\n    function overallLendingAPY(\n        uint256 _nftId\n    )\n        external\n        view\n        returns (uint256)\n    {\n        uint256 len = WISE_LENDING.getPositionLendingTokenLength(\n            _nftId\n        );\n\n        if (len == 0) {\n            return 0;\n        }\n\n        uint256 i;\n        address token;\n        uint256 amount;\n        uint256 ethValue;\n        uint256 overallETH;\n        uint256 weightedRate;\n\n        while (i < len) {\n\n            token = WISE_LENDING.getPositionLendingTokenByIndex(\n                _nftId,\n                i\n            );\n\n            amount = getPositionLendingAmount(\n                _nftId,\n                token\n            );\n\n            ethValue = WISE_ORACLE.getTokensInETH(\n                token,\n                amount\n            );\n\n            weightedRate += ethValue\n                * getLendingRate(token);\n\n            overallETH += ethValue;\n\n            unchecked {\n                ++i;\n            }\n        }\n\n        return weightedRate\n            / overallETH;\n    }\n\n    /**\n     * @dev View function returning weighted\n     * borrow APY of a postion. 1% <=> 1E16\n     */\n    function overallBorrowAPY(\n        uint256 _nftId\n    )\n        external\n        view\n        returns (uint256)\n    {\n        uint256 len = WISE_LENDING.getPositionBorrowTokenLength(\n            _nftId\n        );\n\n        if (len == 0) {\n            return 0;\n        }\n\n        uint256 i;\n        address token;\n        uint256 amount;\n        uint256 ethValue;\n        uint256 overallETH;\n        uint256 weightedRate;\n\n        while (i < len) {\n\n            token = WISE_LENDING.getPositionBorrowTokenByIndex(\n                _nftId,\n                i\n            );\n\n            amount = getPositionBorrowAmount(\n                _nftId,\n                token\n            );\n\n            ethValue = WISE_ORACLE.getTokensInETH(\n                token,\n                amount\n            );\n\n            weightedRate += ethValue\n                * getBorrowRate(token);\n\n            overallETH += ethValue;\n\n            unchecked {\n                ++i;\n            }\n        }\n\n        return weightedRate\n            / overallETH;\n    }\n\n    /**\n     * @dev View function returning the total\n     * net APY of a postion. 1% <=> 1E16\n     */\n    function overallNetAPY(\n        uint256 _nftId\n    )\n        external\n        view\n        returns (uint256, bool)\n    {\n        uint256 i;\n        address token;\n        uint256 ethValue;\n        uint256 ethValueDebt;\n        uint256 ethValueGain;\n        uint256 totalETHSupply;\n\n        uint256 netAPY;\n\n        uint256 lenBorrow = WISE_LENDING.getPositionBorrowTokenLength(\n            _nftId\n        );\n\n        uint256 lenDeposit = WISE_LENDING.getPositionLendingTokenLength(\n            _nftId\n        );\n\n        while (i < lenBorrow) {\n\n            token = WISE_LENDING.getPositionBorrowTokenByIndex(\n                _nftId,\n                i\n            );\n\n            ethValue = getETHBorrow(\n                _nftId,\n                token\n            );\n\n            ethValueDebt += ethValue\n                * getBorrowRate(token);\n\n            unchecked {\n                ++i;\n            }\n        }\n\n        i = 0;\n\n        while (i < lenDeposit) {\n\n            token = WISE_LENDING.getPositionLendingTokenByIndex(\n                _nftId,\n                i\n            );\n\n            ethValue = getETHCollateral(\n                _nftId,\n                token\n            );\n\n            totalETHSupply += ethValue;\n            ethValueGain += ethValue\n                * getLendingRate(token);\n\n            unchecked {\n                ++i;\n            }\n        }\n\n        if (ethValueGain >= ethValueDebt) {\n\n            netAPY = (ethValueGain - ethValueDebt)\n                / totalETHSupply;\n\n            return (netAPY, false);\n        }\n\n        netAPY = (ethValueDebt - ethValueGain)\n                / totalETHSupply;\n\n        return (netAPY, true);\n    }\n\n    /**\n     * @dev View function claculating the open\n     * amount a postion is allowed to borrow.\n     */\n    function safeLimitPosition(\n        uint256 _nftId\n    )\n        external\n        view\n        returns (uint256)\n    {\n        uint256 len = WISE_LENDING.getPositionLendingTokenLength(\n            _nftId\n        );\n\n        if (len == 0) {\n            return 0;\n        }\n\n        uint256 i;\n        address token;\n        uint256 buffer;\n\n        while (i < len) {\n\n            token = WISE_LENDING.getPositionLendingTokenByIndex(\n                _nftId,\n                i\n            );\n\n            unchecked {\n                ++i;\n            }\n\n            if (checkHeartbeat(token) == false) {\n                continue;\n            }\n\n            if (wasBlacklisted[token] == true) {\n                continue;\n            }\n\n            buffer += WISE_LENDING.lendingPoolData(token).collateralFactor\n                * getFullCollateralETH(\n                    _nftId,\n                    token\n                ) / PRECISION_FACTOR_E18;\n        }\n\n        return buffer\n            * BORROW_PERCENTAGE_CAP\n            / PRECISION_FACTOR_E18;\n    }\n\n    /**\n     * @dev View function checking if the postion is\n     * locked due to blacklisted token.\n     */\n    function positionBlackListToken(\n        uint256 _nftId\n    )\n        external\n        view\n        returns (bool, address)\n    {\n        uint256 lenDeposit = WISE_LENDING.getPositionLendingTokenLength(\n            _nftId\n        );\n\n        uint256 i;\n        address token;\n\n        while (i < lenDeposit) {\n\n            token = WISE_LENDING.getPositionLendingTokenByIndex(\n                _nftId,\n                i\n            );\n\n            if (_checkBlacklisted(token) == true) {\n                return (\n                    true,\n                    token\n                );\n            }\n\n            unchecked {\n                ++i;\n            }\n        }\n\n        uint256 lenBorrow = WISE_LENDING.getPositionBorrowTokenLength(\n            _nftId\n        );\n\n        i = 0;\n\n        while (i < lenBorrow) {\n\n            token = WISE_LENDING.getPositionBorrowTokenByIndex(\n                _nftId,\n                i\n            );\n\n            if (_checkBlacklisted(token) == true) {\n                return (\n                    true,\n                    token\n                );\n            }\n\n            unchecked {\n                ++i;\n            }\n        }\n\n        return (\n            false,\n            ZERO_ADDRESS\n        );\n    }\n\n    /**\n     * @dev View function extrapolating the\n     * possible withdraw amount of a postion\n     * for a specific _poolToken.\n     */\n    function maximumWithdrawToken(\n        uint256 _nftId,\n        address _poolToken,\n        uint256 _interval,\n        uint256 _solelyWithdrawAmount\n    )\n        external\n        view\n        returns (uint256)\n    {\n        uint256 withdrawAmount;\n\n        uint256 expectedMaxAmount = getExpectedLendingAmount(\n            _nftId,\n            _poolToken,\n            _interval\n        );\n\n        uint256 maxAmountPool = WISE_LENDING.getTotalPool(\n            _poolToken\n        );\n\n        withdrawAmount = expectedMaxAmount;\n\n        if (expectedMaxAmount > maxAmountPool) {\n            withdrawAmount = maxAmountPool;\n        }\n\n        if (_isUncollateralized(_nftId, _poolToken) == true) {\n            return withdrawAmount;\n        }\n\n        uint256 possibelWithdraw = _getPossibleWithdrawAmount(\n            _nftId,\n            _poolToken,\n            _interval\n        );\n\n        withdrawAmount = possibelWithdraw;\n\n        if (possibelWithdraw > expectedMaxAmount) {\n            withdrawAmount = expectedMaxAmount;\n        }\n\n        if (_solelyWithdrawAmount >= withdrawAmount) {\n            return 0;\n        }\n\n        withdrawAmount = withdrawAmount - _solelyWithdrawAmount;\n\n        if (withdrawAmount > maxAmountPool) {\n            return maxAmountPool;\n        }\n\n        return withdrawAmount;\n    }\n\n    /**\n     * @dev View function extrapolating the\n     * possible withdraw amount of a private\n     * postion for a specific _poolToken.\n     */\n    function maximumWithdrawTokenSolely(\n        uint256 _nftId,\n        address _poolToken,\n        uint256 _interval,\n        uint256 _poolWithdrawAmount\n    )\n        external\n        view\n        returns (uint256)\n    {\n        uint256 tokenAmount = _getPossibleWithdrawAmount(\n            _nftId,\n            _poolToken,\n            _interval\n        );\n\n        if (_isUncollateralized(_nftId, _poolToken) == false) {\n\n            if (_poolWithdrawAmount >= tokenAmount) {\n                return 0;\n            }\n\n            tokenAmount = tokenAmount - _poolWithdrawAmount;\n        }\n\n        uint256 maxSolelyAmount = WISE_LENDING.getPureCollateralAmount(\n            _nftId,\n            _poolToken\n        );\n\n        if (tokenAmount > maxSolelyAmount) {\n            return maxSolelyAmount;\n        }\n\n        return tokenAmount;\n    }\n\n    /**\n     * @dev View function extrapolating the\n     * possible borrow amount of postion for\n     * a specific _poolToken.\n     */\n    function maximumBorrowToken(\n        uint256 _nftId,\n        address _poolToken,\n        uint256 _interval\n    )\n        external\n        view\n        returns (uint256 tokenAmount)\n    {\n        uint256 term = _overallETHCollateralsWeighted(_nftId, _interval)\n            * BORROW_PERCENTAGE_CAP\n            / PRECISION_FACTOR_E18;\n\n        uint256 borrowETH = term\n            - _overallETHBorrow(\n                _nftId,\n                _interval\n            );\n\n        tokenAmount = WISE_ORACLE.getTokensFromETH(\n            _poolToken,\n            borrowETH\n        );\n\n        uint256 maxPoolAmount = WISE_LENDING.getTotalPool(\n            _poolToken\n        );\n\n        if (tokenAmount > maxPoolAmount) {\n            tokenAmount = maxPoolAmount;\n        }\n    }\n\n    /**\n     * @dev View function extrapolating the\n     * possible payback amount of a position\n     * for a specific _poolToken.\n     */\n    function getExpectedPaybackAmount(\n        uint256 _nftId,\n        address _poolToken,\n        uint256 _interval\n    )\n        external\n        view\n        returns (uint256)\n    {\n        uint256 borrowShares = WISE_LENDING.getPositionBorrowShares(\n            _nftId,\n            _poolToken\n        );\n\n        uint256 currentTotalBorrowShares = WISE_LENDING.getTotalBorrowShares(\n            _poolToken\n        );\n\n        if (currentTotalBorrowShares == 0) {\n            return 0;\n        }\n\n        uint256 updatedPseudo = _getUpdatedPseudoBorrow(\n            _poolToken,\n            _interval\n        );\n\n        return borrowShares\n            * updatedPseudo\n            / currentTotalBorrowShares;\n    }\n\n    /**\n     * @dev View function extrapolating the\n     * possible lending amount of a position\n     * for a specific _poolToken.\n     */\n    function getExpectedLendingAmount(\n        uint256 _nftId,\n        address _poolToken,\n        uint256 _interval\n    )\n        public\n        view\n        returns (uint256)\n    {\n        uint256 lendingShares = WISE_LENDING.getPositionLendingShares(\n            _nftId,\n            _poolToken\n        );\n\n        uint256 currentTotalLendingShares = WISE_LENDING.getTotalDepositShares(\n            _poolToken\n        );\n\n        if (currentTotalLendingShares == 0) {\n            return 0;\n        }\n\n        uint256 updatedPseudo = _getUpdatedPseudoPool(\n            _poolToken,\n            _interval\n        );\n\n        return lendingShares\n            * updatedPseudo\n            / currentTotalLendingShares;\n    }\n\n    /**\n     * @dev Set function for blacklisting token.\n     * Those token can not be borrowed or used as\n     * collateral anymore. Only callable by master.\n     */\n    function setBlacklistToken(\n        address _tokenAddress,\n        bool _state\n    )\n        external\n        onlyMaster()\n    {\n        wasBlacklisted[_tokenAddress] = _state;\n    }\n\n    /**\n     * @dev Set function for adding or removing\n     * workers to perform a security shutdown.\n     * Only callable by the master.\n     */\n    function setSecurityWorker(\n        address _entitiy,\n        bool _state\n    )\n        external\n        onlyMaster\n    {\n        securityWorker[_entitiy] = _state;\n    }\n\n    /**\n     * Safety function to perform a security\n     * shutdown of all active pools. Can be\n     * called by the security worker, a\n     * special role set by the master.\n     */\n    function securityShutdown()\n        external\n    {\n        if (securityWorker[msg.sender] == false) {\n            revert NotAllowedEntity();\n        }\n\n        _setPoolState(\n            true\n        );\n\n        emit SecurityShutdown(\n            msg.sender,\n            block.timestamp\n        );\n    }\n\n    /**\n     * @dev Master function to revoke all locks,\n     * only callable by the master.\n     */\n    function revokeShutdown()\n        external\n        onlyMaster\n    {\n        _setPoolState(\n            false\n        );\n    }\n\n    /**\n     * @dev External wrapper for pool condition\n     * check.\n     */\n    function checkPoolCondition(\n        address _token\n    )\n        external\n        view\n    {\n        _checkPoolCondition(\n            _token\n        );\n    }\n\n    /**\n     * @dev External wrapper for pool condition\n     * check.\n     */\n    function checkPoolWithMinDeposit(\n        address _token,\n        uint256 _amount\n    )\n        external\n        view\n        returns (bool)\n    {\n        _checkPoolCondition(\n            _token\n        );\n\n        return _checkMinDepositValue(\n            _token,\n            _amount\n        );\n    }\n\n    function checkMinDepositValue(\n        address _token,\n        uint256 _amount\n    )\n        external\n        view\n        returns (bool)\n    {\n        return _checkMinDepositValue(\n            _token,\n            _amount\n        );\n    }\n\n    function _checkMinDepositValue(\n        address _token,\n        uint256 _amount\n    )\n        private\n        view\n        returns (bool)\n    {\n        if (minDepositEthValue == ONE_WEI) {\n            return true;\n        }\n\n        if (_getTokensInEth(_token, _amount) < minDepositEthValue) {\n            revert DepositAmountTooSmall();\n        }\n\n        return true;\n    }\n\n    function changeMinDepositValue(\n        uint256 _newMinDepositValue\n    )\n        external\n        onlyMaster\n    {\n        if (_newMinDepositValue == 0) {\n            revert NoValue();\n        }\n\n        minDepositEthValue = _newMinDepositValue;\n    }\n}\n"
      },
      "contracts/WiseSecurity/WiseSecurityHelper.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\nimport \"./WiseSecurityDeclarations.sol\";\n\nabstract contract WiseSecurityHelper is WiseSecurityDeclarations {\n\n    /**\n     * @dev Read function returning weighted and\n     * and unweighted total collateral of a\n     * postion with {_nftId} (unweighted means\n     * collateral factor equals 1E18).\n     */\n    function overallETHCollateralsBoth(\n        uint256 _nftId\n    )\n        public\n        view\n        returns (uint256, uint256)\n    {\n        uint256 amount;\n        uint256 weightedTotal;\n        uint256 unweightedAmount;\n        address tokenAddress;\n\n        uint256 i;\n        uint256 l = WISE_LENDING.getPositionLendingTokenLength(\n            _nftId\n        );\n\n        while (i < l) {\n\n            tokenAddress = WISE_LENDING.getPositionLendingTokenByIndex(\n                _nftId,\n                i\n            );\n\n            amount = getFullCollateralETH(\n                _nftId,\n                tokenAddress\n            );\n\n            weightedTotal += amount\n                * WISE_LENDING.lendingPoolData(tokenAddress).collateralFactor\n                / PRECISION_FACTOR_E18;\n\n            unweightedAmount += amount;\n\n            unchecked {\n                ++i;\n            }\n        }\n\n        return (\n            weightedTotal,\n            unweightedAmount\n        );\n    }\n\n    /**\n     * @dev Read function returning weighted\n     *  total collateral of a postion with {_nftId}.\n     */\n    function overallETHCollateralsWeighted(\n        uint256 _nftId\n    )\n        public\n        view\n        returns (uint256 weightedTotal)\n    {\n        address tokenAddress;\n\n        uint256 i;\n        uint256 l = WISE_LENDING.getPositionLendingTokenLength(\n            _nftId\n        );\n\n        while (i < l) {\n\n            tokenAddress = WISE_LENDING.getPositionLendingTokenByIndex(\n                _nftId,\n                i\n            );\n\n            _checkPoolCondition(\n                tokenAddress\n            );\n\n            weightedTotal += WISE_LENDING.lendingPoolData(tokenAddress).collateralFactor\n                * getFullCollateralETH(\n                    _nftId,\n                    tokenAddress\n                ) / PRECISION_FACTOR_E18;\n\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /**\n     * @dev Read function returning unweighted\n     *  total collateral of a postion with {_nftId}\n     * (unweighted means collateral factor equals 1E18).\n     */\n    function overallETHCollateralsBare(\n        uint256 _nftId\n    )\n        public\n        view\n        returns (uint256 amount)\n    {\n        address tokenAddress;\n\n        uint256 i;\n        uint256 l = WISE_LENDING.getPositionLendingTokenLength(\n            _nftId\n        );\n\n        while (i < l) {\n\n            tokenAddress = WISE_LENDING.getPositionLendingTokenByIndex(\n                _nftId,\n                i\n            );\n\n            amount += getFullCollateralETH(\n                _nftId,\n                tokenAddress\n            );\n\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /**\n     * @dev Internal calculation function returning\n     * the updated weighted collateral amount of a\n     * postion with {_nftId}. Result can be\n     * extrapolated linear with length {_interval}.\n     */\n    function _overallETHCollateralsWeighted(\n        uint256 _nftId,\n        uint256 _interval\n    )\n        internal\n        view\n        returns (uint256 weightedTotal)\n    {\n        uint256 i;\n        address tokenAddress;\n\n        uint256 l = WISE_LENDING.getPositionLendingTokenLength(\n            _nftId\n        );\n\n        while (i < l) {\n\n            tokenAddress = WISE_LENDING.getPositionLendingTokenByIndex(\n                _nftId,\n                i\n            );\n\n            _checkPoolCondition(\n                tokenAddress\n            );\n\n            weightedTotal += WISE_LENDING.lendingPoolData(tokenAddress).collateralFactor\n                * _getCollateralOfTokenETHUpdated(\n                    _nftId,\n                    tokenAddress,\n                    _interval\n                ) / PRECISION_FACTOR_E18;\n\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /**\n     * @dev Read function returning the full bare\n     * collateral amount of a {_poolToken} from a\n     * {_nftId}. Full means sum of private and\n     * public added funds.\n     */\n    function getFullCollateralETH(\n        uint256 _nftId,\n        address _poolToken\n    )\n        public\n        view\n        returns (uint256 ethCollateral)\n    {\n        ethCollateral = _getTokensInEth(\n            _poolToken,\n            WISE_LENDING.getPureCollateralAmount(\n                _nftId,\n                _poolToken\n            )\n        );\n\n        if (_isUncollateralized(_nftId, _poolToken) == true) {\n            return ethCollateral;\n        }\n\n        if (WISE_LENDING.getPositionLendingShares(_nftId, _poolToken) == 0) {\n            return ethCollateral;\n        }\n\n        ethCollateral += getETHCollateral(\n            _nftId,\n            _poolToken\n        );\n    }\n\n    /**\n     * @dev Wrapper function checking if a supplied\n     * fund is uncollateralized.\n     */\n    function _isUncollateralized(\n        uint256 _nftId,\n        address _poolToken\n    )\n        internal\n        view\n        returns (bool)\n    {\n        return WISE_LENDING.isUncollateralized(\n            _nftId,\n            _poolToken\n        );\n    }\n\n    /**\n     * @dev Read function returning the full\n     * collateral amount of a {_poolToken} from a\n     * {_nftId} updated to current values.\n     * Full means sum of private and public added\n     * funds. Can be extrapolated linear within\n     * {_interval}.\n     */\n    function _getCollateralOfTokenETHUpdated(\n        uint256 _nftId,\n        address _poolToken,\n        uint256 _interval\n    )\n        internal\n        view\n        returns (uint256 ethCollateral)\n    {\n        ethCollateral = _getTokensInEth(\n            _poolToken,\n            WISE_LENDING.getPureCollateralAmount(\n                _nftId,\n                _poolToken\n            )\n        );\n\n        if (_isUncollateralized(_nftId, _poolToken) == true) {\n            return ethCollateral;\n        }\n\n        ethCollateral += getETHCollateralUpdated(\n            _nftId,\n            _poolToken,\n            _interval\n        );\n    }\n\n    /**\n     * @dev Read function returning the full\n     * (private and public) collateral amount\n     * of a {_poolToken} from a {_nftId} updated\n     * to current values. Can be extrapolated\n     * linear within {_interval}.\n     */\n    function getETHCollateralUpdated(\n        uint256 _nftId,\n        address _poolToken,\n        uint256 _interval\n    )\n        public\n        view\n        returns (uint256)\n    {\n        uint256 lendingShares = WISE_LENDING.getPositionLendingShares(\n            _nftId,\n            _poolToken\n        );\n\n        if (lendingShares == 0) {\n            return 0;\n        }\n\n        uint256 currentTotalLendingShares = WISE_LENDING.getTotalDepositShares(\n            _poolToken\n        );\n\n        uint256 updatedPseudo = _getUpdatedPseudoPool(\n            _poolToken,\n            _interval\n        );\n\n        uint256 updatedToken = lendingShares\n            * updatedPseudo\n            / currentTotalLendingShares;\n\n        return _getTokensInEth(\n            _poolToken,\n            updatedToken\n        );\n    }\n\n    /**\n     * @dev Read function returning the public\n     * collateral amount of a {_poolToken} from a\n     * {_nftId}.\n     */\n    function getETHCollateral(\n        uint256 _nftId,\n        address _poolToken\n    )\n        public\n        view\n        returns (uint256)\n    {\n        return _getTokensInEth(\n            _poolToken,\n            getPositionLendingAmount(\n                _nftId,\n                _poolToken\n            )\n        );\n    }\n\n    function _getTokensInEth(\n        address _poolToken,\n        uint256 _amount\n    )\n        internal\n        view\n        returns (uint256)\n    {\n        return WISE_ORACLE.getTokensInETH(\n            _poolToken,\n            _amount\n        );\n    }\n\n    /**\n     * @dev Read function returning the total\n     * borrow amount of a postion with {_nftId}.\n     * No heartbeat or blacklisted checks are\n     * included in this function!\n     */\n    function overallETHBorrowBare(\n        uint256 _nftId\n    )\n        public\n        view\n        returns (uint256 buffer)\n    {\n        uint256 i;\n        uint256 l = WISE_LENDING.getPositionBorrowTokenLength(\n            _nftId\n        );\n\n        while (i < l) {\n\n            buffer += getETHBorrow(\n                _nftId,\n                WISE_LENDING.getPositionBorrowTokenByIndex(\n                    _nftId,\n                    i\n                )\n            );\n\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /**\n     * @dev Read function returning the total\n     * borrow amount of a postion with {_nftId}.\n     * No blacklisted check is included\n     * in this function!\n     */\n    function overallETHBorrowHeartbeat(\n        uint256 _nftId\n    )\n        public\n        view\n        returns (uint256 buffer)\n    {\n        address tokenAddress;\n\n        uint256 i;\n        uint256 l = WISE_LENDING.getPositionBorrowTokenLength(\n            _nftId\n        );\n\n        while (i < l) {\n\n            tokenAddress = WISE_LENDING.getPositionBorrowTokenByIndex(\n                _nftId,\n                i\n            );\n\n            buffer += getETHBorrow(\n                _nftId,\n                tokenAddress\n            );\n\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /**\n     * @dev Read function returning the total\n     * borrow amount of a postion with {_nftId}.\n     */\n    function overallETHBorrow(\n        uint256 _nftId\n    )\n        public\n        view\n        returns (uint256 buffer)\n    {\n        uint256 i;\n        address tokenAddress;\n\n        uint256 l = WISE_LENDING.getPositionBorrowTokenLength(\n            _nftId\n        );\n\n        while (i < l) {\n\n            tokenAddress = WISE_LENDING.getPositionBorrowTokenByIndex(\n                _nftId,\n                i\n            );\n\n            _checkPoolCondition(\n                tokenAddress\n            );\n\n            buffer += getETHBorrow(\n                _nftId,\n                tokenAddress\n            );\n\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /**\n     * @dev Internal function combining hearbeat\n     * and blacklisted checks.\n     */\n    function _checkBlacklisted(\n        address _poolToken\n    )\n        internal\n        view\n        returns (bool)\n    {\n        return wasBlacklisted[_poolToken] == true;\n    }\n\n    /**\n     * @dev Read function returning the total\n     * updated current borrow amount of a\n     * postion with {_nftId}. Can be\n     * extrapolated linear with {_intervall}.\n     */\n    function _overallETHBorrow(\n        uint256 _nftId,\n        uint256 _interval\n    )\n        internal\n        view\n        returns (uint256 buffer)\n    {\n        uint256 i;\n        address tokenAddress;\n\n        uint256 l = WISE_LENDING.getPositionBorrowTokenLength(\n            _nftId\n        );\n\n        while (i < l) {\n\n            tokenAddress = WISE_LENDING.getPositionBorrowTokenByIndex(\n                _nftId,\n                i\n            );\n\n            _checkPoolCondition(\n                tokenAddress\n            );\n\n            buffer += _getETHBorrowUpdated(\n                _nftId,\n                tokenAddress,\n                _interval\n            );\n\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /**\n     * @dev Internal function calculating\n     * the updated pseudo borrow amount of\n     * {_poolToken}. Result can be extrapolated\n     * linear with {_interval}.\n     */\n    function _getUpdatedPseudoBorrow(\n        address _poolToken,\n        uint256 _interval\n    )\n        internal\n        view\n        returns (uint256)\n    {\n        uint256 currentPseudo = WISE_LENDING.getPseudoTotalBorrowAmount(\n            _poolToken\n        );\n\n        return _getInterest(\n            _poolToken,\n            _interval\n        ) + currentPseudo;\n    }\n\n    /**\n     * @dev Internal function calculating\n     * the updated pseudo lending amount of\n     * {_poolToken}. Result can be extrapolated\n     * linear with {_interval}.\n     */\n    function _getUpdatedPseudoPool(\n        address _poolToken,\n        uint256 _interval\n    )\n        internal\n        view\n        returns (uint256)\n    {\n        uint256 currentPseudo = WISE_LENDING.getPseudoTotalPool(\n            _poolToken\n        );\n\n        return _getInterest(_poolToken, _interval)\n            * (PRECISION_FACTOR_E18 - WISE_LENDING.globalPoolData(_poolToken).poolFee)\n            / PRECISION_FACTOR_E18\n            + currentPseudo;\n    }\n\n    /**\n     * @dev Internal math function calculating\n     * the accumulated interest amount for\n     * {_poolToken}. Result can be extrapolated\n     * linear with {_interval}.\n     */\n    function _getInterest(\n        address _poolToken,\n        uint256 _interval\n    )\n        internal\n        view\n        returns (uint256)\n    {\n        BorrowPoolEntry memory borrowPoolData = WISE_LENDING.borrowPoolData(\n            _poolToken\n        );\n\n        uint256 timeInterval = _interval\n            + block.timestamp\n            - WISE_LENDING.getTimeStamp(_poolToken);\n\n        uint256 rate = timeInterval\n            * borrowPoolData.borrowRate\n            * WISE_LENDING.getPseudoTotalBorrowAmount(_poolToken)\n            / PRECISION_FACTOR_E18\n            / ONE_YEAR;\n\n        return rate;\n    }\n\n    /**\n     * @dev Read function returning the full\n     * borrow amount of a {_poolToken} from a\n     * {_nftId} updated to current values.\n     * Can be extrapolated linear within\n     * {_interval}.\n     */\n    function _getETHBorrowUpdated(\n        uint256 _nftId,\n        address _poolToken,\n        uint256 _intervall\n    )\n        internal\n        view\n        returns (uint256)\n    {\n        uint256 borrowShares = WISE_LENDING.getPositionBorrowShares(\n            _nftId,\n            _poolToken\n        );\n\n        if (borrowShares == 0) {\n            return 0;\n        }\n\n        uint256 currentTotalBorrowShares = WISE_LENDING.getTotalBorrowShares(\n            _poolToken\n        );\n\n        uint256 updatesPseudo = _getUpdatedPseudoBorrow(\n            _poolToken,\n            _intervall\n        );\n\n        uint256 updatedToken = borrowShares\n            * updatesPseudo\n            / currentTotalBorrowShares;\n\n        return _getTokensInEth(\n            _poolToken,\n            updatedToken\n        );\n    }\n\n    /**\n     * @dev Read function returning the borow\n     * amount of a {_poolToken} from a {_nftId}.\n     */\n    function getETHBorrow(\n        uint256 _nftId,\n        address _poolToken\n    )\n        public\n        view\n        returns (uint256)\n    {\n        return _getTokensInEth(\n            _poolToken,\n            getPositionBorrowAmount(\n                _nftId,\n                _poolToken\n            )\n        );\n    }\n\n    /**\n     * @dev Read function checking if\n     * {_poolToken} is allowed to borrow.\n     */\n    function checkTokenAllowed(\n        address _poolAddress\n    )\n        public\n        view\n    {\n        if (WISE_LENDING.borrowPoolData(_poolAddress).allowBorrow == false) {\n            revert NotAllowedToBorrow();\n        }\n    }\n\n    /**\n     * @dev Check if chainLink feed was\n     * updated within expected timeframe\n     */\n    function checkHeartbeat(\n        address _poolToken\n    )\n        public\n        view\n        returns (bool)\n    {\n        return WISE_ORACLE.chainLinkIsDead(_poolToken) == false;\n    }\n\n    /**\n     * @dev Check if the postion with\n     * {_nftId} is locked for interactions.\n     */\n    function _checkPositionLocked(\n        uint256 _nftId\n    )\n        internal\n        view\n    {\n        if (WISE_LENDING.positionLocked(_nftId) == true) {\n            revert PositionLockedWiseSecurity();\n        }\n    }\n\n    /**\n     * @dev Wrapper function for external\n     * {_checkMaxFee} call.\n     */\n    function checkMaxFee(\n        uint256 _paybackETH,\n        uint256 _feeLiquidation,\n        uint256 _maxFeeETH\n    )\n        external\n        pure\n        returns (uint256)\n    {\n        return _checkMaxFee(\n            _paybackETH,\n            _feeLiquidation,\n            _maxFeeETH\n        );\n    }\n\n    /**\n     * @dev Returning the possible fee\n     * for liquidation.\n     */\n    function _checkMaxFee(\n        uint256 _paybackETH,\n        uint256 _liquidationFee,\n        uint256 _maxFeeETH\n    )\n        internal\n        pure\n        returns (uint256)\n    {\n        uint256 feeETH = _paybackETH\n            * _liquidationFee\n            / PRECISION_FACTOR_E18;\n\n        return feeETH < _maxFeeETH\n            ? feeETH\n            : _maxFeeETH;\n    }\n\n    /**\n     * @dev Math function computing the\n     * percentage of the receiving token\n     * which the liquidator receivs for\n     * liquidation.\n     */\n    function calculateWishPercentage(\n        uint256 _nftId,\n        address _receiveToken,\n        uint256 _paybackETH,\n        uint256 _maxFeeETH,\n        uint256 _baseRewardLiquidation\n    )\n        external\n        view\n        returns (uint256)\n    {\n        uint256 feeETH = _checkMaxFee(\n            _paybackETH,\n            _baseRewardLiquidation,\n            _maxFeeETH\n        );\n\n        uint256 numerator = (feeETH + _paybackETH)\n            * PRECISION_FACTOR_E18;\n\n        uint256 denominator = getFullCollateralETH(\n            _nftId,\n            _receiveToken\n        );\n\n        return numerator / denominator + 1;\n    }\n\n    /**\n     * @dev Check function for withdraw flow.\n     * Tests if debt ratio is not greater than\n     * 100% after withdraw of {_poolToken} for\n     * {_amount}.\n     */\n    function _checkHealthState(\n        uint256 _nftId,\n        bool _powerFarm\n    )\n        internal\n        view\n    {\n        if (_getState(_nftId, _powerFarm) == true) {\n            revert ResultsInBadDebt();\n        }\n    }\n\n    function _getState(\n        uint256 _nftId,\n        bool _powerFarm\n    )\n        internal\n        view\n        returns (bool)\n    {\n        uint256 borrowAmount = overallETHBorrow(\n            _nftId\n        );\n\n        if (borrowAmount == 0) {\n            return false;\n        }\n\n        uint256 overallCollateral = _powerFarm == true\n            ? overallETHCollateralsBare(_nftId)\n            : overallETHCollateralsWeighted(_nftId);\n\n        return overallCollateral\n            * BORROW_PERCENTAGE_CAP\n            / PRECISION_FACTOR_E18\n            < borrowAmount;\n    }\n\n    /**\n     * @dev Check function for registration\n     * of power farms. User can only register\n     * when the postion is empty!\n     */\n    function checksRegister(\n        uint256 _nftId,\n        address _caller\n    )\n        public\n        view\n    {\n        checkOwnerPosition(\n            _nftId,\n            _caller\n        );\n\n        if (overallETHCollateralsWeighted(_nftId) > 0) {\n            revert NotAllowedWiseSecurity();\n        }\n    }\n\n    /**\n     * @dev Pure math function comparing\n     * borrow and collateral amount for\n     * liquidation.\n     */\n    function canLiquidate(\n        uint256 _borrowETHTotal,\n        uint256 _weightedCollateralETH\n    )\n        public\n        pure\n    {\n        if (_borrowETHTotal < _weightedCollateralETH) {\n            revert LiquidationDenied();\n        }\n    }\n\n    /**\n     * @dev Helper function for liquidation checking\n     * return amount of receiving shares for liquidator.\n     * Has to be smaller 50% when no bad debt occurs.\n     */\n    function checkMaxShares(\n        uint256 _nftId,\n        address _tokenToPayback,\n        uint256 _borrowETHTotal,\n        uint256 _unweightedCollateralETH,\n        uint256 _shareAmountToPay\n    )\n        public\n        view\n    {\n        uint256 totalSharesUser = WISE_LENDING.getPositionBorrowShares(\n            _nftId,\n            _tokenToPayback\n        );\n\n        uint256 maxShares = checkBadDebtThreshold(_borrowETHTotal, _unweightedCollateralETH)\n            ? totalSharesUser\n            : totalSharesUser * MAX_LIQUIDATION_50 / PRECISION_FACTOR_E18;\n\n        if (_shareAmountToPay <= maxShares) {\n            return;\n        }\n\n        revert TooManyShares();\n    }\n\n    /**\n     * @dev Helper function for liquidation checking\n     * if postion has bad debt.\n     */\n    function checkBadDebtThreshold(\n        uint256 _borrowETHTotal,\n        uint256 _unweightedCollateral\n    )\n        public\n        pure\n        returns (bool)\n    {\n        return _borrowETHTotal * PRECISION_FACTOR_E18\n            >= _unweightedCollateral * BAD_DEBT_THRESHOLD;\n    }\n\n    /**\n     * @dev Helper function computing lending\n     * token amount for {_poolToken}.\n     */\n    function getPositionLendingAmount(\n        uint256 _nftId,\n        address _poolToken\n    )\n        public\n        view\n        returns (uint256)\n    {\n        return WISE_LENDING.cashoutAmount(\n            {\n                _poolToken: _poolToken,\n                _shares: WISE_LENDING.getPositionLendingShares(\n                    _nftId,\n                    _poolToken\n                )\n            }\n        );\n    }\n\n    /**\n     * @dev Helper function computing borrow\n     * token amount for {_poolToken}.\n     */\n    function getPositionBorrowAmount(\n        uint256 _nftId,\n        address _poolToken\n    )\n        public\n        view\n        returns (uint256)\n    {\n        return WISE_LENDING.paybackAmount(\n            _poolToken,\n            WISE_LENDING.getPositionBorrowShares(\n                _nftId,\n                _poolToken\n            )\n        );\n    }\n\n    /**\n     * @dev Helper function checking the owner\n     * of {_nftId}. Reverts if owner is invalid.\n     */\n    function checkOwnerPosition(\n        uint256 _nftId,\n        address _caller\n    )\n        public\n        view\n    {\n        if (POSITION_NFTS.isOwner(\n            _nftId,\n            _caller\n        ) == false) {\n            revert NotOwner();\n        }\n    }\n\n    /**\n     * @dev Wrapper function returning the borrow\n     * rate from pool with token {_poolToken}.\n     */\n    function getBorrowRate(\n        address _poolToken\n    )\n        public\n        view\n        returns (uint256)\n    {\n        return WISE_LENDING.borrowPoolData(_poolToken).borrowRate;\n    }\n\n    /**\n     * @dev View function returning the lending\n     * rate from pool with token {_poolToken}.\n     */\n    function getLendingRate(\n        address _poolToken\n    )\n        public\n        view\n        returns (uint256)\n    {\n        uint256 pseudoTotalPool = WISE_LENDING.getPseudoTotalPool(\n            _poolToken\n        );\n\n        if (pseudoTotalPool == 0) {\n            return 0;\n        }\n\n        uint256 adjustedRate = getBorrowRate(_poolToken)\n            * (PRECISION_FACTOR_E18 - WISE_LENDING.globalPoolData(_poolToken).poolFee)\n            / PRECISION_FACTOR_E18;\n\n        return adjustedRate\n            * WISE_LENDING.getPseudoTotalBorrowAmount(_poolToken)\n            / pseudoTotalPool;\n    }\n\n    /**\n     * @dev Internal helper function calculating\n     * the possible withdraw amount of {_poolToken}\n     * under current borrow and collateral amount\n     * of {_nftId}.\n     */\n    function _getPossibleWithdrawAmount(\n        uint256 _nftId,\n        address _poolToken,\n        uint256 _interval\n    )\n        internal\n        view\n        returns (uint256)\n    {\n        uint256 term = _overallETHBorrow(_nftId, _interval)\n            * PRECISION_FACTOR_E18\n            / BORROW_PERCENTAGE_CAP;\n\n        uint256 withdrawETH = PRECISION_FACTOR_E18\n            * (_overallETHCollateralsWeighted(_nftId, _interval) - term)\n            / WISE_LENDING.lendingPoolData(_poolToken).collateralFactor;\n\n        return WISE_ORACLE.getTokensFromETH(\n            _poolToken,\n            withdrawETH\n        );\n    }\n\n    /**\n     * Locking or unlocking all pools for borrow\n     * and deposit actions. Performs action for\n     * all pools.\n     */\n    function _setPoolState(\n        bool _state\n    )\n        internal\n    {\n        uint256 i;\n        uint256 len = FEE_MANAGER.getPoolTokenAddressesLength();\n\n        while(i < len) {\n\n            wasBlacklisted[\n                FEE_MANAGER.getPoolTokenAdressesByIndex(i)\n            ] = _state;\n\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /**\n     * @dev Wrapper for {_checkBlacklisted}.\n     */\n    function _checkPoolCondition(\n        address _poolToken\n    )\n        internal\n        view\n    {\n        if (_checkBlacklisted(_poolToken) == true) {\n            revert TokenBlackListed();\n        }\n    }\n\n    /**\n     * @dev Internal helper checking of success\n     * for a low level byte call of a function\n     * with {.call()}.\n     */\n    function _checkSuccess(\n        bool _success\n    )\n        internal\n        pure\n    {\n        if (_success == false) {\n            revert SecuritySwapFailed();\n        }\n    }\n}\n"
      },
      "contracts/TransferHub/ApprovalHelper.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\nimport \"./CallOptionalReturn.sol\";\n\ncontract ApprovalHelper is CallOptionalReturn {\n\n    /**\n     * @dev\n     * Allows to execute safe approve for a token\n     */\n    function _safeApprove(\n        address _token,\n        address _spender,\n        uint256 _value\n    )\n        internal\n    {\n        if (_spender == address(0)) {\n            return;\n        }\n\n        _callOptionalReturn(\n            _token,\n            abi.encodeWithSelector(\n                IERC20.approve.selector,\n                _spender,\n                _value\n            )\n        );\n    }\n}"
      },
      "contracts/WiseSecurity/WiseSecurityDeclarations.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\nimport \"../InterfaceHub/IERC20.sol\";\nimport \"../InterfaceHub/ICurve.sol\";\nimport \"../InterfaceHub/IPositionNFTs.sol\";\nimport \"../InterfaceHub/IWiseOracleHub.sol\";\nimport \"../InterfaceHub/IFeeManager.sol\";\nimport \"../InterfaceHub/IWiseLending.sol\";\nimport \"../InterfaceHub/IWiseLiquidation.sol\";\nimport {\n    IAaveHub as IAaveHubWiseSecurity\n} from \"../InterfaceHub/IAaveHub.sol\";\n\nimport \"../FeeManager/FeeManager.sol\";\nimport \"../OwnableMaster.sol\";\n\nerror NotAllowedEntity();\nerror ChainlinkDead();\nerror TokenBlackListed();\nerror NotAllowedWiseSecurity();\nerror PositionLockedWiseSecurity();\nerror ResultsInBadDebt();\nerror NotEnoughCollateral();\nerror NotAllowedToBorrow();\nerror OpenBorrowPosition();\nerror NonVerifiedPool();\nerror NotOwner();\nerror LiquidationDenied();\nerror TooManyShares();\nerror NotRegistered();\nerror Blacklisted();\nerror SecuritySwapFailed();\nerror BaseRewardTooHigh();\nerror BaseRewardTooLow();\nerror BaseRewardFarmTooHigh();\nerror BaseRewardFarmTooLow();\nerror MaxFeeEthTooHigh();\nerror MaxFeeEthTooLow();\nerror MaxFeeFarmEthTooHigh();\nerror MaxFeeFarmEthTooLow();\nerror DepositAmountTooSmall();\n\ncontract WiseSecurityDeclarations is OwnableMaster {\n\n    event SecurityShutdown(\n        address indexed caller,\n        uint256 indexed timestamp\n    );\n\n    constructor(\n        address _master,\n        address _wiseLendingAddress,\n        address _aaveHubAddress\n    )\n        OwnableMaster(\n            _master\n        )\n    {\n        if (_wiseLendingAddress == ZERO_ADDRESS) {\n            revert NoValue();\n        }\n\n        if (_aaveHubAddress == ZERO_ADDRESS) {\n            revert NoValue();\n        }\n\n        securityWorker[_master] = true;\n\n        WISE_LENDING = IWiseLending(\n            _wiseLendingAddress\n        );\n\n        AAVE_HUB = _aaveHubAddress;\n\n        address lendingMaster = WISE_LENDING.master();\n        address oracleHubAddress = WISE_LENDING.WISE_ORACLE();\n        address positionNFTAddress = WISE_LENDING.POSITION_NFT();\n\n        FeeManager feeManagerContract = new FeeManager(\n            lendingMaster,\n            IAaveHubWiseSecurity(AAVE_HUB).AAVE_ADDRESS(),\n            _wiseLendingAddress,\n            oracleHubAddress,\n            address(this),\n            positionNFTAddress\n        );\n\n        WISE_ORACLE = IWiseOracleHub(\n            oracleHubAddress\n        );\n\n        FEE_MANAGER = IFeeManager(\n            address(feeManagerContract)\n        );\n\n        WISE_LIQUIDATION = IWiseLiquidation(\n            _wiseLendingAddress\n        );\n\n        POSITION_NFTS = IPositionNFTs(\n            positionNFTAddress\n        );\n\n        IS_ETH_MAINNET = block.chainid == 1;\n\n        _setLiquidationSettings(\n            {\n                _baseReward: 10 * PRECISION_FACTOR_E16,\n                _baseRewardFarm: 3 * PRECISION_FACTOR_E16,\n                _newMaxFeeETH: 3 * PRECISION_FACTOR_E18,\n                _newMaxFeeFarmETH: 3 * PRECISION_FACTOR_E18\n            }\n        );\n    }\n\n    function _setLiquidationSettings(\n        uint256 _baseReward,\n        uint256 _baseRewardFarm,\n        uint256 _newMaxFeeETH,\n        uint256 _newMaxFeeFarmETH\n    )\n        internal\n    {\n        if (_baseReward > LIQUIDATION_INCENTIVE_MAX) {\n            revert BaseRewardTooHigh();\n        }\n\n        if (_baseReward < LIQUIDATION_INCENTIVE_MIN) {\n            revert BaseRewardTooLow();\n        }\n\n        baseRewardLiquidation = _baseReward;\n\n        if (_baseRewardFarm > LIQUIDATION_INCENTIVE_POWERFARM_MAX) {\n            revert BaseRewardFarmTooHigh();\n        }\n\n        if (_baseRewardFarm < LIQUIDATION_INCENTIVE_MIN) {\n            revert BaseRewardFarmTooLow();\n        }\n\n        baseRewardLiquidationFarm = _baseRewardFarm;\n\n        uint256 maxFee = IS_ETH_MAINNET == true\n            ? LIQUIDATION_FEE_MAX_ETH\n            : LIQUIDATION_FEE_MAX_NON_ETH;\n\n        uint256 minFee = IS_ETH_MAINNET == true\n            ? LIQUIDATION_FEE_MIN_ETH\n            : LIQUIDATION_FEE_MIN_NON_ETH;\n\n        if (_newMaxFeeETH > maxFee) {\n            revert MaxFeeEthTooHigh();\n        }\n\n        if (_newMaxFeeETH < minFee) {\n            revert MaxFeeEthTooLow();\n        }\n\n        maxFeeETH = _newMaxFeeETH;\n\n        uint256 maxFeeFarm = IS_ETH_MAINNET == true\n            ? LIQUIDATION_FEE_MAX_ETH\n            : LIQUIDATION_FEE_MAX_NON_ETH;\n\n        uint256 minFeeFarm = IS_ETH_MAINNET == true\n            ? LIQUIDATION_FEE_MIN_ETH\n            : LIQUIDATION_FEE_MIN_NON_ETH;\n\n        if (_newMaxFeeFarmETH > maxFeeFarm) {\n            revert MaxFeeFarmEthTooHigh();\n        }\n\n        if (_newMaxFeeFarmETH < minFeeFarm) {\n            revert MaxFeeFarmEthTooLow();\n        }\n\n        maxFeeFarmETH = _newMaxFeeFarmETH;\n    }\n\n    // ---- Variables ----\n\n    uint256 public constant BORROW_PERCENTAGE_CAP = 95 * PRECISION_FACTOR_E16;\n    address public immutable AAVE_HUB;\n\n    // ---- Interfaces ----\n\n    // Interface feeManager contract\n    IFeeManager public immutable FEE_MANAGER;\n\n    // Interface wiseLending contract\n    IWiseLending public immutable WISE_LENDING;\n\n    // Interface position NFT contract\n    IPositionNFTs public immutable POSITION_NFTS;\n\n    // Interface oracleHub contract\n    IWiseOracleHub public immutable WISE_ORACLE;\n\n    // Interface wiseLiquidation contract\n    IWiseLiquidation public immutable WISE_LIQUIDATION;\n\n    // Threshold values\n    uint256 internal constant MAX_LIQUIDATION_50 = 50E16;\n    uint256 internal constant BAD_DEBT_THRESHOLD = 89E16;\n\n    uint256 internal constant UINT256_MAX = type(uint256).max;\n    uint256 internal constant ONE_YEAR = 365 days;\n\n    // adjustable\n\n    uint256 public minDepositEthValue = 1; // in wei?\n\n    // Precision factors for computations\n    uint256 internal constant PRECISION_FACTOR_E16 = 1E16;\n    uint256 internal constant PRECISION_FACTOR_E18 = 1E18;\n    uint256 internal constant ONE_WEI = 1;\n\n    // Chain - ID bool for Ethereum mainnet check\n    bool immutable IS_ETH_MAINNET;\n\n    // Liquidation Incentive threshholds\n    uint256 internal constant LIQUIDATION_INCENTIVE_MAX = 11 * PRECISION_FACTOR_E16;\n    uint256 internal constant LIQUIDATION_INCENTIVE_MIN = 2 * PRECISION_FACTOR_E16;\n    uint256 internal constant LIQUIDATION_INCENTIVE_POWERFARM_MAX = 4 * PRECISION_FACTOR_E16;\n\n    // Liquidation Fee threshholds\n    uint256 internal constant LIQUIDATION_FEE_MIN_ETH = 3 * PRECISION_FACTOR_E18;\n    uint256 internal constant LIQUIDATION_FEE_MAX_ETH = 100 * PRECISION_FACTOR_E18;\n    uint256 internal constant LIQUIDATION_FEE_MAX_NON_ETH = 10 * PRECISION_FACTOR_E18;\n    uint256 internal constant LIQUIDATION_FEE_MIN_NON_ETH = 30 * PRECISION_FACTOR_E16;\n\n    // ---- Mapping Variables ----\n\n    // Mapping pool token to blacklist bool\n    mapping(address => bool) public wasBlacklisted;\n\n    // Mapping basic swap data for curve swaps to pool token\n    mapping(address => CurveSwapStructData) public curveSwapInfoData;\n\n    // Mapping swap info of swap token for reentrency guard to pool token\n    mapping(address => CurveSwapStructToken) public curveSwapInfoToken;\n\n    // Mapping addresses which are allowed to perform a security lock.\n    mapping(address => bool) public securityWorker;\n\n    // ---- Liquidation Variables ----\n\n    // Max reward ETH for liquidator power farm liquidation\n    uint256 public maxFeeETH;\n\n    // Max reward ETH for liquidator normal liquidation\n    uint256 public maxFeeFarmETH;\n\n    // Base reward for liquidator normal liquidation\n    uint256 public baseRewardLiquidation;\n\n    // Base reward for liquidator power farm liquidation\n    uint256 public baseRewardLiquidationFarm;\n}\n"
      },
      "contracts/TransferHub/CallOptionalReturn.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\nimport \"../InterfaceHub/IERC20.sol\";\n\ncontract CallOptionalReturn {\n\n    /**\n     * @dev Helper function to do low-level call\n     */\n    function _callOptionalReturn(\n        address token,\n        bytes memory data\n    )\n        internal\n        returns (bool call)\n    {\n        (\n            bool success,\n            bytes memory returndata\n        ) = token.call(\n            data\n        );\n\n        bool results = returndata.length == 0 || abi.decode(\n            returndata,\n            (bool)\n        );\n\n        if (success == false) {\n            revert();\n        }\n\n        call = success\n            && results\n            && token.code.length > 0;\n    }\n}"
      },
      "contracts/InterfaceHub/IERC20.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\ninterface IERC20 {\n\n    function totalSupply()\n        external\n        view\n        returns (uint256);\n\n    function balanceOf(\n        address _account\n    )\n        external\n        view\n        returns (uint256);\n\n    function transferFrom(\n        address _sender,\n        address _recipient,\n        uint256 _amount\n    )\n        external\n        returns (bool);\n\n    function transfer(\n        address _recipient,\n        uint256 _amount\n    )\n        external\n        returns (bool);\n\n    function allowance(\n        address owner,\n        address spender\n    )\n        external\n        view\n        returns (uint256);\n\n    function approve(\n        address _spender,\n        uint256 _amount\n    )\n        external\n        returns (bool);\n\n    function decimals()\n        external\n        view\n        returns (uint8);\n\n    event Transfer(\n        address indexed from,\n        address indexed to,\n        uint256 value\n    );\n\n    event Approval(\n        address indexed owner,\n        address indexed spender,\n        uint256 value\n    );\n\n    event  Deposit(\n        address indexed dst,\n        uint wad\n    );\n\n    event  Withdrawal(\n        address indexed src,\n        uint wad\n    );\n}\n"
      },
      "contracts/InterfaceHub/ICurve.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\ninterface ICurve {\n\n    function add_liquidity(\n        address _pool,\n        uint256[4] memory _depositAmounts,\n        uint256 _minOutAmount\n    )\n        external\n        returns (uint256);\n\n    function balanceOf(\n        address _userAddress\n    )\n        external\n        view\n        returns (uint256);\n\n    function get_dy(\n        int128 i,\n        int128 j,\n        uint256 dx\n    )\n        external\n        view\n        returns (uint256);\n\n    function get_dy_underlying(\n        int128 i,\n        int128 j,\n        uint256 dx\n    )\n        external\n        view\n        returns (uint256);\n\n    function exchange(\n        int128 fromIndex,\n        int128 toIndex,\n        uint256 exactAmountFrom,\n        uint256 minReceiveAmount\n    )\n        external\n        returns (uint256);\n\n    function exchange_underlying(\n        int128 i,\n        int128 j,\n        uint256 dx,\n        uint256 min_dy\n    )\n        external;\n\n    function remove_liquidity(\n        address _pool,\n        uint256 _burnAmount,\n        uint256[4] memory _coins\n    )\n        external;\n\n    function remove_liquidity_one_coin(\n        address _addy,\n        uint256 _burnAmount,\n        int128 _i,\n        uint256 _minReceived\n    )\n        external;\n\n    function coins(\n        uint256 arg0\n    )\n        external\n        view\n        returns (address);\n\n    function decimals()\n        external\n        view\n        returns (uint8);\n\n    function totalSupply()\n        external\n        view\n        returns (uint256);\n\n    function balances(\n        uint256 arg0\n    )\n        external\n        view\n        returns (uint256);\n\n    function approve(\n        address _spender,\n        uint256 _amount\n    )\n        external\n        returns (bool);\n}\n"
      },
      "contracts/InterfaceHub/IPositionNFTs.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\ninterface IPositionNFTs {\n\n    function ownerOf(\n        uint256 _nftId\n    )\n        external\n        view\n        returns (address);\n\n    function totalSupply()\n        external\n        view\n        returns (uint256);\n\n    function reserved(\n        address _owner\n    )\n        external\n        view\n        returns (uint256);\n\n    function reservePosition()\n        external;\n\n    function mintPosition()\n        external\n        returns (uint256);\n\n    function tokenOfOwnerByIndex(\n        address _owner,\n        uint256 _index\n    )\n        external\n        view\n        returns (uint256);\n\n    function walletOfOwner(\n        address _owner\n    )\n        external\n        view\n        returns (uint256[] memory);\n\n    function mintPositionForUser(\n        address _user\n    )\n        external\n        returns (uint256);\n\n    function reservePositionForUser(\n        address _user\n    )\n        external\n        returns (uint256);\n\n    function getNextExpectedId()\n        external\n        view\n        returns (uint256);\n\n    function getApproved(\n        uint256 _nftId\n    )\n        external\n        view\n        returns (address);\n\n    function approve(\n        address _to,\n        uint256 _nftId\n    )\n        external;\n\n    function isOwner(\n        uint256 _nftId,\n        address _caller\n    )\n        external\n        view\n        returns (bool);\n\n    function FEE_MANAGER_NFT()\n        external\n        view\n        returns (uint256);\n}\n"
      },
      "contracts/InterfaceHub/IWiseOracleHub.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\ninterface IWiseOracleHub {\n\n    function getTokensPriceFromUSD(\n        address _tokenAddress,\n        uint256 _usdValue\n    )\n        external\n        view\n        returns (uint256);\n\n    function getTokensPriceInUSD(\n        address _tokenAddress,\n        uint256 _tokenAmount\n    )\n        external\n        view\n        returns (uint256);\n\n    function latestResolver(\n        address _tokenAddress\n    )\n        external\n        view\n        returns (uint256);\n\n    function latestResolverTwap(\n        address _tokenAddress\n    )\n        external\n        view\n        returns (uint256);\n\n    function getTokensFromUSD(\n        address _tokenAddress,\n        uint256 _usdValue\n    )\n        external\n        view\n        returns (uint256);\n\n    function getTokensFromETH(\n        address _tokenAddress,\n        uint256 _ethValue\n    )\n        external\n        view\n        returns (uint256);\n\n    function getTokensInUSD(\n        address _tokenAddress,\n        uint256 _amount\n    )\n        external\n        view\n        returns (uint256);\n\n    function getTokensInETH(\n        address _tokenAddress,\n        uint256 _tokenAmount\n    )\n        external\n        view\n        returns (uint256);\n\n    function chainLinkIsDead(\n        address _tokenAddress\n    )\n        external\n        view\n        returns (bool);\n\n    function decimalsUSD()\n        external\n        pure\n        returns (uint8);\n\n    function addOracle(\n        address _tokenAddress,\n        address _priceFeedAddress,\n        address[] calldata _underlyingFeedTokens\n    )\n        external;\n\n    function recalibrate(\n        address _tokenAddress\n    )\n        external;\n\n    function WETH_ADDRESS()\n        external\n        view\n        returns (address);\n\n    function priceFeed(\n        address _tokenAddress\n    )\n        external\n        view\n        returns (address);\n}\n"
      },
      "contracts/InterfaceHub/IFeeManager.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\ninterface IFeeManager {\n\n    function underlyingToken(\n        address _poolToken\n    )\n        external\n        view\n        returns (address);\n\n    function isAaveToken(\n        address _poolToken\n    )\n        external\n        view\n        returns (bool);\n\n    function increaseTotalBadDebtLiquidation(\n        uint256 _amount\n    )\n        external;\n\n    function FEE_MANAGER_NFT()\n        external\n        view\n        returns (uint256);\n\n    function addPoolTokenAddress(\n        address _poolToken\n    )\n        external;\n\n    function getPoolTokenAdressesByIndex(\n        uint256 _index\n    )\n        external\n        view\n        returns (address);\n\n    function getPoolTokenAddressesLength()\n        external\n        view\n        returns (uint256);\n}"
      },
      "contracts/InterfaceHub/IWiseLending.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\nstruct GlobalPoolEntry {\n    uint256 totalPool;\n    uint256 utilization;\n    uint256 totalBareToken;\n    uint256 poolFee;\n}\n\nstruct BorrowPoolEntry {\n    bool allowBorrow;\n    uint256 pseudoTotalBorrowAmount;\n    uint256 totalBorrowShares;\n    uint256 borrowRate;\n}\n\nstruct LendingPoolEntry {\n    uint256 pseudoTotalPool;\n    uint256 totalDepositShares;\n    uint256 collateralFactor;\n}\n\nstruct PoolEntry {\n    uint256 totalPool;\n    uint256 utilization;\n    uint256 totalBareToken;\n    uint256 poolFee;\n}\n\nstruct BorrowRatesEntry {\n    uint256 pole;\n    uint256 deltaPole;\n    uint256 minPole;\n    uint256 maxPole;\n    uint256 multiplicativeFactor;\n}\n\ninterface IWiseLending {\n\n    function borrowRatesData(\n        address _pooToken\n    )\n        external\n        view\n        returns (BorrowRatesEntry memory);\n\n    function newBorrowRate(\n        address _poolToken\n    )\n        external;\n\n    function calculateBorrowShares(\n        address _poolToken,\n        uint256 _amount,\n        bool _maxSharePrice\n    )\n        external\n        view\n        returns (uint256);\n\n    function borrowPoolData(\n        address _poolToken\n    )\n        external\n        view\n        returns (BorrowPoolEntry memory);\n\n    function lendingPoolData(\n        address _poolToken\n    )\n        external\n        view\n        returns (LendingPoolEntry memory);\n\n    function getPositionBorrowShares(\n        uint256 _nftId,\n        address _poolToken\n    )\n        external\n        view\n        returns (uint256);\n\n    function getTimeStamp(\n        address _poolToken\n    )\n        external\n        view\n        returns (uint256);\n\n    function getPureCollateralAmount(\n        uint256 _nftId,\n        address _poolToken\n    )\n        external\n        view\n        returns (uint256);\n\n    function isUncollateralized(\n        uint256 _nftId,\n        address _poolToken\n    )\n        external\n        view\n        returns (bool);\n\n    function verifiedIsolationPool(\n        address _poolAddress\n    )\n        external\n        view\n        returns (bool);\n\n    function positionLocked(\n        uint256 _nftId\n    )\n        external\n        view\n        returns (bool);\n\n    function getTotalBareToken(\n        address _poolToken\n    )\n        external\n        view\n        returns (uint256);\n\n    function maxDepositValueToken(\n        address _poolToken\n    )\n        external\n        view\n        returns (uint256);\n\n    function master()\n        external\n        view\n        returns (address);\n\n    function WETH_ADDRESS()\n        external\n        view\n        returns (address);\n\n    function WISE_ORACLE()\n        external\n        view\n        returns (address);\n\n    function POSITION_NFT()\n        external\n        view\n        returns (address);\n\n    function FEE_MANAGER()\n        external\n        view\n        returns (address);\n\n    function WISE_SECURITY()\n        external\n        view\n        returns (address);\n\n    function lastUpdated(\n        address _poolAddress\n    )\n        external\n        view\n        returns (uint256);\n\n    function isolationPoolRegistered(\n        uint256 _nftId,\n        address _isolationPool\n    )\n        external\n        view\n        returns (bool);\n\n    function calculateLendingShares(\n        address _poolToken,\n        uint256 _amount,\n        bool _maxSharePrice\n    )\n        external\n        view\n        returns (uint256);\n\n    function pureCollateralAmount(\n        uint256 _nftId,\n        address _poolToken\n    )\n        external\n        returns (uint256);\n\n    function getTotalPool(\n        address _poolToken\n    )\n        external\n        view\n        returns (uint256);\n\n    function depositExactAmount(\n        uint256 _nftId,\n        address _poolToken,\n        uint256 _amount\n    )\n        external\n        returns (uint256);\n\n    function withdrawOnBehalfExactAmount(\n        uint256 _nftId,\n        address _poolToken,\n        uint256 _amount\n    )\n        external\n        returns (uint256);\n\n    function syncManually(\n        address _poolToken\n    )\n        external;\n\n    function withdrawOnBehalfExactShares(\n        uint256 _nftId,\n        address _poolToken,\n        uint256 _shares\n    )\n        external\n        returns (uint256);\n\n    function borrowOnBehalfExactAmount(\n        uint256 _nftId,\n        address _poolToken,\n        uint256 _amount\n    )\n        external\n        returns (uint256);\n\n    function borrowExactAmount(\n        uint256 _nftId,\n        address _poolToken,\n        uint256 _amount\n    )\n        external\n        returns (uint256);\n\n    function paybackExactAmountETH(\n        uint256 _nftId\n    )\n        external\n        payable\n        returns (uint256);\n\n    function solelyDeposit(\n        uint256 _nftId,\n        address _poolToken,\n        uint256 _amount\n    )\n        external;\n\n    function paybackExactAmount(\n        uint256 _nftId,\n        address _poolToken,\n        uint256 _amount\n    )\n        external\n        returns (uint256);\n\n    function paybackExactShares(\n        uint256 _nftId,\n        address _poolToken,\n        uint256 _shares\n    )\n        external\n        returns (uint256);\n\n    function setPoolFee(\n        address _poolToken,\n        uint256 _newFee\n    )\n        external;\n\n    function getPositionLendingShares(\n        uint256 _nftId,\n        address _poolToken\n    )\n        external\n        view\n        returns (uint256);\n\n    function collateralizeDeposit(\n        uint256 _nftId,\n        address _poolToken\n    )\n        external;\n\n    function approve(\n        address _spender,\n        address _poolToken,\n        uint256 _amount\n    )\n        external;\n\n    function withdrawExactShares(\n        uint256 _nftId,\n        address _poolToken,\n        uint256 _shares\n    )\n        external\n        returns (uint256);\n\n    function withdrawExactAmount(\n        uint256 _nftId,\n        address _poolToken,\n        uint256 _amount\n    )\n        external\n        returns (uint256);\n\n    function poolTokenAddresses()\n        external\n        returns (address[] memory);\n\n    function corePaybackFeeManager(\n        address _poolToken,\n        uint256 _nftId,\n        uint256 _amount,\n        uint256 _shares\n    )\n        external;\n\n    function sendingProgress()\n        external\n        view\n        returns (bool);\n\n    function depositExactAmountETH(\n        uint256 _nftId\n    )\n        external\n        payable\n        returns (uint256);\n\n    function coreLiquidationIsolationPools(\n        uint256 _nftId,\n        uint256 _nftIdLiquidator,\n        address _caller,\n        address _tokenToPayback,\n        address _tokenToRecieve,\n        uint256 _paybackAmount,\n        uint256 _shareAmountToPay\n    )\n        external\n        returns (uint256 reveiveAmount);\n\n    function preparePool(\n        address _poolToken\n    )\n        external;\n\n    function getPositionBorrowTokenLength(\n        uint256 _nftId\n    )\n        external\n        view\n        returns (uint256);\n\n    function getPositionBorrowTokenByIndex(\n        uint256 _nftId,\n        uint256 _index\n    )\n        external\n        view\n        returns (address);\n\n    function getPositionLendingTokenByIndex(\n        uint256 _nftId,\n        uint256 _index\n    )\n        external\n        view\n        returns (address);\n\n    function getPositionLendingTokenLength(\n        uint256 _nftId\n    )\n        external\n        view\n        returns (uint256);\n\n    function globalPoolData(\n        address _poolToken\n    )\n        external\n        view\n        returns (GlobalPoolEntry memory);\n\n\n    function getGlobalBorrowAmount(\n        address _token\n    )\n        external\n        view\n        returns (uint256);\n\n    function getPseudoTotalBorrowAmount(\n        address _token\n    )\n        external\n        view\n        returns (uint256);\n\n    function getInitialBorrowAmountUser(\n        address _user,\n        address _token\n    )\n        external\n        view\n        returns (uint256);\n\n    function getPseudoTotalPool(\n        address _token\n    )\n        external\n        view\n        returns (uint256);\n\n    function getInitialDepositAmountUser(\n        address _user,\n        address _token\n    )\n        external\n        view\n        returns (uint256);\n\n    function getGlobalDepositAmount(\n        address _token\n    )\n        external\n        view\n        returns (uint256);\n\n    function paybackAmount(\n        address _token,\n        uint256 _shares\n    )\n        external\n        view\n        returns (uint256);\n\n    function getPositionLendingShares(\n        address _user,\n        address _token\n    )\n        external\n        view\n        returns (uint256);\n\n    function cashoutAmount(\n        address _poolToken,\n        uint256 _shares\n    )\n        external\n        view\n        returns (uint256);\n\n    function getTotalDepositShares(\n        address _token\n    )\n        external\n        view\n        returns (uint256);\n\n    function getTotalBorrowShares(\n        address _token\n    )\n        external\n        view\n        returns (uint256);\n\n    function checkPositionLocked(\n        uint256 _nftId,\n        address _caller\n    )\n        external\n        view;\n\n    function checkDeposit(\n        uint256 _nftId,\n        address _caller,\n        address _poolToken,\n        uint256 _amount\n    )\n        external\n        view;\n\n    function setRegistrationIsolationPool(\n        uint256 _nftId,\n        bool _state\n    )\n        external;\n}\n"
      },
      "contracts/InterfaceHub/IWiseLiquidation.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\ninterface IWiseLiquidation {\n\n    function coreLiquidationIsolationPools(\n        uint256 _nftId,\n        uint256 _nftIdLiquidator,\n        address _caller,\n        address _tokenToPayback,\n        address _tokenToRecieve,\n        uint256 _paybackAmount,\n        uint256 _shareAmountToPay\n    )\n        external\n        returns (uint256 reveiveAmount);\n\n    function liquidatePartiallyFromTokens(\n        uint256 _nftId,\n        uint256 _nftIdLiquidator,\n        address _tokenToPayback,\n        address _tokenToRecieve,\n        uint256 _shareAmountToPay\n    )\n        external;\n}\n"
      },
      "contracts/InterfaceHub/IAaveHub.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\ninterface IAaveHub {\n\n    function AAVE_ADDRESS()\n        external\n        view\n        returns (address);\n\n    function WETH_ADDRESS()\n        external\n        view\n        returns (address);\n\n    function aaveTokenAddress(\n        address _underlyingToken\n    )\n        external\n        view\n        returns (address);\n\n    function setAaveTokenAddress(\n        address _underlyingToken,\n        address _aaveToken\n    )\n        external;\n\n    function borrowExactAmount(\n        uint256 _nftId,\n        address _underlyingAsset,\n        uint256 _borrowAmount\n    )\n        external\n        returns (uint256);\n\n    function paybackExactShares(\n        uint256 _nftId,\n        address _underlyingAsset,\n        uint256 _shares\n    )\n        external\n        returns (uint256);\n\n    function paybackExactAmountETH(\n        uint256 _nftId\n    )\n        external\n        payable\n        returns (uint256);\n\n    function paybackExactAmount(\n        uint256 _nftId,\n        address _underlyingAsset,\n        uint256 _shares\n    )\n        external\n        returns (uint256);\n\n    function depositExactAmount(\n        uint256 _nftId,\n        address _underlyingAsset,\n        uint256 _amount\n    )\n        external\n        returns (uint256);\n\n    function depositExactAmountETH(\n        uint256 _nftId\n    )\n        external\n        payable\n        returns (uint256);\n\n    function depositExactAmountETHMint()\n        external\n        payable\n        returns (uint256);\n\n    function withdrawExactShares(\n        uint256 _nftId,\n        address _underlyingAsset,\n        uint256 _shares\n    )\n        external\n        returns (uint256);\n\n    function withdrawExactAmount(\n        uint256 _nftId,\n        address _token,\n        uint256 _amount\n    )\n        external\n        returns (uint256);\n\n    function sendingProgressAaveHub()\n        external\n        view\n        returns (bool);\n}\n"
      },
      "contracts/FeeManager/FeeManager.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\n/**\n * @author Christoph Krpoun\n * @author René Hochmuth\n * @author Vitally Marinchenko\n */\n\nimport \"./FeeManagerHelper.sol\";\n\n/**\n * @dev Purpose of this contract is to organize fee distribution from wiseLending.\n * The feeManager aquires fee token in form of shares from each pool and can call them\n * with \"claimWiseFees()\" for each pool.\n *\n * Furthermore, this contracts has two different incentive\n * structures which can be used to bootstrap the WISE ecosystem (beneficial and incnetiveOwner roles).\n *\n * Additionally, this contract keeps track of the bad debt of each postion and has a simple mechanism\n * to pay them back via incentives. The incentive amount is funded by the gathered fees.\n */\n\ncontract FeeManager is FeeManagerHelper {\n\n    constructor(\n        address _master,\n        address _aaveAddress,\n        address _wiseLendingAddress,\n        address _oracleHubAddress,\n        address _wiseSecurityAddress,\n        address _positionNFTAddress\n    )\n        DeclarationsFeeManager(\n            _master,\n            _aaveAddress,\n            _wiseLendingAddress,\n            _oracleHubAddress,\n            _wiseSecurityAddress,\n            _positionNFTAddress\n        )\n    {}\n\n    /**\n     * @dev Allows to adjust the paid out incentive\n     * percentage for user to reduce bad debt.\n     */\n    function setRepayBadDebtIncentive(\n        uint256 _percent\n    )\n        external\n        onlyMaster\n    {\n        _checkValue(\n            _percent\n        );\n\n        paybackIncentive = _percent;\n    }\n\n    /**\n     * @dev Maps underlying token with corresponding aToken.\n     * Sets bool to identify pool token as aToken.\n     */\n    function setAaveFlag(\n        address _poolToken,\n        address _underlyingToken\n    )\n        external\n        onlyMaster\n    {\n        _setAaveFlag(\n            _poolToken,\n            _underlyingToken\n        );\n    }\n\n    /**\n     * @dev Bulk function for setting aave flag for multiple pools.\n     */\n    function setAaveFlagBulk(\n        address[] calldata _poolTokens,\n        address[] calldata _underlyingTokens\n    )\n        external\n        onlyMaster\n    {\n        uint256 i;\n        uint256 l = _poolTokens.length;\n\n        while (i < l) {\n            _setAaveFlag(\n                _poolTokens[i],\n                _underlyingTokens[i]\n            );\n\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /**\n     * @dev Function to adjust pool fee. Fee can not be greater than 100%\n     * or lower than 1%. Can be adjusted for each pool individually.\n     */\n    function setPoolFee(\n        address _poolToken,\n        uint256 _newFee\n    )\n        external\n        onlyMaster\n    {\n        _checkValue(\n            _newFee\n        );\n\n        WISE_LENDING.setPoolFee(\n            _poolToken,\n            _newFee\n        );\n\n        emit PoolFeeChanged(\n            _poolToken,\n            _newFee,\n            block.timestamp\n        );\n    }\n\n    /**\n    * @dev Function to adjust pool fees in bulk. Fee for each pool can not be\n    * greater than 100% or lower than 1%. Can be adjusted for each pool individually.\n    */\n    function setPoolFeeBulk(\n        address[] calldata _poolTokens,\n        uint256[] calldata _newFees\n    )\n        external\n        onlyMaster\n    {\n        uint256 i;\n        uint256 l = _poolTokens.length;\n\n        while (i < l) {\n\n            _checkValue(\n                _newFees[i]\n            );\n\n            WISE_LENDING.setPoolFee(\n                _poolTokens[i],\n                _newFees[i]\n            );\n\n            emit PoolFeeChanged(\n                _poolTokens[i],\n                _newFees[i],\n                block.timestamp\n            );\n\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /**\n     * @dev Function to propose new incentive master. This role can increase\n     * the incentive amount for both incentive mappings. These are two roles\n     * for incentivising external persons e.g. developers.\n     */\n    function proposeIncentiveMaster(\n        address _proposedIncentiveMaster\n    )\n        external\n        onlyIncentiveMaster\n    {\n        if (_proposedIncentiveMaster == ZERO_ADDRESS) {\n            revert ZeroAddress();\n        }\n\n        proposedIncentiveMaster = _proposedIncentiveMaster;\n\n        emit IncentiveMasterProposed(\n            _proposedIncentiveMaster,\n            block.timestamp\n        );\n    }\n\n    /**\n     * @dev Claim proposed incentive master by proposed entity.\n     */\n    function claimOwnershipIncentiveMaster()\n        external\n    {\n        if (msg.sender != proposedIncentiveMaster) {\n            revert NotAllowed();\n        }\n\n        incentiveMaster = msg.sender;\n        proposedIncentiveMaster = ZERO_ADDRESS;\n\n        emit ClaimedOwnershipIncentiveMaster(\n            msg.sender,\n            block.timestamp\n        );\n    }\n\n    /**\n     * @dev Increase function for increasing incentive amount for entity A.\n     * Only callable by incentive master.\n     */\n    function increaseIncentiveA(\n        uint256 _value\n    )\n        external\n        onlyIncentiveMaster\n    {\n        incentiveUSD[incentiveOwnerA] += _value;\n\n        emit IncentiveIncreasedA(\n            _value,\n            block.timestamp\n        );\n    }\n\n    /**\n     * @dev Increase function for increasing incentive amount for entity B.\n     * Only callable by incentive master.\n     */\n    function increaseIncentiveB(\n        uint256 _value\n    )\n        external\n        onlyIncentiveMaster\n    {\n        incentiveUSD[incentiveOwnerB] += _value;\n\n        emit IncentiveIncreasedB(\n            _value,\n            block.timestamp\n        );\n    }\n\n    /**\n     * @dev Function to claim all gathered incetives.\n     */\n    function claimIncentivesBulk()\n        external\n    {\n        address tokenAddress;\n\n        uint256 i;\n        uint256 l = getPoolTokenAddressesLength();\n\n        while (i < l) {\n\n            tokenAddress = poolTokenAddresses[i];\n\n            if (isAaveToken[tokenAddress] == true) {\n                tokenAddress = underlyingToken[\n                    tokenAddress\n                ];\n            }\n\n            claimIncentives(\n                tokenAddress\n            );\n\n            unchecked {\n                ++i;\n            }\n        }\n\n        emit ClaimedIncentivesBulk(\n            block.timestamp\n        );\n    }\n\n    /**\n     * @dev Claims gathered incentives for a specific token.\n     */\n    function claimIncentives(\n        address _feeToken\n    )\n        public\n    {\n        uint256 amount = gatheredIncentiveToken[msg.sender][_feeToken];\n\n        if (amount == 0) {\n            revert NoIncentive();\n        }\n\n        delete gatheredIncentiveToken[msg.sender][_feeToken];\n\n        emit ClaimedIncentives(\n            msg.sender,\n            _feeToken,\n            amount,\n            block.timestamp\n        );\n\n        _safeTransfer(\n            _feeToken,\n            msg.sender,\n            amount\n        );\n    }\n\n    /**\n     * @dev Function changing incentiveOwnerA! Only callable by\n     * incentiveOwnerA.\n     */\n    function changeIncentiveUSDA(\n        address _newOwner\n    )\n        external\n    {\n        if (msg.sender != incentiveOwnerA) {\n            revert NotAllowed();\n        }\n\n        if (_newOwner == msg.sender) {\n            revert NotAllowed();\n        }\n\n        if (_newOwner == incentiveOwnerB) {\n            revert NotAllowed();\n        }\n\n        incentiveUSD[_newOwner] = incentiveUSD[\n            msg.sender\n        ];\n\n        delete incentiveUSD[\n            msg.sender\n        ];\n\n        incentiveOwnerA = _newOwner;\n\n        emit IncentiveOwnerAChanged(\n            _newOwner,\n            block.timestamp\n        );\n    }\n\n    /**\n     * @dev Function changing incentiveOwnerB! Only callable by\n     * incentiveOwnerB.\n     */\n    function changeIncentiveUSDB(\n        address _newOwner\n    )\n        external\n    {\n        if (msg.sender != incentiveOwnerB) {\n            revert NotAllowed();\n        }\n\n        if (_newOwner == incentiveOwnerA) {\n            revert NotAllowed();\n        }\n\n        if (_newOwner == msg.sender) {\n            revert NotAllowed();\n        }\n\n        incentiveUSD[_newOwner] = incentiveUSD[\n            msg.sender\n        ];\n\n        delete incentiveUSD[\n            msg.sender\n        ];\n\n        incentiveOwnerB = _newOwner;\n\n        emit IncentiveOwnerBChanged(\n            _newOwner,\n            block.timestamp\n        );\n    }\n\n    /**\n     * @dev Function adding new pool token to pool token list.\n     * Called during pool creation and only callable by wiseLending\n     * contract.\n     */\n    function addPoolTokenAddress(\n        address _poolToken\n    )\n        external\n        onlyWiseLending\n    {\n        poolTokenAddresses.push(\n            _poolToken\n        );\n\n        poolTokenAdded[_poolToken] = true;\n\n        emit PoolTokenAdded(\n            _poolToken,\n            block.timestamp\n        );\n    }\n\n    /**\n     * @dev Function to add pool token manualy. Only\n     * callable by feeManager master.\n     */\n    function addPoolTokenAddressManual(\n        address _poolToken\n    )\n        external\n        onlyMaster\n    {\n        if (poolTokenAdded[_poolToken] == true) {\n            revert PoolAlreadyAdded();\n        }\n\n        poolTokenAddresses.push(\n            _poolToken\n        );\n\n        poolTokenAdded[_poolToken] = true;\n\n        emit PoolTokenAdded(\n            _poolToken,\n            block.timestamp\n        );\n    }\n\n    /**\n     * @dev Function to remove pool token manualy from pool\n     * token list. Only callable by feeManager master.\n     */\n    function removePoolTokenManual(\n        address _poolToken\n    )\n        external\n        onlyMaster\n    {\n        uint256 i;\n        uint256 len = getPoolTokenAddressesLength();\n        uint256 lastEntry = len - 1;\n        bool found;\n\n        if (poolTokenAdded[_poolToken] == false) {\n            revert PoolNotPresent();\n        }\n\n        while (i < len) {\n\n            if (_poolToken != poolTokenAddresses[i]) {\n\n                unchecked {\n                    ++i;\n                }\n\n                continue;\n            }\n\n            found = true;\n\n            if (i != lastEntry) {\n                poolTokenAddresses[i] = poolTokenAddresses[lastEntry];\n            }\n\n            break;\n        }\n\n        if (found == true) {\n\n            poolTokenAddresses.pop();\n            poolTokenAdded[_poolToken] = false;\n\n            emit PoolTokenRemoved(\n                _poolToken,\n                block.timestamp\n            );\n\n            return;\n        }\n\n        revert PoolNotPresent();\n    }\n\n    /**\n     * @dev Increase function for total bad debt of\n     * wiseLending. Only callable by wiseSecurity contract\n     * during liquidation.\n     */\n    function increaseTotalBadDebtLiquidation(\n        uint256 _amount\n    )\n        external\n        onlyWiseSecurity\n    {\n        _increaseTotalBadDebt(\n            _amount\n        );\n\n        emit BadDebtIncreasedLiquidation(\n            _amount,\n            block.timestamp\n        );\n    }\n\n    function setTotalBadDebt(\n        uint256 _amount\n    )\n        external\n        onlyMaster\n    {\n        totalBadDebtETH = _amount;\n    }\n\n    /**\n     * @dev Set function to declare an address as beneficial for\n     * a fee token. Address can claim gathered fee token as long as\n     * it is declared as beneficial. Only setable by master.\n     */\n    function setBeneficial(\n        address _user,\n        address[] calldata _feeTokens\n    )\n        external\n        onlyMaster\n    {\n        uint256 i;\n        uint256 l = _feeTokens.length;\n\n        while (i < l) {\n            _setAllowedTokens(\n                _user,\n                _feeTokens[i],\n                true\n            );\n\n            unchecked {\n                ++i;\n            }\n        }\n\n        emit SetBeneficial(\n            _user,\n            _feeTokens,\n            block.timestamp\n        );\n    }\n\n    /**\n     * @dev Set function to remove an address as beneficial for\n     * a fee token. Only setable by master.\n     */\n    function revokeBeneficial(\n        address _user,\n        address[] memory _feeTokens\n    )\n        external\n        onlyMaster\n    {\n        uint256 i;\n        uint256 l = _feeTokens.length;\n\n        while (i < l) {\n            _setAllowedTokens(\n                _user,\n                _feeTokens[i],\n                false\n            );\n\n            unchecked {\n                ++i;\n            }\n        }\n\n        emit RevokeBeneficial(\n            _user,\n            _feeTokens,\n            block.timestamp\n        );\n    }\n\n    /**\n     * @dev Claim all fees from wiseLending and send them to feeManager.\n     */\n    function claimWiseFeesBulk()\n        external\n    {\n        uint256 i;\n        uint256 l = getPoolTokenAddressesLength();\n\n        while (i < l) {\n            claimWiseFees(\n                poolTokenAddresses[i]\n            );\n\n            unchecked {\n                ++i;\n            }\n        }\n\n        emit ClaimedFeesWiseBulk(\n            block.timestamp\n        );\n    }\n\n    /**\n     * @dev Claim fees from wiseLending and send them to feeManager for\n     * a specific pool.\n     */\n    function claimWiseFees(\n        address _poolToken\n    )\n        public\n    {\n        address underlyingTokenAddress = _poolToken;\n\n        uint256 shares = WISE_LENDING.getPositionLendingShares(\n            FEE_MANAGER_NFT,\n            _poolToken\n        );\n\n        if (shares == 0) {\n            return;\n        }\n\n        uint256 tokenAmount = WISE_LENDING.withdrawExactShares(\n            FEE_MANAGER_NFT,\n            _poolToken,\n            shares\n        );\n\n        if (isAaveToken[_poolToken] == true) {\n\n            underlyingTokenAddress = underlyingToken[\n                _poolToken\n            ];\n\n            tokenAmount = AAVE.withdraw(\n                underlyingTokenAddress,\n                tokenAmount,\n                address(this)\n            );\n        }\n\n        if (totalBadDebtETH == 0) {\n\n            tokenAmount = _distributeIncentives(\n                tokenAmount,\n                _poolToken,\n                underlyingTokenAddress\n            );\n        }\n\n        _increaseFeeTokens(\n            underlyingTokenAddress,\n            tokenAmount\n        );\n\n        emit ClaimedFeesWise(\n            underlyingTokenAddress,\n            tokenAmount,\n            block.timestamp\n        );\n    }\n\n    /**\n     * @dev Function for beneficial to claim gathered fees. Can only\n     * claim fees for which the beneficial is allowed. Can only claim\n     * token which are inside the feeManager.\n     */\n    function claimFeesBeneficial(\n        address _feeToken,\n        uint256 _amount\n    )\n        external\n    {\n        address caller = msg.sender;\n\n        if (totalBadDebtETH > 0) {\n            revert ExistingBadDebt();\n        }\n\n        if (allowedTokens[caller][_feeToken] == false) {\n            revert NotAllowed();\n        }\n\n        _decreaseFeeTokens(\n            _feeToken,\n            _amount\n        );\n\n        _safeTransfer(\n            _feeToken,\n            caller,\n            _amount\n        );\n\n        emit ClaimedFeesBeneficial(\n            caller,\n            _feeToken,\n            _amount,\n            block.timestamp\n        );\n    }\n\n    /**\n     * @dev Function for paying back bad debt of a position. Caller\n     * chooses postion, token and receive token. Only gathered fee token\n     * can be distributed as receive token. Caller gets 5% more\n     * in ETH value as incentive.\n     */\n    function paybackBadDebtForToken(\n        uint256 _nftId,\n        address _paybackToken,\n        address _receivingToken,\n        uint256 _shares\n    )\n        external\n        returns (\n            uint256 paybackAmount,\n            uint256 receivingAmount\n        )\n    {\n        updatePositionCurrentBadDebt(\n            _nftId\n        );\n\n        if (badDebtPosition[_nftId] == 0) {\n            return (\n                0,\n                0\n            );\n        }\n\n        if (WISE_LENDING.getTotalDepositShares(_receivingToken) == 0) {\n            revert PoolNotActive();\n        }\n\n        if (WISE_LENDING.getTotalDepositShares(_paybackToken) == 0) {\n            revert PoolNotActive();\n        }\n\n        paybackAmount = WISE_LENDING.paybackAmount(\n            _paybackToken,\n            _shares\n        );\n\n        WISE_LENDING.corePaybackFeeManager(\n            _paybackToken,\n            _nftId,\n            paybackAmount,\n            _shares\n        );\n\n        receivingAmount = getReceivingToken(\n            _paybackToken,\n            _receivingToken,\n            paybackAmount\n        );\n\n        _decreaseFeeTokens(\n            _receivingToken,\n            receivingAmount\n        );\n\n        _updateUserBadDebt(\n            _nftId\n        );\n\n        _safeTransferFrom(\n            _paybackToken,\n            msg.sender,\n            address(WISE_LENDING),\n            paybackAmount\n        );\n\n        _safeTransfer(\n            _receivingToken,\n            msg.sender,\n            receivingAmount\n        );\n\n        emit PayedBackBadDebt(\n            _nftId,\n            msg.sender,\n            _paybackToken,\n            _receivingToken,\n            paybackAmount,\n            block.timestamp\n        );\n    }\n\n    /**\n     * @dev Function for paying back bad debt of a position. Caller\n     * chooses postion, token and receive token. Caller gets no\n     * receive token!\n     */\n    function paybackBadDebtNoReward(\n        uint256 _nftId,\n        address _paybackToken,\n        uint256 _shares\n    )\n        external\n        returns (uint256 paybackAmount)\n    {\n        updatePositionCurrentBadDebt(\n            _nftId\n        );\n\n        if (badDebtPosition[_nftId] == 0) {\n            return 0;\n        }\n\n        if (_shares == 0) {\n            revert isZero();\n        }\n\n        if (WISE_LENDING.getTotalDepositShares(_paybackToken) == 0) {\n            revert PoolNotActive();\n        }\n\n        paybackAmount = WISE_LENDING.paybackAmount(\n            _paybackToken,\n            _shares\n        );\n\n        WISE_LENDING.corePaybackFeeManager(\n            _paybackToken,\n            _nftId,\n            paybackAmount,\n            _shares\n        );\n\n        _updateUserBadDebt(\n            _nftId\n        );\n\n        emit PayedBackBadDebtFree(\n            _nftId,\n            msg.sender,\n            _paybackToken,\n            paybackAmount,\n            block.timestamp\n        );\n\n        _safeTransferFrom(\n            _paybackToken,\n            msg.sender,\n            address(WISE_LENDING),\n            paybackAmount\n        );\n    }\n\n    /**\n     * @dev Returning the number of pool token\n     * addresses saved inside the feeManager.\n     */\n    function getPoolTokenAddressesLength()\n        public\n        view\n        returns (uint256)\n    {\n        return poolTokenAddresses.length;\n    }\n\n    /**\n     * @dev Returns the pool token address\n     * at the _index postion of the array.\n     */\n    function getPoolTokenAdressesByIndex(\n        uint256 _index\n    )\n        external\n        view\n        returns (address)\n    {\n        return poolTokenAddresses[_index];\n    }\n\n    /**\n     * @dev Bulk function for updating pools - loops through\n     * all pools saved inside the poolTokenAddresses array.\n     */\n    function syncAllPools()\n        external\n    {\n        uint256 i;\n        uint256 l = poolTokenAddresses.length;\n\n        while (i < l) {\n            WISE_LENDING.syncManually(\n                poolTokenAddresses[i]\n            );\n\n            unchecked {\n                ++i;\n            }\n        }\n    }\n}\n"
      },
      "contracts/OwnableMaster.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\nerror NoValue();\nerror NotMaster();\nerror NotProposed();\n\ncontract OwnableMaster {\n\n    address public master;\n    address public proposedMaster;\n\n    address internal constant ZERO_ADDRESS = address(0x0);\n\n    modifier onlyProposed() {\n        _onlyProposed();\n        _;\n    }\n\n    function _onlyMaster()\n        private\n        view\n    {\n        if (msg.sender == master) {\n            return;\n        }\n\n        revert NotMaster();\n    }\n\n    modifier onlyMaster() {\n        _onlyMaster();\n        _;\n    }\n\n    function _onlyProposed()\n        private\n        view\n    {\n        if (msg.sender == proposedMaster) {\n            return;\n        }\n\n        revert NotProposed();\n    }\n\n    event MasterProposed(\n        address indexed proposer,\n        address indexed proposedMaster\n    );\n\n    event RenouncedOwnership(\n        address indexed previousMaster\n    );\n\n    constructor(\n        address _master\n    ) {\n        if (_master == ZERO_ADDRESS) {\n            revert NoValue();\n        }\n        master = _master;\n    }\n\n    /**\n     * @dev Allows to propose next master.\n     * Must be claimed by proposer.\n     */\n    function proposeOwner(\n        address _proposedOwner\n    )\n        external\n        onlyMaster\n    {\n        if (_proposedOwner == ZERO_ADDRESS) {\n            revert NoValue();\n        }\n\n        proposedMaster = _proposedOwner;\n\n        emit MasterProposed(\n            msg.sender,\n            _proposedOwner\n        );\n    }\n\n    /**\n     * @dev Allows to claim master role.\n     * Must be called by proposer.\n     */\n    function claimOwnership()\n        external\n        onlyProposed\n    {\n        master = msg.sender;\n    }\n\n    /**\n     * @dev Removes master role.\n     * No ability to be in control.\n     */\n    function renounceOwnership()\n        external\n        onlyMaster\n    {\n        master = ZERO_ADDRESS;\n        proposedMaster = ZERO_ADDRESS;\n\n        emit RenouncedOwnership(\n            msg.sender\n        );\n    }\n}\n"
      },
      "contracts/FeeManager/FeeManagerHelper.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\nimport \"./DeclarationsFeeManager.sol\";\nimport \"../TransferHub/TransferHelper.sol\";\n\nabstract contract FeeManagerHelper is DeclarationsFeeManager, TransferHelper {\n\n    /**\n     * @dev Internal update function which adds latest aquired token from borrow rate\n     * for all borrow tokens of the position. Idnetical implementation like in wiseSecurity\n     * or wiseLending.\n     */\n    function _prepareBorrows(\n        uint256 _nftId\n    )\n        internal\n    {\n        uint256 i;\n        uint256 l = WISE_LENDING.getPositionBorrowTokenLength(\n            _nftId\n        );\n\n        while (i < l) {\n\n            address currentAddress = WISE_LENDING.getPositionBorrowTokenByIndex(\n                _nftId,\n                i\n            );\n\n            WISE_LENDING.syncManually(\n                currentAddress\n            );\n\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /**\n     * @dev Internal update function which adds latest aquired token from borrow rate\n     * for all collateral tokens of the position. Idnetical implementation like in wiseSecurity\n     * or wiseLending.\n     */\n    function _prepareCollaterals(\n        uint256 _nftId\n    )\n        internal\n    {\n        uint256 i;\n        uint256 l = WISE_LENDING.getPositionLendingTokenLength(\n            _nftId\n        );\n\n        while (i < l) {\n\n            address currentAddress = WISE_LENDING.getPositionLendingTokenByIndex(\n                _nftId,\n                i\n            );\n\n            WISE_LENDING.syncManually(\n                currentAddress\n            );\n\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /**\n     * @dev Internal set function for adjusting bad debt amount of a position.\n     */\n    function _setBadDebtPosition(\n        uint256 _nftId,\n        uint256 _amount\n    )\n        internal\n    {\n        badDebtPosition[_nftId] = _amount;\n    }\n\n    /**\n     * @dev Internal increase function for global bad debt amount.\n     */\n    function _increaseTotalBadDebt(\n        uint256 _amount\n    )\n        internal\n    {\n        totalBadDebtETH += _amount;\n\n        emit TotalBadDebtIncreased(\n            _amount,\n            block.timestamp\n        );\n    }\n\n    /**\n     * @dev Internal decrease function for global bad debt amount.\n     */\n    function _decreaseTotalBadDebt(\n        uint256 _amount\n    )\n        internal\n    {\n        totalBadDebtETH -= _amount;\n\n        emit TotalBadDebtDecreased(\n            _amount,\n            block.timestamp\n        );\n    }\n\n    /**\n     * @dev Internal erease function to delete bad debt amount of a postion.\n     */\n    function _eraseBadDebtUser(\n        uint256 _nftId\n    )\n        internal\n    {\n        delete badDebtPosition[_nftId];\n    }\n\n    /**\n     * @dev Internal function updating bad debt amount of a position and global one (in ETH).\n     * Compares totalBorrow and totalCollateral of the postion in ETH and adjustes bad debt\n     * variables. Pseudo pool amounts needed to be updated before this function is called.\n     */\n    function _updateUserBadDebt(\n        uint256 _nftId\n    )\n        internal\n    {\n        uint256 currentBorrowETH = WISE_SECURITY.overallETHBorrowHeartbeat(\n            _nftId\n        );\n\n        uint256 currentCollateralBareETH = WISE_SECURITY.overallETHCollateralsBare(\n            _nftId\n        );\n\n        uint256 currentBadDebt = badDebtPosition[\n            _nftId\n        ];\n\n        if (currentBorrowETH < currentCollateralBareETH) {\n\n            _eraseBadDebtUser(\n                _nftId\n            );\n\n            _decreaseTotalBadDebt(\n                currentBadDebt\n            );\n\n            emit UpdateBadDebtPosition(\n                _nftId,\n                0,\n                block.timestamp\n            );\n\n            return;\n        }\n\n        unchecked {\n            uint256 newBadDebt = currentBorrowETH\n                - currentCollateralBareETH;\n\n            _setBadDebtPosition(\n                _nftId,\n                newBadDebt\n            );\n\n            newBadDebt > currentBadDebt\n                ? _increaseTotalBadDebt(newBadDebt - currentBadDebt)\n                : _decreaseTotalBadDebt(currentBadDebt - newBadDebt);\n\n            emit UpdateBadDebtPosition(\n                _nftId,\n                newBadDebt,\n                block.timestamp\n            );\n        }\n    }\n\n    /**\n     * @dev Internal increase function for tracking gathered fee token. No need for\n     * balanceOf() checks.\n     */\n    function _increaseFeeTokens(\n        address _feeToken,\n        uint256 _amount\n    )\n        internal\n    {\n        feeTokens[_feeToken] += _amount;\n    }\n\n    /**\n     * @dev Internal decrease function for tracking gathered fee token. No need for\n     * balanceOf() checks.\n     */\n    function _decreaseFeeTokens(\n        address _feeToken,\n        uint256 _amount\n    )\n        internal\n    {\n        feeTokens[_feeToken] -= _amount;\n    }\n\n    /**\n     * @dev Internal function to set benefical mapping for a certain token.\n     */\n    function _setAllowedTokens(\n        address _user,\n        address _feeToken,\n        bool _state\n    )\n        internal\n    {\n        allowedTokens[_user][_feeToken] = _state;\n    }\n\n    function _setAaveFlag(\n        address _poolToken,\n        address _underlyingToken\n    )\n        internal\n    {\n        isAaveToken[_poolToken] = true;\n        underlyingToken[_poolToken] = _underlyingToken;\n    }\n\n    /**\n     * @dev Internal function calculating receive amount for the caller.\n     * paybackIncentive is set to 5E16 => 5% incentive for paying back bad debt.\n     */\n    function getReceivingToken(\n        address _paybackToken,\n        address _receivingToken,\n        uint256 _paybackAmount\n    )\n        public\n        view\n        returns (uint256 receivingAmount)\n    {\n        uint256 increasedAmount = _paybackAmount\n            * (PRECISION_FACTOR_E18 + paybackIncentive)\n            / PRECISION_FACTOR_E18;\n\n        return ORACLE_HUB.getTokensFromETH(\n            _receivingToken,\n            ORACLE_HUB.getTokensInETH(\n                _paybackToken,\n                increasedAmount\n            )\n        );\n    }\n\n    /**\n     * @dev Updates bad debt of a postion. Combines preparation of all\n     * collaterals and borrows for passed _nftId with _updateUserBadDebt().\n     */\n    function updatePositionCurrentBadDebt(\n        uint256 _nftId\n    )\n        public\n    {\n        _prepareCollaterals(\n            _nftId\n        );\n\n        _prepareBorrows(\n            _nftId\n        );\n\n        _updateUserBadDebt(\n            _nftId\n        );\n    }\n\n    /**\n     * @dev Internal function for distributing incentives to incentiveOwnerA\n     * and incentiveOwnerB.\n     */\n    function _distributeIncentives(\n        uint256 _amount,\n        address _poolToken,\n        address _underlyingToken\n    )\n        internal\n        returns (uint256)\n    {\n        uint256 reduceAmount;\n\n        if (incentiveUSD[incentiveOwnerA] > 0) {\n\n            reduceAmount += _gatherIncentives(\n                _poolToken,\n                _underlyingToken,\n                incentiveOwnerA,\n                _amount\n            );\n        }\n\n        if (incentiveUSD[incentiveOwnerB] > 0) {\n\n            reduceAmount += _gatherIncentives(\n                _poolToken,\n                _underlyingToken,\n                incentiveOwnerB,\n                _amount\n            );\n        }\n\n        return _amount - reduceAmount;\n    }\n\n    /**\n     * @dev Internal function computing the incentive amount for an incentiveOwner\n     * depending of the amount per fee token. Reduces the open incentive amount for\n     * the owner.\n     */\n    function _gatherIncentives(\n        address _poolToken,\n        address _underlyingToken,\n        address _incentiveOwner,\n        uint256 _amount\n    )\n        internal\n        returns (uint256)\n    {\n        uint256 incentiveAmount = _amount\n            * INCENTIVE_PORTION\n            / WISE_LENDING.globalPoolData(_poolToken).poolFee;\n\n        uint256 usdEquivalent = ORACLE_HUB.getTokensPriceInUSD(\n            _poolToken,\n            incentiveAmount\n        );\n\n        uint256 reduceUSD = usdEquivalent < incentiveUSD[_incentiveOwner]\n            ? usdEquivalent\n            : incentiveUSD[_incentiveOwner];\n\n        if (reduceUSD == usdEquivalent) {\n\n            incentiveUSD[_incentiveOwner] -= usdEquivalent;\n\n            gatheredIncentiveToken\n                [_incentiveOwner]\n                [_underlyingToken] += incentiveAmount;\n\n            return incentiveAmount;\n        }\n\n        incentiveAmount = ORACLE_HUB.getTokensPriceFromUSD(\n            _poolToken,\n            reduceUSD\n        );\n\n        delete incentiveUSD[\n            _incentiveOwner\n        ];\n\n        gatheredIncentiveToken\n            [_incentiveOwner]\n            [_underlyingToken] += incentiveAmount;\n\n        return incentiveAmount;\n    }\n\n    /**\n     * @dev Internal function checking if the\n     * passed value is smaller 100% and bigger 1%.\n     */\n    function _checkValue(\n        uint256 _value\n    )\n        internal\n        pure\n    {\n        if (_value < PRECISION_FACTOR_E16) {\n            revert TooLowValue();\n        }\n\n        if (_value > PRECISION_FACTOR_E18) {\n            revert TooHighValue();\n        }\n    }\n}\n"
      },
      "contracts/FeeManager/DeclarationsFeeManager.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\nimport \"../InterfaceHub/IAave.sol\";\nimport \"../InterfaceHub/IERC20.sol\";\nimport \"../InterfaceHub/IWiseLending.sol\";\nimport \"../InterfaceHub/IFeeManager.sol\";\nimport \"../InterfaceHub/IWiseSecurity.sol\";\nimport \"../InterfaceHub/IPositionNFTs.sol\";\nimport \"../InterfaceHub/IWiseOracleHub.sol\";\n\nimport \"../OwnableMaster.sol\";\nimport \"./FeeManagerEvents.sol\";\n\nerror NotWiseLiquidation();\nerror AlreadySet();\nerror ExistingBadDebt();\nerror NotWiseLending();\nerror NotIncentiveMaster();\nerror PoolAlreadyAdded();\nerror TooHighValue();\nerror TooLowValue();\nerror NotAllowed();\nerror PoolNotPresent();\nerror ZeroAddress();\nerror NoIncentive();\nerror Reentered();\nerror PoolNotActive();\nerror isZero();\n\ncontract DeclarationsFeeManager is FeeManagerEvents, OwnableMaster {\n\n    constructor(\n        address _master,\n        address _aaveAddress,\n        address _wiseLendingAddress,\n        address _oracleHubAddress,\n        address _wiseSecurityAddress,\n        address _positionNFTAddress\n    )\n        OwnableMaster(\n            _master\n        )\n    {\n        if (_aaveAddress == ZERO_ADDRESS) {\n            revert NoValue();\n        }\n\n        if (_wiseLendingAddress == ZERO_ADDRESS) {\n            revert NoValue();\n        }\n\n        if (_oracleHubAddress == ZERO_ADDRESS) {\n            revert NoValue();\n        }\n\n        if (_wiseSecurityAddress == ZERO_ADDRESS) {\n            revert NoValue();\n        }\n\n        if (_positionNFTAddress == ZERO_ADDRESS) {\n            revert NoValue();\n        }\n\n        WISE_LENDING = IWiseLending(\n            _wiseLendingAddress\n        );\n\n        AAVE = IAave(\n            _aaveAddress\n        );\n\n        ORACLE_HUB = IWiseOracleHub(\n            _oracleHubAddress\n        );\n\n        WISE_SECURITY = IWiseSecurity(\n            _wiseSecurityAddress\n        );\n\n        POSITION_NFTS = IPositionNFTs(\n            _positionNFTAddress\n        );\n\n        FEE_MANAGER_NFT = POSITION_NFTS.FEE_MANAGER_NFT();\n\n        incentiveMaster = _master;\n        paybackIncentive = 5 * PRECISION_FACTOR_E16;\n\n        incentiveOwnerA = 0xf69A0e276664997357BF987df83f32a1a3F80944;\n        incentiveOwnerB = 0x8f741ea9C9ba34B5B8Afc08891bDf53faf4B3FE7;\n\n        incentiveUSD[incentiveOwnerA] = 98000 * PRECISION_FACTOR_E18;\n        incentiveUSD[incentiveOwnerB] = 106500 * PRECISION_FACTOR_E18;\n    }\n\n    // ---- Interfaces ----\n\n    // Interface aave V3 contract\n    IAave public immutable AAVE;\n\n    // Interface wiseLending contract\n    IWiseLending public immutable WISE_LENDING;\n\n    // Interface position NFT contract\n    IPositionNFTs public immutable POSITION_NFTS;\n\n    // Interface wiseSecurity contract\n    IWiseSecurity public immutable WISE_SECURITY;\n\n    // Interface wise oracleHub contract\n    IWiseOracleHub public immutable ORACLE_HUB;\n\n    // ---- Variables ----\n\n    // Global total bad debt variable\n    uint256 public totalBadDebtETH;\n\n    // Incentive percentage for paying back bad debt\n    uint256 public paybackIncentive;\n\n    // Array of pool tokens in wiseLending\n    address[] public poolTokenAddresses;\n\n    // Address of incentive master\n    address public incentiveMaster;\n\n    // Proposed incentive master (for changing)\n    address public proposedIncentiveMaster;\n\n    // Address of incentive owner A\n    address public incentiveOwnerA;\n\n    // Address of incentive owner B\n    address public incentiveOwnerB;\n\n    // ---- Mappings ----\n\n    // Bad debt of a specific position\n    mapping(uint256 => uint256) public badDebtPosition;\n\n    // Amount of fee token inside feeManager\n    mapping(address => uint256) public feeTokens;\n\n    // Open incetive amount for incentiveOwner in ETH\n    mapping(address => uint256) public incentiveUSD;\n\n    // Flag that specific token is already added\n    mapping(address => bool) public poolTokenAdded;\n\n    // Flag for token being aToken\n    mapping(address => bool) public isAaveToken;\n\n    // Getting underlying token of aave aToken\n    mapping(address => address) public underlyingToken;\n\n    // Showing which token are allowed to claim for beneficial address\n    mapping(address => mapping(address => bool)) public allowedTokens;\n\n    // Gives claimable token amount for incentiveOwner per token\n    mapping(address => mapping(address => uint256)) public gatheredIncentiveToken;\n\n    // Position NFT id of the feeManager\n    uint256 public immutable FEE_MANAGER_NFT;\n\n    // Precision factors for computations\n    uint256 internal constant PRECISION_FACTOR_E15 = 1E15;\n    uint256 internal constant PRECISION_FACTOR_E16 = 1E16;\n    uint256 internal constant PRECISION_FACTOR_E18 = 1E18;\n\n    // Base portion from gathered fees for incentiveOwners (0.5%)\n    uint256 public constant INCENTIVE_PORTION = 5 * PRECISION_FACTOR_E15;\n\n    // ---- Modifier ----\n\n    modifier onlyWiseSecurity() {\n        _onlyWiseSecurity();\n        _;\n    }\n\n    modifier onlyWiseLending() {\n        _onlyWiseLending();\n        _;\n    }\n\n    modifier onlyIncentiveMaster() {\n        _onlyIncentiveMaster();\n        _;\n    }\n\n    function _onlyIncentiveMaster()\n        private\n        view\n    {\n        if (msg.sender == incentiveMaster) {\n            return;\n        }\n\n        revert NotIncentiveMaster();\n    }\n\n    function _onlyWiseSecurity()\n        private\n        view\n    {\n        if (msg.sender == address(WISE_SECURITY)) {\n            return;\n        }\n\n        revert NotWiseLiquidation();\n    }\n\n    function _onlyWiseLending()\n        private\n        view\n    {\n        if (msg.sender == address(WISE_LENDING)) {\n            return;\n        }\n\n        revert NotWiseLending();\n    }\n}\n"
      },
      "contracts/TransferHub/TransferHelper.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\nimport \"./CallOptionalReturn.sol\";\n\ncontract TransferHelper is CallOptionalReturn {\n\n    /**\n     * @dev\n     * Allows to execute safe transfer for a token\n     */\n    function _safeTransfer(\n        address _token,\n        address _to,\n        uint256 _value\n    )\n        internal\n    {\n        _callOptionalReturn(\n            _token,\n            abi.encodeWithSelector(\n                IERC20.transfer.selector,\n                _to,\n                _value\n            )\n        );\n    }\n\n    /**\n     * @dev\n     * Allows to execute safe transferFrom for a token\n     */\n    function _safeTransferFrom(\n        address _token,\n        address _from,\n        address _to,\n        uint256 _value\n    )\n        internal\n    {\n        _callOptionalReturn(\n            _token,\n            abi.encodeWithSelector(\n                IERC20.transferFrom.selector,\n                _from,\n                _to,\n                _value\n            )\n        );\n    }\n}\n"
      },
      "contracts/InterfaceHub/IAave.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\ninterface IAave {\n\n    struct ReserveData {\n\n        // Stores the reserve configuration\n        ReserveConfigurationMap configuration;\n\n        // Liquidity index. Expressed in ray\n        uint128 liquidityIndex;\n\n        // Current supply rate. Expressed in ray\n        uint128 currentLiquidityRate;\n\n        // Variable borrow index. Expressed in ray\n        uint128 variableBorrowIndex;\n\n        // Current variable borrow rate. Expressed in ray\n        uint128 currentVariableBorrowRate;\n\n        // Current stable borrow rate. Expressed in ray\n        uint128 currentStableBorrowRate;\n\n        // Timestamp of last update\n        uint40 lastUpdateTimestamp;\n\n        // Id of the reserve.\n        uint16 id;\n\n        // aToken address\n        address aTokenAddress;\n\n        // stableDebtToken address\n        address stableDebtTokenAddress;\n\n        // VariableDebtToken address\n        address variableDebtTokenAddress;\n\n        // Address of the interest rate strategy\n        address interestRateStrategyAddress;\n\n        // Current treasury balance, scaled\n        uint128 accruedToTreasury;\n\n        // Outstanding unbacked aTokens minted through the bridging feature\n        uint128 unbacked;\n\n        // Outstanding debt borrowed against this asset in isolation mode\n        uint128 isolationModeTotalDebt;\n    }\n\n    struct ReserveConfigurationMap {\n        uint256 data;\n    }\n\n    function supply(\n        address _token,\n        uint256 _amount,\n        address _owner,\n        uint16 _referralCode\n    )\n        external;\n\n    function withdraw(\n        address _token,\n        uint256 _amount,\n        address _recipient\n    )\n        external\n        returns (uint256);\n\n    function getReserveData(\n        address asset\n    )\n        external\n        view\n        returns (ReserveData memory);\n\n}"
      },
      "contracts/InterfaceHub/IWiseSecurity.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\nstruct CurveSwapStructToken {\n    uint256 curvePoolTokenIndexFrom;\n    uint256 curvePoolTokenIndexTo;\n    uint256 curveMetaPoolTokenIndexFrom;\n    uint256 curveMetaPoolTokenIndexTo;\n}\n\nstruct CurveSwapStructData {\n    address curvePool;\n    address curveMetaPool;\n    bytes swapBytesPool;\n    bytes swapBytesMeta;\n}\n\ninterface IWiseSecurity {\n\n    function checkMinDepositValue(\n        address _poolToken,\n        uint256 _amount\n    )\n        external\n        view\n        returns (bool);\n\n    function overallETHBorrow(\n        uint256 _nftId\n    )\n        external\n        view\n        returns (uint256 buffer);\n\n    function overallETHCollateralsBoth(\n        uint256 _nftId\n    )\n        external\n        view\n        returns (uint256 weighted, uint256 unweightedamount);\n\n    function getLiveDebtRatio(\n        uint256 _nftId\n    )\n        external\n        view\n        returns (uint256);\n\n    function checkHealthState(\n        uint256 _nftId,\n        bool _isPowerFarm\n    )\n        external\n        view;\n\n    function checkPoolCondition(\n        address _token\n    )\n        external\n        view;\n\n    function checkPoolWithMinDeposit(\n        address _poolToken,\n        uint256 _amount\n    )\n        external\n        view\n        returns (bool);\n\n    function overallETHBorrowHeartbeat(\n        uint256 _nftId\n    )\n        external\n        view\n        returns (uint256 buffer);\n\n    function checksLiquidation(\n        uint256 _nftIdLiquidate,\n        address _tokenToPayback,\n        uint256 _shareAmountToPay\n    )\n        external\n        view;\n\n    function getPositionLendingAmount(\n        uint256 _nftId,\n        address _poolToken\n    )\n        external\n        view\n        returns (uint256);\n\n    function getBorrowRate(\n        address _poolToken\n    )\n        external\n        view\n        returns (uint256);\n\n    function getPositionBorrowAmount(\n        uint256 _nftId,\n        address _poolToken\n    )\n        external\n        view\n        returns (uint256);\n\n    function overallUSDCollateralsBare(\n        uint256 _nftId\n    )\n        external\n        view\n        returns (uint256 amount);\n\n    function overallETHCollateralsBare(\n        uint256 _nftId\n    )\n        external\n        view\n        returns (uint256 amount);\n\n    function FEE_MANAGER()\n        external\n        view\n        returns (address);\n\n    function AAVE_HUB()\n        external\n        view\n        returns (address);\n\n    function curveSecurityCheck(\n        address _poolAddress\n    )\n        external;\n\n    function prepareCurvePools(\n        address _poolToken,\n        CurveSwapStructData calldata _curveSwapStructData,\n        CurveSwapStructToken calldata _curveSwapStructToken\n    )\n        external;\n\n    function overallETHBorrowBare(\n        uint256 _nftId\n    )\n        external\n        view\n        returns (uint256 amount);\n\n    function checksWithdraw(\n        uint256 _nftId,\n        address _caller,\n        address _poolToken\n    )\n        external\n        view\n        returns (bool);\n\n    function checksBorrow(\n        uint256 _nftId,\n        address _caller,\n        address _poolToken\n    )\n        external\n        view\n        returns (bool);\n\n    function checksSolelyWithdraw(\n        uint256 _nftId,\n        address _caller,\n        address _poolToken\n    )\n        external\n        view\n        returns (bool);\n\n    function checkOwnerPosition(\n        uint256 _nftId,\n        address _caller\n    )\n        external\n        view;\n\n    function checksCollateralizeDeposit(\n        uint256 _nftIdCaller,\n        address _caller,\n        address _poolAddress\n    )\n        external\n        view;\n\n    function calculateWishPercentage(\n        uint256 _nftId,\n        address _receiveToken,\n        uint256 _paybackETH,\n        uint256 _maxFeeETH,\n        uint256 _baseRewardLiquidation\n    )\n        external\n        view\n        returns (uint256);\n\n    function checkUncollateralizedDeposit(\n        uint256 _nftIdCaller,\n        address _poolToken\n    )\n        external\n        view;\n\n    function checkPositionLocked(\n        uint256 _nftId,\n        address _caller\n    )\n        external\n        view;\n\n    function maxFeeETH()\n        external\n        view\n        returns (uint256);\n\n    function maxFeeFarmETH()\n        external\n        view\n        returns (uint256);\n\n    function baseRewardLiquidation()\n        external\n        view\n        returns (uint256);\n\n    function baseRewardLiquidationFarm()\n        external\n        view\n        returns (uint256);\n\n    function checksRegister(\n        uint256 _nftId,\n        address _caller\n    )\n        external\n        view;\n\n    function getLendingRate(\n        address _poolToken\n    )\n        external\n        view\n        returns (uint256);\n}\n"
      },
      "contracts/FeeManager/FeeManagerEvents.sol": {
        "content": "// SPDX-License-Identifier: -- WISE --\n\npragma solidity =0.8.25;\n\ncontract FeeManagerEvents {\n\n    event ClaimedFeesWiseBulk(\n        uint256 timestamp\n    );\n\n    event PoolTokenRemoved(\n        address indexed poolToken,\n        uint256 timestamp\n    );\n\n    event PoolTokenAdded(\n        address indexed poolToken,\n        uint256 timestamp\n    );\n\n    event IncentiveOwnerBChanged(\n        address indexed newIncentiveOwnerB,\n        uint256 timestamp\n    );\n\n    event IncentiveOwnerAChanged(\n        address indexed newIncentiveOwnerA,\n        uint256 timestamp\n    );\n\n    event ClaimedOwnershipIncentiveMaster(\n        address indexed newIncentiveMaster,\n        uint256 timestamp\n    );\n\n    event IncentiveMasterProposed(\n        address indexed proposedIncentiveMaster,\n        uint256 timestamp\n    );\n\n    event PoolFeeChanged(\n        address indexed poolToken,\n        uint256 indexed newPoolFee,\n        uint256 timestamp\n    );\n\n    event ClaimedIncentives(\n        address indexed sender,\n        address indexed token,\n        uint256 amount,\n        uint256 timestamp\n    );\n\n    event ClaimedIncentivesBulk(\n        uint256 timestamp\n    );\n\n    event IncentiveIncreasedB(\n        uint256 indexed amount,\n        uint256 timestamp\n    );\n\n    event IncentiveIncreasedA(\n        uint256 indexed amount,\n        uint256 timestamp\n    );\n\n    event BadDebtIncreasedLiquidation(\n        uint256 amount,\n        uint256 timestamp\n    );\n\n    event TotalBadDebtIncreased(\n        uint256 amount,\n        uint256 timestamp\n    );\n\n    event TotalBadDebtDecreased(\n        uint256 amount,\n        uint256 timestamp\n    );\n\n    event SetBadDebtPosition(\n        uint256 indexed nftId,\n        uint256 amount,\n        uint256 timestamp\n    );\n\n    event UpdateBadDebtPosition(\n        uint256 indexed nftId,\n        uint256 newAmount,\n        uint256 timestamp\n    );\n\n    event SetBeneficial(\n        address indexed user,\n        address[] token,\n        uint256 timestamp\n    );\n\n    event RevokeBeneficial(\n        address indexed user,\n        address[] token,\n        uint256 timestamp\n    );\n\n    event ClaimedFeesWise(\n        address indexed token,\n        uint256 indexed amount,\n        uint256 indexed timestamp\n    );\n\n    event ClaimedFeesBeneficial(\n        address indexed user,\n        address indexed token,\n        uint256 amount,\n        uint256 indexed timestamp\n    );\n\n    event PayedBackBadDebt(\n        uint256 indexed nftId,\n        address indexed sender,\n        address indexed paybackToken,\n        address receivingToken,\n        uint256 paybackAmount,\n        uint256 timestamp\n    );\n\n    event PayedBackBadDebtFree(\n        uint256 indexed nftId,\n        address indexed sender,\n        address indexed paybackToken,\n        uint256  paybackAmount,\n        uint256 timestampp\n    );\n}"
      }
    },
    "settings": {
      "remappings": [
        "@balancer-labs/=node_modules/@balancer-labs/",
        "@chainlink/=node_modules/@chainlink/",
        "@ensdomains/=node_modules/@ensdomains/",
        "@eth-optimism/=node_modules/@eth-optimism/",
        "@ethereum-waffle/=node_modules/@ethereum-waffle/",
        "@openzeppelin/=node_modules/@openzeppelin/",
        "@pendle/=node_modules/@pendle/",
        "@uniswap/=node_modules/@uniswap/",
        "base64-sol/=node_modules/base64-sol/",
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "eth-gas-reporter/=node_modules/eth-gas-reporter/",
        "forge-std/=lib/forge-std/src/",
        "hardhat/=node_modules/hardhat/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 20
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "cancun",
      "viaIR": false,
      "libraries": {}
    }
  }}