creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {ContextUpgradeable} from \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n    /// @custom:storage-location erc7201:openzeppelin.storage.Ownable\n    struct OwnableStorage {\n        address _owner;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Ownable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;\n\n    function _getOwnableStorage() private pure returns (OwnableStorage storage $) {\n        assembly {\n            $.slot := OwnableStorageLocation\n        }\n    }\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    function __Ownable_init(address initialOwner) internal onlyInitializing {\n        __Ownable_init_unchained(initialOwner);\n    }\n\n    function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        OwnableStorage storage $ = _getOwnableStorage();\n        return $._owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        OwnableStorage storage $ = _getOwnableStorage();\n        address oldOwner = $._owner;\n        $._owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Storage of the initializable contract.\n     *\n     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\n     * when using with upgradeable contracts.\n     *\n     * @custom:storage-location erc7201:openzeppelin.storage.Initializable\n     */\n    struct InitializableStorage {\n        /**\n         * @dev Indicates that the contract has been initialized.\n         */\n        uint64 _initialized;\n        /**\n         * @dev Indicates that the contract is in the process of being initialized.\n         */\n        bool _initializing;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Initializable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\n\n    /**\n     * @dev The contract is already initialized.\n     */\n    error InvalidInitialization();\n\n    /**\n     * @dev The contract is not initializing.\n     */\n    error NotInitializing();\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint64 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\n     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\n     * production.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        // Cache values to avoid duplicated sloads\n        bool isTopLevelCall = !$._initializing;\n        uint64 initialized = $._initialized;\n\n        // Allowed calls:\n        // - initialSetup: the contract is not in the initializing state and no previous version was\n        //                 initialized\n        // - construction: the contract is initialized at version 1 (no reininitialization) and the\n        //                 current contract is just being deployed\n        bool initialSetup = initialized == 0 && isTopLevelCall;\n        bool construction = initialized == 1 && address(this).code.length == 0;\n\n        if (!initialSetup && !construction) {\n            revert InvalidInitialization();\n        }\n        $._initialized = 1;\n        if (isTopLevelCall) {\n            $._initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            $._initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint64 version) {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing || $._initialized >= version) {\n            revert InvalidInitialization();\n        }\n        $._initialized = version;\n        $._initializing = true;\n        _;\n        $._initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        _checkInitializing();\n        _;\n    }\n\n    /**\n     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\n     */\n    function _checkInitializing() internal view virtual {\n        if (!_isInitializing()) {\n            revert NotInitializing();\n        }\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing) {\n            revert InvalidInitialization();\n        }\n        if ($._initialized != type(uint64).max) {\n            $._initialized = type(uint64).max;\n            emit Initialized(type(uint64).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint64) {\n        return _getInitializableStorage()._initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _getInitializableStorage()._initializing;\n    }\n\n    /**\n     * @dev Returns a pointer to the storage namespace.\n     */\n    // solhint-disable-next-line var-name-mixedcase\n    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\n        assembly {\n            $.slot := INITIALIZABLE_STORAGE\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC1822Proxiable} from \"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\";\nimport {ERC1967Utils} from \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol\";\nimport {Initializable} from \"./Initializable.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n */\nabstract contract UUPSUpgradeable is Initializable, IERC1822Proxiable {\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    address private immutable __self = address(this);\n\n    /**\n     * @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgradeTo(address)`\n     * and `upgradeToAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called,\n     * while `upgradeToAndCall` will invoke the `receive` function if the second argument is the empty byte string.\n     * If the getter returns `\"5.0.0\"`, only `upgradeToAndCall(address,bytes)` is present, and the second argument must\n     * be the empty byte string if no function should be called, making it impossible to invoke the `receive` function\n     * during an upgrade.\n     */\n    string public constant UPGRADE_INTERFACE_VERSION = \"5.0.0\";\n\n    /**\n     * @dev The call is from an unauthorized context.\n     */\n    error UUPSUnauthorizedCallContext();\n\n    /**\n     * @dev The storage `slot` is unsupported as a UUID.\n     */\n    error UUPSUnsupportedProxiableUUID(bytes32 slot);\n\n    /**\n     * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n     * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\n     * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n     * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n     * fail.\n     */\n    modifier onlyProxy() {\n        _checkProxy();\n        _;\n    }\n\n    /**\n     * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n     * callable on the implementing contract but not through proxies.\n     */\n    modifier notDelegated() {\n        _checkNotDelegated();\n        _;\n    }\n\n    function __UUPSUpgradeable_init() internal onlyInitializing {\n    }\n\n    function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\n     * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n     */\n    function proxiableUUID() external view virtual notDelegated returns (bytes32) {\n        return ERC1967Utils.IMPLEMENTATION_SLOT;\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n     * encoded in `data`.\n     *\n     * Calls {_authorizeUpgrade}.\n     *\n     * Emits an {Upgraded} event.\n     *\n     * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n     */\n    function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\n        _authorizeUpgrade(newImplementation);\n        _upgradeToAndCallUUPS(newImplementation, data);\n    }\n\n    /**\n     * @dev Reverts if the execution is not performed via delegatecall or the execution\n     * context is not of a proxy with an ERC1967-compliant implementation pointing to self.\n     * See {_onlyProxy}.\n     */\n    function _checkProxy() internal view virtual {\n        if (\n            address(this) == __self || // Must be called through delegatecall\n            ERC1967Utils.getImplementation() != __self // Must be called through an active proxy\n        ) {\n            revert UUPSUnauthorizedCallContext();\n        }\n    }\n\n    /**\n     * @dev Reverts if the execution is performed via delegatecall.\n     * See {notDelegated}.\n     */\n    function _checkNotDelegated() internal view virtual {\n        if (address(this) != __self) {\n            // Must not be called through delegatecall\n            revert UUPSUnauthorizedCallContext();\n        }\n    }\n\n    /**\n     * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n     * {upgradeToAndCall}.\n     *\n     * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n     *\n     * ```solidity\n     * function _authorizeUpgrade(address) internal onlyOwner {}\n     * ```\n     */\n    function _authorizeUpgrade(address newImplementation) internal virtual;\n\n    /**\n     * @dev Performs an implementation upgrade with a security check for UUPS proxies, and additional setup call.\n     *\n     * As a security check, {proxiableUUID} is invoked in the new implementation, and the return value\n     * is expected to be the implementation slot in ERC1967.\n     *\n     * Emits an {IERC1967-Upgraded} event.\n     */\n    function _upgradeToAndCallUUPS(address newImplementation, bytes memory data) private {\n        try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n            if (slot != ERC1967Utils.IMPLEMENTATION_SLOT) {\n                revert UUPSUnsupportedProxiableUUID(slot);\n            }\n            ERC1967Utils.upgradeToAndCall(newImplementation, data);\n        } catch {\n            // The implementation is not UUPS\n            revert ERC1967Utils.ERC1967InvalidImplementation(newImplementation);\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"
      },
      "@openzeppelin/contracts/access/AccessControl.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControl} from \"./IAccessControl.sol\";\nimport {Context} from \"../utils/Context.sol\";\nimport {ERC165} from \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n    struct RoleData {\n        mapping(address account => bool) hasRole;\n        bytes32 adminRole;\n    }\n\n    mapping(bytes32 role => RoleData) private _roles;\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n    /**\n     * @dev Modifier that checks that an account has a specific role. Reverts\n     * with an {AccessControlUnauthorizedAccount} error including the required role.\n     */\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role);\n        _;\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view virtual returns (bool) {\n        return _roles[role].hasRole[account];\n    }\n\n    /**\n     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`\n     * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.\n     */\n    function _checkRole(bytes32 role) internal view virtual {\n        _checkRole(role, _msgSender());\n    }\n\n    /**\n     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`\n     * is missing `role`.\n     */\n    function _checkRole(bytes32 role, address account) internal view virtual {\n        if (!hasRole(role, account)) {\n            revert AccessControlUnauthorizedAccount(account, role);\n        }\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {\n        return _roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been revoked `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `callerConfirmation`.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function renounceRole(bytes32 role, address callerConfirmation) public virtual {\n        if (callerConfirmation != _msgSender()) {\n            revert AccessControlBadConfirmation();\n        }\n\n        _revokeRole(role, callerConfirmation);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        bytes32 previousAdminRole = getRoleAdmin(role);\n        _roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /**\n     * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual returns (bool) {\n        if (!hasRole(role, account)) {\n            _roles[role].hasRole[account] = true;\n            emit RoleGranted(role, account, _msgSender());\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {\n        if (hasRole(role, account)) {\n            _roles[role].hasRole[account] = false;\n            emit RoleRevoked(role, account, _msgSender());\n            return true;\n        } else {\n            return false;\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/access/IAccessControl.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n    /**\n     * @dev The `account` is missing a role.\n     */\n    error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);\n\n    /**\n     * @dev The caller of a function is not the expected one.\n     *\n     * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.\n     */\n    error AccessControlBadConfirmation();\n\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted signaling this.\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call, an admin role\n     * bearer except when using {AccessControl-_setupRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) external view returns (bool);\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `callerConfirmation`.\n     */\n    function renounceRole(bytes32 role, address callerConfirmation) external;\n}\n"
      },
      "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n    /**\n     * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n     * address.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy.\n     */\n    function proxiableUUID() external view returns (bytes32);\n}\n"
      },
      "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n    /**\n     * @dev Must return an address that can be used as a delegate call target.\n     *\n     * {UpgradeableBeacon} will check that this address is a contract.\n     */\n    function implementation() external view returns (address);\n}\n"
      },
      "@openzeppelin/contracts/proxy/Clones.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/Clones.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for\n * deploying minimal proxy contracts, also known as \"clones\".\n *\n * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies\n * > a minimal bytecode implementation that delegates all calls to a known, fixed address.\n *\n * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`\n * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the\n * deterministic method.\n */\nlibrary Clones {\n    /**\n     * @dev A clone instance deployment failed.\n     */\n    error ERC1167FailedCreateClone();\n\n    /**\n     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n     *\n     * This function uses the create opcode, which should never revert.\n     */\n    function clone(address implementation) internal returns (address instance) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n            // of the `implementation` address with the bytecode before the address.\n            mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n            // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n            mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n            instance := create(0, 0x09, 0x37)\n        }\n        if (instance == address(0)) {\n            revert ERC1167FailedCreateClone();\n        }\n    }\n\n    /**\n     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.\n     *\n     * This function uses the create2 opcode and a `salt` to deterministically deploy\n     * the clone. Using the same `implementation` and `salt` multiple time will revert, since\n     * the clones cannot be deployed twice at the same address.\n     */\n    function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes\n            // of the `implementation` address with the bytecode before the address.\n            mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))\n            // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.\n            mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))\n            instance := create2(0, 0x09, 0x37, salt)\n        }\n        if (instance == address(0)) {\n            revert ERC1167FailedCreateClone();\n        }\n    }\n\n    /**\n     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n     */\n    function predictDeterministicAddress(\n        address implementation,\n        bytes32 salt,\n        address deployer\n    ) internal pure returns (address predicted) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let ptr := mload(0x40)\n            mstore(add(ptr, 0x38), deployer)\n            mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)\n            mstore(add(ptr, 0x14), implementation)\n            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)\n            mstore(add(ptr, 0x58), salt)\n            mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))\n            predicted := keccak256(add(ptr, 0x43), 0x55)\n        }\n    }\n\n    /**\n     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.\n     */\n    function predictDeterministicAddress(\n        address implementation,\n        bytes32 salt\n    ) internal view returns (address predicted) {\n        return predictDeterministicAddress(implementation, salt, address(this));\n    }\n}\n"
      },
      "@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/ERC1967/ERC1967Utils.sol)\n\npragma solidity ^0.8.20;\n\nimport {IBeacon} from \"../beacon/IBeacon.sol\";\nimport {Address} from \"../../utils/Address.sol\";\nimport {StorageSlot} from \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n */\nlibrary ERC1967Utils {\n    // We re-declare ERC-1967 events here because they can't be used directly from IERC1967.\n    // This will be fixed in Solidity 0.8.21. At that point we should remove these events.\n    /**\n     * @dev Emitted when the implementation is upgraded.\n     */\n    event Upgraded(address indexed implementation);\n\n    /**\n     * @dev Emitted when the admin account has changed.\n     */\n    event AdminChanged(address previousAdmin, address newAdmin);\n\n    /**\n     * @dev Emitted when the beacon is changed.\n     */\n    event BeaconUpgraded(address indexed beacon);\n\n    /**\n     * @dev Storage slot with the address of the current implementation.\n     * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1.\n     */\n    // solhint-disable-next-line private-vars-leading-underscore\n    bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    /**\n     * @dev The `implementation` of the proxy is invalid.\n     */\n    error ERC1967InvalidImplementation(address implementation);\n\n    /**\n     * @dev The `admin` of the proxy is invalid.\n     */\n    error ERC1967InvalidAdmin(address admin);\n\n    /**\n     * @dev The `beacon` of the proxy is invalid.\n     */\n    error ERC1967InvalidBeacon(address beacon);\n\n    /**\n     * @dev An upgrade function sees `msg.value > 0` that may be lost.\n     */\n    error ERC1967NonPayable();\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function getImplementation() internal view returns (address) {\n        return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 implementation slot.\n     */\n    function _setImplementation(address newImplementation) private {\n        if (newImplementation.code.length == 0) {\n            revert ERC1967InvalidImplementation(newImplementation);\n        }\n        StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;\n    }\n\n    /**\n     * @dev Performs implementation upgrade with additional setup call if data is nonempty.\n     * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected\n     * to avoid stuck value in the contract.\n     *\n     * Emits an {IERC1967-Upgraded} event.\n     */\n    function upgradeToAndCall(address newImplementation, bytes memory data) internal {\n        _setImplementation(newImplementation);\n        emit Upgraded(newImplementation);\n\n        if (data.length > 0) {\n            Address.functionDelegateCall(newImplementation, data);\n        } else {\n            _checkNonPayable();\n        }\n    }\n\n    /**\n     * @dev Storage slot with the admin of the contract.\n     * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1.\n     */\n    // solhint-disable-next-line private-vars-leading-underscore\n    bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n    /**\n     * @dev Returns the current admin.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using\n     * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n     */\n    function getAdmin() internal view returns (address) {\n        return StorageSlot.getAddressSlot(ADMIN_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 admin slot.\n     */\n    function _setAdmin(address newAdmin) private {\n        if (newAdmin == address(0)) {\n            revert ERC1967InvalidAdmin(address(0));\n        }\n        StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {IERC1967-AdminChanged} event.\n     */\n    function changeAdmin(address newAdmin) internal {\n        emit AdminChanged(getAdmin(), newAdmin);\n        _setAdmin(newAdmin);\n    }\n\n    /**\n     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n     * This is the keccak-256 hash of \"eip1967.proxy.beacon\" subtracted by 1.\n     */\n    // solhint-disable-next-line private-vars-leading-underscore\n    bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n    /**\n     * @dev Returns the current beacon.\n     */\n    function getBeacon() internal view returns (address) {\n        return StorageSlot.getAddressSlot(BEACON_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new beacon in the EIP1967 beacon slot.\n     */\n    function _setBeacon(address newBeacon) private {\n        if (newBeacon.code.length == 0) {\n            revert ERC1967InvalidBeacon(newBeacon);\n        }\n\n        StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;\n\n        address beaconImplementation = IBeacon(newBeacon).implementation();\n        if (beaconImplementation.code.length == 0) {\n            revert ERC1967InvalidImplementation(beaconImplementation);\n        }\n    }\n\n    /**\n     * @dev Change the beacon and trigger a setup call if data is nonempty.\n     * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected\n     * to avoid stuck value in the contract.\n     *\n     * Emits an {IERC1967-BeaconUpgraded} event.\n     *\n     * CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since\n     * it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for\n     * efficiency.\n     */\n    function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {\n        _setBeacon(newBeacon);\n        emit BeaconUpgraded(newBeacon);\n\n        if (data.length > 0) {\n            Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n        } else {\n            _checkNonPayable();\n        }\n    }\n\n    /**\n     * @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract\n     * if an upgrade doesn't perform an initialization call.\n     */\n    function _checkNonPayable() private {\n        if (msg.value > 0) {\n            revert ERC1967NonPayable();\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/proxy/utils/Initializable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Storage of the initializable contract.\n     *\n     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\n     * when using with upgradeable contracts.\n     *\n     * @custom:storage-location erc7201:openzeppelin.storage.Initializable\n     */\n    struct InitializableStorage {\n        /**\n         * @dev Indicates that the contract has been initialized.\n         */\n        uint64 _initialized;\n        /**\n         * @dev Indicates that the contract is in the process of being initialized.\n         */\n        bool _initializing;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Initializable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\n\n    /**\n     * @dev The contract is already initialized.\n     */\n    error InvalidInitialization();\n\n    /**\n     * @dev The contract is not initializing.\n     */\n    error NotInitializing();\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint64 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\n     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\n     * production.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        // Cache values to avoid duplicated sloads\n        bool isTopLevelCall = !$._initializing;\n        uint64 initialized = $._initialized;\n\n        // Allowed calls:\n        // - initialSetup: the contract is not in the initializing state and no previous version was\n        //                 initialized\n        // - construction: the contract is initialized at version 1 (no reininitialization) and the\n        //                 current contract is just being deployed\n        bool initialSetup = initialized == 0 && isTopLevelCall;\n        bool construction = initialized == 1 && address(this).code.length == 0;\n\n        if (!initialSetup && !construction) {\n            revert InvalidInitialization();\n        }\n        $._initialized = 1;\n        if (isTopLevelCall) {\n            $._initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            $._initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint64 version) {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing || $._initialized >= version) {\n            revert InvalidInitialization();\n        }\n        $._initialized = version;\n        $._initializing = true;\n        _;\n        $._initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        _checkInitializing();\n        _;\n    }\n\n    /**\n     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\n     */\n    function _checkInitializing() internal view virtual {\n        if (!_isInitializing()) {\n            revert NotInitializing();\n        }\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing) {\n            revert InvalidInitialization();\n        }\n        if ($._initialized != type(uint64).max) {\n            $._initialized = type(uint64).max;\n            emit Initialized(type(uint64).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint64) {\n        return _getInitializableStorage()._initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _getInitializableStorage()._initializing;\n    }\n\n    /**\n     * @dev Returns a pointer to the storage namespace.\n     */\n    // solhint-disable-next-line var-name-mixedcase\n    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\n        assembly {\n            $.slot := INITIALIZABLE_STORAGE\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * ==== Security Considerations\n *\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\n * generally recommended is:\n *\n * ```solidity\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\n *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\n *     doThing(..., value);\n * }\n *\n * function doThing(..., uint256 value) public {\n *     token.safeTransferFrom(msg.sender, address(this), value);\n *     ...\n * }\n * ```\n *\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\n * {SafeERC20-safeTransferFrom}).\n *\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\n * contracts should have entry points that don't rely on permit.\n */\ninterface IERC20Permit {\n    /**\n     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n     * given ``owner``'s signed approval.\n     *\n     * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n     * ordering also apply here.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `deadline` must be a timestamp in the future.\n     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n     * over the EIP712-formatted function arguments.\n     * - the signature must use ``owner``'s current nonce (see {nonces}).\n     *\n     * For more information on the signature format, see the\n     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n     * section].\n     *\n     * CAUTION: See Security Considerations above.\n     */\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /**\n     * @dev Returns the current nonce for `owner`. This value must be\n     * included whenever a signature is generated for {permit}.\n     *\n     * Every successful call to {permit} increases ``owner``'s nonce by one. This\n     * prevents a signature from being used multiple times.\n     */\n    function nonces(address owner) external view returns (uint256);\n\n    /**\n     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"
      },
      "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\nimport {IERC20Permit} from \"../extensions/IERC20Permit.sol\";\nimport {Address} from \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    /**\n     * @dev An operation with an ERC20 token failed.\n     */\n    error SafeERC20FailedOperation(address token);\n\n    /**\n     * @dev Indicates a failed `decreaseAllowance` request.\n     */\n    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        forceApprove(token, spender, oldAllowance + value);\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\n     * value, non-reverting calls are assumed to be successful.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\n        unchecked {\n            uint256 currentAllowance = token.allowance(address(this), spender);\n            if (currentAllowance < requestedDecrease) {\n                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\n            }\n            forceApprove(token, spender, currentAllowance - requestedDecrease);\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));\n\n        if (!_callOptionalReturnBool(token, approvalCall)) {\n            _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));\n            _callOptionalReturn(token, approvalCall);\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data);\n        if (returndata.length != 0 && !abi.decode(returndata, (bool))) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n     */\n    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n        // and not revert is the subcall reverts.\n\n        (bool success, bytes memory returndata) = address(token).call(data);\n        return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev The ETH balance of the account is not enough to perform the operation.\n     */\n    error AddressInsufficientBalance(address account);\n\n    /**\n     * @dev There's no code at `target` (it is not a contract).\n     */\n    error AddressEmptyCode(address target);\n\n    /**\n     * @dev A call to an address target failed. The target may have reverted.\n     */\n    error FailedInnerCall();\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        if (address(this).balance < amount) {\n            revert AddressInsufficientBalance(address(this));\n        }\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        if (!success) {\n            revert FailedInnerCall();\n        }\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason or custom error, it is bubbled\n     * up by this function (like regular Solidity function calls). However, if\n     * the call reverted with no returned reason, this function reverts with a\n     * {FailedInnerCall} error.\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        if (address(this).balance < value) {\n            revert AddressInsufficientBalance(address(this));\n        }\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target\n     * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an\n     * unsuccessful call.\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata\n    ) internal view returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            // only check if target is a contract if the call was successful and the return data is empty\n            // otherwise we already know that it was a contract\n            if (returndata.length == 0 && target.code.length == 0) {\n                revert AddressEmptyCode(target);\n            }\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the\n     * revert reason or with a default {FailedInnerCall} error.\n     */\n    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.\n     */\n    function _revert(bytes memory returndata) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert FailedInnerCall();\n        }\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/introspection/ERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n */\nabstract contract ERC165 is IERC165 {\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/introspection/IERC165.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
      },
      "@openzeppelin/contracts/utils/ReentrancyGuard.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant NOT_ENTERED = 1;\n    uint256 private constant ENTERED = 2;\n\n    uint256 private _status;\n\n    /**\n     * @dev Unauthorized reentrant call.\n     */\n    error ReentrancyGuardReentrantCall();\n\n    constructor() {\n        _status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    function _nonReentrantBefore() private {\n        // On the first call to nonReentrant, _status will be NOT_ENTERED\n        if (_status == ENTERED) {\n            revert ReentrancyGuardReentrantCall();\n        }\n\n        // Any calls to nonReentrant after this point will fail\n        _status = ENTERED;\n    }\n\n    function _nonReentrantAfter() private {\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        _status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        return _status == ENTERED;\n    }\n}\n"
      },
      "@openzeppelin/contracts/utils/StorageSlot.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(newImplementation.code.length > 0);\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    struct StringSlot {\n        string value;\n    }\n\n    struct BytesSlot {\n        bytes value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n     */\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n     */\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := store.slot\n        }\n    }\n}\n"
      },
      "contracts/base/BaseAccessControlInitiable.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport {\n    CoreAccessControlInitiable,\n    CoreAccessControlConfig\n} from \"../core/CoreAccessControl/v1/CoreAccessControlInitiable.sol\";\nimport { CoreStopGuardian } from \"../core/CoreStopGuardian/v1/CoreStopGuardian.sol\";\n\nimport { CoreStopGuardianTrading } from \"../core/CoreStopGuardianTrading/v1/CoreStopGuardianTrading.sol\";\n\nabstract contract BaseAccessControlInitiable is CoreAccessControlInitiable, CoreStopGuardian, CoreStopGuardianTrading {\n    /**\n     * @dev\n     * Modifiers inherited from CoreAccessControl:\n     * onlyDefinitive\n     * onlyClients\n     * onlyWhitelisted\n     * onlyClientAdmin\n     * onlyDefinitiveAdmin\n     *\n     * Modifiers inherited from CoreStopGuardian:\n     * stopGuarded\n     */\n\n    function __BaseAccessControlInitiable__init(\n        CoreAccessControlConfig calldata coreAccessControlConfig\n    ) internal onlyInitializing {\n        __CoreAccessControlInitiable__init(coreAccessControlConfig);\n        GLOBAL_TRADE_GUARDIAN = 0xE3F35754954B0B77958C72b83EC5205971463064;\n    }\n\n    /**\n     * @dev Inherited from CoreStopGuardianTrading\n     */\n    function updateGlobalTradeGuardian(address _globalTradeGuardian) external override onlyAdmins {\n        return _updateGlobalTradeGuardian(_globalTradeGuardian);\n    }\n\n    /**\n     * @dev Inherited from CoreStopGuardian\n     */\n    function enableStopGuardian() public override onlyAdmins {\n        return _enableStopGuardian();\n    }\n\n    /**\n     * @dev Inherited from CoreStopGuardian\n     */\n    function disableStopGuardian() public override onlyClientAdmin {\n        return _disableStopGuardian();\n    }\n\n    /**\n     * @dev Inherited from CoreStopGuardianTrading\n     */\n\n    function disableTrading() public override onlyAdmins {\n        return _disableTrading();\n    }\n\n    /**\n     * @dev Inherited from CoreStopGuardianTrading\n     */\n    function enableTrading() public override onlyAdmins {\n        return _enableTrading();\n    }\n\n    /**\n     * @dev Inherited from CoreStopGuardianTrading\n     */\n    function disableWithdrawals() public override onlyClientAdmin {\n        return _disableWithdrawals();\n    }\n\n    /**\n     * @dev Inherited from CoreStopGuardianTrading\n     */\n    function enableWithdrawals() public override onlyClientAdmin {\n        return _enableWithdrawals();\n    }\n}\n"
      },
      "contracts/base/BaseFeesInitiable.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { BaseAccessControlInitiable } from \"./BaseAccessControlInitiable.sol\";\nimport { CoreFeesInitiable, CoreFeesConfig } from \"../core/CoreFees/v1/CoreFeesInitiable.sol\";\nimport { DefinitiveAssets, IERC20 } from \"../core/libraries/DefinitiveAssets.sol\";\nimport { DefinitiveConstants } from \"../core/libraries/DefinitiveConstants.sol\";\nimport { InvalidFeePercent } from \"../core/libraries/DefinitiveErrors.sol\";\n\nabstract contract BaseFeesInitiable is BaseAccessControlInitiable, CoreFeesInitiable {\n    using DefinitiveAssets for IERC20;\n\n    function __BaseFeesInitiable__init(CoreFeesConfig calldata coreFeesConfig) internal onlyInitializing {\n        __CoreFeesInitiable__init(coreFeesConfig);\n    }\n\n    function updateFeeAccount(address payable _feeAccount) public override onlyDefinitiveAdmin {\n        _updateFeeAccount(_feeAccount);\n    }\n\n    function _handleFeesOnAmount(address token, uint256 amount, uint256 feePct) internal returns (uint256 feeAmount) {\n        uint256 mMaxFeePCT = DefinitiveConstants.MAX_FEE_PCT;\n        if (feePct > mMaxFeePCT) {\n            revert InvalidFeePercent();\n        }\n\n        feeAmount = (amount * feePct) / mMaxFeePCT;\n        if (feeAmount == 0) {\n            return feeAmount;\n        }\n\n        if (token == DefinitiveConstants.NATIVE_ASSET_ADDRESS) {\n            DefinitiveAssets.safeTransferETH(FEE_ACCOUNT, feeAmount);\n        } else {\n            IERC20(token).safeTransfer(FEE_ACCOUNT, feeAmount);\n        }\n    }\n}\n"
      },
      "contracts/base/BaseNativeWrapper/v1/BaseNativeWrapperInitiable.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { BaseAccessControlInitiable } from \"../../BaseAccessControlInitiable.sol\";\nimport { IBaseNativeWrapperV1 } from \"./IBaseNativeWrapperV1.sol\";\nimport { ReentrancyGuard } from \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport { DefinitiveAssets, IERC20 } from \"../../../core/libraries/DefinitiveAssets.sol\";\n\nstruct BaseNativeWrapperConfig {\n    address payable wrappedNativeAssetAddress;\n}\n\nabstract contract BaseNativeWrapperInitiable is IBaseNativeWrapperV1, BaseAccessControlInitiable, ReentrancyGuard {\n    using DefinitiveAssets for IERC20;\n\n    address payable public WRAPPED_NATIVE_ASSET_ADDRESS;\n\n    function __BaseNativeWrapperInitiable__init(\n        BaseNativeWrapperConfig calldata baseNativeWrapperConfig\n    ) internal onlyInitializing {\n        WRAPPED_NATIVE_ASSET_ADDRESS = baseNativeWrapperConfig.wrappedNativeAssetAddress;\n    }\n\n    /**\n     * @notice Publicly accessible method to wrap native assets\n     * @param amount Amount of native assets to wrap\n     */\n    function wrap(uint256 amount) public onlyWhitelisted nonReentrant {\n        _wrap(amount);\n        emit NativeAssetWrap(_msgSender(), amount, true /* wrappingToNative */);\n    }\n\n    /**\n     * @notice Publicly accessible method to unwrap native assets\n     * @param amount Amount of tokenized assets to unwrap\n     */\n    function unwrap(uint256 amount) public onlyWhitelisted nonReentrant {\n        _unwrap(amount);\n        emit NativeAssetWrap(_msgSender(), amount, false /* wrappingToNative */);\n    }\n\n    /**\n     * @notice Publicly accessible method to unwrap full balance of native assets\n     * @dev Method is not marked as `nonReentrant` since it is a wrapper around `unwrap`\n     */\n    function unwrapAll() external onlyWhitelisted {\n        return unwrap(DefinitiveAssets.getBalance(WRAPPED_NATIVE_ASSET_ADDRESS));\n    }\n\n    /**\n     * @notice Internal method to wrap native assets\n     * @dev Override this method with native asset wrapping implementation\n     */\n    function _wrap(uint256 amount) internal virtual;\n\n    /**\n     * @notice Internal method to unwrap native assets\n     * @dev Override this method with native asset unwrapping implementation\n     */\n    function _unwrap(uint256 amount) internal virtual;\n}\n"
      },
      "contracts/base/BaseNativeWrapper/v1/IBaseNativeWrapperV1.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\ninterface IBaseNativeWrapperV1 {\n    event NativeAssetWrap(address actor, uint256 amount, bool indexed wrappingToNative);\n\n    function wrap(uint256 amount) external;\n\n    function unwrap(uint256 amount) external;\n\n    function unwrapAll() external;\n}\n"
      },
      "contracts/base/BaseSimpleSwapInitiable.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { BaseFeesInitiable } from \"./BaseFeesInitiable.sol\";\nimport {\n    CoreSimpleSwapInitiable,\n    CoreSimpleSwapConfig,\n    SwapPayload\n} from \"../core/CoreSimpleSwap/v1/CoreSimpleSwapInitiable.sol\";\nimport { ReentrancyGuard } from \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\nimport { DefinitiveConstants } from \"../core/libraries/DefinitiveConstants.sol\";\nimport { InvalidFeePercent, SlippageExceeded } from \"../core/libraries/DefinitiveErrors.sol\";\nimport { ICoreSwapHandlerV1 } from \"../core/CoreSwapHandler/ICoreSwapHandlerV1.sol\";\n\nabstract contract BaseSimpleSwapInitiable is BaseFeesInitiable, CoreSimpleSwapInitiable, ReentrancyGuard {\n    function __BaseSimpleSwapInitiable__init(\n        CoreSimpleSwapConfig calldata coreSimpleSwapConfig\n    ) internal onlyInitializing {\n        __CoreSimpleSwapInitiable__init(coreSimpleSwapConfig);\n    }\n\n    function enableSwapHandlers(address[] memory swapHandlers) public override onlyHandlerManager stopGuarded {\n        _updateSwapHandlers(swapHandlers, true);\n    }\n\n    function disableSwapHandlers(address[] memory swapHandlers) public override onlyAdmins {\n        _updateSwapHandlers(swapHandlers, false);\n    }\n\n    function swap(\n        SwapPayload[] memory payloads,\n        address outputToken,\n        uint256 amountOutMin,\n        uint256 feePct\n    ) external override onlyDefinitive nonReentrant stopGuarded tradingEnabled returns (uint256) {\n        if (feePct > DefinitiveConstants.MAX_FEE_PCT) {\n            revert InvalidFeePercent();\n        }\n\n        (uint256[] memory inputAmounts, uint256 outputAmount) = _swap(payloads, outputToken);\n        if (outputAmount < amountOutMin) {\n            revert SlippageExceeded(outputAmount, amountOutMin);\n        }\n\n        address[] memory swapTokens = new address[](payloads.length);\n        uint256 swapTokensLength = swapTokens.length;\n        for (uint256 i; i < swapTokensLength; ) {\n            swapTokens[i] = payloads[i].swapToken;\n            unchecked {\n                ++i;\n            }\n        }\n\n        uint256 feeAmount;\n        if (FEE_ACCOUNT != address(0) && outputAmount > 0 && feePct > 0) {\n            feeAmount = _handleFeesOnAmount(outputToken, outputAmount, feePct);\n        }\n        emit SwapHandled(swapTokens, inputAmounts, outputToken, outputAmount, feeAmount);\n\n        return outputAmount;\n    }\n\n    function _getEncodedSwapHandlerCalldata(\n        SwapPayload memory payload,\n        address expectedOutputToken,\n        bool isDelegateCall\n    ) internal pure override returns (bytes memory) {\n        bytes4 selector = isDelegateCall\n            ? ICoreSwapHandlerV1.swapDelegate.selector\n            : ICoreSwapHandlerV1.swapCall.selector;\n        ICoreSwapHandlerV1.SwapParams memory _params = ICoreSwapHandlerV1.SwapParams({\n            inputAssetAddress: payload.swapToken,\n            inputAmount: payload.amount,\n            outputAssetAddress: expectedOutputToken,\n            minOutputAmount: payload.amountOutMin,\n            data: payload.handlerCalldata,\n            signature: payload.signature\n        });\n        return abi.encodeWithSelector(selector, _params);\n    }\n}\n"
      },
      "contracts/core/CoreAccessControl/v1/CoreAccessControlInitiable.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { AccessControl as OZAccessControl } from \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport { ICoreAccessControlV1 } from \"./ICoreAccessControlV1.sol\";\nimport { AccountNotAdmin, AccountNotWhitelisted, AccountMissingRole } from \"../../libraries/DefinitiveErrors.sol\";\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\n\nstruct CoreAccessControlConfig {\n    address admin;\n    address definitiveAdmin;\n    address[] definitive;\n    address[] client;\n}\n\nabstract contract CoreAccessControlInitiable is ICoreAccessControlV1, OZAccessControl, Initializable {\n    // roles\n    bytes32 public constant ROLE_DEFINITIVE = keccak256(\"DEFINITIVE\");\n    bytes32 public constant ROLE_DEFINITIVE_ADMIN = keccak256(\"DEFINITIVE_ADMIN\");\n    bytes32 public constant ROLE_CLIENT = keccak256(\"CLIENT\");\n\n    // keccak256(\"HANDLER_MANAGER\")\n    bytes32 internal constant ROLE_HANDLER_MANAGER = 0xb2b11089d67559292849a1467a255e145c674dd358427860d2c8f589cfbd7aa2;\n\n    modifier onlyDefinitive() {\n        _checkRole(ROLE_DEFINITIVE);\n        _;\n    }\n    modifier onlyDefinitiveAdmin() {\n        _checkRole(ROLE_DEFINITIVE_ADMIN);\n        _;\n    }\n    modifier onlyClients() {\n        _checkRole(ROLE_CLIENT);\n        _;\n    }\n    modifier onlyClientAdmin() {\n        _checkRole(DEFAULT_ADMIN_ROLE);\n        _;\n    }\n\n    modifier onlyHandlerManager() {\n        _checkRole(ROLE_HANDLER_MANAGER);\n        _;\n    }\n    // default admin + definitive admin\n    modifier onlyAdmins() {\n        bool isAdmins = (hasRole(DEFAULT_ADMIN_ROLE, _msgSender()) || hasRole(ROLE_DEFINITIVE_ADMIN, _msgSender()));\n\n        if (!isAdmins) {\n            revert AccountNotAdmin(_msgSender());\n        }\n        _;\n    }\n    // client + definitive\n    modifier onlyWhitelisted() {\n        bool isWhitelisted = (hasRole(ROLE_CLIENT, _msgSender()) || hasRole(ROLE_DEFINITIVE, _msgSender()));\n\n        if (!isWhitelisted) {\n            revert AccountNotWhitelisted(_msgSender());\n        }\n        _;\n    }\n\n    function __CoreAccessControlInitiable__init(CoreAccessControlConfig calldata cfg) internal onlyInitializing {\n        // admin\n        _grantRole(DEFAULT_ADMIN_ROLE, cfg.admin);\n        _grantRole(ROLE_HANDLER_MANAGER, cfg.definitiveAdmin);\n        _grantRole(ROLE_HANDLER_MANAGER, cfg.admin);\n\n        // definitive admin\n        _grantRole(ROLE_DEFINITIVE_ADMIN, cfg.definitiveAdmin);\n        _setRoleAdmin(ROLE_DEFINITIVE_ADMIN, ROLE_DEFINITIVE_ADMIN);\n\n        // definitive\n        uint256 cfgDefinitiveLength = cfg.definitive.length;\n        for (uint256 i; i < cfgDefinitiveLength; ) {\n            _grantRole(ROLE_DEFINITIVE, cfg.definitive[i]);\n            unchecked {\n                ++i;\n            }\n        }\n        _setRoleAdmin(ROLE_DEFINITIVE, ROLE_DEFINITIVE_ADMIN);\n\n        // clients - implicit role admin is DEFAULT_ADMIN_ROLE\n        uint256 cfgClientLength = cfg.client.length;\n        for (uint256 i; i < cfgClientLength; ) {\n            _grantRole(ROLE_CLIENT, cfg.client[i]);\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    function _checkRole(bytes32 role, address account) internal view virtual override {\n        if (!hasRole(role, account)) {\n            revert AccountMissingRole(account, role);\n        }\n    }\n}\n"
      },
      "contracts/core/CoreAccessControl/v1/ICoreAccessControlV1.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { IAccessControl } from \"@openzeppelin/contracts/access/IAccessControl.sol\";\n\ninterface ICoreAccessControlV1 is IAccessControl {\n    function ROLE_CLIENT() external returns (bytes32);\n\n    function ROLE_DEFINITIVE() external returns (bytes32);\n\n    function ROLE_DEFINITIVE_ADMIN() external returns (bytes32);\n}\n"
      },
      "contracts/core/CoreFees/v1/CoreFeesInitiable.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { ICoreFeesV1 } from \"./ICoreFeesV1.sol\";\nimport { Context } from \"@openzeppelin/contracts/utils/Context.sol\";\n\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\n\nstruct CoreFeesConfig {\n    address payable feeAccount;\n}\n\nabstract contract CoreFeesInitiable is ICoreFeesV1, Context, Initializable {\n    address payable public FEE_ACCOUNT;\n\n    function __CoreFeesInitiable__init(CoreFeesConfig calldata coreFeesConfig) internal onlyInitializing {\n        FEE_ACCOUNT = coreFeesConfig.feeAccount;\n    }\n\n    function _updateFeeAccount(address payable feeAccount) internal {\n        FEE_ACCOUNT = feeAccount;\n        emit FeeAccountUpdated(_msgSender(), feeAccount);\n    }\n}\n"
      },
      "contracts/core/CoreFees/v1/ICoreFeesV1.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\ninterface ICoreFeesV1 {\n    event FeeAccountUpdated(address actor, address feeAccount);\n\n    function FEE_ACCOUNT() external returns (address payable);\n\n    function updateFeeAccount(address payable feeAccount) external;\n}\n"
      },
      "contracts/core/CoreSimpleSwap/v1/CoreSimpleSwapInitiable.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { ICoreSimpleSwapV1 } from \"./ICoreSimpleSwapV1.sol\";\nimport { DefinitiveAssets, IERC20 } from \"../../libraries/DefinitiveAssets.sol\";\nimport { Context } from \"@openzeppelin/contracts/utils/Context.sol\";\nimport { CallUtils } from \"../../../tools/BubbleReverts/BubbleReverts.sol\";\nimport { DefinitiveConstants } from \"../../libraries/DefinitiveConstants.sol\";\nimport {\n    InvalidSwapHandler,\n    InsufficientSwapTokenBalance,\n    SwapTokenIsOutputToken,\n    InvalidOutputToken,\n    InvalidReportedOutputAmount,\n    InvalidExecutedOutputAmount\n} from \"../../libraries/DefinitiveErrors.sol\";\nimport { Initializable } from \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport { SwapPayload } from \"./ICoreSimpleSwapV1.sol\";\n\nstruct CoreSimpleSwapConfig {\n    address[] swapHandlers;\n}\n\nabstract contract CoreSimpleSwapInitiable is ICoreSimpleSwapV1, Context, Initializable {\n    using DefinitiveAssets for IERC20;\n\n    /// @dev handler contract => enabled\n    mapping(address => bool) public _swapHandlers;\n\n    function __CoreSimpleSwapInitiable__init(\n        CoreSimpleSwapConfig calldata coreSimpleSwapConfig\n    ) internal onlyInitializing {\n        uint256 handlersLength = coreSimpleSwapConfig.swapHandlers.length;\n        for (uint256 i; i < handlersLength; ) {\n            _swapHandlers[coreSimpleSwapConfig.swapHandlers[i]] = true;\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    function enableSwapHandlers(address[] memory swapHandlers) public virtual;\n\n    function disableSwapHandlers(address[] memory swapHandlers) public virtual;\n\n    function _updateSwapHandlers(address[] memory swapHandlers, bool enabled) internal {\n        uint256 swapHandlersLength = swapHandlers.length;\n        for (uint256 i; i < swapHandlersLength; ) {\n            _swapHandlers[swapHandlers[i]] = enabled;\n            emit SwapHandlerUpdate(_msgSender(), swapHandlers[i], enabled);\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    function swap(\n        SwapPayload[] memory payloads,\n        address outputToken,\n        uint256 amountOutMin,\n        uint256 feePct\n    ) external virtual returns (uint256 outputAmount);\n\n    function _swap(\n        SwapPayload[] memory payloads,\n        address expectedOutputToken\n    ) internal returns (uint256[] memory inputTokenAmounts, uint256 outputTokenAmount) {\n        uint256 payloadsLength = payloads.length;\n        inputTokenAmounts = new uint256[](payloadsLength);\n        uint256 outputTokenBalanceStart = DefinitiveAssets.getBalance(expectedOutputToken);\n\n        for (uint256 i; i < payloadsLength; ) {\n            SwapPayload memory payload = payloads[i];\n\n            if (!_swapHandlers[payload.handler]) {\n                revert InvalidSwapHandler();\n            }\n\n            if (expectedOutputToken == payload.swapToken) {\n                revert SwapTokenIsOutputToken();\n            }\n\n            uint256 outputTokenBalanceBefore = DefinitiveAssets.getBalance(expectedOutputToken);\n            inputTokenAmounts[i] = DefinitiveAssets.getBalance(payload.swapToken);\n\n            (uint256 _outputAmount, address _outputToken) = _processSwap(payload, expectedOutputToken);\n\n            if (_outputToken != expectedOutputToken) {\n                revert InvalidOutputToken();\n            }\n            if (_outputAmount < payload.amountOutMin) {\n                revert InvalidReportedOutputAmount();\n            }\n            uint256 outputTokenBalanceAfter = DefinitiveAssets.getBalance(expectedOutputToken);\n\n            if ((outputTokenBalanceAfter - outputTokenBalanceBefore) < payload.amountOutMin) {\n                revert InvalidExecutedOutputAmount();\n            }\n\n            // Update `inputTokenAmounts` to reflect the amount of tokens actually swapped\n            inputTokenAmounts[i] -= DefinitiveAssets.getBalance(payload.swapToken);\n            unchecked {\n                ++i;\n            }\n        }\n\n        outputTokenAmount = DefinitiveAssets.getBalance(expectedOutputToken) - outputTokenBalanceStart;\n    }\n\n    function _processSwap(SwapPayload memory payload, address expectedOutputToken) private returns (uint256, address) {\n        // Override payload.amount with validated amount\n        payload.amount = _getValidatedPayloadAmount(payload);\n\n        bytes memory _calldata = _getEncodedSwapHandlerCalldata(payload, expectedOutputToken, payload.isDelegate);\n\n        bool _success;\n        bytes memory _returnBytes;\n        if (payload.isDelegate) {\n            // slither-disable-next-line controlled-delegatecall\n            (_success, _returnBytes) = payload.handler.delegatecall(_calldata);\n        } else {\n            uint256 msgValue = _prepareAssetsForNonDelegateHandlerCall(payload, payload.amount);\n            (_success, _returnBytes) = payload.handler.call{ value: msgValue }(_calldata);\n        }\n\n        if (!_success) {\n            CallUtils.revertFromReturnedData(_returnBytes);\n        }\n\n        return abi.decode(_returnBytes, (uint256, address));\n    }\n\n    function _getEncodedSwapHandlerCalldata(\n        SwapPayload memory payload,\n        address expectedOutputToken,\n        bool isDelegateCall\n    ) internal pure virtual returns (bytes memory);\n\n    function _getValidatedPayloadAmount(SwapPayload memory payload) private view returns (uint256 amount) {\n        uint256 balance = DefinitiveAssets.getBalance(payload.swapToken);\n\n        // Ensure balance > 0\n        DefinitiveAssets.validateAmount(balance);\n\n        amount = payload.amount;\n\n        if (amount != 0 && balance < amount) {\n            revert InsufficientSwapTokenBalance();\n        }\n\n        // maximum available balance if amount == 0\n        if (amount == 0) {\n            return balance;\n        }\n    }\n\n    function _prepareAssetsForNonDelegateHandlerCall(\n        SwapPayload memory payload,\n        uint256 amount\n    ) private returns (uint256 msgValue) {\n        if (payload.swapToken == DefinitiveConstants.NATIVE_ASSET_ADDRESS) {\n            return amount;\n        } else {\n            IERC20(payload.swapToken).resetAndSafeIncreaseAllowance(address(this), payload.handler, amount);\n        }\n    }\n}\n"
      },
      "contracts/core/CoreSimpleSwap/v1/ICoreSimpleSwapV1.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nstruct SwapPayload {\n    address handler;\n    uint256 amount; // set 0 for maximum available balance\n    address swapToken;\n    uint256 amountOutMin;\n    bool isDelegate;\n    bytes handlerCalldata;\n    bytes signature;\n}\n\ninterface ICoreSimpleSwapV1 {\n    event SwapHandlerUpdate(address actor, address swapHandler, bool isEnabled);\n    event SwapHandled(\n        address[] swapTokens,\n        uint256[] swapAmounts,\n        address outputToken,\n        uint256 outputAmount,\n        uint256 feeAmount\n    );\n\n    function enableSwapHandlers(address[] memory swapHandlers) external;\n\n    function disableSwapHandlers(address[] memory swapHandlers) external;\n\n    function swap(\n        SwapPayload[] memory payloads,\n        address outputToken,\n        uint256 amountOutMin,\n        uint256 feePct\n    ) external returns (uint256 outputAmount);\n}\n"
      },
      "contracts/core/CoreStopGuardian/v1/CoreStopGuardian.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { ICoreStopGuardianV1 } from \"./ICoreStopGuardianV1.sol\";\n\nimport { Context } from \"@openzeppelin/contracts/utils/Context.sol\";\nimport { StopGuardianEnabled } from \"../../libraries/DefinitiveErrors.sol\";\n\nabstract contract CoreStopGuardian is ICoreStopGuardianV1, Context {\n    bool public STOP_GUARDIAN_ENABLED;\n\n    // recommended for every public/external function\n    modifier stopGuarded() {\n        if (STOP_GUARDIAN_ENABLED) {\n            revert StopGuardianEnabled();\n        }\n\n        _;\n    }\n\n    function enableStopGuardian() public virtual;\n\n    function disableStopGuardian() public virtual;\n\n    function _enableStopGuardian() internal {\n        STOP_GUARDIAN_ENABLED = true;\n        emit StopGuardianUpdate(_msgSender(), true);\n    }\n\n    function _disableStopGuardian() internal {\n        STOP_GUARDIAN_ENABLED = false;\n        emit StopGuardianUpdate(_msgSender(), false);\n    }\n}\n"
      },
      "contracts/core/CoreStopGuardian/v1/ICoreStopGuardianV1.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\ninterface ICoreStopGuardianV1 {\n    event StopGuardianUpdate(address indexed actor, bool indexed isEnabled);\n\n    function STOP_GUARDIAN_ENABLED() external view returns (bool);\n\n    function enableStopGuardian() external;\n\n    function disableStopGuardian() external;\n}\n"
      },
      "contracts/core/CoreStopGuardianTrading/v1/CoreStopGuardianTrading.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { ICoreStopGuardianTradingV1 } from \"./ICoreStopGuardianTradingV1.sol\";\n\nimport { Context } from \"@openzeppelin/contracts/utils/Context.sol\";\nimport { WithdrawalsDisabled, TradingDisabled, GlobalStopGuardianEnabled } from \"../../libraries/DefinitiveErrors.sol\";\nimport { IGlobalGuardian } from \"../../../tools/GlobalGuardian/IGlobalGuardian.sol\";\n\nabstract contract CoreStopGuardianTrading is ICoreStopGuardianTradingV1, Context {\n    event GlobalTradeGuardianUpdate(address indexed globalTradeGuardian);\n\n    /// @notice For minimal clone strategies, this will be initialized as address(0)\n    /// It is expected that this value will be reinitialized in the `initialize` function\n    address public GLOBAL_TRADE_GUARDIAN = 0xE3F35754954B0B77958C72b83EC5205971463064;\n\n    bool public TRADING_GUARDIAN_TRADING_DISABLED;\n    bool public TRADING_GUARDIAN_WITHDRAWALS_DISABLED;\n\n    /// 0x49feb0371fc9661748a3d1bc01dbf9f5cdeb4102767351e1c6dd1f5d331acd6d\n    bytes32 internal constant GLOBAL_TRADING_HASH = keccak256(\"TRADING\");\n\n    modifier tradingEnabled() {\n        if (IGlobalGuardian(GLOBAL_TRADE_GUARDIAN).functionalityIsDisabled(GLOBAL_TRADING_HASH)) {\n            revert GlobalStopGuardianEnabled();\n        }\n\n        if (TRADING_GUARDIAN_TRADING_DISABLED) {\n            revert TradingDisabled();\n        }\n        _;\n    }\n\n    modifier withdrawalsEnabled() {\n        if (TRADING_GUARDIAN_WITHDRAWALS_DISABLED) {\n            revert WithdrawalsDisabled();\n        }\n        _;\n    }\n\n    function updateGlobalTradeGuardian(address _globalTradeGuardian) external virtual;\n\n    function disableTrading() public virtual;\n\n    function enableTrading() public virtual;\n\n    function disableWithdrawals() public virtual;\n\n    function enableWithdrawals() public virtual;\n\n    function _updateGlobalTradeGuardian(address _globalTradeGuardian) internal {\n        GLOBAL_TRADE_GUARDIAN = _globalTradeGuardian;\n        emit GlobalTradeGuardianUpdate(_globalTradeGuardian);\n    }\n\n    function _disableTrading() internal {\n        TRADING_GUARDIAN_TRADING_DISABLED = true;\n        emit TradingDisabledUpdate(_msgSender(), true);\n    }\n\n    function _enableTrading() internal {\n        delete TRADING_GUARDIAN_TRADING_DISABLED;\n        emit TradingDisabledUpdate(_msgSender(), false);\n    }\n\n    function _disableWithdrawals() internal {\n        TRADING_GUARDIAN_WITHDRAWALS_DISABLED = true;\n        emit WithdrawalsDisabledUpdate(_msgSender(), true);\n    }\n\n    function _enableWithdrawals() internal {\n        delete TRADING_GUARDIAN_WITHDRAWALS_DISABLED;\n        emit WithdrawalsDisabledUpdate(_msgSender(), false);\n    }\n}\n"
      },
      "contracts/core/CoreStopGuardianTrading/v1/ICoreStopGuardianTradingV1.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\ninterface ICoreStopGuardianTradingV1 {\n    event TradingDisabledUpdate(address indexed actor, bool indexed isEnabled);\n    event WithdrawalsDisabledUpdate(address indexed actor, bool indexed isEnabled);\n}\n"
      },
      "contracts/core/CoreSwapHandler/ICoreSwapHandlerV1.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\ninterface ICoreSwapHandlerV1 {\n    event Swap(\n        address indexed actor,\n        address indexed inputToken,\n        uint256 inputAmount,\n        address indexed outputToken,\n        uint256 outputAmount\n    );\n\n    struct SwapParams {\n        address inputAssetAddress;\n        uint256 inputAmount;\n        address outputAssetAddress;\n        uint256 minOutputAmount;\n        bytes data;\n        bytes signature;\n    }\n\n    function swapCall(SwapParams calldata params) external payable returns (uint256 amountOut, address outputAsset);\n\n    function swapDelegate(SwapParams calldata params) external payable returns (uint256 amountOut, address outputAsset);\n\n    function swapUsingValidatedPathCall(\n        SwapParams calldata params\n    ) external payable returns (uint256 amountOut, address outputAsset);\n}\n"
      },
      "contracts/core/libraries/DefinitiveAssets.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { IERC20, SafeERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SafeTransferLib } from \"solmate/src/utils/SafeTransferLib.sol\";\nimport { DefinitiveConstants } from \"./DefinitiveConstants.sol\";\n\nimport { InsufficientBalance, InvalidAmount, InvalidAmounts, InvalidERC20Address } from \"./DefinitiveErrors.sol\";\n\n/**\n * @notice Contains methods used throughout the Definitive contracts\n * @dev This file should only be used as an internal library.\n */\nlibrary DefinitiveAssets {\n    /**\n     * @dev Checks if an address is a valid ERC20 token\n     */\n    modifier onlyValidERC20(address erc20Token) {\n        if (address(erc20Token) == DefinitiveConstants.NATIVE_ASSET_ADDRESS) {\n            revert InvalidERC20Address();\n        }\n        _;\n    }\n\n    //////////////////////////////////////////////////\n    //////////////////////////////////////////////////\n    // ↓ ERC20 and Native Asset Methods ↓\n    //////////////////////////////////////////////////\n\n    /**\n     * @dev Gets the balance of an ERC20 token or native asset\n     */\n    function getBalance(address assetAddress) internal view returns (uint256) {\n        if (assetAddress == DefinitiveConstants.NATIVE_ASSET_ADDRESS) {\n            return address(this).balance;\n        } else {\n            return IERC20(assetAddress).balanceOf(address(this));\n        }\n    }\n\n    /**\n     * @dev internal function to validate balance is higher than a given amount for ERC20 and native assets\n     */\n    function validateBalance(address token, uint256 amount) internal view {\n        if (token == DefinitiveConstants.NATIVE_ASSET_ADDRESS) {\n            validateNativeBalance(amount);\n        } else {\n            validateERC20Balance(token, amount);\n        }\n    }\n\n    //////////////////////////////////////////////////\n    //////////////////////////////////////////////////\n    // ↓ Native Asset Methods ↓\n    //////////////////////////////////////////////////\n\n    /**\n     * @dev validates amount and balance, then uses SafeTransferLib to transfer native asset\n     */\n    function safeTransferETH(address recipient, uint256 amount) internal {\n        if (amount > 0) {\n            SafeTransferLib.safeTransferETH(payable(recipient), amount);\n        }\n    }\n\n    //////////////////////////////////////////////////\n    //////////////////////////////////////////////////\n    // ↓ ERC20 Methods ↓\n    //////////////////////////////////////////////////\n\n    /**\n     * @dev Resets and increases the allowance of a spender for an ERC20 token\n     */\n    function resetAndSafeIncreaseAllowance(\n        IERC20 token,\n        address owner,\n        address spender,\n        uint256 amount\n    ) internal onlyValidERC20(address(token)) {\n        return SafeERC20.forceApprove(token, spender, amount);\n    }\n\n    function safeTransfer(IERC20 token, address to, uint256 amount) internal onlyValidERC20(address(token)) {\n        if (amount > 0) {\n            SafeERC20.safeTransfer(token, to, amount);\n        }\n    }\n\n    function safeTransferFrom(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 amount\n    ) internal onlyValidERC20(address(token)) {\n        if (amount > 0) {\n            //slither-disable-next-line arbitrary-send-erc20\n            SafeERC20.safeTransferFrom(token, from, to, amount);\n        }\n    }\n\n    //////////////////////////////////////////////////\n    //////////////////////////////////////////////////\n    // ↓ Asset Amount Helper Methods ↓\n    //////////////////////////////////////////////////\n\n    /**\n     * @dev internal function to validate that amounts contains a value greater than zero\n     */\n    function validateAmounts(uint256[] calldata amounts) internal pure {\n        bool hasValidAmounts;\n        uint256 amountsLength = amounts.length;\n        for (uint256 i; i < amountsLength; ) {\n            if (amounts[i] > 0) {\n                hasValidAmounts = true;\n                break;\n            }\n            unchecked {\n                ++i;\n            }\n        }\n\n        if (!hasValidAmounts) {\n            revert InvalidAmounts();\n        }\n    }\n\n    /**\n     * @dev internal function to validate if native asset balance is higher than the amount requested\n     */\n    function validateNativeBalance(uint256 amount) internal view {\n        if (getBalance(DefinitiveConstants.NATIVE_ASSET_ADDRESS) < amount) {\n            revert InsufficientBalance();\n        }\n    }\n\n    /**\n     * @dev internal function to validate balance is higher than the amount requested for a token\n     */\n    function validateERC20Balance(address token, uint256 amount) internal view onlyValidERC20(token) {\n        if (getBalance(token) < amount) {\n            revert InsufficientBalance();\n        }\n    }\n\n    function validateAmount(uint256 _amount) internal pure {\n        if (_amount == 0) {\n            revert InvalidAmount();\n        }\n    }\n}\n"
      },
      "contracts/core/libraries/DefinitiveConstants.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\n/**\n * @notice Contains constants used throughout the Definitive contracts\n * @dev This file should only be used as an internal library.\n */\nlibrary DefinitiveConstants {\n    /**\n     * @notice Maximum fee percentage\n     */\n    uint256 internal constant MAX_FEE_PCT = 10000;\n\n    /**\n     * @notice Address to signify native assets\n     */\n    address internal constant NATIVE_ASSET_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n    /**\n     * @notice Maximum number of swaps allowed per block\n     */\n    uint8 internal constant MAX_SWAPS_PER_BLOCK = 25;\n\n    struct Assets {\n        uint256[] amounts;\n        address[] addresses;\n    }\n}\n"
      },
      "contracts/core/libraries/DefinitiveErrors.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\n/**\n * @notice Contains all errors used throughout the Definitive contracts\n * @dev This file should only be used as an internal library.\n * @dev When adding a new error, add alphabetically\n */\n\nerror AccountMissingRole(address _account, bytes32 _role);\nerror AccountNotAdmin(address);\nerror AccountNotWhitelisted(address);\nerror AddLiquidityFailed();\nerror AlreadyDeployed();\nerror AlreadyInitialized();\nerror BytecodeEmpty();\nerror DeadlineExceeded();\nerror DeployInitFailed();\nerror DeployFailed();\nerror BorrowFailed(uint256 errorCode);\nerror DecollateralizeFailed(uint256 errorCode);\nerror DepositMoreThanMax();\nerror EmptyBytecode();\nerror EnterAllFailed();\nerror EnforcedSafeLTV(uint256 invalidLTV);\nerror ExceededMaxDelta();\nerror ExceededMaxLTV();\nerror ExceededShareToAssetRatioDeltaThreshold();\nerror ExitAllFailed();\nerror ExitOneCoinFailed();\nerror GlobalStopGuardianEnabled();\nerror InitializeMarketsFailed();\nerror InputGreaterThanStaked();\nerror InsufficientBalance();\nerror InsufficientSwapTokenBalance();\nerror InvalidAddress();\nerror InvalidAmount();\nerror InvalidAmounts();\nerror InvalidCalldata();\nerror InvalidDestinationSwapper();\nerror InvalidERC20Address();\nerror InvalidExecutedOutputAmount();\nerror InvalidFeePercent();\nerror InvalidHandler();\nerror InvalidInputs();\nerror InvalidMsgValue();\nerror InvalidSingleHopSwap();\nerror InvalidMultiHopSwap();\nerror InvalidOutputToken();\nerror InvalidRedemptionRecipient(); // Used in cross-chain redeptions\nerror InvalidReportedOutputAmount();\nerror InvalidRewardsClaim();\nerror InvalidSignature();\nerror InvalidSignatureLength();\nerror InvalidSwapHandler();\nerror InvalidSwapInputAmount();\nerror InvalidSwapOutputToken();\nerror InvalidSwapPath();\nerror InvalidSwapPayload();\nerror InvalidSwapToken();\nerror MintMoreThanMax();\nerror MismatchedChainId();\nerror NativeAssetWrapFailed(bool wrappingToNative);\nerror NoSignatureVerificationSignerSet();\nerror RedeemMoreThanMax();\nerror RemoveLiquidityFailed();\nerror RepayDebtFailed();\nerror SafeHarborModeEnabled();\nerror SafeHarborRedemptionDisabled();\nerror SlippageExceeded(uint256 _outputAmount, uint256 _outputAmountMin);\nerror StakeFailed();\nerror SupplyFailed();\nerror StopGuardianEnabled();\nerror TradingDisabled();\nerror SwapDeadlineExceeded();\nerror SwapLimitExceeded();\nerror SwapTokenIsOutputToken();\nerror TransfersLimitExceeded();\nerror UnstakeFailed();\nerror UnauthenticatedFlashloan();\nerror UntrustedFlashLoanSender(address);\nerror WithdrawMoreThanMax();\nerror WithdrawalsDisabled();\nerror ZeroShares();\n"
      },
      "contracts/core/libraries/SignatureVerifier.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { InvalidSignature, InvalidSignatureLength } from \"./DefinitiveErrors.sol\";\n\nlibrary SignatureVerifier {\n    function verifySignature(\n        mapping(address => bool) storage validSigners,\n        bytes32 messageHash,\n        bytes memory signature\n    ) internal view {\n        bytes32 ethSignedMessageHash = getEthSignedMessageHash(messageHash);\n\n        address signer = recoverSigner(ethSignedMessageHash, signature);\n\n        if (!validSigners[signer]) {\n            revert InvalidSignature();\n        }\n    }\n\n    /* cSpell:disable */\n    function getEthSignedMessageHash(bytes32 messageHash) public pure returns (bytes32) {\n        /*\n            Signature is produced by signing a keccak256 hash with the following format:\n            \"\\x19Ethereum Signed Message\\n\" + len(msg) + msg\n        */\n        return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", messageHash));\n    }\n\n    /* cSpell:enable */\n\n    function recoverSigner(bytes32 ethSignedMessageHash, bytes memory signature) private pure returns (address signer) {\n        (bytes32 r, bytes32 s, uint8 v) = splitSignature(signature);\n        return ecrecover(ethSignedMessageHash, v, r, s);\n    }\n\n    // https://solidity-by-example.org/signature\n    function splitSignature(bytes memory sig) private pure returns (bytes32 r, bytes32 s, uint8 v) {\n        if (sig.length != 65) {\n            revert InvalidSignatureLength();\n        }\n\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            /*\n            First 32 bytes stores the length of the signature\n\n            add(sig, 32) = pointer of sig + 32\n            effectively, skips first 32 bytes of signature\n\n            mload(p) loads next 32 bytes starting at the memory address p into memory\n            */\n\n            // first 32 bytes, after the length prefix\n            r := mload(add(sig, 32))\n            // second 32 bytes\n            s := mload(add(sig, 64))\n            // final byte (first byte of the next 32 bytes)\n            v := byte(0, mload(add(sig, 96)))\n        }\n\n        // implicitly return (r, s, v)\n    }\n}\n"
      },
      "contracts/modules/native-asset-wrappers/WETH9NativeWrapperInitiable.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport {\n    BaseNativeWrapperInitiable,\n    BaseNativeWrapperConfig\n} from \"../../base/BaseNativeWrapper/v1/BaseNativeWrapperInitiable.sol\";\nimport { IWETH9 } from \"../../vendor/interfaces/IWETH9.sol\";\n\nabstract contract WETH9NativeWrapperInitiable is BaseNativeWrapperInitiable {\n    function __WETH9NativeWrapperInitiable__init(BaseNativeWrapperConfig calldata config) internal onlyInitializing {\n        __BaseNativeWrapperInitiable__init(config);\n    }\n\n    function _wrap(uint256 amount) internal override {\n        // slither-disable-next-line arbitrary-send-eth\n        IWETH9(WRAPPED_NATIVE_ASSET_ADDRESS).deposit{ value: amount }();\n    }\n\n    function _unwrap(uint256 amount) internal override {\n        IWETH9(WRAPPED_NATIVE_ASSET_ADDRESS).withdraw(amount);\n    }\n}\n"
      },
      "contracts/strategies/Trading/v2/ITradingVaultImplementation.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { CoreSimpleSwapConfig } from \"../../../base/BaseSimpleSwapInitiable.sol\";\nimport { CoreAccessControlConfig } from \"../../../base/BaseAccessControlInitiable.sol\";\nimport { CoreFeesConfig } from \"../../../base/BaseFeesInitiable.sol\";\nimport { BaseNativeWrapperConfig } from \"../../../modules/native-asset-wrappers/WETH9NativeWrapperInitiable.sol\";\n\ninterface ITradingVaultImplementation {\n    function initialize(\n        BaseNativeWrapperConfig calldata baseNativeWrapperConfig,\n        CoreAccessControlConfig calldata coreAccessControlConfig,\n        CoreSimpleSwapConfig calldata coreSimpleSwapConfig,\n        CoreFeesConfig calldata coreFeesConfig\n    ) external;\n}\n"
      },
      "contracts/strategies/Trading/v2/TradingVaultFactory.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { Clones } from \"@openzeppelin/contracts/proxy/Clones.sol\";\nimport {\n    ITradingVaultImplementation,\n    BaseNativeWrapperConfig,\n    CoreAccessControlConfig,\n    CoreSimpleSwapConfig,\n    CoreFeesConfig\n} from \"./ITradingVaultImplementation.sol\";\nimport { SignatureVerifier } from \"../../../core/libraries/SignatureVerifier.sol\";\n\nimport { DeadlineExceeded, MismatchedChainId, InvalidAddress } from \"../../../core/libraries/DefinitiveErrors.sol\";\nimport { OwnableUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { UUPSUpgradeable } from \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\n\nstruct DeployParams {\n    address tradingVaultImplementation;\n    uint256 chainId;\n    uint256 deadline;\n    bytes32 deploySalt;\n    BaseNativeWrapperConfig baseNativeWrapperConfig;\n    CoreAccessControlConfig coreAccessControlConfig;\n    CoreSimpleSwapConfig coreSimpleSwapConfig;\n    CoreFeesConfig coreFeesConfig;\n}\n\ncontract TradingVaultFactory is OwnableUpgradeable, UUPSUpgradeable {\n    using Clones for address;\n\n    event NewVaultDeploy(address sender, address vault, bytes32 salt);\n\n    event SignatureVerifierAdded(address signatureVerifier);\n\n    event SignatureVerifierRemoved(address signatureVerifier);\n\n    /// @custom:storage-location erc7201:openzeppelin.storage.TradingVaultFactory\n    struct TradingVaultFactoryStorage {\n        mapping(address => bool) isSignatureVerifier;\n    }\n\n    /* solhint-disable max-line-length */\n    /* keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.TradingVaultFactory\")) - 1)) & ~bytes32(uint256(0xff)) */\n    bytes32 private constant TradingVaultFactoryStorageLocation =\n        0x1e05315c660d2d2e3b92cca2a3c5f6e530c7e4414b0a08bd1d920d985b0e0300;\n\n    /* solhint-enable max-line-length */\n\n    function _getTradingVaultFactoryStorage() private pure returns (TradingVaultFactoryStorage storage $) {\n        assembly {\n            $.slot := TradingVaultFactoryStorageLocation\n        }\n    }\n\n    /// @notice Constructor on the implementation contract should call _disableInitializers()\n    /// @dev https://forum.openzeppelin.com/t/what-does-disableinitializers-function-mean/28730/2\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    function initialize(address _owner, address[] memory _initialVerifiers) external initializer {\n        __Ownable_init(_owner);\n        uint256 length = _initialVerifiers.length;\n        for (uint256 i = 0; i < length; ) {\n            _addSignatureVerifier(_initialVerifiers[i]);\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    function _authorizeUpgrade(address) internal override onlyOwner {}\n\n    function createVault(\n        address tradingVaultImplementation,\n        bytes32 salt,\n        BaseNativeWrapperConfig calldata baseNativeWrapperConfig,\n        CoreAccessControlConfig calldata coreAccessControlConfig,\n        CoreSimpleSwapConfig calldata coreSimpleSwapConfig,\n        CoreFeesConfig calldata coreFeesConfig\n    ) external payable {\n        bytes32 deploymentSalt = encodeSalt(msg.sender, salt);\n\n        address vault = tradingVaultImplementation.cloneDeterministic(deploymentSalt);\n\n        ITradingVaultImplementation(vault).initialize(\n            baseNativeWrapperConfig,\n            coreAccessControlConfig,\n            coreSimpleSwapConfig,\n            coreFeesConfig\n        );\n\n        emit NewVaultDeploy(msg.sender, vault, deploymentSalt);\n    }\n\n    function createVaultWithPermission(\n        DeployParams calldata deployParams,\n        bytes calldata authorizedSignature\n    ) external payable {\n        _verifyDeploymentParams(deployParams, authorizedSignature);\n\n        address vault = deployParams.tradingVaultImplementation.cloneDeterministic(deployParams.deploySalt);\n\n        ITradingVaultImplementation(vault).initialize(\n            deployParams.baseNativeWrapperConfig,\n            deployParams.coreAccessControlConfig,\n            deployParams.coreSimpleSwapConfig,\n            deployParams.coreFeesConfig\n        );\n\n        emit NewVaultDeploy(msg.sender, vault, deployParams.deploySalt);\n    }\n\n    function getVaultAddress(\n        address tradingVaultImplementation,\n        bytes32 deploymentSalt\n    ) external view returns (address) {\n        if (tradingVaultImplementation == address(0)) {\n            revert InvalidAddress();\n        }\n\n        return tradingVaultImplementation.predictDeterministicAddress(deploymentSalt);\n    }\n\n    function isSignatureVerifier(address account) external view returns (bool) {\n        TradingVaultFactoryStorage storage $ = _getTradingVaultFactoryStorage();\n\n        return $.isSignatureVerifier[account];\n    }\n\n    function addSignatureVerifier(address _signatureVerifier) public onlyOwner {\n        _addSignatureVerifier(_signatureVerifier);\n    }\n\n    function removeSignatureVerifier(address _signatureVerifier) public onlyOwner {\n        _removeSignatureVerifier(_signatureVerifier);\n    }\n\n    function _addSignatureVerifier(address _signatureVerifier) private {\n        if (_signatureVerifier == address(0)) {\n            revert InvalidAddress();\n        }\n        TradingVaultFactoryStorage storage $ = _getTradingVaultFactoryStorage();\n        $.isSignatureVerifier[_signatureVerifier] = true;\n        emit SignatureVerifierAdded(_signatureVerifier);\n    }\n\n    function _removeSignatureVerifier(address _signatureVerifier) private {\n        if (_signatureVerifier == address(0)) {\n            revert InvalidAddress();\n        }\n        TradingVaultFactoryStorage storage $ = _getTradingVaultFactoryStorage();\n        $.isSignatureVerifier[_signatureVerifier] = false;\n        emit SignatureVerifierRemoved(_signatureVerifier);\n    }\n\n    function _verifyDeploymentParams(DeployParams calldata deployParams, bytes calldata signature) private view {\n        if (deployParams.tradingVaultImplementation == address(0)) {\n            revert InvalidAddress();\n        }\n\n        if (deployParams.deadline < block.timestamp) {\n            revert DeadlineExceeded();\n        }\n\n        if (deployParams.chainId != block.chainid && deployParams.chainId != type(uint256).max) {\n            revert MismatchedChainId();\n        }\n        TradingVaultFactoryStorage storage $ = _getTradingVaultFactoryStorage();\n\n        SignatureVerifier.verifySignature($.isSignatureVerifier, encodeDeploymentParams(deployParams), signature);\n    }\n\n    function encodeSalt(address sender, bytes32 deploymentSalt) public pure returns (bytes32) {\n        return keccak256(abi.encode(deploymentSalt, sender));\n    }\n\n    function encodeDeploymentParams(DeployParams calldata deployParams) public pure returns (bytes32) {\n        return keccak256(abi.encode(deployParams));\n    }\n}\n"
      },
      "contracts/tools/BubbleReverts/BubbleReverts.sol": {
        "content": "// SPDX-License-Identifier: AGPLv3\npragma solidity >=0.8.20;\n\nimport { InvalidCalldata } from \"../../core/libraries/DefinitiveErrors.sol\";\n\n/**\n * @title Call utilities library that is absent from the OpenZeppelin\n * @author Superfluid\n * Forked from\n * https://github.com/superfluid-finance/protocol-monorepo/blob\n * /d473b4876a689efb3bbb05552040bafde364a8b2/packages/ethereum-contracts/contracts/libs/CallUtils.sol\n * (Separated by 2 lines to prevent going over 120 character per line limit)\n */\nlibrary CallUtils {\n    /// @dev Bubble up the revert from the returnedData (supports Panic, Error & Custom Errors)\n    /// @notice This is needed in order to provide some human-readable revert message from a call\n    /// @param returnedData Response of the call\n    function revertFromReturnedData(bytes memory returnedData) internal pure {\n        if (returnedData.length < 4) {\n            // case 1: catch all\n            revert(\"CallUtils: target revert()\"); // solhint-disable-line custom-errors\n        } else {\n            bytes4 errorSelector;\n            // solhint-disable-next-line no-inline-assembly\n            assembly {\n                errorSelector := mload(add(returnedData, 0x20))\n            }\n            if (errorSelector == bytes4(0x4e487b71) /* `seth sig \"Panic(uint256)\"` */) {\n                // case 2: Panic(uint256) (Defined since 0.8.0)\n                // solhint-disable-next-line max-line-length\n                // ref: https://docs.soliditylang.org/en/v0.8.0/control-structures.html#panic-via-assert-and-error-via-require)\n                string memory reason = \"CallUtils: target panicked: 0x__\";\n                uint256 errorCode;\n                // solhint-disable-next-line no-inline-assembly\n                assembly {\n                    errorCode := mload(add(returnedData, 0x24))\n                    let reasonWord := mload(add(reason, 0x20))\n                    // [0..9] is converted to ['0'..'9']\n                    // [0xa..0xf] is not correctly converted to ['a'..'f']\n                    // but since panic code doesn't have those cases, we will ignore them for now!\n                    let e1 := add(and(errorCode, 0xf), 0x30)\n                    let e2 := shl(8, add(shr(4, and(errorCode, 0xf0)), 0x30))\n                    reasonWord := or(\n                        and(reasonWord, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000),\n                        or(e2, e1)\n                    )\n                    mstore(add(reason, 0x20), reasonWord)\n                }\n                revert(reason);\n            } else {\n                // case 3: Error(string) (Defined at least since 0.7.0)\n                // case 4: Custom errors (Defined since 0.8.0)\n                uint256 len = returnedData.length;\n                // solhint-disable-next-line no-inline-assembly\n                assembly {\n                    revert(add(returnedData, 32), len)\n                }\n            }\n        }\n    }\n\n    /**\n     * @dev Helper method to parse data and extract the method signature (selector).\n     *\n     * Copied from: https://github.com/argentlabs/argent-contracts/\n     * blob/master/contracts/modules/common/Utils.sol#L54-L60\n     */\n    function parseSelector(bytes memory callData) internal pure returns (bytes4 selector) {\n        if (callData.length < 4) {\n            revert InvalidCalldata();\n        }\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            selector := mload(add(callData, 0x20))\n        }\n    }\n\n    /**\n     * @dev Pad length to 32 bytes word boundary\n     */\n    function padLength32(uint256 len) internal pure returns (uint256 paddedLen) {\n        return ((len / 32) + (((len & 31) > 0) /* rounding? */ ? 1 : 0)) * 32;\n    }\n\n    /**\n     * @dev Validate if the data is encoded correctly with abi.encode(bytesData)\n     *\n     * Expected ABI Encode Layout:\n     * | word 1      | word 2           | word 3           | the rest...\n     * | data length | bytesData offset | bytesData length | bytesData + padLength32 zeros |\n     */\n    function isValidAbiEncodedBytes(bytes memory data) internal pure returns (bool) {\n        if (data.length < 64) return false;\n        uint256 bytesOffset;\n        uint256 bytesLen;\n        // bytes offset is always expected to be 32\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            bytesOffset := mload(add(data, 32))\n        }\n        if (bytesOffset != 32) return false;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            bytesLen := mload(add(data, 64))\n        }\n        // the data length should be bytesData.length + 64 + padded bytes length\n        return data.length == 64 + padLength32(bytesLen);\n    }\n}\n"
      },
      "contracts/tools/GlobalGuardian/IGlobalGuardian.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\ninterface IGlobalGuardian {\n    function disable(bytes32 keyHash) external;\n\n    function enable(bytes32 keyHash) external;\n\n    function functionalityIsDisabled(bytes32 keyHash) external view returns (bool);\n\n    function accountIsPerformer(address _account) external view returns (bool);\n\n    function accountIsSwapHandler(address _account) external view returns (bool);\n\n    function isDefinitiveAdmin() external view returns (bool);\n\n    function isHandlerManager() external view returns (bool);\n\n    function feeAccount() external view returns (address);\n\n    function accountIsDefinitiveAdmin(address _account) external view returns (bool);\n\n    function accountIsHandlerManager(address _account) external view returns (bool);\n}\n"
      },
      "contracts/vendor/interfaces/IWETH9.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.8.20;\n\ninterface IWETH9 {\n    function balanceOf(address) external view returns (uint256);\n\n    function deposit() external payable;\n\n    function withdraw(uint256 wad) external;\n}\n"
      },
      "solmate/src/tokens/ERC20.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\nabstract contract ERC20 {\n    /*//////////////////////////////////////////////////////////////\n                                 EVENTS\n    //////////////////////////////////////////////////////////////*/\n\n    event Transfer(address indexed from, address indexed to, uint256 amount);\n\n    event Approval(address indexed owner, address indexed spender, uint256 amount);\n\n    /*//////////////////////////////////////////////////////////////\n                            METADATA STORAGE\n    //////////////////////////////////////////////////////////////*/\n\n    string public name;\n\n    string public symbol;\n\n    uint8 public immutable decimals;\n\n    /*//////////////////////////////////////////////////////////////\n                              ERC20 STORAGE\n    //////////////////////////////////////////////////////////////*/\n\n    uint256 public totalSupply;\n\n    mapping(address => uint256) public balanceOf;\n\n    mapping(address => mapping(address => uint256)) public allowance;\n\n    /*//////////////////////////////////////////////////////////////\n                            EIP-2612 STORAGE\n    //////////////////////////////////////////////////////////////*/\n\n    uint256 internal immutable INITIAL_CHAIN_ID;\n\n    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\n\n    mapping(address => uint256) public nonces;\n\n    /*//////////////////////////////////////////////////////////////\n                               CONSTRUCTOR\n    //////////////////////////////////////////////////////////////*/\n\n    constructor(\n        string memory _name,\n        string memory _symbol,\n        uint8 _decimals\n    ) {\n        name = _name;\n        symbol = _symbol;\n        decimals = _decimals;\n\n        INITIAL_CHAIN_ID = block.chainid;\n        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                               ERC20 LOGIC\n    //////////////////////////////////////////////////////////////*/\n\n    function approve(address spender, uint256 amount) public virtual returns (bool) {\n        allowance[msg.sender][spender] = amount;\n\n        emit Approval(msg.sender, spender, amount);\n\n        return true;\n    }\n\n    function transfer(address to, uint256 amount) public virtual returns (bool) {\n        balanceOf[msg.sender] -= amount;\n\n        // Cannot overflow because the sum of all user\n        // balances can't exceed the max uint256 value.\n        unchecked {\n            balanceOf[to] += amount;\n        }\n\n        emit Transfer(msg.sender, to, amount);\n\n        return true;\n    }\n\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) public virtual returns (bool) {\n        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\n\n        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\n\n        balanceOf[from] -= amount;\n\n        // Cannot overflow because the sum of all user\n        // balances can't exceed the max uint256 value.\n        unchecked {\n            balanceOf[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n\n        return true;\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                             EIP-2612 LOGIC\n    //////////////////////////////////////////////////////////////*/\n\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) public virtual {\n        require(deadline >= block.timestamp, \"PERMIT_DEADLINE_EXPIRED\");\n\n        // Unchecked because the only math done is incrementing\n        // the owner's nonce which cannot realistically overflow.\n        unchecked {\n            address recoveredAddress = ecrecover(\n                keccak256(\n                    abi.encodePacked(\n                        \"\\x19\\x01\",\n                        DOMAIN_SEPARATOR(),\n                        keccak256(\n                            abi.encode(\n                                keccak256(\n                                    \"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\"\n                                ),\n                                owner,\n                                spender,\n                                value,\n                                nonces[owner]++,\n                                deadline\n                            )\n                        )\n                    )\n                ),\n                v,\n                r,\n                s\n            );\n\n            require(recoveredAddress != address(0) && recoveredAddress == owner, \"INVALID_SIGNER\");\n\n            allowance[recoveredAddress][spender] = value;\n        }\n\n        emit Approval(owner, spender, value);\n    }\n\n    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\n    }\n\n    function computeDomainSeparator() internal view virtual returns (bytes32) {\n        return\n            keccak256(\n                abi.encode(\n                    keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"),\n                    keccak256(bytes(name)),\n                    keccak256(\"1\"),\n                    block.chainid,\n                    address(this)\n                )\n            );\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                        INTERNAL MINT/BURN LOGIC\n    //////////////////////////////////////////////////////////////*/\n\n    function _mint(address to, uint256 amount) internal virtual {\n        totalSupply += amount;\n\n        // Cannot overflow because the sum of all user\n        // balances can't exceed the max uint256 value.\n        unchecked {\n            balanceOf[to] += amount;\n        }\n\n        emit Transfer(address(0), to, amount);\n    }\n\n    function _burn(address from, uint256 amount) internal virtual {\n        balanceOf[from] -= amount;\n\n        // Cannot underflow because a user's balance\n        // will never be larger than the total supply.\n        unchecked {\n            totalSupply -= amount;\n        }\n\n        emit Transfer(from, address(0), amount);\n    }\n}\n"
      },
      "solmate/src/utils/SafeTransferLib.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport {ERC20} from \"../tokens/ERC20.sol\";\n\n/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)\n/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.\n/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.\nlibrary SafeTransferLib {\n    /*//////////////////////////////////////////////////////////////\n                             ETH OPERATIONS\n    //////////////////////////////////////////////////////////////*/\n\n    function safeTransferETH(address to, uint256 amount) internal {\n        bool success;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Transfer the ETH and store if it succeeded or not.\n            success := call(gas(), to, amount, 0, 0, 0, 0)\n        }\n\n        require(success, \"ETH_TRANSFER_FAILED\");\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                            ERC20 OPERATIONS\n    //////////////////////////////////////////////////////////////*/\n\n    function safeTransferFrom(\n        ERC20 token,\n        address from,\n        address to,\n        uint256 amount\n    ) internal {\n        bool success;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Get a pointer to some free memory.\n            let freeMemoryPointer := mload(0x40)\n\n            // Write the abi-encoded calldata into memory, beginning with the function selector.\n            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)\n            mstore(add(freeMemoryPointer, 4), from) // Append the \"from\" argument.\n            mstore(add(freeMemoryPointer, 36), to) // Append the \"to\" argument.\n            mstore(add(freeMemoryPointer, 68), amount) // Append the \"amount\" argument.\n\n            success := and(\n                // Set success to whether the call reverted, if not we check it either\n                // returned exactly 1 (can't just be non-zero data), or had no return data.\n                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\n                // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.\n                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\n                // Counterintuitively, this call must be positioned second to the or() call in the\n                // surrounding and() call or else returndatasize() will be zero during the computation.\n                call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)\n            )\n        }\n\n        require(success, \"TRANSFER_FROM_FAILED\");\n    }\n\n    function safeTransfer(\n        ERC20 token,\n        address to,\n        uint256 amount\n    ) internal {\n        bool success;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Get a pointer to some free memory.\n            let freeMemoryPointer := mload(0x40)\n\n            // Write the abi-encoded calldata into memory, beginning with the function selector.\n            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)\n            mstore(add(freeMemoryPointer, 4), to) // Append the \"to\" argument.\n            mstore(add(freeMemoryPointer, 36), amount) // Append the \"amount\" argument.\n\n            success := and(\n                // Set success to whether the call reverted, if not we check it either\n                // returned exactly 1 (can't just be non-zero data), or had no return data.\n                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\n                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.\n                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\n                // Counterintuitively, this call must be positioned second to the or() call in the\n                // surrounding and() call or else returndatasize() will be zero during the computation.\n                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)\n            )\n        }\n\n        require(success, \"TRANSFER_FAILED\");\n    }\n\n    function safeApprove(\n        ERC20 token,\n        address to,\n        uint256 amount\n    ) internal {\n        bool success;\n\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Get a pointer to some free memory.\n            let freeMemoryPointer := mload(0x40)\n\n            // Write the abi-encoded calldata into memory, beginning with the function selector.\n            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)\n            mstore(add(freeMemoryPointer, 4), to) // Append the \"to\" argument.\n            mstore(add(freeMemoryPointer, 36), amount) // Append the \"amount\" argument.\n\n            success := and(\n                // Set success to whether the call reverted, if not we check it either\n                // returned exactly 1 (can't just be non-zero data), or had no return data.\n                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),\n                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.\n                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.\n                // Counterintuitively, this call must be positioned second to the or() call in the\n                // surrounding and() call or else returndatasize() will be zero during the computation.\n                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)\n            )\n        }\n\n        require(success, \"APPROVE_FAILED\");\n    }\n}\n"
      }
    },
    "settings": {
      "evmVersion": "paris",
      "metadata": {
        "bytecodeHash": "none"
      },
      "optimizer": {
        "enabled": true,
        "runs": 500
      },
      "viaIR": false,
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}