creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\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 Indicates that the contract has been initialized.\n     * @custom:oz-retyped-from bool\n     */\n    uint8 private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint8 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 functions marked with `initializer` can be nested in the context of a\n     * constructor.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        bool isTopLevelCall = !_initializing;\n        require(\n            (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n            \"Initializable: contract is already initialized\"\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 255 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint8 version) {\n        require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\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        require(_initializing, \"Initializable: contract is not initializing\");\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        require(!_initializing, \"Initializable: contract is initializing\");\n        if (_initialized != type(uint8).max) {\n            _initialized = type(uint8).max;\n            emit Initialized(type(uint8).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint8) {\n        return _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 _initializing;\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant _NOT_ENTERED = 1;\n    uint256 private constant _ENTERED = 2;\n\n    uint256 private _status;\n\n    function __ReentrancyGuard_init() internal onlyInitializing {\n        __ReentrancyGuard_init_unchained();\n    }\n\n    function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, _status will be _NOT_ENTERED\n        require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n        // Any calls to nonReentrant after this point will fail\n        _status = _ENTERED;\n    }\n\n    function _nonReentrantAfter() private {\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = _NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        return _status == _ENTERED;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     *\n     * Furthermore, `isContract` will also return true if the target contract within\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n     * which only has an effect at the end of a transaction.\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert(errorMessage);\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * ==== Security Considerations\n *\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\n * generally recommended is:\n *\n * ```solidity\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\n *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\n *     doThing(..., value);\n * }\n *\n * function doThing(..., uint256 value) public {\n *     token.safeTransferFrom(msg.sender, address(this), value);\n *     ...\n * }\n * ```\n *\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\n * {SafeERC20-safeTransferFrom}).\n *\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\n * contracts should have entry points that don't rely on permit.\n */\ninterface IERC20Permit {\n    /**\n     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n     * given ``owner``'s signed approval.\n     *\n     * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n     * ordering also apply here.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `deadline` must be a timestamp in the future.\n     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n     * over the EIP712-formatted function arguments.\n     * - the signature must use ``owner``'s current nonce (see {nonces}).\n     *\n     * For more information on the signature format, see the\n     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n     * section].\n     *\n     * CAUTION: See Security Considerations above.\n     */\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /**\n     * @dev Returns the current nonce for `owner`. This value must be\n     * included whenever a signature is generated for {permit}.\n     *\n     * Every successful call to {permit} increases ``owner``'s nonce by one. This\n     * prevents a signature from being used multiple times.\n     */\n    function nonces(address owner) external view returns (uint256);\n\n    /**\n     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\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 amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(IERC20 token, address spender, uint256 value) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n        if (!_callOptionalReturnBool(token, approvalCall)) {\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n            _callOptionalReturn(token, approvalCall);\n        }\n    }\n\n    /**\n     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n     * Revert on invalid signature.\n     */\n    function safePermit(\n        IERC20Permit token,\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal {\n        uint256 nonceBefore = token.nonces(owner);\n        token.permit(owner, spender, value, deadline, v, r, s);\n        uint256 nonceAfter = token.nonces(owner);\n        require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n     */\n    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n        // and not revert is the subcall reverts.\n\n        (bool success, bytes memory returndata) = address(token).call(data);\n        return\n            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     *\n     * Furthermore, `isContract` will also return true if the target contract within\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n     * which only has an effect at the end of a transaction.\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert(errorMessage);\n        }\n    }\n}\n"
      },
      "contracts/Delegation/IOperatorDelegator.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../EigenLayer/interfaces/IStrategyManager.sol\";\nimport \"../EigenLayer/interfaces/IDelegationManager.sol\";\nimport \"../EigenLayer/interfaces/IEigenPod.sol\";\n\ninterface IOperatorDelegator {\n    function getTokenBalanceFromStrategy(IERC20 token) external view returns (uint256);\n\n    function deposit(IERC20 _token, uint256 _tokenAmount) external returns (uint256 shares);\n\n    function startWithdrawal(IERC20 _token, uint256 _tokenAmount) external returns (bytes32);\n\n    function completeWithdrawal(\n        IStrategyManager.QueuedWithdrawal calldata _withdrawal,\n        IERC20 _token,\n        uint256 _middlewareTimesIndex,\n        address _sendToAddress\n    ) external;\n\n    function getStakedETHBalance() external view returns (uint256);\n\n    function stakeEth(\n        bytes calldata pubkey,\n        bytes calldata signature,\n        bytes32 depositDataRoot\n    ) external payable;\n\n    function eigenPod() external view returns (IEigenPod);\n\n    function pendingUnstakedDelayedWithdrawalAmount() external view returns (uint256);\n}\n"
      },
      "contracts/Deposits/DepositQueue.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"./DepositQueueStorage.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"../Errors/Errors.sol\";\n\ncontract DepositQueue is Initializable, ReentrancyGuardUpgradeable, DepositQueueStorageV1 {\n    using SafeERC20 for IERC20;\n\n    event RewardsDeposited(IERC20 token, uint256 amount);\n\n    event FeeConfigUpdated(address feeAddress, uint256 feeBasisPoints);\n\n    event RestakeManagerUpdated(IRestakeManager restakeManager);\n\n    event ETHDepositedFromProtocol(uint256 amount);\n\n    event ETHStakedFromQueue(\n        IOperatorDelegator operatorDelegator,\n        bytes pubkey,\n        uint256 amountStaked,\n        uint256 amountQueued\n    );\n\n    event ProtocolFeesPaid(IERC20 token, uint256 amount, address destination);\n\n    event GasRefunded(address admin, uint256 gasRefunded);\n\n    /// @dev Allows only a whitelisted address to configure the contract\n    modifier onlyRestakeManagerAdmin() {\n        if (!roleManager.isRestakeManagerAdmin(msg.sender)) revert NotRestakeManagerAdmin();\n        _;\n    }\n\n    /// @dev Allows only the RestakeManager address to call functions\n    modifier onlyRestakeManager() {\n        if (msg.sender != address(restakeManager)) revert NotRestakeManager();\n        _;\n    }\n\n    /// @dev Allows only a whitelisted address to trigger native ETH staking\n    modifier onlyNativeEthRestakeAdmin() {\n        if (!roleManager.isNativeEthRestakeAdmin(msg.sender)) revert NotNativeEthRestakeAdmin();\n        _;\n    }\n\n    /// @dev Allows only a whitelisted address to trigger ERC20 rewards sweeping\n    modifier onlyERC20RewardsAdmin() {\n        if (!roleManager.isERC20RewardsAdmin(msg.sender)) revert NotERC20RewardsAdmin();\n        _;\n    }\n\n    /// @dev Prevents implementation contract from being initialized.\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    /// @dev Initializes the contract with initial vars\n    function initialize(IRoleManager _roleManager) public initializer {\n        __ReentrancyGuard_init();\n\n        if (address(_roleManager) == address(0x0)) revert InvalidZeroInput();\n\n        roleManager = _roleManager;\n    }\n\n    /// @dev Sets the config for fees - if either value is set to 0 then fees are disabled\n    function setFeeConfig(\n        address _feeAddress,\n        uint256 _feeBasisPoints\n    ) external onlyRestakeManagerAdmin {\n        // Verify address is set if basis points are non-zero\n        if (_feeBasisPoints > 0) {\n            if (_feeAddress == address(0x0)) revert InvalidZeroInput();\n        }\n\n        // Verify basis points are not over 100%\n        if (_feeBasisPoints > 10000) revert OverMaxBasisPoints();\n\n        feeAddress = _feeAddress;\n        feeBasisPoints = _feeBasisPoints;\n\n        emit FeeConfigUpdated(_feeAddress, _feeBasisPoints);\n    }\n\n    /// @dev Sets the address of the RestakeManager contract\n    function setRestakeManager(IRestakeManager _restakeManager) external onlyRestakeManagerAdmin {\n        if (address(_restakeManager) == address(0x0)) revert InvalidZeroInput();\n\n        restakeManager = _restakeManager;\n\n        emit RestakeManagerUpdated(_restakeManager);\n    }\n\n    /// @dev Handle ETH sent to the protocol through the RestakeManager - e.g. user deposits\n    /// ETH will be stored here until used for a validator deposit\n    function depositETHFromProtocol() external payable onlyRestakeManager {\n        emit ETHDepositedFromProtocol(msg.value);\n    }\n\n    /// @dev Handle ETH sent to this contract from outside the protocol - e.g. rewards\n    /// ETH will be stored here until used for a validator deposit\n    /// This should receive ETH from scenarios like Execution Layer Rewards and MEV from native staking\n    /// Users should NOT send ETH directly to this contract unless they want to donate to existing ezETH holders\n    receive() external payable nonReentrant {\n        uint256 feeAmount = 0;\n        // Take protocol cut of rewards if enabled\n        if (feeAddress != address(0x0) && feeBasisPoints > 0) {\n            feeAmount = (msg.value * feeBasisPoints) / 10000;\n            (bool success, ) = feeAddress.call{ value: feeAmount }(\"\");\n            if (!success) revert TransferFailed();\n\n            emit ProtocolFeesPaid(IERC20(address(0x0)), feeAmount, feeAddress);\n        }\n\n        // Add to the total earned\n        totalEarned[address(0x0)] = totalEarned[address(0x0)] + msg.value - feeAmount;\n\n        // Emit the rewards event\n        emit RewardsDeposited(IERC20(address(0x0)), msg.value - feeAmount);\n    }\n\n    /// @dev Function called by ETH Restake Admin to start the restaking process in Native ETH\n    /// Only callable by a permissioned account\n    function stakeEthFromQueue(\n        IOperatorDelegator operatorDelegator,\n        bytes calldata pubkey,\n        bytes calldata signature,\n        bytes32 depositDataRoot\n    ) external onlyNativeEthRestakeAdmin {\n        uint256 gasBefore = gasleft();\n        // Send the ETH and the params through to the restake manager\n        restakeManager.stakeEthInOperatorDelegator{ value: 32 ether }(\n            operatorDelegator,\n            pubkey,\n            signature,\n            depositDataRoot\n        );\n\n        emit ETHStakedFromQueue(operatorDelegator, pubkey, 32 ether, address(this).balance);\n\n        // Refund the gas to the Admin address if enough ETH available\n        _refundGas(gasBefore);\n    }\n\n    /// @dev Function called by ETH Restake Admin to start the restaking process in Native ETH\n    /// Only callable by a permissioned account\n    /// Can stake multiple validators with 1 tx\n    function stakeEthFromQueueMulti(\n        IOperatorDelegator[] calldata operatorDelegators,\n        bytes[] calldata pubkeys,\n        bytes[] calldata signatures,\n        bytes32[] calldata depositDataRoots\n    ) external onlyNativeEthRestakeAdmin nonReentrant {\n        uint256 gasBefore = gasleft();\n        // Verify all arrays are the same length\n        if (\n            operatorDelegators.length != pubkeys.length ||\n            operatorDelegators.length != signatures.length ||\n            operatorDelegators.length != depositDataRoots.length\n        ) revert MismatchedArrayLengths();\n\n        // Iterate through the arrays and stake each one\n        uint256 arrayLength = operatorDelegators.length;\n        for (uint256 i = 0; i < arrayLength; ) {\n            // Send the ETH and the params through to the restake manager\n            restakeManager.stakeEthInOperatorDelegator{ value: 32 ether }(\n                operatorDelegators[i],\n                pubkeys[i],\n                signatures[i],\n                depositDataRoots[i]\n            );\n\n            emit ETHStakedFromQueue(\n                operatorDelegators[i],\n                pubkeys[i],\n                32 ether,\n                address(this).balance\n            );\n\n            unchecked {\n                ++i;\n            }\n        }\n\n        // Refund the gas to the Admin address if enough ETH available\n        _refundGas(gasBefore);\n    }\n\n    /// @dev Sweeps any accumulated ERC20 tokens in this contract to the RestakeManager\n    /// Only callable by a permissioned account\n    function sweepERC20(IERC20 token) external onlyERC20RewardsAdmin {\n        uint256 balance = IERC20(token).balanceOf(address(this));\n        if (balance > 0) {\n            uint256 feeAmount = 0;\n\n            // Sweep fees if configured\n            if (feeAddress != address(0x0) && feeBasisPoints > 0) {\n                feeAmount = (balance * feeBasisPoints) / 10000;\n                IERC20(token).safeTransfer(feeAddress, feeAmount);\n\n                emit ProtocolFeesPaid(token, feeAmount, feeAddress);\n            }\n\n            // Approve and deposit the rewards\n            token.approve(address(restakeManager), balance - feeAmount);\n            restakeManager.depositTokenRewardsFromProtocol(token, balance - feeAmount);\n\n            // Add to the total earned\n            totalEarned[address(token)] = totalEarned[address(token)] + balance - feeAmount;\n\n            // Emit the rewards event\n            emit RewardsDeposited(IERC20(address(token)), balance - feeAmount);\n        }\n    }\n\n    /**\n     * @notice Internal function used to refund gas to admin accounts if enough balance\n     * @param initialGas Initial Gas available\n     */\n    function _refundGas(uint256 initialGas) internal {\n        uint256 gasUsed = (initialGas - gasleft()) * tx.gasprice;\n        uint256 gasRefund = address(this).balance >= gasUsed ? gasUsed : address(this).balance;\n        (bool success, ) = payable(msg.sender).call{ value: gasRefund }(\"\");\n        if (!success) revert TransferFailed();\n        emit GasRefunded(msg.sender, gasRefund);\n    }\n}\n"
      },
      "contracts/Deposits/DepositQueueStorage.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\n\nimport \"../Permissions/IRoleManager.sol\";\nimport \"../IRestakeManager.sol\";\nimport \"./IDepositQueue.sol\";\n\nabstract contract DepositQueueStorageV1 is IDepositQueue {\n    /// @dev reference to the RoleManager contract\n    IRoleManager public roleManager;\n\n    /// @dev the address of the RestakeManager contract\n    IRestakeManager public restakeManager;\n\n    /// @dev the address where fees will be sent - must be non zero to enable fees\n    address public feeAddress;\n\n    /// @dev the basis points to charge for fees - 100 basis points = 1%\n    uint256 public feeBasisPoints;\n\n    /// @dev the total amount the protocol has earned - token address => amount\n    mapping(address => uint256) public totalEarned;\n}\n"
      },
      "contracts/Deposits/IDepositQueue.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\n\ninterface IDepositQueue {\n    function depositETHFromProtocol() external payable;\n    function totalEarned(address tokenAddress) external view returns (uint256);\n}\n"
      },
      "contracts/EigenLayer/interfaces/IBeaconChainOracle.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity =0.8.19;\n\n/**\n * @title Interface for the BeaconStateOracle contract.\n * @author Layr Labs, Inc.\n * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service\n */\ninterface IBeaconChainOracle {\n    /// @notice Largest blockNumber that has been confirmed by the oracle.\n    function latestConfirmedOracleBlockNumber() external view returns (uint64);\n    /// @notice Mapping: Beacon Chain blockNumber => the Beacon Chain state root at the specified blockNumber.\n    /// @dev This will return `bytes32(0)` if the state root at the specified blockNumber is not yet confirmed.\n    function beaconStateRootAtBlockNumber(uint64 blockNumber) external view returns (bytes32);\n\n    /// @notice Mapping: address => whether or not the address is in the set of oracle signers.\n    function isOracleSigner(address _oracleSigner) external view returns (bool);\n\n    /// @notice Mapping: Beacon Chain blockNumber => oracle signer address => whether or not the oracle signer has voted on the state root at the blockNumber.\n    function hasVoted(uint64 blockNumber, address oracleSigner) external view returns (bool);\n\n    /// @notice Mapping: Beacon Chain blockNumber => state root => total number of oracle signer votes for the state root at the blockNumber.\n    function stateRootVotes(uint64 blockNumber, bytes32 stateRoot) external view returns (uint256);\n\n    /// @notice Total number of members of the set of oracle signers.\n    function totalOracleSigners() external view returns (uint256);\n\n    /**\n     * @notice Number of oracle signers that must vote for a state root in order for the state root to be confirmed.\n     * Adjustable by this contract's owner through use of the `setThreshold` function.\n     * @dev We note that there is an edge case -- when the threshold is adjusted downward, if a state root already has enough votes to meet the *new* threshold,\n     * the state root must still receive one additional vote from an oracle signer to be confirmed. This behavior is intended, to minimize unexpected root confirmations.\n     */\n    function threshold() external view returns (uint256);\n\n    /**\n     * @notice Owner-only function used to modify the value of the `threshold` variable.\n     * @param _threshold Desired new value for the `threshold` variable. Function will revert if this is set to zero.\n     */\n    function setThreshold(uint256 _threshold) external;\n\n    /**\n     * @notice Owner-only function used to add a signer to the set of oracle signers.\n     * @param _oracleSigners Array of address to be added to the set.\n     * @dev Function will have no effect on the i-th input address if `_oracleSigners[i]`is already in the set of oracle signers.\n     */\n    function addOracleSigners(address[] memory _oracleSigners) external;\n\n    /**\n     * @notice Owner-only function used to remove a signer from the set of oracle signers.\n     * @param _oracleSigners Array of address to be removed from the set.\n     * @dev Function will have no effect on the i-th input address if `_oracleSigners[i]`is already not in the set of oracle signers.\n     */\n    function removeOracleSigners(address[] memory _oracleSigners) external;\n\n    /**\n     * @notice Called by a member of the set of oracle signers to assert that the Beacon Chain state root is `stateRoot` at `blockNumber`.\n     * @dev The state root will be finalized once the total number of votes *for this exact state root at this exact blockNumber* meets the `threshold` value.\n     * @param blockNumber The Beacon Chain blockNumber of interest.\n     * @param stateRoot The Beacon Chain state root that the caller asserts was the correct root, at the specified `blockNumber`.\n     */\n    function voteForBeaconChainStateRoot(uint64 blockNumber, bytes32 stateRoot) external;\n}\n"
      },
      "contracts/EigenLayer/interfaces/IDelayedWithdrawalRouter.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity =0.8.19;\n\ninterface IDelayedWithdrawalRouter {\n    // struct used to pack data into a single storage slot\n    struct DelayedWithdrawal {\n        uint224 amount;\n        uint32 blockCreated;\n    }\n\n    // struct used to store a single users delayedWithdrawal data\n    struct UserDelayedWithdrawals {\n        uint256 delayedWithdrawalsCompleted;\n        DelayedWithdrawal[] delayedWithdrawals;\n    }\n\n    /**\n     * @notice Creates an delayed withdrawal for `msg.value` to the `recipient`.\n     * @dev Only callable by the `podOwner`'s EigenPod contract.\n     */\n    function createDelayedWithdrawal(address podOwner, address recipient) external payable;\n\n    /**\n     * @notice Called in order to withdraw delayed withdrawals made to the `recipient` that have passed the `withdrawalDelayBlocks` period.\n     * @param recipient The address to claim delayedWithdrawals for.\n     * @param maxNumberOfWithdrawalsToClaim Used to limit the maximum number of withdrawals to loop through claiming.\n     */\n    function claimDelayedWithdrawals(\n        address recipient,\n        uint256 maxNumberOfWithdrawalsToClaim\n    ) external;\n\n    /**\n     * @notice Called in order to withdraw delayed withdrawals made to the caller that have passed the `withdrawalDelayBlocks` period.\n     * @param maxNumberOfWithdrawalsToClaim Used to limit the maximum number of withdrawals to loop through claiming.\n     */\n    function claimDelayedWithdrawals(uint256 maxNumberOfWithdrawalsToClaim) external;\n\n    /// @notice Owner-only function for modifying the value of the `withdrawalDelayBlocks` variable.\n    function setWithdrawalDelayBlocks(uint256 newValue) external;\n\n    /// @notice Getter function for the mapping `_userWithdrawals`\n    function userWithdrawals(address user) external view returns (UserDelayedWithdrawals memory);\n\n    /// @notice Getter function to get all delayedWithdrawals of the `user`\n    function getUserDelayedWithdrawals(\n        address user\n    ) external view returns (DelayedWithdrawal[] memory);\n\n    /// @notice Getter function to get all delayedWithdrawals that are currently claimable by the `user`\n    function getClaimableUserDelayedWithdrawals(\n        address user\n    ) external view returns (DelayedWithdrawal[] memory);\n\n    /// @notice Getter function for fetching the delayedWithdrawal at the `index`th entry from the `_userWithdrawals[user].delayedWithdrawals` array\n    function userDelayedWithdrawalByIndex(\n        address user,\n        uint256 index\n    ) external view returns (DelayedWithdrawal memory);\n\n    /// @notice Getter function for fetching the length of the delayedWithdrawals array of a specific user\n    function userWithdrawalsLength(address user) external view returns (uint256);\n\n    /// @notice Convenience function for checking whether or not the delayedWithdrawal at the `index`th entry from the `_userWithdrawals[user].delayedWithdrawals` array is currently claimable\n    function canClaimDelayedWithdrawal(address user, uint256 index) external view returns (bool);\n\n    /**\n     * @notice Delay enforced by this contract for completing any delayedWithdrawal. Measured in blocks, and adjustable by this contract's owner,\n     * up to a maximum of `MAX_WITHDRAWAL_DELAY_BLOCKS`. Minimum value is 0 (i.e. no delay enforced).\n     */\n    function withdrawalDelayBlocks() external view returns (uint256);\n}\n"
      },
      "contracts/EigenLayer/interfaces/IDelegationManager.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity =0.8.19;\n\nimport \"./IDelegationTerms.sol\";\n\n/**\n * @title The interface for the primary delegation contract for EigenLayer.\n * @author Layr Labs, Inc.\n * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service\n * @notice  This is the contract for delegation in EigenLayer. The main functionalities of this contract are\n * - enabling anyone to register as an operator in EigenLayer\n * - allowing new operators to provide a DelegationTerms-type contract, which may mediate their interactions with stakers who delegate to them\n * - enabling any staker to delegate its stake to the operator of its choice\n * - enabling a staker to undelegate its assets from an operator (performed as part of the withdrawal process, initiated through the StrategyManager)\n */\ninterface IDelegationManager {\n    /**\n     * @notice This will be called by an operator to register itself as an operator that stakers can choose to delegate to.\n     * @param dt is the `DelegationTerms` contract that the operator has for those who delegate to them.\n     * @dev An operator can set `dt` equal to their own address (or another EOA address), in the event that they want to split payments\n     * in a more 'trustful' manner.\n     * @dev In the present design, once set, there is no way for an operator to ever modify the address of their DelegationTerms contract.\n     */\n    function registerAsOperator(IDelegationTerms dt) external;\n\n    /**\n     *  @notice This will be called by a staker to delegate its assets to some operator.\n     *  @param operator is the operator to whom staker (msg.sender) is delegating its assets\n     */\n    function delegateTo(address operator) external;\n\n    /**\n     * @notice Delegates from `staker` to `operator`.\n     * @dev requires that:\n     * 1) if `staker` is an EOA, then `signature` is valid ECDSA signature from `staker`, indicating their intention for this action\n     * 2) if `staker` is a contract, then `signature` must will be checked according to EIP-1271\n     */\n    function delegateToBySignature(\n        address staker,\n        address operator,\n        uint256 expiry,\n        bytes memory signature\n    ) external;\n\n    /**\n     * @notice Undelegates `staker` from the operator who they are delegated to.\n     * @notice Callable only by the StrategyManager\n     * @dev Should only ever be called in the event that the `staker` has no active deposits in EigenLayer.\n     */\n    function undelegate(address staker) external;\n\n    /// @notice returns the address of the operator that `staker` is delegated to.\n    function delegatedTo(address staker) external view returns (address);\n\n    /// @notice returns the DelegationTerms of the `operator`, which may mediate their interactions with stakers who delegate to them.\n    function delegationTerms(address operator) external view returns (IDelegationTerms);\n\n    /// @notice returns the total number of shares in `strategy` that are delegated to `operator`.\n    function operatorShares(address operator, IStrategy strategy) external view returns (uint256);\n\n    /**\n     * @notice Increases the `staker`'s delegated shares in `strategy` by `shares, typically called when the staker has further deposits into EigenLayer\n     * @dev Callable only by the StrategyManager\n     */\n    function increaseDelegatedShares(address staker, IStrategy strategy, uint256 shares) external;\n\n    /**\n     * @notice Decreases the `staker`'s delegated shares in each entry of `strategies` by its respective `shares[i]`, typically called when the staker withdraws from EigenLayer\n     * @dev Callable only by the StrategyManager\n     */\n    function decreaseDelegatedShares(\n        address staker,\n        IStrategy[] calldata strategies,\n        uint256[] calldata shares\n    ) external;\n\n    /// @notice Returns 'true' if `staker` *is* actively delegated, and 'false' otherwise.\n    function isDelegated(address staker) external view returns (bool);\n\n    /// @notice Returns 'true' if `staker` is *not* actively delegated, and 'false' otherwise.\n    function isNotDelegated(address staker) external view returns (bool);\n\n    /// @notice Returns if an operator can be delegated to, i.e. it has called `registerAsOperator`.\n    function isOperator(address operator) external view returns (bool);\n}\n"
      },
      "contracts/EigenLayer/interfaces/IDelegationTerms.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity =0.8.19;\n\nimport \"./IStrategy.sol\";\n\n/**\n * @title Abstract interface for a contract that helps structure the delegation relationship.\n * @author Layr Labs, Inc.\n * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service\n * @notice The gas budget provided to this contract in calls from EigenLayer contracts is limited.\n */\ninterface IDelegationTerms {\n    function payForService(IERC20 token, uint256 amount) external payable;\n\n    function onDelegationWithdrawn(\n        address delegator,\n        IStrategy[] memory stakerStrategyList,\n        uint256[] memory stakerShares\n    ) external returns (bytes memory);\n\n    function onDelegationReceived(\n        address delegator,\n        IStrategy[] memory stakerStrategyList,\n        uint256[] memory stakerShares\n    ) external returns (bytes memory);\n}\n"
      },
      "contracts/EigenLayer/interfaces/IEigenPod.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity =0.8.19;\n\nimport \"../libraries/BeaconChainProofs.sol\";\nimport \"./IEigenPodManager.sol\";\nimport \"./IBeaconChainOracle.sol\";\nimport \"./IDelayedWithdrawalRouter.sol\";\n\n/**\n * @title The implementation contract used for restaking beacon chain ETH on EigenLayer\n * @author Layr Labs, Inc.\n * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service\n * @notice The main functionalities are:\n * - creating new ETH validators with their withdrawal credentials pointed to this contract\n * - proving from beacon chain state roots that withdrawal credentials are pointed to this contract\n * - proving from beacon chain state roots the balances of ETH validators with their withdrawal credentials\n *   pointed to this contract\n * - updating aggregate balances in the EigenPodManager\n * - withdrawing eth when withdrawals are initiated\n * @dev Note that all beacon chain balances are stored as gwei within the beacon chain datastructures. We choose\n *   to account balances in terms of gwei in the EigenPod contract and convert to wei when making calls to other contracts\n */\ninterface IEigenPod {\n    // Hack to allow the external visibility of the public variable for default getter in EigenPod\n    function delayedWithdrawalRouter() external returns (IDelayedWithdrawalRouter);\n\n    enum VALIDATOR_STATUS {\n        INACTIVE, // doesnt exist\n        ACTIVE, // staked on ethpos and withdrawal credentials are pointed to the EigenPod\n        OVERCOMMITTED, // proven to be overcommitted to EigenLayer\n        WITHDRAWN // withdrawn from the Beacon Chain\n    }\n\n    // this struct keeps track of PartialWithdrawalClaims\n    struct PartialWithdrawalClaim {\n        PARTIAL_WITHDRAWAL_CLAIM_STATUS status;\n        // block at which the PartialWithdrawalClaim was created\n        uint32 creationBlockNumber;\n        // last block (inclusive) in which the PartialWithdrawalClaim can be fraudproofed\n        uint32 fraudproofPeriodEndBlockNumber;\n        // amount of ETH -- in Gwei -- to be withdrawn until completion of this claim\n        uint64 partialWithdrawalAmountGwei;\n    }\n\n    enum PARTIAL_WITHDRAWAL_CLAIM_STATUS {\n        REDEEMED,\n        PENDING,\n        FAILED\n    }\n\n    /// @notice The amount of eth, in gwei, that is restaked per validator\n    function REQUIRED_BALANCE_GWEI() external view returns (uint64);\n\n    /// @notice The amount of eth, in wei, that is restaked per validator\n    function REQUIRED_BALANCE_WEI() external view returns (uint256);\n\n    /// @notice this is a mapping of validator indices to a Validator struct containing pertinent info about the validator\n    function validatorStatus(uint40 validatorIndex) external view returns (VALIDATOR_STATUS);\n\n    /// @notice the amount of execution layer ETH in this contract that is staked in EigenLayer (i.e. withdrawn from beaconchain but not EigenLayer),\n    function restakedExecutionLayerGwei() external view returns (uint64);\n\n    /// @notice Used to initialize the pointers to contracts crucial to the pod's functionality, in beacon proxy construction from EigenPodManager\n    function initialize(address owner) external;\n\n    /// @notice Called by EigenPodManager when the owner wants to create another ETH validator.\n    function stake(\n        bytes calldata pubkey,\n        bytes calldata signature,\n        bytes32 depositDataRoot\n    ) external payable;\n\n    /**\n     * @notice Transfers `amountWei` in ether from this contract to the specified `recipient` address\n     * @notice Called by EigenPodManager to withdrawBeaconChainETH that has been added to the EigenPod's balance due to a withdrawal from the beacon chain.\n     * @dev Called during withdrawal or slashing.\n     * @dev Note that this function is marked as non-reentrant to prevent the recipient calling back into it\n     */\n    function withdrawRestakedBeaconChainETH(address recipient, uint256 amount) external;\n\n    /// @notice The single EigenPodManager for EigenLayer\n    function eigenPodManager() external view returns (IEigenPodManager);\n\n    /// @notice The owner of this EigenPod\n    function podOwner() external view returns (address);\n\n    /// @notice an indicator of whether or not the podOwner has ever \"fully restaked\" by successfully calling `verifyCorrectWithdrawalCredentials`.\n    function hasRestaked() external view returns (bool);\n\n    /// @notice block number of the most recent withdrawal\n    function mostRecentWithdrawalBlockNumber() external view returns (uint64);\n\n    ///@notice mapping that tracks proven partial withdrawals\n    function provenPartialWithdrawal(\n        uint40 validatorIndex,\n        uint64 slot\n    ) external view returns (bool);\n\n    /**\n     * @notice This function verifies that the withdrawal credentials of the podOwner are pointed to\n     * this contract. It also verifies the current (not effective) balance  of the validator.  It verifies the provided proof of the ETH validator against the beacon chain state\n     * root, marks the validator as 'active' in EigenLayer, and credits the restaked ETH in Eigenlayer.\n     * @param oracleBlockNumber is the Beacon Chain blockNumber whose state root the `proof` will be proven against.\n     * @param validatorIndex is the index of the validator being proven, refer to consensus specs\n     * @param proofs is the bytes that prove the ETH validator's balance and withdrawal credentials against a beacon chain state root\n     * @param validatorFields are the fields of the \"Validator Container\", refer to consensus specs\n     * for details: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#validator\n     */\n    function verifyWithdrawalCredentialsAndBalance(\n        uint64 oracleBlockNumber,\n        uint40 validatorIndex,\n        BeaconChainProofs.ValidatorFieldsAndBalanceProofs memory proofs,\n        bytes32[] calldata validatorFields\n    ) external;\n\n    /**\n     * @notice This function records an overcommitment of stake to EigenLayer on behalf of a certain ETH validator.\n     *         If successful, the overcommitted balance is penalized (available for withdrawal whenever the pod's balance allows).\n     *         The ETH validator's shares in the enshrined beaconChainETH strategy are also removed from the StrategyManager and undelegated.\n     * @param oracleBlockNumber The oracleBlockNumber whose state root the `proof` will be proven against.\n     *        Must be within `VERIFY_OVERCOMMITTED_WINDOW_BLOCKS` of the current block.\n     * @param validatorIndex is the index of the validator being proven, refer to consensus specs\n     * @param proofs is the proof of the validator's balance and validatorFields in the balance tree and the balanceRoot to prove for\n     * @param beaconChainETHStrategyIndex is the index of the beaconChainETHStrategy for the pod owner for the callback to\n     *                                    the StrategyManager in case it must be removed from the list of the podOwners strategies\n     * @param validatorFields are the fields of the \"Validator Container\", refer to consensus specs\n     * @dev For more details on the Beacon Chain spec, see: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#validator\n     */\n    function verifyOvercommittedStake(\n        uint40 validatorIndex,\n        BeaconChainProofs.ValidatorFieldsAndBalanceProofs calldata proofs,\n        bytes32[] calldata validatorFields,\n        uint256 beaconChainETHStrategyIndex,\n        uint64 oracleBlockNumber\n    ) external;\n\n    /**\n     * @notice This function records a full withdrawal on behalf of one of the Ethereum validators for this EigenPod\n     * @param withdrawalProofs is the information needed to check the veracity of the block number and withdrawal being proven\n     * @param validatorFieldsProof is the proof of the validator's fields in the validator tree\n     * @param withdrawalFields are the fields of the withdrawal being proven\n     * @param validatorFields are the fields of the validator being proven\n     * @param beaconChainETHStrategyIndex is the index of the beaconChainETHStrategy for the pod owner for the callback to\n     *        the EigenPodManager to the StrategyManager in case it must be removed from the podOwner's list of strategies\n     */\n    function verifyAndProcessWithdrawal(\n        BeaconChainProofs.WithdrawalProofs calldata withdrawalProofs,\n        bytes calldata validatorFieldsProof,\n        bytes32[] calldata validatorFields,\n        bytes32[] calldata withdrawalFields,\n        uint256 beaconChainETHStrategyIndex,\n        uint64 oracleBlockNumber\n    ) external;\n\n    /// @notice Called by the pod owner to withdraw the balance of the pod when `hasRestaked` is set to false\n    function withdrawBeforeRestaking() external;\n}\n"
      },
      "contracts/EigenLayer/interfaces/IEigenPodManager.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity =0.8.19;\n\nimport \"./IStrategyManager.sol\";\nimport \"./IEigenPod.sol\";\nimport \"./IBeaconChainOracle.sol\";\nimport \"./IPausable.sol\";\n\n/**\n * @title Interface for factory that creates and manages solo staking pods that have their withdrawal credentials pointed to EigenLayer.\n * @author Layr Labs, Inc.\n * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service\n */\n\ninterface IEigenPodManager is IPausable {\n    /**\n     * @notice Creates an EigenPod for the sender.\n     * @dev Function will revert if the `msg.sender` already has an EigenPod.\n     */\n    function createPod() external;\n\n    /**\n     * @notice Stakes for a new beacon chain validator on the sender's EigenPod.\n     * Also creates an EigenPod for the sender if they don't have one already.\n     * @param pubkey The 48 bytes public key of the beacon chain validator.\n     * @param signature The validator's signature of the deposit data.\n     * @param depositDataRoot The root/hash of the deposit data for the validator's deposit.\n     */\n    function stake(\n        bytes calldata pubkey,\n        bytes calldata signature,\n        bytes32 depositDataRoot\n    ) external payable;\n\n    /**\n     * @notice Deposits/Restakes beacon chain ETH in EigenLayer on behalf of the owner of an EigenPod.\n     * @param podOwner The owner of the pod whose balance must be deposited.\n     * @param amount The amount of ETH to 'deposit' (i.e. be credited to the podOwner).\n     * @dev Callable only by the podOwner's EigenPod contract.\n     */\n    function restakeBeaconChainETH(address podOwner, uint256 amount) external;\n\n    /**\n     * @notice Removes beacon chain ETH from EigenLayer on behalf of the owner of an EigenPod, when the\n     *         balance of a validator is lower than how much stake they have committed to EigenLayer\n     * @param podOwner The owner of the pod whose balance must be removed.\n     * @param beaconChainETHStrategyIndex is the index of the beaconChainETHStrategy for the pod owner for the callback to\n     *                                    the StrategyManager in case it must be removed from the list of the podOwner's strategies\n     * @param amount The amount of ETH to remove.\n     * @dev Callable only by the podOwner's EigenPod contract.\n     */\n    function recordOvercommittedBeaconChainETH(\n        address podOwner,\n        uint256 beaconChainETHStrategyIndex,\n        uint256 amount\n    ) external;\n\n    /**\n     * @notice Withdraws ETH from an EigenPod. The ETH must have first been withdrawn from the beacon chain.\n     * @param podOwner The owner of the pod whose balance must be withdrawn.\n     * @param recipient The recipient of the withdrawn ETH.\n     * @param amount The amount of ETH to withdraw.\n     * @dev Callable only by the StrategyManager contract.\n     */\n    function withdrawRestakedBeaconChainETH(\n        address podOwner,\n        address recipient,\n        uint256 amount\n    ) external;\n\n    /**\n     * @notice Updates the oracle contract that provides the beacon chain state root\n     * @param newBeaconChainOracle is the new oracle contract being pointed to\n     * @dev Callable only by the owner of this contract (i.e. governance)\n     */\n    function updateBeaconChainOracle(IBeaconChainOracle newBeaconChainOracle) external;\n\n    /// @notice Returns the address of the `podOwner`'s EigenPod if it has been deployed.\n    function ownerToPod(address podOwner) external view returns (IEigenPod);\n\n    /// @notice Returns the address of the `podOwner`'s EigenPod (whether it is deployed yet or not).\n    function getPod(address podOwner) external view returns (IEigenPod);\n\n    /// @notice Oracle contract that provides updates to the beacon chain's state\n    function beaconChainOracle() external view returns (IBeaconChainOracle);\n\n    /// @notice Returns the Beacon Chain state root at `blockNumber`. Reverts if the Beacon Chain state root at `blockNumber` has not yet been finalized.\n    function getBeaconChainStateRoot(uint64 blockNumber) external view returns (bytes32);\n\n    /// @notice EigenLayer's StrategyManager contract\n    function strategyManager() external view returns (IStrategyManager);\n\n    /// @notice EigenLayer's Slasher contract\n    function slasher() external view returns (ISlasher);\n\n    function hasPod(address podOwner) external view returns (bool);\n}\n"
      },
      "contracts/EigenLayer/interfaces/IPausable.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity =0.8.19;\n\nimport \"../interfaces/IPauserRegistry.sol\";\n\n/**\n * @title Adds pausability to a contract, with pausing & unpausing controlled by the `pauser` and `unpauser` of a PauserRegistry contract.\n * @author Layr Labs, Inc.\n * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service\n * @notice Contracts that inherit from this contract may define their own `pause` and `unpause` (and/or related) functions.\n * These functions should be permissioned as \"onlyPauser\" which defers to a `PauserRegistry` for determining access control.\n * @dev Pausability is implemented using a uint256, which allows up to 256 different single bit-flags; each bit can potentially pause different functionality.\n * Inspiration for this was taken from the NearBridge design here https://etherscan.io/address/0x3FEFc5A4B1c02f21cBc8D3613643ba0635b9a873#code.\n * For the `pause` and `unpause` functions we've implemented, if you pause, you can only flip (any number of) switches to on/1 (aka \"paused\"), and if you unpause,\n * you can only flip (any number of) switches to off/0 (aka \"paused\").\n * If you want a pauseXYZ function that just flips a single bit / \"pausing flag\", it will:\n * 1) 'bit-wise and' (aka `&`) a flag with the current paused state (as a uint256)\n * 2) update the paused state to this new value\n * @dev We note as well that we have chosen to identify flags by their *bit index* as opposed to their numerical value, so, e.g. defining `DEPOSITS_PAUSED = 3`\n * indicates specifically that if the *third bit* of `_paused` is flipped -- i.e. it is a '1' -- then deposits should be paused\n */\n\ninterface IPausable {\n    /// @notice Address of the `PauserRegistry` contract that this contract defers to for determining access control (for pausing).\n    function pauserRegistry() external view returns (IPauserRegistry);\n\n    /**\n     * @notice This function is used to pause an EigenLayer contract's functionality.\n     * It is permissioned to the `pauser` address, which is expected to be a low threshold multisig.\n     * @param newPausedStatus represents the new value for `_paused` to take, which means it may flip several bits at once.\n     * @dev This function can only pause functionality, and thus cannot 'unflip' any bit in `_paused` from 1 to 0.\n     */\n    function pause(uint256 newPausedStatus) external;\n\n    /**\n     * @notice Alias for `pause(type(uint256).max)`.\n     */\n    function pauseAll() external;\n\n    /**\n     * @notice This function is used to unpause an EigenLayer contract's functionality.\n     * It is permissioned to the `unpauser` address, which is expected to be a high threshold multisig or governance contract.\n     * @param newPausedStatus represents the new value for `_paused` to take, which means it may flip several bits at once.\n     * @dev This function can only unpause functionality, and thus cannot 'flip' any bit in `_paused` from 0 to 1.\n     */\n    function unpause(uint256 newPausedStatus) external;\n\n    /// @notice Returns the current paused status as a uint256.\n    function paused() external view returns (uint256);\n\n    /// @notice Returns 'true' if the `indexed`th bit of `_paused` is 1, and 'false' otherwise\n    function paused(uint8 index) external view returns (bool);\n\n    /// @notice Allows the unpauser to set a new pauser registry\n    function setPauserRegistry(IPauserRegistry newPauserRegistry) external;\n}\n"
      },
      "contracts/EigenLayer/interfaces/IPauserRegistry.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity =0.8.19;\n\n/**\n * @title Interface for the `PauserRegistry` contract.\n * @author Layr Labs, Inc.\n * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service\n */\ninterface IPauserRegistry {\n    /// @notice Mapping of addresses to whether they hold the pauser role.\n    function isPauser(address pauser) external view returns (bool);\n\n    /// @notice Unique address that holds the unpauser role. Capable of changing *both* the pauser and unpauser addresses.\n    function unpauser() external view returns (address);\n}\n"
      },
      "contracts/EigenLayer/interfaces/ISlasher.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity =0.8.19;\n\n/**\n * @title Interface for the primary 'slashing' contract for EigenLayer.\n * @author Layr Labs, Inc.\n * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service\n * @notice See the `Slasher` contract itself for implementation details.\n */\ninterface ISlasher {\n    // struct used to store information about the current state of an operator's obligations to middlewares they are serving\n    struct MiddlewareTimes {\n        // The update block for the middleware whose most recent update was earliest, i.e. the 'stalest' update out of all middlewares the operator is serving\n        uint32 stalestUpdateBlock;\n        // The latest 'serveUntilBlock' from all of the middleware that the operator is serving\n        uint32 latestServeUntilBlock;\n    }\n\n    // struct used to store details relevant to a single middleware that an operator has opted-in to serving\n    struct MiddlewareDetails {\n        // the block before which the contract is allowed to slash the user\n        uint32 contractCanSlashOperatorUntilBlock;\n        // the block at which the middleware's view of the operator's stake was most recently updated\n        uint32 latestUpdateBlock;\n    }\n\n    /**\n     * @notice Gives the `contractAddress` permission to slash the funds of the caller.\n     * @dev Typically, this function must be called prior to registering for a middleware.\n     */\n    function optIntoSlashing(address contractAddress) external;\n\n    /**\n     * @notice Used for 'slashing' a certain operator.\n     * @param toBeFrozen The operator to be frozen.\n     * @dev Technically the operator is 'frozen' (hence the name of this function), and then subject to slashing pending a decision by a human-in-the-loop.\n     * @dev The operator must have previously given the caller (which should be a contract) the ability to slash them, through a call to `optIntoSlashing`.\n     */\n    function freezeOperator(address toBeFrozen) external;\n\n    /**\n     * @notice Removes the 'frozen' status from each of the `frozenAddresses`\n     * @dev Callable only by the contract owner (i.e. governance).\n     */\n    function resetFrozenStatus(address[] calldata frozenAddresses) external;\n\n    /**\n     * @notice this function is a called by middlewares during an operator's registration to make sure the operator's stake at registration\n     *         is slashable until serveUntil\n     * @param operator the operator whose stake update is being recorded\n     * @param serveUntilBlock the block until which the operator's stake at the current block is slashable\n     * @dev adds the middleware's slashing contract to the operator's linked list\n     */\n    function recordFirstStakeUpdate(address operator, uint32 serveUntilBlock) external;\n\n    /**\n     * @notice this function is a called by middlewares during a stake update for an operator (perhaps to free pending withdrawals)\n     *         to make sure the operator's stake at updateBlock is slashable until serveUntil\n     * @param operator the operator whose stake update is being recorded\n     * @param updateBlock the block for which the stake update is being recorded\n     * @param serveUntilBlock the block until which the operator's stake at updateBlock is slashable\n     * @param insertAfter the element of the operators linked list that the currently updating middleware should be inserted after\n     * @dev insertAfter should be calculated offchain before making the transaction that calls this. this is subject to race conditions,\n     *      but it is anticipated to be rare and not detrimental.\n     */\n    function recordStakeUpdate(\n        address operator,\n        uint32 updateBlock,\n        uint32 serveUntilBlock,\n        uint256 insertAfter\n    ) external;\n\n    /**\n     * @notice this function is a called by middlewares during an operator's deregistration to make sure the operator's stake at deregistration\n     *         is slashable until serveUntil\n     * @param operator the operator whose stake update is being recorded\n     * @param serveUntilBlock the block until which the operator's stake at the current block is slashable\n     * @dev removes the middleware's slashing contract to the operator's linked list and revokes the middleware's (i.e. caller's) ability to\n     * slash `operator` once `serveUntil` is reached\n     */\n    function recordLastStakeUpdateAndRevokeSlashingAbility(\n        address operator,\n        uint32 serveUntilBlock\n    ) external;\n\n    /**\n     * @notice Used to determine whether `staker` is actively 'frozen'. If a staker is frozen, then they are potentially subject to\n     * slashing of their funds, and cannot cannot deposit or withdraw from the strategyManager until the slashing process is completed\n     * and the staker's status is reset (to 'unfrozen').\n     * @param staker The staker of interest.\n     * @return Returns 'true' if `staker` themselves has their status set to frozen, OR if the staker is delegated\n     * to an operator who has their status set to frozen. Otherwise returns 'false'.\n     */\n    function isFrozen(address staker) external view returns (bool);\n\n    /// @notice Returns true if `slashingContract` is currently allowed to slash `toBeSlashed`.\n    function canSlash(address toBeSlashed, address slashingContract) external view returns (bool);\n\n    /// @notice Returns the block until which `serviceContract` is allowed to slash the `operator`.\n    function contractCanSlashOperatorUntilBlock(\n        address operator,\n        address serviceContract\n    ) external view returns (uint32);\n\n    /// @notice Returns the block at which the `serviceContract` last updated its view of the `operator`'s stake\n    function latestUpdateBlock(\n        address operator,\n        address serviceContract\n    ) external view returns (uint32);\n\n    /// @notice A search routine for finding the correct input value of `insertAfter` to `recordStakeUpdate` / `_updateMiddlewareList`.\n    function getCorrectValueForInsertAfter(\n        address operator,\n        uint32 updateBlock\n    ) external view returns (uint256);\n\n    /**\n     * @notice Returns 'true' if `operator` can currently complete a withdrawal started at the `withdrawalStartBlock`, with `middlewareTimesIndex` used\n     * to specify the index of a `MiddlewareTimes` struct in the operator's list (i.e. an index in `operatorToMiddlewareTimes[operator]`). The specified\n     * struct is consulted as proof of the `operator`'s ability (or lack thereof) to complete the withdrawal.\n     * This function will return 'false' if the operator cannot currently complete a withdrawal started at the `withdrawalStartBlock`, *or* in the event\n     * that an incorrect `middlewareTimesIndex` is supplied, even if one or more correct inputs exist.\n     * @param operator Either the operator who queued the withdrawal themselves, or if the withdrawing party is a staker who delegated to an operator,\n     * this address is the operator *who the staker was delegated to* at the time of the `withdrawalStartBlock`.\n     * @param withdrawalStartBlock The block number at which the withdrawal was initiated.\n     * @param middlewareTimesIndex Indicates an index in `operatorToMiddlewareTimes[operator]` to consult as proof of the `operator`'s ability to withdraw\n     * @dev The correct `middlewareTimesIndex` input should be computable off-chain.\n     */\n    function canWithdraw(\n        address operator,\n        uint32 withdrawalStartBlock,\n        uint256 middlewareTimesIndex\n    ) external returns (bool);\n\n    /**\n     * operator =>\n     *  [\n     *      (\n     *          the least recent update block of all of the middlewares it's serving/served,\n     *          latest time that the stake bonded at that update needed to serve until\n     *      )\n     *  ]\n     */\n    function operatorToMiddlewareTimes(\n        address operator,\n        uint256 arrayIndex\n    ) external view returns (MiddlewareTimes memory);\n\n    /// @notice Getter function for fetching `operatorToMiddlewareTimes[operator].length`\n    function middlewareTimesLength(address operator) external view returns (uint256);\n\n    /// @notice Getter function for fetching `operatorToMiddlewareTimes[operator][index].stalestUpdateBlock`.\n    function getMiddlewareTimesIndexBlock(\n        address operator,\n        uint32 index\n    ) external view returns (uint32);\n\n    /// @notice Getter function for fetching `operatorToMiddlewareTimes[operator][index].latestServeUntil`.\n    function getMiddlewareTimesIndexServeUntilBlock(\n        address operator,\n        uint32 index\n    ) external view returns (uint32);\n\n    /// @notice Getter function for fetching `_operatorToWhitelistedContractsByUpdate[operator].size`.\n    function operatorWhitelistedContractsLinkedListSize(\n        address operator\n    ) external view returns (uint256);\n\n    /// @notice Getter function for fetching a single node in the operator's linked list (`_operatorToWhitelistedContractsByUpdate[operator]`).\n    function operatorWhitelistedContractsLinkedListEntry(\n        address operator,\n        address node\n    ) external view returns (bool, uint256, uint256);\n}\n"
      },
      "contracts/EigenLayer/interfaces/IStrategy.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity =0.8.19;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/**\n * @title Minimal interface for an `Strategy` contract.\n * @author Layr Labs, Inc.\n * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service\n * @notice Custom `Strategy` implementations may expand extensively on this interface.\n */\ninterface IStrategy {\n    /**\n     * @notice Used to deposit tokens into this Strategy\n     * @param token is the ERC20 token being deposited\n     * @param amount is the amount of token being deposited\n     * @dev This function is only callable by the strategyManager contract. It is invoked inside of the strategyManager's\n     * `depositIntoStrategy` function, and individual share balances are recorded in the strategyManager as well.\n     * @return newShares is the number of new shares issued at the current exchange ratio.\n     */\n    function deposit(IERC20 token, uint256 amount) external returns (uint256);\n\n    /**\n     * @notice Used to withdraw tokens from this Strategy, to the `depositor`'s address\n     * @param depositor is the address to receive the withdrawn funds\n     * @param token is the ERC20 token being transferred out\n     * @param amountShares is the amount of shares being withdrawn\n     * @dev This function is only callable by the strategyManager contract. It is invoked inside of the strategyManager's\n     * other functions, and individual share balances are recorded in the strategyManager as well.\n     */\n    function withdraw(address depositor, IERC20 token, uint256 amountShares) external;\n\n    /**\n     * @notice Used to convert a number of shares to the equivalent amount of underlying tokens for this strategy.\n     * @notice In contrast to `sharesToUnderlyingView`, this function **may** make state modifications\n     * @param amountShares is the amount of shares to calculate its conversion into the underlying token\n     * @return The amount of underlying tokens corresponding to the input `amountShares`\n     * @dev Implementation for these functions in particular may vary significantly for different strategies\n     */\n    function sharesToUnderlying(uint256 amountShares) external returns (uint256);\n\n    /**\n     * @notice Used to convert an amount of underlying tokens to the equivalent amount of shares in this strategy.\n     * @notice In contrast to `underlyingToSharesView`, this function **may** make state modifications\n     * @param amountUnderlying is the amount of `underlyingToken` to calculate its conversion into strategy shares\n     * @return The amount of underlying tokens corresponding to the input `amountShares`\n     * @dev Implementation for these functions in particular may vary significantly for different strategies\n     */\n    function underlyingToShares(uint256 amountUnderlying) external returns (uint256);\n\n    /**\n     * @notice convenience function for fetching the current underlying value of all of the `user`'s shares in\n     * this strategy. In contrast to `userUnderlyingView`, this function **may** make state modifications\n     */\n    function userUnderlying(address user) external returns (uint256);\n\n    /**\n     * @notice Used to convert a number of shares to the equivalent amount of underlying tokens for this strategy.\n     * @notice In contrast to `sharesToUnderlying`, this function guarantees no state modifications\n     * @param amountShares is the amount of shares to calculate its conversion into the underlying token\n     * @return The amount of shares corresponding to the input `amountUnderlying`\n     * @dev Implementation for these functions in particular may vary significantly for different strategies\n     */\n    function sharesToUnderlyingView(uint256 amountShares) external view returns (uint256);\n\n    /**\n     * @notice Used to convert an amount of underlying tokens to the equivalent amount of shares in this strategy.\n     * @notice In contrast to `underlyingToShares`, this function guarantees no state modifications\n     * @param amountUnderlying is the amount of `underlyingToken` to calculate its conversion into strategy shares\n     * @return The amount of shares corresponding to the input `amountUnderlying`\n     * @dev Implementation for these functions in particular may vary significantly for different strategies\n     */\n    function underlyingToSharesView(uint256 amountUnderlying) external view returns (uint256);\n\n    /**\n     * @notice convenience function for fetching the current underlying value of all of the `user`'s shares in\n     * this strategy. In contrast to `userUnderlying`, this function guarantees no state modifications\n     */\n    function userUnderlyingView(address user) external view returns (uint256);\n\n    /// @notice The underlying token for shares in this Strategy\n    function underlyingToken() external view returns (IERC20);\n\n    /// @notice The total number of extant shares in this Strategy\n    function totalShares() external view returns (uint256);\n\n    /// @notice Returns either a brief string explaining the strategy's goal & purpose, or a link to metadata that explains in more detail.\n    function explanation() external view returns (string memory);\n}\n"
      },
      "contracts/EigenLayer/interfaces/IStrategyManager.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity =0.8.19;\n\nimport \"./IStrategy.sol\";\nimport \"./ISlasher.sol\";\nimport \"./IDelegationManager.sol\";\n\n/**\n * @title Interface for the primary entrypoint for funds into EigenLayer.\n * @author Layr Labs, Inc.\n * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service\n * @notice See the `StrategyManager` contract itself for implementation details.\n */\ninterface IStrategyManager {\n    // Access to public vars - hack locally\n    function stakerStrategyList(address staker, uint256 index) external view returns (IStrategy);\n    function numWithdrawalsQueued(address staker) external view returns (uint256);\n\n    // packed struct for queued withdrawals; helps deal with stack-too-deep errors\n    struct WithdrawerAndNonce {\n        address withdrawer;\n        uint96 nonce;\n    }\n\n    /**\n     * Struct type used to specify an existing queued withdrawal. Rather than storing the entire struct, only a hash is stored.\n     * In functions that operate on existing queued withdrawals -- e.g. `startQueuedWithdrawalWaitingPeriod` or `completeQueuedWithdrawal`,\n     * the data is resubmitted and the hash of the submitted data is computed by `calculateWithdrawalRoot` and checked against the\n     * stored hash in order to confirm the integrity of the submitted data.\n     */\n    struct QueuedWithdrawal {\n        IStrategy[] strategies;\n        uint256[] shares;\n        address depositor;\n        WithdrawerAndNonce withdrawerAndNonce;\n        uint32 withdrawalStartBlock;\n        address delegatedAddress;\n    }\n\n    /**\n     * @notice Deposits `amount` of `token` into the specified `strategy`, with the resultant shares credited to `msg.sender`\n     * @param strategy is the specified strategy where deposit is to be made,\n     * @param token is the denomination in which the deposit is to be made,\n     * @param amount is the amount of token to be deposited in the strategy by the depositor\n     * @return shares The amount of new shares in the `strategy` created as part of the action.\n     * @dev The `msg.sender` must have previously approved this contract to transfer at least `amount` of `token` on their behalf.\n     * @dev Cannot be called by an address that is 'frozen' (this function will revert if the `msg.sender` is frozen).\n     *\n     * WARNING: Depositing tokens that allow reentrancy (eg. ERC-777) into a strategy is not recommended.  This can lead to attack vectors\n     *          where the token balance and corresponding strategy shares are not in sync upon reentrancy.\n     */\n    function depositIntoStrategy(\n        IStrategy strategy,\n        IERC20 token,\n        uint256 amount\n    ) external returns (uint256 shares);\n\n    /**\n     * @notice Deposits `amount` of beaconchain ETH into this contract on behalf of `staker`\n     * @param staker is the entity that is restaking in eigenlayer,\n     * @param amount is the amount of beaconchain ETH being restaked,\n     * @dev Only callable by EigenPodManager.\n     */\n    function depositBeaconChainETH(address staker, uint256 amount) external;\n\n    /**\n     * @notice Records an overcommitment event on behalf of a staker. The staker's beaconChainETH shares are decremented by `amount`.\n     * @param overcommittedPodOwner is the pod owner to be slashed\n     * @param beaconChainETHStrategyIndex is the index of the beaconChainETHStrategy in case it must be removed,\n     * @param amount is the amount to decrement the slashedAddress's beaconChainETHStrategy shares\n     * @dev Only callable by EigenPodManager.\n     */\n    function recordOvercommittedBeaconChainETH(\n        address overcommittedPodOwner,\n        uint256 beaconChainETHStrategyIndex,\n        uint256 amount\n    ) external;\n\n    /**\n     * @notice Used for depositing an asset into the specified strategy with the resultant shares credited to `staker`,\n     * who must sign off on the action.\n     * Note that the assets are transferred out/from the `msg.sender`, not from the `staker`; this function is explicitly designed\n     * purely to help one address deposit 'for' another.\n     * @param strategy is the specified strategy where deposit is to be made,\n     * @param token is the denomination in which the deposit is to be made,\n     * @param amount is the amount of token to be deposited in the strategy by the depositor\n     * @param staker the staker that the deposited assets will be credited to\n     * @param expiry the timestamp at which the signature expires\n     * @param signature is a valid signature from the `staker`. either an ECDSA signature if the `staker` is an EOA, or data to forward\n     * following EIP-1271 if the `staker` is a contract\n     * @return shares The amount of new shares in the `strategy` created as part of the action.\n     * @dev The `msg.sender` must have previously approved this contract to transfer at least `amount` of `token` on their behalf.\n     * @dev A signature is required for this function to eliminate the possibility of griefing attacks, specifically those\n     * targeting stakers who may be attempting to undelegate.\n     * @dev Cannot be called on behalf of a staker that is 'frozen' (this function will revert if the `staker` is frozen).\n     *\n     *  WARNING: Depositing tokens that allow reentrancy (eg. ERC-777) into a strategy is not recommended.  This can lead to attack vectors\n     *          where the token balance and corresponding strategy shares are not in sync upon reentrancy\n     */\n    function depositIntoStrategyWithSignature(\n        IStrategy strategy,\n        IERC20 token,\n        uint256 amount,\n        address staker,\n        uint256 expiry,\n        bytes memory signature\n    ) external returns (uint256 shares);\n\n    /// @notice Returns the current shares of `user` in `strategy`\n    function stakerStrategyShares(\n        address user,\n        IStrategy strategy\n    ) external view returns (uint256 shares);\n\n    /**\n     * @notice Get all details on the depositor's deposits and corresponding shares\n     * @return (depositor's strategies, shares in these strategies)\n     */\n    function getDeposits(\n        address depositor\n    ) external view returns (IStrategy[] memory, uint256[] memory);\n\n    /// @notice Simple getter function that returns `stakerStrategyList[staker].length`.\n    function stakerStrategyListLength(address staker) external view returns (uint256);\n\n    /**\n     * @notice Called by a staker to queue a withdrawal of the given amount of `shares` from each of the respective given `strategies`.\n     * @dev Stakers will complete their withdrawal by calling the 'completeQueuedWithdrawal' function.\n     * User shares are decreased in this function, but the total number of shares in each strategy remains the same.\n     * The total number of shares is decremented in the 'completeQueuedWithdrawal' function instead, which is where\n     * the funds are actually sent to the user through use of the strategies' 'withdrawal' function. This ensures\n     * that the value per share reported by each strategy will remain consistent, and that the shares will continue\n     * to accrue gains during the enforced withdrawal waiting period.\n     * @param strategyIndexes is a list of the indices in `stakerStrategyList[msg.sender]` that correspond to the strategies\n     * for which `msg.sender` is withdrawing 100% of their shares\n     * @param strategies The Strategies to withdraw from\n     * @param shares The amount of shares to withdraw from each of the respective Strategies in the `strategies` array\n     * @param withdrawer The address that can complete the withdrawal and will receive any withdrawn funds or shares upon completing the withdrawal\n     * @param undelegateIfPossible If this param is marked as 'true' *and the withdrawal will result in `msg.sender` having no shares in any Strategy,*\n     * then this function will also make an internal call to `undelegate(msg.sender)` to undelegate the `msg.sender`.\n     * @return The 'withdrawalRoot' of the newly created Queued Withdrawal\n     * @dev Strategies are removed from `stakerStrategyList` by swapping the last entry with the entry to be removed, then\n     * popping off the last entry in `stakerStrategyList`. The simplest way to calculate the correct `strategyIndexes` to input\n     * is to order the strategies *for which `msg.sender` is withdrawing 100% of their shares* from highest index in\n     * `stakerStrategyList` to lowest index\n     * @dev Note that if the withdrawal includes shares in the enshrined 'beaconChainETH' strategy, then it must *only* include shares in this strategy, and\n     * `withdrawer` must match the caller's address. The first condition is because slashing of queued withdrawals cannot be guaranteed\n     * for Beacon Chain ETH (since we cannot trigger a withdrawal from the beacon chain through a smart contract) and the second condition is because shares in\n     * the enshrined 'beaconChainETH' strategy technically represent non-fungible positions (deposits to the Beacon Chain, each pointed at a specific EigenPod).\n     */\n    function queueWithdrawal(\n        uint256[] calldata strategyIndexes,\n        IStrategy[] calldata strategies,\n        uint256[] calldata shares,\n        address withdrawer,\n        bool undelegateIfPossible\n    ) external returns (bytes32);\n\n    /**\n     * @notice Used to complete the specified `queuedWithdrawal`. The function caller must match `queuedWithdrawal.withdrawer`\n     * @param queuedWithdrawal The QueuedWithdrawal to complete.\n     * @param tokens Array in which the i-th entry specifies the `token` input to the 'withdraw' function of the i-th Strategy in the `strategies` array\n     * of the `queuedWithdrawal`. This input can be provided with zero length if `receiveAsTokens` is set to 'false' (since in that case, this input will be unused)\n     * @param middlewareTimesIndex is the index in the operator that the staker who triggered the withdrawal was delegated to's middleware times array\n     * @param receiveAsTokens If true, the shares specified in the queued withdrawal will be withdrawn from the specified strategies themselves\n     * and sent to the caller, through calls to `queuedWithdrawal.strategies[i].withdraw`. If false, then the shares in the specified strategies\n     * will simply be transferred to the caller directly.\n     * @dev middlewareTimesIndex should be calculated off chain before calling this function by finding the first index that satisfies `slasher.canWithdraw`\n     */\n    function completeQueuedWithdrawal(\n        QueuedWithdrawal calldata queuedWithdrawal,\n        IERC20[] calldata tokens,\n        uint256 middlewareTimesIndex,\n        bool receiveAsTokens\n    ) external;\n\n    /**\n     * @notice Used to complete the specified `queuedWithdrawals`. The function caller must match `queuedWithdrawals[...].withdrawer`\n     * @param queuedWithdrawals The QueuedWithdrawals to complete.\n     * @param tokens Array of tokens for each QueuedWithdrawal. See `completeQueuedWithdrawal` for the usage of a single array.\n     * @param middlewareTimesIndexes One index to reference per QueuedWithdrawal. See `completeQueuedWithdrawal` for the usage of a single index.\n     * @param receiveAsTokens If true, the shares specified in the queued withdrawal will be withdrawn from the specified strategies themselves\n     * and sent to the caller, through calls to `queuedWithdrawal.strategies[i].withdraw`. If false, then the shares in the specified strategies\n     * will simply be transferred to the caller directly.\n     * @dev Array-ified version of `completeQueuedWithdrawal`\n     * @dev middlewareTimesIndex should be calculated off chain before calling this function by finding the first index that satisfies `slasher.canWithdraw`\n     */\n    function completeQueuedWithdrawals(\n        QueuedWithdrawal[] calldata queuedWithdrawals,\n        IERC20[][] calldata tokens,\n        uint256[] calldata middlewareTimesIndexes,\n        bool[] calldata receiveAsTokens\n    ) external;\n\n    /**\n     * @notice Slashes the shares of a 'frozen' operator (or a staker delegated to one)\n     * @param slashedAddress is the frozen address that is having its shares slashed\n     * @param recipient is the address that will receive the slashed funds, which could e.g. be a harmed party themself,\n     * or a MerkleDistributor-type contract that further sub-divides the slashed funds.\n     * @param strategies Strategies to slash\n     * @param shareAmounts The amount of shares to slash in each of the provided `strategies`\n     * @param tokens The tokens to use as input to the `withdraw` function of each of the provided `strategies`\n     * @param strategyIndexes is a list of the indices in `stakerStrategyList[msg.sender]` that correspond to the strategies\n     * for which `msg.sender` is withdrawing 100% of their shares\n     * @param recipient The slashed funds are withdrawn as tokens to this address.\n     * @dev strategies are removed from `stakerStrategyList` by swapping the last entry with the entry to be removed, then\n     * popping off the last entry in `stakerStrategyList`. The simplest way to calculate the correct `strategyIndexes` to input\n     * is to order the strategies *for which `msg.sender` is withdrawing 100% of their shares* from highest index in\n     * `stakerStrategyList` to lowest index\n     */\n    function slashShares(\n        address slashedAddress,\n        address recipient,\n        IStrategy[] calldata strategies,\n        IERC20[] calldata tokens,\n        uint256[] calldata strategyIndexes,\n        uint256[] calldata shareAmounts\n    ) external;\n\n    /**\n     * @notice Slashes an existing queued withdrawal that was created by a 'frozen' operator (or a staker delegated to one)\n     * @param recipient The funds in the slashed withdrawal are withdrawn as tokens to this address.\n     * @param queuedWithdrawal The previously queued withdrawal to be slashed\n     * @param tokens Array in which the i-th entry specifies the `token` input to the 'withdraw' function of the i-th Strategy in the `strategies`\n     * array of the `queuedWithdrawal`.\n     * @param indicesToSkip Optional input parameter -- indices in the `strategies` array to skip (i.e. not call the 'withdraw' function on). This input exists\n     * so that, e.g., if the slashed QueuedWithdrawal contains a malicious strategy in the `strategies` array which always reverts on calls to its 'withdraw' function,\n     * then the malicious strategy can be skipped (with the shares in effect \"burned\"), while the non-malicious strategies are still called as normal.\n     */\n    function slashQueuedWithdrawal(\n        address recipient,\n        QueuedWithdrawal calldata queuedWithdrawal,\n        IERC20[] calldata tokens,\n        uint256[] calldata indicesToSkip\n    ) external;\n\n    /// @notice Returns the keccak256 hash of `queuedWithdrawal`.\n    function calculateWithdrawalRoot(\n        QueuedWithdrawal memory queuedWithdrawal\n    ) external pure returns (bytes32);\n\n    /**\n     * @notice Owner-only function that adds the provided Strategies to the 'whitelist' of strategies that stakers can deposit into\n     * @param strategiesToWhitelist Strategies that will be added to the `strategyIsWhitelistedForDeposit` mapping (if they aren't in it already)\n     */\n    function addStrategiesToDepositWhitelist(IStrategy[] calldata strategiesToWhitelist) external;\n\n    /**\n     * @notice Owner-only function that removes the provided Strategies from the 'whitelist' of strategies that stakers can deposit into\n     * @param strategiesToRemoveFromWhitelist Strategies that will be removed to the `strategyIsWhitelistedForDeposit` mapping (if they are in it)\n     */\n    function removeStrategiesFromDepositWhitelist(\n        IStrategy[] calldata strategiesToRemoveFromWhitelist\n    ) external;\n\n    /// @notice Returns the single, central Delegation contract of EigenLayer\n    function delegation() external view returns (IDelegationManager);\n\n    /// @notice Returns the single, central Slasher contract of EigenLayer\n    function slasher() external view returns (ISlasher);\n\n    /// @notice returns the enshrined, virtual 'beaconChainETH' Strategy\n    function beaconChainETHStrategy() external view returns (IStrategy);\n\n    /// @notice Returns the number of blocks that must pass between the time a withdrawal is queued and the time it can be completed\n    function withdrawalDelayBlocks() external view returns (uint256);\n}\n"
      },
      "contracts/EigenLayer/libraries/BeaconChainProofs.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity =0.8.19;\n\nimport \"./Merkle.sol\";\nimport \"../libraries/Endian.sol\";\n\n//Utility library for parsing and PHASE0 beacon chain block headers\n//SSZ Spec: https://github.com/ethereum/consensus-specs/blob/dev/ssz/simple-serialize.md#merkleization\n//BeaconBlockHeader Spec: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#beaconblockheader\n//BeaconState Spec: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#beaconstate\nlibrary BeaconChainProofs {\n    // constants are the number of fields and the heights of the different merkle trees used in merkleizing beacon chain containers\n    uint256 internal constant NUM_BEACON_BLOCK_HEADER_FIELDS = 5;\n    uint256 internal constant BEACON_BLOCK_HEADER_FIELD_TREE_HEIGHT = 3;\n\n    uint256 internal constant NUM_BEACON_BLOCK_BODY_FIELDS = 11;\n    uint256 internal constant BEACON_BLOCK_BODY_FIELD_TREE_HEIGHT = 4;\n\n    uint256 internal constant NUM_BEACON_STATE_FIELDS = 21;\n    uint256 internal constant BEACON_STATE_FIELD_TREE_HEIGHT = 5;\n\n    uint256 internal constant NUM_ETH1_DATA_FIELDS = 3;\n    uint256 internal constant ETH1_DATA_FIELD_TREE_HEIGHT = 2;\n\n    uint256 internal constant NUM_VALIDATOR_FIELDS = 8;\n    uint256 internal constant VALIDATOR_FIELD_TREE_HEIGHT = 3;\n\n    uint256 internal constant NUM_EXECUTION_PAYLOAD_HEADER_FIELDS = 15;\n    uint256 internal constant EXECUTION_PAYLOAD_HEADER_FIELD_TREE_HEIGHT = 4;\n\n    uint256 internal constant NUM_EXECUTION_PAYLOAD_FIELDS = 15;\n    uint256 internal constant EXECUTION_PAYLOAD_FIELD_TREE_HEIGHT = 4;\n\n    // HISTORICAL_ROOTS_LIMIT\t = 2**24, so tree height is 24\n    uint256 internal constant HISTORICAL_ROOTS_TREE_HEIGHT = 24;\n\n    // HISTORICAL_BATCH is root of state_roots and block_root, so number of leaves =  2^1\n    uint256 internal constant HISTORICAL_BATCH_TREE_HEIGHT = 1;\n\n    // SLOTS_PER_HISTORICAL_ROOT = 2**13, so tree height is 13\n    uint256 internal constant STATE_ROOTS_TREE_HEIGHT = 13;\n    uint256 internal constant BLOCK_ROOTS_TREE_HEIGHT = 13;\n\n    uint256 internal constant NUM_WITHDRAWAL_FIELDS = 4;\n    // tree height for hash tree of an individual withdrawal container\n    uint256 internal constant WITHDRAWAL_FIELD_TREE_HEIGHT = 2;\n\n    uint256 internal constant VALIDATOR_TREE_HEIGHT = 40;\n    //refer to the eigenlayer-cli proof library.  Despite being the same dimensions as the validator tree, the balance tree is merkleized differently\n    uint256 internal constant BALANCE_TREE_HEIGHT = 38;\n\n    // MAX_WITHDRAWALS_PER_PAYLOAD = 2**4, making tree height = 4\n    uint256 internal constant WITHDRAWALS_TREE_HEIGHT = 4;\n\n    //in beacon block body\n    uint256 internal constant EXECUTION_PAYLOAD_INDEX = 9;\n\n    // in beacon block header\n    uint256 internal constant STATE_ROOT_INDEX = 3;\n    uint256 internal constant PROPOSER_INDEX_INDEX = 1;\n    uint256 internal constant SLOT_INDEX = 0;\n    uint256 internal constant BODY_ROOT_INDEX = 4;\n    // in beacon state\n    uint256 internal constant STATE_ROOTS_INDEX = 6;\n    uint256 internal constant BLOCK_ROOTS_INDEX = 5;\n    uint256 internal constant HISTORICAL_ROOTS_INDEX = 7;\n    uint256 internal constant ETH_1_ROOT_INDEX = 8;\n    uint256 internal constant VALIDATOR_TREE_ROOT_INDEX = 11;\n    uint256 internal constant BALANCE_INDEX = 12;\n    uint256 internal constant EXECUTION_PAYLOAD_HEADER_INDEX = 24;\n    uint256 internal constant HISTORICAL_BATCH_STATE_ROOT_INDEX = 1;\n\n    // in validator\n    uint256 internal constant VALIDATOR_WITHDRAWAL_CREDENTIALS_INDEX = 1;\n    uint256 internal constant VALIDATOR_BALANCE_INDEX = 2;\n    uint256 internal constant VALIDATOR_SLASHED_INDEX = 3;\n    uint256 internal constant VALIDATOR_WITHDRAWABLE_EPOCH_INDEX = 7;\n\n    // in execution payload header\n    uint256 internal constant BLOCK_NUMBER_INDEX = 6;\n    uint256 internal constant WITHDRAWALS_ROOT_INDEX = 14;\n\n    //in execution payload\n    uint256 internal constant WITHDRAWALS_INDEX = 14;\n\n    // in withdrawal\n    uint256 internal constant WITHDRAWAL_VALIDATOR_INDEX_INDEX = 1;\n    uint256 internal constant WITHDRAWAL_VALIDATOR_AMOUNT_INDEX = 3;\n\n    //In historicalBatch\n    uint256 internal constant HISTORICALBATCH_STATEROOTS_INDEX = 1;\n\n    //Misc Constants\n    uint256 internal constant SLOTS_PER_EPOCH = 32;\n\n    bytes8 internal constant UINT64_MASK = 0xffffffffffffffff;\n\n    struct WithdrawalProofs {\n        bytes blockHeaderProof;\n        bytes withdrawalProof;\n        bytes slotProof;\n        bytes executionPayloadProof;\n        bytes blockNumberProof;\n        uint64 blockHeaderRootIndex;\n        uint64 withdrawalIndex;\n        bytes32 blockHeaderRoot;\n        bytes32 blockBodyRoot;\n        bytes32 slotRoot;\n        bytes32 blockNumberRoot;\n        bytes32 executionPayloadRoot;\n    }\n\n    struct ValidatorFieldsAndBalanceProofs {\n        bytes validatorFieldsProof;\n        bytes validatorBalanceProof;\n        bytes32 balanceRoot;\n    }\n\n    struct ValidatorFieldsProof {\n        bytes validatorProof;\n        uint40 validatorIndex;\n    }\n\n    /**\n     *\n     * @notice This function is parses the balanceRoot to get the uint64 balance of a validator.  During merkleization of the\n     * beacon state balance tree, four uint64 values (making 32 bytes) are grouped together and treated as a single leaf in the merkle tree. Thus the\n     * validatorIndex mod 4 is used to determine which of the four uint64 values to extract from the balanceRoot.\n     * @param validatorIndex is the index of the validator being proven for.\n     * @param balanceRoot is the combination of 4 validator balances being proven for.\n     * @return The validator's balance, in Gwei\n     */\n    function getBalanceFromBalanceRoot(\n        uint40 validatorIndex,\n        bytes32 balanceRoot\n    ) internal pure returns (uint64) {\n        uint256 bitShiftAmount = (validatorIndex % 4) * 64;\n        bytes32 validatorBalanceLittleEndian = bytes32((uint256(balanceRoot) << bitShiftAmount));\n        uint64 validatorBalance = Endian.fromLittleEndianUint64(validatorBalanceLittleEndian);\n        return validatorBalance;\n    }\n\n    /**\n     * @notice This function verifies merkle proofs of the fields of a certain validator against a beacon chain state root\n     * @param validatorIndex the index of the proven validator\n     * @param beaconStateRoot is the beacon chain state root to be proven against.\n     * @param proof is the data used in proving the validator's fields\n     * @param validatorFields the claimed fields of the validator\n     */\n    function verifyValidatorFields(\n        uint40 validatorIndex,\n        bytes32 beaconStateRoot,\n        bytes calldata proof,\n        bytes32[] calldata validatorFields\n    ) internal view {\n        require(\n            validatorFields.length == 2 ** VALIDATOR_FIELD_TREE_HEIGHT,\n            \"BeaconChainProofs.verifyValidatorFields: Validator fields has incorrect length\"\n        );\n\n        /**\n         * Note: the length of the validator merkle proof is BeaconChainProofs.VALIDATOR_TREE_HEIGHT + 1.\n         * There is an additional layer added by hashing the root with the length of the validator list\n         */\n        require(\n            proof.length == 32 * ((VALIDATOR_TREE_HEIGHT + 1) + BEACON_STATE_FIELD_TREE_HEIGHT),\n            \"BeaconChainProofs.verifyValidatorFields: Proof has incorrect length\"\n        );\n        uint256 index = (VALIDATOR_TREE_ROOT_INDEX << (VALIDATOR_TREE_HEIGHT + 1)) |\n            uint256(validatorIndex);\n        // merkleize the validatorFields to get the leaf to prove\n        bytes32 validatorRoot = Merkle.merkleizeSha256(validatorFields);\n\n        // verify the proof of the validatorRoot against the beaconStateRoot\n        require(\n            Merkle.verifyInclusionSha256(proof, beaconStateRoot, validatorRoot, index),\n            \"BeaconChainProofs.verifyValidatorFields: Invalid merkle proof\"\n        );\n    }\n\n    /**\n     * @notice This function verifies merkle proofs of the balance of a certain validator against a beacon chain state root\n     * @param validatorIndex the index of the proven validator\n     * @param beaconStateRoot is the beacon chain state root to be proven against.\n     * @param proof is the proof of the balance against the beacon chain state root\n     * @param balanceRoot is the serialized balance used to prove the balance of the validator (refer to `getBalanceFromBalanceRoot` above for detailed explanation)\n     */\n    function verifyValidatorBalance(\n        uint40 validatorIndex,\n        bytes32 beaconStateRoot,\n        bytes calldata proof,\n        bytes32 balanceRoot\n    ) internal view {\n        require(\n            proof.length == 32 * ((BALANCE_TREE_HEIGHT + 1) + BEACON_STATE_FIELD_TREE_HEIGHT),\n            \"BeaconChainProofs.verifyValidatorBalance: Proof has incorrect length\"\n        );\n\n        /**\n         * the beacon state's balance list is a list of uint64 values, and these are grouped together in 4s when merkleized.\n         * Therefore, the index of the balance of a validator is validatorIndex/4\n         */\n        uint256 balanceIndex = uint256(validatorIndex / 4);\n        balanceIndex = (BALANCE_INDEX << (BALANCE_TREE_HEIGHT + 1)) | balanceIndex;\n\n        require(\n            Merkle.verifyInclusionSha256(proof, beaconStateRoot, balanceRoot, balanceIndex),\n            \"BeaconChainProofs.verifyValidatorBalance: Invalid merkle proof\"\n        );\n    }\n\n    /**\n     * @notice This function verifies the slot and the withdrawal fields for a given withdrawal\n     * @param beaconStateRoot is the beacon chain state root to be proven against.\n     * @param proofs is the provided set of merkle proofs\n     * @param withdrawalFields is the serialized withdrawal container to be proven\n     */\n    function verifyWithdrawalProofs(\n        bytes32 beaconStateRoot,\n        WithdrawalProofs calldata proofs,\n        bytes32[] calldata withdrawalFields\n    ) internal view {\n        require(\n            withdrawalFields.length == 2 ** WITHDRAWAL_FIELD_TREE_HEIGHT,\n            \"BeaconChainProofs.verifyWithdrawalProofs: withdrawalFields has incorrect length\"\n        );\n\n        require(\n            proofs.blockHeaderRootIndex < 2 ** BLOCK_ROOTS_TREE_HEIGHT,\n            \"BeaconChainProofs.verifyWithdrawalProofs: blockRootIndex is too large\"\n        );\n        require(\n            proofs.withdrawalIndex < 2 ** WITHDRAWALS_TREE_HEIGHT,\n            \"BeaconChainProofs.verifyWithdrawalProofs: withdrawalIndex is too large\"\n        );\n\n        // verify the block header proof length\n        require(\n            proofs.blockHeaderProof.length ==\n                32 * (BEACON_STATE_FIELD_TREE_HEIGHT + BLOCK_ROOTS_TREE_HEIGHT),\n            \"BeaconChainProofs.verifyWithdrawalProofs: blockHeaderProof has incorrect length\"\n        );\n        require(\n            proofs.withdrawalProof.length ==\n                32 * (EXECUTION_PAYLOAD_HEADER_FIELD_TREE_HEIGHT + WITHDRAWALS_TREE_HEIGHT + 1),\n            \"BeaconChainProofs.verifyWithdrawalProofs: withdrawalProof has incorrect length\"\n        );\n        require(\n            proofs.executionPayloadProof.length ==\n                32 * (BEACON_BLOCK_HEADER_FIELD_TREE_HEIGHT + BEACON_BLOCK_BODY_FIELD_TREE_HEIGHT),\n            \"BeaconChainProofs.verifyWithdrawalProofs: executionPayloadProof has incorrect length\"\n        );\n        require(\n            proofs.slotProof.length == 32 * (BEACON_BLOCK_HEADER_FIELD_TREE_HEIGHT),\n            \"BeaconChainProofs.verifyWithdrawalProofs: slotProof has incorrect length\"\n        );\n        require(\n            proofs.blockNumberProof.length == 32 * (EXECUTION_PAYLOAD_HEADER_FIELD_TREE_HEIGHT),\n            \"BeaconChainProofs.verifyWithdrawalProofs: blockNumberProof has incorrect length\"\n        );\n\n        /**\n         * Computes the block_header_index relative to the beaconStateRoot.  It concatenates the indexes of all the\n         * intermediate root indexes from the bottom of the sub trees (the block header container) to the top of the tree\n         */\n        uint256 blockHeaderIndex = (BLOCK_ROOTS_INDEX << (BLOCK_ROOTS_TREE_HEIGHT)) |\n            uint256(proofs.blockHeaderRootIndex);\n        // Verify the blockHeaderRoot against the beaconStateRoot\n        require(\n            Merkle.verifyInclusionSha256(\n                proofs.blockHeaderProof,\n                beaconStateRoot,\n                proofs.blockHeaderRoot,\n                blockHeaderIndex\n            ),\n            \"BeaconChainProofs.verifyWithdrawalProofs: Invalid block header merkle proof\"\n        );\n\n        //Next we verify the slot against the blockHeaderRoot\n        require(\n            Merkle.verifyInclusionSha256(\n                proofs.slotProof,\n                proofs.blockHeaderRoot,\n                proofs.slotRoot,\n                SLOT_INDEX\n            ),\n            \"BeaconChainProofs.verifyWithdrawalProofs: Invalid slot merkle proof\"\n        );\n\n        // Next we verify the executionPayloadRoot against the blockHeaderRoot\n        uint256 executionPayloadIndex = (BODY_ROOT_INDEX << (BEACON_BLOCK_BODY_FIELD_TREE_HEIGHT)) |\n            EXECUTION_PAYLOAD_INDEX;\n        require(\n            Merkle.verifyInclusionSha256(\n                proofs.executionPayloadProof,\n                proofs.blockHeaderRoot,\n                proofs.executionPayloadRoot,\n                executionPayloadIndex\n            ),\n            \"BeaconChainProofs.verifyWithdrawalProofs: Invalid executionPayload merkle proof\"\n        );\n\n        // Next we verify the blockNumberRoot against the executionPayload root\n        require(\n            Merkle.verifyInclusionSha256(\n                proofs.blockNumberProof,\n                proofs.executionPayloadRoot,\n                proofs.blockNumberRoot,\n                BLOCK_NUMBER_INDEX\n            ),\n            \"BeaconChainProofs.verifyWithdrawalProofs: Invalid blockNumber merkle proof\"\n        );\n\n        /**\n         * Next we verify the withdrawal fields against the blockHeaderRoot:\n         * First we compute the withdrawal_index relative to the blockHeaderRoot by concatenating the indexes of all the\n         * intermediate root indexes from the bottom of the sub trees (the withdrawal container) to the top, the blockHeaderRoot.\n         * Then we calculate merkleize the withdrawalFields container to calculate the the withdrawalRoot.\n         * Finally we verify the withdrawalRoot against the executionPayloadRoot.\n         */\n        uint256 withdrawalIndex = (WITHDRAWALS_INDEX << (WITHDRAWALS_TREE_HEIGHT + 1)) |\n            uint256(proofs.withdrawalIndex);\n        bytes32 withdrawalRoot = Merkle.merkleizeSha256(withdrawalFields);\n        require(\n            Merkle.verifyInclusionSha256(\n                proofs.withdrawalProof,\n                proofs.executionPayloadRoot,\n                withdrawalRoot,\n                withdrawalIndex\n            ),\n            \"BeaconChainProofs.verifyWithdrawalProofs: Invalid withdrawal merkle proof\"\n        );\n    }\n}\n"
      },
      "contracts/EigenLayer/libraries/Endian.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity =0.8.19;\n\nlibrary Endian {\n    /**\n     * @notice Converts a little endian-formatted uint64 to a big endian-formatted uint64\n     * @param lenum little endian-formatted uint64 input, provided as 'bytes32' type\n     * @return n The big endian-formatted uint64\n     * @dev Note that the input is formatted as a 'bytes32' type (i.e. 256 bits), but it is immediately truncated to a uint64 (i.e. 64 bits)\n     * through a right-shift/shr operation.\n     */\n    function fromLittleEndianUint64(bytes32 lenum) internal pure returns (uint64 n) {\n        // the number needs to be stored in little-endian encoding (ie in bytes 0-8)\n        n = uint64(uint256(lenum >> 192));\n        return\n            (n >> 56) |\n            ((0x00FF000000000000 & n) >> 40) |\n            ((0x0000FF0000000000 & n) >> 24) |\n            ((0x000000FF00000000 & n) >> 8) |\n            ((0x00000000FF000000 & n) << 8) |\n            ((0x0000000000FF0000 & n) << 24) |\n            ((0x000000000000FF00 & n) << 40) |\n            ((0x00000000000000FF & n) << 56);\n    }\n}\n"
      },
      "contracts/EigenLayer/libraries/Merkle.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n// Adapted from OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/MerkleProof.sol)\n\npragma solidity =0.8.19;\n\n/**\n * @dev These functions deal with verification of Merkle Tree proofs.\n *\n * The tree and the proofs can be generated using our\n * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].\n * You will find a quickstart guide in the readme.\n *\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\n * hashing, or use a hash function other than keccak256 for hashing leaves.\n * This is because the concatenation of a sorted pair of internal nodes in\n * the merkle tree could be reinterpreted as a leaf value.\n * OpenZeppelin's JavaScript library generates merkle trees that are safe\n * against this attack out of the box.\n */\nlibrary Merkle {\n    /**\n     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\n     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\n     * hash matches the root of the tree. The tree is built assuming `leaf` is\n     * the 0 indexed `index`'th leaf from the bottom left of the tree.\n     *\n     * Note this is for a Merkle tree using the keccak/sha3 hash function\n     */\n    function verifyInclusionKeccak(\n        bytes memory proof,\n        bytes32 root,\n        bytes32 leaf,\n        uint256 index\n    ) internal pure returns (bool) {\n        return processInclusionProofKeccak(proof, leaf, index) == root;\n    }\n\n    /**\n     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\n     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\n     * hash matches the root of the tree. The tree is built assuming `leaf` is\n     * the 0 indexed `index`'th leaf from the bottom left of the tree.\n     *\n     * _Available since v4.4._\n     *\n     * Note this is for a Merkle tree using the keccak/sha3 hash function\n     */\n    function processInclusionProofKeccak(\n        bytes memory proof,\n        bytes32 leaf,\n        uint256 index\n    ) internal pure returns (bytes32) {\n        require(\n            proof.length != 0 && proof.length % 32 == 0,\n            \"Merkle.processInclusionProofKeccak: proof length should be a non-zero multiple of 32\"\n        );\n        bytes32 computedHash = leaf;\n        for (uint256 i = 32; i <= proof.length; i += 32) {\n            if (index % 2 == 0) {\n                // if ith bit of index is 0, then computedHash is a left sibling\n                assembly {\n                    mstore(0x00, computedHash)\n                    mstore(0x20, mload(add(proof, i)))\n                    computedHash := keccak256(0x00, 0x40)\n                    index := div(index, 2)\n                }\n            } else {\n                // if ith bit of index is 1, then computedHash is a right sibling\n                assembly {\n                    mstore(0x00, mload(add(proof, i)))\n                    mstore(0x20, computedHash)\n                    computedHash := keccak256(0x00, 0x40)\n                    index := div(index, 2)\n                }\n            }\n        }\n        return computedHash;\n    }\n\n    /**\n     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\n     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\n     * hash matches the root of the tree. The tree is built assuming `leaf` is\n     * the 0 indexed `index`'th leaf from the bottom left of the tree.\n     *\n     * Note this is for a Merkle tree using the sha256 hash function\n     */\n    function verifyInclusionSha256(\n        bytes memory proof,\n        bytes32 root,\n        bytes32 leaf,\n        uint256 index\n    ) internal view returns (bool) {\n        return processInclusionProofSha256(proof, leaf, index) == root;\n    }\n\n    /**\n     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\n     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\n     * hash matches the root of the tree. The tree is built assuming `leaf` is\n     * the 0 indexed `index`'th leaf from the bottom left of the tree.\n     *\n     * _Available since v4.4._\n     *\n     * Note this is for a Merkle tree using the sha256 hash function\n     */\n    function processInclusionProofSha256(\n        bytes memory proof,\n        bytes32 leaf,\n        uint256 index\n    ) internal view returns (bytes32) {\n        require(\n            proof.length != 0 && proof.length % 32 == 0,\n            \"Merkle.processInclusionProofSha256: proof length should be a non-zero multiple of 32\"\n        );\n        bytes32[1] memory computedHash = [leaf];\n        for (uint256 i = 32; i <= proof.length; i += 32) {\n            if (index % 2 == 0) {\n                // if ith bit of index is 0, then computedHash is a left sibling\n                assembly {\n                    mstore(0x00, mload(computedHash))\n                    mstore(0x20, mload(add(proof, i)))\n                    if iszero(staticcall(sub(gas(), 2000), 2, 0x00, 0x40, computedHash, 0x20)) {\n                        revert(0, 0)\n                    }\n                    index := div(index, 2)\n                }\n            } else {\n                // if ith bit of index is 1, then computedHash is a right sibling\n                assembly {\n                    mstore(0x00, mload(add(proof, i)))\n                    mstore(0x20, mload(computedHash))\n                    if iszero(staticcall(sub(gas(), 2000), 2, 0x00, 0x40, computedHash, 0x20)) {\n                        revert(0, 0)\n                    }\n                    index := div(index, 2)\n                }\n            }\n        }\n        return computedHash[0];\n    }\n\n    /**\n     @notice this function returns the merkle root of a tree created from a set of leaves using sha256 as its hash function\n     @param leaves the leaves of the merkle tree\n     @return The computed Merkle root of the tree.\n     @dev A pre-condition to this function is that leaves.length is a power of two.  If not, the function will merkleize the inputs incorrectly.\n     */\n    function merkleizeSha256(bytes32[] memory leaves) internal pure returns (bytes32) {\n        //there are half as many nodes in the layer above the leaves\n        uint256 numNodesInLayer = leaves.length / 2;\n        //create a layer to store the internal nodes\n        bytes32[] memory layer = new bytes32[](numNodesInLayer);\n        //fill the layer with the pairwise hashes of the leaves\n        for (uint i = 0; i < numNodesInLayer; i++) {\n            layer[i] = sha256(abi.encodePacked(leaves[2 * i], leaves[2 * i + 1]));\n        }\n        //the next layer above has half as many nodes\n        numNodesInLayer /= 2;\n        //while we haven't computed the root\n        while (numNodesInLayer != 0) {\n            //overwrite the first numNodesInLayer nodes in layer with the pairwise hashes of their children\n            for (uint i = 0; i < numNodesInLayer; i++) {\n                layer[i] = sha256(abi.encodePacked(layer[2 * i], layer[2 * i + 1]));\n            }\n            //the next layer above has half as many nodes\n            numNodesInLayer /= 2;\n        }\n        //the first node in the layer is the root\n        return layer[0];\n    }\n}\n"
      },
      "contracts/Errors/Errors.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\n\n/// @dev Error for 0x0 address inputs\nerror InvalidZeroInput();\n\n/// @dev Error for already added items to a list\nerror AlreadyAdded();\n\n/// @dev Error for not found items in a list\nerror NotFound();\n\n/// @dev Error for hitting max TVL\nerror MaxTVLReached();\n\n/// @dev Error for caller not having permissions\nerror NotRestakeManagerAdmin();\n\n/// @dev Error for call not coming from deposit queue contract\nerror NotDepositQueue();\n\n/// @dev Error for contract being paused\nerror ContractPaused();\n\n/// @dev Error for exceeding max basis points (100%)\nerror OverMaxBasisPoints();\n\n/// @dev Error for invalid token decimals for collateral tokens (must be 18)\nerror InvalidTokenDecimals(uint8 expected, uint8 actual);\n\n/// @dev Error when withdraw is already completed\nerror WithdrawAlreadyCompleted();\n\n/// @dev Error when a different address tries to complete withdraw\nerror NotOriginalWithdrawCaller(address expectedCaller);\n\n/// @dev Error when caller does not have OD admin role\nerror NotOperatorDelegatorAdmin();\n\n/// @dev Error when caller does not have Oracle Admin role\nerror NotOracleAdmin();\n\n/// @dev Error when caller is not RestakeManager contract\nerror NotRestakeManager();\n\n/// @dev Errror when caller does not have ETH Restake Admin role\nerror NotNativeEthRestakeAdmin();\n\n/// @dev Error when delegation address was already set - cannot be set again\nerror DelegateAddressAlreadySet();\n\n/// @dev Error when caller does not have ERC20 Rewards Admin role\nerror NotERC20RewardsAdmin();\n\n/// @dev Error when ending ETH fails\nerror TransferFailed();\n\n/// @dev Error when caller does not have ETH Minter Burner Admin role\nerror NotEzETHMinterBurner();\n\n/// @dev Error when caller does not have Token Admin role\nerror NotTokenAdmin();\n\n/// @dev Error when price oracle is not configured\nerror OracleNotFound();\n\n/// @dev Error when price oracle data is stale\nerror OraclePriceExpired();\n\n/// @dev Error when array lengths do not match\nerror MismatchedArrayLengths();\n\n/// @dev Error when caller does not have Deposit Withdraw Pauser role\nerror NotDepositWithdrawPauser();\n\n/// @dev Error when an individual token TVL is over the max\nerror MaxTokenTVLReached();\n\n/// @dev Error when Oracle price is invalid\nerror InvalidOraclePrice();\n\n/// @dev Error when calling an invalid function\nerror NotImplemented();\n\n/// @dev Error when calculating token amounts is invalid\nerror InvalidTokenAmount();\n\n/// @dev Error when timestamp is invalid - likely in the past\nerror InvalidTimestamp(uint256 timestamp);\n\n/// @dev Error when trade does not meet minimum output amount\nerror InsufficientOutputAmount();\n\n/// @dev Error when the token received over the bridge is not the one expected\nerror InvalidTokenReceived();\n\n/// @dev Error when the origin address is not whitelisted\nerror InvalidOrigin();\n\n/// @dev Error when the sender is not expected\nerror InvalidSender(address expectedSender, address actualSender);\n\n/// @dev error when function returns 0 amount\nerror InvalidZeroOutput();\n\n/// @dev error when xRenzoBridge does not have enough balance to pay for fee\nerror NotEnoughBalance(uint256 currentBalance, uint256 calculatedFees);\n\n/// @dev error when source chain is not expected\nerror InvalidSourceChain(uint64 expectedCCIPChainSelector, uint64 actualCCIPChainSelector);\n\n/// @dev Error when an unauthorized address tries to call the bridge function on the L2\nerror UnauthorizedBridgeSweeper();\n\n/// @dev Error when caller does not have BRIDGE_ADMIN role\nerror NotBridgeAdmin();\n\n/// @dev Error when caller does not have PRICE_FEED_SENDER role\nerror NotPriceFeedSender();\n\n/// @dev Error for connext price Feed unauthorised call\nerror UnAuthorisedCall();\n\n/// @dev Error for no price feed configured on L2\nerror PriceFeedNotAvailable();\n"
      },
      "contracts/IRestakeManager.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\n\nimport \"./Delegation/IOperatorDelegator.sol\";\nimport \"./Deposits/IDepositQueue.sol\";\n\ninterface IRestakeManager {\n    function stakeEthInOperatorDelegator(\n        IOperatorDelegator operatorDelegator,\n        bytes calldata pubkey,\n        bytes calldata signature,\n        bytes32 depositDataRoot\n    ) external payable;\n    function depositTokenRewardsFromProtocol(IERC20 _token, uint256 _amount) external;\n    function depositQueue() external view returns (IDepositQueue);\n\n    function calculateTVLs() external view returns (uint256[][] memory, uint256[] memory, uint256);\n\n    function depositETH() external payable;\n}\n"
      },
      "contracts/Permissions/IRoleManager.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\n\ninterface IRoleManager {\n    /// @dev Determines if the specified address has permissions to manage RoleManager\n    /// @param potentialAddress Address to check\n    function isRoleManagerAdmin(address potentialAddress) external view returns (bool);\n\n    /// @dev Determines if the specified address has permission to mint or burn ezETH tokens\n    /// @param potentialAddress Address to check\n    function isEzETHMinterBurner(address potentialAddress) external view returns (bool);\n\n    /// @dev Determines if the specified address has permission to update config on the OperatorDelgator Contracts\n    /// @param potentialAddress Address to check\n    function isOperatorDelegatorAdmin(address potentialAddress) external view returns (bool);\n\n    /// @dev Determines if the specified address has permission to update config on the Oracle Contract config\n    /// @param potentialAddress Address to check\n    function isOracleAdmin(address potentialAddress) external view returns (bool);\n\n    /// @dev Determines if the specified address has permission to update config on the Restake Manager\n    /// @param potentialAddress Address to check\n    function isRestakeManagerAdmin(address potentialAddress) external view returns (bool);\n\n    /// @dev Determines if the specified address has permission to update config on the Token Contract\n    /// @param potentialAddress Address to check\n    function isTokenAdmin(address potentialAddress) external view returns (bool);\n\n    /// @dev Determines if the specified address has permission to trigger restaking of native ETH\n    /// @param potentialAddress Address to check\n    function isNativeEthRestakeAdmin(address potentialAddress) external view returns (bool);\n\n    /// @dev Determines if the specified address has permission to sweep and deposit ERC20 Rewards\n    /// @param potentialAddress Address to check\n    function isERC20RewardsAdmin(address potentialAddress) external view returns (bool);\n\n    /// @dev Determines if the specified address has permission to pause deposits and withdraws\n    /// @param potentialAddress Address to check\n    function isDepositWithdrawPauser(address potentialAddress) external view returns (bool);\n\n    /// @dev Determines if the specified address has permission to set whitelisted origin in xRenzoBridge\n    /// @param potentialAddress Address to check\n    function isBridgeAdmin(address potentialAddress) external view returns (bool);\n\n    /// @dev Determined if the specified address has permission to send price feed of ezETH to L2\n    /// @param potentialAddress Address to check\n    function isPriceFeedSender(address potentialAddress) external view returns (bool);\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "metadata": {
        "useLiteralContent": true
      },
      "libraries": {}
    }
  }}