creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "src/v0.8/automation/interfaces/AutomationCompatibleInterface.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AutomationCompatibleInterface {\n  /**\n   * @notice method that is simulated by the keepers to see if any work actually\n   * needs to be performed. This method does does not actually need to be\n   * executable, and since it is only ever simulated it can consume lots of gas.\n   * @dev To ensure that it is never called, you may want to add the\n   * cannotExecute modifier from KeeperBase to your implementation of this\n   * method.\n   * @param checkData specified in the upkeep registration so it is always the\n   * same for a registered upkeep. This can easily be broken down into specific\n   * arguments using `abi.decode`, so multiple upkeeps can be registered on the\n   * same contract and easily differentiated by the contract.\n   * @return upkeepNeeded boolean to indicate whether the keeper should call\n   * performUpkeep or not.\n   * @return performData bytes that the keeper should call performUpkeep with, if\n   * upkeep is needed. If you would like to encode data to decode later, try\n   * `abi.encode`.\n   */\n  function checkUpkeep(bytes calldata checkData) external returns (bool upkeepNeeded, bytes memory performData);\n\n  /**\n   * @notice method that is actually executed by the keepers, via the registry.\n   * The data returned by the checkUpkeep simulation will be passed into\n   * this method to actually be executed.\n   * @dev The input to this method should not be trusted, and the caller of the\n   * method should not even be restricted to any single registry. Anyone should\n   * be able call it, and the input should be validated, there is no guarantee\n   * that the data passed in is the performData returned from checkUpkeep. This\n   * could happen due to malicious keepers, racing keepers, or simply a state\n   * change while the performUpkeep transaction is waiting for confirmation.\n   * Always validate the data passed in.\n   * @param performData is the data which was passed back from the checkData\n   * simulation. If it is encoded, it can easily be decoded into other types by\n   * calling `abi.decode`. This data should not be trusted, and should be\n   * validated against the contract's current state.\n   */\n  function performUpkeep(bytes calldata performData) external;\n}\n"
      },
      "src/v0.8/automation/upkeeps/LinkAvailableBalanceMonitor.sol": {
        "content": "// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.19;\n\nimport {AutomationCompatibleInterface} from \"../interfaces/AutomationCompatibleInterface.sol\";\nimport {AccessControl} from \"../../vendor/openzeppelin-solidity/v4.8.3/contracts/access/AccessControl.sol\";\nimport {EnumerableMap} from \"../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableMap.sol\";\nimport {EnumerableSet} from \"../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol\";\nimport {IERC20} from \"../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol\";\nimport {Pausable} from \"../../vendor/openzeppelin-solidity/v4.8.3/contracts/security/Pausable.sol\";\n\ninterface IAggregatorProxy {\n  function aggregator() external view returns (address);\n}\n\ninterface ILinkAvailable {\n  function linkAvailableForPayment() external view returns (int256 availableBalance);\n}\n\n/// @title The LinkAvailableBalanceMonitor contract.\n/// @notice A keeper-compatible contract that monitors target contracts for balance from a custom\n/// function linkAvailableForPayment() and funds them with LINK if it falls below a defined\n/// threshold. Also supports aggregator proxy contracts monitoring which require fetching the actual\n/// target contract through a predefined interface.\n/// @dev with 30 addresses as the s_maxPerform, the measured max gas usage of performUpkeep is around 2M\n/// therefore, we recommend an upkeep gas limit of 3M (this has a 33% margin of safety). Although, nothing\n/// prevents us from using 5M gas and increasing s_maxPerform, 30 seems like a reasonable batch size that\n/// is probably plenty for most needs.\n/// @dev with 130 addresses as the s_maxCheck, the measured max gas usage of checkUpkeep is around 3.5M,\n/// which is 30% below the 5M limit.\n/// Note that testing conditions DO NOT match live chain gas usage, hence the margins. Change\n/// at your own risk!!!\n/// @dev some areas for improvement / acknowledgement of limitations:\n///  validate that all addresses conform to interface when adding them to the watchlist\n///  this is a \"trusless\" upkeep, meaning it does not trust the caller of performUpkeep;\n/// we could save a fair amount of gas and re-write this upkeep for use with Automation v2.0+,\n/// which has significantly different trust assumptions\ncontract LinkAvailableBalanceMonitor is AccessControl, AutomationCompatibleInterface, Pausable {\n  using EnumerableMap for EnumerableMap.UintToAddressMap;\n  using EnumerableSet for EnumerableSet.AddressSet;\n\n  event BalanceUpdated(address indexed addr, uint256 oldBalance, uint256 newBalance);\n  event FundsWithdrawn(uint256 amountWithdrawn, address payee);\n  event UpkeepIntervalSet(uint256 oldUpkeepInterval, uint256 newUpkeepInterval);\n  event MaxCheckSet(uint256 oldMaxCheck, uint256 newMaxCheck);\n  event MaxPerformSet(uint256 oldMaxPerform, uint256 newMaxPerform);\n  event MinWaitPeriodSet(uint256 s_minWaitPeriodSeconds, uint256 minWaitPeriodSeconds);\n  event TopUpBlocked(address indexed topUpAddress);\n  event TopUpFailed(address indexed recipient);\n  event TopUpSucceeded(address indexed topUpAddress);\n  event TopUpUpdated(address indexed addr, uint256 oldTopUpAmount, uint256 newTopUpAmount);\n  event WatchlistUpdated();\n\n  error InvalidAddress(address target);\n  error InvalidMaxCheck(uint16 maxCheck);\n  error InvalixMaxPerform(uint16 maxPerform);\n  error InvalidMinBalance(uint96 minBalance);\n  error InvalidTopUpAmount(uint96 topUpAmount);\n  error InvalidUpkeepInterval(uint8 upkeepInterval);\n  error InvalidLinkTokenAddress(address lt);\n  error InvalidWatchList();\n  error InvalidChainSelector();\n  error DuplicateAddress(address duplicate);\n\n  struct MonitoredAddress {\n    uint96 minBalance;\n    uint96 topUpAmount;\n    uint56 lastTopUpTimestamp;\n    bool isActive;\n  }\n\n  bytes32 private constant ADMIN_ROLE = keccak256(\"ADMIN_ROLE\");\n  bytes32 private constant EXECUTOR_ROLE = keccak256(\"EXECUTOR_ROLE\");\n  uint96 private constant DEFAULT_TOP_UP_AMOUNT_JUELS = 9000000000000000000;\n  uint96 private constant DEFAULT_MIN_BALANCE_JUELS = 1000000000000000000;\n  IERC20 private immutable i_linkToken;\n\n  uint256 private s_minWaitPeriodSeconds;\n  uint16 private s_maxPerform;\n  uint16 private s_maxCheck;\n  uint8 private s_upkeepInterval;\n\n  /// @notice s_watchList contains all the addresses watched by this monitor\n  /// @dev It mainly provides the length() function\n  EnumerableSet.AddressSet private s_watchList;\n\n  /// @notice s_targets contains all the addresses watched by this monitor\n  /// Each key points to a MonitoredAddress with all the needed metadata\n  mapping(address targetAddress => MonitoredAddress targetProperties) private s_targets;\n\n  /// @notice s_onRampAddresses represents a list of CCIP onRamp addresses watched on this contract\n  /// There has to be only one onRamp per dstChainSelector.\n  /// dstChainSelector is needed as we have to track the live onRamp, and delete the onRamp\n  /// whenever a new one is deployed with the same dstChainSelector.\n  EnumerableMap.UintToAddressMap private s_onRampAddresses;\n\n  /// @param admin is the administrator address of this contract\n  /// @param linkToken the LINK token address\n  /// @param minWaitPeriodSeconds represents the amount of time that has to wait a contract to be funded\n  /// @param maxPerform maximum amount of contracts to fund\n  /// @param maxCheck maximum amount of contracts to check\n  /// @param upkeepInterval randomizes the check for underfunded contracts\n  constructor(\n    address admin,\n    IERC20 linkToken,\n    uint256 minWaitPeriodSeconds,\n    uint16 maxPerform,\n    uint16 maxCheck,\n    uint8 upkeepInterval\n  ) {\n    _setRoleAdmin(ADMIN_ROLE, ADMIN_ROLE);\n    _setRoleAdmin(EXECUTOR_ROLE, ADMIN_ROLE);\n    _grantRole(ADMIN_ROLE, admin);\n    i_linkToken = linkToken;\n    setMinWaitPeriodSeconds(minWaitPeriodSeconds);\n    setMaxPerform(maxPerform);\n    setMaxCheck(maxCheck);\n    setUpkeepInterval(upkeepInterval);\n  }\n\n  /// @notice Sets the list of subscriptions to watch and their funding parameters\n  /// @param addresses the list of target addresses to watch (could be direct target or IAggregatorProxy)\n  /// @param minBalances the list of corresponding minBalance for the target address\n  /// @param topUpAmounts the list of corresponding minTopUp for the target address\n  function setWatchList(\n    address[] calldata addresses,\n    uint96[] calldata minBalances,\n    uint96[] calldata topUpAmounts,\n    uint64[] calldata dstChainSelectors\n  ) external onlyAdminOrExecutor {\n    if (\n      addresses.length != minBalances.length ||\n      addresses.length != topUpAmounts.length ||\n      addresses.length != dstChainSelectors.length\n    ) {\n      revert InvalidWatchList();\n    }\n    for (uint256 idx = s_watchList.length(); idx > 0; idx--) {\n      address member = s_watchList.at(idx - 1);\n      s_watchList.remove(member);\n      delete s_targets[member];\n    }\n    // s_onRampAddresses is not the same length as s_watchList, so it has\n    // to be clean in a separate loop\n    for (uint256 idx = s_onRampAddresses.length(); idx > 0; idx--) {\n      (uint256 key, ) = s_onRampAddresses.at(idx - 1);\n      s_onRampAddresses.remove(key);\n    }\n    for (uint256 idx = 0; idx < addresses.length; idx++) {\n      address targetAddress = addresses[idx];\n      if (s_targets[targetAddress].isActive) revert DuplicateAddress(targetAddress);\n      if (targetAddress == address(0)) revert InvalidWatchList();\n      if (minBalances[idx] == 0) revert InvalidWatchList();\n      if (topUpAmounts[idx] == 0) revert InvalidWatchList();\n      s_targets[targetAddress] = MonitoredAddress({\n        isActive: true,\n        minBalance: minBalances[idx],\n        topUpAmount: topUpAmounts[idx],\n        lastTopUpTimestamp: 0\n      });\n      if (dstChainSelectors[idx] > 0) {\n        s_onRampAddresses.set(dstChainSelectors[idx], targetAddress);\n      }\n      s_watchList.add(targetAddress);\n    }\n    emit WatchlistUpdated();\n  }\n\n  /// @notice Adds a new address to the watchlist\n  /// @param targetAddress the address to be added to the watchlist\n  /// @param dstChainSelector carries a non-zero value in case the targetAddress is an onRamp, otherwise it carries a 0\n  /// @dev this function has to be compatible with the event onRampSet(address, dstChainSelector) emitted by\n  /// the CCIP router. Important detail to know is this event is also emitted when an onRamp is decomissioned,\n  /// in which case it will carry the proper dstChainSelector along with the 0x0 address\n  function addToWatchListOrDecomission(address targetAddress, uint64 dstChainSelector) public onlyAdminOrExecutor {\n    if (s_targets[targetAddress].isActive) revert DuplicateAddress(targetAddress);\n    if (targetAddress == address(0) && dstChainSelector == 0) revert InvalidAddress(targetAddress);\n    bool onRampExists = s_onRampAddresses.contains(dstChainSelector);\n    // if targetAddress is an existing onRamp, there's a need of cleaning the previous onRamp associated to this dstChainSelector\n    // there's no need to remove any other address that's not an onRamp\n    if (dstChainSelector > 0 && onRampExists) {\n      address oldAddress = s_onRampAddresses.get(dstChainSelector);\n      removeFromWatchList(oldAddress);\n    }\n    // only add the new address if it's not 0x0\n    if (targetAddress != address(0)) {\n      s_targets[targetAddress] = MonitoredAddress({\n        isActive: true,\n        minBalance: DEFAULT_MIN_BALANCE_JUELS,\n        topUpAmount: DEFAULT_TOP_UP_AMOUNT_JUELS,\n        lastTopUpTimestamp: 0\n      });\n      s_watchList.add(targetAddress);\n      // add the contract to onRampAddresses if it carries a valid dstChainSelector\n      if (dstChainSelector > 0) {\n        s_onRampAddresses.set(dstChainSelector, targetAddress);\n      }\n      // else if is refundant as this is the only corner case left, maintaining it for legibility\n    } else if (targetAddress == address(0) && dstChainSelector > 0) {\n      s_onRampAddresses.remove(dstChainSelector);\n    }\n  }\n\n  /// @notice Delete an address from the watchlist and sets the target to inactive\n  /// @param targetAddress the address to be deleted\n  function removeFromWatchList(address targetAddress) public onlyAdminOrExecutor returns (bool) {\n    if (s_watchList.remove(targetAddress)) {\n      delete s_targets[targetAddress];\n      return true;\n    }\n    return false;\n  }\n\n  /// @notice Gets a list of proxies that are underfunded, up to the s_maxPerform size\n  /// @dev the function starts at a random index in the list to avoid biasing the first\n  /// addresses in the list over latter ones.\n  /// @dev the function will check at most s_maxCheck proxies in a single call\n  /// @dev the function returns a list with a max length of s_maxPerform\n  /// @return list of target addresses which are underfunded\n  function sampleUnderfundedAddresses() public view returns (address[] memory) {\n    uint16 maxPerform = s_maxPerform;\n    uint16 maxCheck = s_maxCheck;\n    uint256 numTargets = s_watchList.length();\n    uint256 idx = uint256(blockhash(block.number - (block.number % s_upkeepInterval) - 1)) % numTargets;\n    uint256 numToCheck = numTargets < maxCheck ? numTargets : maxCheck;\n    uint256 numFound = 0;\n    uint256 minWaitPeriod = s_minWaitPeriodSeconds;\n    address[] memory targetsToFund = new address[](maxPerform);\n    MonitoredAddress memory contractToFund;\n    for (\n      uint256 numChecked = 0;\n      numChecked < numToCheck;\n      (idx, numChecked) = ((idx + 1) % numTargets, numChecked + 1)\n    ) {\n      address targetAddress = s_watchList.at(idx);\n      contractToFund = s_targets[targetAddress];\n      if (\n        _needsFunding(\n          targetAddress,\n          contractToFund.lastTopUpTimestamp + minWaitPeriod,\n          contractToFund.minBalance,\n          contractToFund.isActive\n        )\n      ) {\n        targetsToFund[numFound] = targetAddress;\n        numFound++;\n        if (numFound == maxPerform) {\n          break; // max number of addresses in batch reached\n        }\n      }\n    }\n    if (numFound != maxPerform) {\n      assembly {\n        mstore(targetsToFund, numFound) // resize array to number of valid targets\n      }\n    }\n    return targetsToFund;\n  }\n\n  /// @notice tries to fund an array of target addresses, checking if they're underfunded in the process\n  /// @param targetAddresses is an array of contract addresses to be funded in case they're underfunded\n  function topUp(address[] memory targetAddresses) public whenNotPaused {\n    MonitoredAddress memory contractToFund;\n    uint256 minWaitPeriod = s_minWaitPeriodSeconds;\n    uint256 localBalance = i_linkToken.balanceOf(address(this));\n    for (uint256 idx = 0; idx < targetAddresses.length; idx++) {\n      address targetAddress = targetAddresses[idx];\n      contractToFund = s_targets[targetAddress];\n      s_targets[targetAddress].lastTopUpTimestamp = uint56(block.timestamp);\n      if (\n        localBalance >= contractToFund.topUpAmount &&\n        _needsFunding(\n          targetAddress,\n          contractToFund.lastTopUpTimestamp + minWaitPeriod,\n          contractToFund.minBalance,\n          contractToFund.isActive\n        )\n      ) {\n        bool success = i_linkToken.transfer(targetAddress, contractToFund.topUpAmount);\n        if (success) {\n          localBalance -= contractToFund.topUpAmount;\n          emit TopUpSucceeded(targetAddress);\n        } else {\n          s_targets[targetAddress].lastTopUpTimestamp = contractToFund.lastTopUpTimestamp;\n          emit TopUpFailed(targetAddress);\n        }\n      } else {\n        s_targets[targetAddress].lastTopUpTimestamp = contractToFund.lastTopUpTimestamp;\n        emit TopUpBlocked(targetAddress);\n      }\n    }\n  }\n\n  /// @notice checks the target (could be direct target or IAggregatorProxy), and determines\n  /// if it is elligible for funding\n  /// @param targetAddress the target to check\n  /// @param minBalance minimum balance required for the target\n  /// @param minWaitPeriodPassed the minimum wait period (target lastTopUpTimestamp + minWaitPeriod)\n  /// @return bool whether the target needs funding or not\n  function _needsFunding(\n    address targetAddress,\n    uint256 minWaitPeriodPassed,\n    uint256 minBalance,\n    bool contractIsActive\n  ) private view returns (bool) {\n    // Explicitly check if the targetAddress is the zero address\n    // or if it's not a contract. In both cases return with false,\n    // to prevent target.linkAvailableForPayment from running,\n    // which would revert the operation.\n    if (targetAddress == address(0) || targetAddress.code.length == 0) {\n      return false;\n    }\n    ILinkAvailable target;\n    IAggregatorProxy proxy = IAggregatorProxy(targetAddress);\n    try proxy.aggregator() returns (address aggregatorAddress) {\n      // proxy.aggregator() can return a 0 address if the address is not an aggregator\n      if (aggregatorAddress == address(0)) return false;\n      target = ILinkAvailable(aggregatorAddress);\n    } catch {\n      target = ILinkAvailable(targetAddress);\n    }\n    try target.linkAvailableForPayment() returns (int256 balance) {\n      if (balance < int256(minBalance) && minWaitPeriodPassed <= block.timestamp && contractIsActive) {\n        return true;\n      }\n    } catch {}\n    return false;\n  }\n\n  /// @notice Gets list of subscription ids that are underfunded and returns a keeper-compatible payload.\n  /// @return upkeepNeeded signals if upkeep is needed\n  /// @return performData is an abi encoded list of subscription ids that need funds\n  function checkUpkeep(\n    bytes calldata\n  ) external view override whenNotPaused returns (bool upkeepNeeded, bytes memory performData) {\n    address[] memory needsFunding = sampleUnderfundedAddresses();\n    upkeepNeeded = needsFunding.length > 0;\n    performData = abi.encode(needsFunding);\n    return (upkeepNeeded, performData);\n  }\n\n  /// @notice Called by the keeper to send funds to underfunded addresses.\n  /// @param performData the abi encoded list of addresses to fund\n  function performUpkeep(bytes calldata performData) external override {\n    address[] memory needsFunding = abi.decode(performData, (address[]));\n    topUp(needsFunding);\n  }\n\n  /// @notice Withdraws the contract balance in the LINK token.\n  /// @param amount the amount of the LINK to withdraw\n  /// @param payee the address to pay\n  function withdraw(uint256 amount, address payable payee) external onlyAdminOrExecutor {\n    if (payee == address(0)) revert InvalidAddress(payee);\n    i_linkToken.transfer(payee, amount);\n    emit FundsWithdrawn(amount, payee);\n  }\n\n  /// @notice Sets the minimum balance for the given target address\n  function setMinBalance(address target, uint96 minBalance) external onlyRole(ADMIN_ROLE) {\n    if (target == address(0)) revert InvalidAddress(target);\n    if (minBalance == 0) revert InvalidMinBalance(minBalance);\n    if (!s_targets[target].isActive) revert InvalidWatchList();\n    uint256 oldBalance = s_targets[target].minBalance;\n    s_targets[target].minBalance = minBalance;\n    emit BalanceUpdated(target, oldBalance, minBalance);\n  }\n\n  /// @notice Sets the minimum balance for the given target address\n  function setTopUpAmount(address target, uint96 topUpAmount) external onlyRole(ADMIN_ROLE) {\n    if (target == address(0)) revert InvalidAddress(target);\n    if (topUpAmount == 0) revert InvalidTopUpAmount(topUpAmount);\n    if (!s_targets[target].isActive) revert InvalidWatchList();\n    uint256 oldTopUpAmount = s_targets[target].topUpAmount;\n    s_targets[target].topUpAmount = topUpAmount;\n    emit BalanceUpdated(target, oldTopUpAmount, topUpAmount);\n  }\n\n  /// @notice Update s_maxPerform\n  function setMaxPerform(uint16 maxPerform) public onlyRole(ADMIN_ROLE) {\n    emit MaxPerformSet(s_maxPerform, maxPerform);\n    s_maxPerform = maxPerform;\n  }\n\n  /// @notice Update s_maxCheck\n  function setMaxCheck(uint16 maxCheck) public onlyRole(ADMIN_ROLE) {\n    emit MaxCheckSet(s_maxCheck, maxCheck);\n    s_maxCheck = maxCheck;\n  }\n\n  /// @notice Sets the minimum wait period (in seconds) for addresses between funding\n  function setMinWaitPeriodSeconds(uint256 minWaitPeriodSeconds) public onlyRole(ADMIN_ROLE) {\n    emit MinWaitPeriodSet(s_minWaitPeriodSeconds, minWaitPeriodSeconds);\n    s_minWaitPeriodSeconds = minWaitPeriodSeconds;\n  }\n\n  /// @notice Update s_upkeepInterval\n  function setUpkeepInterval(uint8 upkeepInterval) public onlyRole(ADMIN_ROLE) {\n    if (upkeepInterval > 255) revert InvalidUpkeepInterval(upkeepInterval);\n    emit UpkeepIntervalSet(s_upkeepInterval, upkeepInterval);\n    s_upkeepInterval = upkeepInterval;\n  }\n\n  /// @notice Gets maxPerform\n  function getMaxPerform() external view returns (uint16) {\n    return s_maxPerform;\n  }\n\n  /// @notice Gets maxCheck\n  function getMaxCheck() external view returns (uint16) {\n    return s_maxCheck;\n  }\n\n  /// @notice Gets the minimum wait period\n  function getMinWaitPeriodSeconds() external view returns (uint256) {\n    return s_minWaitPeriodSeconds;\n  }\n\n  /// @notice Gets upkeepInterval\n  function getUpkeepInterval() external view returns (uint8) {\n    return s_upkeepInterval;\n  }\n\n  /// @notice Gets the list of subscription ids being watched\n  function getWatchList() external view returns (address[] memory) {\n    return s_watchList.values();\n  }\n\n  /// @notice Gets the onRamp address with the specified dstChainSelector\n  function getOnRampAddressAtChainSelector(uint64 dstChainSelector) external view returns (address) {\n    if (dstChainSelector == 0) revert InvalidChainSelector();\n    return s_onRampAddresses.get(dstChainSelector);\n  }\n\n  /// @notice Gets configuration information for an address on the watchlist\n  function getAccountInfo(\n    address targetAddress\n  ) external view returns (bool isActive, uint96 minBalance, uint96 topUpAmount, uint56 lastTopUpTimestamp) {\n    MonitoredAddress memory target = s_targets[targetAddress];\n    return (target.isActive, target.minBalance, target.topUpAmount, target.lastTopUpTimestamp);\n  }\n\n  /// @dev Modifier to make a function callable only by executor role or the\n  /// admin role.\n  modifier onlyAdminOrExecutor() {\n    address sender = _msgSender();\n    if (!hasRole(ADMIN_ROLE, sender)) {\n      _checkRole(EXECUTOR_ROLE, sender);\n    }\n    _;\n  }\n\n  /// @notice Pause the contract, which prevents executing performUpkeep\n  function pause() external onlyRole(ADMIN_ROLE) {\n    _pause();\n  }\n\n  /// @notice Unpause the contract\n  function unpause() external onlyRole(ADMIN_ROLE) {\n    _unpause();\n  }\n}\n"
      },
      "src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/access/AccessControl.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n    struct RoleData {\n        mapping(address => bool) members;\n        bytes32 adminRole;\n    }\n\n    mapping(bytes32 => RoleData) private _roles;\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n    /**\n     * @dev Modifier that checks that an account has a specific role. Reverts\n     * with a standardized message including the required role.\n     *\n     * The format of the revert reason is given by the following regular expression:\n     *\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n     *\n     * _Available since v4.1._\n     */\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role);\n        _;\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n        return _roles[role].members[account];\n    }\n\n    /**\n     * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n     * Overriding this function changes the behavior of the {onlyRole} modifier.\n     *\n     * Format of the revert message is described in {_checkRole}.\n     *\n     * _Available since v4.6._\n     */\n    function _checkRole(bytes32 role) internal view virtual {\n        _checkRole(role, _msgSender());\n    }\n\n    /**\n     * @dev Revert with a standard message if `account` is missing `role`.\n     *\n     * The format of the revert reason is given by the following regular expression:\n     *\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n     */\n    function _checkRole(bytes32 role, address account) internal view virtual {\n        if (!hasRole(role, account)) {\n            revert(\n                string(\n                    abi.encodePacked(\n                        \"AccessControl: account \",\n                        Strings.toHexString(account),\n                        \" is missing role \",\n                        Strings.toHexString(uint256(role), 32)\n                    )\n                )\n            );\n        }\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n        return _roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been revoked `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function renounceRole(bytes32 role, address account) public virtual override {\n        require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event. Note that unlike {grantRole}, this function doesn't perform any\n     * checks on the calling account.\n     *\n     * May emit a {RoleGranted} event.\n     *\n     * [WARNING]\n     * ====\n     * This function should only be called from the constructor when setting\n     * up the initial roles for the system.\n     *\n     * Using this function in any other way is effectively circumventing the admin\n     * system imposed by {AccessControl}.\n     * ====\n     *\n     * NOTE: This function is deprecated in favor of {_grantRole}.\n     */\n    function _setupRole(bytes32 role, address account) internal virtual {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        bytes32 previousAdminRole = getRoleAdmin(role);\n        _roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual {\n        if (!hasRole(role, account)) {\n            _roles[role].members[account] = true;\n            emit RoleGranted(role, account, _msgSender());\n        }\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual {\n        if (hasRole(role, account)) {\n            _roles[role].members[account] = false;\n            emit RoleRevoked(role, account, _msgSender());\n        }\n    }\n}"
      },
      "src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/access/IAccessControl.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted signaling this.\n     *\n     * _Available since v3.1._\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call, an admin role\n     * bearer except when using {AccessControl-_setupRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) external view returns (bool);\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     */\n    function renounceRole(bytes32 role, address account) external;\n}"
      },
      "src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/security/Pausable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n  /**\n   * @dev Emitted when the pause is triggered by `account`.\n   */\n  event Paused(address account);\n\n  /**\n   * @dev Emitted when the pause is lifted by `account`.\n   */\n  event Unpaused(address account);\n\n  bool private _paused;\n\n  /**\n   * @dev Initializes the contract in unpaused state.\n   */\n  constructor() {\n    _paused = false;\n  }\n\n  /**\n   * @dev Modifier to make a function callable only when the contract is not paused.\n   *\n   * Requirements:\n   *\n   * - The contract must not be paused.\n   */\n  modifier whenNotPaused() {\n    _requireNotPaused();\n    _;\n  }\n\n  /**\n   * @dev Modifier to make a function callable only when the contract is paused.\n   *\n   * Requirements:\n   *\n   * - The contract must be paused.\n   */\n  modifier whenPaused() {\n    _requirePaused();\n    _;\n  }\n\n  /**\n   * @dev Returns true if the contract is paused, and false otherwise.\n   */\n  function paused() public view virtual returns (bool) {\n    return _paused;\n  }\n\n  /**\n   * @dev Throws if the contract is paused.\n   */\n  function _requireNotPaused() internal view virtual {\n    require(!paused(), \"Pausable: paused\");\n  }\n\n  /**\n   * @dev Throws if the contract is not paused.\n   */\n  function _requirePaused() internal view virtual {\n    require(paused(), \"Pausable: not paused\");\n  }\n\n  /**\n   * @dev Triggers stopped state.\n   *\n   * Requirements:\n   *\n   * - The contract must not be paused.\n   */\n  function _pause() internal virtual whenNotPaused {\n    _paused = true;\n    emit Paused(_msgSender());\n  }\n\n  /**\n   * @dev Returns to normal state.\n   *\n   * Requirements:\n   *\n   * - The contract must be paused.\n   */\n  function _unpause() internal virtual whenPaused {\n    _paused = false;\n    emit Unpaused(_msgSender());\n  }\n}\n"
      },
      "src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n  /**\n   * @dev Emitted when `value` tokens are moved from one account (`from`) to\n   * another (`to`).\n   *\n   * Note that `value` may be zero.\n   */\n  event Transfer(address indexed from, address indexed to, uint256 value);\n\n  /**\n   * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n   * a call to {approve}. `value` is the new allowance.\n   */\n  event Approval(address indexed owner, address indexed spender, uint256 value);\n\n  /**\n   * @dev Returns the amount of tokens in existence.\n   */\n  function totalSupply() external view returns (uint256);\n\n  /**\n   * @dev Returns the amount of tokens owned by `account`.\n   */\n  function balanceOf(address account) external view returns (uint256);\n\n  /**\n   * @dev Moves `amount` tokens from the caller's account to `to`.\n   *\n   * Returns a boolean value indicating whether the operation succeeded.\n   *\n   * Emits a {Transfer} event.\n   */\n  function transfer(address to, uint256 amount) external returns (bool);\n\n  /**\n   * @dev Returns the remaining number of tokens that `spender` will be\n   * allowed to spend on behalf of `owner` through {transferFrom}. This is\n   * zero by default.\n   *\n   * This value changes when {approve} or {transferFrom} are called.\n   */\n  function allowance(address owner, address spender) external view returns (uint256);\n\n  /**\n   * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n   *\n   * Returns a boolean value indicating whether the operation succeeded.\n   *\n   * IMPORTANT: Beware that changing an allowance with this method brings the risk\n   * that someone may use both the old and the new allowance by unfortunate\n   * transaction ordering. One possible solution to mitigate this race\n   * condition is to first reduce the spender's allowance to 0 and set the\n   * desired value afterwards:\n   * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n   *\n   * Emits an {Approval} event.\n   */\n  function approve(address spender, uint256 amount) external returns (bool);\n\n  /**\n   * @dev Moves `amount` tokens from `from` to `to` using the\n   * allowance mechanism. `amount` is then deducted from the caller's\n   * allowance.\n   *\n   * Returns a boolean value indicating whether the operation succeeded.\n   *\n   * Emits a {Transfer} event.\n   */\n  function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n"
      },
      "src/v0.8/vendor/openzeppelin-solidity/v4.8.3/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"
      },
      "src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/utils/Strings.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n  bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n  uint8 private constant _ADDRESS_LENGTH = 20;\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    unchecked {\n      uint256 length = Math.log10(value) + 1;\n      string memory buffer = new string(length);\n      uint256 ptr;\n      /// @solidity memory-safe-assembly\n      assembly {\n        ptr := add(buffer, add(32, length))\n      }\n      while (true) {\n        ptr--;\n        /// @solidity memory-safe-assembly\n        assembly {\n          mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n        }\n        value /= 10;\n        if (value == 0) break;\n      }\n      return buffer;\n    }\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    unchecked {\n      return toHexString(value, Math.log256(value) + 1);\n    }\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] = _SYMBOLS[value & 0xf];\n      value >>= 4;\n    }\n    require(value == 0, \"Strings: hex length insufficient\");\n    return string(buffer);\n  }\n\n  /**\n   * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n   */\n  function toHexString(address addr) internal pure returns (string memory) {\n    return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n  }\n}\n"
      },
      "src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}"
      },
      "src/v0.8/vendor/openzeppelin-solidity/v4.8.3/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}"
      },
      "src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/utils/math/Math.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n  enum Rounding {\n    Down, // Toward negative infinity\n    Up, // Toward infinity\n    Zero // Toward zero\n  }\n\n  /**\n   * @dev Returns the largest of two numbers.\n   */\n  function max(uint256 a, uint256 b) internal pure returns (uint256) {\n    return a > b ? a : b;\n  }\n\n  /**\n   * @dev Returns the smallest of two numbers.\n   */\n  function min(uint256 a, uint256 b) internal pure returns (uint256) {\n    return a < b ? a : b;\n  }\n\n  /**\n   * @dev Returns the average of two numbers. The result is rounded towards\n   * zero.\n   */\n  function average(uint256 a, uint256 b) internal pure returns (uint256) {\n    // (a + b) / 2 can overflow.\n    return (a & b) + (a ^ b) / 2;\n  }\n\n  /**\n   * @dev Returns the ceiling of the division of two numbers.\n   *\n   * This differs from standard division with `/` in that it rounds up instead\n   * of rounding down.\n   */\n  function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n    // (a + b - 1) / b can overflow on addition, so we distribute.\n    return a == 0 ? 0 : (a - 1) / b + 1;\n  }\n\n  /**\n   * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n   * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n   * with further edits by Uniswap Labs also under MIT license.\n   */\n  function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n    unchecked {\n      // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n      // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n      // variables such that product = prod1 * 2^256 + prod0.\n      uint256 prod0; // Least significant 256 bits of the product\n      uint256 prod1; // Most significant 256 bits of the product\n      assembly {\n        let mm := mulmod(x, y, not(0))\n        prod0 := mul(x, y)\n        prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n      }\n\n      // Handle non-overflow cases, 256 by 256 division.\n      if (prod1 == 0) {\n        return prod0 / denominator;\n      }\n\n      // Make sure the result is less than 2^256. Also prevents denominator == 0.\n      require(denominator > prod1);\n\n      ///////////////////////////////////////////////\n      // 512 by 256 division.\n      ///////////////////////////////////////////////\n\n      // Make division exact by subtracting the remainder from [prod1 prod0].\n      uint256 remainder;\n      assembly {\n        // Compute remainder using mulmod.\n        remainder := mulmod(x, y, denominator)\n\n        // Subtract 256 bit number from 512 bit number.\n        prod1 := sub(prod1, gt(remainder, prod0))\n        prod0 := sub(prod0, remainder)\n      }\n\n      // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n      // See https://cs.stackexchange.com/q/138556/92363.\n\n      // Does not overflow because the denominator cannot be zero at this stage in the function.\n      uint256 twos = denominator & (~denominator + 1);\n      assembly {\n        // Divide denominator by twos.\n        denominator := div(denominator, twos)\n\n        // Divide [prod1 prod0] by twos.\n        prod0 := div(prod0, twos)\n\n        // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n        twos := add(div(sub(0, twos), twos), 1)\n      }\n\n      // Shift in bits from prod1 into prod0.\n      prod0 |= prod1 * twos;\n\n      // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n      // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n      // four bits. That is, denominator * inv = 1 mod 2^4.\n      uint256 inverse = (3 * denominator) ^ 2;\n\n      // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n      // in modular arithmetic, doubling the correct bits in each step.\n      inverse *= 2 - denominator * inverse; // inverse mod 2^8\n      inverse *= 2 - denominator * inverse; // inverse mod 2^16\n      inverse *= 2 - denominator * inverse; // inverse mod 2^32\n      inverse *= 2 - denominator * inverse; // inverse mod 2^64\n      inverse *= 2 - denominator * inverse; // inverse mod 2^128\n      inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n      // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n      // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n      // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n      // is no longer required.\n      result = prod0 * inverse;\n      return result;\n    }\n  }\n\n  /**\n   * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n   */\n  function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n    uint256 result = mulDiv(x, y, denominator);\n    if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n      result += 1;\n    }\n    return result;\n  }\n\n  /**\n   * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n   *\n   * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n   */\n  function sqrt(uint256 a) internal pure returns (uint256) {\n    if (a == 0) {\n      return 0;\n    }\n\n    // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n    //\n    // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n    // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n    //\n    // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n    // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n    // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n    //\n    // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n    uint256 result = 1 << (log2(a) >> 1);\n\n    // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n    // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n    // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n    // into the expected uint128 result.\n    unchecked {\n      result = (result + a / result) >> 1;\n      result = (result + a / result) >> 1;\n      result = (result + a / result) >> 1;\n      result = (result + a / result) >> 1;\n      result = (result + a / result) >> 1;\n      result = (result + a / result) >> 1;\n      result = (result + a / result) >> 1;\n      return min(result, a / result);\n    }\n  }\n\n  /**\n   * @notice Calculates sqrt(a), following the selected rounding direction.\n   */\n  function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n    unchecked {\n      uint256 result = sqrt(a);\n      return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n    }\n  }\n\n  /**\n   * @dev Return the log in base 2, rounded down, of a positive value.\n   * Returns 0 if given 0.\n   */\n  function log2(uint256 value) internal pure returns (uint256) {\n    uint256 result = 0;\n    unchecked {\n      if (value >> 128 > 0) {\n        value >>= 128;\n        result += 128;\n      }\n      if (value >> 64 > 0) {\n        value >>= 64;\n        result += 64;\n      }\n      if (value >> 32 > 0) {\n        value >>= 32;\n        result += 32;\n      }\n      if (value >> 16 > 0) {\n        value >>= 16;\n        result += 16;\n      }\n      if (value >> 8 > 0) {\n        value >>= 8;\n        result += 8;\n      }\n      if (value >> 4 > 0) {\n        value >>= 4;\n        result += 4;\n      }\n      if (value >> 2 > 0) {\n        value >>= 2;\n        result += 2;\n      }\n      if (value >> 1 > 0) {\n        result += 1;\n      }\n    }\n    return result;\n  }\n\n  /**\n   * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n   * Returns 0 if given 0.\n   */\n  function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n    unchecked {\n      uint256 result = log2(value);\n      return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n    }\n  }\n\n  /**\n   * @dev Return the log in base 10, rounded down, of a positive value.\n   * Returns 0 if given 0.\n   */\n  function log10(uint256 value) internal pure returns (uint256) {\n    uint256 result = 0;\n    unchecked {\n      if (value >= 10 ** 64) {\n        value /= 10 ** 64;\n        result += 64;\n      }\n      if (value >= 10 ** 32) {\n        value /= 10 ** 32;\n        result += 32;\n      }\n      if (value >= 10 ** 16) {\n        value /= 10 ** 16;\n        result += 16;\n      }\n      if (value >= 10 ** 8) {\n        value /= 10 ** 8;\n        result += 8;\n      }\n      if (value >= 10 ** 4) {\n        value /= 10 ** 4;\n        result += 4;\n      }\n      if (value >= 10 ** 2) {\n        value /= 10 ** 2;\n        result += 2;\n      }\n      if (value >= 10 ** 1) {\n        result += 1;\n      }\n    }\n    return result;\n  }\n\n  /**\n   * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n   * Returns 0 if given 0.\n   */\n  function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n    unchecked {\n      uint256 result = log10(value);\n      return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n    }\n  }\n\n  /**\n   * @dev Return the log in base 256, rounded down, of a positive value.\n   * Returns 0 if given 0.\n   *\n   * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n   */\n  function log256(uint256 value) internal pure returns (uint256) {\n    uint256 result = 0;\n    unchecked {\n      if (value >> 128 > 0) {\n        value >>= 128;\n        result += 16;\n      }\n      if (value >> 64 > 0) {\n        value >>= 64;\n        result += 8;\n      }\n      if (value >> 32 > 0) {\n        value >>= 32;\n        result += 4;\n      }\n      if (value >> 16 > 0) {\n        value >>= 16;\n        result += 2;\n      }\n      if (value >> 8 > 0) {\n        result += 1;\n      }\n    }\n    return result;\n  }\n\n  /**\n   * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n   * Returns 0 if given 0.\n   */\n  function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n    unchecked {\n      uint256 result = log256(value);\n      return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n    }\n  }\n}\n"
      },
      "src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableMap.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableMap.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableMap.js.\n\npragma solidity ^0.8.0;\n\nimport \"./EnumerableSet.sol\";\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n *     // Add the library methods\n *     using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n *     // Declare a set state variable\n *     EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * The following map types are supported:\n *\n * - `uint256 -> address` (`UintToAddressMap`) since v3.0.0\n * - `address -> uint256` (`AddressToUintMap`) since v4.6.0\n * - `bytes32 -> bytes32` (`Bytes32ToBytes32Map`) since v4.6.0\n * - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0\n * - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableMap.\n * ====\n */\nlibrary EnumerableMap {\n    using EnumerableSet for EnumerableSet.Bytes32Set;\n\n    // To implement this library for multiple types with as little code\n    // repetition as possible, we write it in terms of a generic Map type with\n    // bytes32 keys and values.\n    // The Map implementation uses private functions, and user-facing\n    // implementations (such as Uint256ToAddressMap) are just wrappers around\n    // the underlying Map.\n    // This means that we can only create new EnumerableMaps for types that fit\n    // in bytes32.\n\n    struct Bytes32ToBytes32Map {\n        // Storage of keys\n        EnumerableSet.Bytes32Set _keys;\n        mapping(bytes32 => bytes32) _values;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(\n        Bytes32ToBytes32Map storage map,\n        bytes32 key,\n        bytes32 value\n    ) internal returns (bool) {\n        map._values[key] = value;\n        return map._keys.add(key);\n    }\n\n    /**\n     * @dev Removes a key-value pair from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) {\n        delete map._values[key];\n        return map._keys.remove(key);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) {\n        return map._keys.contains(key);\n    }\n\n    /**\n     * @dev Returns the number of key-value pairs in the map. O(1).\n     */\n    function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) {\n        return map._keys.length();\n    }\n\n    /**\n     * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n     *\n     * Note that there are no guarantees on the ordering of entries inside the\n     * array, and it may change when more entries are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32, bytes32) {\n        bytes32 key = map._keys.at(index);\n        return (key, map._values[key]);\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool, bytes32) {\n        bytes32 value = map._values[key];\n        if (value == bytes32(0)) {\n            return (contains(map, key), bytes32(0));\n        } else {\n            return (true, value);\n        }\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) {\n        bytes32 value = map._values[key];\n        require(value != 0 || contains(map, key), \"EnumerableMap: nonexistent key\");\n        return value;\n    }\n\n    /**\n     * @dev Same as {get}, with a custom error message when `key` is not in the map.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryGet}.\n     */\n    function get(\n        Bytes32ToBytes32Map storage map,\n        bytes32 key,\n        string memory errorMessage\n    ) internal view returns (bytes32) {\n        bytes32 value = map._values[key];\n        require(value != 0 || contains(map, key), errorMessage);\n        return value;\n    }\n\n    // UintToUintMap\n\n    struct UintToUintMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(\n        UintToUintMap storage map,\n        uint256 key,\n        uint256 value\n    ) internal returns (bool) {\n        return set(map._inner, bytes32(key), bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(UintToUintMap storage map, uint256 key) internal returns (bool) {\n        return remove(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) {\n        return contains(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(UintToUintMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the set. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintToUintMap storage map, uint256 index) internal view returns (uint256, uint256) {\n        (bytes32 key, bytes32 value) = at(map._inner, index);\n        return (uint256(key), uint256(value));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool, uint256) {\n        (bool success, bytes32 value) = tryGet(map._inner, bytes32(key));\n        return (success, uint256(value));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) {\n        return uint256(get(map._inner, bytes32(key)));\n    }\n\n    /**\n     * @dev Same as {get}, with a custom error message when `key` is not in the map.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryGet}.\n     */\n    function get(\n        UintToUintMap storage map,\n        uint256 key,\n        string memory errorMessage\n    ) internal view returns (uint256) {\n        return uint256(get(map._inner, bytes32(key), errorMessage));\n    }\n\n    // UintToAddressMap\n\n    struct UintToAddressMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(\n        UintToAddressMap storage map,\n        uint256 key,\n        address value\n    ) internal returns (bool) {\n        return set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n        return remove(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n        return contains(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(UintToAddressMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the set. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {\n        (bytes32 key, bytes32 value) = at(map._inner, index);\n        return (uint256(key), address(uint160(uint256(value))));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {\n        (bool success, bytes32 value) = tryGet(map._inner, bytes32(key));\n        return (success, address(uint160(uint256(value))));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n        return address(uint160(uint256(get(map._inner, bytes32(key)))));\n    }\n\n    /**\n     * @dev Same as {get}, with a custom error message when `key` is not in the map.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryGet}.\n     */\n    function get(\n        UintToAddressMap storage map,\n        uint256 key,\n        string memory errorMessage\n    ) internal view returns (address) {\n        return address(uint160(uint256(get(map._inner, bytes32(key), errorMessage))));\n    }\n\n    // AddressToUintMap\n\n    struct AddressToUintMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(\n        AddressToUintMap storage map,\n        address key,\n        uint256 value\n    ) internal returns (bool) {\n        return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(AddressToUintMap storage map, address key) internal returns (bool) {\n        return remove(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(AddressToUintMap storage map, address key) internal view returns (bool) {\n        return contains(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(AddressToUintMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the set. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) {\n        (bytes32 key, bytes32 value) = at(map._inner, index);\n        return (address(uint160(uint256(key))), uint256(value));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) {\n        (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key))));\n        return (success, uint256(value));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(AddressToUintMap storage map, address key) internal view returns (uint256) {\n        return uint256(get(map._inner, bytes32(uint256(uint160(key)))));\n    }\n\n    /**\n     * @dev Same as {get}, with a custom error message when `key` is not in the map.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryGet}.\n     */\n    function get(\n        AddressToUintMap storage map,\n        address key,\n        string memory errorMessage\n    ) internal view returns (uint256) {\n        return uint256(get(map._inner, bytes32(uint256(uint160(key))), errorMessage));\n    }\n\n    // Bytes32ToUintMap\n\n    struct Bytes32ToUintMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(\n        Bytes32ToUintMap storage map,\n        bytes32 key,\n        uint256 value\n    ) internal returns (bool) {\n        return set(map._inner, key, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) {\n        return remove(map._inner, key);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) {\n        return contains(map._inner, key);\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(Bytes32ToUintMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the set. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32, uint256) {\n        (bytes32 key, bytes32 value) = at(map._inner, index);\n        return (key, uint256(value));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool, uint256) {\n        (bool success, bytes32 value) = tryGet(map._inner, key);\n        return (success, uint256(value));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) {\n        return uint256(get(map._inner, key));\n    }\n\n    /**\n     * @dev Same as {get}, with a custom error message when `key` is not in the map.\n     *\n     * CAUTION: This function is deprecated because it requires allocating memory for the error\n     * message unnecessarily. For custom revert reasons use {tryGet}.\n     */\n    function get(\n        Bytes32ToUintMap storage map,\n        bytes32 key,\n        string memory errorMessage\n    ) internal view returns (uint256) {\n        return uint256(get(map._inner, key, errorMessage));\n    }\n}"
      },
      "src/v0.8/vendor/openzeppelin-solidity/v4.8.3/contracts/utils/structs/EnumerableSet.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n *     // Add the library methods\n *     using EnumerableSet for EnumerableSet.AddressSet;\n *\n *     // Declare a set state variable\n *     EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n  // To implement this library for multiple types with as little code\n  // repetition as possible, we write it in terms of a generic Set type with\n  // bytes32 values.\n  // The Set implementation uses private functions, and user-facing\n  // implementations (such as AddressSet) are just wrappers around the\n  // underlying Set.\n  // This means that we can only create new EnumerableSets for types that fit\n  // in bytes32.\n\n  struct Set {\n    // Storage of set values\n    bytes32[] _values;\n    // Position of the value in the `values` array, plus 1 because index 0\n    // means a value is not in the set.\n    mapping(bytes32 => uint256) _indexes;\n  }\n\n  /**\n   * @dev Add a value to a set. O(1).\n   *\n   * Returns true if the value was added to the set, that is if it was not\n   * already present.\n   */\n  function _add(Set storage set, bytes32 value) private returns (bool) {\n    if (!_contains(set, value)) {\n      set._values.push(value);\n      // The value is stored at length-1, but we add 1 to all indexes\n      // and use 0 as a sentinel value\n      set._indexes[value] = set._values.length;\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  /**\n   * @dev Removes a value from a set. O(1).\n   *\n   * Returns true if the value was removed from the set, that is if it was\n   * present.\n   */\n  function _remove(Set storage set, bytes32 value) private returns (bool) {\n    // We read and store the value's index to prevent multiple reads from the same storage slot\n    uint256 valueIndex = set._indexes[value];\n\n    if (valueIndex != 0) {\n      // Equivalent to contains(set, value)\n      // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n      // the array, and then remove the last element (sometimes called as 'swap and pop').\n      // This modifies the order of the array, as noted in {at}.\n\n      uint256 toDeleteIndex = valueIndex - 1;\n      uint256 lastIndex = set._values.length - 1;\n\n      if (lastIndex != toDeleteIndex) {\n        bytes32 lastValue = set._values[lastIndex];\n\n        // Move the last value to the index where the value to delete is\n        set._values[toDeleteIndex] = lastValue;\n        // Update the index for the moved value\n        set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n      }\n\n      // Delete the slot where the moved value was stored\n      set._values.pop();\n\n      // Delete the index for the deleted slot\n      delete set._indexes[value];\n\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  /**\n   * @dev Returns true if the value is in the set. O(1).\n   */\n  function _contains(Set storage set, bytes32 value) private view returns (bool) {\n    return set._indexes[value] != 0;\n  }\n\n  /**\n   * @dev Returns the number of values on the set. O(1).\n   */\n  function _length(Set storage set) private view returns (uint256) {\n    return set._values.length;\n  }\n\n  /**\n   * @dev Returns the value stored at position `index` in the set. O(1).\n   *\n   * Note that there are no guarantees on the ordering of values inside the\n   * array, and it may change when more values are added or removed.\n   *\n   * Requirements:\n   *\n   * - `index` must be strictly less than {length}.\n   */\n  function _at(Set storage set, uint256 index) private view returns (bytes32) {\n    return set._values[index];\n  }\n\n  /**\n   * @dev Return the entire set in an array\n   *\n   * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n   * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n   * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n   * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n   */\n  function _values(Set storage set) private view returns (bytes32[] memory) {\n    return set._values;\n  }\n\n  // Bytes32Set\n\n  struct Bytes32Set {\n    Set _inner;\n  }\n\n  /**\n   * @dev Add a value to a set. O(1).\n   *\n   * Returns true if the value was added to the set, that is if it was not\n   * already present.\n   */\n  function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n    return _add(set._inner, value);\n  }\n\n  /**\n   * @dev Removes a value from a set. O(1).\n   *\n   * Returns true if the value was removed from the set, that is if it was\n   * present.\n   */\n  function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n    return _remove(set._inner, value);\n  }\n\n  /**\n   * @dev Returns true if the value is in the set. O(1).\n   */\n  function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n    return _contains(set._inner, value);\n  }\n\n  /**\n   * @dev Returns the number of values in the set. O(1).\n   */\n  function length(Bytes32Set storage set) internal view returns (uint256) {\n    return _length(set._inner);\n  }\n\n  /**\n   * @dev Returns the value stored at position `index` in the set. O(1).\n   *\n   * Note that there are no guarantees on the ordering of values inside the\n   * array, and it may change when more values are added or removed.\n   *\n   * Requirements:\n   *\n   * - `index` must be strictly less than {length}.\n   */\n  function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n    return _at(set._inner, index);\n  }\n\n  /**\n   * @dev Return the entire set in an array\n   *\n   * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n   * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n   * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n   * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n   */\n  function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n    bytes32[] memory store = _values(set._inner);\n    bytes32[] memory result;\n\n    /// @solidity memory-safe-assembly\n    assembly {\n      result := store\n    }\n\n    return result;\n  }\n\n  // AddressSet\n\n  struct AddressSet {\n    Set _inner;\n  }\n\n  /**\n   * @dev Add a value to a set. O(1).\n   *\n   * Returns true if the value was added to the set, that is if it was not\n   * already present.\n   */\n  function add(AddressSet storage set, address value) internal returns (bool) {\n    return _add(set._inner, bytes32(uint256(uint160(value))));\n  }\n\n  /**\n   * @dev Removes a value from a set. O(1).\n   *\n   * Returns true if the value was removed from the set, that is if it was\n   * present.\n   */\n  function remove(AddressSet storage set, address value) internal returns (bool) {\n    return _remove(set._inner, bytes32(uint256(uint160(value))));\n  }\n\n  /**\n   * @dev Returns true if the value is in the set. O(1).\n   */\n  function contains(AddressSet storage set, address value) internal view returns (bool) {\n    return _contains(set._inner, bytes32(uint256(uint160(value))));\n  }\n\n  /**\n   * @dev Returns the number of values in the set. O(1).\n   */\n  function length(AddressSet storage set) internal view returns (uint256) {\n    return _length(set._inner);\n  }\n\n  /**\n   * @dev Returns the value stored at position `index` in the set. O(1).\n   *\n   * Note that there are no guarantees on the ordering of values inside the\n   * array, and it may change when more values are added or removed.\n   *\n   * Requirements:\n   *\n   * - `index` must be strictly less than {length}.\n   */\n  function at(AddressSet storage set, uint256 index) internal view returns (address) {\n    return address(uint160(uint256(_at(set._inner, index))));\n  }\n\n  /**\n   * @dev Return the entire set in an array\n   *\n   * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n   * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n   * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n   * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n   */\n  function values(AddressSet storage set) internal view returns (address[] memory) {\n    bytes32[] memory store = _values(set._inner);\n    address[] memory result;\n\n    /// @solidity memory-safe-assembly\n    assembly {\n      result := store\n    }\n\n    return result;\n  }\n\n  // UintSet\n\n  struct UintSet {\n    Set _inner;\n  }\n\n  /**\n   * @dev Add a value to a set. O(1).\n   *\n   * Returns true if the value was added to the set, that is if it was not\n   * already present.\n   */\n  function add(UintSet storage set, uint256 value) internal returns (bool) {\n    return _add(set._inner, bytes32(value));\n  }\n\n  /**\n   * @dev Removes a value from a set. O(1).\n   *\n   * Returns true if the value was removed from the set, that is if it was\n   * present.\n   */\n  function remove(UintSet storage set, uint256 value) internal returns (bool) {\n    return _remove(set._inner, bytes32(value));\n  }\n\n  /**\n   * @dev Returns true if the value is in the set. O(1).\n   */\n  function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n    return _contains(set._inner, bytes32(value));\n  }\n\n  /**\n   * @dev Returns the number of values in the set. O(1).\n   */\n  function length(UintSet storage set) internal view returns (uint256) {\n    return _length(set._inner);\n  }\n\n  /**\n   * @dev Returns the value stored at position `index` in the set. O(1).\n   *\n   * Note that there are no guarantees on the ordering of values inside the\n   * array, and it may change when more values are added or removed.\n   *\n   * Requirements:\n   *\n   * - `index` must be strictly less than {length}.\n   */\n  function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n    return uint256(_at(set._inner, index));\n  }\n\n  /**\n   * @dev Return the entire set in an array\n   *\n   * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n   * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n   * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n   * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n   */\n  function values(UintSet storage set) internal view returns (uint256[] memory) {\n    bytes32[] memory store = _values(set._inner);\n    uint256[] memory result;\n\n    /// @solidity memory-safe-assembly\n    assembly {\n      result := store\n    }\n\n    return result;\n  }\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "ds-test/=foundry-lib/forge-std/lib/ds-test/src/",
        "forge-std/=foundry-lib/forge-std/src/",
        "@openzeppelin/=node_modules/@openzeppelin/",
        "hardhat/=node_modules/hardhat/",
        "@eth-optimism/=node_modules/@eth-optimism/",
        "@scroll-tech/=node_modules/@scroll-tech/",
        "@ensdomains/=node_modules/@ensdomains/",
        "erc4626-tests/=foundry-lib/openzeppelin-contracts/lib/erc4626-tests/",
        "eth-gas-reporter/=node_modules/eth-gas-reporter/",
        "openzeppelin-contracts/=foundry-lib/openzeppelin-contracts/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 1000000
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "none",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "libraries": {}
    }
  }}