creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {ContextUpgradeable} from \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n    /// @custom:storage-location erc7201:openzeppelin.storage.Ownable\n    struct OwnableStorage {\n        address _owner;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Ownable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;\n\n    function _getOwnableStorage() private pure returns (OwnableStorage storage $) {\n        assembly {\n            $.slot := OwnableStorageLocation\n        }\n    }\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    function __Ownable_init(address initialOwner) internal onlyInitializing {\n        __Ownable_init_unchained(initialOwner);\n    }\n\n    function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        OwnableStorage storage $ = _getOwnableStorage();\n        return $._owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        OwnableStorage storage $ = _getOwnableStorage();\n        address oldOwner = $._owner;\n        $._owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Storage of the initializable contract.\n     *\n     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\n     * when using with upgradeable contracts.\n     *\n     * @custom:storage-location erc7201:openzeppelin.storage.Initializable\n     */\n    struct InitializableStorage {\n        /**\n         * @dev Indicates that the contract has been initialized.\n         */\n        uint64 _initialized;\n        /**\n         * @dev Indicates that the contract is in the process of being initialized.\n         */\n        bool _initializing;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Initializable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\n\n    /**\n     * @dev The contract is already initialized.\n     */\n    error InvalidInitialization();\n\n    /**\n     * @dev The contract is not initializing.\n     */\n    error NotInitializing();\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint64 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\n     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\n     * production.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        // Cache values to avoid duplicated sloads\n        bool isTopLevelCall = !$._initializing;\n        uint64 initialized = $._initialized;\n\n        // Allowed calls:\n        // - initialSetup: the contract is not in the initializing state and no previous version was\n        //                 initialized\n        // - construction: the contract is initialized at version 1 (no reininitialization) and the\n        //                 current contract is just being deployed\n        bool initialSetup = initialized == 0 && isTopLevelCall;\n        bool construction = initialized == 1 && address(this).code.length == 0;\n\n        if (!initialSetup && !construction) {\n            revert InvalidInitialization();\n        }\n        $._initialized = 1;\n        if (isTopLevelCall) {\n            $._initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            $._initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint64 version) {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing || $._initialized >= version) {\n            revert InvalidInitialization();\n        }\n        $._initialized = version;\n        $._initializing = true;\n        _;\n        $._initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        _checkInitializing();\n        _;\n    }\n\n    /**\n     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\n     */\n    function _checkInitializing() internal view virtual {\n        if (!_isInitializing()) {\n            revert NotInitializing();\n        }\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing) {\n            revert InvalidInitialization();\n        }\n        if ($._initialized != type(uint64).max) {\n            $._initialized = type(uint64).max;\n            emit Initialized(type(uint64).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint64) {\n        return _getInitializableStorage()._initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _getInitializableStorage()._initializing;\n    }\n\n    /**\n     * @dev Returns a pointer to the storage namespace.\n     */\n    // solhint-disable-next-line var-name-mixedcase\n    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\n        assembly {\n            $.slot := INITIALIZABLE_STORAGE\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"
      },
      "contracts/Incentives/EligibilityDataProvider.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.23;\n\nimport { OwnableUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { ICollateralChecker } from \"../interfaces/IIncentive/ICollateralChecker.sol\";\nimport { IPriceProvider } from \"../interfaces/IIncentive/IPriceProvider.sol\";\nimport { IChefIncentivesController, IEDPUserDefinedTypes, IEligibilityDataProvider } from \"../interfaces/IIncentive/IEligibilityDataProvider.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title Eligible Deposit Provider\n/// @author 0xKMG\n/// based on Radiant's EligibilityDataProvider\ncontract EligibilityDataProvider is IEligibilityDataProvider, IEDPUserDefinedTypes, OwnableUpgradeable {\n    /********************** Common Info ***********************/\n    /// @notice RATIO BASE equal to 100%\n    uint256 public constant RATIO_DIVISOR = 10000;\n\n    /// @notice Initial required ratio of TVL to get reward; in bips\n    uint256 public constant INITIAL_REQUIRED_DEPOSIT_RATIO = 500;\n\n    /// @notice Initial ratio of the required price to still allow without disqualification; in bips\n    uint256 public constant INITIAL_PRICE_TOLERANCE_RATIO = 9000;\n\n    /// @notice Minimum required ratio of TVL to get reward; in bips\n    uint256 public constant MIN_PRICE_TOLERANCE_RATIO = 8000;\n\n    /// @notice Address of collateralChecker (to be deployed)\n    ICollateralChecker public collateralChecker;\n    /// @notice Address of CIC\n    IChefIncentivesController public chef;\n\n    /// @notice APUFF + LP price provider\n    IPriceProvider public priceProvider;\n\n    /// @notice Required ratio of TVL to get reward; in bips\n    uint256 public requiredDepositRatio;\n\n    /// @notice Ratio of the required price to still allow without disqualification; in bips\n    uint256 public priceToleranceRatio;\n\n    /// @notice veToken\n    address public veToken;\n\n    /********************** Eligible info ***********************/\n\n    /// @notice Last eligible status of the user\n    mapping(address => bool) public lastEligibleStatus;\n\n    /// @notice Disqualified time of the user\n    mapping(address => uint256) public disqualifiedTime;\n\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    /**\n     * @param _collateralChecker Address of lending pool.\n     * @param _priceProvider PriceProvider address.\n     */\n    function initialize(ICollateralChecker _collateralChecker, IPriceProvider _priceProvider) public initializer {\n        if (address(_collateralChecker) == address(0)) revert AddressZero();\n        if (address(_priceProvider) == address(0)) revert AddressZero();\n\n        collateralChecker = _collateralChecker;\n        priceProvider = _priceProvider;\n\n        requiredDepositRatio = INITIAL_REQUIRED_DEPOSIT_RATIO;\n        priceToleranceRatio = INITIAL_PRICE_TOLERANCE_RATIO;\n        __Ownable_init(msg.sender);\n    }\n\n    /********************** Setters ***********************/\n    /**\n     * @notice Set CIC\n     * @param _chef address.\n     */\n    function setChefIncentivesController(IChefIncentivesController _chef) external onlyOwner {\n        if (address(_chef) == address(0)) revert AddressZero();\n        chef = _chef;\n        emit ChefIncentivesControllerUpdated(_chef);\n    }\n\n    /**\n     * @notice Set LP token\n     */\n    function setVeToken(address _veToken) external onlyOwner {\n        if (_veToken == address(0)) revert AddressZero();\n        if (veToken != address(0)) revert LPTokenSet(veToken);\n        veToken = _veToken;\n\n        emit VeTokenUpdated(_veToken);\n    }\n\n    /**\n     * @notice Sets required tvl ratio. Can only be called by the owner.\n     * @param _requiredDepositRatio Ratio in bips.\n     */\n    function setRequiredDepositRatio(uint256 _requiredDepositRatio) external onlyOwner {\n        if (_requiredDepositRatio > RATIO_DIVISOR) revert InvalidRatio();\n        requiredDepositRatio = _requiredDepositRatio;\n\n        emit RequiredDepositRatioUpdated(_requiredDepositRatio);\n    }\n\n    /**\n     * @notice Sets price tolerance ratio. Can only be called by the owner.\n     * @param _priceToleranceRatio Ratio in bips.\n     */\n    function setPriceToleranceRatio(uint256 _priceToleranceRatio) external onlyOwner {\n        if (_priceToleranceRatio < MIN_PRICE_TOLERANCE_RATIO || _priceToleranceRatio > RATIO_DIVISOR) revert InvalidRatio();\n        priceToleranceRatio = _priceToleranceRatio;\n\n        emit PriceToleranceRatioUpdated(_priceToleranceRatio);\n    }\n\n    /**\n     * @notice Sets DQ time of the user\n     * @dev Only callable by CIC\n     * @param _user's address\n     * @param _time for DQ\n     */\n    //@note use in CIC: stopEmissionsFor\n    function setDqTime(address _user, uint256 _time) external {\n        if (msg.sender != address(chef)) revert OnlyCIC();\n        disqualifiedTime[_user] = _time;\n\n        emit DqTimeUpdated(_user, _time);\n    }\n\n    /********************** View functions ***********************/\n    /**\n     * @notice Returns locked APUFF and LP token value in eth\n     * @param user's address\n     */\n    function lockedVeTokenUsdcValue(address user) public view returns (uint256) {\n        //@todo confirm decimal handling\n        uint256 price = priceProvider.getTokenPrice();\n        uint256 veTokenAmount = IERC20(veToken).balanceOf(user);\n        return ((veTokenAmount * price) * 1e6) / 1e18 / 1e18; // 1e6 for 6 decimals of usdc, 1e18 for 18 decimals of veToken and price\n    }\n\n    /**\n     * @notice Returns USD value required to be locked\n     * @param user's address\n     * @return required USD value.\n     */\n    function requiredUsdcValue(address user) public view returns (uint256 required) {\n        uint256 totalCollateralUSD = collateralChecker.getTotalCollateralInUsdc(user) / 1e12;\n        required = (totalCollateralUSD * requiredDepositRatio) / RATIO_DIVISOR;\n    }\n\n    /**\n     * @notice Returns if the user is eligible to receive rewards\n     * @param _user's address\n     */\n    function isEligibleForRewards(address _user) public view returns (bool) {\n        uint256 lockedValue = lockedVeTokenUsdcValue(_user);\n        uint256 requiredValue = (requiredUsdcValue(_user) * priceToleranceRatio) / RATIO_DIVISOR;\n        return requiredValue != 0 && lockedValue >= requiredValue;\n    }\n\n    /**\n     * @notice Returns if the user is eligible to receive rewards, lockedVeToken Value and totalCollateralUSD, saved to backend before execution\n     * @param _user's address\n     */\n    function getEligibilityData(address _user) public view returns (bool isEligible, uint256 lockedValue, uint256 totalCollateralUSD) {\n        lockedValue = lockedVeTokenUsdcValue(_user);\n        totalCollateralUSD = collateralChecker.getTotalCollateralInUsdc(_user) / 1e12;\n        uint256 requiredBeforePT = (totalCollateralUSD * requiredDepositRatio) / RATIO_DIVISOR;\n        uint256 requiredValue = (requiredBeforePT * priceToleranceRatio) / RATIO_DIVISOR;\n        isEligible = requiredValue != 0 && lockedValue >= requiredValue;\n    }\n\n    /**\n     * @notice Returns DQ time of the user\n     * @param _user's address\n     */\n    function getDqTime(address _user) public view returns (uint256) {\n        return disqualifiedTime[_user];\n    }\n\n    /********************** Operate functions ***********************/\n    //     /**\n    //      * @notice Refresh token amount for eligibility\n    //      * @param user The address of the user\n    //      * @return currentEligibility the current eligibility status of the user\n    //      */\n    //     function refresh(address user) external returns (bool currentEligibility) {\n    //         if (msg.sender != address(chef)) revert OnlyCIC();\n    //         if (user == address(0)) revert AddressZero();\n    //\n    //         currentEligibility = isEligibleForRewards(user);\n    //         if (currentEligibility && disqualifiedTime[user] != 0) {\n    //             disqualifiedTime[user] = 0;\n    //         }\n    //         lastEligibleStatus[user] = currentEligibility;\n    //     }\n\n    /**\n     * @notice Refresh token amount for eligibility by Keeper\n     * @param user The address of the user\n     * @return currentEligibility The current eligibility status of the user\n     */\n    function refreshByKeeper(address user, bool isEligible) external returns (bool currentEligibility) {\n        if (msg.sender != address(chef)) revert OnlyCIC();\n        if (user == address(0)) revert AddressZero();\n\n        currentEligibility = isEligible;\n        if (currentEligibility && disqualifiedTime[user] != 0) {\n            disqualifiedTime[user] = 0;\n        }\n        lastEligibleStatus[user] = currentEligibility;\n    }\n\n    /********************** Internal functions ***********************/\n}\n"
      },
      "contracts/interfaces/IIncentive/IChefIncentivesController.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity ^0.8.23;\npragma experimental ABIEncoderV2;\n\ninterface ICICUserDefinedTypes {\n    // Info of each user.\n    // reward = user.`amount` * pool.`accRewardPerShare` - `rewardDebt`\n    struct UserInfo {\n        uint256 amount;\n        uint256 rewardDebt;\n        uint256 lastClaimTime;\n    }\n\n    // Info of each pool.\n    struct PoolInfo {\n        uint256 totalSupply;\n        uint256 allocPoint; // How many allocation points assigned to this pool.\n        uint256 lastRewardTime; // Last second that reward distribution occurs.\n        uint256 accRewardPerShare; // Accumulated rewards per share, times ACC_REWARD_PRECISION. See below.\n    }\n    // Info about token emissions for a given time period.\n    struct EmissionPoint {\n        uint128 startTimeOffset;\n        uint128 rewardsPerSecond;\n    }\n    // Info about ending time of reward emissions\n    struct EndingTime {\n        uint256 estimatedTime;\n        uint256 lastUpdatedTime;\n        uint256 updateCadence;\n    }\n\n    enum EligibilityModes {\n        // check on all rToken transfers\n        FULL,\n        // only check on Claim\n        LIMITED,\n        // 0 eligibility functions run\n        DISABLED\n    }\n\n    /********************** Events ***********************/\n    // Emitted when rewardPerSecond is updated\n    event RewardsPerSecondUpdated(uint256 indexed rewardsPerSecond);\n\n    event BalanceUpdated(address indexed token, address indexed user, uint256 balance);\n\n    event EmissionScheduleAppended(uint256[] startTimeOffsets, uint256[] rewardsPerSeconds);\n\n    event Disqualified(address indexed user);\n\n    event EligibilityModeUpdated(EligibilityModes indexed _newVal);\n\n    event BatchAllocPointsUpdated(address[] _tokens, uint256[] _allocPoints);\n\n    event AuthorizedContractUpdated(address _contract, bool _authorized);\n\n    event EndingTimeUpdateCadence(uint256 indexed _lapse);\n\n    event RewardDeposit(uint256 indexed _amount);\n\n    event UpdateRequested(address indexed _user, uint256 feePaid);\n\n    event KeeperConfigSet(address indexed keeper, uint256 executionGasLimit, uint256 internalGasLimit);\n\n    /********************** Errors ***********************/\n    error AddressZero();\n\n    error UnknownPool();\n\n    error PoolExists();\n\n    error AlreadyStarted();\n\n    error NotAllowed();\n\n    error ArrayLengthMismatch();\n\n    error InvalidStart();\n\n    error InvalidRToken();\n\n    error InsufficientPermission();\n\n    error AuthorizationAlreadySet();\n\n    error NotVeContract();\n\n    error NotWhitelisted();\n\n    error NotEligible();\n\n    error CadenceTooLong();\n\n    error EligibleRequired();\n\n    error NotValidPool();\n\n    error OutOfRewards();\n\n    error DuplicateSchedule();\n\n    error ValueZero();\n\n    error NotKeeper();\n\n    error InsufficientFee();\n\n    error TransferFailed();\n\n    error UpdateInProgress();\n\n    error ExemptedUser();\n\n    error EthTransferFailed(); \n\n}\n\ninterface IChefIncentivesController {\n    /**\n     * @dev Called by the corresponding asset on any update that affects the rewards distribution\n     * @param user The address of the user\n     **/\n    function handleActionBefore(address user) external;\n\n    /**\n     * @dev Called by the corresponding asset on any update that affects the rewards distribution\n     * @param user The address of the user\n     * @param userBalance The balance of the user of the asset in the lending pool\n     **/\n    function handleWithdrawAfter(address user, uint256 userBalance) external;\n\n    /**\n     * @dev Called by the locking contracts after locking or unlocking happens\n     * @param user The address of the user\n     **/\n    function beforeLockUpdate(address user) external;\n\n    /**\n     * @notice Hook for lock update.\n     * @dev Called by the locking contracts after locking or unlocking happens\n     */\n    function afterLockUpdate(address _user) external;\n\n    function addPool(address _token, uint256 _allocPoint) external;\n\n    function claim(address _user, address[] calldata _tokens) external;\n\n    // function disqualifyUser(address _user, address _hunter) external returns (uint256 bounty);\n\n    // function bountyForUser(address _user) external view returns (uint256 bounty);\n\n    function allPendingRewards(address _user) external view returns (uint256 pending);\n\n    function claimAll(address _user) external;\n\n    // function claimBounty(address _user, bool _execute) external returns (bool issueBaseBounty);\n\n    function setEligibilityExempt(address _address, bool _value) external;\n\n    function manualStopEmissionsFor(address _user, address[] memory _tokens) external;\n\n    function manualStopAllEmissionsFor(address _user) external;\n\n    function setAddressWLstatus(address user, bool status) external;\n\n    function toggleWhitelist() external;\n}\n"
      },
      "contracts/interfaces/IIncentive/ICollateralChecker.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.23;\n\ninterface ICollateralChecker {\n    //@dev total collatral Amount deposited in our system on a certain chain\n    function getTotalCollateralInUsdc(address _user) external view returns (uint256 totalCollateralInUSD);\n\n    function owner() external view returns (address);\n}\n"
      },
      "contracts/interfaces/IIncentive/IEligibilityDataProvider.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity ^0.8.23;\n\nimport { IChefIncentivesController } from \"./IChefIncentivesController.sol\";\n\ninterface IEDPUserDefinedTypes {\n    /********************** Events ***********************/\n    /// @notice Emitted when CIC is set\n    event ChefIncentivesControllerUpdated(IChefIncentivesController indexed _chef);\n\n    /// @notice Emitted when LP token is set\n    event VeTokenUpdated(address indexed _lpToken);\n\n    /// @notice Emitted when required TVL ratio is updated\n    event RequiredDepositRatioUpdated(uint256 indexed requiredDepositRatio);\n\n    /// @notice Emitted when price tolerance ratio is updated\n    event PriceToleranceRatioUpdated(uint256 indexed priceToleranceRatio);\n\n    /// @notice Emitted when DQ time is set\n    event DqTimeUpdated(address indexed _user, uint256 _time);\n\n    /********************** Errors ***********************/\n    error AddressZero();\n\n    error LPTokenSet(address currentVeToken);\n\n    error InvalidRatio();\n\n    error OnlyCIC();\n}\n\ninterface IEligibilityDataProvider {\n    function refreshByKeeper(address user, bool isEligible) external returns (bool currentEligibility);\n\n    function isEligibleForRewards(address _user) external view returns (bool isEligible);\n\n    function lockedVeTokenUsdcValue(address user) external view returns (uint256);\n\n    function requiredUsdcValue(address user) external view returns (uint256 required);\n\n    function lastEligibleStatus(address user) external view returns (bool);\n\n    function setDqTime(address _user, uint256 _time) external;\n\n    function getDqTime(address _user) external view returns (uint256);\n\n    function requiredDepositRatio() external view returns (uint256);\n\n    function RATIO_DIVISOR() external view returns (uint256);\n}\n"
      },
      "contracts/interfaces/IIncentive/IPriceProvider.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.23;\n\ninterface IPriceProvider {\n    /********************** Events ***********************/\n\n    event ChainlinkOracleSet(address ethOracle);\n    event TimeIntervalSet(uint256 indexed timeInterval, uint32 indexed twapInterval, uint8 indexed timePoints);\n    event PriceUpdated(uint256 indexed price);\n    event PriceBroadcasted(uint256 chainId, uint256 indexed price);\n    event ApuffTokenPoolSet(address indexed apuffTokenPoolAddress);\n    event EthWithdrawn(uint256 indexed amount);\n    event KeeperSet(address keeper, bool isKeeper);\n    /********************** Errors ***********************/\n    error AddressZero();\n    error InvalidTimeInterval();\n    error InvalidTimePoints();\n    error NotKeeper();\n\n    function getTokenPrice() external view returns (uint256);\n\n    function decimals() external view returns (uint8);\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "evmVersion": "paris",
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "metadata": {
        "useLiteralContent": true
      },
      "libraries": {}
    }
  }}