{
  "language": "Solidity",
  "sources": {
    "contracts/hardhat-dependency-compiler/@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol';\n"
    },
    "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/** ****************************************************************************\n * @notice Interface for contracts using VRF randomness\n * *****************************************************************************\n * @dev PURPOSE\n *\n * @dev Reggie the Random Oracle (not his real job) wants to provide randomness\n * @dev to Vera the verifier in such a way that Vera can be sure he's not\n * @dev making his output up to suit himself. Reggie provides Vera a public key\n * @dev to which he knows the secret key. Each time Vera provides a seed to\n * @dev Reggie, he gives back a value which is computed completely\n * @dev deterministically from the seed and the secret key.\n *\n * @dev Reggie provides a proof by which Vera can verify that the output was\n * @dev correctly computed once Reggie tells it to her, but without that proof,\n * @dev the output is indistinguishable to her from a uniform random sample\n * @dev from the output space.\n *\n * @dev The purpose of this contract is to make it easy for unrelated contracts\n * @dev to talk to Vera the verifier about the work Reggie is doing, to provide\n * @dev simple access to a verifiable source of randomness. It ensures 2 things:\n * @dev 1. The fulfillment came from the VRFCoordinator\n * @dev 2. The consumer contract implements fulfillRandomWords.\n * *****************************************************************************\n * @dev USAGE\n *\n * @dev Calling contracts must inherit from VRFConsumerBase, and can\n * @dev initialize VRFConsumerBase's attributes in their constructor as\n * @dev shown:\n *\n * @dev   contract VRFConsumer {\n * @dev     constructor(<other arguments>, address _vrfCoordinator, address _link)\n * @dev       VRFConsumerBase(_vrfCoordinator) public {\n * @dev         <initialization with other arguments goes here>\n * @dev       }\n * @dev   }\n *\n * @dev The oracle will have given you an ID for the VRF keypair they have\n * @dev committed to (let's call it keyHash). Create subscription, fund it\n * @dev and your consumer contract as a consumer of it (see VRFCoordinatorInterface\n * @dev subscription management functions).\n * @dev Call requestRandomWords(keyHash, subId, minimumRequestConfirmations,\n * @dev callbackGasLimit, numWords),\n * @dev see (VRFCoordinatorInterface for a description of the arguments).\n *\n * @dev Once the VRFCoordinator has received and validated the oracle's response\n * @dev to your request, it will call your contract's fulfillRandomWords method.\n *\n * @dev The randomness argument to fulfillRandomWords is a set of random words\n * @dev generated from your requestId and the blockHash of the request.\n *\n * @dev If your contract could have concurrent requests open, you can use the\n * @dev requestId returned from requestRandomWords to track which response is associated\n * @dev with which randomness request.\n * @dev See \"SECURITY CONSIDERATIONS\" for principles to keep in mind,\n * @dev if your contract could have multiple requests in flight simultaneously.\n *\n * @dev Colliding `requestId`s are cryptographically impossible as long as seeds\n * @dev differ.\n *\n * *****************************************************************************\n * @dev SECURITY CONSIDERATIONS\n *\n * @dev A method with the ability to call your fulfillRandomness method directly\n * @dev could spoof a VRF response with any random value, so it's critical that\n * @dev it cannot be directly called by anything other than this base contract\n * @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method).\n *\n * @dev For your users to trust that your contract's random behavior is free\n * @dev from malicious interference, it's best if you can write it so that all\n * @dev behaviors implied by a VRF response are executed *during* your\n * @dev fulfillRandomness method. If your contract must store the response (or\n * @dev anything derived from it) and use it later, you must ensure that any\n * @dev user-significant behavior which depends on that stored value cannot be\n * @dev manipulated by a subsequent VRF request.\n *\n * @dev Similarly, both miners and the VRF oracle itself have some influence\n * @dev over the order in which VRF responses appear on the blockchain, so if\n * @dev your contract could have multiple VRF requests in flight simultaneously,\n * @dev you must ensure that the order in which the VRF responses arrive cannot\n * @dev be used to manipulate your contract's user-significant behavior.\n *\n * @dev Since the block hash of the block which contains the requestRandomness\n * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful\n * @dev miner could, in principle, fork the blockchain to evict the block\n * @dev containing the request, forcing the request to be included in a\n * @dev different block with a different hash, and therefore a different input\n * @dev to the VRF. However, such an attack would incur a substantial economic\n * @dev cost. This cost scales with the number of blocks the VRF oracle waits\n * @dev until it calls responds to a request. It is for this reason that\n * @dev that you can signal to an oracle you'd like them to wait longer before\n * @dev responding to the request (however this is not enforced in the contract\n * @dev and so remains effective only in the case of unmodified oracle software).\n */\nabstract contract VRFConsumerBaseV2 {\n  error OnlyCoordinatorCanFulfill(address have, address want);\n  address private immutable vrfCoordinator;\n\n  /**\n   * @param _vrfCoordinator address of VRFCoordinator contract\n   */\n  constructor(address _vrfCoordinator) {\n    vrfCoordinator = _vrfCoordinator;\n  }\n\n  /**\n   * @notice fulfillRandomness handles the VRF response. Your contract must\n   * @notice implement it. See \"SECURITY CONSIDERATIONS\" above for important\n   * @notice principles to keep in mind when implementing your fulfillRandomness\n   * @notice method.\n   *\n   * @dev VRFConsumerBaseV2 expects its subcontracts to have a method with this\n   * @dev signature, and will call it once it has verified the proof\n   * @dev associated with the randomness. (It is triggered via a call to\n   * @dev rawFulfillRandomness, below.)\n   *\n   * @param requestId The Id initially returned by requestRandomness\n   * @param randomWords the VRF output expanded to the requested number of words\n   */\n  function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal virtual;\n\n  // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF\n  // proof. rawFulfillRandomness then calls fulfillRandomness, after validating\n  // the origin of the call\n  function rawFulfillRandomWords(uint256 requestId, uint256[] memory randomWords) external {\n    if (msg.sender != vrfCoordinator) {\n      revert OnlyCoordinatorCanFulfill(msg.sender, vrfCoordinator);\n    }\n    fulfillRandomWords(requestId, randomWords);\n  }\n}\n"
    },
    "@pooltogether/owner-manager-contracts/contracts/Manageable.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.0;\n\nimport \"./Ownable.sol\";\n\n/**\n * @title Abstract manageable contract that can be inherited by other contracts\n * @notice Contract module based on Ownable which provides a basic access control mechanism, where\n * there is an owner and a manager that can be granted exclusive access to specific functions.\n *\n * By default, the owner is the deployer of the contract.\n *\n * The owner account is set through a two steps process.\n *      1. The current `owner` calls {transferOwnership} to set a `pendingOwner`\n *      2. The `pendingOwner` calls {acceptOwnership} to accept the ownership transfer\n *\n * The manager account needs to be set using {setManager}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyManager`, which can be applied to your functions to restrict their use to\n * the manager.\n */\nabstract contract Manageable is Ownable {\n    address private _manager;\n\n    /**\n     * @dev Emitted when `_manager` has been changed.\n     * @param previousManager previous `_manager` address.\n     * @param newManager new `_manager` address.\n     */\n    event ManagerTransferred(address indexed previousManager, address indexed newManager);\n\n    /* ============ External Functions ============ */\n\n    /**\n     * @notice Gets current `_manager`.\n     * @return Current `_manager` address.\n     */\n    function manager() public view virtual returns (address) {\n        return _manager;\n    }\n\n    /**\n     * @notice Set or change of manager.\n     * @dev Throws if called by any account other than the owner.\n     * @param _newManager New _manager address.\n     * @return Boolean to indicate if the operation was successful or not.\n     */\n    function setManager(address _newManager) external onlyOwner returns (bool) {\n        return _setManager(_newManager);\n    }\n\n    /* ============ Internal Functions ============ */\n\n    /**\n     * @notice Set or change of manager.\n     * @param _newManager New _manager address.\n     * @return Boolean to indicate if the operation was successful or not.\n     */\n    function _setManager(address _newManager) private returns (bool) {\n        address _previousManager = _manager;\n\n        require(_newManager != _previousManager, \"Manageable/existing-manager-address\");\n\n        _manager = _newManager;\n\n        emit ManagerTransferred(_previousManager, _newManager);\n        return true;\n    }\n\n    /* ============ Modifier Functions ============ */\n\n    /**\n     * @dev Throws if called by any account other than the manager.\n     */\n    modifier onlyManager() {\n        require(manager() == msg.sender, \"Manageable/caller-not-manager\");\n        _;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the manager or the owner.\n     */\n    modifier onlyManagerOrOwner() {\n        require(manager() == msg.sender || owner() == msg.sender, \"Manageable/caller-not-manager-or-owner\");\n        _;\n    }\n}\n"
    },
    "@pooltogether/owner-manager-contracts/contracts/Ownable.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.0;\n\n/**\n * @title Abstract ownable contract that can be inherited by other contracts\n * @notice Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner is the deployer of the contract.\n *\n * The owner account is set through a two steps process.\n *      1. The current `owner` calls {transferOwnership} to set a `pendingOwner`\n *      2. The `pendingOwner` calls {acceptOwnership} to accept the ownership transfer\n *\n * The manager account needs to be set using {setManager}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable {\n    address private _owner;\n    address private _pendingOwner;\n\n    /**\n     * @dev Emitted when `_pendingOwner` has been changed.\n     * @param pendingOwner new `_pendingOwner` address.\n     */\n    event OwnershipOffered(address indexed pendingOwner);\n\n    /**\n     * @dev Emitted when `_owner` has been changed.\n     * @param previousOwner previous `_owner` address.\n     * @param newOwner new `_owner` address.\n     */\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /* ============ Deploy ============ */\n\n    /**\n     * @notice Initializes the contract setting `_initialOwner` as the initial owner.\n     * @param _initialOwner Initial owner of the contract.\n     */\n    constructor(address _initialOwner) {\n        _setOwner(_initialOwner);\n    }\n\n    /* ============ External Functions ============ */\n\n    /**\n     * @notice Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @notice Gets current `_pendingOwner`.\n     * @return Current `_pendingOwner` address.\n     */\n    function pendingOwner() external view virtual returns (address) {\n        return _pendingOwner;\n    }\n\n    /**\n     * @notice Renounce ownership of the contract.\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() external virtual onlyOwner {\n        _setOwner(address(0));\n    }\n\n    /**\n    * @notice Allows current owner to set the `_pendingOwner` address.\n    * @param _newOwner Address to transfer ownership to.\n    */\n    function transferOwnership(address _newOwner) external onlyOwner {\n        require(_newOwner != address(0), \"Ownable/pendingOwner-not-zero-address\");\n\n        _pendingOwner = _newOwner;\n\n        emit OwnershipOffered(_newOwner);\n    }\n\n    /**\n    * @notice Allows the `_pendingOwner` address to finalize the transfer.\n    * @dev This function is only callable by the `_pendingOwner`.\n    */\n    function claimOwnership() external onlyPendingOwner {\n        _setOwner(_pendingOwner);\n        _pendingOwner = address(0);\n    }\n\n    /* ============ Internal Functions ============ */\n\n    /**\n     * @notice Internal function to set the `_owner` of the contract.\n     * @param _newOwner New `_owner` address.\n     */\n    function _setOwner(address _newOwner) private {\n        address _oldOwner = _owner;\n        _owner = _newOwner;\n        emit OwnershipTransferred(_oldOwner, _newOwner);\n    }\n\n    /* ============ Modifier Functions ============ */\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(owner() == msg.sender, \"Ownable/caller-not-owner\");\n        _;\n    }\n\n    /**\n    * @dev Throws if called by any account other than the `pendingOwner`.\n    */\n    modifier onlyPendingOwner() {\n        require(msg.sender == _pendingOwner, \"Ownable/caller-not-pendingOwner\");\n        _;\n    }\n}\n"
    },
    "@openzeppelin/contracts/utils/Address.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\n\npragma solidity ^0.8.0;\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     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize, which returns 0 for contracts in\n        // construction, since the code is only stored at the end of the\n        // constructor execution.\n\n        uint256 size;\n        assembly {\n            size := extcodesize(account)\n        }\n        return size > 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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, \"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(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) 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        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(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        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(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        require(isContract(target), \"Address: delegate call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason 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            // 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\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}\n"
    },
    "@pooltogether/yield-source-interface/contracts/IYieldSource.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity >=0.6.0;\n\n/// @title Defines the functions used to interact with a yield source.  The Prize Pool inherits this contract.\n/// @notice Prize Pools subclasses need to implement this interface so that yield can be generated.\ninterface IYieldSource {\n    /// @notice Returns the ERC20 asset token used for deposits.\n    /// @return The ERC20 asset token address.\n    function depositToken() external view returns (address);\n\n    /// @notice Returns the total balance (in asset tokens).  This includes the deposits and interest.\n    /// @return The underlying balance of asset tokens.\n    function balanceOfToken(address addr) external returns (uint256);\n\n    /// @notice Supplies tokens to the yield source.  Allows assets to be supplied on other user's behalf using the `to` param.\n    /// @param amount The amount of asset tokens to be supplied.  Denominated in `depositToken()` as above.\n    /// @param to The user whose balance will receive the tokens\n    function supplyTokenTo(uint256 amount, address to) external;\n\n    /// @notice Redeems tokens from the yield source.\n    /// @param amount The amount of asset tokens to withdraw.  Denominated in `depositToken()` as above.\n    /// @return The actual amount of interst bearing tokens that were redeemed.\n    function redeemToken(uint256 amount) external returns (uint256);\n}\n"
    },
    "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (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 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 `recipient`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address recipient, 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 `sender` to `recipient` 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(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) external returns (bool);\n\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"
    },
    "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation 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 * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n    using Counters for Counters.Counter;\n\n    mapping(address => Counters.Counter) private _nonces;\n\n    // solhint-disable-next-line var-name-mixedcase\n    bytes32 private immutable _PERMIT_TYPEHASH =\n        keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n\n    /**\n     * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n     *\n     * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n     */\n    constructor(string memory name) EIP712(name, \"1\") {}\n\n    /**\n     * @dev See {IERC20Permit-permit}.\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    ) public virtual override {\n        require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n        bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n        bytes32 hash = _hashTypedDataV4(structHash);\n\n        address signer = ECDSA.recover(hash, v, r, s);\n        require(signer == owner, \"ERC20Permit: invalid signature\");\n\n        _approve(owner, spender, value);\n    }\n\n    /**\n     * @dev See {IERC20Permit-nonces}.\n     */\n    function nonces(address owner) public view virtual override returns (uint256) {\n        return _nonces[owner].current();\n    }\n\n    /**\n     * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n        return _domainSeparatorV4();\n    }\n\n    /**\n     * @dev \"Consume a nonce\": return the current value and increment.\n     *\n     * _Available since v4.1._\n     */\n    function _useNonce(address owner) internal virtual returns (uint256 current) {\n        Counters.Counter storage nonce = _nonces[owner];\n        current = nonce.current();\n        nonce.increment();\n    }\n}\n"
    },
    "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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 */\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    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/ERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * The default value of {decimals} is 18. To select a different value for\n     * {decimals} you should overload it.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the value {ERC20} uses, unless this function is\n     * overridden;\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `recipient` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n        _transfer(_msgSender(), recipient, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        _approve(_msgSender(), spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * Requirements:\n     *\n     * - `sender` and `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``sender``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) public virtual override returns (bool) {\n        _transfer(sender, recipient, amount);\n\n        uint256 currentAllowance = _allowances[sender][_msgSender()];\n        require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n        unchecked {\n            _approve(sender, _msgSender(), currentAllowance - amount);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        uint256 currentAllowance = _allowances[_msgSender()][spender];\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `sender` to `recipient`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `sender` cannot be the zero address.\n     * - `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     */\n    function _transfer(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) internal virtual {\n        require(sender != address(0), \"ERC20: transfer from the zero address\");\n        require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(sender, recipient, amount);\n\n        uint256 senderBalance = _balances[sender];\n        require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[sender] = senderBalance - amount;\n        }\n        _balances[recipient] += amount;\n\n        emit Transfer(sender, recipient, amount);\n\n        _afterTokenTransfer(sender, recipient, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        _balances[account] += amount;\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n        }\n        _totalSupply -= amount;\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(\n        address owner,\n        address spender,\n        uint256 amount\n    ) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256 amount\n    ) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(\n        address from,\n        address to,\n        uint256 amount\n    ) internal virtual {}\n}\n"
    },
    "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n    /* solhint-disable var-name-mixedcase */\n    // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n    // invalidate the cached domain separator if the chain id changes.\n    bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n    uint256 private immutable _CACHED_CHAIN_ID;\n    address private immutable _CACHED_THIS;\n\n    bytes32 private immutable _HASHED_NAME;\n    bytes32 private immutable _HASHED_VERSION;\n    bytes32 private immutable _TYPE_HASH;\n\n    /* solhint-enable var-name-mixedcase */\n\n    /**\n     * @dev Initializes the domain separator and parameter caches.\n     *\n     * The meaning of `name` and `version` is specified in\n     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n     *\n     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n     * - `version`: the current major version of the signing domain.\n     *\n     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n     * contract upgrade].\n     */\n    constructor(string memory name, string memory version) {\n        bytes32 hashedName = keccak256(bytes(name));\n        bytes32 hashedVersion = keccak256(bytes(version));\n        bytes32 typeHash = keccak256(\n            \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n        );\n        _HASHED_NAME = hashedName;\n        _HASHED_VERSION = hashedVersion;\n        _CACHED_CHAIN_ID = block.chainid;\n        _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n        _CACHED_THIS = address(this);\n        _TYPE_HASH = typeHash;\n    }\n\n    /**\n     * @dev Returns the domain separator for the current chain.\n     */\n    function _domainSeparatorV4() internal view returns (bytes32) {\n        if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n            return _CACHED_DOMAIN_SEPARATOR;\n        } else {\n            return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n        }\n    }\n\n    function _buildDomainSeparator(\n        bytes32 typeHash,\n        bytes32 nameHash,\n        bytes32 versionHash\n    ) private view returns (bytes32) {\n        return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n    }\n\n    /**\n     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n     * function returns the hash of the fully encoded EIP712 message for this domain.\n     *\n     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n     *\n     * ```solidity\n     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n     *     keccak256(\"Mail(address to,string contents)\"),\n     *     mailTo,\n     *     keccak256(bytes(mailContents))\n     * )));\n     * address signer = ECDSA.recover(digest, signature);\n     * ```\n     */\n    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n        return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n    }\n}\n"
    },
    "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n    enum RecoverError {\n        NoError,\n        InvalidSignature,\n        InvalidSignatureLength,\n        InvalidSignatureS,\n        InvalidSignatureV\n    }\n\n    function _throwError(RecoverError error) private pure {\n        if (error == RecoverError.NoError) {\n            return; // no error: do nothing\n        } else if (error == RecoverError.InvalidSignature) {\n            revert(\"ECDSA: invalid signature\");\n        } else if (error == RecoverError.InvalidSignatureLength) {\n            revert(\"ECDSA: invalid signature length\");\n        } else if (error == RecoverError.InvalidSignatureS) {\n            revert(\"ECDSA: invalid signature 's' value\");\n        } else if (error == RecoverError.InvalidSignatureV) {\n            revert(\"ECDSA: invalid signature 'v' value\");\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature` or error string. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     *\n     * Documentation for signature generation:\n     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n        // Check the signature length\n        // - case 65: r,s,v signature (standard)\n        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n        if (signature.length == 65) {\n            bytes32 r;\n            bytes32 s;\n            uint8 v;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            assembly {\n                r := mload(add(signature, 0x20))\n                s := mload(add(signature, 0x40))\n                v := byte(0, mload(add(signature, 0x60)))\n            }\n            return tryRecover(hash, v, r, s);\n        } else if (signature.length == 64) {\n            bytes32 r;\n            bytes32 vs;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            assembly {\n                r := mload(add(signature, 0x20))\n                vs := mload(add(signature, 0x40))\n            }\n            return tryRecover(hash, r, vs);\n        } else {\n            return (address(0), RecoverError.InvalidSignatureLength);\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature`. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {toEthSignedMessageHash} on it.\n     */\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, signature);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n     *\n     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(\n        bytes32 hash,\n        bytes32 r,\n        bytes32 vs\n    ) internal pure returns (address, RecoverError) {\n        bytes32 s;\n        uint8 v;\n        assembly {\n            s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\n            v := add(shr(255, vs), 27)\n        }\n        return tryRecover(hash, v, r, s);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n     *\n     * _Available since v4.2._\n     */\n    function recover(\n        bytes32 hash,\n        bytes32 r,\n        bytes32 vs\n    ) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     *\n     * _Available since v4.3._\n     */\n    function tryRecover(\n        bytes32 hash,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (address, RecoverError) {\n        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n        //\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n        // these malleable signatures as well.\n        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n            return (address(0), RecoverError.InvalidSignatureS);\n        }\n        if (v != 27 && v != 28) {\n            return (address(0), RecoverError.InvalidSignatureV);\n        }\n\n        // If the signature is valid (and not malleable), return the signer address\n        address signer = ecrecover(hash, v, r, s);\n        if (signer == address(0)) {\n            return (address(0), RecoverError.InvalidSignature);\n        }\n\n        return (signer, RecoverError.NoError);\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function recover(\n        bytes32 hash,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (address) {\n        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n        _throwError(error);\n        return recovered;\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n        // 32 is the length in bytes of hash,\n        // enforced by the type signature above\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Message, created from `s`. This\n     * produces hash corresponding to the one signed with the\n     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n     * JSON-RPC method as part of EIP-191.\n     *\n     * See {recover}.\n     */\n    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n    }\n\n    /**\n     * @dev Returns an Ethereum Signed Typed Data, created from a\n     * `domainSeparator` and a `structHash`. This produces hash corresponding\n     * to the one signed with the\n     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n     * JSON-RPC method as part of EIP-712.\n     *\n     * See {recover}.\n     */\n    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n        return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n    }\n}\n"
    },
    "@openzeppelin/contracts/utils/Counters.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n    struct Counter {\n        // This variable should never be directly accessed by users of the library: interactions must be restricted to\n        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n        // this feature: see https://github.com/ethereum/solidity/issues/4637\n        uint256 _value; // default: 0\n    }\n\n    function current(Counter storage counter) internal view returns (uint256) {\n        return counter._value;\n    }\n\n    function increment(Counter storage counter) internal {\n        unchecked {\n            counter._value += 1;\n        }\n    }\n\n    function decrement(Counter storage counter) internal {\n        uint256 value = counter._value;\n        require(value > 0, \"Counter: decrement overflow\");\n        unchecked {\n            counter._value = value - 1;\n        }\n    }\n\n    function reset(Counter storage counter) internal {\n        counter._value = 0;\n    }\n}\n"
    },
    "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"
    },
    "@openzeppelin/contracts/utils/Context.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"
    },
    "@openzeppelin/contracts/utils/Strings.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n    bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        // Inspired by OraclizeAPI's implementation - MIT licence\n        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n        if (value == 0) {\n            return \"0\";\n        }\n        uint256 temp = value;\n        uint256 digits;\n        while (temp != 0) {\n            digits++;\n            temp /= 10;\n        }\n        bytes memory buffer = new bytes(digits);\n        while (value != 0) {\n            digits -= 1;\n            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n            value /= 10;\n        }\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        if (value == 0) {\n            return \"0x00\";\n        }\n        uint256 temp = value;\n        uint256 length = 0;\n        while (temp != 0) {\n            length++;\n            temp >>= 8;\n        }\n        return toHexString(value, length);\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = _HEX_SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n}\n"
    },
    "@pooltogether/fixed-point/contracts/FixedPoint.sol": {
      "content": "/**\nCopyright 2020 PoolTogether Inc.\n\nThis file is part of PoolTogether.\n\nPoolTogether is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation under version 3 of the License.\n\nPoolTogether is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with PoolTogether.  If not, see <https://www.gnu.org/licenses/>.\n*/\n\npragma solidity >=0.4.0;\n\nimport \"./external/openzeppelin/OpenZeppelinSafeMath_V3_3_0.sol\";\n\n/**\n * @author Brendan Asselstine\n * @notice Provides basic fixed point math calculations.\n *\n * This library calculates integer fractions by scaling values by 1e18 then performing standard integer math.\n */\nlibrary FixedPoint {\n    using OpenZeppelinSafeMath_V3_3_0 for uint256;\n\n    // The scale to use for fixed point numbers.  Same as Ether for simplicity.\n    uint256 internal constant SCALE = 1e18;\n\n    /**\n        * Calculates a Fixed18 mantissa given the numerator and denominator\n        *\n        * The mantissa = (numerator * 1e18) / denominator\n        *\n        * @param numerator The mantissa numerator\n        * @param denominator The mantissa denominator\n        * @return The mantissa of the fraction\n        */\n    function calculateMantissa(uint256 numerator, uint256 denominator) internal pure returns (uint256) {\n        uint256 mantissa = numerator.mul(SCALE);\n        mantissa = mantissa.div(denominator);\n        return mantissa;\n    }\n\n    /**\n        * Multiplies a Fixed18 number by an integer.\n        *\n        * @param b The whole integer to multiply\n        * @param mantissa The Fixed18 number\n        * @return An integer that is the result of multiplying the params.\n        */\n    function multiplyUintByMantissa(uint256 b, uint256 mantissa) internal pure returns (uint256) {\n        uint256 result = mantissa.mul(b);\n        result = result.div(SCALE);\n        return result;\n    }\n\n    /**\n    * Divides an integer by a fixed point 18 mantissa\n    *\n    * @param dividend The integer to divide\n    * @param mantissa The fixed point 18 number to serve as the divisor\n    * @return An integer that is the result of dividing an integer by a fixed point 18 mantissa\n    */\n    function divideUintByMantissa(uint256 dividend, uint256 mantissa) internal pure returns (uint256) {\n        uint256 result = SCALE.mul(dividend);\n        result = result.div(mantissa);\n        return result;\n    }\n}\n"
    },
    "@pooltogether/fixed-point/contracts/external/openzeppelin/OpenZeppelinSafeMath_V3_3_0.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\n// NOTE: Copied from OpenZeppelin Contracts version 3.3.0\n\npragma solidity >=0.4.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary OpenZeppelinSafeMath_V3_3_0 {\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     *\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c >= a, \"SafeMath: addition overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return sub(a, b, \"SafeMath: subtraction overflow\");\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b <= a, errorMessage);\n        uint256 c = a - b;\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `*` operator.\n     *\n     * Requirements:\n     *\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n        // benefit is lost if 'b' is also tested.\n        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n        if (a == 0) {\n            return 0;\n        }\n\n        uint256 c = a * b;\n        require(c / a == b, \"SafeMath: multiplication overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers. Reverts on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        return div(a, b, \"SafeMath: division by zero\");\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b > 0, errorMessage);\n        uint256 c = a / b;\n        // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * Reverts when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        return mod(a, b, \"SafeMath: modulo by zero\");\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * Reverts with custom message when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b != 0, errorMessage);\n        return a % b;\n    }\n}\n"
    },
    "@openzeppelin/contracts/security/ReentrancyGuard.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\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 ReentrancyGuard {\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    constructor() {\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        // On the first call to nonReentrant, _notEntered will be true\n        require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n        // Any calls to nonReentrant after this point will fail\n        _status = _ENTERED;\n\n        _;\n\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"
    },
    "@pooltogether/aave-v3-yield-source/contracts/AaveV3YieldSource.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity 0.8.10;\n\nimport { IAToken } from \"@aave/core-v3/contracts/interfaces/IAToken.sol\";\nimport { IPool } from \"@aave/core-v3/contracts/interfaces/IPool.sol\";\nimport { IPoolAddressesProvider } from \"@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol\";\nimport { IPoolAddressesProviderRegistry } from \"@aave/core-v3/contracts/interfaces/IPoolAddressesProviderRegistry.sol\";\nimport { IRewardsController } from \"@aave/periphery-v3/contracts/rewards/interfaces/IRewardsController.sol\";\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { IERC20 } from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport { SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { ReentrancyGuard } from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\nimport { Manageable, Ownable } from \"@pooltogether/owner-manager-contracts/contracts/Manageable.sol\";\nimport { IYieldSource } from \"@pooltogether/yield-source-interface/contracts/IYieldSource.sol\";\n\n/**\n * @title Aave V3 Yield Source contract, implementing PoolTogether's generic yield source interface.\n * @dev This contract inherits from the ERC20 implementation to keep track of users deposits.\n * @notice Yield Source for a PoolTogether prize pool that generates yield by depositing into Aave V3.\n */\ncontract AaveV3YieldSource is ERC20, IYieldSource, Manageable, ReentrancyGuard {\n  using SafeERC20 for IERC20;\n\n  /* ============ Events ============ */\n\n  /**\n   * @notice Emitted when the yield source is initialized.\n   * @param aToken Aave aToken address\n   * @param rewardsController Aave rewardsController address\n   * @param poolAddressesProviderRegistry Aave poolAddressesProviderRegistry address\n   * @param name Token name for the underlying ERC20 shares\n   * @param symbol Token symbol for the underlying ERC20 shares\n   * @param decimals Number of decimals the shares (inherited ERC20) will have. Same as underlying asset to ensure sane exchange rates for shares.\n   * @param owner Owner of this contract\n   */\n  event AaveV3YieldSourceInitialized(\n    IAToken indexed aToken,\n    IRewardsController rewardsController,\n    IPoolAddressesProviderRegistry poolAddressesProviderRegistry,\n    string name,\n    string symbol,\n    uint8 decimals,\n    address indexed owner\n  );\n\n  /**\n   * @notice Emitted when asset tokens are supplied to the yield source.\n   * @param from Address that supplied the tokens\n   * @param shares Amount of shares minted to the user\n   * @param amount Amount of tokens supplied\n   * @param to Address that received the shares\n   */\n  event SuppliedTokenTo(address indexed from, uint256 shares, uint256 amount, address indexed to);\n\n  /**\n   * @notice Emitted when asset tokens are redeemed from the yield source.\n   * @param from Address who redeemed the tokens\n   * @param shares Amount of shares burnt\n   * @param amount Amount of tokens redeemed\n   */\n  event RedeemedToken(address indexed from, uint256 shares, uint256 amount);\n\n  /**\n   * @notice Emitted when Aave rewards have been claimed.\n   * @param from Address who claimed the rewards\n   * @param to Address that received the rewards\n   * @param rewardsList List of addresses of the reward tokens\n   * @param claimedAmounts List that contains the claimed amount per reward token\n   */\n  event Claimed(\n    address indexed from,\n    address indexed to,\n    address[] rewardsList,\n    uint256[] claimedAmounts\n  );\n\n  /**\n   * @notice Emitted when decreasing allowance of ERC20 tokens other than yield source's aToken.\n   * @param from Address of the caller\n   * @param spender Address of the spender\n   * @param amount Amount of `token` to decrease allowance by\n   * @param token Address of the ERC20 token to decrease allowance for\n   */\n  event DecreasedERC20Allowance(\n    address indexed from,\n    address indexed spender,\n    uint256 amount,\n    IERC20 indexed token\n  );\n\n  /**\n   * @notice Emitted when increasing allowance of ERC20 tokens other than yield source's aToken.\n   * @param from Address of the caller\n   * @param spender Address of the spender\n   * @param amount Amount of `token` to increase allowance by\n   * @param token Address of the ERC20 token to increase allowance for\n   */\n  event IncreasedERC20Allowance(\n    address indexed from,\n    address indexed spender,\n    uint256 amount,\n    IERC20 indexed token\n  );\n\n  /**\n   * @notice Emitted when ERC20 tokens other than yield source's aToken are withdrawn from the yield source.\n   * @param from Address of the caller\n   * @param to Address of the recipient\n   * @param amount Amount of `token` transferred\n   * @param token Address of the ERC20 token transferred\n   */\n  event TransferredERC20(\n    address indexed from,\n    address indexed to,\n    uint256 amount,\n    IERC20 indexed token\n  );\n\n  /* ============ Variables ============ */\n\n  /// @notice Yield-bearing Aave aToken address.\n  IAToken public immutable aToken;\n\n  /// @notice Aave RewardsController address.\n  IRewardsController public immutable rewardsController;\n\n  /// @notice Aave poolAddressesProviderRegistry address.\n  IPoolAddressesProviderRegistry public immutable poolAddressesProviderRegistry;\n\n  /// @notice Underlying asset token address.\n  address private immutable _tokenAddress;\n\n  /// @notice Underlying asset unit.\n  uint256 private immutable _tokenUnit;\n\n  /// @notice ERC20 token decimals.\n  uint8 private immutable _decimals;\n\n  /**\n   * @dev Aave genesis market PoolAddressesProvider's ID.\n   * @dev This variable could evolve in the future if we decide to support other markets.\n   */\n  uint256 private constant ADDRESSES_PROVIDER_ID = uint256(0);\n\n  /// @dev PoolTogether's Aave Referral Code\n  uint16 private constant REFERRAL_CODE = uint16(188);\n\n  /* ============ Constructor ============ */\n\n  /**\n   * @notice Initializes the yield source with Aave aToken.\n   * @param _aToken Aave aToken address\n   * @param _rewardsController Aave rewardsController address\n   * @param _poolAddressesProviderRegistry Aave poolAddressesProviderRegistry address\n   * @param _name Token name for the underlying ERC20 shares\n   * @param _symbol Token symbol for the underlying ERC20 shares\n   * @param decimals_ Number of decimals the shares (inherited ERC20) will have. Same as underlying asset to ensure sane exchange rates for shares.\n   * @param _owner Owner of this contract\n   */\n  constructor(\n    IAToken _aToken,\n    IRewardsController _rewardsController,\n    IPoolAddressesProviderRegistry _poolAddressesProviderRegistry,\n    string memory _name,\n    string memory _symbol,\n    uint8 decimals_,\n    address _owner\n  ) Ownable(_owner) ERC20(_name, _symbol) ReentrancyGuard() {\n    require(_owner != address(0), \"AaveV3YS/owner-not-zero-address\");\n    require(address(_aToken) != address(0), \"AaveV3YS/aToken-not-zero-address\");\n    require(decimals_ > 0, \"AaveV3YS/decimals-gt-zero\");\n    require(address(_rewardsController) != address(0), \"AaveV3YS/RC-not-zero-address\");\n    require(address(_poolAddressesProviderRegistry) != address(0), \"AaveV3YS/PR-not-zero-address\");\n\n    aToken = _aToken;\n    _decimals = decimals_;\n    _tokenUnit = 10**decimals_;\n    _tokenAddress = address(_aToken.UNDERLYING_ASSET_ADDRESS());\n    rewardsController = _rewardsController;\n    poolAddressesProviderRegistry = _poolAddressesProviderRegistry;\n\n    // Approve once for max amount\n    IERC20(_tokenAddress).safeApprove(address(_pool()), type(uint256).max);\n\n    emit AaveV3YieldSourceInitialized(\n      _aToken,\n      _rewardsController,\n      _poolAddressesProviderRegistry,\n      _name,\n      _symbol,\n      decimals_,\n      _owner\n    );\n  }\n\n  /* ============ External Functions ============ */\n\n  /**\n   * @notice Returns user total balance (in asset tokens). This includes their deposit and interest.\n   * @param _user Address of the user to get balance of token for\n   * @return The underlying balance of asset tokens.\n   */\n  function balanceOfToken(address _user) external view override returns (uint256) {\n    return _sharesToToken(balanceOf(_user), _pricePerShare());\n  }\n\n  /**\n   * @notice Returns the ERC20 asset token used for deposits.\n   * @return The ERC20 asset token address.\n   */\n  function depositToken() public view override returns (address) {\n    return _tokenAddress;\n  }\n\n  /**\n   * @notice Returns the Yield Source ERC20 token decimals.\n   * @dev This value should be equal to the decimals of the token used to deposit into the pool.\n   * @return The number of decimals.\n   */\n  function decimals() public view virtual override returns (uint8) {\n    return _decimals;\n  }\n\n  /**\n   * @notice Supplies asset tokens to the yield source.\n   * @dev Shares corresponding to the number of tokens supplied are minted to the user's balance.\n   * @dev Asset tokens are supplied to the yield source, then deposited into Aave.\n   * @param _depositAmount The amount of asset tokens to be supplied\n   * @param _to The user whose balance will receive the tokens\n   */\n  function supplyTokenTo(uint256 _depositAmount, address _to) external override nonReentrant {\n    uint256 _fullShare = _pricePerShare();\n\n    uint256 _shares = _tokenToShares(_depositAmount, _fullShare);\n    _requireSharesGTZero(_shares);\n\n    uint256 _tokenAmount = _sharesToToken(_shares, _fullShare);\n    IERC20(_tokenAddress).safeTransferFrom(msg.sender, address(this), _tokenAmount);\n    _pool().supply(_tokenAddress, _tokenAmount, address(this), REFERRAL_CODE);\n\n    _mint(_to, _shares);\n\n    emit SuppliedTokenTo(msg.sender, _shares, _tokenAmount, _to);\n  }\n\n  /**\n   * @notice Redeems asset tokens from the yield source.\n   * @dev Shares corresponding to the number of tokens withdrawn are burnt from the user's balance.\n   * @dev Asset tokens are withdrawn from Aave, then transferred from the yield source to the user's wallet.\n   * @param _redeemAmount The amount of asset tokens to be redeemed\n   * @return The actual amount of asset tokens that were redeemed.\n   */\n  function redeemToken(uint256 _redeemAmount) external override nonReentrant returns (uint256) {\n    uint256 _fullShare = _pricePerShare();\n\n    uint256 _shares = _tokenToShares(_redeemAmount, _fullShare);\n    _requireSharesGTZero(_shares);\n\n    uint256 _tokenAmount = _sharesToToken(_shares, _fullShare);\n\n    _burn(msg.sender, _shares);\n\n    IERC20 _assetToken = IERC20(_tokenAddress);\n    uint256 _beforeBalance = _assetToken.balanceOf(address(this));\n    _pool().withdraw(_tokenAddress, _tokenAmount, address(this));\n\n    uint256 _balanceDiff;\n\n    unchecked {\n      _balanceDiff = _assetToken.balanceOf(address(this)) - _beforeBalance;\n    }\n\n    _assetToken.safeTransfer(msg.sender, _balanceDiff);\n\n    emit RedeemedToken(msg.sender, _shares, _tokenAmount);\n    return _balanceDiff;\n  }\n\n  /**\n   * @notice Claims the accrued rewards for the aToken, accumulating any pending rewards.\n   * @dev Only callable by the owner or manager.\n   * @param _to Address where the claimed rewards will be sent\n   */\n  function claimRewards(address _to) external onlyManagerOrOwner {\n    require(_to != address(0), \"AaveV3YS/payee-not-zero-address\");\n\n    address[] memory _assets = new address[](1);\n    _assets[0] = address(aToken);\n\n    (address[] memory _rewardsList, uint256[] memory _claimedAmounts) = rewardsController\n      .claimAllRewards(_assets, _to);\n\n    emit Claimed(msg.sender, _to, _rewardsList, _claimedAmounts);\n  }\n\n  /**\n   * @notice Decrease allowance of ERC20 tokens other than the aTokens held by this contract.\n   * @dev This function is only callable by the owner or asset manager.\n   * @dev Current allowance should be computed off-chain to avoid any underflow.\n   * @param _token Address of the ERC20 token to decrease allowance for\n   * @param _spender Address of the spender of the tokens\n   * @param _amount Amount of tokens to decrease allowance by\n   */\n  function decreaseERC20Allowance(\n    IERC20 _token,\n    address _spender,\n    uint256 _amount\n  ) external onlyManagerOrOwner {\n    _requireNotAToken(address(_token));\n    _token.safeDecreaseAllowance(_spender, _amount);\n    emit DecreasedERC20Allowance(msg.sender, _spender, _amount, _token);\n  }\n\n  /**\n   * @notice Increase allowance of ERC20 tokens other than the aTokens held by this contract.\n   * @dev This function is only callable by the owner or asset manager.\n   * @dev Allows another contract or address to withdraw funds from the yield source.\n   * @dev Current allowance should be computed off-chain to avoid any overflow.\n   * @param _token Address of the ERC20 token to increase allowance for\n   * @param _spender Address of the spender of the tokens\n   * @param _amount Amount of tokens to increase allowance by\n   */\n  function increaseERC20Allowance(\n    IERC20 _token,\n    address _spender,\n    uint256 _amount\n  ) external onlyManagerOrOwner {\n    _requireNotAToken(address(_token));\n    _token.safeIncreaseAllowance(_spender, _amount);\n    emit IncreasedERC20Allowance(msg.sender, _spender, _amount, _token);\n  }\n\n  /**\n   * @notice Transfer ERC20 tokens other than the aTokens held by this contract to the recipient address.\n   * @dev This function is only callable by the owner or asset manager.\n   * @param _token Address of the ERC20 token to transfer\n   * @param _to Address of the recipient of the tokens\n   * @param _amount Amount of tokens to transfer\n   */\n  function transferERC20(\n    IERC20 _token,\n    address _to,\n    uint256 _amount\n  ) external onlyManagerOrOwner {\n    _requireNotAToken(address(_token));\n    _token.safeTransfer(_to, _amount);\n    emit TransferredERC20(msg.sender, _to, _amount, _token);\n  }\n\n  /* ============ Internal Functions ============ */\n\n  /**\n   * @notice Checks that the amount of shares is greater than zero.\n   * @param _shares Amount of shares to check\n   */\n  function _requireSharesGTZero(uint256 _shares) internal pure {\n    require(_shares > 0, \"AaveV3YS/shares-gt-zero\");\n  }\n\n  /**\n   * @notice Checks that the token address passed is not the aToken address.\n   * @param _token Address of the ERC20 token to check\n   */\n  function _requireNotAToken(address _token) internal view {\n    require(_token != address(aToken), \"AaveV3YS/forbid-aToken-change\");\n  }\n\n  /**\n   * @notice Calculates the price of a full share.\n   * @dev We use this calculation to ensure that the price per share can't be manipulated.\n   * @return The current price per share\n   */\n  function _pricePerShare() internal view returns (uint256) {\n    uint256 _supply = totalSupply();\n\n    // pricePerShare = (token * yieldSourceBalanceOfAToken) / totalSupply\n    return _supply == 0 ? _tokenUnit : (_tokenUnit * aToken.balanceOf(address(this))) / _supply;\n  }\n\n  /**\n   * @notice Calculates the number of shares that should be minted or burnt when a user deposit or withdraw.\n   * @param _tokens Amount of asset tokens\n   * @param _fullShare Price of a full share\n   * @return Number of shares.\n   */\n  function _tokenToShares(uint256 _tokens, uint256 _fullShare) internal view returns (uint256) {\n    // shares = (tokens * totalSupply) / yieldSourceBalanceOfAToken\n    return _tokens == 0 ? _tokens : (_tokens * _tokenUnit) / _fullShare;\n  }\n\n  /**\n   * @notice Calculates the number of asset tokens a user has in the yield source.\n   * @param _shares Amount of shares\n   * @param _fullShare Price of a full share\n   * @return Number of asset tokens.\n   */\n  function _sharesToToken(uint256 _shares, uint256 _fullShare) internal view returns (uint256) {\n    // tokens = (shares * yieldSourceBalanceOfAToken) / totalSupply\n    return _shares == 0 ? _shares : (_shares * _fullShare) / _tokenUnit;\n  }\n\n  /**\n   * @notice Retrieves Aave Pool address.\n   * @return A reference to Pool interface.\n   */\n  function _pool() internal view returns (IPool) {\n    return\n      IPool(\n        IPoolAddressesProvider(\n          poolAddressesProviderRegistry.getAddressesProvidersList()[ADDRESSES_PROVIDER_ID]\n        ).getPool()\n      );\n  }\n}\n"
    },
    "@aave/core-v3/contracts/interfaces/IAToken.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0\npragma solidity 0.8.10;\n\nimport {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';\nimport {IScaledBalanceToken} from './IScaledBalanceToken.sol';\nimport {IInitializableAToken} from './IInitializableAToken.sol';\n\n/**\n * @title IAToken\n * @author Aave\n * @notice Defines the basic interface for an AToken.\n **/\ninterface IAToken is IERC20, IScaledBalanceToken, IInitializableAToken {\n  /**\n   * @dev Emitted during the transfer action\n   * @param from The user whose tokens are being transferred\n   * @param to The recipient\n   * @param value The amount being transferred\n   * @param index The next liquidity index of the reserve\n   **/\n  event BalanceTransfer(address indexed from, address indexed to, uint256 value, uint256 index);\n\n  /**\n   * @notice Mints `amount` aTokens to `user`\n   * @param caller The address performing the mint\n   * @param onBehalfOf The address of the user that will receive the minted aTokens\n   * @param amount The amount of tokens getting minted\n   * @param index The next liquidity index of the reserve\n   * @return `true` if the the previous balance of the user was 0\n   */\n  function mint(\n    address caller,\n    address onBehalfOf,\n    uint256 amount,\n    uint256 index\n  ) external returns (bool);\n\n  /**\n   * @notice Burns aTokens from `user` and sends the equivalent amount of underlying to `receiverOfUnderlying`\n   * @dev In some instances, the mint event could be emitted from a burn transaction\n   * if the amount to burn is less than the interest that the user accrued\n   * @param from The address from which the aTokens will be burned\n   * @param receiverOfUnderlying The address that will receive the underlying\n   * @param amount The amount being burned\n   * @param index The next liquidity index of the reserve\n   **/\n  function burn(\n    address from,\n    address receiverOfUnderlying,\n    uint256 amount,\n    uint256 index\n  ) external;\n\n  /**\n   * @notice Mints aTokens to the reserve treasury\n   * @param amount The amount of tokens getting minted\n   * @param index The next liquidity index of the reserve\n   */\n  function mintToTreasury(uint256 amount, uint256 index) external;\n\n  /**\n   * @notice Transfers aTokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken\n   * @param from The address getting liquidated, current owner of the aTokens\n   * @param to The recipient\n   * @param value The amount of tokens getting transferred\n   **/\n  function transferOnLiquidation(\n    address from,\n    address to,\n    uint256 value\n  ) external;\n\n  /**\n   * @notice Transfers the underlying asset to `target`.\n   * @dev Used by the Pool to transfer assets in borrow(), withdraw() and flashLoan()\n   * @param user The recipient of the underlying\n   * @param amount The amount getting transferred\n   **/\n  function transferUnderlyingTo(address user, uint256 amount) external;\n\n  /**\n   * @notice Handles the underlying received by the aToken after the transfer has been completed.\n   * @dev The default implementation is empty as with standard ERC20 tokens, nothing needs to be done after the\n   * transfer is concluded. However in the future there may be aTokens that allow for example to stake the underlying\n   * to receive LM rewards. In that case, `handleRepayment()` would perform the staking of the underlying asset.\n   * @param user The user executing the repayment\n   * @param amount The amount getting repaid\n   **/\n  function handleRepayment(address user, uint256 amount) external;\n\n  /**\n   * @notice Allow passing a signed message to approve spending\n   * @dev implements the permit function as for\n   * https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md\n   * @param owner The owner of the funds\n   * @param spender The spender\n   * @param value The amount\n   * @param deadline The deadline timestamp, type(uint256).max for max deadline\n   * @param v Signature param\n   * @param s Signature param\n   * @param r Signature param\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   * @notice Returns the address of the underlying asset of this aToken (E.g. WETH for aWETH)\n   * @return The address of the underlying asset\n   **/\n  function UNDERLYING_ASSET_ADDRESS() external view returns (address);\n\n  /**\n   * @notice Returns the address of the Aave treasury, receiving the fees on this aToken.\n   * @return Address of the Aave treasury\n   **/\n  function RESERVE_TREASURY_ADDRESS() external view returns (address);\n\n  /**\n   * @notice Get the domain separator for the token\n   * @dev Return cached value if chainId matches cache, otherwise recomputes separator\n   * @return The domain separator of the token at current chain\n   */\n  function DOMAIN_SEPARATOR() external view returns (bytes32);\n\n  /**\n   * @notice Returns the nonce for owner.\n   * @param owner The address of the owner\n   * @return The nonce of the owner\n   **/\n  function nonces(address owner) external view returns (uint256);\n\n  /**\n   * @notice Rescue and transfer tokens locked in this contract\n   * @param token The address of the token\n   * @param to The address of the recipient\n   * @param amount The amount of token to transfer\n   */\n  function rescueTokens(\n    address token,\n    address to,\n    uint256 amount\n  ) external;\n}\n"
    },
    "@aave/core-v3/contracts/interfaces/IPool.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0\npragma solidity 0.8.10;\n\nimport {IPoolAddressesProvider} from './IPoolAddressesProvider.sol';\nimport {DataTypes} from '../protocol/libraries/types/DataTypes.sol';\n\n/**\n * @title IPool\n * @author Aave\n * @notice Defines the basic interface for an Aave Pool.\n **/\ninterface IPool {\n  /**\n   * @dev Emitted on mintUnbacked()\n   * @param reserve The address of the underlying asset of the reserve\n   * @param user The address initiating the supply\n   * @param onBehalfOf The beneficiary of the supplied assets, receiving the aTokens\n   * @param amount The amount of supplied assets\n   * @param referralCode The referral code used\n   **/\n  event MintUnbacked(\n    address indexed reserve,\n    address user,\n    address indexed onBehalfOf,\n    uint256 amount,\n    uint16 indexed referralCode\n  );\n\n  /**\n   * @dev Emitted on backUnbacked()\n   * @param reserve The address of the underlying asset of the reserve\n   * @param backer The address paying for the backing\n   * @param amount The amount added as backing\n   * @param fee The amount paid in fees\n   **/\n  event BackUnbacked(address indexed reserve, address indexed backer, uint256 amount, uint256 fee);\n\n  /**\n   * @dev Emitted on supply()\n   * @param reserve The address of the underlying asset of the reserve\n   * @param user The address initiating the supply\n   * @param onBehalfOf The beneficiary of the supply, receiving the aTokens\n   * @param amount The amount supplied\n   * @param referralCode The referral code used\n   **/\n  event Supply(\n    address indexed reserve,\n    address user,\n    address indexed onBehalfOf,\n    uint256 amount,\n    uint16 indexed referralCode\n  );\n\n  /**\n   * @dev Emitted on withdraw()\n   * @param reserve The address of the underlying asset being withdrawn\n   * @param user The address initiating the withdrawal, owner of aTokens\n   * @param to The address that will receive the underlying\n   * @param amount The amount to be withdrawn\n   **/\n  event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount);\n\n  /**\n   * @dev Emitted on borrow() and flashLoan() when debt needs to be opened\n   * @param reserve The address of the underlying asset being borrowed\n   * @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just\n   * initiator of the transaction on flashLoan()\n   * @param onBehalfOf The address that will be getting the debt\n   * @param amount The amount borrowed out\n   * @param interestRateMode The rate mode: 1 for Stable, 2 for Variable\n   * @param borrowRate The numeric rate at which the user has borrowed, expressed in ray\n   * @param referralCode The referral code used\n   **/\n  event Borrow(\n    address indexed reserve,\n    address user,\n    address indexed onBehalfOf,\n    uint256 amount,\n    DataTypes.InterestRateMode interestRateMode,\n    uint256 borrowRate,\n    uint16 indexed referralCode\n  );\n\n  /**\n   * @dev Emitted on repay()\n   * @param reserve The address of the underlying asset of the reserve\n   * @param user The beneficiary of the repayment, getting his debt reduced\n   * @param repayer The address of the user initiating the repay(), providing the funds\n   * @param amount The amount repaid\n   * @param useATokens True if the repayment is done using aTokens, `false` if done with underlying asset directly\n   **/\n  event Repay(\n    address indexed reserve,\n    address indexed user,\n    address indexed repayer,\n    uint256 amount,\n    bool useATokens\n  );\n\n  /**\n   * @dev Emitted on swapBorrowRateMode()\n   * @param reserve The address of the underlying asset of the reserve\n   * @param user The address of the user swapping his rate mode\n   * @param interestRateMode The current interest rate mode of the position being swapped: 1 for Stable, 2 for Variable\n   **/\n  event SwapBorrowRateMode(\n    address indexed reserve,\n    address indexed user,\n    DataTypes.InterestRateMode interestRateMode\n  );\n\n  /**\n   * @dev Emitted on borrow(), repay() and liquidationCall() when using isolated assets\n   * @param asset The address of the underlying asset of the reserve\n   * @param totalDebt The total isolation mode debt for the reserve\n   */\n  event IsolationModeTotalDebtUpdated(address indexed asset, uint256 totalDebt);\n\n  /**\n   * @dev Emitted when the user selects a certain asset category for eMode\n   * @param user The address of the user\n   * @param categoryId The category id\n   **/\n  event UserEModeSet(address indexed user, uint8 categoryId);\n\n  /**\n   * @dev Emitted on setUserUseReserveAsCollateral()\n   * @param reserve The address of the underlying asset of the reserve\n   * @param user The address of the user enabling the usage as collateral\n   **/\n  event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user);\n\n  /**\n   * @dev Emitted on setUserUseReserveAsCollateral()\n   * @param reserve The address of the underlying asset of the reserve\n   * @param user The address of the user enabling the usage as collateral\n   **/\n  event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user);\n\n  /**\n   * @dev Emitted on rebalanceStableBorrowRate()\n   * @param reserve The address of the underlying asset of the reserve\n   * @param user The address of the user for which the rebalance has been executed\n   **/\n  event RebalanceStableBorrowRate(address indexed reserve, address indexed user);\n\n  /**\n   * @dev Emitted on flashLoan()\n   * @param target The address of the flash loan receiver contract\n   * @param initiator The address initiating the flash loan\n   * @param asset The address of the asset being flash borrowed\n   * @param amount The amount flash borrowed\n   * @param interestRateMode The flashloan mode: 0 for regular flashloan, 1 for Stable debt, 2 for Variable debt\n   * @param premium The fee flash borrowed\n   * @param referralCode The referral code used\n   **/\n  event FlashLoan(\n    address indexed target,\n    address initiator,\n    address indexed asset,\n    uint256 amount,\n    DataTypes.InterestRateMode interestRateMode,\n    uint256 premium,\n    uint16 indexed referralCode\n  );\n\n  /**\n   * @dev Emitted when a borrower is liquidated.\n   * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation\n   * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation\n   * @param user The address of the borrower getting liquidated\n   * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover\n   * @param liquidatedCollateralAmount The amount of collateral received by the liquidator\n   * @param liquidator The address of the liquidator\n   * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants\n   * to receive the underlying collateral asset directly\n   **/\n  event LiquidationCall(\n    address indexed collateralAsset,\n    address indexed debtAsset,\n    address indexed user,\n    uint256 debtToCover,\n    uint256 liquidatedCollateralAmount,\n    address liquidator,\n    bool receiveAToken\n  );\n\n  /**\n   * @dev Emitted when the state of a reserve is updated.\n   * @param reserve The address of the underlying asset of the reserve\n   * @param liquidityRate The next liquidity rate\n   * @param stableBorrowRate The next stable borrow rate\n   * @param variableBorrowRate The next variable borrow rate\n   * @param liquidityIndex The next liquidity index\n   * @param variableBorrowIndex The next variable borrow index\n   **/\n  event ReserveDataUpdated(\n    address indexed reserve,\n    uint256 liquidityRate,\n    uint256 stableBorrowRate,\n    uint256 variableBorrowRate,\n    uint256 liquidityIndex,\n    uint256 variableBorrowIndex\n  );\n\n  /**\n   * @dev Emitted when the protocol treasury receives minted aTokens from the accrued interest.\n   * @param reserve The address of the reserve\n   * @param amountMinted The amount minted to the treasury\n   **/\n  event MintedToTreasury(address indexed reserve, uint256 amountMinted);\n\n  /**\n   * @dev Mints an `amount` of aTokens to the `onBehalfOf`\n   * @param asset The address of the underlying asset to mint\n   * @param amount The amount to mint\n   * @param onBehalfOf The address that will receive the aTokens\n   * @param referralCode Code used to register the integrator originating the operation, for potential rewards.\n   *   0 if the action is executed directly by the user, without any middle-man\n   **/\n  function mintUnbacked(\n    address asset,\n    uint256 amount,\n    address onBehalfOf,\n    uint16 referralCode\n  ) external;\n\n  /**\n   * @dev Back the current unbacked underlying with `amount` and pay `fee`.\n   * @param asset The address of the underlying asset to back\n   * @param amount The amount to back\n   * @param fee The amount paid in fees\n   **/\n  function backUnbacked(\n    address asset,\n    uint256 amount,\n    uint256 fee\n  ) external;\n\n  /**\n   * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.\n   * - E.g. User supplies 100 USDC and gets in return 100 aUSDC\n   * @param asset The address of the underlying asset to supply\n   * @param amount The amount to be supplied\n   * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user\n   *   wants to receive them on his own wallet, or a different address if the beneficiary of aTokens\n   *   is a different wallet\n   * @param referralCode Code used to register the integrator originating the operation, for potential rewards.\n   *   0 if the action is executed directly by the user, without any middle-man\n   **/\n  function supply(\n    address asset,\n    uint256 amount,\n    address onBehalfOf,\n    uint16 referralCode\n  ) external;\n\n  /**\n   * @notice Supply with transfer approval of asset to be supplied done via permit function\n   * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713\n   * @param asset The address of the underlying asset to supply\n   * @param amount The amount to be supplied\n   * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user\n   *   wants to receive them on his own wallet, or a different address if the beneficiary of aTokens\n   *   is a different wallet\n   * @param deadline The deadline timestamp that the permit is valid\n   * @param referralCode Code used to register the integrator originating the operation, for potential rewards.\n   *   0 if the action is executed directly by the user, without any middle-man\n   * @param permitV The V parameter of ERC712 permit sig\n   * @param permitR The R parameter of ERC712 permit sig\n   * @param permitS The S parameter of ERC712 permit sig\n   **/\n  function supplyWithPermit(\n    address asset,\n    uint256 amount,\n    address onBehalfOf,\n    uint16 referralCode,\n    uint256 deadline,\n    uint8 permitV,\n    bytes32 permitR,\n    bytes32 permitS\n  ) external;\n\n  /**\n   * @notice Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned\n   * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC\n   * @param asset The address of the underlying asset to withdraw\n   * @param amount The underlying amount to be withdrawn\n   *   - Send the value type(uint256).max in order to withdraw the whole aToken balance\n   * @param to The address that will receive the underlying, same as msg.sender if the user\n   *   wants to receive it on his own wallet, or a different address if the beneficiary is a\n   *   different wallet\n   * @return The final amount withdrawn\n   **/\n  function withdraw(\n    address asset,\n    uint256 amount,\n    address to\n  ) external returns (uint256);\n\n  /**\n   * @notice Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower\n   * already supplied enough collateral, or he was given enough allowance by a credit delegator on the\n   * corresponding debt token (StableDebtToken or VariableDebtToken)\n   * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet\n   *   and 100 stable/variable debt tokens, depending on the `interestRateMode`\n   * @param asset The address of the underlying asset to borrow\n   * @param amount The amount to be borrowed\n   * @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable\n   * @param referralCode The code used to register the integrator originating the operation, for potential rewards.\n   *   0 if the action is executed directly by the user, without any middle-man\n   * @param onBehalfOf The address of the user who will receive the debt. Should be the address of the borrower itself\n   * calling the function if he wants to borrow against his own collateral, or the address of the credit delegator\n   * if he has been given credit delegation allowance\n   **/\n  function borrow(\n    address asset,\n    uint256 amount,\n    uint256 interestRateMode,\n    uint16 referralCode,\n    address onBehalfOf\n  ) external;\n\n  /**\n   * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned\n   * - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address\n   * @param asset The address of the borrowed underlying asset previously borrowed\n   * @param amount The amount to repay\n   * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`\n   * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable\n   * @param onBehalfOf The address of the user who will get his debt reduced/removed. Should be the address of the\n   * user calling the function if he wants to reduce/remove his own debt, or the address of any other\n   * other borrower whose debt should be removed\n   * @return The final amount repaid\n   **/\n  function repay(\n    address asset,\n    uint256 amount,\n    uint256 interestRateMode,\n    address onBehalfOf\n  ) external returns (uint256);\n\n  /**\n   * @notice Repay with transfer approval of asset to be repaid done via permit function\n   * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713\n   * @param asset The address of the borrowed underlying asset previously borrowed\n   * @param amount The amount to repay\n   * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`\n   * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable\n   * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the\n   * user calling the function if he wants to reduce/remove his own debt, or the address of any other\n   * other borrower whose debt should be removed\n   * @param deadline The deadline timestamp that the permit is valid\n   * @param permitV The V parameter of ERC712 permit sig\n   * @param permitR The R parameter of ERC712 permit sig\n   * @param permitS The S parameter of ERC712 permit sig\n   * @return The final amount repaid\n   **/\n  function repayWithPermit(\n    address asset,\n    uint256 amount,\n    uint256 interestRateMode,\n    address onBehalfOf,\n    uint256 deadline,\n    uint8 permitV,\n    bytes32 permitR,\n    bytes32 permitS\n  ) external returns (uint256);\n\n  /**\n   * @notice Repays a borrowed `amount` on a specific reserve using the reserve aTokens, burning the\n   * equivalent debt tokens\n   * - E.g. User repays 100 USDC using 100 aUSDC, burning 100 variable/stable debt tokens\n   * @dev  Passing uint256.max as amount will clean up any residual aToken dust balance, if the user aToken\n   * balance is not enough to cover the whole debt\n   * @param asset The address of the borrowed underlying asset previously borrowed\n   * @param amount The amount to repay\n   * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`\n   * @param interestRateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable\n   * @return The final amount repaid\n   **/\n  function repayWithATokens(\n    address asset,\n    uint256 amount,\n    uint256 interestRateMode\n  ) external returns (uint256);\n\n  /**\n   * @notice Allows a borrower to swap his debt between stable and variable mode, or vice versa\n   * @param asset The address of the underlying asset borrowed\n   * @param interestRateMode The rate mode that the user wants to swap to: 1 for Stable, 2 for Variable\n   **/\n  function swapBorrowRateMode(address asset, uint256 interestRateMode) external;\n\n  /**\n   * @notice Rebalances the stable interest rate of a user to the current stable rate defined on the reserve.\n   * - Users can be rebalanced if the following conditions are satisfied:\n   *     1. Usage ratio is above 95%\n   *     2. the current supply APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too\n   *        much has been borrowed at a stable rate and suppliers are not earning enough\n   * @param asset The address of the underlying asset borrowed\n   * @param user The address of the user to be rebalanced\n   **/\n  function rebalanceStableBorrowRate(address asset, address user) external;\n\n  /**\n   * @notice Allows suppliers to enable/disable a specific supplied asset as collateral\n   * @param asset The address of the underlying asset supplied\n   * @param useAsCollateral True if the user wants to use the supply as collateral, false otherwise\n   **/\n  function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external;\n\n  /**\n   * @notice Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1\n   * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives\n   *   a proportionally amount of the `collateralAsset` plus a bonus to cover market risk\n   * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation\n   * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation\n   * @param user The address of the borrower getting liquidated\n   * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover\n   * @param receiveAToken True if the liquidators wants to receive the collateral aTokens, `false` if he wants\n   * to receive the underlying collateral asset directly\n   **/\n  function liquidationCall(\n    address collateralAsset,\n    address debtAsset,\n    address user,\n    uint256 debtToCover,\n    bool receiveAToken\n  ) external;\n\n  /**\n   * @notice Allows smartcontracts to access the liquidity of the pool within one transaction,\n   * as long as the amount taken plus a fee is returned.\n   * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept\n   * into consideration. For further details please visit https://developers.aave.com\n   * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanReceiver interface\n   * @param assets The addresses of the assets being flash-borrowed\n   * @param amounts The amounts of the assets being flash-borrowed\n   * @param interestRateModes Types of the debt to open if the flash loan is not returned:\n   *   0 -> Don't open any debt, just revert if funds can't be transferred from the receiver\n   *   1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address\n   *   2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address\n   * @param onBehalfOf The address  that will receive the debt in the case of using on `modes` 1 or 2\n   * @param params Variadic packed params to pass to the receiver as extra information\n   * @param referralCode The code used to register the integrator originating the operation, for potential rewards.\n   *   0 if the action is executed directly by the user, without any middle-man\n   **/\n  function flashLoan(\n    address receiverAddress,\n    address[] calldata assets,\n    uint256[] calldata amounts,\n    uint256[] calldata interestRateModes,\n    address onBehalfOf,\n    bytes calldata params,\n    uint16 referralCode\n  ) external;\n\n  /**\n   * @notice Allows smartcontracts to access the liquidity of the pool within one transaction,\n   * as long as the amount taken plus a fee is returned.\n   * @dev IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept\n   * into consideration. For further details please visit https://developers.aave.com\n   * @param receiverAddress The address of the contract receiving the funds, implementing IFlashLoanSimpleReceiver interface\n   * @param asset The address of the asset being flash-borrowed\n   * @param amount The amount of the asset being flash-borrowed\n   * @param params Variadic packed params to pass to the receiver as extra information\n   * @param referralCode The code used to register the integrator originating the operation, for potential rewards.\n   *   0 if the action is executed directly by the user, without any middle-man\n   **/\n  function flashLoanSimple(\n    address receiverAddress,\n    address asset,\n    uint256 amount,\n    bytes calldata params,\n    uint16 referralCode\n  ) external;\n\n  /**\n   * @notice Returns the user account data across all the reserves\n   * @param user The address of the user\n   * @return totalCollateralBase The total collateral of the user in the base currency used by the price feed\n   * @return totalDebtBase The total debt of the user in the base currency used by the price feed\n   * @return availableBorrowsBase The borrowing power left of the user in the base currency used by the price feed\n   * @return currentLiquidationThreshold The liquidation threshold of the user\n   * @return ltv The loan to value of The user\n   * @return healthFactor The current health factor of the user\n   **/\n  function getUserAccountData(address user)\n    external\n    view\n    returns (\n      uint256 totalCollateralBase,\n      uint256 totalDebtBase,\n      uint256 availableBorrowsBase,\n      uint256 currentLiquidationThreshold,\n      uint256 ltv,\n      uint256 healthFactor\n    );\n\n  /**\n   * @notice Initializes a reserve, activating it, assigning an aToken and debt tokens and an\n   * interest rate strategy\n   * @dev Only callable by the PoolConfigurator contract\n   * @param asset The address of the underlying asset of the reserve\n   * @param aTokenAddress The address of the aToken that will be assigned to the reserve\n   * @param stableDebtAddress The address of the StableDebtToken that will be assigned to the reserve\n   * @param variableDebtAddress The address of the VariableDebtToken that will be assigned to the reserve\n   * @param interestRateStrategyAddress The address of the interest rate strategy contract\n   **/\n  function initReserve(\n    address asset,\n    address aTokenAddress,\n    address stableDebtAddress,\n    address variableDebtAddress,\n    address interestRateStrategyAddress\n  ) external;\n\n  /**\n   * @notice Drop a reserve\n   * @dev Only callable by the PoolConfigurator contract\n   * @param asset The address of the underlying asset of the reserve\n   **/\n  function dropReserve(address asset) external;\n\n  /**\n   * @notice Updates the address of the interest rate strategy contract\n   * @dev Only callable by the PoolConfigurator contract\n   * @param asset The address of the underlying asset of the reserve\n   * @param rateStrategyAddress The address of the interest rate strategy contract\n   **/\n  function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress)\n    external;\n\n  /**\n   * @notice Sets the configuration bitmap of the reserve as a whole\n   * @dev Only callable by the PoolConfigurator contract\n   * @param asset The address of the underlying asset of the reserve\n   * @param configuration The new configuration bitmap\n   **/\n  function setConfiguration(address asset, DataTypes.ReserveConfigurationMap calldata configuration)\n    external;\n\n  /**\n   * @notice Returns the configuration of the reserve\n   * @param asset The address of the underlying asset of the reserve\n   * @return The configuration of the reserve\n   **/\n  function getConfiguration(address asset)\n    external\n    view\n    returns (DataTypes.ReserveConfigurationMap memory);\n\n  /**\n   * @notice Returns the configuration of the user across all the reserves\n   * @param user The user address\n   * @return The configuration of the user\n   **/\n  function getUserConfiguration(address user)\n    external\n    view\n    returns (DataTypes.UserConfigurationMap memory);\n\n  /**\n   * @notice Returns the normalized income normalized income of the reserve\n   * @param asset The address of the underlying asset of the reserve\n   * @return The reserve's normalized income\n   */\n  function getReserveNormalizedIncome(address asset) external view returns (uint256);\n\n  /**\n   * @notice Returns the normalized variable debt per unit of asset\n   * @param asset The address of the underlying asset of the reserve\n   * @return The reserve normalized variable debt\n   */\n  function getReserveNormalizedVariableDebt(address asset) external view returns (uint256);\n\n  /**\n   * @notice Returns the state and configuration of the reserve\n   * @param asset The address of the underlying asset of the reserve\n   * @return The state and configuration data of the reserve\n   **/\n  function getReserveData(address asset) external view returns (DataTypes.ReserveData memory);\n\n  /**\n   * @notice Validates and finalizes an aToken transfer\n   * @dev Only callable by the overlying aToken of the `asset`\n   * @param asset The address of the underlying asset of the aToken\n   * @param from The user from which the aTokens are transferred\n   * @param to The user receiving the aTokens\n   * @param amount The amount being transferred/withdrawn\n   * @param balanceFromBefore The aToken balance of the `from` user before the transfer\n   * @param balanceToBefore The aToken balance of the `to` user before the transfer\n   */\n  function finalizeTransfer(\n    address asset,\n    address from,\n    address to,\n    uint256 amount,\n    uint256 balanceFromBefore,\n    uint256 balanceToBefore\n  ) external;\n\n  /**\n   * @notice Returns the list of the initialized reserves\n   * @dev It does not include dropped reserves\n   * @return The addresses of the reserves\n   **/\n  function getReservesList() external view returns (address[] memory);\n\n  /**\n   * @notice Returns the PoolAddressesProvider connected to this contract\n   * @return The address of the PoolAddressesProvider\n   **/\n  function ADDRESSES_PROVIDER() external view returns (IPoolAddressesProvider);\n\n  /**\n   * @notice Updates the protocol fee on the bridging\n   * @param bridgeProtocolFee The part of the premium sent to the protocol treasury\n   */\n  function updateBridgeProtocolFee(uint256 bridgeProtocolFee) external;\n\n  /**\n   * @notice Updates flash loan premiums. Flash loan premium consists of two parts:\n   * - A part is sent to aToken holders as extra, one time accumulated interest\n   * - A part is collected by the protocol treasury\n   * @dev The total premium is calculated on the total borrowed amount\n   * @dev The premium to protocol is calculated on the total premium, being a percentage of `flashLoanPremiumTotal`\n   * @dev Only callable by the PoolConfigurator contract\n   * @param flashLoanPremiumTotal The total premium, expressed in bps\n   * @param flashLoanPremiumToProtocol The part of the premium sent to the protocol treasury, expressed in bps\n   */\n  function updateFlashloanPremiums(\n    uint128 flashLoanPremiumTotal,\n    uint128 flashLoanPremiumToProtocol\n  ) external;\n\n  /**\n   * @notice Configures a new category for the eMode.\n   * @dev In eMode, the protocol allows very high borrowing power to borrow assets of the same category.\n   * The category 0 is reserved as it's the default for volatile assets\n   * @param id The id of the category\n   * @param config The configuration of the category\n   */\n  function configureEModeCategory(uint8 id, DataTypes.EModeCategory memory config) external;\n\n  /**\n   * @notice Returns the data of an eMode category\n   * @param id The id of the category\n   * @return The configuration data of the category\n   */\n  function getEModeCategoryData(uint8 id) external view returns (DataTypes.EModeCategory memory);\n\n  /**\n   * @notice Allows a user to use the protocol in eMode\n   * @param categoryId The id of the category\n   */\n  function setUserEMode(uint8 categoryId) external;\n\n  /**\n   * @notice Returns the eMode the user is using\n   * @param user The address of the user\n   * @return The eMode id\n   */\n  function getUserEMode(address user) external view returns (uint256);\n\n  /**\n   * @notice Resets the isolation mode total debt of the given asset to zero\n   * @dev It requires the given asset has zero debt ceiling\n   * @param asset The address of the underlying asset to reset the isolationModeTotalDebt\n   */\n  function resetIsolationModeTotalDebt(address asset) external;\n\n  /**\n   * @notice Returns the percentage of available liquidity that can be borrowed at once at stable rate\n   * @return The percentage of available liquidity to borrow, expressed in bps\n   */\n  function MAX_STABLE_RATE_BORROW_SIZE_PERCENT() external view returns (uint256);\n\n  /**\n   * @notice Returns the total fee on flash loans\n   * @return The total fee on flashloans\n   */\n  function FLASHLOAN_PREMIUM_TOTAL() external view returns (uint128);\n\n  /**\n   * @notice Returns the part of the bridge fees sent to protocol\n   * @return The bridge fee sent to the protocol treasury\n   */\n  function BRIDGE_PROTOCOL_FEE() external view returns (uint256);\n\n  /**\n   * @notice Returns the part of the flashloan fees sent to protocol\n   * @return The flashloan fee sent to the protocol treasury\n   */\n  function FLASHLOAN_PREMIUM_TO_PROTOCOL() external view returns (uint128);\n\n  /**\n   * @notice Returns the maximum number of reserves supported to be listed in this Pool\n   * @return The maximum number of reserves supported\n   */\n  function MAX_NUMBER_RESERVES() external view returns (uint16);\n\n  /**\n   * @notice Mints the assets accrued through the reserve factor to the treasury in the form of aTokens\n   * @param assets The list of reserves for which the minting needs to be executed\n   **/\n  function mintToTreasury(address[] calldata assets) external;\n\n  /**\n   * @notice Rescue and transfer tokens locked in this contract\n   * @param token The address of the token\n   * @param to The address of the recipient\n   * @param amount The amount of token to transfer\n   */\n  function rescueTokens(\n    address token,\n    address to,\n    uint256 amount\n  ) external;\n\n  /**\n   * @notice Supplies an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.\n   * - E.g. User supplies 100 USDC and gets in return 100 aUSDC\n   * @dev Deprecated: Use the `supply` function instead\n   * @param asset The address of the underlying asset to supply\n   * @param amount The amount to be supplied\n   * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user\n   *   wants to receive them on his own wallet, or a different address if the beneficiary of aTokens\n   *   is a different wallet\n   * @param referralCode Code used to register the integrator originating the operation, for potential rewards.\n   *   0 if the action is executed directly by the user, without any middle-man\n   **/\n  function deposit(\n    address asset,\n    uint256 amount,\n    address onBehalfOf,\n    uint16 referralCode\n  ) external;\n}\n"
    },
    "@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0\npragma solidity 0.8.10;\n\n/**\n * @title IPoolAddressesProvider\n * @author Aave\n * @notice Defines the basic interface for a Pool Addresses Provider.\n **/\ninterface IPoolAddressesProvider {\n  /**\n   * @dev Emitted when the market identifier is updated.\n   * @param oldMarketId The old id of the market\n   * @param newMarketId The new id of the market\n   */\n  event MarketIdSet(string indexed oldMarketId, string indexed newMarketId);\n\n  /**\n   * @dev Emitted when the pool is updated.\n   * @param oldAddress The old address of the Pool\n   * @param newAddress The new address of the Pool\n   */\n  event PoolUpdated(address indexed oldAddress, address indexed newAddress);\n\n  /**\n   * @dev Emitted when the pool configurator is updated.\n   * @param oldAddress The old address of the PoolConfigurator\n   * @param newAddress The new address of the PoolConfigurator\n   */\n  event PoolConfiguratorUpdated(address indexed oldAddress, address indexed newAddress);\n\n  /**\n   * @dev Emitted when the price oracle is updated.\n   * @param oldAddress The old address of the PriceOracle\n   * @param newAddress The new address of the PriceOracle\n   */\n  event PriceOracleUpdated(address indexed oldAddress, address indexed newAddress);\n\n  /**\n   * @dev Emitted when the ACL manager is updated.\n   * @param oldAddress The old address of the ACLManager\n   * @param newAddress The new address of the ACLManager\n   */\n  event ACLManagerUpdated(address indexed oldAddress, address indexed newAddress);\n\n  /**\n   * @dev Emitted when the ACL admin is updated.\n   * @param oldAddress The old address of the ACLAdmin\n   * @param newAddress The new address of the ACLAdmin\n   */\n  event ACLAdminUpdated(address indexed oldAddress, address indexed newAddress);\n\n  /**\n   * @dev Emitted when the price oracle sentinel is updated.\n   * @param oldAddress The old address of the PriceOracleSentinel\n   * @param newAddress The new address of the PriceOracleSentinel\n   */\n  event PriceOracleSentinelUpdated(address indexed oldAddress, address indexed newAddress);\n\n  /**\n   * @dev Emitted when the pool data provider is updated.\n   * @param oldAddress The old address of the PoolDataProvider\n   * @param newAddress The new address of the PoolDataProvider\n   */\n  event PoolDataProviderUpdated(address indexed oldAddress, address indexed newAddress);\n\n  /**\n   * @dev Emitted when a new proxy is created.\n   * @param id The identifier of the proxy\n   * @param proxyAddress The address of the created proxy contract\n   * @param implementationAddress The address of the implementation contract\n   */\n  event ProxyCreated(\n    bytes32 indexed id,\n    address indexed proxyAddress,\n    address indexed implementationAddress\n  );\n\n  /**\n   * @dev Emitted when a new non-proxied contract address is registered.\n   * @param id The identifier of the contract\n   * @param oldAddress The address of the old contract\n   * @param newAddress The address of the new contract\n   */\n  event AddressSet(bytes32 indexed id, address indexed oldAddress, address indexed newAddress);\n\n  /**\n   * @dev Emitted when the implementation of the proxy registered with id is updated\n   * @param id The identifier of the contract\n   * @param proxyAddress The address of the proxy contract\n   * @param oldImplementationAddress The address of the old implementation contract\n   * @param newImplementationAddress The address of the new implementation contract\n   */\n  event AddressSetAsProxy(\n    bytes32 indexed id,\n    address indexed proxyAddress,\n    address oldImplementationAddress,\n    address indexed newImplementationAddress\n  );\n\n  /**\n   * @notice Returns the id of the Aave market to which this contract points to.\n   * @return The market id\n   **/\n  function getMarketId() external view returns (string memory);\n\n  /**\n   * @notice Associates an id with a specific PoolAddressesProvider.\n   * @dev This can be used to create an onchain registry of PoolAddressesProviders to\n   * identify and validate multiple Aave markets.\n   * @param newMarketId The market id\n   */\n  function setMarketId(string calldata newMarketId) external;\n\n  /**\n   * @notice Returns an address by its identifier.\n   * @dev The returned address might be an EOA or a contract, potentially proxied\n   * @dev It returns ZERO if there is no registered address with the given id\n   * @param id The id\n   * @return The address of the registered for the specified id\n   */\n  function getAddress(bytes32 id) external view returns (address);\n\n  /**\n   * @notice General function to update the implementation of a proxy registered with\n   * certain `id`. If there is no proxy registered, it will instantiate one and\n   * set as implementation the `newImplementationAddress`.\n   * @dev IMPORTANT Use this function carefully, only for ids that don't have an explicit\n   * setter function, in order to avoid unexpected consequences\n   * @param id The id\n   * @param newImplementationAddress The address of the new implementation\n   */\n  function setAddressAsProxy(bytes32 id, address newImplementationAddress) external;\n\n  /**\n   * @notice Sets an address for an id replacing the address saved in the addresses map.\n   * @dev IMPORTANT Use this function carefully, as it will do a hard replacement\n   * @param id The id\n   * @param newAddress The address to set\n   */\n  function setAddress(bytes32 id, address newAddress) external;\n\n  /**\n   * @notice Returns the address of the Pool proxy.\n   * @return The Pool proxy address\n   **/\n  function getPool() external view returns (address);\n\n  /**\n   * @notice Updates the implementation of the Pool, or creates a proxy\n   * setting the new `pool` implementation when the function is called for the first time.\n   * @param newPoolImpl The new Pool implementation\n   **/\n  function setPoolImpl(address newPoolImpl) external;\n\n  /**\n   * @notice Returns the address of the PoolConfigurator proxy.\n   * @return The PoolConfigurator proxy address\n   **/\n  function getPoolConfigurator() external view returns (address);\n\n  /**\n   * @notice Updates the implementation of the PoolConfigurator, or creates a proxy\n   * setting the new `PoolConfigurator` implementation when the function is called for the first time.\n   * @param newPoolConfiguratorImpl The new PoolConfigurator implementation\n   **/\n  function setPoolConfiguratorImpl(address newPoolConfiguratorImpl) external;\n\n  /**\n   * @notice Returns the address of the price oracle.\n   * @return The address of the PriceOracle\n   */\n  function getPriceOracle() external view returns (address);\n\n  /**\n   * @notice Updates the address of the price oracle.\n   * @param newPriceOracle The address of the new PriceOracle\n   */\n  function setPriceOracle(address newPriceOracle) external;\n\n  /**\n   * @notice Returns the address of the ACL manager.\n   * @return The address of the ACLManager\n   */\n  function getACLManager() external view returns (address);\n\n  /**\n   * @notice Updates the address of the ACL manager.\n   * @param newAclManager The address of the new ACLManager\n   **/\n  function setACLManager(address newAclManager) external;\n\n  /**\n   * @notice Returns the address of the ACL admin.\n   * @return The address of the ACL admin\n   */\n  function getACLAdmin() external view returns (address);\n\n  /**\n   * @notice Updates the address of the ACL admin.\n   * @param newAclAdmin The address of the new ACL admin\n   */\n  function setACLAdmin(address newAclAdmin) external;\n\n  /**\n   * @notice Returns the address of the price oracle sentinel.\n   * @return The address of the PriceOracleSentinel\n   */\n  function getPriceOracleSentinel() external view returns (address);\n\n  /**\n   * @notice Updates the address of the price oracle sentinel.\n   * @param newPriceOracleSentinel The address of the new PriceOracleSentinel\n   **/\n  function setPriceOracleSentinel(address newPriceOracleSentinel) external;\n\n  /**\n   * @notice Returns the address of the data provider.\n   * @return The address of the DataProvider\n   */\n  function getPoolDataProvider() external view returns (address);\n\n  /**\n   * @notice Updates the address of the data provider.\n   * @param newDataProvider The address of the new DataProvider\n   **/\n  function setPoolDataProvider(address newDataProvider) external;\n}\n"
    },
    "@aave/core-v3/contracts/interfaces/IPoolAddressesProviderRegistry.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0\npragma solidity 0.8.10;\n\n/**\n * @title IPoolAddressesProviderRegistry\n * @author Aave\n * @notice Defines the basic interface for an Aave Pool Addresses Provider Registry.\n **/\ninterface IPoolAddressesProviderRegistry {\n  /**\n   * @dev Emitted when a new AddressesProvider is registered.\n   * @param addressesProvider The address of the registered PoolAddressesProvider\n   * @param id The id of the registered PoolAddressesProvider\n   */\n  event AddressesProviderRegistered(address indexed addressesProvider, uint256 indexed id);\n\n  /**\n   * @dev Emitted when an AddressesProvider is unregistered.\n   * @param addressesProvider The address of the unregistered PoolAddressesProvider\n   * @param id The id of the unregistered PoolAddressesProvider\n   */\n  event AddressesProviderUnregistered(address indexed addressesProvider, uint256 indexed id);\n\n  /**\n   * @notice Returns the list of registered addresses providers\n   * @return The list of addresses providers\n   **/\n  function getAddressesProvidersList() external view returns (address[] memory);\n\n  /**\n   * @notice Returns the id of a registered PoolAddressesProvider\n   * @param addressesProvider The address of the PoolAddressesProvider\n   * @return The id of the PoolAddressesProvider or 0 if is not registered\n   */\n  function getAddressesProviderIdByAddress(address addressesProvider)\n    external\n    view\n    returns (uint256);\n\n  /**\n   * @notice Returns the address of a registered PoolAddressesProvider\n   * @param id The id of the market\n   * @return The address of the PoolAddressesProvider with the given id or zero address if it is not registered\n   */\n  function getAddressesProviderAddressById(uint256 id) external view returns (address);\n\n  /**\n   * @notice Registers an addresses provider\n   * @dev The PoolAddressesProvider must not already be registered in the registry\n   * @dev The id must not be used by an already registered PoolAddressesProvider\n   * @param provider The address of the new PoolAddressesProvider\n   * @param id The id for the new PoolAddressesProvider, referring to the market it belongs to\n   **/\n  function registerAddressesProvider(address provider, uint256 id) external;\n\n  /**\n   * @notice Removes an addresses provider from the list of registered addresses providers\n   * @param provider The PoolAddressesProvider address\n   **/\n  function unregisterAddressesProvider(address provider) external;\n}\n"
    },
    "@aave/periphery-v3/contracts/rewards/interfaces/IRewardsController.sol": {
      "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.8.10;\n\nimport {IRewardsDistributor} from './IRewardsDistributor.sol';\nimport {RewardsDistributorTypes} from '../libraries/RewardsDistributorTypes.sol';\nimport {ITransferStrategyBase} from './ITransferStrategyBase.sol';\nimport {IEACAggregatorProxy} from '../../misc/interfaces/IEACAggregatorProxy.sol';\n\ninterface IRewardsController is IRewardsDistributor {\n  event ClaimerSet(address indexed user, address indexed claimer);\n\n  event RewardsClaimed(\n    address indexed user,\n    address indexed reward,\n    address indexed to,\n    address claimer,\n    uint256 amount\n  );\n\n  event TransferStrategyInstalled(address indexed reward, address indexed transferStrategy);\n\n  event RewardOracleUpdated(address indexed reward, address indexed rewardOracle);\n\n  /**\n   * @dev Whitelists an address to claim the rewards on behalf of another address\n   * @param user The address of the user\n   * @param claimer The address of the claimer\n   */\n  function setClaimer(address user, address claimer) external;\n\n  /**\n   * @dev Sets a TransferStrategy logic contract that determines the logic of the rewards transfer\n   * @param reward The address of the reward token\n   * @param transferStrategy The address of the TransferStrategy logic contract\n   */\n  function setTransferStrategy(address reward, ITransferStrategyBase transferStrategy) external;\n\n  /**\n   * @dev Sets an Aave Oracle contract to enforce rewards with a source of value.\n   * @notice At the moment of reward configuration, the Incentives Controller performs\n   * a check to see if the reward asset oracle is compatible with IEACAggregator proxy.\n   * This check is enforced for integrators to be able to show incentives at\n   * the current Aave UI without the need to setup an external price registry\n   * @param reward The address of the reward to set the price aggregator\n   * @param rewardOracle The address of price aggregator that follows IEACAggregatorProxy interface\n   */\n  function setRewardOracle(address reward, IEACAggregatorProxy rewardOracle) external;\n\n  /**\n   * @dev Get the price aggregator oracle address\n   * @param reward The address of the reward\n   * @return The price oracle of the reward\n   */\n  function getRewardOracle(address reward) external view returns (address);\n\n  /**\n   * @dev Returns the whitelisted claimer for a certain address (0x0 if not set)\n   * @param user The address of the user\n   * @return The claimer address\n   */\n  function getClaimer(address user) external view returns (address);\n\n  /**\n   * @dev Returns the Transfer Strategy implementation contract address being used for a reward address\n   * @param reward The address of the reward\n   * @return The address of the TransferStrategy contract\n   */\n  function getTransferStrategy(address reward) external view returns (address);\n\n  /**\n   * @dev Configure assets to incentivize with an emission of rewards per second until the end of distribution.\n   * @param config The assets configuration input, the list of structs contains the following fields:\n   *   uint104 emissionPerSecond: The emission per second following rewards unit decimals.\n   *   uint256 totalSupply: The total supply of the asset to incentivize\n   *   uint40 distributionEnd: The end of the distribution of the incentives for an asset\n   *   address asset: The asset address to incentivize\n   *   address reward: The reward token address\n   *   ITransferStrategy transferStrategy: The TransferStrategy address with the install hook and claim logic.\n   *   IEACAggregatorProxy rewardOracle: The Price Oracle of a reward to visualize the incentives at the UI Frontend.\n   *                                     Must follow Chainlink Aggregator IEACAggregatorProxy interface to be compatible.\n   */\n  function configureAssets(RewardsDistributorTypes.RewardsConfigInput[] memory config) external;\n\n  /**\n   * @dev Called by the corresponding asset on any update that affects the rewards distribution\n   * @param user The address of the user\n   * @param userBalance The user balance of the asset\n   * @param totalSupply The total supply of the asset\n   **/\n  function handleAction(\n    address user,\n    uint256 userBalance,\n    uint256 totalSupply\n  ) external;\n\n  /**\n   * @dev Claims reward for an user to the desired address, on all the assets of the lending pool, accumulating the pending rewards\n   * @param assets List of assets to check eligible distributions before claiming rewards\n   * @param amount Amount of rewards to claim\n   * @param to Address that will be receiving the rewards\n   * @param reward Address of the reward token\n   * @return Rewards claimed\n   **/\n  function claimRewards(\n    address[] calldata assets,\n    uint256 amount,\n    address to,\n    address reward\n  ) external returns (uint256);\n\n  /**\n   * @dev Claims reward for an user on behalf, on all the assets of the lending pool, accumulating the pending rewards. The caller must\n   * be whitelisted via \"allowClaimOnBehalf\" function by the RewardsAdmin role manager\n   * @param assets List of assets to check eligible distributions before claiming rewards\n   * @param amount Amount of rewards to claim\n   * @param user Address to check and claim rewards\n   * @param to Address that will be receiving the rewards\n   * @param reward Address of the reward token\n   * @return Rewards claimed\n   **/\n  function claimRewardsOnBehalf(\n    address[] calldata assets,\n    uint256 amount,\n    address user,\n    address to,\n    address reward\n  ) external returns (uint256);\n\n  /**\n   * @dev Claims reward for msg.sender, on all the assets of the lending pool, accumulating the pending rewards\n   * @param assets List of assets to check eligible distributions before claiming rewards\n   * @param amount Amount of rewards to claim\n   * @param reward Address of the reward token\n   * @return Rewards claimed\n   **/\n  function claimRewardsToSelf(\n    address[] calldata assets,\n    uint256 amount,\n    address reward\n  ) external returns (uint256);\n\n  /**\n   * @dev Claims all rewards for an user to the desired address, on all the assets of the lending pool, accumulating the pending rewards\n   * @param assets List of assets to check eligible distributions before claiming rewards\n   * @param to Address that will be receiving the rewards\n   * @return rewardsList List of addresses of the reward tokens and claimedAmounts, the list that contains the claimed amount per reward, following same order as \"rewardList\"\n   * @return claimedAmounts List that contains the claimed amount per reward, following same order as \"rewardList\"\n   **/\n  function claimAllRewards(address[] calldata assets, address to)\n    external\n    returns (address[] memory rewardsList, uint256[] memory claimedAmounts);\n\n  /**\n   * @dev Claims all rewards for an user on behalf, on all the assets of the lending pool, accumulating the pending rewards. The caller must\n   * be whitelisted via \"allowClaimOnBehalf\" function by the RewardsAdmin role manager\n   * @param assets List of assets to check eligible distributions before claiming rewards\n   * @param user Address to check and claim rewards\n   * @param to Address that will be receiving the rewards\n   * @return rewardsList List of addresses of the reward tokens and claimedAmounts, the list that contains the claimed amount per reward, following same order as \"rewardList\"\n   * @return claimedAmounts List that contains the claimed amount per reward, following same order as \"rewardsList\"\n   **/\n  function claimAllRewardsOnBehalf(\n    address[] calldata assets,\n    address user,\n    address to\n  ) external returns (address[] memory rewardsList, uint256[] memory claimedAmounts);\n\n  /**\n   * @dev Claims all reward for msg.sender, on all the assets of the lending pool, accumulating the pending rewards\n   * @param assets List of assets to check eligible distributions before claiming rewards\n   * @return rewardsList List of addresses of the reward tokens and claimedAmounts, the list that contains the claimed amount per reward, following same order as \"rewardList\"\n   * @return claimedAmounts List that contains the claimed amount per reward, following same order as \"rewardsList\"\n   **/\n  function claimAllRewardsToSelf(address[] calldata assets)\n    external\n    returns (address[] memory rewardsList, uint256[] memory claimedAmounts);\n}\n"
    },
    "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.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    function safeTransfer(\n        IERC20 token,\n        address to,\n        uint256 value\n    ) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 value\n    ) 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(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) 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    function safeIncreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        uint256 newAllowance = token.allowance(address(this), spender) + value;\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    function safeDecreaseAllowance(\n        IERC20 token,\n        address spender,\n        uint256 value\n    ) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            uint256 newAllowance = oldAllowance - value;\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n        }\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        if (returndata.length > 0) {\n            // Return data is optional\n            require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n        }\n    }\n}\n"
    },
    "@aave/core-v3/contracts/dependencies/openzeppelin/contracts/IERC20.sol": {
      "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.8.10;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\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 `recipient`.\n   *\n   * Returns a boolean value indicating whether the operation succeeded.\n   *\n   * Emits a {Transfer} event.\n   */\n  function transfer(address recipient, 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 `sender` to `recipient` 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(\n    address sender,\n    address recipient,\n    uint256 amount\n  ) external returns (bool);\n\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"
    },
    "@aave/core-v3/contracts/interfaces/IScaledBalanceToken.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0\npragma solidity 0.8.10;\n\n/**\n * @title IScaledBalanceToken\n * @author Aave\n * @notice Defines the basic interface for a scaledbalance token.\n **/\ninterface IScaledBalanceToken {\n  /**\n   * @dev Emitted after the mint action\n   * @param caller The address performing the mint\n   * @param onBehalfOf The address of the user that will receive the minted scaled balance tokens\n   * @param value The amount being minted (user entered amount + balance increase from interest)\n   * @param balanceIncrease The increase in balance since the last action of the user\n   * @param index The next liquidity index of the reserve\n   **/\n  event Mint(\n    address indexed caller,\n    address indexed onBehalfOf,\n    uint256 value,\n    uint256 balanceIncrease,\n    uint256 index\n  );\n\n  /**\n   * @dev Emitted after scaled balance tokens are burned\n   * @param from The address from which the scaled tokens will be burned\n   * @param target The address that will receive the underlying, if any\n   * @param value The amount being burned (user entered amount - balance increase from interest)\n   * @param balanceIncrease The increase in balance since the last action of the user\n   * @param index The next liquidity index of the reserve\n   **/\n  event Burn(\n    address indexed from,\n    address indexed target,\n    uint256 value,\n    uint256 balanceIncrease,\n    uint256 index\n  );\n\n  /**\n   * @notice Returns the scaled balance of the user.\n   * @dev The scaled balance is the sum of all the updated stored balance divided by the reserve's liquidity index\n   * at the moment of the update\n   * @param user The user whose balance is calculated\n   * @return The scaled balance of the user\n   **/\n  function scaledBalanceOf(address user) external view returns (uint256);\n\n  /**\n   * @notice Returns the scaled balance of the user and the scaled total supply.\n   * @param user The address of the user\n   * @return The scaled balance of the user\n   * @return The scaled total supply\n   **/\n  function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256);\n\n  /**\n   * @notice Returns the scaled total supply of the scaled balance token. Represents sum(debt/index)\n   * @return The scaled total supply\n   **/\n  function scaledTotalSupply() external view returns (uint256);\n\n  /**\n   * @notice Returns last index interest was accrued to the user's balance\n   * @param user The address of the user\n   * @return The last index interest was accrued to the user's balance, expressed in ray\n   **/\n  function getPreviousIndex(address user) external view returns (uint256);\n}\n"
    },
    "@aave/core-v3/contracts/interfaces/IInitializableAToken.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0\npragma solidity 0.8.10;\n\nimport {IAaveIncentivesController} from './IAaveIncentivesController.sol';\nimport {IPool} from './IPool.sol';\n\n/**\n * @title IInitializableAToken\n * @author Aave\n * @notice Interface for the initialize function on AToken\n **/\ninterface IInitializableAToken {\n  /**\n   * @dev Emitted when an aToken is initialized\n   * @param underlyingAsset The address of the underlying asset\n   * @param pool The address of the associated pool\n   * @param treasury The address of the treasury\n   * @param incentivesController The address of the incentives controller for this aToken\n   * @param aTokenDecimals The decimals of the underlying\n   * @param aTokenName The name of the aToken\n   * @param aTokenSymbol The symbol of the aToken\n   * @param params A set of encoded parameters for additional initialization\n   **/\n  event Initialized(\n    address indexed underlyingAsset,\n    address indexed pool,\n    address treasury,\n    address incentivesController,\n    uint8 aTokenDecimals,\n    string aTokenName,\n    string aTokenSymbol,\n    bytes params\n  );\n\n  /**\n   * @notice Initializes the aToken\n   * @param pool The pool contract that is initializing this contract\n   * @param treasury The address of the Aave treasury, receiving the fees on this aToken\n   * @param underlyingAsset The address of the underlying asset of this aToken (E.g. WETH for aWETH)\n   * @param incentivesController The smart contract managing potential incentives distribution\n   * @param aTokenDecimals The decimals of the aToken, same as the underlying asset's\n   * @param aTokenName The name of the aToken\n   * @param aTokenSymbol The symbol of the aToken\n   * @param params A set of encoded parameters for additional initialization\n   */\n  function initialize(\n    IPool pool,\n    address treasury,\n    address underlyingAsset,\n    IAaveIncentivesController incentivesController,\n    uint8 aTokenDecimals,\n    string calldata aTokenName,\n    string calldata aTokenSymbol,\n    bytes calldata params\n  ) external;\n}\n"
    },
    "@aave/core-v3/contracts/interfaces/IAaveIncentivesController.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0\npragma solidity 0.8.10;\n\n/**\n * @title IAaveIncentivesController\n * @author Aave\n * @notice Defines the basic interface for an Aave Incentives Controller.\n **/\ninterface IAaveIncentivesController {\n  /**\n   * @dev Emitted during `handleAction`, `claimRewards` and `claimRewardsOnBehalf`\n   * @param user The user that accrued rewards\n   * @param amount The amount of accrued rewards\n   */\n  event RewardsAccrued(address indexed user, uint256 amount);\n\n  event RewardsClaimed(address indexed user, address indexed to, uint256 amount);\n\n  /**\n   * @dev Emitted during `claimRewards` and `claimRewardsOnBehalf`\n   * @param user The address that accrued rewards\n   * @param to The address that will be receiving the rewards\n   * @param claimer The address that performed the claim\n   * @param amount The amount of rewards\n   */\n  event RewardsClaimed(\n    address indexed user,\n    address indexed to,\n    address indexed claimer,\n    uint256 amount\n  );\n\n  /**\n   * @dev Emitted during `setClaimer`\n   * @param user The address of the user\n   * @param claimer The address of the claimer\n   */\n  event ClaimerSet(address indexed user, address indexed claimer);\n\n  /**\n   * @notice Returns the configuration of the distribution for a certain asset\n   * @param asset The address of the reference asset of the distribution\n   * @return The asset index\n   * @return The emission per second\n   * @return The last updated timestamp\n   **/\n  function getAssetData(address asset)\n    external\n    view\n    returns (\n      uint256,\n      uint256,\n      uint256\n    );\n\n  /**\n   * LEGACY **************************\n   * @dev Returns the configuration of the distribution for a certain asset\n   * @param asset The address of the reference asset of the distribution\n   * @return The asset index, the emission per second and the last updated timestamp\n   **/\n  function assets(address asset)\n    external\n    view\n    returns (\n      uint128,\n      uint128,\n      uint256\n    );\n\n  /**\n   * @notice Whitelists an address to claim the rewards on behalf of another address\n   * @param user The address of the user\n   * @param claimer The address of the claimer\n   */\n  function setClaimer(address user, address claimer) external;\n\n  /**\n   * @notice Returns the whitelisted claimer for a certain address (0x0 if not set)\n   * @param user The address of the user\n   * @return The claimer address\n   */\n  function getClaimer(address user) external view returns (address);\n\n  /**\n   * @notice Configure assets for a certain rewards emission\n   * @param assets The assets to incentivize\n   * @param emissionsPerSecond The emission for each asset\n   */\n  function configureAssets(address[] calldata assets, uint256[] calldata emissionsPerSecond)\n    external;\n\n  /**\n   * @notice Called by the corresponding asset on any update that affects the rewards distribution\n   * @param asset The address of the user\n   * @param userBalance The balance of the user of the asset in the pool\n   * @param totalSupply The total supply of the asset in the pool\n   **/\n  function handleAction(\n    address asset,\n    uint256 userBalance,\n    uint256 totalSupply\n  ) external;\n\n  /**\n   * @notice Returns the total of rewards of a user, already accrued + not yet accrued\n   * @param assets The assets to accumulate rewards for\n   * @param user The address of the user\n   * @return The rewards\n   **/\n  function getRewardsBalance(address[] calldata assets, address user)\n    external\n    view\n    returns (uint256);\n\n  /**\n   * @notice Claims reward for a user, on the assets of the pool, accumulating the pending rewards\n   * @param assets The assets to accumulate rewards for\n   * @param amount Amount of rewards to claim\n   * @param to Address that will be receiving the rewards\n   * @return Rewards claimed\n   **/\n  function claimRewards(\n    address[] calldata assets,\n    uint256 amount,\n    address to\n  ) external returns (uint256);\n\n  /**\n   * @notice Claims reward for a user on its behalf, on the assets of the pool, accumulating the pending rewards.\n   * @dev The caller must be whitelisted via \"allowClaimOnBehalf\" function by the RewardsAdmin role manager\n   * @param assets The assets to accumulate rewards for\n   * @param amount The amount of rewards to claim\n   * @param user The address to check and claim rewards\n   * @param to The address that will be receiving the rewards\n   * @return The amount of rewards claimed\n   **/\n  function claimRewardsOnBehalf(\n    address[] calldata assets,\n    uint256 amount,\n    address user,\n    address to\n  ) external returns (uint256);\n\n  /**\n   * @notice Returns the unclaimed rewards of the user\n   * @param user The address of the user\n   * @return The unclaimed user rewards\n   */\n  function getUserUnclaimedRewards(address user) external view returns (uint256);\n\n  /**\n   * @notice Returns the user index for a specific asset\n   * @param user The address of the user\n   * @param asset The asset to incentivize\n   * @return The user index for the asset\n   */\n  function getUserAssetData(address user, address asset) external view returns (uint256);\n\n  /**\n   * @notice for backward compatibility with previous implementation of the Incentives controller\n   * @return The address of the reward token\n   */\n  function REWARD_TOKEN() external view returns (address);\n\n  /**\n   * @notice for backward compatibility with previous implementation of the Incentives controller\n   * @return The precision used in the incentives controller\n   */\n  function PRECISION() external view returns (uint8);\n\n  /**\n   * @dev Gets the distribution end timestamp of the emissions\n   */\n  function DISTRIBUTION_END() external view returns (uint256);\n}\n"
    },
    "@aave/core-v3/contracts/protocol/libraries/types/DataTypes.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.10;\n\nlibrary DataTypes {\n  struct ReserveData {\n    //stores the reserve configuration\n    ReserveConfigurationMap configuration;\n    //the liquidity index. Expressed in ray\n    uint128 liquidityIndex;\n    //the current supply rate. Expressed in ray\n    uint128 currentLiquidityRate;\n    //variable borrow index. Expressed in ray\n    uint128 variableBorrowIndex;\n    //the current variable borrow rate. Expressed in ray\n    uint128 currentVariableBorrowRate;\n    //the current stable borrow rate. Expressed in ray\n    uint128 currentStableBorrowRate;\n    //timestamp of last update\n    uint40 lastUpdateTimestamp;\n    //the id of the reserve. Represents the position in the list of the active reserves\n    uint16 id;\n    //aToken address\n    address aTokenAddress;\n    //stableDebtToken address\n    address stableDebtTokenAddress;\n    //variableDebtToken address\n    address variableDebtTokenAddress;\n    //address of the interest rate strategy\n    address interestRateStrategyAddress;\n    //the current treasury balance, scaled\n    uint128 accruedToTreasury;\n    //the outstanding unbacked aTokens minted through the bridging feature\n    uint128 unbacked;\n    //the outstanding debt borrowed against this asset in isolation mode\n    uint128 isolationModeTotalDebt;\n  }\n\n  struct ReserveConfigurationMap {\n    //bit 0-15: LTV\n    //bit 16-31: Liq. threshold\n    //bit 32-47: Liq. bonus\n    //bit 48-55: Decimals\n    //bit 56: reserve is active\n    //bit 57: reserve is frozen\n    //bit 58: borrowing is enabled\n    //bit 59: stable rate borrowing enabled\n    //bit 60: asset is paused\n    //bit 61: borrowing in isolation mode is enabled\n    //bit 62-63: reserved\n    //bit 64-79: reserve factor\n    //bit 80-115 borrow cap in whole tokens, borrowCap == 0 => no cap\n    //bit 116-151 supply cap in whole tokens, supplyCap == 0 => no cap\n    //bit 152-167 liquidation protocol fee\n    //bit 168-175 eMode category\n    //bit 176-211 unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled\n    //bit 212-251 debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals\n    //bit 252-255 unused\n\n    uint256 data;\n  }\n\n  struct UserConfigurationMap {\n    /**\n     * @dev Bitmap of the users collaterals and borrows. It is divided in pairs of bits, one pair per asset.\n     * The first bit indicates if an asset is used as collateral by the user, the second whether an\n     * asset is borrowed by the user.\n     */\n    uint256 data;\n  }\n\n  struct EModeCategory {\n    // each eMode category has a custom ltv and liquidation threshold\n    uint16 ltv;\n    uint16 liquidationThreshold;\n    uint16 liquidationBonus;\n    // each eMode category may or may not have a custom oracle to override the individual assets price oracles\n    address priceSource;\n    string label;\n  }\n\n  enum InterestRateMode {\n    NONE,\n    STABLE,\n    VARIABLE\n  }\n\n  struct ReserveCache {\n    uint256 currScaledVariableDebt;\n    uint256 nextScaledVariableDebt;\n    uint256 currPrincipalStableDebt;\n    uint256 currAvgStableBorrowRate;\n    uint256 currTotalStableDebt;\n    uint256 nextAvgStableBorrowRate;\n    uint256 nextTotalStableDebt;\n    uint256 currLiquidityIndex;\n    uint256 nextLiquidityIndex;\n    uint256 currVariableBorrowIndex;\n    uint256 nextVariableBorrowIndex;\n    uint256 currLiquidityRate;\n    uint256 currVariableBorrowRate;\n    uint256 reserveFactor;\n    ReserveConfigurationMap reserveConfiguration;\n    address aTokenAddress;\n    address stableDebtTokenAddress;\n    address variableDebtTokenAddress;\n    uint40 reserveLastUpdateTimestamp;\n    uint40 stableDebtLastUpdateTimestamp;\n  }\n\n  struct ExecuteLiquidationCallParams {\n    uint256 reservesCount;\n    uint256 debtToCover;\n    address collateralAsset;\n    address debtAsset;\n    address user;\n    bool receiveAToken;\n    address priceOracle;\n    uint8 userEModeCategory;\n    address priceOracleSentinel;\n  }\n\n  struct ExecuteSupplyParams {\n    address asset;\n    uint256 amount;\n    address onBehalfOf;\n    uint16 referralCode;\n  }\n\n  struct ExecuteBorrowParams {\n    address asset;\n    address user;\n    address onBehalfOf;\n    uint256 amount;\n    InterestRateMode interestRateMode;\n    uint16 referralCode;\n    bool releaseUnderlying;\n    uint256 maxStableRateBorrowSizePercent;\n    uint256 reservesCount;\n    address oracle;\n    uint8 userEModeCategory;\n    address priceOracleSentinel;\n  }\n\n  struct ExecuteRepayParams {\n    address asset;\n    uint256 amount;\n    InterestRateMode interestRateMode;\n    address onBehalfOf;\n    bool useATokens;\n  }\n\n  struct ExecuteWithdrawParams {\n    address asset;\n    uint256 amount;\n    address to;\n    uint256 reservesCount;\n    address oracle;\n    uint8 userEModeCategory;\n  }\n\n  struct ExecuteSetUserEModeParams {\n    uint256 reservesCount;\n    address oracle;\n    uint8 categoryId;\n  }\n\n  struct FinalizeTransferParams {\n    address asset;\n    address from;\n    address to;\n    uint256 amount;\n    uint256 balanceFromBefore;\n    uint256 balanceToBefore;\n    uint256 reservesCount;\n    address oracle;\n    uint8 fromEModeCategory;\n  }\n\n  struct FlashloanParams {\n    address receiverAddress;\n    address[] assets;\n    uint256[] amounts;\n    uint256[] interestRateModes;\n    address onBehalfOf;\n    bytes params;\n    uint16 referralCode;\n    uint256 flashLoanPremiumToProtocol;\n    uint256 flashLoanPremiumTotal;\n    uint256 maxStableRateBorrowSizePercent;\n    uint256 reservesCount;\n    address addressesProvider;\n    uint8 userEModeCategory;\n    bool isAuthorizedFlashBorrower;\n  }\n\n  struct FlashloanSimpleParams {\n    address receiverAddress;\n    address asset;\n    uint256 amount;\n    bytes params;\n    uint16 referralCode;\n    uint256 flashLoanPremiumToProtocol;\n    uint256 flashLoanPremiumTotal;\n  }\n\n  struct FlashLoanRepaymentParams {\n    uint256 amount;\n    uint256 totalPremium;\n    uint256 flashLoanPremiumToProtocol;\n    address asset;\n    address receiverAddress;\n    uint16 referralCode;\n  }\n\n  struct CalculateUserAccountDataParams {\n    UserConfigurationMap userConfig;\n    uint256 reservesCount;\n    address user;\n    address oracle;\n    uint8 userEModeCategory;\n  }\n\n  struct ValidateBorrowParams {\n    ReserveCache reserveCache;\n    UserConfigurationMap userConfig;\n    address asset;\n    address userAddress;\n    uint256 amount;\n    InterestRateMode interestRateMode;\n    uint256 maxStableLoanPercent;\n    uint256 reservesCount;\n    address oracle;\n    uint8 userEModeCategory;\n    address priceOracleSentinel;\n    bool isolationModeActive;\n    address isolationModeCollateralAddress;\n    uint256 isolationModeDebtCeiling;\n  }\n\n  struct ValidateLiquidationCallParams {\n    ReserveCache debtReserveCache;\n    uint256 totalDebt;\n    uint256 healthFactor;\n    address priceOracleSentinel;\n  }\n\n  struct CalculateInterestRatesParams {\n    uint256 unbacked;\n    uint256 liquidityAdded;\n    uint256 liquidityTaken;\n    uint256 totalStableDebt;\n    uint256 totalVariableDebt;\n    uint256 averageStableBorrowRate;\n    uint256 reserveFactor;\n    address reserve;\n    address aToken;\n  }\n\n  struct InitReserveParams {\n    address asset;\n    address aTokenAddress;\n    address stableDebtAddress;\n    address variableDebtAddress;\n    address interestRateStrategyAddress;\n    uint16 reservesCount;\n    uint16 maxNumberReserves;\n  }\n}\n"
    },
    "@aave/periphery-v3/contracts/rewards/interfaces/IRewardsDistributor.sol": {
      "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.8.10;\n\nimport {RewardsDistributorTypes} from '../libraries/RewardsDistributorTypes.sol';\n\ninterface IRewardsDistributor {\n  event AssetConfigUpdated(\n    address indexed asset,\n    address indexed reward,\n    uint256 emission,\n    uint256 distributionEnd\n  );\n  event AssetIndexUpdated(address indexed asset, address indexed reward, uint256 index);\n  event UserIndexUpdated(\n    address indexed user,\n    address indexed asset,\n    address indexed reward,\n    uint256 index\n  );\n\n  event RewardsAccrued(address indexed user, address indexed reward, uint256 amount);\n\n  /**\n   * @dev Sets the end date for the distribution\n   * @param asset The asset to incentivize\n   * @param reward The reward token that incentives the asset\n   * @param distributionEnd The end date of the incentivization, in unix time format\n   **/\n  function setDistributionEnd(\n    address asset,\n    address reward,\n    uint32 distributionEnd\n  ) external;\n\n  /**\n   * @dev Gets the end date for the distribution\n   * @param asset The incentivized asset\n   * @param reward The reward token of the incentivized asset\n   * @return The timestamp with the end of the distribution, in unix time format\n   **/\n  function getDistributionEnd(address asset, address reward) external view returns (uint256);\n\n  /**\n   * @dev Returns the index of an user on a reward distribution\n   * @param user Address of the user\n   * @param asset The incentivized asset\n   * @param reward The reward token of the incentivized asset\n   * @return The current user asset index in storage, not including new distributions\n   **/\n  function getUserAssetData(\n    address user,\n    address asset,\n    address reward\n  ) external view returns (uint256);\n\n  /**\n   * @dev Returns the configuration of the distribution for a certain asset\n   * @param asset The incentivized asset\n   * @param reward The reward token of the incentivized asset\n   * @return The asset index, the emission per second, the last updated timestamp and the distribution end timestamp\n   **/\n  function getRewardsData(address asset, address reward)\n    external\n    view\n    returns (\n      uint256,\n      uint256,\n      uint256,\n      uint256\n    );\n\n  /**\n   * @dev Returns the list of available reward token addresses of an incentivized asset\n   * @param asset The incentivized asset\n   * @return List of rewards addresses of the input asset\n   **/\n  function getRewardsByAsset(address asset) external view returns (address[] memory);\n\n  /**\n   * @dev Returns the list of available reward addresses\n   * @return List of rewards supported in this contract\n   **/\n  function getRewardsList() external view returns (address[] memory);\n\n  /**\n   * @dev Returns a single rewards balance of an user from contract storage state, not including virtually accrued rewards since last distribution.\n   * @param user The address of the user\n   * @param reward The address of the reward token\n   * @return Unclaimed rewards, from storage\n   **/\n  function getUserUnclaimedRewardsFromStorage(address user, address reward)\n    external\n    view\n    returns (uint256);\n\n  /**\n   * @dev Returns a single rewards balance of an user, including virtually accrued and unrealized claimable rewards.\n   * @param assets List of incentivized assets to check eligible distributions\n   * @param user The address of the user\n   * @param reward The address of the reward token\n   * @return The rewards amount\n   **/\n  function getUserRewardsBalance(\n    address[] calldata assets,\n    address user,\n    address reward\n  ) external view returns (uint256);\n\n  /**\n   * @dev Returns a list all rewards of an user, including already accrued and unrealized claimable rewards\n   * @param assets List of incentivized assets to check eligible distributions\n   * @param user The address of the user\n   * @return The function returns a Tuple of rewards list and the unclaimed rewards list\n   **/\n  function getAllUserRewardsBalance(address[] calldata assets, address user)\n    external\n    view\n    returns (address[] memory, uint256[] memory);\n\n  /**\n   * @dev Returns the decimals of an asset to calculate the distribution delta\n   * @param asset The address to retrieve decimals saved at storage\n   * @return The decimals of an underlying asset\n   */\n  function getAssetDecimals(address asset) external view returns (uint8);\n}\n"
    },
    "@aave/periphery-v3/contracts/rewards/libraries/RewardsDistributorTypes.sol": {
      "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.8.10;\n\nimport {ITransferStrategyBase} from '../interfaces/ITransferStrategyBase.sol';\nimport {IEACAggregatorProxy} from '../../misc/interfaces/IEACAggregatorProxy.sol';\n\nlibrary RewardsDistributorTypes {\n  struct RewardsConfigInput {\n    uint88 emissionPerSecond;\n    uint256 totalSupply;\n    uint32 distributionEnd;\n    address asset;\n    address reward;\n    ITransferStrategyBase transferStrategy;\n    IEACAggregatorProxy rewardOracle;\n  }\n\n  struct UserAssetStatsInput {\n    address underlyingAsset;\n    uint256 userBalance;\n    uint256 totalSupply;\n  }\n}\n"
    },
    "@aave/periphery-v3/contracts/rewards/interfaces/ITransferStrategyBase.sol": {
      "content": "// SPDX-License-Identifier: AGPL-3.0\npragma solidity 0.8.10;\n\ninterface ITransferStrategyBase {\n  event EmergencyWithdrawal(\n    address indexed caller,\n    address indexed token,\n    address indexed to,\n    uint256 amount\n  );\n\n  /**\n   * @dev Perform custom transfer logic via delegate call from source contract to a TransferStrategy implementation\n   * @param to Account to transfer rewards\n   * @param reward Address of the reward token\n   * @param amount Amount to transfer to the \"to\" address parameter\n   * @return Returns true bool if transfer logic succeeds\n   */\n  function performTransfer(\n    address to,\n    address reward,\n    uint256 amount\n  ) external returns (bool);\n\n  /**\n   * @return Returns the address of the Incentives Controller\n   */\n  function getIncentivesController() external view returns (address);\n\n  /**\n   * @return Returns the address of the Rewards admin\n   */\n  function getRewardsAdmin() external view returns (address);\n\n  /**\n   * @dev Perform an emergency token withdrawal only callable by the Rewards admin\n   * @param token Address of the token to withdraw funds from this contract\n   * @param to Address of the recipient of the withdrawal\n   * @param amount Amount of the withdrawal\n   */\n  function emergencyWithdrawal(\n    address token,\n    address to,\n    uint256 amount\n  ) external;\n}\n"
    },
    "@aave/periphery-v3/contracts/misc/interfaces/IEACAggregatorProxy.sol": {
      "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.8.10;\n\ninterface IEACAggregatorProxy {\n  function decimals() external view returns (uint8);\n\n  function latestAnswer() external view returns (int256);\n\n  function latestTimestamp() external view returns (uint256);\n\n  function latestRound() external view returns (uint256);\n\n  function getAnswer(uint256 roundId) external view returns (int256);\n\n  function getTimestamp(uint256 roundId) external view returns (uint256);\n\n  event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 timestamp);\n  event NewRound(uint256 indexed roundId, address indexed startedBy);\n}\n"
    },
    "@openzeppelin/contracts/utils/math/SafeCast.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/math/SafeCast.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n    /**\n     * @dev Returns the downcasted uint224 from uint256, reverting on\n     * overflow (when the input is greater than largest uint224).\n     *\n     * Counterpart to Solidity's `uint224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toUint224(uint256 value) internal pure returns (uint224) {\n        require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n        return uint224(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint128 from uint256, reverting on\n     * overflow (when the input is greater than largest uint128).\n     *\n     * Counterpart to Solidity's `uint128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toUint128(uint256 value) internal pure returns (uint128) {\n        require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n        return uint128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint96 from uint256, reverting on\n     * overflow (when the input is greater than largest uint96).\n     *\n     * Counterpart to Solidity's `uint96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toUint96(uint256 value) internal pure returns (uint96) {\n        require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n        return uint96(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint64 from uint256, reverting on\n     * overflow (when the input is greater than largest uint64).\n     *\n     * Counterpart to Solidity's `uint64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toUint64(uint256 value) internal pure returns (uint64) {\n        require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n        return uint64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint32 from uint256, reverting on\n     * overflow (when the input is greater than largest uint32).\n     *\n     * Counterpart to Solidity's `uint32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toUint32(uint256 value) internal pure returns (uint32) {\n        require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n        return uint32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint16 from uint256, reverting on\n     * overflow (when the input is greater than largest uint16).\n     *\n     * Counterpart to Solidity's `uint16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toUint16(uint256 value) internal pure returns (uint16) {\n        require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n        return uint16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint8 from uint256, reverting on\n     * overflow (when the input is greater than largest uint8).\n     *\n     * Counterpart to Solidity's `uint8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits.\n     */\n    function toUint8(uint256 value) internal pure returns (uint8) {\n        require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n        return uint8(value);\n    }\n\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        require(value >= 0, \"SafeCast: value must be positive\");\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int128 from int256, reverting on\n     * overflow (when the input is less than smallest int128 or\n     * greater than largest int128).\n     *\n     * Counterpart to Solidity's `int128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt128(int256 value) internal pure returns (int128) {\n        require(value >= type(int128).min && value <= type(int128).max, \"SafeCast: value doesn't fit in 128 bits\");\n        return int128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int64 from int256, reverting on\n     * overflow (when the input is less than smallest int64 or\n     * greater than largest int64).\n     *\n     * Counterpart to Solidity's `int64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt64(int256 value) internal pure returns (int64) {\n        require(value >= type(int64).min && value <= type(int64).max, \"SafeCast: value doesn't fit in 64 bits\");\n        return int64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int32 from int256, reverting on\n     * overflow (when the input is less than smallest int32 or\n     * greater than largest int32).\n     *\n     * Counterpart to Solidity's `int32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt32(int256 value) internal pure returns (int32) {\n        require(value >= type(int32).min && value <= type(int32).max, \"SafeCast: value doesn't fit in 32 bits\");\n        return int32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int16 from int256, reverting on\n     * overflow (when the input is less than smallest int16 or\n     * greater than largest int16).\n     *\n     * Counterpart to Solidity's `int16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt16(int256 value) internal pure returns (int16) {\n        require(value >= type(int16).min && value <= type(int16).max, \"SafeCast: value doesn't fit in 16 bits\");\n        return int16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int8 from int256, reverting on\n     * overflow (when the input is less than smallest int8 or\n     * greater than largest int8).\n     *\n     * Counterpart to Solidity's `int8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits.\n     *\n     * _Available since v3.1._\n     */\n    function toInt8(int256 value) internal pure returns (int8) {\n        require(value >= type(int8).min && value <= type(int8).max, \"SafeCast: value doesn't fit in 8 bits\");\n        return int8(value);\n    }\n\n    /**\n     * @dev Converts an unsigned uint256 into a signed int256.\n     *\n     * Requirements:\n     *\n     * - input must be less than or equal to maxInt256.\n     */\n    function toInt256(uint256 value) internal pure returns (int256) {\n        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n        require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n        return int256(value);\n    }\n}\n"
    },
    "contracts/hardhat-dependency-compiler/@pooltogether/aave-v3-yield-source/contracts/AaveV3YieldSource.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@pooltogether/aave-v3-yield-source/contracts/AaveV3YieldSource.sol';\n"
    },
    "@openzeppelin/contracts/utils/math/SafeMath.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)\n\npragma solidity ^0.8.0;\n\n// CAUTION\n// This version of SafeMath should only be used with Solidity 0.8 or later,\n// because it relies on the compiler's built in overflow checks.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations.\n *\n * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler\n * now has built in overflow checking.\n */\nlibrary SafeMath {\n    /**\n     * @dev Returns the addition of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            uint256 c = a + b;\n            if (c < a) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the substraction of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b > a) return (false, 0);\n            return (true, a - b);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n            // benefit is lost if 'b' is also tested.\n            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n            if (a == 0) return (true, 0);\n            uint256 c = a * b;\n            if (c / a != b) return (false, 0);\n            return (true, c);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a division by zero flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a / b);\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\n     *\n     * _Available since v3.4._\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\n        unchecked {\n            if (b == 0) return (false, 0);\n            return (true, a % b);\n        }\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     *\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a + b;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a - b;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `*` operator.\n     *\n     * Requirements:\n     *\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a * b;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator.\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a / b;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * reverting when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a % b;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n     * overflow (when the result is negative).\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {trySub}.\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(\n        uint256 a,\n        uint256 b,\n        string memory errorMessage\n    ) internal pure returns (uint256) {\n        unchecked {\n            require(b <= a, errorMessage);\n            return a - b;\n        }\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers, reverting with custom message on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(\n        uint256 a,\n        uint256 b,\n        string memory errorMessage\n    ) internal pure returns (uint256) {\n        unchecked {\n            require(b > 0, errorMessage);\n            return a / b;\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * reverting with custom message when dividing by zero.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryMod}.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(\n        uint256 a,\n        uint256 b,\n        string memory errorMessage\n    ) internal pure returns (uint256) {\n        unchecked {\n            require(b > 0, errorMessage);\n            return a % b;\n        }\n    }\n}\n"
    },
    "@openzeppelin/contracts/proxy/Clones.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/Clones.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for\n * deploying minimal proxy contracts, also known as \"clones\".\n *\n * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies\n * > a minimal bytecode implementation that delegates all calls to a known, fixed address.\n *\n * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`\n * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the\n * deterministic method.\n *\n * _Available since v3.4._\n */\nlibrary Clones {\n    /**\n     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n     *\n     * This function uses the create opcode, which should never revert.\n     */\n    function clone(address implementation) internal returns (address instance) {\n        assembly {\n            let ptr := mload(0x40)\n            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n            mstore(add(ptr, 0x14), shl(0x60, implementation))\n            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n            instance := create(0, ptr, 0x37)\n        }\n        require(instance != address(0), \"ERC1167: create failed\");\n    }\n\n    /**\n     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n     *\n     * This function uses the create2 opcode and a `salt` to deterministically deploy\n     * the clone. Using the same `implementation` and `salt` multiple time will revert, since\n     * the clones cannot be deployed twice at the same address.\n     */\n    function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {\n        assembly {\n            let ptr := mload(0x40)\n            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n            mstore(add(ptr, 0x14), shl(0x60, implementation))\n            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)\n            instance := create2(0, ptr, 0x37, salt)\n        }\n        require(instance != address(0), \"ERC1167: create2 failed\");\n    }\n\n    /**\n     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n     */\n    function predictDeterministicAddress(\n        address implementation,\n        bytes32 salt,\n        address deployer\n    ) internal pure returns (address predicted) {\n        assembly {\n            let ptr := mload(0x40)\n            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)\n            mstore(add(ptr, 0x14), shl(0x60, implementation))\n            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000)\n            mstore(add(ptr, 0x38), shl(0x60, deployer))\n            mstore(add(ptr, 0x4c), salt)\n            mstore(add(ptr, 0x6c), keccak256(ptr, 0x37))\n            predicted := keccak256(add(ptr, 0x37), 0x55)\n        }\n    }\n\n    /**\n     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n     */\n    function predictDeterministicAddress(address implementation, bytes32 salt)\n        internal\n        view\n        returns (address predicted)\n    {\n        return predictDeterministicAddress(implementation, salt, address(this));\n    }\n}\n"
    },
    "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Checker.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Library used to query support of an interface declared via {IERC165}.\n *\n * Note that these functions return the actual result of the query: they do not\n * `revert` if an interface is not supported. It is up to the caller to decide\n * what to do in these cases.\n */\nlibrary ERC165Checker {\n    // As per the EIP-165 spec, no interface should ever match 0xffffffff\n    bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;\n\n    /**\n     * @dev Returns true if `account` supports the {IERC165} interface,\n     */\n    function supportsERC165(address account) internal view returns (bool) {\n        // Any contract that implements ERC165 must explicitly indicate support of\n        // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid\n        return\n            _supportsERC165Interface(account, type(IERC165).interfaceId) &&\n            !_supportsERC165Interface(account, _INTERFACE_ID_INVALID);\n    }\n\n    /**\n     * @dev Returns true if `account` supports the interface defined by\n     * `interfaceId`. Support for {IERC165} itself is queried automatically.\n     *\n     * See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {\n        // query support of both ERC165 as per the spec and support of _interfaceId\n        return supportsERC165(account) && _supportsERC165Interface(account, interfaceId);\n    }\n\n    /**\n     * @dev Returns a boolean array where each value corresponds to the\n     * interfaces passed in and whether they're supported or not. This allows\n     * you to batch check interfaces for a contract where your expectation\n     * is that some interfaces may not be supported.\n     *\n     * See {IERC165-supportsInterface}.\n     *\n     * _Available since v3.4._\n     */\n    function getSupportedInterfaces(address account, bytes4[] memory interfaceIds)\n        internal\n        view\n        returns (bool[] memory)\n    {\n        // an array of booleans corresponding to interfaceIds and whether they're supported or not\n        bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);\n\n        // query support of ERC165 itself\n        if (supportsERC165(account)) {\n            // query support of each interface in interfaceIds\n            for (uint256 i = 0; i < interfaceIds.length; i++) {\n                interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]);\n            }\n        }\n\n        return interfaceIdsSupported;\n    }\n\n    /**\n     * @dev Returns true if `account` supports all the interfaces defined in\n     * `interfaceIds`. Support for {IERC165} itself is queried automatically.\n     *\n     * Batch-querying can lead to gas savings by skipping repeated checks for\n     * {IERC165} support.\n     *\n     * See {IERC165-supportsInterface}.\n     */\n    function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {\n        // query support of ERC165 itself\n        if (!supportsERC165(account)) {\n            return false;\n        }\n\n        // query support of each interface in _interfaceIds\n        for (uint256 i = 0; i < interfaceIds.length; i++) {\n            if (!_supportsERC165Interface(account, interfaceIds[i])) {\n                return false;\n            }\n        }\n\n        // all interfaces supported\n        return true;\n    }\n\n    /**\n     * @notice Query if a contract implements an interface, does not check ERC165 support\n     * @param account The address of the contract to query for support of an interface\n     * @param interfaceId The interface identifier, as specified in ERC-165\n     * @return true if the contract at account indicates support of the interface with\n     * identifier interfaceId, false otherwise\n     * @dev Assumes that account contains a contract that supports ERC165, otherwise\n     * the behavior of this method is undefined. This precondition can be checked\n     * with {supportsERC165}.\n     * Interface identification is specified in ERC-165.\n     */\n    function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) {\n        bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId);\n        (bool success, bytes memory result) = account.staticcall{gas: 30000}(encodedParams);\n        if (result.length < 32) return false;\n        return success && abi.decode(result, (bool));\n    }\n}\n"
    },
    "@openzeppelin/contracts/utils/introspection/IERC165.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
    },
    "@openzeppelin/contracts/token/ERC721/IERC721.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n    /**\n     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n     */\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n    /**\n     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n     */\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n    /**\n     * @dev Returns the number of tokens in ``owner``'s account.\n     */\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    /**\n     * @dev Returns the owner of the `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n     * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 tokenId\n    ) external;\n\n    /**\n     * @dev Transfers `tokenId` token from `from` to `to`.\n     *\n     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address from,\n        address to,\n        uint256 tokenId\n    ) external;\n\n    /**\n     * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n     * The approval is cleared when the token is transferred.\n     *\n     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n     *\n     * Requirements:\n     *\n     * - The caller must own the token or be an approved operator.\n     * - `tokenId` must exist.\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address to, uint256 tokenId) external;\n\n    /**\n     * @dev Returns the account approved for `tokenId` token.\n     *\n     * Requirements:\n     *\n     * - `tokenId` must exist.\n     */\n    function getApproved(uint256 tokenId) external view returns (address operator);\n\n    /**\n     * @dev Approve or remove `operator` as an operator for the caller.\n     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n     *\n     * Requirements:\n     *\n     * - The `operator` cannot be the caller.\n     *\n     * Emits an {ApprovalForAll} event.\n     */\n    function setApprovalForAll(address operator, bool _approved) external;\n\n    /**\n     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n     *\n     * See {setApprovalForAll}\n     */\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n\n    /**\n     * @dev Safely transfers `tokenId` token from `from` to `to`.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `tokenId` token must exist and be owned by `from`.\n     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n     *\n     * Emits a {Transfer} event.\n     */\n    function safeTransferFrom(\n        address from,\n        address to,\n        uint256 tokenId,\n        bytes calldata data\n    ) external;\n}\n"
    },
    "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n    /**\n     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n     * by `operator` from `from`, this function is called.\n     *\n     * It must return its Solidity selector to confirm the token transfer.\n     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n     *\n     * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.\n     */\n    function onERC721Received(\n        address operator,\n        address from,\n        uint256 tokenId,\n        bytes calldata data\n    ) external returns (bytes4);\n}\n"
    },
    "contracts/hardhat-dependency-compiler/@pooltogether/owner-manager-contracts/contracts/Ownable.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@pooltogether/owner-manager-contracts/contracts/Ownable.sol';\n"
    },
    "contracts/hardhat-dependency-compiler/@pooltogether/owner-manager-contracts/contracts/Manageable.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@pooltogether/owner-manager-contracts/contracts/Manageable.sol';\n"
    },
    "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface VRFCoordinatorV2Interface {\n  /**\n   * @notice Get configuration relevant for making requests\n   * @return minimumRequestConfirmations global min for request confirmations\n   * @return maxGasLimit global max for request gas limit\n   * @return s_provingKeyHashes list of registered key hashes\n   */\n  function getRequestConfig()\n    external\n    view\n    returns (\n      uint16,\n      uint32,\n      bytes32[] memory\n    );\n\n  /**\n   * @notice Request a set of random words.\n   * @param keyHash - Corresponds to a particular oracle job which uses\n   * that key for generating the VRF proof. Different keyHash's have different gas price\n   * ceilings, so you can select a specific one to bound your maximum per request cost.\n   * @param subId  - The ID of the VRF subscription. Must be funded\n   * with the minimum subscription balance required for the selected keyHash.\n   * @param minimumRequestConfirmations - How many blocks you'd like the\n   * oracle to wait before responding to the request. See SECURITY CONSIDERATIONS\n   * for why you may want to request more. The acceptable range is\n   * [minimumRequestBlockConfirmations, 200].\n   * @param callbackGasLimit - How much gas you'd like to receive in your\n   * fulfillRandomWords callback. Note that gasleft() inside fulfillRandomWords\n   * may be slightly less than this amount because of gas used calling the function\n   * (argument decoding etc.), so you may need to request slightly more than you expect\n   * to have inside fulfillRandomWords. The acceptable range is\n   * [0, maxGasLimit]\n   * @param numWords - The number of uint256 random values you'd like to receive\n   * in your fulfillRandomWords callback. Note these numbers are expanded in a\n   * secure way by the VRFCoordinator from a single random value supplied by the oracle.\n   * @return requestId - A unique identifier of the request. Can be used to match\n   * a request to a response in fulfillRandomWords.\n   */\n  function requestRandomWords(\n    bytes32 keyHash,\n    uint64 subId,\n    uint16 minimumRequestConfirmations,\n    uint32 callbackGasLimit,\n    uint32 numWords\n  ) external returns (uint256 requestId);\n\n  /**\n   * @notice Create a VRF subscription.\n   * @return subId - A unique subscription id.\n   * @dev You can manage the consumer set dynamically with addConsumer/removeConsumer.\n   * @dev Note to fund the subscription, use transferAndCall. For example\n   * @dev  LINKTOKEN.transferAndCall(\n   * @dev    address(COORDINATOR),\n   * @dev    amount,\n   * @dev    abi.encode(subId));\n   */\n  function createSubscription() external returns (uint64 subId);\n\n  /**\n   * @notice Get a VRF subscription.\n   * @param subId - ID of the subscription\n   * @return balance - LINK balance of the subscription in juels.\n   * @return reqCount - number of requests for this subscription, determines fee tier.\n   * @return owner - owner of the subscription.\n   * @return consumers - list of consumer address which are able to use this subscription.\n   */\n  function getSubscription(uint64 subId)\n    external\n    view\n    returns (\n      uint96 balance,\n      uint64 reqCount,\n      address owner,\n      address[] memory consumers\n    );\n\n  /**\n   * @notice Request subscription owner transfer.\n   * @param subId - ID of the subscription\n   * @param newOwner - proposed new owner of the subscription\n   */\n  function requestSubscriptionOwnerTransfer(uint64 subId, address newOwner) external;\n\n  /**\n   * @notice Request subscription owner transfer.\n   * @param subId - ID of the subscription\n   * @dev will revert if original owner of subId has\n   * not requested that msg.sender become the new owner.\n   */\n  function acceptSubscriptionOwnerTransfer(uint64 subId) external;\n\n  /**\n   * @notice Add a consumer to a VRF subscription.\n   * @param subId - ID of the subscription\n   * @param consumer - New consumer which can use the subscription\n   */\n  function addConsumer(uint64 subId, address consumer) external;\n\n  /**\n   * @notice Remove a consumer from a VRF subscription.\n   * @param subId - ID of the subscription\n   * @param consumer - Consumer to remove from the subscription\n   */\n  function removeConsumer(uint64 subId, address consumer) external;\n\n  /**\n   * @notice Cancel a subscription\n   * @param subId - ID of the subscription\n   * @param to - Where to send the remaining LINK to\n   */\n  function cancelSubscription(uint64 subId, address to) external;\n}\n"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": true,
      "runs": 2000
    },
    "evmVersion": "london",
    "outputSelection": {
      "*": {
        "*": [
          "abi",
          "evm.bytecode",
          "evm.deployedBytecode",
          "evm.methodIdentifiers",
          "metadata",
          "devdoc",
          "userdoc",
          "storageLayout",
          "evm.gasEstimates"
        ],
        "": [
          "ast"
        ]
      }
    },
    "metadata": {
      "useLiteralContent": true
    }
  }
}