ETH Price: $2,413.59 (+7.36%)
Gas: 1.04 Gwei

Transaction Decoder

Block:
21024564 at Oct-23-2024 12:01:11 AM +UTC
Transaction Fee:
0.001279214888271452 ETH $3.09
Gas Used:
113,201 Gas / 11.300385052 Gwei

Emitted Events:

474 ERC1967Proxy.0x33e849cb0fec1c09717acb97b31d5c785c809f0b281858ddae6dcbc17ded5b9d( 0x33e849cb0fec1c09717acb97b31d5c785c809f0b281858ddae6dcbc17ded5b9d, 0000000000000000000000000000000000000000000000000000000000000080, 00000000000000000000000000000000000000000000000000000000000000c0, 0000000000000000000000000000000000000000000000000000000000000100, 0000000000000000000000000000000000000000000000000000000000000180, 0000000000000000000000000000000000000000000000000000000000000020, 0bcb6b0b9168c058e28754b0255038028ff8515b5755d989d746fdd8b8f11d7e, 0000000000000000000000000000000000000000000000000000000000000020, 2b7712f4e0170b0413aafb4f36ef011c7a65fe16995d728a1ad0bb0d9be6bd65, 0000000000000000000000000000000000000000000000000000000000000060, 00000000000000000000000007ef0d75c2a7a7ebc2ee8d449efd8542abd53a8c, ed1fbae5bd033941ce212182d017fb055b5dd64e9748b39a3bc027f6aa514ff3, 00000000000000000000000000000000000000000000000000000000001e8480, 0000000000000000000000000000000000000000000000000000000000000020, 00000000000000000000000000000000000000000000000083d2b583188290bd )
475 ERC1967Proxy.0xe3407208b14fa025330ca187030f118a1c0cdb604aba93ba45c862e6095aee27( 0xe3407208b14fa025330ca187030f118a1c0cdb604aba93ba45c862e6095aee27, 0x00000000000000000000000083cb71d80078bf670b3efec6ad9e5e6407cd0fd1, 00000000000000000000000000000000000000000000000000071afd498d0000 )
476 ERC1967Proxy.0xfe447f84c02bd3d47e0f77ccc68779ac1a79d4a2e3a0a66f626b495f8bf88084( 0xfe447f84c02bd3d47e0f77ccc68779ac1a79d4a2e3a0a66f626b495f8bf88084, 0x00000000000000000000000007ef0d75c2a7a7ebc2ee8d449efd8542abd53a8c, 0xed1fbae5bd033941ce212182d017fb055b5dd64e9748b39a3bc027f6aa514ff3, 00000000000000000000000000000000000000000000000000071afd498d0000 )

Account State Difference:

  Address   Before After State Difference Code
0x07EF0d75...2Abd53A8C
0.063729751713667935 Eth
Nonce: 264
0.060450536825396483 Eth
Nonce: 265
0.003279214888271452
(beaverbuild)
14.88359719725738654 Eth14.88365379775738654 Eth0.0000566005
0xb23B2492...33660968d
0xD7E4b67E...ac670E644
(Eclipse: L1 Deposit Contract)
955.432824473 Eth955.434824473 Eth0.002

Execution Trace

ETH 0.002 ERC1967Proxy.1de26e16( )
  • ETH 0.002 EtherBridge.deposit( recipient=ED1FBAE5BD033941CE212182D017FB055B5DD64E9748B39A3BC027F6AA514FF3, amountWei=2000000000000000 )
    • ERC1967Proxy.0984f0c1( )
      • Mailbox.sendMessage( 0x, receiver_=0x0BCB6B0B9168C058E28754B0255038028FF8515B5755D989D746FDD8B8F11D7E, message_=0x00000000000000000000000007EF0D75C2A7A7EBC2EE8D449EFD8542ABD53A8CED1FBAE5BD033941CE212182D017FB055B5DD64E9748B39A3BC027F6AA514FF300000000000000000000000000000000000000000000000000000000001E8480, 0x ) => ( True )
      • ETH 0.002 ERC1967Proxy.CALL( )
        • ETH 0.002 Treasury.DELEGATECALL( )
          File 1 of 6: ERC1967Proxy
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Proxy.sol)
          pragma solidity ^0.8.20;
          import {Proxy} from "../Proxy.sol";
          import {ERC1967Utils} from "./ERC1967Utils.sol";
          /**
           * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
           * implementation address that can be changed. This address is stored in storage in the location specified by
           * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the
           * implementation behind the proxy.
           */
          contract ERC1967Proxy is Proxy {
              /**
               * @dev Initializes the upgradeable proxy with an initial implementation specified by `implementation`.
               *
               * If `_data` is nonempty, it's used as data in a delegate call to `implementation`. This will typically be an
               * encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.
               *
               * Requirements:
               *
               * - If `data` is empty, `msg.value` must be zero.
               */
              constructor(address implementation, bytes memory _data) payable {
                  ERC1967Utils.upgradeToAndCall(implementation, _data);
              }
              /**
               * @dev Returns the current implementation address.
               *
               * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using
               * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
               * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`
               */
              function _implementation() internal view virtual override returns (address) {
                  return ERC1967Utils.getImplementation();
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/Proxy.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
           * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
           * be specified by overriding the virtual {_implementation} function.
           *
           * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
           * different contract through the {_delegate} function.
           *
           * The success and return data of the delegated call will be returned back to the caller of the proxy.
           */
          abstract contract Proxy {
              /**
               * @dev Delegates the current call to `implementation`.
               *
               * This function does not return to its internal call site, it will return directly to the external caller.
               */
              function _delegate(address implementation) internal virtual {
                  assembly {
                      // Copy msg.data. We take full control of memory in this inline assembly
                      // block because it will not return to Solidity code. We overwrite the
                      // Solidity scratch pad at memory position 0.
                      calldatacopy(0, 0, calldatasize())
                      // Call the implementation.
                      // out and outsize are 0 because we don't know the size yet.
                      let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
                      // Copy the returned data.
                      returndatacopy(0, 0, returndatasize())
                      switch result
                      // delegatecall returns 0 on error.
                      case 0 {
                          revert(0, returndatasize())
                      }
                      default {
                          return(0, returndatasize())
                      }
                  }
              }
              /**
               * @dev This is a virtual function that should be overridden so it returns the address to which the fallback
               * function and {_fallback} should delegate.
               */
              function _implementation() internal view virtual returns (address);
              /**
               * @dev Delegates the current call to the address returned by `_implementation()`.
               *
               * This function does not return to its internal call site, it will return directly to the external caller.
               */
              function _fallback() internal virtual {
                  _delegate(_implementation());
              }
              /**
               * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
               * function in the contract matches the call data.
               */
              fallback() external payable virtual {
                  _fallback();
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Utils.sol)
          pragma solidity ^0.8.20;
          import {IBeacon} from "../beacon/IBeacon.sol";
          import {Address} from "../../utils/Address.sol";
          import {StorageSlot} from "../../utils/StorageSlot.sol";
          /**
           * @dev This abstract contract provides getters and event emitting update functions for
           * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
           */
          library ERC1967Utils {
              // We re-declare ERC-1967 events here because they can't be used directly from IERC1967.
              // This will be fixed in Solidity 0.8.21. At that point we should remove these events.
              /**
               * @dev Emitted when the implementation is upgraded.
               */
              event Upgraded(address indexed implementation);
              /**
               * @dev Emitted when the admin account has changed.
               */
              event AdminChanged(address previousAdmin, address newAdmin);
              /**
               * @dev Emitted when the beacon is changed.
               */
              event BeaconUpgraded(address indexed beacon);
              /**
               * @dev Storage slot with the address of the current implementation.
               * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1.
               */
              // solhint-disable-next-line private-vars-leading-underscore
              bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
              /**
               * @dev The `implementation` of the proxy is invalid.
               */
              error ERC1967InvalidImplementation(address implementation);
              /**
               * @dev The `admin` of the proxy is invalid.
               */
              error ERC1967InvalidAdmin(address admin);
              /**
               * @dev The `beacon` of the proxy is invalid.
               */
              error ERC1967InvalidBeacon(address beacon);
              /**
               * @dev An upgrade function sees `msg.value > 0` that may be lost.
               */
              error ERC1967NonPayable();
              /**
               * @dev Returns the current implementation address.
               */
              function getImplementation() internal view returns (address) {
                  return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;
              }
              /**
               * @dev Stores a new address in the EIP1967 implementation slot.
               */
              function _setImplementation(address newImplementation) private {
                  if (newImplementation.code.length == 0) {
                      revert ERC1967InvalidImplementation(newImplementation);
                  }
                  StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;
              }
              /**
               * @dev Performs implementation upgrade with additional setup call if data is nonempty.
               * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
               * to avoid stuck value in the contract.
               *
               * Emits an {IERC1967-Upgraded} event.
               */
              function upgradeToAndCall(address newImplementation, bytes memory data) internal {
                  _setImplementation(newImplementation);
                  emit Upgraded(newImplementation);
                  if (data.length > 0) {
                      Address.functionDelegateCall(newImplementation, data);
                  } else {
                      _checkNonPayable();
                  }
              }
              /**
               * @dev Storage slot with the admin of the contract.
               * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1.
               */
              // solhint-disable-next-line private-vars-leading-underscore
              bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
              /**
               * @dev Returns the current admin.
               *
               * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using
               * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
               * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
               */
              function getAdmin() internal view returns (address) {
                  return StorageSlot.getAddressSlot(ADMIN_SLOT).value;
              }
              /**
               * @dev Stores a new address in the EIP1967 admin slot.
               */
              function _setAdmin(address newAdmin) private {
                  if (newAdmin == address(0)) {
                      revert ERC1967InvalidAdmin(address(0));
                  }
                  StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;
              }
              /**
               * @dev Changes the admin of the proxy.
               *
               * Emits an {IERC1967-AdminChanged} event.
               */
              function changeAdmin(address newAdmin) internal {
                  emit AdminChanged(getAdmin(), newAdmin);
                  _setAdmin(newAdmin);
              }
              /**
               * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
               * This is the keccak-256 hash of "eip1967.proxy.beacon" subtracted by 1.
               */
              // solhint-disable-next-line private-vars-leading-underscore
              bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
              /**
               * @dev Returns the current beacon.
               */
              function getBeacon() internal view returns (address) {
                  return StorageSlot.getAddressSlot(BEACON_SLOT).value;
              }
              /**
               * @dev Stores a new beacon in the EIP1967 beacon slot.
               */
              function _setBeacon(address newBeacon) private {
                  if (newBeacon.code.length == 0) {
                      revert ERC1967InvalidBeacon(newBeacon);
                  }
                  StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;
                  address beaconImplementation = IBeacon(newBeacon).implementation();
                  if (beaconImplementation.code.length == 0) {
                      revert ERC1967InvalidImplementation(beaconImplementation);
                  }
              }
              /**
               * @dev Change the beacon and trigger a setup call if data is nonempty.
               * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
               * to avoid stuck value in the contract.
               *
               * Emits an {IERC1967-BeaconUpgraded} event.
               *
               * CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since
               * it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for
               * efficiency.
               */
              function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {
                  _setBeacon(newBeacon);
                  emit BeaconUpgraded(newBeacon);
                  if (data.length > 0) {
                      Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
                  } else {
                      _checkNonPayable();
                  }
              }
              /**
               * @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract
               * if an upgrade doesn't perform an initialization call.
               */
              function _checkNonPayable() private {
                  if (msg.value > 0) {
                      revert ERC1967NonPayable();
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev This is the interface that {BeaconProxy} expects of its beacon.
           */
          interface IBeacon {
              /**
               * @dev Must return an address that can be used as a delegate call target.
               *
               * {UpgradeableBeacon} will check that this address is a contract.
               */
              function implementation() external view returns (address);
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev Collection of functions related to the address type
           */
          library Address {
              /**
               * @dev The ETH balance of the account is not enough to perform the operation.
               */
              error AddressInsufficientBalance(address account);
              /**
               * @dev There's no code at `target` (it is not a contract).
               */
              error AddressEmptyCode(address target);
              /**
               * @dev A call to an address target failed. The target may have reverted.
               */
              error FailedInnerCall();
              /**
               * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
               * `recipient`, forwarding all available gas and reverting on errors.
               *
               * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
               * of certain opcodes, possibly making contracts go over the 2300 gas limit
               * imposed by `transfer`, making them unable to receive funds via
               * `transfer`. {sendValue} removes this limitation.
               *
               * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
               *
               * IMPORTANT: because control is transferred to `recipient`, care must be
               * taken to not create reentrancy vulnerabilities. Consider using
               * {ReentrancyGuard} or the
               * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
               */
              function sendValue(address payable recipient, uint256 amount) internal {
                  if (address(this).balance < amount) {
                      revert AddressInsufficientBalance(address(this));
                  }
                  (bool success, ) = recipient.call{value: amount}("");
                  if (!success) {
                      revert FailedInnerCall();
                  }
              }
              /**
               * @dev Performs a Solidity function call using a low level `call`. A
               * plain `call` is an unsafe replacement for a function call: use this
               * function instead.
               *
               * If `target` reverts with a revert reason or custom error, it is bubbled
               * up by this function (like regular Solidity function calls). However, if
               * the call reverted with no returned reason, this function reverts with a
               * {FailedInnerCall} error.
               *
               * Returns the raw returned data. To convert to the expected return value,
               * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
               *
               * Requirements:
               *
               * - `target` must be a contract.
               * - calling `target` with `data` must not revert.
               */
              function functionCall(address target, bytes memory data) internal returns (bytes memory) {
                  return functionCallWithValue(target, data, 0);
              }
              /**
               * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
               * but also transferring `value` wei to `target`.
               *
               * Requirements:
               *
               * - the calling contract must have an ETH balance of at least `value`.
               * - the called Solidity function must be `payable`.
               */
              function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
                  if (address(this).balance < value) {
                      revert AddressInsufficientBalance(address(this));
                  }
                  (bool success, bytes memory returndata) = target.call{value: value}(data);
                  return verifyCallResultFromTarget(target, success, returndata);
              }
              /**
               * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
               * but performing a static call.
               */
              function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
                  (bool success, bytes memory returndata) = target.staticcall(data);
                  return verifyCallResultFromTarget(target, success, returndata);
              }
              /**
               * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
               * but performing a delegate call.
               */
              function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
                  (bool success, bytes memory returndata) = target.delegatecall(data);
                  return verifyCallResultFromTarget(target, success, returndata);
              }
              /**
               * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
               * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
               * unsuccessful call.
               */
              function verifyCallResultFromTarget(
                  address target,
                  bool success,
                  bytes memory returndata
              ) internal view returns (bytes memory) {
                  if (!success) {
                      _revert(returndata);
                  } else {
                      // only check if target is a contract if the call was successful and the return data is empty
                      // otherwise we already know that it was a contract
                      if (returndata.length == 0 && target.code.length == 0) {
                          revert AddressEmptyCode(target);
                      }
                      return returndata;
                  }
              }
              /**
               * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
               * revert reason or with a default {FailedInnerCall} error.
               */
              function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
                  if (!success) {
                      _revert(returndata);
                  } else {
                      return returndata;
                  }
              }
              /**
               * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
               */
              function _revert(bytes memory returndata) private pure {
                  // Look for revert reason and bubble it up if present
                  if (returndata.length > 0) {
                      // The easiest way to bubble the revert reason is using memory via assembly
                      /// @solidity memory-safe-assembly
                      assembly {
                          let returndata_size := mload(returndata)
                          revert(add(32, returndata), returndata_size)
                      }
                  } else {
                      revert FailedInnerCall();
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol)
          // This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
          pragma solidity ^0.8.20;
          /**
           * @dev Library for reading and writing primitive types to specific storage slots.
           *
           * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
           * This library helps with reading and writing to such slots without the need for inline assembly.
           *
           * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
           *
           * Example usage to set ERC1967 implementation slot:
           * ```solidity
           * contract ERC1967 {
           *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
           *
           *     function _getImplementation() internal view returns (address) {
           *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
           *     }
           *
           *     function _setImplementation(address newImplementation) internal {
           *         require(newImplementation.code.length > 0);
           *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
           *     }
           * }
           * ```
           */
          library StorageSlot {
              struct AddressSlot {
                  address value;
              }
              struct BooleanSlot {
                  bool value;
              }
              struct Bytes32Slot {
                  bytes32 value;
              }
              struct Uint256Slot {
                  uint256 value;
              }
              struct StringSlot {
                  string value;
              }
              struct BytesSlot {
                  bytes value;
              }
              /**
               * @dev Returns an `AddressSlot` with member `value` located at `slot`.
               */
              function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
               */
              function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
               */
              function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
               */
              function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `StringSlot` with member `value` located at `slot`.
               */
              function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `StringSlot` representation of the string storage pointer `store`.
               */
              function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := store.slot
                  }
              }
              /**
               * @dev Returns an `BytesSlot` with member `value` located at `slot`.
               */
              function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
               */
              function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := store.slot
                  }
              }
          }
          

          File 2 of 6: ERC1967Proxy
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Proxy.sol)
          pragma solidity ^0.8.20;
          import {Proxy} from "../Proxy.sol";
          import {ERC1967Utils} from "./ERC1967Utils.sol";
          /**
           * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
           * implementation address that can be changed. This address is stored in storage in the location specified by
           * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the
           * implementation behind the proxy.
           */
          contract ERC1967Proxy is Proxy {
              /**
               * @dev Initializes the upgradeable proxy with an initial implementation specified by `implementation`.
               *
               * If `_data` is nonempty, it's used as data in a delegate call to `implementation`. This will typically be an
               * encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.
               *
               * Requirements:
               *
               * - If `data` is empty, `msg.value` must be zero.
               */
              constructor(address implementation, bytes memory _data) payable {
                  ERC1967Utils.upgradeToAndCall(implementation, _data);
              }
              /**
               * @dev Returns the current implementation address.
               *
               * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using
               * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
               * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`
               */
              function _implementation() internal view virtual override returns (address) {
                  return ERC1967Utils.getImplementation();
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/Proxy.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
           * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
           * be specified by overriding the virtual {_implementation} function.
           *
           * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
           * different contract through the {_delegate} function.
           *
           * The success and return data of the delegated call will be returned back to the caller of the proxy.
           */
          abstract contract Proxy {
              /**
               * @dev Delegates the current call to `implementation`.
               *
               * This function does not return to its internal call site, it will return directly to the external caller.
               */
              function _delegate(address implementation) internal virtual {
                  assembly {
                      // Copy msg.data. We take full control of memory in this inline assembly
                      // block because it will not return to Solidity code. We overwrite the
                      // Solidity scratch pad at memory position 0.
                      calldatacopy(0, 0, calldatasize())
                      // Call the implementation.
                      // out and outsize are 0 because we don't know the size yet.
                      let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
                      // Copy the returned data.
                      returndatacopy(0, 0, returndatasize())
                      switch result
                      // delegatecall returns 0 on error.
                      case 0 {
                          revert(0, returndatasize())
                      }
                      default {
                          return(0, returndatasize())
                      }
                  }
              }
              /**
               * @dev This is a virtual function that should be overridden so it returns the address to which the fallback
               * function and {_fallback} should delegate.
               */
              function _implementation() internal view virtual returns (address);
              /**
               * @dev Delegates the current call to the address returned by `_implementation()`.
               *
               * This function does not return to its internal call site, it will return directly to the external caller.
               */
              function _fallback() internal virtual {
                  _delegate(_implementation());
              }
              /**
               * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
               * function in the contract matches the call data.
               */
              fallback() external payable virtual {
                  _fallback();
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Utils.sol)
          pragma solidity ^0.8.20;
          import {IBeacon} from "../beacon/IBeacon.sol";
          import {Address} from "../../utils/Address.sol";
          import {StorageSlot} from "../../utils/StorageSlot.sol";
          /**
           * @dev This abstract contract provides getters and event emitting update functions for
           * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
           */
          library ERC1967Utils {
              // We re-declare ERC-1967 events here because they can't be used directly from IERC1967.
              // This will be fixed in Solidity 0.8.21. At that point we should remove these events.
              /**
               * @dev Emitted when the implementation is upgraded.
               */
              event Upgraded(address indexed implementation);
              /**
               * @dev Emitted when the admin account has changed.
               */
              event AdminChanged(address previousAdmin, address newAdmin);
              /**
               * @dev Emitted when the beacon is changed.
               */
              event BeaconUpgraded(address indexed beacon);
              /**
               * @dev Storage slot with the address of the current implementation.
               * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1.
               */
              // solhint-disable-next-line private-vars-leading-underscore
              bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
              /**
               * @dev The `implementation` of the proxy is invalid.
               */
              error ERC1967InvalidImplementation(address implementation);
              /**
               * @dev The `admin` of the proxy is invalid.
               */
              error ERC1967InvalidAdmin(address admin);
              /**
               * @dev The `beacon` of the proxy is invalid.
               */
              error ERC1967InvalidBeacon(address beacon);
              /**
               * @dev An upgrade function sees `msg.value > 0` that may be lost.
               */
              error ERC1967NonPayable();
              /**
               * @dev Returns the current implementation address.
               */
              function getImplementation() internal view returns (address) {
                  return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;
              }
              /**
               * @dev Stores a new address in the EIP1967 implementation slot.
               */
              function _setImplementation(address newImplementation) private {
                  if (newImplementation.code.length == 0) {
                      revert ERC1967InvalidImplementation(newImplementation);
                  }
                  StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;
              }
              /**
               * @dev Performs implementation upgrade with additional setup call if data is nonempty.
               * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
               * to avoid stuck value in the contract.
               *
               * Emits an {IERC1967-Upgraded} event.
               */
              function upgradeToAndCall(address newImplementation, bytes memory data) internal {
                  _setImplementation(newImplementation);
                  emit Upgraded(newImplementation);
                  if (data.length > 0) {
                      Address.functionDelegateCall(newImplementation, data);
                  } else {
                      _checkNonPayable();
                  }
              }
              /**
               * @dev Storage slot with the admin of the contract.
               * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1.
               */
              // solhint-disable-next-line private-vars-leading-underscore
              bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
              /**
               * @dev Returns the current admin.
               *
               * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using
               * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
               * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
               */
              function getAdmin() internal view returns (address) {
                  return StorageSlot.getAddressSlot(ADMIN_SLOT).value;
              }
              /**
               * @dev Stores a new address in the EIP1967 admin slot.
               */
              function _setAdmin(address newAdmin) private {
                  if (newAdmin == address(0)) {
                      revert ERC1967InvalidAdmin(address(0));
                  }
                  StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;
              }
              /**
               * @dev Changes the admin of the proxy.
               *
               * Emits an {IERC1967-AdminChanged} event.
               */
              function changeAdmin(address newAdmin) internal {
                  emit AdminChanged(getAdmin(), newAdmin);
                  _setAdmin(newAdmin);
              }
              /**
               * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
               * This is the keccak-256 hash of "eip1967.proxy.beacon" subtracted by 1.
               */
              // solhint-disable-next-line private-vars-leading-underscore
              bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
              /**
               * @dev Returns the current beacon.
               */
              function getBeacon() internal view returns (address) {
                  return StorageSlot.getAddressSlot(BEACON_SLOT).value;
              }
              /**
               * @dev Stores a new beacon in the EIP1967 beacon slot.
               */
              function _setBeacon(address newBeacon) private {
                  if (newBeacon.code.length == 0) {
                      revert ERC1967InvalidBeacon(newBeacon);
                  }
                  StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;
                  address beaconImplementation = IBeacon(newBeacon).implementation();
                  if (beaconImplementation.code.length == 0) {
                      revert ERC1967InvalidImplementation(beaconImplementation);
                  }
              }
              /**
               * @dev Change the beacon and trigger a setup call if data is nonempty.
               * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
               * to avoid stuck value in the contract.
               *
               * Emits an {IERC1967-BeaconUpgraded} event.
               *
               * CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since
               * it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for
               * efficiency.
               */
              function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {
                  _setBeacon(newBeacon);
                  emit BeaconUpgraded(newBeacon);
                  if (data.length > 0) {
                      Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
                  } else {
                      _checkNonPayable();
                  }
              }
              /**
               * @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract
               * if an upgrade doesn't perform an initialization call.
               */
              function _checkNonPayable() private {
                  if (msg.value > 0) {
                      revert ERC1967NonPayable();
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev This is the interface that {BeaconProxy} expects of its beacon.
           */
          interface IBeacon {
              /**
               * @dev Must return an address that can be used as a delegate call target.
               *
               * {UpgradeableBeacon} will check that this address is a contract.
               */
              function implementation() external view returns (address);
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev Collection of functions related to the address type
           */
          library Address {
              /**
               * @dev The ETH balance of the account is not enough to perform the operation.
               */
              error AddressInsufficientBalance(address account);
              /**
               * @dev There's no code at `target` (it is not a contract).
               */
              error AddressEmptyCode(address target);
              /**
               * @dev A call to an address target failed. The target may have reverted.
               */
              error FailedInnerCall();
              /**
               * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
               * `recipient`, forwarding all available gas and reverting on errors.
               *
               * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
               * of certain opcodes, possibly making contracts go over the 2300 gas limit
               * imposed by `transfer`, making them unable to receive funds via
               * `transfer`. {sendValue} removes this limitation.
               *
               * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
               *
               * IMPORTANT: because control is transferred to `recipient`, care must be
               * taken to not create reentrancy vulnerabilities. Consider using
               * {ReentrancyGuard} or the
               * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
               */
              function sendValue(address payable recipient, uint256 amount) internal {
                  if (address(this).balance < amount) {
                      revert AddressInsufficientBalance(address(this));
                  }
                  (bool success, ) = recipient.call{value: amount}("");
                  if (!success) {
                      revert FailedInnerCall();
                  }
              }
              /**
               * @dev Performs a Solidity function call using a low level `call`. A
               * plain `call` is an unsafe replacement for a function call: use this
               * function instead.
               *
               * If `target` reverts with a revert reason or custom error, it is bubbled
               * up by this function (like regular Solidity function calls). However, if
               * the call reverted with no returned reason, this function reverts with a
               * {FailedInnerCall} error.
               *
               * Returns the raw returned data. To convert to the expected return value,
               * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
               *
               * Requirements:
               *
               * - `target` must be a contract.
               * - calling `target` with `data` must not revert.
               */
              function functionCall(address target, bytes memory data) internal returns (bytes memory) {
                  return functionCallWithValue(target, data, 0);
              }
              /**
               * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
               * but also transferring `value` wei to `target`.
               *
               * Requirements:
               *
               * - the calling contract must have an ETH balance of at least `value`.
               * - the called Solidity function must be `payable`.
               */
              function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
                  if (address(this).balance < value) {
                      revert AddressInsufficientBalance(address(this));
                  }
                  (bool success, bytes memory returndata) = target.call{value: value}(data);
                  return verifyCallResultFromTarget(target, success, returndata);
              }
              /**
               * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
               * but performing a static call.
               */
              function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
                  (bool success, bytes memory returndata) = target.staticcall(data);
                  return verifyCallResultFromTarget(target, success, returndata);
              }
              /**
               * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
               * but performing a delegate call.
               */
              function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
                  (bool success, bytes memory returndata) = target.delegatecall(data);
                  return verifyCallResultFromTarget(target, success, returndata);
              }
              /**
               * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
               * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
               * unsuccessful call.
               */
              function verifyCallResultFromTarget(
                  address target,
                  bool success,
                  bytes memory returndata
              ) internal view returns (bytes memory) {
                  if (!success) {
                      _revert(returndata);
                  } else {
                      // only check if target is a contract if the call was successful and the return data is empty
                      // otherwise we already know that it was a contract
                      if (returndata.length == 0 && target.code.length == 0) {
                          revert AddressEmptyCode(target);
                      }
                      return returndata;
                  }
              }
              /**
               * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
               * revert reason or with a default {FailedInnerCall} error.
               */
              function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
                  if (!success) {
                      _revert(returndata);
                  } else {
                      return returndata;
                  }
              }
              /**
               * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
               */
              function _revert(bytes memory returndata) private pure {
                  // Look for revert reason and bubble it up if present
                  if (returndata.length > 0) {
                      // The easiest way to bubble the revert reason is using memory via assembly
                      /// @solidity memory-safe-assembly
                      assembly {
                          let returndata_size := mload(returndata)
                          revert(add(32, returndata), returndata_size)
                      }
                  } else {
                      revert FailedInnerCall();
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol)
          // This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
          pragma solidity ^0.8.20;
          /**
           * @dev Library for reading and writing primitive types to specific storage slots.
           *
           * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
           * This library helps with reading and writing to such slots without the need for inline assembly.
           *
           * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
           *
           * Example usage to set ERC1967 implementation slot:
           * ```solidity
           * contract ERC1967 {
           *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
           *
           *     function _getImplementation() internal view returns (address) {
           *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
           *     }
           *
           *     function _setImplementation(address newImplementation) internal {
           *         require(newImplementation.code.length > 0);
           *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
           *     }
           * }
           * ```
           */
          library StorageSlot {
              struct AddressSlot {
                  address value;
              }
              struct BooleanSlot {
                  bool value;
              }
              struct Bytes32Slot {
                  bytes32 value;
              }
              struct Uint256Slot {
                  uint256 value;
              }
              struct StringSlot {
                  string value;
              }
              struct BytesSlot {
                  bytes value;
              }
              /**
               * @dev Returns an `AddressSlot` with member `value` located at `slot`.
               */
              function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
               */
              function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
               */
              function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
               */
              function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `StringSlot` with member `value` located at `slot`.
               */
              function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `StringSlot` representation of the string storage pointer `store`.
               */
              function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := store.slot
                  }
              }
              /**
               * @dev Returns an `BytesSlot` with member `value` located at `slot`.
               */
              function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
               */
              function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := store.slot
                  }
              }
          }
          

          File 3 of 6: ERC1967Proxy
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Proxy.sol)
          pragma solidity ^0.8.20;
          import {Proxy} from "../Proxy.sol";
          import {ERC1967Utils} from "./ERC1967Utils.sol";
          /**
           * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
           * implementation address that can be changed. This address is stored in storage in the location specified by
           * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the
           * implementation behind the proxy.
           */
          contract ERC1967Proxy is Proxy {
              /**
               * @dev Initializes the upgradeable proxy with an initial implementation specified by `implementation`.
               *
               * If `_data` is nonempty, it's used as data in a delegate call to `implementation`. This will typically be an
               * encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.
               *
               * Requirements:
               *
               * - If `data` is empty, `msg.value` must be zero.
               */
              constructor(address implementation, bytes memory _data) payable {
                  ERC1967Utils.upgradeToAndCall(implementation, _data);
              }
              /**
               * @dev Returns the current implementation address.
               *
               * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using
               * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
               * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`
               */
              function _implementation() internal view virtual override returns (address) {
                  return ERC1967Utils.getImplementation();
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/Proxy.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
           * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
           * be specified by overriding the virtual {_implementation} function.
           *
           * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
           * different contract through the {_delegate} function.
           *
           * The success and return data of the delegated call will be returned back to the caller of the proxy.
           */
          abstract contract Proxy {
              /**
               * @dev Delegates the current call to `implementation`.
               *
               * This function does not return to its internal call site, it will return directly to the external caller.
               */
              function _delegate(address implementation) internal virtual {
                  assembly {
                      // Copy msg.data. We take full control of memory in this inline assembly
                      // block because it will not return to Solidity code. We overwrite the
                      // Solidity scratch pad at memory position 0.
                      calldatacopy(0, 0, calldatasize())
                      // Call the implementation.
                      // out and outsize are 0 because we don't know the size yet.
                      let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
                      // Copy the returned data.
                      returndatacopy(0, 0, returndatasize())
                      switch result
                      // delegatecall returns 0 on error.
                      case 0 {
                          revert(0, returndatasize())
                      }
                      default {
                          return(0, returndatasize())
                      }
                  }
              }
              /**
               * @dev This is a virtual function that should be overridden so it returns the address to which the fallback
               * function and {_fallback} should delegate.
               */
              function _implementation() internal view virtual returns (address);
              /**
               * @dev Delegates the current call to the address returned by `_implementation()`.
               *
               * This function does not return to its internal call site, it will return directly to the external caller.
               */
              function _fallback() internal virtual {
                  _delegate(_implementation());
              }
              /**
               * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
               * function in the contract matches the call data.
               */
              fallback() external payable virtual {
                  _fallback();
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Utils.sol)
          pragma solidity ^0.8.20;
          import {IBeacon} from "../beacon/IBeacon.sol";
          import {Address} from "../../utils/Address.sol";
          import {StorageSlot} from "../../utils/StorageSlot.sol";
          /**
           * @dev This abstract contract provides getters and event emitting update functions for
           * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
           */
          library ERC1967Utils {
              // We re-declare ERC-1967 events here because they can't be used directly from IERC1967.
              // This will be fixed in Solidity 0.8.21. At that point we should remove these events.
              /**
               * @dev Emitted when the implementation is upgraded.
               */
              event Upgraded(address indexed implementation);
              /**
               * @dev Emitted when the admin account has changed.
               */
              event AdminChanged(address previousAdmin, address newAdmin);
              /**
               * @dev Emitted when the beacon is changed.
               */
              event BeaconUpgraded(address indexed beacon);
              /**
               * @dev Storage slot with the address of the current implementation.
               * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1.
               */
              // solhint-disable-next-line private-vars-leading-underscore
              bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
              /**
               * @dev The `implementation` of the proxy is invalid.
               */
              error ERC1967InvalidImplementation(address implementation);
              /**
               * @dev The `admin` of the proxy is invalid.
               */
              error ERC1967InvalidAdmin(address admin);
              /**
               * @dev The `beacon` of the proxy is invalid.
               */
              error ERC1967InvalidBeacon(address beacon);
              /**
               * @dev An upgrade function sees `msg.value > 0` that may be lost.
               */
              error ERC1967NonPayable();
              /**
               * @dev Returns the current implementation address.
               */
              function getImplementation() internal view returns (address) {
                  return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;
              }
              /**
               * @dev Stores a new address in the EIP1967 implementation slot.
               */
              function _setImplementation(address newImplementation) private {
                  if (newImplementation.code.length == 0) {
                      revert ERC1967InvalidImplementation(newImplementation);
                  }
                  StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;
              }
              /**
               * @dev Performs implementation upgrade with additional setup call if data is nonempty.
               * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
               * to avoid stuck value in the contract.
               *
               * Emits an {IERC1967-Upgraded} event.
               */
              function upgradeToAndCall(address newImplementation, bytes memory data) internal {
                  _setImplementation(newImplementation);
                  emit Upgraded(newImplementation);
                  if (data.length > 0) {
                      Address.functionDelegateCall(newImplementation, data);
                  } else {
                      _checkNonPayable();
                  }
              }
              /**
               * @dev Storage slot with the admin of the contract.
               * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1.
               */
              // solhint-disable-next-line private-vars-leading-underscore
              bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
              /**
               * @dev Returns the current admin.
               *
               * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using
               * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
               * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
               */
              function getAdmin() internal view returns (address) {
                  return StorageSlot.getAddressSlot(ADMIN_SLOT).value;
              }
              /**
               * @dev Stores a new address in the EIP1967 admin slot.
               */
              function _setAdmin(address newAdmin) private {
                  if (newAdmin == address(0)) {
                      revert ERC1967InvalidAdmin(address(0));
                  }
                  StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;
              }
              /**
               * @dev Changes the admin of the proxy.
               *
               * Emits an {IERC1967-AdminChanged} event.
               */
              function changeAdmin(address newAdmin) internal {
                  emit AdminChanged(getAdmin(), newAdmin);
                  _setAdmin(newAdmin);
              }
              /**
               * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
               * This is the keccak-256 hash of "eip1967.proxy.beacon" subtracted by 1.
               */
              // solhint-disable-next-line private-vars-leading-underscore
              bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
              /**
               * @dev Returns the current beacon.
               */
              function getBeacon() internal view returns (address) {
                  return StorageSlot.getAddressSlot(BEACON_SLOT).value;
              }
              /**
               * @dev Stores a new beacon in the EIP1967 beacon slot.
               */
              function _setBeacon(address newBeacon) private {
                  if (newBeacon.code.length == 0) {
                      revert ERC1967InvalidBeacon(newBeacon);
                  }
                  StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;
                  address beaconImplementation = IBeacon(newBeacon).implementation();
                  if (beaconImplementation.code.length == 0) {
                      revert ERC1967InvalidImplementation(beaconImplementation);
                  }
              }
              /**
               * @dev Change the beacon and trigger a setup call if data is nonempty.
               * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
               * to avoid stuck value in the contract.
               *
               * Emits an {IERC1967-BeaconUpgraded} event.
               *
               * CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since
               * it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for
               * efficiency.
               */
              function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {
                  _setBeacon(newBeacon);
                  emit BeaconUpgraded(newBeacon);
                  if (data.length > 0) {
                      Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
                  } else {
                      _checkNonPayable();
                  }
              }
              /**
               * @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract
               * if an upgrade doesn't perform an initialization call.
               */
              function _checkNonPayable() private {
                  if (msg.value > 0) {
                      revert ERC1967NonPayable();
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev This is the interface that {BeaconProxy} expects of its beacon.
           */
          interface IBeacon {
              /**
               * @dev Must return an address that can be used as a delegate call target.
               *
               * {UpgradeableBeacon} will check that this address is a contract.
               */
              function implementation() external view returns (address);
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev Collection of functions related to the address type
           */
          library Address {
              /**
               * @dev The ETH balance of the account is not enough to perform the operation.
               */
              error AddressInsufficientBalance(address account);
              /**
               * @dev There's no code at `target` (it is not a contract).
               */
              error AddressEmptyCode(address target);
              /**
               * @dev A call to an address target failed. The target may have reverted.
               */
              error FailedInnerCall();
              /**
               * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
               * `recipient`, forwarding all available gas and reverting on errors.
               *
               * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
               * of certain opcodes, possibly making contracts go over the 2300 gas limit
               * imposed by `transfer`, making them unable to receive funds via
               * `transfer`. {sendValue} removes this limitation.
               *
               * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
               *
               * IMPORTANT: because control is transferred to `recipient`, care must be
               * taken to not create reentrancy vulnerabilities. Consider using
               * {ReentrancyGuard} or the
               * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
               */
              function sendValue(address payable recipient, uint256 amount) internal {
                  if (address(this).balance < amount) {
                      revert AddressInsufficientBalance(address(this));
                  }
                  (bool success, ) = recipient.call{value: amount}("");
                  if (!success) {
                      revert FailedInnerCall();
                  }
              }
              /**
               * @dev Performs a Solidity function call using a low level `call`. A
               * plain `call` is an unsafe replacement for a function call: use this
               * function instead.
               *
               * If `target` reverts with a revert reason or custom error, it is bubbled
               * up by this function (like regular Solidity function calls). However, if
               * the call reverted with no returned reason, this function reverts with a
               * {FailedInnerCall} error.
               *
               * Returns the raw returned data. To convert to the expected return value,
               * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
               *
               * Requirements:
               *
               * - `target` must be a contract.
               * - calling `target` with `data` must not revert.
               */
              function functionCall(address target, bytes memory data) internal returns (bytes memory) {
                  return functionCallWithValue(target, data, 0);
              }
              /**
               * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
               * but also transferring `value` wei to `target`.
               *
               * Requirements:
               *
               * - the calling contract must have an ETH balance of at least `value`.
               * - the called Solidity function must be `payable`.
               */
              function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
                  if (address(this).balance < value) {
                      revert AddressInsufficientBalance(address(this));
                  }
                  (bool success, bytes memory returndata) = target.call{value: value}(data);
                  return verifyCallResultFromTarget(target, success, returndata);
              }
              /**
               * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
               * but performing a static call.
               */
              function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
                  (bool success, bytes memory returndata) = target.staticcall(data);
                  return verifyCallResultFromTarget(target, success, returndata);
              }
              /**
               * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
               * but performing a delegate call.
               */
              function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
                  (bool success, bytes memory returndata) = target.delegatecall(data);
                  return verifyCallResultFromTarget(target, success, returndata);
              }
              /**
               * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
               * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
               * unsuccessful call.
               */
              function verifyCallResultFromTarget(
                  address target,
                  bool success,
                  bytes memory returndata
              ) internal view returns (bytes memory) {
                  if (!success) {
                      _revert(returndata);
                  } else {
                      // only check if target is a contract if the call was successful and the return data is empty
                      // otherwise we already know that it was a contract
                      if (returndata.length == 0 && target.code.length == 0) {
                          revert AddressEmptyCode(target);
                      }
                      return returndata;
                  }
              }
              /**
               * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
               * revert reason or with a default {FailedInnerCall} error.
               */
              function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
                  if (!success) {
                      _revert(returndata);
                  } else {
                      return returndata;
                  }
              }
              /**
               * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
               */
              function _revert(bytes memory returndata) private pure {
                  // Look for revert reason and bubble it up if present
                  if (returndata.length > 0) {
                      // The easiest way to bubble the revert reason is using memory via assembly
                      /// @solidity memory-safe-assembly
                      assembly {
                          let returndata_size := mload(returndata)
                          revert(add(32, returndata), returndata_size)
                      }
                  } else {
                      revert FailedInnerCall();
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol)
          // This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
          pragma solidity ^0.8.20;
          /**
           * @dev Library for reading and writing primitive types to specific storage slots.
           *
           * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
           * This library helps with reading and writing to such slots without the need for inline assembly.
           *
           * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
           *
           * Example usage to set ERC1967 implementation slot:
           * ```solidity
           * contract ERC1967 {
           *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
           *
           *     function _getImplementation() internal view returns (address) {
           *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
           *     }
           *
           *     function _setImplementation(address newImplementation) internal {
           *         require(newImplementation.code.length > 0);
           *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
           *     }
           * }
           * ```
           */
          library StorageSlot {
              struct AddressSlot {
                  address value;
              }
              struct BooleanSlot {
                  bool value;
              }
              struct Bytes32Slot {
                  bytes32 value;
              }
              struct Uint256Slot {
                  uint256 value;
              }
              struct StringSlot {
                  string value;
              }
              struct BytesSlot {
                  bytes value;
              }
              /**
               * @dev Returns an `AddressSlot` with member `value` located at `slot`.
               */
              function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
               */
              function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
               */
              function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
               */
              function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `StringSlot` with member `value` located at `slot`.
               */
              function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `StringSlot` representation of the string storage pointer `store`.
               */
              function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := store.slot
                  }
              }
              /**
               * @dev Returns an `BytesSlot` with member `value` located at `slot`.
               */
              function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
               */
              function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := store.slot
                  }
              }
          }
          

          File 4 of 6: EtherBridge
          // SPDX-License_Identifier: UNLICENSED
          pragma solidity 0.8.21;
          import "openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol";
          import "openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol";
          import "openzeppelin-contracts-upgradeable/contracts/access/AccessControlUpgradeable.sol";
          import "openzeppelin-contracts-upgradeable/contracts/utils/ReentrancyGuardUpgradeable.sol";
          import "openzeppelin-contracts-upgradeable/contracts/utils/PausableUpgradeable.sol";
          import "./interfaces/IEtherBridge.sol";
          import "./interfaces/ITreasury.sol";
          import "./interfaces/IMailbox.sol";
          import "./interfaces/ISemVer.sol";
          import "./CommonContainer.sol";
          /// @title EtherBridge
          /// @dev A bridge contract for depositing and withdrawing ether to and from the Eclipse rollup.
          contract EtherBridge is
              IEtherBridge,
              ISemVer,
              CommonContainer,
              Initializable,
              AccessControlUpgradeable,
              PausableUpgradeable,
              ReentrancyGuardUpgradeable,
              UUPSUpgradeable
          {
              bytes32 public constant ETHER_BRIDGE_ID = keccak256("EtherBridge");
              uint256 public constant MIN_DEPOSIT = MIN_DEPOSIT_LAMPORTS * WEI_PER_LAMPORT;
              uint256 private constant MIN_DEPOSIT_LAMPORTS = 2_000_000;
              uint256 private constant WEI_PER_LAMPORT = 1_000_000_000;
              uint8 private constant MAJOR_VERSION = 1;
              uint8 private constant MINOR_VERSION = 0;
              uint8 private constant PATCH_VERSION = 0;
              /// @custom:storage-location erc7201:eclipse.ether_bridge.v1
              struct StorageV1 {
                  bytes etherBridgeId;
                  IMailbox mailboxProxy;
                  ITreasury treasuryProxy;
              }
              // keccak256(abi.encode(uint256(keccak256("eclipse.ether_bridge.v1")) - 1)) & ~bytes32(uint256(0xff))
              bytes32 private constant STORAGE_V1_LOCATION = 0x47de546cf6a4c0310e912c3941a75f4e016a86b1301d78e45822946d7c351e00;
              function _getStorageV1() internal pure returns (StorageV1 storage $) {
                  assembly {
                      $.slot := STORAGE_V1_LOCATION
                  }
              }
              /// @dev Ensures the deposit amount and msg.value valid & equal and they are greater then eq to min deposit amount
              /// @param amountWei The amount to be deposited.
              modifier validDepositAmount(uint256 amountWei) {
                  require(msg.value == amountWei, "Deposit amount and msg.value must be equal");
                  require(msg.value % WEI_PER_LAMPORT == 0, "Deposit msg.value must not have a fractional gwei value");
                  require(msg.value >= MIN_DEPOSIT, "Deposit amount must be greater than equal to the minimum wei amount");
                  _;
              }
              /// @dev Restricts the function call to only admins.
              modifier onlyAuthority() {
                  require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Only an admin can call this method.");
                  _;
              }
              /// @dev Constructor that disables initializers
              /// @custom:oz-upgrades-unsafe-allow constructor
              constructor() {
                  _disableInitializers();
              }
              /// @dev Initializes the contract variables and deploys the treasury.
              /// @param mailboxAddress_ Address of the mailbox contract.
              /// @param treasuryAddress_ Address of the treasury contract.
              function initialize(address owner_, address mailboxAddress_, address treasuryAddress_)
                  public
                  addressInitialized(owner_)
                  addressInitialized(mailboxAddress_)
                  addressInitialized(treasuryAddress_)
                  initializer
              {
                  __AccessControl_init();
                  __Pausable_init();
                  __ReentrancyGuard_init();
                  __UUPSUpgradeable_init();
                  _grantRole(DEFAULT_ADMIN_ROLE, owner_);
                  StorageV1 storage $ = _getStorageV1();
                  $.mailboxProxy = IMailbox(mailboxAddress_);
                  $.treasuryProxy = ITreasury(treasuryAddress_);
                  $.etherBridgeId = abi.encode(ETHER_BRIDGE_ID);
              }
              /// @dev Retrieves the constant version details of the smart contract.
              function getVersionComponents() public pure override returns (Version memory) {
                  return Version(MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION);
              }
              /// @notice Deposit amount and a fee after deductions into treasury
              function deposit(bytes32 recipient, uint256 amountWei)
                  external
                  payable
                  virtual
                  override
                  whenNotPaused
                  bytes32Initialized(recipient)
                  validDepositAmount(amountWei)
                  nonReentrant
              {
                  StorageV1 storage $ = _getStorageV1();
                  // Create deposit message with amount in gwei
                  uint256 amountGwei = amountWei / WEI_PER_LAMPORT;
                  IEtherBridge.DepositMessage memory message =
                      IEtherBridge.DepositMessage({sender: msg.sender, recipient: recipient, amountGwei: amountGwei});
                  // Encode message and forward to mailbox
                  bytes memory encodedMessage = abi.encode(message);
                  bool success = $.mailboxProxy.sendMessage("", $.etherBridgeId, encodedMessage, "");
                  require(success, "Unable to forward deposit message to Mailbox");
                  // Lock funds in the treasury
                  (success,) = payable(address($.treasuryProxy)).call{value: amountWei}("");
                  require(success, "Transfer failed");
                  emit Deposited(msg.sender, recipient, amountWei);
              }
              /// @dev Pause deposits
              function pause() external virtual onlyAuthority {
                  _pause();
              }
              /// @dev Unpause deposits
              function unpause() external virtual onlyAuthority {
                  _unpause();
              }
              /// @dev required by the OZ UUPS module
              function _authorizeUpgrade(address) internal virtual override onlyAuthority {}
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
           * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
           * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
           * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
           *
           * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
           * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
           * case an upgrade adds a module that needs to be initialized.
           *
           * For example:
           *
           * [.hljs-theme-light.nopadding]
           * ```solidity
           * contract MyToken is ERC20Upgradeable {
           *     function initialize() initializer public {
           *         __ERC20_init("MyToken", "MTK");
           *     }
           * }
           *
           * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
           *     function initializeV2() reinitializer(2) public {
           *         __ERC20Permit_init("MyToken");
           *     }
           * }
           * ```
           *
           * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
           * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
           *
           * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
           * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
           *
           * [CAUTION]
           * ====
           * Avoid leaving a contract uninitialized.
           *
           * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
           * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
           * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
           *
           * [.hljs-theme-light.nopadding]
           * ```
           * /// @custom:oz-upgrades-unsafe-allow constructor
           * constructor() {
           *     _disableInitializers();
           * }
           * ```
           * ====
           */
          abstract contract Initializable {
              /**
               * @dev Storage of the initializable contract.
               *
               * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
               * when using with upgradeable contracts.
               *
               * @custom:storage-location erc7201:openzeppelin.storage.Initializable
               */
              struct InitializableStorage {
                  /**
                   * @dev Indicates that the contract has been initialized.
                   */
                  uint64 _initialized;
                  /**
                   * @dev Indicates that the contract is in the process of being initialized.
                   */
                  bool _initializing;
              }
              // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
              bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
              /**
               * @dev The contract is already initialized.
               */
              error InvalidInitialization();
              /**
               * @dev The contract is not initializing.
               */
              error NotInitializing();
              /**
               * @dev Triggered when the contract has been initialized or reinitialized.
               */
              event Initialized(uint64 version);
              /**
               * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
               * `onlyInitializing` functions can be used to initialize parent contracts.
               *
               * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
               * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
               * production.
               *
               * Emits an {Initialized} event.
               */
              modifier initializer() {
                  // solhint-disable-next-line var-name-mixedcase
                  InitializableStorage storage $ = _getInitializableStorage();
                  // Cache values to avoid duplicated sloads
                  bool isTopLevelCall = !$._initializing;
                  uint64 initialized = $._initialized;
                  // Allowed calls:
                  // - initialSetup: the contract is not in the initializing state and no previous version was
                  //                 initialized
                  // - construction: the contract is initialized at version 1 (no reininitialization) and the
                  //                 current contract is just being deployed
                  bool initialSetup = initialized == 0 && isTopLevelCall;
                  bool construction = initialized == 1 && address(this).code.length == 0;
                  if (!initialSetup && !construction) {
                      revert InvalidInitialization();
                  }
                  $._initialized = 1;
                  if (isTopLevelCall) {
                      $._initializing = true;
                  }
                  _;
                  if (isTopLevelCall) {
                      $._initializing = false;
                      emit Initialized(1);
                  }
              }
              /**
               * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
               * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
               * used to initialize parent contracts.
               *
               * A reinitializer may be used after the original initialization step. This is essential to configure modules that
               * are added through upgrades and that require initialization.
               *
               * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
               * cannot be nested. If one is invoked in the context of another, execution will revert.
               *
               * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
               * a contract, executing them in the right order is up to the developer or operator.
               *
               * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
               *
               * Emits an {Initialized} event.
               */
              modifier reinitializer(uint64 version) {
                  // solhint-disable-next-line var-name-mixedcase
                  InitializableStorage storage $ = _getInitializableStorage();
                  if ($._initializing || $._initialized >= version) {
                      revert InvalidInitialization();
                  }
                  $._initialized = version;
                  $._initializing = true;
                  _;
                  $._initializing = false;
                  emit Initialized(version);
              }
              /**
               * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
               * {initializer} and {reinitializer} modifiers, directly or indirectly.
               */
              modifier onlyInitializing() {
                  _checkInitializing();
                  _;
              }
              /**
               * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
               */
              function _checkInitializing() internal view virtual {
                  if (!_isInitializing()) {
                      revert NotInitializing();
                  }
              }
              /**
               * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
               * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
               * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
               * through proxies.
               *
               * Emits an {Initialized} event the first time it is successfully executed.
               */
              function _disableInitializers() internal virtual {
                  // solhint-disable-next-line var-name-mixedcase
                  InitializableStorage storage $ = _getInitializableStorage();
                  if ($._initializing) {
                      revert InvalidInitialization();
                  }
                  if ($._initialized != type(uint64).max) {
                      $._initialized = type(uint64).max;
                      emit Initialized(type(uint64).max);
                  }
              }
              /**
               * @dev Returns the highest version that has been initialized. See {reinitializer}.
               */
              function _getInitializedVersion() internal view returns (uint64) {
                  return _getInitializableStorage()._initialized;
              }
              /**
               * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
               */
              function _isInitializing() internal view returns (bool) {
                  return _getInitializableStorage()._initializing;
              }
              /**
               * @dev Returns a pointer to the storage namespace.
               */
              // solhint-disable-next-line var-name-mixedcase
              function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
                  assembly {
                      $.slot := INITIALIZABLE_STORAGE
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/UUPSUpgradeable.sol)
          pragma solidity ^0.8.20;
          import {IERC1822Proxiable} from "@openzeppelin/contracts/interfaces/draft-IERC1822.sol";
          import {ERC1967Utils} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";
          import {Initializable} from "./Initializable.sol";
          /**
           * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
           * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
           *
           * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
           * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
           * `UUPSUpgradeable` with a custom implementation of upgrades.
           *
           * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
           */
          abstract contract UUPSUpgradeable is Initializable, IERC1822Proxiable {
              /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
              address private immutable __self = address(this);
              /**
               * @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgradeTo(address)`
               * and `upgradeToAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called,
               * while `upgradeToAndCall` will invoke the `receive` function if the second argument is the empty byte string.
               * If the getter returns `"5.0.0"`, only `upgradeToAndCall(address,bytes)` is present, and the second argument must
               * be the empty byte string if no function should be called, making it impossible to invoke the `receive` function
               * during an upgrade.
               */
              string public constant UPGRADE_INTERFACE_VERSION = "5.0.0";
              /**
               * @dev The call is from an unauthorized context.
               */
              error UUPSUnauthorizedCallContext();
              /**
               * @dev The storage `slot` is unsupported as a UUID.
               */
              error UUPSUnsupportedProxiableUUID(bytes32 slot);
              /**
               * @dev Check that the execution is being performed through a delegatecall call and that the execution context is
               * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
               * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
               * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
               * fail.
               */
              modifier onlyProxy() {
                  _checkProxy();
                  _;
              }
              /**
               * @dev Check that the execution is not being performed through a delegate call. This allows a function to be
               * callable on the implementing contract but not through proxies.
               */
              modifier notDelegated() {
                  _checkNotDelegated();
                  _;
              }
              function __UUPSUpgradeable_init() internal onlyInitializing {
              }
              function __UUPSUpgradeable_init_unchained() internal onlyInitializing {
              }
              /**
               * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
               * implementation. It is used to validate the implementation's compatibility when performing an upgrade.
               *
               * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
               * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
               * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
               */
              function proxiableUUID() external view virtual notDelegated returns (bytes32) {
                  return ERC1967Utils.IMPLEMENTATION_SLOT;
              }
              /**
               * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
               * encoded in `data`.
               *
               * Calls {_authorizeUpgrade}.
               *
               * Emits an {Upgraded} event.
               *
               * @custom:oz-upgrades-unsafe-allow-reachable delegatecall
               */
              function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {
                  _authorizeUpgrade(newImplementation);
                  _upgradeToAndCallUUPS(newImplementation, data);
              }
              /**
               * @dev Reverts if the execution is not performed via delegatecall or the execution
               * context is not of a proxy with an ERC1967-compliant implementation pointing to self.
               * See {_onlyProxy}.
               */
              function _checkProxy() internal view virtual {
                  if (
                      address(this) == __self || // Must be called through delegatecall
                      ERC1967Utils.getImplementation() != __self // Must be called through an active proxy
                  ) {
                      revert UUPSUnauthorizedCallContext();
                  }
              }
              /**
               * @dev Reverts if the execution is performed via delegatecall.
               * See {notDelegated}.
               */
              function _checkNotDelegated() internal view virtual {
                  if (address(this) != __self) {
                      // Must not be called through delegatecall
                      revert UUPSUnauthorizedCallContext();
                  }
              }
              /**
               * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
               * {upgradeToAndCall}.
               *
               * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
               *
               * ```solidity
               * function _authorizeUpgrade(address) internal onlyOwner {}
               * ```
               */
              function _authorizeUpgrade(address newImplementation) internal virtual;
              /**
               * @dev Performs an implementation upgrade with a security check for UUPS proxies, and additional setup call.
               *
               * As a security check, {proxiableUUID} is invoked in the new implementation, and the return value
               * is expected to be the implementation slot in ERC1967.
               *
               * Emits an {IERC1967-Upgraded} event.
               */
              function _upgradeToAndCallUUPS(address newImplementation, bytes memory data) private {
                  try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {
                      if (slot != ERC1967Utils.IMPLEMENTATION_SLOT) {
                          revert UUPSUnsupportedProxiableUUID(slot);
                      }
                      ERC1967Utils.upgradeToAndCall(newImplementation, data);
                  } catch {
                      // The implementation is not UUPS
                      revert ERC1967Utils.ERC1967InvalidImplementation(newImplementation);
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)
          pragma solidity ^0.8.20;
          import {IAccessControl} from "@openzeppelin/contracts/access/IAccessControl.sol";
          import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
          import {ERC165Upgradeable} from "../utils/introspection/ERC165Upgradeable.sol";
          import {Initializable} from "../proxy/utils/Initializable.sol";
          /**
           * @dev Contract module that allows children to implement role-based access
           * control mechanisms. This is a lightweight version that doesn't allow enumerating role
           * members except through off-chain means by accessing the contract event logs. Some
           * applications may benefit from on-chain enumerability, for those cases see
           * {AccessControlEnumerable}.
           *
           * Roles are referred to by their `bytes32` identifier. These should be exposed
           * in the external API and be unique. The best way to achieve this is by
           * using `public constant` hash digests:
           *
           * ```solidity
           * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
           * ```
           *
           * Roles can be used to represent a set of permissions. To restrict access to a
           * function call, use {hasRole}:
           *
           * ```solidity
           * function foo() public {
           *     require(hasRole(MY_ROLE, msg.sender));
           *     ...
           * }
           * ```
           *
           * Roles can be granted and revoked dynamically via the {grantRole} and
           * {revokeRole} functions. Each role has an associated admin role, and only
           * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
           *
           * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
           * that only accounts with this role will be able to grant or revoke other
           * roles. More complex role relationships can be created by using
           * {_setRoleAdmin}.
           *
           * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
           * grant and revoke this role. Extra precautions should be taken to secure
           * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
           * to enforce additional security measures for this role.
           */
          abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControl, ERC165Upgradeable {
              struct RoleData {
                  mapping(address account => bool) hasRole;
                  bytes32 adminRole;
              }
              bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
              /// @custom:storage-location erc7201:openzeppelin.storage.AccessControl
              struct AccessControlStorage {
                  mapping(bytes32 role => RoleData) _roles;
              }
              // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.AccessControl")) - 1)) & ~bytes32(uint256(0xff))
              bytes32 private constant AccessControlStorageLocation = 0x02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800;
              function _getAccessControlStorage() private pure returns (AccessControlStorage storage $) {
                  assembly {
                      $.slot := AccessControlStorageLocation
                  }
              }
              /**
               * @dev Modifier that checks that an account has a specific role. Reverts
               * with an {AccessControlUnauthorizedAccount} error including the required role.
               */
              modifier onlyRole(bytes32 role) {
                  _checkRole(role);
                  _;
              }
              function __AccessControl_init() internal onlyInitializing {
              }
              function __AccessControl_init_unchained() internal onlyInitializing {
              }
              /**
               * @dev See {IERC165-supportsInterface}.
               */
              function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
                  return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
              }
              /**
               * @dev Returns `true` if `account` has been granted `role`.
               */
              function hasRole(bytes32 role, address account) public view virtual returns (bool) {
                  AccessControlStorage storage $ = _getAccessControlStorage();
                  return $._roles[role].hasRole[account];
              }
              /**
               * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
               * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
               */
              function _checkRole(bytes32 role) internal view virtual {
                  _checkRole(role, _msgSender());
              }
              /**
               * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
               * is missing `role`.
               */
              function _checkRole(bytes32 role, address account) internal view virtual {
                  if (!hasRole(role, account)) {
                      revert AccessControlUnauthorizedAccount(account, role);
                  }
              }
              /**
               * @dev Returns the admin role that controls `role`. See {grantRole} and
               * {revokeRole}.
               *
               * To change a role's admin, use {_setRoleAdmin}.
               */
              function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
                  AccessControlStorage storage $ = _getAccessControlStorage();
                  return $._roles[role].adminRole;
              }
              /**
               * @dev Grants `role` to `account`.
               *
               * If `account` had not been already granted `role`, emits a {RoleGranted}
               * event.
               *
               * Requirements:
               *
               * - the caller must have ``role``'s admin role.
               *
               * May emit a {RoleGranted} event.
               */
              function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
                  _grantRole(role, account);
              }
              /**
               * @dev Revokes `role` from `account`.
               *
               * If `account` had been granted `role`, emits a {RoleRevoked} event.
               *
               * Requirements:
               *
               * - the caller must have ``role``'s admin role.
               *
               * May emit a {RoleRevoked} event.
               */
              function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
                  _revokeRole(role, account);
              }
              /**
               * @dev Revokes `role` from the calling account.
               *
               * Roles are often managed via {grantRole} and {revokeRole}: this function's
               * purpose is to provide a mechanism for accounts to lose their privileges
               * if they are compromised (such as when a trusted device is misplaced).
               *
               * If the calling account had been revoked `role`, emits a {RoleRevoked}
               * event.
               *
               * Requirements:
               *
               * - the caller must be `callerConfirmation`.
               *
               * May emit a {RoleRevoked} event.
               */
              function renounceRole(bytes32 role, address callerConfirmation) public virtual {
                  if (callerConfirmation != _msgSender()) {
                      revert AccessControlBadConfirmation();
                  }
                  _revokeRole(role, callerConfirmation);
              }
              /**
               * @dev Sets `adminRole` as ``role``'s admin role.
               *
               * Emits a {RoleAdminChanged} event.
               */
              function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
                  AccessControlStorage storage $ = _getAccessControlStorage();
                  bytes32 previousAdminRole = getRoleAdmin(role);
                  $._roles[role].adminRole = adminRole;
                  emit RoleAdminChanged(role, previousAdminRole, adminRole);
              }
              /**
               * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
               *
               * Internal function without access restriction.
               *
               * May emit a {RoleGranted} event.
               */
              function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
                  AccessControlStorage storage $ = _getAccessControlStorage();
                  if (!hasRole(role, account)) {
                      $._roles[role].hasRole[account] = true;
                      emit RoleGranted(role, account, _msgSender());
                      return true;
                  } else {
                      return false;
                  }
              }
              /**
               * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.
               *
               * Internal function without access restriction.
               *
               * May emit a {RoleRevoked} event.
               */
              function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
                  AccessControlStorage storage $ = _getAccessControlStorage();
                  if (hasRole(role, account)) {
                      $._roles[role].hasRole[account] = false;
                      emit RoleRevoked(role, account, _msgSender());
                      return true;
                  } else {
                      return false;
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)
          pragma solidity ^0.8.20;
          import {Initializable} from "../proxy/utils/Initializable.sol";
          /**
           * @dev Contract module that helps prevent reentrant calls to a function.
           *
           * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
           * available, which can be applied to functions to make sure there are no nested
           * (reentrant) calls to them.
           *
           * Note that because there is a single `nonReentrant` guard, functions marked as
           * `nonReentrant` may not call one another. This can be worked around by making
           * those functions `private`, and then adding `external` `nonReentrant` entry
           * points to them.
           *
           * TIP: If you would like to learn more about reentrancy and alternative ways
           * to protect against it, check out our blog post
           * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
           */
          abstract contract ReentrancyGuardUpgradeable is Initializable {
              // Booleans are more expensive than uint256 or any type that takes up a full
              // word because each write operation emits an extra SLOAD to first read the
              // slot's contents, replace the bits taken up by the boolean, and then write
              // back. This is the compiler's defense against contract upgrades and
              // pointer aliasing, and it cannot be disabled.
              // The values being non-zero value makes deployment a bit more expensive,
              // but in exchange the refund on every call to nonReentrant will be lower in
              // amount. Since refunds are capped to a percentage of the total
              // transaction's gas, it is best to keep them low in cases like this one, to
              // increase the likelihood of the full refund coming into effect.
              uint256 private constant NOT_ENTERED = 1;
              uint256 private constant ENTERED = 2;
              /// @custom:storage-location erc7201:openzeppelin.storage.ReentrancyGuard
              struct ReentrancyGuardStorage {
                  uint256 _status;
              }
              // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ReentrancyGuard")) - 1)) & ~bytes32(uint256(0xff))
              bytes32 private constant ReentrancyGuardStorageLocation = 0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;
              function _getReentrancyGuardStorage() private pure returns (ReentrancyGuardStorage storage $) {
                  assembly {
                      $.slot := ReentrancyGuardStorageLocation
                  }
              }
              /**
               * @dev Unauthorized reentrant call.
               */
              error ReentrancyGuardReentrantCall();
              function __ReentrancyGuard_init() internal onlyInitializing {
                  __ReentrancyGuard_init_unchained();
              }
              function __ReentrancyGuard_init_unchained() internal onlyInitializing {
                  ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
                  $._status = NOT_ENTERED;
              }
              /**
               * @dev Prevents a contract from calling itself, directly or indirectly.
               * Calling a `nonReentrant` function from another `nonReentrant`
               * function is not supported. It is possible to prevent this from happening
               * by making the `nonReentrant` function external, and making it call a
               * `private` function that does the actual work.
               */
              modifier nonReentrant() {
                  _nonReentrantBefore();
                  _;
                  _nonReentrantAfter();
              }
              function _nonReentrantBefore() private {
                  ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
                  // On the first call to nonReentrant, _status will be NOT_ENTERED
                  if ($._status == ENTERED) {
                      revert ReentrancyGuardReentrantCall();
                  }
                  // Any calls to nonReentrant after this point will fail
                  $._status = ENTERED;
              }
              function _nonReentrantAfter() private {
                  ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
                  // By storing the original value once again, a refund is triggered (see
                  // https://eips.ethereum.org/EIPS/eip-2200)
                  $._status = NOT_ENTERED;
              }
              /**
               * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
               * `nonReentrant` function in the call stack.
               */
              function _reentrancyGuardEntered() internal view returns (bool) {
                  ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
                  return $._status == ENTERED;
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol)
          pragma solidity ^0.8.20;
          import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
          import {Initializable} from "../proxy/utils/Initializable.sol";
          /**
           * @dev Contract module which allows children to implement an emergency stop
           * mechanism that can be triggered by an authorized account.
           *
           * This module is used through inheritance. It will make available the
           * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
           * the functions of your contract. Note that they will not be pausable by
           * simply including this module, only once the modifiers are put in place.
           */
          abstract contract PausableUpgradeable is Initializable, ContextUpgradeable {
              /// @custom:storage-location erc7201:openzeppelin.storage.Pausable
              struct PausableStorage {
                  bool _paused;
              }
              // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Pausable")) - 1)) & ~bytes32(uint256(0xff))
              bytes32 private constant PausableStorageLocation = 0xcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300;
              function _getPausableStorage() private pure returns (PausableStorage storage $) {
                  assembly {
                      $.slot := PausableStorageLocation
                  }
              }
              /**
               * @dev Emitted when the pause is triggered by `account`.
               */
              event Paused(address account);
              /**
               * @dev Emitted when the pause is lifted by `account`.
               */
              event Unpaused(address account);
              /**
               * @dev The operation failed because the contract is paused.
               */
              error EnforcedPause();
              /**
               * @dev The operation failed because the contract is not paused.
               */
              error ExpectedPause();
              /**
               * @dev Initializes the contract in unpaused state.
               */
              function __Pausable_init() internal onlyInitializing {
                  __Pausable_init_unchained();
              }
              function __Pausable_init_unchained() internal onlyInitializing {
                  PausableStorage storage $ = _getPausableStorage();
                  $._paused = false;
              }
              /**
               * @dev Modifier to make a function callable only when the contract is not paused.
               *
               * Requirements:
               *
               * - The contract must not be paused.
               */
              modifier whenNotPaused() {
                  _requireNotPaused();
                  _;
              }
              /**
               * @dev Modifier to make a function callable only when the contract is paused.
               *
               * Requirements:
               *
               * - The contract must be paused.
               */
              modifier whenPaused() {
                  _requirePaused();
                  _;
              }
              /**
               * @dev Returns true if the contract is paused, and false otherwise.
               */
              function paused() public view virtual returns (bool) {
                  PausableStorage storage $ = _getPausableStorage();
                  return $._paused;
              }
              /**
               * @dev Throws if the contract is paused.
               */
              function _requireNotPaused() internal view virtual {
                  if (paused()) {
                      revert EnforcedPause();
                  }
              }
              /**
               * @dev Throws if the contract is not paused.
               */
              function _requirePaused() internal view virtual {
                  if (!paused()) {
                      revert ExpectedPause();
                  }
              }
              /**
               * @dev Triggers stopped state.
               *
               * Requirements:
               *
               * - The contract must not be paused.
               */
              function _pause() internal virtual whenNotPaused {
                  PausableStorage storage $ = _getPausableStorage();
                  $._paused = true;
                  emit Paused(_msgSender());
              }
              /**
               * @dev Returns to normal state.
               *
               * Requirements:
               *
               * - The contract must be paused.
               */
              function _unpause() internal virtual whenPaused {
                  PausableStorage storage $ = _getPausableStorage();
                  $._paused = false;
                  emit Unpaused(_msgSender());
              }
          }
          // SPDX-License_Identifier: UNLICENSED
          pragma solidity 0.8.21;
          /// @title IEtherBridge
          /// @notice Interface for a bridge contract that handles deposits of ether.
          /// @dev This smart-contract interface supports a peg between gwei and lamports by messaging out ether values in gwei
          interface IEtherBridge {
              /// @notice Contains deposit details sent to the target rollup chain.
              /// @param sender The address which provided the ether to deposit.
              /// @param recipient Abi packed bytes32 of a base58-encoded Solana address on the target chain.
              /// @param amountGwei The amount in gwei to be deposited.
              struct DepositMessage {
                  address sender;
                  bytes32 recipient;
                  uint256 amountGwei;
              }
              /// @notice Emitted on a successful deposit.
              /// @param sender The address of the user who made the deposit.
              /// @param recipient The recipient account on the target chain.
              /// @param amountWei The amount in wei deposited.
              event Deposited(address indexed sender, bytes32 indexed recipient, uint256 amountWei);
              /// @notice Allows users to deposit ether to the target chain.
              /// @dev Accepts Ether along with the deposit message. Emits the `Deposited` event upon success.
              /// @param recipient The recipient account on target chain.
              /// @param amountWei The amount in wei to deposit.
              function deposit(bytes32 recipient, uint256 amountWei) external payable;
          }
          // SPDX-License_Identifier: UNLICENSED
          pragma solidity 0.8.21;
          /// @title ITreasury
          /// @notice Interface for a treasury contract stores ether
          /// @dev This interface assumes the implementation will provide a fallback function to receive ether.
          interface ITreasury {
              /// @notice Emitted when ether is deposited into the treasury
              /// @param from The address of the sender who deposited ether
              /// @param amount The amount of ether deposited
              event TreasuryDeposit(address indexed from, uint256 amount);
              /// @notice Emitted when ether is withdrawn from the treasury during an emergency withdraw
              /// @param to The address to which ether was sent
              /// @param amount The amount of ether withdrawn
              event EmergencyTreasuryWithdraw(address indexed to, uint256 amount);
              /// @notice Withdraws an 'amount' of ether during emergencies
              /// @param amount The amount of ether to be sent
              function emergencyWithdraw(uint256 amount) external;
          }
          // SPDX-License_Identifier: Apache-2.0
          pragma solidity 0.8.21;
          /// @title Cross-Chain Messaging interface
          /// @dev Allows seamless interchain messaging.
          /// @author Sujith Somraaj (extended by Eclipse Labs)
          /// Note: Based on EIP-6170 with the minor modifications (See Mailbox.md)
          interface IMailbox {
              /// @dev This emits when a cross-chain message is sent.
              /// Note: MessageSent MUST trigger when a message is sent, including zero bytes transfers.
              event MessageSent(bytes to, bytes toChainId, bytes message, bytes extraData);
              /// @dev This emits when a cross-chain message is received.
              /// MessageReceived MUST trigger on any successful call to receiveMessage
              event MessageReceived(bytes from, bytes fromChainId, bytes message, bytes extraData);
              /// @notice Sends a message to another blockchain through the trusted relayer
              /// @dev Sends an encoded message to a specified receiver on the target chain using a trusted relayer.
              /// @param chainId_ is the address of the receiver.
              /// @param receiver_ is the address of the receiver.
              /// @param message_ is the arbitrary message to be delivered.
              /// @param data_ is the address of the receiver.
              function sendMessage(bytes memory chainId_, bytes memory receiver_, bytes memory message_, bytes memory data_)
                  external
                  payable
                  returns (bool);
              /// @notice Receives a message from a sender on a different blockchain
              /// @dev Validates the sender, chainId, and ensures the message has not been replayed (checks nonce).
              /// @param chainId_ is the unique identifier of the sending blockchain.
              /// @param sender_ is the address of the sender.
              /// @param message_ is the arbitrary message sent by the sender.
              /// @param data_ is an additional parameter to be used for security purposes. E.g, can send nonce in layerzero.
              /// @return the status of message processing/storage.
              /// Note: sender validation (or) message validation should happen before processing the message.
              function receiveMessage(bytes memory chainId_, bytes memory sender_, bytes memory message_, bytes memory data_)
                  external
                  payable
                  returns (bool);
          }
          // SPDX-License_Identifier: UNLICENSED
          pragma solidity 0.8.21;
          /**
           * @title ISemVer
           * @dev Interface for SemVer versioning within smart contracts.
           */
          interface ISemVer {
              /**
               * @dev Struct to hold the version components.
               * @param major The major version component, incremented for incompatible API changes.
               * @param minor The minor version component, incremented for added functionality in a backwards-compatible manner.
               * @param patch The patch version component, incremented for backwards-compatible bug fixes.
               */
              struct Version {
                  uint8 major;
                  uint8 minor;
                  uint8 patch;
              }
              /**
               * @dev Returns the major, minor, and patch components of the version as a struct.
               * @return Version memory Returns the version details encapsulated in a Version struct.
               */
              function getVersionComponents() external pure returns (Version memory);
          }
          // SPDX-License_Identifier: UNLICENSED
          pragma solidity 0.8.21;
          /// @title Common Container
          /// @dev Contains modifiers for validating `ChainId`, `bytesArray` init status and address validation.
          abstract contract CommonContainer {
              function encodeChainId(bytes32 _chainId) internal pure returns (bytes memory) {
                  return abi.encode(_chainId);
              }
              function generateChainId(string memory _chainId) internal pure returns (bytes32) {
                  return keccak256(abi.encodePacked(_chainId));
              }
              function decodeChainId(bytes memory _encodedChainId) internal pure returns (bytes32) {
                  return abi.decode(_encodedChainId, (bytes32));
              }
              /// @dev Ensures that address is non-zero.
              modifier addressInitialized(address _address) {
                  require(_address != address(0), "CommonUtility: zero address");
                  _;
              }
              /// @dev Ensures that all addresses are non-zero.
              modifier addressArrayInitialized(address[] memory _addresses) {
                  require(_addresses.length > 0, "CommonUtility: addresses is empty");
                  for (uint256 i = 0; i < _addresses.length; i++) {
                      require(_addresses[i] != address(0), "CommonUtility: zero address in array");
                  }
                  _;
              }
              /// @dev Ensures that bytes have been initialized with data.
              modifier bytesInitialized(bytes memory _data) {
                  require(_data.length > 0, "CommonUtility: empty bytes");
                  _;
              }
              /// @dev Ensures that array of bytes have been initialized with data.
              modifier bytesArrayInitialized(bytes[] memory _data) {
                  require(_data.length > 0, "CommonUtility: empty bytes array");
                  for (uint256 i = 0; i < _data.length; i++) {
                      require(_data[i].length > 0, "CommonUtility: empty bytes in bytes array");
                  }
                  _;
              }
              /// @dev Ensures that bytes32 data is initialized with data.
              modifier bytes32Initialized(bytes32 _data) {
                  require(_data != bytes32(0), "CommonUtility: empty bytes32");
                  _;
              }
              /// @dev Ensures that an array of bytes32 data is initialized.
              modifier bytes32ArrayInitialized(bytes32[] memory _data) {
                  require(_data.length > 0, "CommonUtility: empty bytes32 array");
                  for (uint256 i = 0; i < _data.length; i++) {
                      require(_data[i] != bytes32(0), "CommonUtility: empty bytes32 in bytes32 array");
                  }
                  _;
              }
              /// @dev Ensures that bytes data is exactly equal to 32.
              modifier bytesLengthEq32(bytes memory _data) {
                  require(_data.length == 32, "CommonUtility: bytes must be 32 bytes long");
                  _;
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC1822.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
           * proxy whose upgrades are fully controlled by the current implementation.
           */
          interface IERC1822Proxiable {
              /**
               * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
               * address.
               *
               * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
               * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
               * function revert if invoked through a proxy.
               */
              function proxiableUUID() external view returns (bytes32);
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Utils.sol)
          pragma solidity ^0.8.20;
          import {IBeacon} from "../beacon/IBeacon.sol";
          import {Address} from "../../utils/Address.sol";
          import {StorageSlot} from "../../utils/StorageSlot.sol";
          /**
           * @dev This abstract contract provides getters and event emitting update functions for
           * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
           */
          library ERC1967Utils {
              // We re-declare ERC-1967 events here because they can't be used directly from IERC1967.
              // This will be fixed in Solidity 0.8.21. At that point we should remove these events.
              /**
               * @dev Emitted when the implementation is upgraded.
               */
              event Upgraded(address indexed implementation);
              /**
               * @dev Emitted when the admin account has changed.
               */
              event AdminChanged(address previousAdmin, address newAdmin);
              /**
               * @dev Emitted when the beacon is changed.
               */
              event BeaconUpgraded(address indexed beacon);
              /**
               * @dev Storage slot with the address of the current implementation.
               * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1.
               */
              // solhint-disable-next-line private-vars-leading-underscore
              bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
              /**
               * @dev The `implementation` of the proxy is invalid.
               */
              error ERC1967InvalidImplementation(address implementation);
              /**
               * @dev The `admin` of the proxy is invalid.
               */
              error ERC1967InvalidAdmin(address admin);
              /**
               * @dev The `beacon` of the proxy is invalid.
               */
              error ERC1967InvalidBeacon(address beacon);
              /**
               * @dev An upgrade function sees `msg.value > 0` that may be lost.
               */
              error ERC1967NonPayable();
              /**
               * @dev Returns the current implementation address.
               */
              function getImplementation() internal view returns (address) {
                  return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;
              }
              /**
               * @dev Stores a new address in the EIP1967 implementation slot.
               */
              function _setImplementation(address newImplementation) private {
                  if (newImplementation.code.length == 0) {
                      revert ERC1967InvalidImplementation(newImplementation);
                  }
                  StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;
              }
              /**
               * @dev Performs implementation upgrade with additional setup call if data is nonempty.
               * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
               * to avoid stuck value in the contract.
               *
               * Emits an {IERC1967-Upgraded} event.
               */
              function upgradeToAndCall(address newImplementation, bytes memory data) internal {
                  _setImplementation(newImplementation);
                  emit Upgraded(newImplementation);
                  if (data.length > 0) {
                      Address.functionDelegateCall(newImplementation, data);
                  } else {
                      _checkNonPayable();
                  }
              }
              /**
               * @dev Storage slot with the admin of the contract.
               * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1.
               */
              // solhint-disable-next-line private-vars-leading-underscore
              bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
              /**
               * @dev Returns the current admin.
               *
               * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using
               * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
               * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
               */
              function getAdmin() internal view returns (address) {
                  return StorageSlot.getAddressSlot(ADMIN_SLOT).value;
              }
              /**
               * @dev Stores a new address in the EIP1967 admin slot.
               */
              function _setAdmin(address newAdmin) private {
                  if (newAdmin == address(0)) {
                      revert ERC1967InvalidAdmin(address(0));
                  }
                  StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;
              }
              /**
               * @dev Changes the admin of the proxy.
               *
               * Emits an {IERC1967-AdminChanged} event.
               */
              function changeAdmin(address newAdmin) internal {
                  emit AdminChanged(getAdmin(), newAdmin);
                  _setAdmin(newAdmin);
              }
              /**
               * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
               * This is the keccak-256 hash of "eip1967.proxy.beacon" subtracted by 1.
               */
              // solhint-disable-next-line private-vars-leading-underscore
              bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
              /**
               * @dev Returns the current beacon.
               */
              function getBeacon() internal view returns (address) {
                  return StorageSlot.getAddressSlot(BEACON_SLOT).value;
              }
              /**
               * @dev Stores a new beacon in the EIP1967 beacon slot.
               */
              function _setBeacon(address newBeacon) private {
                  if (newBeacon.code.length == 0) {
                      revert ERC1967InvalidBeacon(newBeacon);
                  }
                  StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;
                  address beaconImplementation = IBeacon(newBeacon).implementation();
                  if (beaconImplementation.code.length == 0) {
                      revert ERC1967InvalidImplementation(beaconImplementation);
                  }
              }
              /**
               * @dev Change the beacon and trigger a setup call if data is nonempty.
               * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
               * to avoid stuck value in the contract.
               *
               * Emits an {IERC1967-BeaconUpgraded} event.
               *
               * CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since
               * it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for
               * efficiency.
               */
              function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {
                  _setBeacon(newBeacon);
                  emit BeaconUpgraded(newBeacon);
                  if (data.length > 0) {
                      Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
                  } else {
                      _checkNonPayable();
                  }
              }
              /**
               * @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract
               * if an upgrade doesn't perform an initialization call.
               */
              function _checkNonPayable() private {
                  if (msg.value > 0) {
                      revert ERC1967NonPayable();
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev External interface of AccessControl declared to support ERC165 detection.
           */
          interface IAccessControl {
              /**
               * @dev The `account` is missing a role.
               */
              error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
              /**
               * @dev The caller of a function is not the expected one.
               *
               * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
               */
              error AccessControlBadConfirmation();
              /**
               * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
               *
               * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
               * {RoleAdminChanged} not being emitted signaling this.
               */
              event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
              /**
               * @dev Emitted when `account` is granted `role`.
               *
               * `sender` is the account that originated the contract call, an admin role
               * bearer except when using {AccessControl-_setupRole}.
               */
              event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
              /**
               * @dev Emitted when `account` is revoked `role`.
               *
               * `sender` is the account that originated the contract call:
               *   - if using `revokeRole`, it is the admin role bearer
               *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
               */
              event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
              /**
               * @dev Returns `true` if `account` has been granted `role`.
               */
              function hasRole(bytes32 role, address account) external view returns (bool);
              /**
               * @dev Returns the admin role that controls `role`. See {grantRole} and
               * {revokeRole}.
               *
               * To change a role's admin, use {AccessControl-_setRoleAdmin}.
               */
              function getRoleAdmin(bytes32 role) external view returns (bytes32);
              /**
               * @dev Grants `role` to `account`.
               *
               * If `account` had not been already granted `role`, emits a {RoleGranted}
               * event.
               *
               * Requirements:
               *
               * - the caller must have ``role``'s admin role.
               */
              function grantRole(bytes32 role, address account) external;
              /**
               * @dev Revokes `role` from `account`.
               *
               * If `account` had been granted `role`, emits a {RoleRevoked} event.
               *
               * Requirements:
               *
               * - the caller must have ``role``'s admin role.
               */
              function revokeRole(bytes32 role, address account) external;
              /**
               * @dev Revokes `role` from the calling account.
               *
               * Roles are often managed via {grantRole} and {revokeRole}: this function's
               * purpose is to provide a mechanism for accounts to lose their privileges
               * if they are compromised (such as when a trusted device is misplaced).
               *
               * If the calling account had been granted `role`, emits a {RoleRevoked}
               * event.
               *
               * Requirements:
               *
               * - the caller must be `callerConfirmation`.
               */
              function renounceRole(bytes32 role, address callerConfirmation) external;
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
          pragma solidity ^0.8.20;
          import {Initializable} from "../proxy/utils/Initializable.sol";
          /**
           * @dev Provides information about the current execution context, including the
           * sender of the transaction and its data. While these are generally available
           * via msg.sender and msg.data, they should not be accessed in such a direct
           * manner, since when dealing with meta-transactions the account sending and
           * paying for execution may not be the actual sender (as far as an application
           * is concerned).
           *
           * This contract is only required for intermediate, library-like contracts.
           */
          abstract contract ContextUpgradeable is Initializable {
              function __Context_init() internal onlyInitializing {
              }
              function __Context_init_unchained() internal onlyInitializing {
              }
              function _msgSender() internal view virtual returns (address) {
                  return msg.sender;
              }
              function _msgData() internal view virtual returns (bytes calldata) {
                  return msg.data;
              }
              function _contextSuffixLength() internal view virtual returns (uint256) {
                  return 0;
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)
          pragma solidity ^0.8.20;
          import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
          import {Initializable} from "../../proxy/utils/Initializable.sol";
          /**
           * @dev Implementation of the {IERC165} interface.
           *
           * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
           * for the additional interface id that will be supported. For example:
           *
           * ```solidity
           * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
           *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
           * }
           * ```
           */
          abstract contract ERC165Upgradeable is Initializable, IERC165 {
              function __ERC165_init() internal onlyInitializing {
              }
              function __ERC165_init_unchained() internal onlyInitializing {
              }
              /**
               * @dev See {IERC165-supportsInterface}.
               */
              function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
                  return interfaceId == type(IERC165).interfaceId;
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev This is the interface that {BeaconProxy} expects of its beacon.
           */
          interface IBeacon {
              /**
               * @dev Must return an address that can be used as a delegate call target.
               *
               * {UpgradeableBeacon} will check that this address is a contract.
               */
              function implementation() external view returns (address);
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev Collection of functions related to the address type
           */
          library Address {
              /**
               * @dev The ETH balance of the account is not enough to perform the operation.
               */
              error AddressInsufficientBalance(address account);
              /**
               * @dev There's no code at `target` (it is not a contract).
               */
              error AddressEmptyCode(address target);
              /**
               * @dev A call to an address target failed. The target may have reverted.
               */
              error FailedInnerCall();
              /**
               * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
               * `recipient`, forwarding all available gas and reverting on errors.
               *
               * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
               * of certain opcodes, possibly making contracts go over the 2300 gas limit
               * imposed by `transfer`, making them unable to receive funds via
               * `transfer`. {sendValue} removes this limitation.
               *
               * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
               *
               * IMPORTANT: because control is transferred to `recipient`, care must be
               * taken to not create reentrancy vulnerabilities. Consider using
               * {ReentrancyGuard} or the
               * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
               */
              function sendValue(address payable recipient, uint256 amount) internal {
                  if (address(this).balance < amount) {
                      revert AddressInsufficientBalance(address(this));
                  }
                  (bool success, ) = recipient.call{value: amount}("");
                  if (!success) {
                      revert FailedInnerCall();
                  }
              }
              /**
               * @dev Performs a Solidity function call using a low level `call`. A
               * plain `call` is an unsafe replacement for a function call: use this
               * function instead.
               *
               * If `target` reverts with a revert reason or custom error, it is bubbled
               * up by this function (like regular Solidity function calls). However, if
               * the call reverted with no returned reason, this function reverts with a
               * {FailedInnerCall} error.
               *
               * Returns the raw returned data. To convert to the expected return value,
               * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
               *
               * Requirements:
               *
               * - `target` must be a contract.
               * - calling `target` with `data` must not revert.
               */
              function functionCall(address target, bytes memory data) internal returns (bytes memory) {
                  return functionCallWithValue(target, data, 0);
              }
              /**
               * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
               * but also transferring `value` wei to `target`.
               *
               * Requirements:
               *
               * - the calling contract must have an ETH balance of at least `value`.
               * - the called Solidity function must be `payable`.
               */
              function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
                  if (address(this).balance < value) {
                      revert AddressInsufficientBalance(address(this));
                  }
                  (bool success, bytes memory returndata) = target.call{value: value}(data);
                  return verifyCallResultFromTarget(target, success, returndata);
              }
              /**
               * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
               * but performing a static call.
               */
              function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
                  (bool success, bytes memory returndata) = target.staticcall(data);
                  return verifyCallResultFromTarget(target, success, returndata);
              }
              /**
               * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
               * but performing a delegate call.
               */
              function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
                  (bool success, bytes memory returndata) = target.delegatecall(data);
                  return verifyCallResultFromTarget(target, success, returndata);
              }
              /**
               * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
               * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
               * unsuccessful call.
               */
              function verifyCallResultFromTarget(
                  address target,
                  bool success,
                  bytes memory returndata
              ) internal view returns (bytes memory) {
                  if (!success) {
                      _revert(returndata);
                  } else {
                      // only check if target is a contract if the call was successful and the return data is empty
                      // otherwise we already know that it was a contract
                      if (returndata.length == 0 && target.code.length == 0) {
                          revert AddressEmptyCode(target);
                      }
                      return returndata;
                  }
              }
              /**
               * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
               * revert reason or with a default {FailedInnerCall} error.
               */
              function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
                  if (!success) {
                      _revert(returndata);
                  } else {
                      return returndata;
                  }
              }
              /**
               * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
               */
              function _revert(bytes memory returndata) private pure {
                  // Look for revert reason and bubble it up if present
                  if (returndata.length > 0) {
                      // The easiest way to bubble the revert reason is using memory via assembly
                      /// @solidity memory-safe-assembly
                      assembly {
                          let returndata_size := mload(returndata)
                          revert(add(32, returndata), returndata_size)
                      }
                  } else {
                      revert FailedInnerCall();
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol)
          // This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
          pragma solidity ^0.8.20;
          /**
           * @dev Library for reading and writing primitive types to specific storage slots.
           *
           * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
           * This library helps with reading and writing to such slots without the need for inline assembly.
           *
           * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
           *
           * Example usage to set ERC1967 implementation slot:
           * ```solidity
           * contract ERC1967 {
           *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
           *
           *     function _getImplementation() internal view returns (address) {
           *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
           *     }
           *
           *     function _setImplementation(address newImplementation) internal {
           *         require(newImplementation.code.length > 0);
           *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
           *     }
           * }
           * ```
           */
          library StorageSlot {
              struct AddressSlot {
                  address value;
              }
              struct BooleanSlot {
                  bool value;
              }
              struct Bytes32Slot {
                  bytes32 value;
              }
              struct Uint256Slot {
                  uint256 value;
              }
              struct StringSlot {
                  string value;
              }
              struct BytesSlot {
                  bytes value;
              }
              /**
               * @dev Returns an `AddressSlot` with member `value` located at `slot`.
               */
              function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
               */
              function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
               */
              function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
               */
              function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `StringSlot` with member `value` located at `slot`.
               */
              function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `StringSlot` representation of the string storage pointer `store`.
               */
              function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := store.slot
                  }
              }
              /**
               * @dev Returns an `BytesSlot` with member `value` located at `slot`.
               */
              function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
               */
              function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := store.slot
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev Interface of the ERC165 standard, as defined in the
           * https://eips.ethereum.org/EIPS/eip-165[EIP].
           *
           * Implementers can declare support of contract interfaces, which can then be
           * queried by others ({ERC165Checker}).
           *
           * For an implementation, see {ERC165}.
           */
          interface IERC165 {
              /**
               * @dev Returns true if this contract implements the interface defined by
               * `interfaceId`. See the corresponding
               * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
               * to learn more about how these ids are created.
               *
               * This function call must use less than 30 000 gas.
               */
              function supportsInterface(bytes4 interfaceId) external view returns (bool);
          }
          

          File 5 of 6: Mailbox
          // SPDX-License_Identifier: UNLICENSED
          pragma solidity 0.8.21;
          import "openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol";
          import "openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol";
          import "openzeppelin-contracts-upgradeable/contracts/access/AccessControlUpgradeable.sol";
          import "openzeppelin-contracts-upgradeable/contracts/utils/ReentrancyGuardUpgradeable.sol";
          import "./interfaces/IMailbox.sol";
          import "./CommonContainer.sol";
          import "./interfaces/ISemVer.sol";
          /// @title Mailbox
          /// @dev Allows certain contracts to send and receive messages between Ethereum and Eclipse using a trusted relayer.
          contract Mailbox is
              IMailbox,
              ISemVer,
              CommonContainer,
              Initializable,
              AccessControlUpgradeable,
              ReentrancyGuardUpgradeable,
              UUPSUpgradeable
          {
              bytes32 public constant TRUSTED_RELAYER_ROLE = keccak256("TRUSTED_RELAYER_ROLE");
              bytes32 public constant MODULE_ROLE = keccak256("MODULE_ROLE");
              uint8 private constant MAJOR_VERSION = 1;
              uint8 private constant MINOR_VERSION = 0;
              uint8 private constant PATCH_VERSION = 0;
              // @dev Messages received from Eclipse include a security param which decodes into this structure.
              // @param nonce is random number used only once for a message which is received.
              struct EclipseSecurityParam {
                  uint64 nonce;
              }
              // @dev Messages sent from Ethereum include a security param which is encoded using this structure.
              // @param nonce is random number used only once for sending a message.
              struct EthereumSecurityParam {
                  uint64 nonce;
              }
              // @dev The params passed into initializer (useful for avoiding stack too deep issues)
              /// @param trustedRelayer_ The address of the trusted relayer.
              /// @param ids_ Module identifiers (hash of contract name) that can send messages through this mailbox.
              /// @param modules_ The addresses of the contracts that can send messages through this mailbox.
              /// @param ethereumChainId_ The chainId for this Ethereum chain.
              /// @param eclipseChainId_ The chainId for the Eclipse chain.
              struct InitParams {
                  address initialOwner;
                  address trustedRelayer;
                  bytes32[] ids;
                  address[] modules;
                  string ethereumChainId;
                  string eclipseChainId;
              }
              /// @custom:storage-location erc7201:eclipse.mailbox.v1
              struct StorageV1 {
                  uint256 lastNonce;
                  bytes32 ethereumChainId;
                  bytes32 eclipseChainId;
                  mapping(bytes32 => address) modulesById;
                  mapping(uint64 => bool) receiveNonces;
                  mapping(uint64 => bool) sendNonces;
              }
              // keccak256(abi.encode(uint256(keccak256("eclipse.mailbox.v1")) - 1)) & ~bytes32(uint256(0xff))
              bytes32 private constant STORAGE_V1_LOCATION = 0x8455de2eaf4bdcf2bc20fa04052c8c0cac25abccf9eccf721a14442c18547600;
              function _getStorageV1() internal pure returns (StorageV1 storage $) {
                  assembly {
                      $.slot := STORAGE_V1_LOCATION
                  }
              }
              /// @dev Validates the chainId corresponds to the Ethereum chain.
              modifier ethereumChainIdValid(bytes memory chainId_) {
                  require(decodeChainId(chainId_) == _getStorageV1().ethereumChainId, "Unsupported Ethereum chain id.");
                  _;
              }
              /// @dev Validates the chainId corresponds to the Eclipse chain.
              modifier eclipseChainIdValid(bytes memory chainId_) {
                  require(decodeChainId(chainId_) == _getStorageV1().eclipseChainId, "Unsupported Eclipse chain id.");
                  _;
              }
              /// @dev Restricts the function call to only the trusted relayer.
              modifier onlyTrustedRelayer() {
                  require(hasRole(TRUSTED_RELAYER_ROLE, msg.sender), "Only the trusted relayer can call this method.");
                  _;
              }
              /// @dev Restricts the function call to only recognized modules.
              modifier onlyModule() {
                  require(hasRole(MODULE_ROLE, msg.sender), "Only an authorized module can call this method.");
                  _;
              }
              /// @dev Restricts the function call to only admins.
              modifier onlyAuthority() {
                  require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Only an admin can call this method.");
                  _;
              }
              /// @dev Validates the length of module ids array and modules array
              modifier validateModuleArrays(bytes32[] calldata ids_, address[] calldata modules_) {
                  require(ids_.length != 0, "Module identifiers must be initialized");
                  require(modules_.length != 0, "Module addresses must be initialized");
                  require(ids_.length == modules_.length, "Module identifiers and addresses must have same length");
                  _;
              }
              /// @dev Constructor that disables initializers
              /// @custom:oz-upgrades-unsafe-allow constructor
              constructor() {
                  _disableInitializers();
              }
              /// @dev Initializes the mailbox contract
              /// @param params the variable which contains all the fields needed to init
              function initialize(InitParams calldata params)
                  public
                  addressInitialized(params.initialOwner)
                  addressInitialized(params.trustedRelayer)
                  addressArrayInitialized(params.modules)
                  bytes32ArrayInitialized(params.ids)
                  bytesInitialized(bytes(params.ethereumChainId))
                  bytesInitialized(bytes(params.eclipseChainId))
                  initializer
              {
                  require(params.ids.length == params.modules.length, "Module ids and addresses must have equal length");
                  __AccessControl_init();
                  __ReentrancyGuard_init();
                  __UUPSUpgradeable_init();
                  // Grant roles and update modules by id
                  StorageV1 storage $ = _getStorageV1();
                  _grantRole(DEFAULT_ADMIN_ROLE, params.initialOwner);
                  _grantRole(TRUSTED_RELAYER_ROLE, params.trustedRelayer);
                  for (uint256 i = 0; i < params.modules.length; i++) {
                      bytes32 id = params.ids[i];
                      address module = params.modules[i];
                      _grantRole(MODULE_ROLE, module);
                      $.modulesById[id] = module;
                  }
                  // Store chain ids and initial nonce seed
                  $.ethereumChainId = generateChainId(params.ethereumChainId);
                  $.eclipseChainId = generateChainId(params.eclipseChainId);
                  $.lastNonce = generateRandomNonce();
              }
              /// @dev Retrieves the constant version details of the smart contract.
              function getVersionComponents() public pure override returns (Version memory) {
                  return Version(MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION);
              }
              /// @dev (NOT UNIT TESTED) Add module address by id and grant module role to that address
              function addModule(bytes32 moduleId, address module)
                  external
                  bytes32Initialized(moduleId)
                  addressInitialized(module)
                  onlyAuthority
              {
                  StorageV1 storage $ = _getStorageV1();
                  if ($.modulesById[moduleId] != address(0)) {
                      revert("Module address for module id already set");
                  }
                  $.modulesById[moduleId] = module;
                  _grantRole(MODULE_ROLE, module);
              }
              /// @dev (NOT UNIT TESTED) Remove module address by id and revoke module role for that address
              function removeModule(bytes32 moduleId, address module)
                  external
                  bytes32Initialized(moduleId)
                  addressInitialized(module)
                  onlyAuthority
              {
                  StorageV1 storage $ = _getStorageV1();
                  if ($.modulesById[moduleId] == address(0)) {
                      revert("Module address for module id not yet set");
                  }
                  if ($.modulesById[moduleId] != module) {
                      revert("Module address for module id does not match provided module address to remove/revoke");
                  }
                  delete $.modulesById[moduleId];
                  _revokeRole(MODULE_ROLE, module);
              }
              /// @dev Receives messages from eclipse and send them to a specific module for processing.
              function receiveMessage(
                  bytes memory eclipseChainId_,
                  bytes memory sender_,
                  bytes memory message_,
                  bytes memory data_
              )
                  external
                  payable
                  virtual
                  override
                  onlyTrustedRelayer
                  bytesLengthEq32(eclipseChainId_)
                  eclipseChainIdValid(eclipseChainId_)
                  bytesInitialized(sender_)
                  bytesInitialized(message_)
                  bytesInitialized(data_)
                  nonReentrant
                  returns (bool)
              {
                  // Validate and store the security param nonce
                  StorageV1 storage $ = _getStorageV1();
                  EclipseSecurityParam memory secParam = abi.decode(data_, (EclipseSecurityParam));
                  require($.receiveNonces[secParam.nonce] == false, "Message with this nonce already received.");
                  $.receiveNonces[secParam.nonce] = true;
                  // Send the message to the module
                  address module = $.modulesById[bytes32(sender_)];
                  require(module != address(0), "Module does not exist.");
                  (bool success,) = module.call(message_);
                  require(success, "External call to module failed.");
                  // Emit the message received event
                  emit MessageReceived(sender_, eclipseChainId_, message_, data_);
                  return true;
              }
              /// @dev Modules call this method to send messages out to Eclipse.
              function sendMessage(bytes memory, bytes memory receiver_, bytes memory message_, bytes memory)
                  external
                  payable
                  virtual
                  override
                  onlyModule
                  nonReentrant
                  returns (bool)
              {
                  // Create and set nonce
                  StorageV1 storage $ = _getStorageV1();
                  uint64 outboundNonce = generateRandomNonce();
                  if ($.sendNonces[outboundNonce] == true) {
                      revert("Nonce collision");
                  }
                  $.sendNonces[outboundNonce] = true;
                  // Create security param
                  bytes memory param = abi.encode(EthereumSecurityParam({nonce: outboundNonce}));
                  emit MessageSent(receiver_, encodeChainId($.eclipseChainId), message_, param);
                  return true;
              }
              /// @dev required by the OZ UUPS module
              function _authorizeUpgrade(address) internal virtual override onlyAuthority {}
              /// @dev Generates a pseudo-random nonce based on block properties and chained state.
              /// This function combines previous nonce state with the hash of the last block,
              /// current block timestamp, and block difficulty to produce a new nonce that is
              /// resistant to manipulation and harder to predict in advance given the params solidity supports.
              /// @return Returns a 64-bit nonce generated from various entropy sources.
              function generateRandomNonce() internal returns (uint64) {
                  StorageV1 storage $ = _getStorageV1();
                  // Combine unpredictable block properties with the last nonce to generate a new nonce.
                  $.lastNonce = uint256(
                      keccak256(abi.encodePacked($.lastNonce, blockhash(block.number - 1), block.timestamp, block.coinbase))
                  );
                  return uint64($.lastNonce); // Return the least significant 64 bits
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
           * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
           * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
           * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
           *
           * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
           * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
           * case an upgrade adds a module that needs to be initialized.
           *
           * For example:
           *
           * [.hljs-theme-light.nopadding]
           * ```solidity
           * contract MyToken is ERC20Upgradeable {
           *     function initialize() initializer public {
           *         __ERC20_init("MyToken", "MTK");
           *     }
           * }
           *
           * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
           *     function initializeV2() reinitializer(2) public {
           *         __ERC20Permit_init("MyToken");
           *     }
           * }
           * ```
           *
           * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
           * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
           *
           * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
           * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
           *
           * [CAUTION]
           * ====
           * Avoid leaving a contract uninitialized.
           *
           * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
           * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
           * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
           *
           * [.hljs-theme-light.nopadding]
           * ```
           * /// @custom:oz-upgrades-unsafe-allow constructor
           * constructor() {
           *     _disableInitializers();
           * }
           * ```
           * ====
           */
          abstract contract Initializable {
              /**
               * @dev Storage of the initializable contract.
               *
               * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
               * when using with upgradeable contracts.
               *
               * @custom:storage-location erc7201:openzeppelin.storage.Initializable
               */
              struct InitializableStorage {
                  /**
                   * @dev Indicates that the contract has been initialized.
                   */
                  uint64 _initialized;
                  /**
                   * @dev Indicates that the contract is in the process of being initialized.
                   */
                  bool _initializing;
              }
              // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
              bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
              /**
               * @dev The contract is already initialized.
               */
              error InvalidInitialization();
              /**
               * @dev The contract is not initializing.
               */
              error NotInitializing();
              /**
               * @dev Triggered when the contract has been initialized or reinitialized.
               */
              event Initialized(uint64 version);
              /**
               * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
               * `onlyInitializing` functions can be used to initialize parent contracts.
               *
               * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
               * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
               * production.
               *
               * Emits an {Initialized} event.
               */
              modifier initializer() {
                  // solhint-disable-next-line var-name-mixedcase
                  InitializableStorage storage $ = _getInitializableStorage();
                  // Cache values to avoid duplicated sloads
                  bool isTopLevelCall = !$._initializing;
                  uint64 initialized = $._initialized;
                  // Allowed calls:
                  // - initialSetup: the contract is not in the initializing state and no previous version was
                  //                 initialized
                  // - construction: the contract is initialized at version 1 (no reininitialization) and the
                  //                 current contract is just being deployed
                  bool initialSetup = initialized == 0 && isTopLevelCall;
                  bool construction = initialized == 1 && address(this).code.length == 0;
                  if (!initialSetup && !construction) {
                      revert InvalidInitialization();
                  }
                  $._initialized = 1;
                  if (isTopLevelCall) {
                      $._initializing = true;
                  }
                  _;
                  if (isTopLevelCall) {
                      $._initializing = false;
                      emit Initialized(1);
                  }
              }
              /**
               * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
               * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
               * used to initialize parent contracts.
               *
               * A reinitializer may be used after the original initialization step. This is essential to configure modules that
               * are added through upgrades and that require initialization.
               *
               * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
               * cannot be nested. If one is invoked in the context of another, execution will revert.
               *
               * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
               * a contract, executing them in the right order is up to the developer or operator.
               *
               * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
               *
               * Emits an {Initialized} event.
               */
              modifier reinitializer(uint64 version) {
                  // solhint-disable-next-line var-name-mixedcase
                  InitializableStorage storage $ = _getInitializableStorage();
                  if ($._initializing || $._initialized >= version) {
                      revert InvalidInitialization();
                  }
                  $._initialized = version;
                  $._initializing = true;
                  _;
                  $._initializing = false;
                  emit Initialized(version);
              }
              /**
               * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
               * {initializer} and {reinitializer} modifiers, directly or indirectly.
               */
              modifier onlyInitializing() {
                  _checkInitializing();
                  _;
              }
              /**
               * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
               */
              function _checkInitializing() internal view virtual {
                  if (!_isInitializing()) {
                      revert NotInitializing();
                  }
              }
              /**
               * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
               * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
               * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
               * through proxies.
               *
               * Emits an {Initialized} event the first time it is successfully executed.
               */
              function _disableInitializers() internal virtual {
                  // solhint-disable-next-line var-name-mixedcase
                  InitializableStorage storage $ = _getInitializableStorage();
                  if ($._initializing) {
                      revert InvalidInitialization();
                  }
                  if ($._initialized != type(uint64).max) {
                      $._initialized = type(uint64).max;
                      emit Initialized(type(uint64).max);
                  }
              }
              /**
               * @dev Returns the highest version that has been initialized. See {reinitializer}.
               */
              function _getInitializedVersion() internal view returns (uint64) {
                  return _getInitializableStorage()._initialized;
              }
              /**
               * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
               */
              function _isInitializing() internal view returns (bool) {
                  return _getInitializableStorage()._initializing;
              }
              /**
               * @dev Returns a pointer to the storage namespace.
               */
              // solhint-disable-next-line var-name-mixedcase
              function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
                  assembly {
                      $.slot := INITIALIZABLE_STORAGE
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/UUPSUpgradeable.sol)
          pragma solidity ^0.8.20;
          import {IERC1822Proxiable} from "@openzeppelin/contracts/interfaces/draft-IERC1822.sol";
          import {ERC1967Utils} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";
          import {Initializable} from "./Initializable.sol";
          /**
           * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
           * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
           *
           * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
           * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
           * `UUPSUpgradeable` with a custom implementation of upgrades.
           *
           * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
           */
          abstract contract UUPSUpgradeable is Initializable, IERC1822Proxiable {
              /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
              address private immutable __self = address(this);
              /**
               * @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgradeTo(address)`
               * and `upgradeToAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called,
               * while `upgradeToAndCall` will invoke the `receive` function if the second argument is the empty byte string.
               * If the getter returns `"5.0.0"`, only `upgradeToAndCall(address,bytes)` is present, and the second argument must
               * be the empty byte string if no function should be called, making it impossible to invoke the `receive` function
               * during an upgrade.
               */
              string public constant UPGRADE_INTERFACE_VERSION = "5.0.0";
              /**
               * @dev The call is from an unauthorized context.
               */
              error UUPSUnauthorizedCallContext();
              /**
               * @dev The storage `slot` is unsupported as a UUID.
               */
              error UUPSUnsupportedProxiableUUID(bytes32 slot);
              /**
               * @dev Check that the execution is being performed through a delegatecall call and that the execution context is
               * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
               * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
               * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
               * fail.
               */
              modifier onlyProxy() {
                  _checkProxy();
                  _;
              }
              /**
               * @dev Check that the execution is not being performed through a delegate call. This allows a function to be
               * callable on the implementing contract but not through proxies.
               */
              modifier notDelegated() {
                  _checkNotDelegated();
                  _;
              }
              function __UUPSUpgradeable_init() internal onlyInitializing {
              }
              function __UUPSUpgradeable_init_unchained() internal onlyInitializing {
              }
              /**
               * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
               * implementation. It is used to validate the implementation's compatibility when performing an upgrade.
               *
               * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
               * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
               * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
               */
              function proxiableUUID() external view virtual notDelegated returns (bytes32) {
                  return ERC1967Utils.IMPLEMENTATION_SLOT;
              }
              /**
               * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
               * encoded in `data`.
               *
               * Calls {_authorizeUpgrade}.
               *
               * Emits an {Upgraded} event.
               *
               * @custom:oz-upgrades-unsafe-allow-reachable delegatecall
               */
              function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {
                  _authorizeUpgrade(newImplementation);
                  _upgradeToAndCallUUPS(newImplementation, data);
              }
              /**
               * @dev Reverts if the execution is not performed via delegatecall or the execution
               * context is not of a proxy with an ERC1967-compliant implementation pointing to self.
               * See {_onlyProxy}.
               */
              function _checkProxy() internal view virtual {
                  if (
                      address(this) == __self || // Must be called through delegatecall
                      ERC1967Utils.getImplementation() != __self // Must be called through an active proxy
                  ) {
                      revert UUPSUnauthorizedCallContext();
                  }
              }
              /**
               * @dev Reverts if the execution is performed via delegatecall.
               * See {notDelegated}.
               */
              function _checkNotDelegated() internal view virtual {
                  if (address(this) != __self) {
                      // Must not be called through delegatecall
                      revert UUPSUnauthorizedCallContext();
                  }
              }
              /**
               * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
               * {upgradeToAndCall}.
               *
               * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
               *
               * ```solidity
               * function _authorizeUpgrade(address) internal onlyOwner {}
               * ```
               */
              function _authorizeUpgrade(address newImplementation) internal virtual;
              /**
               * @dev Performs an implementation upgrade with a security check for UUPS proxies, and additional setup call.
               *
               * As a security check, {proxiableUUID} is invoked in the new implementation, and the return value
               * is expected to be the implementation slot in ERC1967.
               *
               * Emits an {IERC1967-Upgraded} event.
               */
              function _upgradeToAndCallUUPS(address newImplementation, bytes memory data) private {
                  try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {
                      if (slot != ERC1967Utils.IMPLEMENTATION_SLOT) {
                          revert UUPSUnsupportedProxiableUUID(slot);
                      }
                      ERC1967Utils.upgradeToAndCall(newImplementation, data);
                  } catch {
                      // The implementation is not UUPS
                      revert ERC1967Utils.ERC1967InvalidImplementation(newImplementation);
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)
          pragma solidity ^0.8.20;
          import {IAccessControl} from "@openzeppelin/contracts/access/IAccessControl.sol";
          import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
          import {ERC165Upgradeable} from "../utils/introspection/ERC165Upgradeable.sol";
          import {Initializable} from "../proxy/utils/Initializable.sol";
          /**
           * @dev Contract module that allows children to implement role-based access
           * control mechanisms. This is a lightweight version that doesn't allow enumerating role
           * members except through off-chain means by accessing the contract event logs. Some
           * applications may benefit from on-chain enumerability, for those cases see
           * {AccessControlEnumerable}.
           *
           * Roles are referred to by their `bytes32` identifier. These should be exposed
           * in the external API and be unique. The best way to achieve this is by
           * using `public constant` hash digests:
           *
           * ```solidity
           * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
           * ```
           *
           * Roles can be used to represent a set of permissions. To restrict access to a
           * function call, use {hasRole}:
           *
           * ```solidity
           * function foo() public {
           *     require(hasRole(MY_ROLE, msg.sender));
           *     ...
           * }
           * ```
           *
           * Roles can be granted and revoked dynamically via the {grantRole} and
           * {revokeRole} functions. Each role has an associated admin role, and only
           * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
           *
           * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
           * that only accounts with this role will be able to grant or revoke other
           * roles. More complex role relationships can be created by using
           * {_setRoleAdmin}.
           *
           * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
           * grant and revoke this role. Extra precautions should be taken to secure
           * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
           * to enforce additional security measures for this role.
           */
          abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControl, ERC165Upgradeable {
              struct RoleData {
                  mapping(address account => bool) hasRole;
                  bytes32 adminRole;
              }
              bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
              /// @custom:storage-location erc7201:openzeppelin.storage.AccessControl
              struct AccessControlStorage {
                  mapping(bytes32 role => RoleData) _roles;
              }
              // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.AccessControl")) - 1)) & ~bytes32(uint256(0xff))
              bytes32 private constant AccessControlStorageLocation = 0x02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800;
              function _getAccessControlStorage() private pure returns (AccessControlStorage storage $) {
                  assembly {
                      $.slot := AccessControlStorageLocation
                  }
              }
              /**
               * @dev Modifier that checks that an account has a specific role. Reverts
               * with an {AccessControlUnauthorizedAccount} error including the required role.
               */
              modifier onlyRole(bytes32 role) {
                  _checkRole(role);
                  _;
              }
              function __AccessControl_init() internal onlyInitializing {
              }
              function __AccessControl_init_unchained() internal onlyInitializing {
              }
              /**
               * @dev See {IERC165-supportsInterface}.
               */
              function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
                  return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
              }
              /**
               * @dev Returns `true` if `account` has been granted `role`.
               */
              function hasRole(bytes32 role, address account) public view virtual returns (bool) {
                  AccessControlStorage storage $ = _getAccessControlStorage();
                  return $._roles[role].hasRole[account];
              }
              /**
               * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
               * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
               */
              function _checkRole(bytes32 role) internal view virtual {
                  _checkRole(role, _msgSender());
              }
              /**
               * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
               * is missing `role`.
               */
              function _checkRole(bytes32 role, address account) internal view virtual {
                  if (!hasRole(role, account)) {
                      revert AccessControlUnauthorizedAccount(account, role);
                  }
              }
              /**
               * @dev Returns the admin role that controls `role`. See {grantRole} and
               * {revokeRole}.
               *
               * To change a role's admin, use {_setRoleAdmin}.
               */
              function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
                  AccessControlStorage storage $ = _getAccessControlStorage();
                  return $._roles[role].adminRole;
              }
              /**
               * @dev Grants `role` to `account`.
               *
               * If `account` had not been already granted `role`, emits a {RoleGranted}
               * event.
               *
               * Requirements:
               *
               * - the caller must have ``role``'s admin role.
               *
               * May emit a {RoleGranted} event.
               */
              function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
                  _grantRole(role, account);
              }
              /**
               * @dev Revokes `role` from `account`.
               *
               * If `account` had been granted `role`, emits a {RoleRevoked} event.
               *
               * Requirements:
               *
               * - the caller must have ``role``'s admin role.
               *
               * May emit a {RoleRevoked} event.
               */
              function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
                  _revokeRole(role, account);
              }
              /**
               * @dev Revokes `role` from the calling account.
               *
               * Roles are often managed via {grantRole} and {revokeRole}: this function's
               * purpose is to provide a mechanism for accounts to lose their privileges
               * if they are compromised (such as when a trusted device is misplaced).
               *
               * If the calling account had been revoked `role`, emits a {RoleRevoked}
               * event.
               *
               * Requirements:
               *
               * - the caller must be `callerConfirmation`.
               *
               * May emit a {RoleRevoked} event.
               */
              function renounceRole(bytes32 role, address callerConfirmation) public virtual {
                  if (callerConfirmation != _msgSender()) {
                      revert AccessControlBadConfirmation();
                  }
                  _revokeRole(role, callerConfirmation);
              }
              /**
               * @dev Sets `adminRole` as ``role``'s admin role.
               *
               * Emits a {RoleAdminChanged} event.
               */
              function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
                  AccessControlStorage storage $ = _getAccessControlStorage();
                  bytes32 previousAdminRole = getRoleAdmin(role);
                  $._roles[role].adminRole = adminRole;
                  emit RoleAdminChanged(role, previousAdminRole, adminRole);
              }
              /**
               * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
               *
               * Internal function without access restriction.
               *
               * May emit a {RoleGranted} event.
               */
              function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
                  AccessControlStorage storage $ = _getAccessControlStorage();
                  if (!hasRole(role, account)) {
                      $._roles[role].hasRole[account] = true;
                      emit RoleGranted(role, account, _msgSender());
                      return true;
                  } else {
                      return false;
                  }
              }
              /**
               * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.
               *
               * Internal function without access restriction.
               *
               * May emit a {RoleRevoked} event.
               */
              function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
                  AccessControlStorage storage $ = _getAccessControlStorage();
                  if (hasRole(role, account)) {
                      $._roles[role].hasRole[account] = false;
                      emit RoleRevoked(role, account, _msgSender());
                      return true;
                  } else {
                      return false;
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)
          pragma solidity ^0.8.20;
          import {Initializable} from "../proxy/utils/Initializable.sol";
          /**
           * @dev Contract module that helps prevent reentrant calls to a function.
           *
           * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
           * available, which can be applied to functions to make sure there are no nested
           * (reentrant) calls to them.
           *
           * Note that because there is a single `nonReentrant` guard, functions marked as
           * `nonReentrant` may not call one another. This can be worked around by making
           * those functions `private`, and then adding `external` `nonReentrant` entry
           * points to them.
           *
           * TIP: If you would like to learn more about reentrancy and alternative ways
           * to protect against it, check out our blog post
           * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
           */
          abstract contract ReentrancyGuardUpgradeable is Initializable {
              // Booleans are more expensive than uint256 or any type that takes up a full
              // word because each write operation emits an extra SLOAD to first read the
              // slot's contents, replace the bits taken up by the boolean, and then write
              // back. This is the compiler's defense against contract upgrades and
              // pointer aliasing, and it cannot be disabled.
              // The values being non-zero value makes deployment a bit more expensive,
              // but in exchange the refund on every call to nonReentrant will be lower in
              // amount. Since refunds are capped to a percentage of the total
              // transaction's gas, it is best to keep them low in cases like this one, to
              // increase the likelihood of the full refund coming into effect.
              uint256 private constant NOT_ENTERED = 1;
              uint256 private constant ENTERED = 2;
              /// @custom:storage-location erc7201:openzeppelin.storage.ReentrancyGuard
              struct ReentrancyGuardStorage {
                  uint256 _status;
              }
              // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ReentrancyGuard")) - 1)) & ~bytes32(uint256(0xff))
              bytes32 private constant ReentrancyGuardStorageLocation = 0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;
              function _getReentrancyGuardStorage() private pure returns (ReentrancyGuardStorage storage $) {
                  assembly {
                      $.slot := ReentrancyGuardStorageLocation
                  }
              }
              /**
               * @dev Unauthorized reentrant call.
               */
              error ReentrancyGuardReentrantCall();
              function __ReentrancyGuard_init() internal onlyInitializing {
                  __ReentrancyGuard_init_unchained();
              }
              function __ReentrancyGuard_init_unchained() internal onlyInitializing {
                  ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
                  $._status = NOT_ENTERED;
              }
              /**
               * @dev Prevents a contract from calling itself, directly or indirectly.
               * Calling a `nonReentrant` function from another `nonReentrant`
               * function is not supported. It is possible to prevent this from happening
               * by making the `nonReentrant` function external, and making it call a
               * `private` function that does the actual work.
               */
              modifier nonReentrant() {
                  _nonReentrantBefore();
                  _;
                  _nonReentrantAfter();
              }
              function _nonReentrantBefore() private {
                  ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
                  // On the first call to nonReentrant, _status will be NOT_ENTERED
                  if ($._status == ENTERED) {
                      revert ReentrancyGuardReentrantCall();
                  }
                  // Any calls to nonReentrant after this point will fail
                  $._status = ENTERED;
              }
              function _nonReentrantAfter() private {
                  ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
                  // By storing the original value once again, a refund is triggered (see
                  // https://eips.ethereum.org/EIPS/eip-2200)
                  $._status = NOT_ENTERED;
              }
              /**
               * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
               * `nonReentrant` function in the call stack.
               */
              function _reentrancyGuardEntered() internal view returns (bool) {
                  ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
                  return $._status == ENTERED;
              }
          }
          // SPDX-License_Identifier: Apache-2.0
          pragma solidity 0.8.21;
          /// @title Cross-Chain Messaging interface
          /// @dev Allows seamless interchain messaging.
          /// @author Sujith Somraaj (extended by Eclipse Labs)
          /// Note: Based on EIP-6170 with the minor modifications (See Mailbox.md)
          interface IMailbox {
              /// @dev This emits when a cross-chain message is sent.
              /// Note: MessageSent MUST trigger when a message is sent, including zero bytes transfers.
              event MessageSent(bytes to, bytes toChainId, bytes message, bytes extraData);
              /// @dev This emits when a cross-chain message is received.
              /// MessageReceived MUST trigger on any successful call to receiveMessage
              event MessageReceived(bytes from, bytes fromChainId, bytes message, bytes extraData);
              /// @notice Sends a message to another blockchain through the trusted relayer
              /// @dev Sends an encoded message to a specified receiver on the target chain using a trusted relayer.
              /// @param chainId_ is the address of the receiver.
              /// @param receiver_ is the address of the receiver.
              /// @param message_ is the arbitrary message to be delivered.
              /// @param data_ is the address of the receiver.
              function sendMessage(bytes memory chainId_, bytes memory receiver_, bytes memory message_, bytes memory data_)
                  external
                  payable
                  returns (bool);
              /// @notice Receives a message from a sender on a different blockchain
              /// @dev Validates the sender, chainId, and ensures the message has not been replayed (checks nonce).
              /// @param chainId_ is the unique identifier of the sending blockchain.
              /// @param sender_ is the address of the sender.
              /// @param message_ is the arbitrary message sent by the sender.
              /// @param data_ is an additional parameter to be used for security purposes. E.g, can send nonce in layerzero.
              /// @return the status of message processing/storage.
              /// Note: sender validation (or) message validation should happen before processing the message.
              function receiveMessage(bytes memory chainId_, bytes memory sender_, bytes memory message_, bytes memory data_)
                  external
                  payable
                  returns (bool);
          }
          // SPDX-License_Identifier: UNLICENSED
          pragma solidity 0.8.21;
          /// @title Common Container
          /// @dev Contains modifiers for validating `ChainId`, `bytesArray` init status and address validation.
          abstract contract CommonContainer {
              function encodeChainId(bytes32 _chainId) internal pure returns (bytes memory) {
                  return abi.encode(_chainId);
              }
              function generateChainId(string memory _chainId) internal pure returns (bytes32) {
                  return keccak256(abi.encodePacked(_chainId));
              }
              function decodeChainId(bytes memory _encodedChainId) internal pure returns (bytes32) {
                  return abi.decode(_encodedChainId, (bytes32));
              }
              /// @dev Ensures that address is non-zero.
              modifier addressInitialized(address _address) {
                  require(_address != address(0), "CommonUtility: zero address");
                  _;
              }
              /// @dev Ensures that all addresses are non-zero.
              modifier addressArrayInitialized(address[] memory _addresses) {
                  require(_addresses.length > 0, "CommonUtility: addresses is empty");
                  for (uint256 i = 0; i < _addresses.length; i++) {
                      require(_addresses[i] != address(0), "CommonUtility: zero address in array");
                  }
                  _;
              }
              /// @dev Ensures that bytes have been initialized with data.
              modifier bytesInitialized(bytes memory _data) {
                  require(_data.length > 0, "CommonUtility: empty bytes");
                  _;
              }
              /// @dev Ensures that array of bytes have been initialized with data.
              modifier bytesArrayInitialized(bytes[] memory _data) {
                  require(_data.length > 0, "CommonUtility: empty bytes array");
                  for (uint256 i = 0; i < _data.length; i++) {
                      require(_data[i].length > 0, "CommonUtility: empty bytes in bytes array");
                  }
                  _;
              }
              /// @dev Ensures that bytes32 data is initialized with data.
              modifier bytes32Initialized(bytes32 _data) {
                  require(_data != bytes32(0), "CommonUtility: empty bytes32");
                  _;
              }
              /// @dev Ensures that an array of bytes32 data is initialized.
              modifier bytes32ArrayInitialized(bytes32[] memory _data) {
                  require(_data.length > 0, "CommonUtility: empty bytes32 array");
                  for (uint256 i = 0; i < _data.length; i++) {
                      require(_data[i] != bytes32(0), "CommonUtility: empty bytes32 in bytes32 array");
                  }
                  _;
              }
              /// @dev Ensures that bytes data is exactly equal to 32.
              modifier bytesLengthEq32(bytes memory _data) {
                  require(_data.length == 32, "CommonUtility: bytes must be 32 bytes long");
                  _;
              }
          }
          // SPDX-License_Identifier: UNLICENSED
          pragma solidity 0.8.21;
          /**
           * @title ISemVer
           * @dev Interface for SemVer versioning within smart contracts.
           */
          interface ISemVer {
              /**
               * @dev Struct to hold the version components.
               * @param major The major version component, incremented for incompatible API changes.
               * @param minor The minor version component, incremented for added functionality in a backwards-compatible manner.
               * @param patch The patch version component, incremented for backwards-compatible bug fixes.
               */
              struct Version {
                  uint8 major;
                  uint8 minor;
                  uint8 patch;
              }
              /**
               * @dev Returns the major, minor, and patch components of the version as a struct.
               * @return Version memory Returns the version details encapsulated in a Version struct.
               */
              function getVersionComponents() external pure returns (Version memory);
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC1822.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
           * proxy whose upgrades are fully controlled by the current implementation.
           */
          interface IERC1822Proxiable {
              /**
               * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
               * address.
               *
               * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
               * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
               * function revert if invoked through a proxy.
               */
              function proxiableUUID() external view returns (bytes32);
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Utils.sol)
          pragma solidity ^0.8.20;
          import {IBeacon} from "../beacon/IBeacon.sol";
          import {Address} from "../../utils/Address.sol";
          import {StorageSlot} from "../../utils/StorageSlot.sol";
          /**
           * @dev This abstract contract provides getters and event emitting update functions for
           * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
           */
          library ERC1967Utils {
              // We re-declare ERC-1967 events here because they can't be used directly from IERC1967.
              // This will be fixed in Solidity 0.8.21. At that point we should remove these events.
              /**
               * @dev Emitted when the implementation is upgraded.
               */
              event Upgraded(address indexed implementation);
              /**
               * @dev Emitted when the admin account has changed.
               */
              event AdminChanged(address previousAdmin, address newAdmin);
              /**
               * @dev Emitted when the beacon is changed.
               */
              event BeaconUpgraded(address indexed beacon);
              /**
               * @dev Storage slot with the address of the current implementation.
               * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1.
               */
              // solhint-disable-next-line private-vars-leading-underscore
              bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
              /**
               * @dev The `implementation` of the proxy is invalid.
               */
              error ERC1967InvalidImplementation(address implementation);
              /**
               * @dev The `admin` of the proxy is invalid.
               */
              error ERC1967InvalidAdmin(address admin);
              /**
               * @dev The `beacon` of the proxy is invalid.
               */
              error ERC1967InvalidBeacon(address beacon);
              /**
               * @dev An upgrade function sees `msg.value > 0` that may be lost.
               */
              error ERC1967NonPayable();
              /**
               * @dev Returns the current implementation address.
               */
              function getImplementation() internal view returns (address) {
                  return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;
              }
              /**
               * @dev Stores a new address in the EIP1967 implementation slot.
               */
              function _setImplementation(address newImplementation) private {
                  if (newImplementation.code.length == 0) {
                      revert ERC1967InvalidImplementation(newImplementation);
                  }
                  StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;
              }
              /**
               * @dev Performs implementation upgrade with additional setup call if data is nonempty.
               * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
               * to avoid stuck value in the contract.
               *
               * Emits an {IERC1967-Upgraded} event.
               */
              function upgradeToAndCall(address newImplementation, bytes memory data) internal {
                  _setImplementation(newImplementation);
                  emit Upgraded(newImplementation);
                  if (data.length > 0) {
                      Address.functionDelegateCall(newImplementation, data);
                  } else {
                      _checkNonPayable();
                  }
              }
              /**
               * @dev Storage slot with the admin of the contract.
               * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1.
               */
              // solhint-disable-next-line private-vars-leading-underscore
              bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
              /**
               * @dev Returns the current admin.
               *
               * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using
               * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
               * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
               */
              function getAdmin() internal view returns (address) {
                  return StorageSlot.getAddressSlot(ADMIN_SLOT).value;
              }
              /**
               * @dev Stores a new address in the EIP1967 admin slot.
               */
              function _setAdmin(address newAdmin) private {
                  if (newAdmin == address(0)) {
                      revert ERC1967InvalidAdmin(address(0));
                  }
                  StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;
              }
              /**
               * @dev Changes the admin of the proxy.
               *
               * Emits an {IERC1967-AdminChanged} event.
               */
              function changeAdmin(address newAdmin) internal {
                  emit AdminChanged(getAdmin(), newAdmin);
                  _setAdmin(newAdmin);
              }
              /**
               * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
               * This is the keccak-256 hash of "eip1967.proxy.beacon" subtracted by 1.
               */
              // solhint-disable-next-line private-vars-leading-underscore
              bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
              /**
               * @dev Returns the current beacon.
               */
              function getBeacon() internal view returns (address) {
                  return StorageSlot.getAddressSlot(BEACON_SLOT).value;
              }
              /**
               * @dev Stores a new beacon in the EIP1967 beacon slot.
               */
              function _setBeacon(address newBeacon) private {
                  if (newBeacon.code.length == 0) {
                      revert ERC1967InvalidBeacon(newBeacon);
                  }
                  StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;
                  address beaconImplementation = IBeacon(newBeacon).implementation();
                  if (beaconImplementation.code.length == 0) {
                      revert ERC1967InvalidImplementation(beaconImplementation);
                  }
              }
              /**
               * @dev Change the beacon and trigger a setup call if data is nonempty.
               * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
               * to avoid stuck value in the contract.
               *
               * Emits an {IERC1967-BeaconUpgraded} event.
               *
               * CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since
               * it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for
               * efficiency.
               */
              function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {
                  _setBeacon(newBeacon);
                  emit BeaconUpgraded(newBeacon);
                  if (data.length > 0) {
                      Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
                  } else {
                      _checkNonPayable();
                  }
              }
              /**
               * @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract
               * if an upgrade doesn't perform an initialization call.
               */
              function _checkNonPayable() private {
                  if (msg.value > 0) {
                      revert ERC1967NonPayable();
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev External interface of AccessControl declared to support ERC165 detection.
           */
          interface IAccessControl {
              /**
               * @dev The `account` is missing a role.
               */
              error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
              /**
               * @dev The caller of a function is not the expected one.
               *
               * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
               */
              error AccessControlBadConfirmation();
              /**
               * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
               *
               * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
               * {RoleAdminChanged} not being emitted signaling this.
               */
              event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
              /**
               * @dev Emitted when `account` is granted `role`.
               *
               * `sender` is the account that originated the contract call, an admin role
               * bearer except when using {AccessControl-_setupRole}.
               */
              event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
              /**
               * @dev Emitted when `account` is revoked `role`.
               *
               * `sender` is the account that originated the contract call:
               *   - if using `revokeRole`, it is the admin role bearer
               *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
               */
              event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
              /**
               * @dev Returns `true` if `account` has been granted `role`.
               */
              function hasRole(bytes32 role, address account) external view returns (bool);
              /**
               * @dev Returns the admin role that controls `role`. See {grantRole} and
               * {revokeRole}.
               *
               * To change a role's admin, use {AccessControl-_setRoleAdmin}.
               */
              function getRoleAdmin(bytes32 role) external view returns (bytes32);
              /**
               * @dev Grants `role` to `account`.
               *
               * If `account` had not been already granted `role`, emits a {RoleGranted}
               * event.
               *
               * Requirements:
               *
               * - the caller must have ``role``'s admin role.
               */
              function grantRole(bytes32 role, address account) external;
              /**
               * @dev Revokes `role` from `account`.
               *
               * If `account` had been granted `role`, emits a {RoleRevoked} event.
               *
               * Requirements:
               *
               * - the caller must have ``role``'s admin role.
               */
              function revokeRole(bytes32 role, address account) external;
              /**
               * @dev Revokes `role` from the calling account.
               *
               * Roles are often managed via {grantRole} and {revokeRole}: this function's
               * purpose is to provide a mechanism for accounts to lose their privileges
               * if they are compromised (such as when a trusted device is misplaced).
               *
               * If the calling account had been granted `role`, emits a {RoleRevoked}
               * event.
               *
               * Requirements:
               *
               * - the caller must be `callerConfirmation`.
               */
              function renounceRole(bytes32 role, address callerConfirmation) external;
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
          pragma solidity ^0.8.20;
          import {Initializable} from "../proxy/utils/Initializable.sol";
          /**
           * @dev Provides information about the current execution context, including the
           * sender of the transaction and its data. While these are generally available
           * via msg.sender and msg.data, they should not be accessed in such a direct
           * manner, since when dealing with meta-transactions the account sending and
           * paying for execution may not be the actual sender (as far as an application
           * is concerned).
           *
           * This contract is only required for intermediate, library-like contracts.
           */
          abstract contract ContextUpgradeable is Initializable {
              function __Context_init() internal onlyInitializing {
              }
              function __Context_init_unchained() internal onlyInitializing {
              }
              function _msgSender() internal view virtual returns (address) {
                  return msg.sender;
              }
              function _msgData() internal view virtual returns (bytes calldata) {
                  return msg.data;
              }
              function _contextSuffixLength() internal view virtual returns (uint256) {
                  return 0;
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)
          pragma solidity ^0.8.20;
          import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
          import {Initializable} from "../../proxy/utils/Initializable.sol";
          /**
           * @dev Implementation of the {IERC165} interface.
           *
           * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
           * for the additional interface id that will be supported. For example:
           *
           * ```solidity
           * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
           *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
           * }
           * ```
           */
          abstract contract ERC165Upgradeable is Initializable, IERC165 {
              function __ERC165_init() internal onlyInitializing {
              }
              function __ERC165_init_unchained() internal onlyInitializing {
              }
              /**
               * @dev See {IERC165-supportsInterface}.
               */
              function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
                  return interfaceId == type(IERC165).interfaceId;
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev This is the interface that {BeaconProxy} expects of its beacon.
           */
          interface IBeacon {
              /**
               * @dev Must return an address that can be used as a delegate call target.
               *
               * {UpgradeableBeacon} will check that this address is a contract.
               */
              function implementation() external view returns (address);
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev Collection of functions related to the address type
           */
          library Address {
              /**
               * @dev The ETH balance of the account is not enough to perform the operation.
               */
              error AddressInsufficientBalance(address account);
              /**
               * @dev There's no code at `target` (it is not a contract).
               */
              error AddressEmptyCode(address target);
              /**
               * @dev A call to an address target failed. The target may have reverted.
               */
              error FailedInnerCall();
              /**
               * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
               * `recipient`, forwarding all available gas and reverting on errors.
               *
               * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
               * of certain opcodes, possibly making contracts go over the 2300 gas limit
               * imposed by `transfer`, making them unable to receive funds via
               * `transfer`. {sendValue} removes this limitation.
               *
               * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
               *
               * IMPORTANT: because control is transferred to `recipient`, care must be
               * taken to not create reentrancy vulnerabilities. Consider using
               * {ReentrancyGuard} or the
               * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
               */
              function sendValue(address payable recipient, uint256 amount) internal {
                  if (address(this).balance < amount) {
                      revert AddressInsufficientBalance(address(this));
                  }
                  (bool success, ) = recipient.call{value: amount}("");
                  if (!success) {
                      revert FailedInnerCall();
                  }
              }
              /**
               * @dev Performs a Solidity function call using a low level `call`. A
               * plain `call` is an unsafe replacement for a function call: use this
               * function instead.
               *
               * If `target` reverts with a revert reason or custom error, it is bubbled
               * up by this function (like regular Solidity function calls). However, if
               * the call reverted with no returned reason, this function reverts with a
               * {FailedInnerCall} error.
               *
               * Returns the raw returned data. To convert to the expected return value,
               * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
               *
               * Requirements:
               *
               * - `target` must be a contract.
               * - calling `target` with `data` must not revert.
               */
              function functionCall(address target, bytes memory data) internal returns (bytes memory) {
                  return functionCallWithValue(target, data, 0);
              }
              /**
               * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
               * but also transferring `value` wei to `target`.
               *
               * Requirements:
               *
               * - the calling contract must have an ETH balance of at least `value`.
               * - the called Solidity function must be `payable`.
               */
              function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
                  if (address(this).balance < value) {
                      revert AddressInsufficientBalance(address(this));
                  }
                  (bool success, bytes memory returndata) = target.call{value: value}(data);
                  return verifyCallResultFromTarget(target, success, returndata);
              }
              /**
               * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
               * but performing a static call.
               */
              function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
                  (bool success, bytes memory returndata) = target.staticcall(data);
                  return verifyCallResultFromTarget(target, success, returndata);
              }
              /**
               * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
               * but performing a delegate call.
               */
              function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
                  (bool success, bytes memory returndata) = target.delegatecall(data);
                  return verifyCallResultFromTarget(target, success, returndata);
              }
              /**
               * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
               * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
               * unsuccessful call.
               */
              function verifyCallResultFromTarget(
                  address target,
                  bool success,
                  bytes memory returndata
              ) internal view returns (bytes memory) {
                  if (!success) {
                      _revert(returndata);
                  } else {
                      // only check if target is a contract if the call was successful and the return data is empty
                      // otherwise we already know that it was a contract
                      if (returndata.length == 0 && target.code.length == 0) {
                          revert AddressEmptyCode(target);
                      }
                      return returndata;
                  }
              }
              /**
               * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
               * revert reason or with a default {FailedInnerCall} error.
               */
              function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
                  if (!success) {
                      _revert(returndata);
                  } else {
                      return returndata;
                  }
              }
              /**
               * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
               */
              function _revert(bytes memory returndata) private pure {
                  // Look for revert reason and bubble it up if present
                  if (returndata.length > 0) {
                      // The easiest way to bubble the revert reason is using memory via assembly
                      /// @solidity memory-safe-assembly
                      assembly {
                          let returndata_size := mload(returndata)
                          revert(add(32, returndata), returndata_size)
                      }
                  } else {
                      revert FailedInnerCall();
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol)
          // This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
          pragma solidity ^0.8.20;
          /**
           * @dev Library for reading and writing primitive types to specific storage slots.
           *
           * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
           * This library helps with reading and writing to such slots without the need for inline assembly.
           *
           * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
           *
           * Example usage to set ERC1967 implementation slot:
           * ```solidity
           * contract ERC1967 {
           *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
           *
           *     function _getImplementation() internal view returns (address) {
           *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
           *     }
           *
           *     function _setImplementation(address newImplementation) internal {
           *         require(newImplementation.code.length > 0);
           *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
           *     }
           * }
           * ```
           */
          library StorageSlot {
              struct AddressSlot {
                  address value;
              }
              struct BooleanSlot {
                  bool value;
              }
              struct Bytes32Slot {
                  bytes32 value;
              }
              struct Uint256Slot {
                  uint256 value;
              }
              struct StringSlot {
                  string value;
              }
              struct BytesSlot {
                  bytes value;
              }
              /**
               * @dev Returns an `AddressSlot` with member `value` located at `slot`.
               */
              function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
               */
              function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
               */
              function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
               */
              function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `StringSlot` with member `value` located at `slot`.
               */
              function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `StringSlot` representation of the string storage pointer `store`.
               */
              function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := store.slot
                  }
              }
              /**
               * @dev Returns an `BytesSlot` with member `value` located at `slot`.
               */
              function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
               */
              function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := store.slot
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev Interface of the ERC165 standard, as defined in the
           * https://eips.ethereum.org/EIPS/eip-165[EIP].
           *
           * Implementers can declare support of contract interfaces, which can then be
           * queried by others ({ERC165Checker}).
           *
           * For an implementation, see {ERC165}.
           */
          interface IERC165 {
              /**
               * @dev Returns true if this contract implements the interface defined by
               * `interfaceId`. See the corresponding
               * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
               * to learn more about how these ids are created.
               *
               * This function call must use less than 30 000 gas.
               */
              function supportsInterface(bytes4 interfaceId) external view returns (bool);
          }
          

          File 6 of 6: Treasury
          // SPDX-License_Identifier: UNLICENSED
          pragma solidity 0.8.21;
          import "openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol";
          import "openzeppelin-contracts-upgradeable/contracts/proxy/utils/UUPSUpgradeable.sol";
          import "openzeppelin-contracts-upgradeable/contracts/access/Ownable2StepUpgradeable.sol";
          import "openzeppelin-contracts-upgradeable/contracts/utils/ReentrancyGuardUpgradeable.sol";
          import "openzeppelin-contracts-upgradeable/contracts/utils/PausableUpgradeable.sol";
          import "./interfaces/ITreasury.sol";
          import "./CommonContainer.sol";
          import "./interfaces/ISemVer.sol";
          /// @title Treasury
          /// @dev Stores ether from the ether bridge or the owner and allows for emergency withdrawals by the owner.
          contract Treasury is
              ITreasury,
              ISemVer,
              CommonContainer,
              Initializable,
              Ownable2StepUpgradeable,
              PausableUpgradeable,
              ReentrancyGuardUpgradeable,
              UUPSUpgradeable
          {
              uint8 private constant MAJOR_VERSION = 1;
              uint8 private constant MINOR_VERSION = 0;
              uint8 private constant PATCH_VERSION = 0;
              /// @custom:storage-location erc7201:eclipse.treasury.v1
              struct StorageV1 {
                  address etherBridgeAddress;
              }
              // keccak256(abi.encode(uint256(keccak256("eclipse.treasury.v1")) - 1)) & ~bytes32(uint256(0xff))
              bytes32 private constant STORAGE_V1_LOCATION = 0x81159cb40e73093d0d223f2fb64aaf85cf8f1e0b1fd69939c1101cbd5855c900;
              function _getStorageV1() internal pure returns (StorageV1 storage $) {
                  assembly {
                      $.slot := STORAGE_V1_LOCATION
                  }
              }
              /// @dev Constructor that disables initializers
              /// @custom:oz-upgrades-unsafe-allow constructor
              constructor() {
                  _disableInitializers();
              }
              /// @dev Initializes the treasury contract, entry point for initialization
              /// @param etherBridgeAddress_ The address of the ether bridge contract.
              function initialize(address owner_, address etherBridgeAddress_)
                  public
                  addressInitialized(owner_)
                  addressInitialized(etherBridgeAddress_)
                  initializer
              {
                  __Ownable_init(owner_);
                  __Ownable2Step_init();
                  __Pausable_init();
                  __ReentrancyGuard_init();
                  __UUPSUpgradeable_init();
                  StorageV1 storage $ = _getStorageV1();
                  $.etherBridgeAddress = etherBridgeAddress_;
              }
              /// @dev Retrieves the constant version details of the smart contract.
              function getVersionComponents() public pure override returns (Version memory) {
                  return Version(MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION);
              }
              /// @dev Allows for emergency withdraws to owner.
              /// @param amount The amount of Ether (in wei) to withdraw.
              function emergencyWithdraw(uint256 amount) external virtual override onlyOwner nonReentrant {
                  require(address(this).balance >= amount, "Insufficient funds");
                  (bool success,) = msg.sender.call{value: amount}("");
                  require(success, "Failed to send Ether");
                  emit EmergencyTreasuryWithdraw(msg.sender, amount);
              }
              function pause() external virtual onlyOwner {
                  _pause();
              }
              function unpause() external virtual onlyOwner {
                  _unpause();
              }
              /// @dev Required by the OZ UUPS module
              function _authorizeUpgrade(address) internal view virtual override onlyOwner {}
              /// @dev Function to receive Ether, marked as virtual for future override
              receive() external payable virtual whenNotPaused {
                  StorageV1 storage $ = _getStorageV1();
                  require(msg.sender == $.etherBridgeAddress || msg.sender == owner(), "Unauthorized source");
                  emit TreasuryDeposit(msg.sender, msg.value);
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
           * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
           * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
           * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
           *
           * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
           * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
           * case an upgrade adds a module that needs to be initialized.
           *
           * For example:
           *
           * [.hljs-theme-light.nopadding]
           * ```solidity
           * contract MyToken is ERC20Upgradeable {
           *     function initialize() initializer public {
           *         __ERC20_init("MyToken", "MTK");
           *     }
           * }
           *
           * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
           *     function initializeV2() reinitializer(2) public {
           *         __ERC20Permit_init("MyToken");
           *     }
           * }
           * ```
           *
           * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
           * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
           *
           * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
           * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
           *
           * [CAUTION]
           * ====
           * Avoid leaving a contract uninitialized.
           *
           * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
           * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
           * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
           *
           * [.hljs-theme-light.nopadding]
           * ```
           * /// @custom:oz-upgrades-unsafe-allow constructor
           * constructor() {
           *     _disableInitializers();
           * }
           * ```
           * ====
           */
          abstract contract Initializable {
              /**
               * @dev Storage of the initializable contract.
               *
               * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
               * when using with upgradeable contracts.
               *
               * @custom:storage-location erc7201:openzeppelin.storage.Initializable
               */
              struct InitializableStorage {
                  /**
                   * @dev Indicates that the contract has been initialized.
                   */
                  uint64 _initialized;
                  /**
                   * @dev Indicates that the contract is in the process of being initialized.
                   */
                  bool _initializing;
              }
              // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
              bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
              /**
               * @dev The contract is already initialized.
               */
              error InvalidInitialization();
              /**
               * @dev The contract is not initializing.
               */
              error NotInitializing();
              /**
               * @dev Triggered when the contract has been initialized or reinitialized.
               */
              event Initialized(uint64 version);
              /**
               * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
               * `onlyInitializing` functions can be used to initialize parent contracts.
               *
               * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
               * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
               * production.
               *
               * Emits an {Initialized} event.
               */
              modifier initializer() {
                  // solhint-disable-next-line var-name-mixedcase
                  InitializableStorage storage $ = _getInitializableStorage();
                  // Cache values to avoid duplicated sloads
                  bool isTopLevelCall = !$._initializing;
                  uint64 initialized = $._initialized;
                  // Allowed calls:
                  // - initialSetup: the contract is not in the initializing state and no previous version was
                  //                 initialized
                  // - construction: the contract is initialized at version 1 (no reininitialization) and the
                  //                 current contract is just being deployed
                  bool initialSetup = initialized == 0 && isTopLevelCall;
                  bool construction = initialized == 1 && address(this).code.length == 0;
                  if (!initialSetup && !construction) {
                      revert InvalidInitialization();
                  }
                  $._initialized = 1;
                  if (isTopLevelCall) {
                      $._initializing = true;
                  }
                  _;
                  if (isTopLevelCall) {
                      $._initializing = false;
                      emit Initialized(1);
                  }
              }
              /**
               * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
               * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
               * used to initialize parent contracts.
               *
               * A reinitializer may be used after the original initialization step. This is essential to configure modules that
               * are added through upgrades and that require initialization.
               *
               * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
               * cannot be nested. If one is invoked in the context of another, execution will revert.
               *
               * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
               * a contract, executing them in the right order is up to the developer or operator.
               *
               * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
               *
               * Emits an {Initialized} event.
               */
              modifier reinitializer(uint64 version) {
                  // solhint-disable-next-line var-name-mixedcase
                  InitializableStorage storage $ = _getInitializableStorage();
                  if ($._initializing || $._initialized >= version) {
                      revert InvalidInitialization();
                  }
                  $._initialized = version;
                  $._initializing = true;
                  _;
                  $._initializing = false;
                  emit Initialized(version);
              }
              /**
               * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
               * {initializer} and {reinitializer} modifiers, directly or indirectly.
               */
              modifier onlyInitializing() {
                  _checkInitializing();
                  _;
              }
              /**
               * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
               */
              function _checkInitializing() internal view virtual {
                  if (!_isInitializing()) {
                      revert NotInitializing();
                  }
              }
              /**
               * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
               * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
               * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
               * through proxies.
               *
               * Emits an {Initialized} event the first time it is successfully executed.
               */
              function _disableInitializers() internal virtual {
                  // solhint-disable-next-line var-name-mixedcase
                  InitializableStorage storage $ = _getInitializableStorage();
                  if ($._initializing) {
                      revert InvalidInitialization();
                  }
                  if ($._initialized != type(uint64).max) {
                      $._initialized = type(uint64).max;
                      emit Initialized(type(uint64).max);
                  }
              }
              /**
               * @dev Returns the highest version that has been initialized. See {reinitializer}.
               */
              function _getInitializedVersion() internal view returns (uint64) {
                  return _getInitializableStorage()._initialized;
              }
              /**
               * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
               */
              function _isInitializing() internal view returns (bool) {
                  return _getInitializableStorage()._initializing;
              }
              /**
               * @dev Returns a pointer to the storage namespace.
               */
              // solhint-disable-next-line var-name-mixedcase
              function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
                  assembly {
                      $.slot := INITIALIZABLE_STORAGE
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/UUPSUpgradeable.sol)
          pragma solidity ^0.8.20;
          import {IERC1822Proxiable} from "@openzeppelin/contracts/interfaces/draft-IERC1822.sol";
          import {ERC1967Utils} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol";
          import {Initializable} from "./Initializable.sol";
          /**
           * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
           * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
           *
           * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
           * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
           * `UUPSUpgradeable` with a custom implementation of upgrades.
           *
           * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
           */
          abstract contract UUPSUpgradeable is Initializable, IERC1822Proxiable {
              /// @custom:oz-upgrades-unsafe-allow state-variable-immutable
              address private immutable __self = address(this);
              /**
               * @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgradeTo(address)`
               * and `upgradeToAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called,
               * while `upgradeToAndCall` will invoke the `receive` function if the second argument is the empty byte string.
               * If the getter returns `"5.0.0"`, only `upgradeToAndCall(address,bytes)` is present, and the second argument must
               * be the empty byte string if no function should be called, making it impossible to invoke the `receive` function
               * during an upgrade.
               */
              string public constant UPGRADE_INTERFACE_VERSION = "5.0.0";
              /**
               * @dev The call is from an unauthorized context.
               */
              error UUPSUnauthorizedCallContext();
              /**
               * @dev The storage `slot` is unsupported as a UUID.
               */
              error UUPSUnsupportedProxiableUUID(bytes32 slot);
              /**
               * @dev Check that the execution is being performed through a delegatecall call and that the execution context is
               * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
               * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
               * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
               * fail.
               */
              modifier onlyProxy() {
                  _checkProxy();
                  _;
              }
              /**
               * @dev Check that the execution is not being performed through a delegate call. This allows a function to be
               * callable on the implementing contract but not through proxies.
               */
              modifier notDelegated() {
                  _checkNotDelegated();
                  _;
              }
              function __UUPSUpgradeable_init() internal onlyInitializing {
              }
              function __UUPSUpgradeable_init_unchained() internal onlyInitializing {
              }
              /**
               * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
               * implementation. It is used to validate the implementation's compatibility when performing an upgrade.
               *
               * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
               * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
               * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
               */
              function proxiableUUID() external view virtual notDelegated returns (bytes32) {
                  return ERC1967Utils.IMPLEMENTATION_SLOT;
              }
              /**
               * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
               * encoded in `data`.
               *
               * Calls {_authorizeUpgrade}.
               *
               * Emits an {Upgraded} event.
               *
               * @custom:oz-upgrades-unsafe-allow-reachable delegatecall
               */
              function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {
                  _authorizeUpgrade(newImplementation);
                  _upgradeToAndCallUUPS(newImplementation, data);
              }
              /**
               * @dev Reverts if the execution is not performed via delegatecall or the execution
               * context is not of a proxy with an ERC1967-compliant implementation pointing to self.
               * See {_onlyProxy}.
               */
              function _checkProxy() internal view virtual {
                  if (
                      address(this) == __self || // Must be called through delegatecall
                      ERC1967Utils.getImplementation() != __self // Must be called through an active proxy
                  ) {
                      revert UUPSUnauthorizedCallContext();
                  }
              }
              /**
               * @dev Reverts if the execution is performed via delegatecall.
               * See {notDelegated}.
               */
              function _checkNotDelegated() internal view virtual {
                  if (address(this) != __self) {
                      // Must not be called through delegatecall
                      revert UUPSUnauthorizedCallContext();
                  }
              }
              /**
               * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
               * {upgradeToAndCall}.
               *
               * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
               *
               * ```solidity
               * function _authorizeUpgrade(address) internal onlyOwner {}
               * ```
               */
              function _authorizeUpgrade(address newImplementation) internal virtual;
              /**
               * @dev Performs an implementation upgrade with a security check for UUPS proxies, and additional setup call.
               *
               * As a security check, {proxiableUUID} is invoked in the new implementation, and the return value
               * is expected to be the implementation slot in ERC1967.
               *
               * Emits an {IERC1967-Upgraded} event.
               */
              function _upgradeToAndCallUUPS(address newImplementation, bytes memory data) private {
                  try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {
                      if (slot != ERC1967Utils.IMPLEMENTATION_SLOT) {
                          revert UUPSUnsupportedProxiableUUID(slot);
                      }
                      ERC1967Utils.upgradeToAndCall(newImplementation, data);
                  } catch {
                      // The implementation is not UUPS
                      revert ERC1967Utils.ERC1967InvalidImplementation(newImplementation);
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol)
          pragma solidity ^0.8.20;
          import {OwnableUpgradeable} from "./OwnableUpgradeable.sol";
          import {Initializable} from "../proxy/utils/Initializable.sol";
          /**
           * @dev Contract module which provides access control mechanism, where
           * there is an account (an owner) that can be granted exclusive access to
           * specific functions.
           *
           * The initial owner is specified at deployment time in the constructor for `Ownable`. This
           * can later be changed with {transferOwnership} and {acceptOwnership}.
           *
           * This module is used through inheritance. It will make available all functions
           * from parent (Ownable).
           */
          abstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {
              /// @custom:storage-location erc7201:openzeppelin.storage.Ownable2Step
              struct Ownable2StepStorage {
                  address _pendingOwner;
              }
              // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable2Step")) - 1)) & ~bytes32(uint256(0xff))
              bytes32 private constant Ownable2StepStorageLocation = 0x237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00;
              function _getOwnable2StepStorage() private pure returns (Ownable2StepStorage storage $) {
                  assembly {
                      $.slot := Ownable2StepStorageLocation
                  }
              }
              event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
              function __Ownable2Step_init() internal onlyInitializing {
              }
              function __Ownable2Step_init_unchained() internal onlyInitializing {
              }
              /**
               * @dev Returns the address of the pending owner.
               */
              function pendingOwner() public view virtual returns (address) {
                  Ownable2StepStorage storage $ = _getOwnable2StepStorage();
                  return $._pendingOwner;
              }
              /**
               * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
               * Can only be called by the current owner.
               */
              function transferOwnership(address newOwner) public virtual override onlyOwner {
                  Ownable2StepStorage storage $ = _getOwnable2StepStorage();
                  $._pendingOwner = newOwner;
                  emit OwnershipTransferStarted(owner(), newOwner);
              }
              /**
               * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
               * Internal function without access restriction.
               */
              function _transferOwnership(address newOwner) internal virtual override {
                  Ownable2StepStorage storage $ = _getOwnable2StepStorage();
                  delete $._pendingOwner;
                  super._transferOwnership(newOwner);
              }
              /**
               * @dev The new owner accepts the ownership transfer.
               */
              function acceptOwnership() public virtual {
                  address sender = _msgSender();
                  if (pendingOwner() != sender) {
                      revert OwnableUnauthorizedAccount(sender);
                  }
                  _transferOwnership(sender);
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)
          pragma solidity ^0.8.20;
          import {Initializable} from "../proxy/utils/Initializable.sol";
          /**
           * @dev Contract module that helps prevent reentrant calls to a function.
           *
           * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
           * available, which can be applied to functions to make sure there are no nested
           * (reentrant) calls to them.
           *
           * Note that because there is a single `nonReentrant` guard, functions marked as
           * `nonReentrant` may not call one another. This can be worked around by making
           * those functions `private`, and then adding `external` `nonReentrant` entry
           * points to them.
           *
           * TIP: If you would like to learn more about reentrancy and alternative ways
           * to protect against it, check out our blog post
           * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
           */
          abstract contract ReentrancyGuardUpgradeable is Initializable {
              // Booleans are more expensive than uint256 or any type that takes up a full
              // word because each write operation emits an extra SLOAD to first read the
              // slot's contents, replace the bits taken up by the boolean, and then write
              // back. This is the compiler's defense against contract upgrades and
              // pointer aliasing, and it cannot be disabled.
              // The values being non-zero value makes deployment a bit more expensive,
              // but in exchange the refund on every call to nonReentrant will be lower in
              // amount. Since refunds are capped to a percentage of the total
              // transaction's gas, it is best to keep them low in cases like this one, to
              // increase the likelihood of the full refund coming into effect.
              uint256 private constant NOT_ENTERED = 1;
              uint256 private constant ENTERED = 2;
              /// @custom:storage-location erc7201:openzeppelin.storage.ReentrancyGuard
              struct ReentrancyGuardStorage {
                  uint256 _status;
              }
              // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ReentrancyGuard")) - 1)) & ~bytes32(uint256(0xff))
              bytes32 private constant ReentrancyGuardStorageLocation = 0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;
              function _getReentrancyGuardStorage() private pure returns (ReentrancyGuardStorage storage $) {
                  assembly {
                      $.slot := ReentrancyGuardStorageLocation
                  }
              }
              /**
               * @dev Unauthorized reentrant call.
               */
              error ReentrancyGuardReentrantCall();
              function __ReentrancyGuard_init() internal onlyInitializing {
                  __ReentrancyGuard_init_unchained();
              }
              function __ReentrancyGuard_init_unchained() internal onlyInitializing {
                  ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
                  $._status = NOT_ENTERED;
              }
              /**
               * @dev Prevents a contract from calling itself, directly or indirectly.
               * Calling a `nonReentrant` function from another `nonReentrant`
               * function is not supported. It is possible to prevent this from happening
               * by making the `nonReentrant` function external, and making it call a
               * `private` function that does the actual work.
               */
              modifier nonReentrant() {
                  _nonReentrantBefore();
                  _;
                  _nonReentrantAfter();
              }
              function _nonReentrantBefore() private {
                  ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
                  // On the first call to nonReentrant, _status will be NOT_ENTERED
                  if ($._status == ENTERED) {
                      revert ReentrancyGuardReentrantCall();
                  }
                  // Any calls to nonReentrant after this point will fail
                  $._status = ENTERED;
              }
              function _nonReentrantAfter() private {
                  ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
                  // By storing the original value once again, a refund is triggered (see
                  // https://eips.ethereum.org/EIPS/eip-2200)
                  $._status = NOT_ENTERED;
              }
              /**
               * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
               * `nonReentrant` function in the call stack.
               */
              function _reentrancyGuardEntered() internal view returns (bool) {
                  ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
                  return $._status == ENTERED;
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/Pausable.sol)
          pragma solidity ^0.8.20;
          import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
          import {Initializable} from "../proxy/utils/Initializable.sol";
          /**
           * @dev Contract module which allows children to implement an emergency stop
           * mechanism that can be triggered by an authorized account.
           *
           * This module is used through inheritance. It will make available the
           * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
           * the functions of your contract. Note that they will not be pausable by
           * simply including this module, only once the modifiers are put in place.
           */
          abstract contract PausableUpgradeable is Initializable, ContextUpgradeable {
              /// @custom:storage-location erc7201:openzeppelin.storage.Pausable
              struct PausableStorage {
                  bool _paused;
              }
              // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Pausable")) - 1)) & ~bytes32(uint256(0xff))
              bytes32 private constant PausableStorageLocation = 0xcd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f03300;
              function _getPausableStorage() private pure returns (PausableStorage storage $) {
                  assembly {
                      $.slot := PausableStorageLocation
                  }
              }
              /**
               * @dev Emitted when the pause is triggered by `account`.
               */
              event Paused(address account);
              /**
               * @dev Emitted when the pause is lifted by `account`.
               */
              event Unpaused(address account);
              /**
               * @dev The operation failed because the contract is paused.
               */
              error EnforcedPause();
              /**
               * @dev The operation failed because the contract is not paused.
               */
              error ExpectedPause();
              /**
               * @dev Initializes the contract in unpaused state.
               */
              function __Pausable_init() internal onlyInitializing {
                  __Pausable_init_unchained();
              }
              function __Pausable_init_unchained() internal onlyInitializing {
                  PausableStorage storage $ = _getPausableStorage();
                  $._paused = false;
              }
              /**
               * @dev Modifier to make a function callable only when the contract is not paused.
               *
               * Requirements:
               *
               * - The contract must not be paused.
               */
              modifier whenNotPaused() {
                  _requireNotPaused();
                  _;
              }
              /**
               * @dev Modifier to make a function callable only when the contract is paused.
               *
               * Requirements:
               *
               * - The contract must be paused.
               */
              modifier whenPaused() {
                  _requirePaused();
                  _;
              }
              /**
               * @dev Returns true if the contract is paused, and false otherwise.
               */
              function paused() public view virtual returns (bool) {
                  PausableStorage storage $ = _getPausableStorage();
                  return $._paused;
              }
              /**
               * @dev Throws if the contract is paused.
               */
              function _requireNotPaused() internal view virtual {
                  if (paused()) {
                      revert EnforcedPause();
                  }
              }
              /**
               * @dev Throws if the contract is not paused.
               */
              function _requirePaused() internal view virtual {
                  if (!paused()) {
                      revert ExpectedPause();
                  }
              }
              /**
               * @dev Triggers stopped state.
               *
               * Requirements:
               *
               * - The contract must not be paused.
               */
              function _pause() internal virtual whenNotPaused {
                  PausableStorage storage $ = _getPausableStorage();
                  $._paused = true;
                  emit Paused(_msgSender());
              }
              /**
               * @dev Returns to normal state.
               *
               * Requirements:
               *
               * - The contract must be paused.
               */
              function _unpause() internal virtual whenPaused {
                  PausableStorage storage $ = _getPausableStorage();
                  $._paused = false;
                  emit Unpaused(_msgSender());
              }
          }
          // SPDX-License_Identifier: UNLICENSED
          pragma solidity 0.8.21;
          /// @title ITreasury
          /// @notice Interface for a treasury contract stores ether
          /// @dev This interface assumes the implementation will provide a fallback function to receive ether.
          interface ITreasury {
              /// @notice Emitted when ether is deposited into the treasury
              /// @param from The address of the sender who deposited ether
              /// @param amount The amount of ether deposited
              event TreasuryDeposit(address indexed from, uint256 amount);
              /// @notice Emitted when ether is withdrawn from the treasury during an emergency withdraw
              /// @param to The address to which ether was sent
              /// @param amount The amount of ether withdrawn
              event EmergencyTreasuryWithdraw(address indexed to, uint256 amount);
              /// @notice Withdraws an 'amount' of ether during emergencies
              /// @param amount The amount of ether to be sent
              function emergencyWithdraw(uint256 amount) external;
          }
          // SPDX-License_Identifier: UNLICENSED
          pragma solidity 0.8.21;
          /// @title Common Container
          /// @dev Contains modifiers for validating `ChainId`, `bytesArray` init status and address validation.
          abstract contract CommonContainer {
              function encodeChainId(bytes32 _chainId) internal pure returns (bytes memory) {
                  return abi.encode(_chainId);
              }
              function generateChainId(string memory _chainId) internal pure returns (bytes32) {
                  return keccak256(abi.encodePacked(_chainId));
              }
              function decodeChainId(bytes memory _encodedChainId) internal pure returns (bytes32) {
                  return abi.decode(_encodedChainId, (bytes32));
              }
              /// @dev Ensures that address is non-zero.
              modifier addressInitialized(address _address) {
                  require(_address != address(0), "CommonUtility: zero address");
                  _;
              }
              /// @dev Ensures that all addresses are non-zero.
              modifier addressArrayInitialized(address[] memory _addresses) {
                  require(_addresses.length > 0, "CommonUtility: addresses is empty");
                  for (uint256 i = 0; i < _addresses.length; i++) {
                      require(_addresses[i] != address(0), "CommonUtility: zero address in array");
                  }
                  _;
              }
              /// @dev Ensures that bytes have been initialized with data.
              modifier bytesInitialized(bytes memory _data) {
                  require(_data.length > 0, "CommonUtility: empty bytes");
                  _;
              }
              /// @dev Ensures that array of bytes have been initialized with data.
              modifier bytesArrayInitialized(bytes[] memory _data) {
                  require(_data.length > 0, "CommonUtility: empty bytes array");
                  for (uint256 i = 0; i < _data.length; i++) {
                      require(_data[i].length > 0, "CommonUtility: empty bytes in bytes array");
                  }
                  _;
              }
              /// @dev Ensures that bytes32 data is initialized with data.
              modifier bytes32Initialized(bytes32 _data) {
                  require(_data != bytes32(0), "CommonUtility: empty bytes32");
                  _;
              }
              /// @dev Ensures that an array of bytes32 data is initialized.
              modifier bytes32ArrayInitialized(bytes32[] memory _data) {
                  require(_data.length > 0, "CommonUtility: empty bytes32 array");
                  for (uint256 i = 0; i < _data.length; i++) {
                      require(_data[i] != bytes32(0), "CommonUtility: empty bytes32 in bytes32 array");
                  }
                  _;
              }
              /// @dev Ensures that bytes data is exactly equal to 32.
              modifier bytesLengthEq32(bytes memory _data) {
                  require(_data.length == 32, "CommonUtility: bytes must be 32 bytes long");
                  _;
              }
          }
          // SPDX-License_Identifier: UNLICENSED
          pragma solidity 0.8.21;
          /**
           * @title ISemVer
           * @dev Interface for SemVer versioning within smart contracts.
           */
          interface ISemVer {
              /**
               * @dev Struct to hold the version components.
               * @param major The major version component, incremented for incompatible API changes.
               * @param minor The minor version component, incremented for added functionality in a backwards-compatible manner.
               * @param patch The patch version component, incremented for backwards-compatible bug fixes.
               */
              struct Version {
                  uint8 major;
                  uint8 minor;
                  uint8 patch;
              }
              /**
               * @dev Returns the major, minor, and patch components of the version as a struct.
               * @return Version memory Returns the version details encapsulated in a Version struct.
               */
              function getVersionComponents() external pure returns (Version memory);
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC1822.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
           * proxy whose upgrades are fully controlled by the current implementation.
           */
          interface IERC1822Proxiable {
              /**
               * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
               * address.
               *
               * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
               * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
               * function revert if invoked through a proxy.
               */
              function proxiableUUID() external view returns (bytes32);
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Utils.sol)
          pragma solidity ^0.8.20;
          import {IBeacon} from "../beacon/IBeacon.sol";
          import {Address} from "../../utils/Address.sol";
          import {StorageSlot} from "../../utils/StorageSlot.sol";
          /**
           * @dev This abstract contract provides getters and event emitting update functions for
           * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
           */
          library ERC1967Utils {
              // We re-declare ERC-1967 events here because they can't be used directly from IERC1967.
              // This will be fixed in Solidity 0.8.21. At that point we should remove these events.
              /**
               * @dev Emitted when the implementation is upgraded.
               */
              event Upgraded(address indexed implementation);
              /**
               * @dev Emitted when the admin account has changed.
               */
              event AdminChanged(address previousAdmin, address newAdmin);
              /**
               * @dev Emitted when the beacon is changed.
               */
              event BeaconUpgraded(address indexed beacon);
              /**
               * @dev Storage slot with the address of the current implementation.
               * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1.
               */
              // solhint-disable-next-line private-vars-leading-underscore
              bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
              /**
               * @dev The `implementation` of the proxy is invalid.
               */
              error ERC1967InvalidImplementation(address implementation);
              /**
               * @dev The `admin` of the proxy is invalid.
               */
              error ERC1967InvalidAdmin(address admin);
              /**
               * @dev The `beacon` of the proxy is invalid.
               */
              error ERC1967InvalidBeacon(address beacon);
              /**
               * @dev An upgrade function sees `msg.value > 0` that may be lost.
               */
              error ERC1967NonPayable();
              /**
               * @dev Returns the current implementation address.
               */
              function getImplementation() internal view returns (address) {
                  return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;
              }
              /**
               * @dev Stores a new address in the EIP1967 implementation slot.
               */
              function _setImplementation(address newImplementation) private {
                  if (newImplementation.code.length == 0) {
                      revert ERC1967InvalidImplementation(newImplementation);
                  }
                  StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;
              }
              /**
               * @dev Performs implementation upgrade with additional setup call if data is nonempty.
               * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
               * to avoid stuck value in the contract.
               *
               * Emits an {IERC1967-Upgraded} event.
               */
              function upgradeToAndCall(address newImplementation, bytes memory data) internal {
                  _setImplementation(newImplementation);
                  emit Upgraded(newImplementation);
                  if (data.length > 0) {
                      Address.functionDelegateCall(newImplementation, data);
                  } else {
                      _checkNonPayable();
                  }
              }
              /**
               * @dev Storage slot with the admin of the contract.
               * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1.
               */
              // solhint-disable-next-line private-vars-leading-underscore
              bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
              /**
               * @dev Returns the current admin.
               *
               * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using
               * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
               * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
               */
              function getAdmin() internal view returns (address) {
                  return StorageSlot.getAddressSlot(ADMIN_SLOT).value;
              }
              /**
               * @dev Stores a new address in the EIP1967 admin slot.
               */
              function _setAdmin(address newAdmin) private {
                  if (newAdmin == address(0)) {
                      revert ERC1967InvalidAdmin(address(0));
                  }
                  StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;
              }
              /**
               * @dev Changes the admin of the proxy.
               *
               * Emits an {IERC1967-AdminChanged} event.
               */
              function changeAdmin(address newAdmin) internal {
                  emit AdminChanged(getAdmin(), newAdmin);
                  _setAdmin(newAdmin);
              }
              /**
               * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
               * This is the keccak-256 hash of "eip1967.proxy.beacon" subtracted by 1.
               */
              // solhint-disable-next-line private-vars-leading-underscore
              bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
              /**
               * @dev Returns the current beacon.
               */
              function getBeacon() internal view returns (address) {
                  return StorageSlot.getAddressSlot(BEACON_SLOT).value;
              }
              /**
               * @dev Stores a new beacon in the EIP1967 beacon slot.
               */
              function _setBeacon(address newBeacon) private {
                  if (newBeacon.code.length == 0) {
                      revert ERC1967InvalidBeacon(newBeacon);
                  }
                  StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;
                  address beaconImplementation = IBeacon(newBeacon).implementation();
                  if (beaconImplementation.code.length == 0) {
                      revert ERC1967InvalidImplementation(beaconImplementation);
                  }
              }
              /**
               * @dev Change the beacon and trigger a setup call if data is nonempty.
               * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected
               * to avoid stuck value in the contract.
               *
               * Emits an {IERC1967-BeaconUpgraded} event.
               *
               * CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since
               * it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for
               * efficiency.
               */
              function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {
                  _setBeacon(newBeacon);
                  emit BeaconUpgraded(newBeacon);
                  if (data.length > 0) {
                      Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
                  } else {
                      _checkNonPayable();
                  }
              }
              /**
               * @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract
               * if an upgrade doesn't perform an initialization call.
               */
              function _checkNonPayable() private {
                  if (msg.value > 0) {
                      revert ERC1967NonPayable();
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
          pragma solidity ^0.8.20;
          import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
          import {Initializable} from "../proxy/utils/Initializable.sol";
          /**
           * @dev Contract module which provides a basic access control mechanism, where
           * there is an account (an owner) that can be granted exclusive access to
           * specific functions.
           *
           * The initial owner is set to the address provided by the deployer. This can
           * later be changed with {transferOwnership}.
           *
           * This module is used through inheritance. It will make available the modifier
           * `onlyOwner`, which can be applied to your functions to restrict their use to
           * the owner.
           */
          abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
              /// @custom:storage-location erc7201:openzeppelin.storage.Ownable
              struct OwnableStorage {
                  address _owner;
              }
              // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable")) - 1)) & ~bytes32(uint256(0xff))
              bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;
              function _getOwnableStorage() private pure returns (OwnableStorage storage $) {
                  assembly {
                      $.slot := OwnableStorageLocation
                  }
              }
              /**
               * @dev The caller account is not authorized to perform an operation.
               */
              error OwnableUnauthorizedAccount(address account);
              /**
               * @dev The owner is not a valid owner account. (eg. `address(0)`)
               */
              error OwnableInvalidOwner(address owner);
              event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
              /**
               * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
               */
              function __Ownable_init(address initialOwner) internal onlyInitializing {
                  __Ownable_init_unchained(initialOwner);
              }
              function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {
                  if (initialOwner == address(0)) {
                      revert OwnableInvalidOwner(address(0));
                  }
                  _transferOwnership(initialOwner);
              }
              /**
               * @dev Throws if called by any account other than the owner.
               */
              modifier onlyOwner() {
                  _checkOwner();
                  _;
              }
              /**
               * @dev Returns the address of the current owner.
               */
              function owner() public view virtual returns (address) {
                  OwnableStorage storage $ = _getOwnableStorage();
                  return $._owner;
              }
              /**
               * @dev Throws if the sender is not the owner.
               */
              function _checkOwner() internal view virtual {
                  if (owner() != _msgSender()) {
                      revert OwnableUnauthorizedAccount(_msgSender());
                  }
              }
              /**
               * @dev Leaves the contract without owner. It will not be possible to call
               * `onlyOwner` functions. Can only be called by the current owner.
               *
               * NOTE: Renouncing ownership will leave the contract without an owner,
               * thereby disabling any functionality that is only available to the owner.
               */
              function renounceOwnership() public virtual onlyOwner {
                  _transferOwnership(address(0));
              }
              /**
               * @dev Transfers ownership of the contract to a new account (`newOwner`).
               * Can only be called by the current owner.
               */
              function transferOwnership(address newOwner) public virtual onlyOwner {
                  if (newOwner == address(0)) {
                      revert OwnableInvalidOwner(address(0));
                  }
                  _transferOwnership(newOwner);
              }
              /**
               * @dev Transfers ownership of the contract to a new account (`newOwner`).
               * Internal function without access restriction.
               */
              function _transferOwnership(address newOwner) internal virtual {
                  OwnableStorage storage $ = _getOwnableStorage();
                  address oldOwner = $._owner;
                  $._owner = newOwner;
                  emit OwnershipTransferred(oldOwner, newOwner);
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
          pragma solidity ^0.8.20;
          import {Initializable} from "../proxy/utils/Initializable.sol";
          /**
           * @dev Provides information about the current execution context, including the
           * sender of the transaction and its data. While these are generally available
           * via msg.sender and msg.data, they should not be accessed in such a direct
           * manner, since when dealing with meta-transactions the account sending and
           * paying for execution may not be the actual sender (as far as an application
           * is concerned).
           *
           * This contract is only required for intermediate, library-like contracts.
           */
          abstract contract ContextUpgradeable is Initializable {
              function __Context_init() internal onlyInitializing {
              }
              function __Context_init_unchained() internal onlyInitializing {
              }
              function _msgSender() internal view virtual returns (address) {
                  return msg.sender;
              }
              function _msgData() internal view virtual returns (bytes calldata) {
                  return msg.data;
              }
              function _contextSuffixLength() internal view virtual returns (uint256) {
                  return 0;
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev This is the interface that {BeaconProxy} expects of its beacon.
           */
          interface IBeacon {
              /**
               * @dev Must return an address that can be used as a delegate call target.
               *
               * {UpgradeableBeacon} will check that this address is a contract.
               */
              function implementation() external view returns (address);
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
          pragma solidity ^0.8.20;
          /**
           * @dev Collection of functions related to the address type
           */
          library Address {
              /**
               * @dev The ETH balance of the account is not enough to perform the operation.
               */
              error AddressInsufficientBalance(address account);
              /**
               * @dev There's no code at `target` (it is not a contract).
               */
              error AddressEmptyCode(address target);
              /**
               * @dev A call to an address target failed. The target may have reverted.
               */
              error FailedInnerCall();
              /**
               * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
               * `recipient`, forwarding all available gas and reverting on errors.
               *
               * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
               * of certain opcodes, possibly making contracts go over the 2300 gas limit
               * imposed by `transfer`, making them unable to receive funds via
               * `transfer`. {sendValue} removes this limitation.
               *
               * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
               *
               * IMPORTANT: because control is transferred to `recipient`, care must be
               * taken to not create reentrancy vulnerabilities. Consider using
               * {ReentrancyGuard} or the
               * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
               */
              function sendValue(address payable recipient, uint256 amount) internal {
                  if (address(this).balance < amount) {
                      revert AddressInsufficientBalance(address(this));
                  }
                  (bool success, ) = recipient.call{value: amount}("");
                  if (!success) {
                      revert FailedInnerCall();
                  }
              }
              /**
               * @dev Performs a Solidity function call using a low level `call`. A
               * plain `call` is an unsafe replacement for a function call: use this
               * function instead.
               *
               * If `target` reverts with a revert reason or custom error, it is bubbled
               * up by this function (like regular Solidity function calls). However, if
               * the call reverted with no returned reason, this function reverts with a
               * {FailedInnerCall} error.
               *
               * Returns the raw returned data. To convert to the expected return value,
               * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
               *
               * Requirements:
               *
               * - `target` must be a contract.
               * - calling `target` with `data` must not revert.
               */
              function functionCall(address target, bytes memory data) internal returns (bytes memory) {
                  return functionCallWithValue(target, data, 0);
              }
              /**
               * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
               * but also transferring `value` wei to `target`.
               *
               * Requirements:
               *
               * - the calling contract must have an ETH balance of at least `value`.
               * - the called Solidity function must be `payable`.
               */
              function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
                  if (address(this).balance < value) {
                      revert AddressInsufficientBalance(address(this));
                  }
                  (bool success, bytes memory returndata) = target.call{value: value}(data);
                  return verifyCallResultFromTarget(target, success, returndata);
              }
              /**
               * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
               * but performing a static call.
               */
              function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
                  (bool success, bytes memory returndata) = target.staticcall(data);
                  return verifyCallResultFromTarget(target, success, returndata);
              }
              /**
               * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
               * but performing a delegate call.
               */
              function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
                  (bool success, bytes memory returndata) = target.delegatecall(data);
                  return verifyCallResultFromTarget(target, success, returndata);
              }
              /**
               * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
               * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
               * unsuccessful call.
               */
              function verifyCallResultFromTarget(
                  address target,
                  bool success,
                  bytes memory returndata
              ) internal view returns (bytes memory) {
                  if (!success) {
                      _revert(returndata);
                  } else {
                      // only check if target is a contract if the call was successful and the return data is empty
                      // otherwise we already know that it was a contract
                      if (returndata.length == 0 && target.code.length == 0) {
                          revert AddressEmptyCode(target);
                      }
                      return returndata;
                  }
              }
              /**
               * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
               * revert reason or with a default {FailedInnerCall} error.
               */
              function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
                  if (!success) {
                      _revert(returndata);
                  } else {
                      return returndata;
                  }
              }
              /**
               * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
               */
              function _revert(bytes memory returndata) private pure {
                  // Look for revert reason and bubble it up if present
                  if (returndata.length > 0) {
                      // The easiest way to bubble the revert reason is using memory via assembly
                      /// @solidity memory-safe-assembly
                      assembly {
                          let returndata_size := mload(returndata)
                          revert(add(32, returndata), returndata_size)
                      }
                  } else {
                      revert FailedInnerCall();
                  }
              }
          }
          // SPDX-License-Identifier: MIT
          // OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol)
          // This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
          pragma solidity ^0.8.20;
          /**
           * @dev Library for reading and writing primitive types to specific storage slots.
           *
           * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
           * This library helps with reading and writing to such slots without the need for inline assembly.
           *
           * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
           *
           * Example usage to set ERC1967 implementation slot:
           * ```solidity
           * contract ERC1967 {
           *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
           *
           *     function _getImplementation() internal view returns (address) {
           *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
           *     }
           *
           *     function _setImplementation(address newImplementation) internal {
           *         require(newImplementation.code.length > 0);
           *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
           *     }
           * }
           * ```
           */
          library StorageSlot {
              struct AddressSlot {
                  address value;
              }
              struct BooleanSlot {
                  bool value;
              }
              struct Bytes32Slot {
                  bytes32 value;
              }
              struct Uint256Slot {
                  uint256 value;
              }
              struct StringSlot {
                  string value;
              }
              struct BytesSlot {
                  bytes value;
              }
              /**
               * @dev Returns an `AddressSlot` with member `value` located at `slot`.
               */
              function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
               */
              function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
               */
              function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
               */
              function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `StringSlot` with member `value` located at `slot`.
               */
              function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `StringSlot` representation of the string storage pointer `store`.
               */
              function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := store.slot
                  }
              }
              /**
               * @dev Returns an `BytesSlot` with member `value` located at `slot`.
               */
              function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := slot
                  }
              }
              /**
               * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
               */
              function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
                  /// @solidity memory-safe-assembly
                  assembly {
                      r.slot := store.slot
                  }
              }
          }