creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@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/IERC1271.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n */\ninterface IERC1271 {\n    /**\n     * @dev Should return whether the signature provided is valid for the provided data\n     * @param hash      Hash of the data to be signed\n     * @param signature Signature byte array associated with _data\n     */\n    function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\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/cryptography/ECDSA.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n    enum RecoverError {\n        NoError,\n        InvalidSignature,\n        InvalidSignatureLength,\n        InvalidSignatureS\n    }\n\n    /**\n     * @dev The signature derives the `address(0)`.\n     */\n    error ECDSAInvalidSignature();\n\n    /**\n     * @dev The signature has an invalid length.\n     */\n    error ECDSAInvalidSignatureLength(uint256 length);\n\n    /**\n     * @dev The signature has an S value that is in the upper half order.\n     */\n    error ECDSAInvalidSignatureS(bytes32 s);\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not\n     * return address(0) without also returning an error description. Errors are documented using an enum (error type)\n     * and a bytes32 providing additional information about the error.\n     *\n     * If no error is returned, then the address can be used for verification purposes.\n     *\n     * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.\n     *\n     * Documentation for signature generation:\n     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n     */\n    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) {\n        if (signature.length == 65) {\n            bytes32 r;\n            bytes32 s;\n            uint8 v;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            /// @solidity memory-safe-assembly\n            assembly {\n                r := mload(add(signature, 0x20))\n                s := mload(add(signature, 0x40))\n                v := byte(0, mload(add(signature, 0x60)))\n            }\n            return tryRecover(hash, v, r, s);\n        } else {\n            return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));\n        }\n    }\n\n    /**\n     * @dev Returns the address that signed a hashed message (`hash`) with\n     * `signature`. This address can then be used for verification purposes.\n     *\n     * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:\n     * this function rejects them by requiring the `s` value to be in the lower\n     * half order, and the `v` value to be either 27 or 28.\n     *\n     * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n     * verification to be secure: it is possible to craft signatures that\n     * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n     * this is by receiving a hash of the original message (which may otherwise\n     * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.\n     */\n    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);\n        _throwError(error, errorArg);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n     *\n     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n     */\n    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) {\n        unchecked {\n            bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n            // We do not check for an overflow here since the shift operation results in 0 or 1.\n            uint8 v = uint8((uint256(vs) >> 255) + 27);\n            return tryRecover(hash, v, r, s);\n        }\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n     */\n    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\n        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);\n        _throwError(error, errorArg);\n        return recovered;\n    }\n\n    /**\n     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function tryRecover(\n        bytes32 hash,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal pure returns (address, RecoverError, bytes32) {\n        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n        // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n        //\n        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n        // these malleable signatures as well.\n        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n            return (address(0), RecoverError.InvalidSignatureS, s);\n        }\n\n        // If the signature is valid (and not malleable), return the signer address\n        address signer = ecrecover(hash, v, r, s);\n        if (signer == address(0)) {\n            return (address(0), RecoverError.InvalidSignature, bytes32(0));\n        }\n\n        return (signer, RecoverError.NoError, bytes32(0));\n    }\n\n    /**\n     * @dev Overload of {ECDSA-recover} that receives the `v`,\n     * `r` and `s` signature fields separately.\n     */\n    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);\n        _throwError(error, errorArg);\n        return recovered;\n    }\n\n    /**\n     * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.\n     */\n    function _throwError(RecoverError error, bytes32 errorArg) private pure {\n        if (error == RecoverError.NoError) {\n            return; // no error: do nothing\n        } else if (error == RecoverError.InvalidSignature) {\n            revert ECDSAInvalidSignature();\n        } else if (error == RecoverError.InvalidSignatureLength) {\n            revert ECDSAInvalidSignatureLength(uint256(errorArg));\n        } else if (error == RecoverError.InvalidSignatureS) {\n            revert ECDSAInvalidSignatureS(errorArg);\n        }\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"
      },
      "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    }\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/BasePermissionedExecution/BasePermissionedExecutionInitiable.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { BaseAccessControlInitiable } from \"../BaseAccessControlInitiable.sol\";\nimport { CallUtils } from \"../../tools/BubbleReverts/BubbleReverts.sol\";\nimport { IBasePermissionedExecution } from \"./IBasePermissionedExecution.sol\";\n\nabstract contract BasePermissionedExecutionInitiable is BaseAccessControlInitiable, IBasePermissionedExecution {\n    function executeOperation(address target, bytes calldata payload) external payable override onlyClientAdmin {\n        // slither-disable-next-line arbitrary-send-eth\n        (bool _success, bytes memory _returnedData) = payable(target).call{ value: msg.value }(payload);\n        if (!_success) {\n            CallUtils.revertFromReturnedData(_returnedData);\n        }\n    }\n}\n"
      },
      "contracts/base/BasePermissionedExecution/IBasePermissionedExecution.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { ICoreAccessControlV1 } from \"../../core/CoreAccessControl/v1/ICoreAccessControlV1.sol\";\n\ninterface IBasePermissionedExecution is ICoreAccessControlV1 {\n    function executeOperation(address target, bytes calldata payload) external payable;\n}\n"
      },
      "contracts/base/BaseRecoverSignerInitiable.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { IERC1271 } from \"@openzeppelin/contracts/interfaces/IERC1271.sol\";\nimport { ECDSA } from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport { BaseAccessControlInitiable } from \"./BaseAccessControlInitiable.sol\";\nimport { AccountNotAdmin, InvalidSignature } from \"../core/libraries/DefinitiveErrors.sol\";\n\n/**\n * @title BaseRecoverSignerInitiable\n * @author WardenJakx\n * @notice `isValidSignature` ensures the signer is a valid client\n */\nabstract contract BaseRecoverSignerInitiable is BaseAccessControlInitiable, IERC1271 {\n    // bytes4(keccak256(\"isValidSignature(bytes32,bytes)\")\n    bytes4 internal constant EIP_1271_RETURN_VALUE = 0x1626ba7e;\n\n    /**\n     * @notice Verifies that the signer is the owner of the signing contract.\n     */\n    function isValidSignature(bytes32 _hash, bytes calldata _encodedSignature) external view override returns (bytes4) {\n        (address clientAdminAddress, bytes memory signature) = abi.decode(_encodedSignature, (address, bytes));\n\n        if (!hasRole(DEFAULT_ADMIN_ROLE, clientAdminAddress)) {\n            revert AccountNotAdmin(clientAdminAddress);\n        }\n\n        if (clientAdminAddress.code.length > 0) {\n            return IERC1271(clientAdminAddress).isValidSignature(_hash, signature);\n        } else if (ECDSA.recover(_hash, signature) == clientAdminAddress) {\n            return EIP_1271_RETURN_VALUE;\n        }\n\n        revert InvalidSignature();\n    }\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/base/BaseTransfers/v1/BaseTransfersInitiable.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { CoreDeposit } from \"../../../core/CoreDeposit/v1/CoreDeposit.sol\";\nimport { CoreWithdraw } from \"../../../core/CoreWithdraw/v1/CoreWithdraw.sol\";\nimport { BaseAccessControlInitiable } from \"../../BaseAccessControlInitiable.sol\";\nimport { ReentrancyGuard } from \"@openzeppelin/contracts/utils/ReentrancyGuard.sol\";\n\nabstract contract BaseTransfersInitiable is CoreDeposit, CoreWithdraw, BaseAccessControlInitiable, ReentrancyGuard {\n    function deposit(\n        uint256[] calldata amounts,\n        address[] calldata erc20Tokens\n    ) external payable virtual override onlyClients nonReentrant stopGuarded {\n        return _deposit(amounts, erc20Tokens);\n    }\n\n    function withdraw(\n        uint256 amount,\n        address erc20Token\n    ) public virtual override onlyClients nonReentrant stopGuarded withdrawalsEnabled returns (bool) {\n        return _withdraw(amount, erc20Token);\n    }\n\n    function withdrawTo(\n        uint256 amount,\n        address erc20Token,\n        address to\n    ) public virtual override onlyWhitelisted nonReentrant stopGuarded withdrawalsEnabled returns (bool) {\n        // `to` account must be a client\n        _checkRole(ROLE_CLIENT, to);\n\n        return _withdrawTo(amount, erc20Token, to);\n    }\n\n    function withdrawAll(\n        address[] calldata tokens\n    ) public virtual override onlyClients nonReentrant stopGuarded withdrawalsEnabled returns (bool) {\n        return _withdrawAll(tokens);\n    }\n\n    function withdrawAllTo(\n        address[] calldata tokens,\n        address to\n    ) public virtual override onlyWhitelisted stopGuarded withdrawalsEnabled returns (bool) {\n        _checkRole(ROLE_CLIENT, to);\n        return _withdrawAllTo(tokens, to);\n    }\n\n    function supportsNativeAssets() public pure virtual override returns (bool) {\n        return false;\n    }\n}\n"
      },
      "contracts/base/BaseTransfersNative/v1/BaseTransfersNativeInitiable.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { IBaseNativeWrapperV1 } from \"../../BaseNativeWrapper/v1/IBaseNativeWrapperV1.sol\";\nimport { BaseTransfersInitiable } from \"../../BaseTransfers/v1/BaseTransfersInitiable.sol\";\nimport { CoreTransfersNative } from \"../../../core/CoreTransfersNative/v1/CoreTransfersNative.sol\";\n\nabstract contract BaseTransfersNativeInitiable is IBaseNativeWrapperV1, CoreTransfersNative, BaseTransfersInitiable {\n    function deposit(\n        uint256[] calldata amounts,\n        address[] calldata assetAddresses\n    ) external payable override onlyClients nonReentrant stopGuarded {\n        _depositNativeAndERC20(amounts, assetAddresses);\n        emit Deposit(_msgSender(), assetAddresses, amounts);\n    }\n\n    function supportsNativeAssets() public pure virtual override returns (bool) {\n        return true;\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/CoreDeposit/v1/CoreDeposit.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { ICoreDepositV1 } from \"./ICoreDepositV1.sol\";\nimport { Context } from \"@openzeppelin/contracts/utils/Context.sol\";\nimport { DefinitiveAssets, IERC20 } from \"../../libraries/DefinitiveAssets.sol\";\n\nimport { InvalidInputs } from \"../../libraries/DefinitiveErrors.sol\";\n\nabstract contract CoreDeposit is ICoreDepositV1, Context {\n    using DefinitiveAssets for IERC20;\n\n    function deposit(uint256[] calldata amounts, address[] calldata assetAddresses) external payable virtual;\n\n    function _deposit(uint256[] calldata amounts, address[] calldata erc20Tokens) internal virtual {\n        _depositERC20(amounts, erc20Tokens);\n\n        emit Deposit(_msgSender(), erc20Tokens, amounts);\n    }\n\n    function _depositERC20(uint256[] calldata amounts, address[] calldata erc20Tokens) internal {\n        uint256 amountsLength = amounts.length;\n        if (amountsLength != erc20Tokens.length) {\n            revert InvalidInputs();\n        }\n\n        for (uint256 i; i < amountsLength; ) {\n            IERC20(erc20Tokens[i]).safeTransferFrom(_msgSender(), address(this), amounts[i]);\n            unchecked {\n                ++i;\n            }\n        }\n    }\n}\n"
      },
      "contracts/core/CoreDeposit/v1/ICoreDepositV1.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\ninterface ICoreDepositV1 {\n    event Deposit(address indexed actor, address[] assetAddresses, uint256[] amounts);\n\n    function deposit(uint256[] calldata amounts, address[] calldata assetAddresses) external payable;\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/CoreMulticall/v1/CoreMulticall.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { ICoreMulticallV1 } from \"./ICoreMulticallV1.sol\";\nimport { Address } from \"@openzeppelin/contracts/utils/Address.sol\";\nimport { DefinitiveAssets } from \"../../libraries/DefinitiveAssets.sol\";\n\n/* solhint-disable max-line-length */\n/**\n * @notice Implements openzeppelin/contracts/utils/Multicall.sol\n * Source: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/5b027e517e6aee69f4b4b2f5e78274ac8ee53513/contracts/utils/Multicall.sol solhint-disable max-line-length\n */\n/* solhint-enable max-line-length */\nabstract contract CoreMulticall is ICoreMulticallV1 {\n    /**\n     * @dev Receives and executes a batch of function calls on this contract.\n     */\n    function multicall(bytes[] calldata data) external returns (bytes[] memory results) {\n        uint256 dataLength = data.length;\n        results = new bytes[](dataLength);\n        for (uint256 i; i < dataLength; ) {\n            results[i] = Address.functionDelegateCall(address(this), data[i]);\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    function getBalance(address assetAddress) public view returns (uint256) {\n        return DefinitiveAssets.getBalance(assetAddress);\n    }\n}\n"
      },
      "contracts/core/CoreMulticall/v1/ICoreMulticallV1.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\ninterface ICoreMulticallV1 {\n    function multicall(bytes[] calldata data) external returns (bytes[] memory results);\n\n    function getBalance(address assetAddress) external view returns (uint256);\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    address public constant GLOBAL_TRADE_GUARDIAN = 0x3AB7069fCB015Bd18d0542dA9deeDce3F4374aEE;\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 disableTrading() public virtual;\n\n    function enableTrading() public virtual;\n\n    function disableWithdrawals() public virtual;\n\n    function enableWithdrawals() public virtual;\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/CoreTransfersNative/v1/CoreTransfersNative.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { Context } from \"@openzeppelin/contracts/utils/Context.sol\";\nimport { ICoreTransfersNativeV1 } from \"./ICoreTransfersNativeV1.sol\";\n\nimport { DefinitiveAssets, IERC20 } from \"../../libraries/DefinitiveAssets.sol\";\nimport { DefinitiveConstants } from \"../../libraries/DefinitiveConstants.sol\";\nimport { InvalidInputs, InvalidMsgValue } from \"../../libraries/DefinitiveErrors.sol\";\n\nabstract contract CoreTransfersNative is ICoreTransfersNativeV1, Context {\n    using DefinitiveAssets for IERC20;\n\n    /**\n     * @notice Allows contract to receive native assets\n     */\n    receive() external payable virtual {\n        emit NativeTransfer(_msgSender(), msg.value);\n    }\n\n    function _depositNativeAndERC20(uint256[] calldata amounts, address[] calldata assetAddresses) internal virtual {\n        uint256 assetAddressesLength = assetAddresses.length;\n        if (amounts.length != assetAddressesLength) {\n            revert InvalidInputs();\n        }\n\n        bool hasNativeAsset;\n        uint256 nativeAssetIndex;\n\n        for (uint256 i; i < assetAddressesLength; ) {\n            if (assetAddresses[i] == DefinitiveConstants.NATIVE_ASSET_ADDRESS) {\n                nativeAssetIndex = i;\n                hasNativeAsset = true;\n                unchecked {\n                    ++i;\n                }\n                continue;\n            }\n            // ERC20 tokens\n            IERC20(assetAddresses[i]).safeTransferFrom(_msgSender(), address(this), amounts[i]);\n            unchecked {\n                ++i;\n            }\n        }\n        // Revert if NATIVE_ASSET_ADDRESS is not in assetAddresses and msg.value is not zero\n        if (!hasNativeAsset && msg.value != 0) {\n            revert InvalidMsgValue();\n        }\n\n        // Revert if depositing native asset and amount != msg.value\n        if (hasNativeAsset && msg.value != amounts[nativeAssetIndex]) {\n            revert InvalidMsgValue();\n        }\n    }\n}\n"
      },
      "contracts/core/CoreTransfersNative/v1/ICoreTransfersNativeV1.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\ninterface ICoreTransfersNativeV1 {\n    /**\n     * @dev Emitted when `value` native asset is received by the contract\n     */\n    event NativeTransfer(address indexed from, uint256 value);\n\n    receive() external payable;\n}\n"
      },
      "contracts/core/CoreWithdraw/v1/CoreWithdraw.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { ICoreWithdrawV1 } from \"./ICoreWithdrawV1.sol\";\nimport { DefinitiveAssets, IERC20 } from \"../../libraries/DefinitiveAssets.sol\";\nimport { Context } from \"@openzeppelin/contracts/utils/Context.sol\";\nimport { DefinitiveConstants } from \"../../libraries/DefinitiveConstants.sol\";\n\nabstract contract CoreWithdraw is ICoreWithdrawV1, Context {\n    using DefinitiveAssets for IERC20;\n\n    function supportsNativeAssets() public pure virtual returns (bool);\n\n    function withdraw(uint256 amount, address erc20Token) public virtual returns (bool);\n\n    function withdrawTo(uint256 amount, address erc20Token, address to) public virtual returns (bool);\n\n    function _withdraw(uint256 amount, address erc20Token) internal returns (bool) {\n        return _withdrawTo(amount, erc20Token, _msgSender());\n    }\n\n    function _withdrawTo(uint256 amount, address erc20Token, address to) internal returns (bool success) {\n        if (erc20Token == DefinitiveConstants.NATIVE_ASSET_ADDRESS) {\n            DefinitiveAssets.safeTransferETH(payable(to), amount);\n        } else {\n            IERC20(erc20Token).safeTransfer(to, amount);\n        }\n\n        emit Withdrawal(erc20Token, amount, to);\n\n        success = true;\n    }\n\n    function withdrawAll(address[] calldata tokens) public virtual returns (bool);\n\n    function withdrawAllTo(address[] calldata tokens, address to) public virtual returns (bool);\n\n    function _withdrawAll(address[] calldata tokens) internal returns (bool) {\n        return _withdrawAllTo(tokens, _msgSender());\n    }\n\n    function _withdrawAllTo(address[] calldata tokens, address to) internal returns (bool success) {\n        uint256 tokenLength = tokens.length;\n        for (uint256 i; i < tokenLength; ) {\n            uint256 tokenBalance = DefinitiveAssets.getBalance(tokens[i]);\n            if (tokenBalance > 0) {\n                _withdrawTo(tokenBalance, tokens[i], to);\n            }\n            unchecked {\n                ++i;\n            }\n        }\n        return true;\n    }\n}\n"
      },
      "contracts/core/CoreWithdraw/v1/ICoreWithdrawV1.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\ninterface ICoreWithdrawV1 {\n    event Withdrawal(address indexed erc20Token, uint256 amount, address indexed recipient);\n\n    function withdrawAll(address[] calldata tokens) external returns (bool);\n\n    function withdrawAllTo(address[] calldata tokens, address to) external returns (bool);\n\n    function supportsNativeAssets() external pure returns (bool);\n\n    function withdraw(uint256 amount, address erc20Token) external returns (bool);\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 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/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/TradingVaultImplementation.sol": {
        "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >=0.8.20;\n\nimport { BaseTransfersNativeInitiable } from \"../../../base/BaseTransfersNative/v1/BaseTransfersNativeInitiable.sol\";\nimport { BaseSimpleSwapInitiable, CoreSimpleSwapConfig } from \"../../../base/BaseSimpleSwapInitiable.sol\";\nimport { CoreAccessControlConfig } from \"../../../base/BaseAccessControlInitiable.sol\";\nimport { BaseRecoverSignerInitiable } from \"../../../base/BaseRecoverSignerInitiable.sol\";\nimport { CoreFeesConfig } from \"../../../base/BaseFeesInitiable.sol\";\nimport { CoreMulticall } from \"../../../core/CoreMulticall/v1/CoreMulticall.sol\";\nimport {\n    WETH9NativeWrapperInitiable,\n    BaseNativeWrapperConfig\n} from \"../../../modules/native-asset-wrappers/WETH9NativeWrapperInitiable.sol\";\nimport {\n    BasePermissionedExecutionInitiable\n} from \"../../../base/BasePermissionedExecution/BasePermissionedExecutionInitiable.sol\";\nimport { ITradingVaultImplementation } from \"./ITradingVaultImplementation.sol\";\n\ncontract TradingVaultImplementation is\n    ITradingVaultImplementation,\n    WETH9NativeWrapperInitiable,\n    BaseTransfersNativeInitiable,\n    BaseSimpleSwapInitiable,\n    BasePermissionedExecutionInitiable,\n    CoreMulticall,\n    BaseRecoverSignerInitiable\n{\n    /// @notice Constructor on the implementation contract should call _disableInitializers()\n    /// @dev https://forum.openzeppelin.com/t/what-does-disableinitializers-function-mean/28730\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    function initialize(\n        BaseNativeWrapperConfig calldata baseNativeWrapperConfig,\n        CoreAccessControlConfig calldata coreAccessControlConfig,\n        CoreSimpleSwapConfig calldata coreSimpleSwapConfig,\n        CoreFeesConfig calldata coreFeesConfig\n    ) external override initializer {\n        __WETH9NativeWrapperInitiable__init(baseNativeWrapperConfig);\n        __BaseAccessControlInitiable__init(coreAccessControlConfig);\n        __BaseSimpleSwapInitiable__init(coreSimpleSwapConfig);\n        __BaseFeesInitiable__init(coreFeesConfig);\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"
      },
      "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": {}
    }
  }}