{"file_path":"protocol/token/src/fund/v1.3.0/FundTokenV1_3_0.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.0 ^0.8.1 ^0.8.2 ^0.8.20 ^0.8.28;\n\n// dependencies/openzeppelin-contracts-upgradeable-v4.9.3-4.9.3/contracts/utils/AddressUpgradeable.sol\n\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     *\n     * Furthermore, `isContract` will also return true if the target contract within\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n     * which only has an effect at the end of a transaction.\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://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.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) 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(errorMessage);\n        }\n    }\n}\n\n// dependencies/chainlink-2.11.1/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol\n\ninterface AggregatorV3Interface {\n  function decimals() external view returns (uint8);\n\n  function description() external view returns (string memory);\n\n  function version() external view returns (uint256);\n\n  function getRoundData(\n    uint80 _roundId\n  ) external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n\n  function latestRoundData()\n    external\n    view\n    returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n}\n\n// dependencies/openzeppelin-contracts-v4.8.0-4.8.0/contracts/utils/cryptography/ECDSA.sol\n\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/ECDSA.sol)\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n    enum RecoverError {\n        NoError,\n        InvalidSignature,\n        InvalidSignatureLength,\n        InvalidSignatureS\n    }\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(\n        bytes32 hash,\n        bytes memory signature\n    ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {\n        if (signature.length == 65) {\n            bytes32 r;\n            bytes32 s;\n            uint8 v;\n            // ecrecover takes the signature parameters, and the only way to get them\n            // currently is to use assembly.\n            assembly (\"memory-safe\") {\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[ERC-2098 short signatures]\n     */\n    function tryRecover(\n        bytes32 hash,\n        bytes32 r,\n        bytes32 vs\n    ) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {\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 recovered, RecoverError err, bytes32 errArg) {\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\n// protocol/token/src/interfaces/IAccountingPausable.sol\n\n/**\n * @title IAccountingPausable\n * @notice Interface for pausable accounting functionality\n * @dev Defines the interface for pausing and unpausing minting and burning operations independently from transfers\n */\ninterface IAccountingPausable {\n    /**\n     * @dev Pauses accounting operations (minting and burning)\n     * @notice Can only be called by authorized addresses (defined in implementation)\n     */\n    function accountingPause() external;\n\n    /**\n     * @dev Unpauses accounting operations\n     * @notice Can only be called by authorized addresses (defined in implementation)\n     */\n    function accountingUnpause() external;\n\n    /**\n     * @dev Returns whether accounting is currently paused\n     * @return True if accounting is paused, false otherwise\n     */\n    function isAccountingPaused() external view returns (bool);\n\n    /**\n     * @dev Emitted when accounting is paused by `pauser`\n     */\n    event AccountingPaused(address indexed pauser);\n\n    /**\n     * @dev Emitted when accounting is unpaused by `unpauser`\n     */\n    event AccountingUnpaused(address indexed unpauser);\n\n    /**\n     * @dev Error thrown when attempting to perform accounting operations while paused\n     */\n    error AccountingIsPaused();\n\n    /**\n     * @dev Error thrown when attempting to unpause accounting when it's not paused\n     */\n    error AccountingIsNotPaused();\n}\n\n// protocol/allowlist/src/interfaces/IAllowlistAddressPermissions.sol\n\n/**\n * @title IAllowlistAddressPermissions\n * @notice Core interface for address permissions and entity ID lookups\n * @dev This interface provides the essential allowlist functions needed for\n * checking address permissions and entity mappings\n */\ninterface IAllowlistAddressPermissions {\n    /**\n     * @notice Gets the entityId for the provided address\n     * @param addr The address to get the entityId for\n     */\n    function addressEntityIds(address addr) external view returns (uint256);\n\n    /**\n     * @notice Checks whether an address is allowed to use a private instrument\n     * @param addr The address to check permissions for\n     * @param instrument The private instrument symbol to check permissions for\n     */\n    function isAddressAllowedForPrivateInstrument(address addr, string calldata instrument) external view returns (bool);\n\n    /**\n     * @dev Checks if an address is allowed to interact with public instrument\n     * @param addr The address to check\n     * @return True if the address is allowed, false otherwise\n     */\n    function isAddressAllowedForPublicInstrument(address addr) external view returns (bool);\n}\n// protocol/token/src/interfaces/IAllowlistable.sol\n\n/**\n * @title IAllowlistable\n * @notice Interface for allowlist functionality\n * @dev Defines the interface for checking if addresses have permission to interact with the token\n */\ninterface IAllowlistable {\n    /**\n     * @dev Returns the current allowlist contract\n     * @return The allowlist contract address\n     */\n    function allowlist() external view returns (address);\n\n    /**\n     * @dev Returns whether the instrument is public or private\n     * @return True if the instrument is public, false if private\n     */\n    function isPublicInstrument() external view returns (bool);\n\n    /**\n     * @dev Checks if an address is allowed based on instrument type\n     * @param addr The address to check\n     * @return True if the address is allowed, false otherwise\n     * @notice Automatically uses public or private permission check based on isPublicInstrument().\n     *         Uses V3 compat functions on allowlist for smooth AllowlistV3→V4 upgrade.\n     */\n    function isAllowed(address addr) external view returns (bool);\n\n    /**\n     * @dev Emitted when the allowlist is updated\n     */\n    event AllowlistUpdated(address indexed oldAllowlist, address indexed newAllowlist);\n\n    /**\n     * @dev Emitted when the instrument type (public/private) is updated\n     */\n    event IsPublicInstrumentUpdated(bool oldIsPublicInstrument, bool newIsPublicInstrument);\n\n    /**\n     * @dev Error thrown when an address doesn't have sufficient permissions\n     */\n    error InsufficientPermissions();\n\n    error ZeroAddressNotAllowed();\n\n    error AlreadySet();\n}\n\n// protocol/token/src/interfaces/IBridgeable.sol\n\n/**\n * @title IBridgeable\n * @notice Interface for cross-chain bridging functionality\n * @dev Defines the interface for burning tokens on one chain and minting on another\n */\ninterface IBridgeable {\n    /**\n     * @dev Returns whether a chain ID is supported for bridging\n     * @param chainId The chain ID to check\n     * @return True if the chain ID is supported, false otherwise\n     */\n    function isChainIdSupported(uint256 chainId) external view returns (bool);\n\n    /**\n     * @dev Sets support status for a specific chain ID\n     * @param chainId The chain ID to update\n     * @param supported Whether the chain ID should be supported\n     */\n    function setChainIdSupport(uint256 chainId, bool supported) external;\n\n    /**\n     * @notice Burns tokens from the caller to bridge to another chain\n     * @dev Reverts if chainId is not supported.\n     * @dev If destination address on chainId isn't on allowlist on the other chain, tokens burn to book entry.\n     * @dev Use chainId 0 to burn tokens to Superstate book entry.\n     * @param amount Amount of tokens to burn\n     * @param ethDestinationAddress ETH address to send to on another chain\n     * @param otherDestinationAddress Non-EVM addresses to send to on another chain\n     * @param chainId Numerical identifier of destination chain to send tokens to\n     */\n    function bridge(\n        uint256 amount,\n        address ethDestinationAddress,\n        string memory otherDestinationAddress,\n        uint256 chainId\n    ) external;\n\n    /**\n     * @dev Burns tokens from the caller to bridge to Superstate book entry\n     * @param amount Amount of tokens to burn\n     */\n    function bridgeToBookEntry(uint256 amount) external;\n\n    /// @notice Emitted when a chain ID's support status is updated\n    event SetChainIdSupport(uint256 indexed chainId, bool oldSupported, bool newSupported);\n\n    /// @dev Event emitted when the user wants to bridge their tokens to another chain or book entry\n    event Bridge(\n        address caller,\n        address indexed src,\n        uint256 amount,\n        address indexed ethDestinationAddress,\n        string otherDestinationAddress,\n        uint256 chainId\n    );\n\n    /**\n     * @dev Error thrown when destination chain is not supported\n     */\n    error BridgeChainIdDestinationNotSupported();\n\n    /**\n     * @dev Error thrown when both ETH and non-ETH destination addresses are provided\n     */\n    error TwoDestinationsInvalid();\n\n    /**\n     * @dev Error thrown when zero tokens are provided for bridging\n     */\n    error ZeroSuperstateTokensOutBridgeable();\n\n    /**\n     * @dev Error thrown when destination is set for bridge to book entry\n     */\n    error OnchainDestinationSetForBridgeToBookEntry();\n\n    /**\n     * @dev Error thrown for invalid function arguments\n     */\n    error BadArgsBridgeable();\n}\n\n// dependencies/openzeppelin-contracts-v4.8.0-4.8.0/contracts/utils/introspection/IERC165.sol\n\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\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[ERC 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\n// dependencies/openzeppelin-contracts-v4.8.0-4.8.0/contracts/token/ERC20/IERC20.sol\n\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\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\n// dependencies/openzeppelin-contracts-upgradeable-v4.9.3-4.9.3/contracts/token/ERC20/IERC20Upgradeable.sol\n\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n\n// protocol/token/src/interfaces/IOracleConsumable.sol\n\n/**\n * @title IOracleConsumable\n * @notice Interface for contracts that consume Chainlink oracle data\n */\ninterface IOracleConsumable {\n    /**\n     * @notice Returns the oracle address\n     * @return The address of the oracle\n     */\n    function superstateOracle() external view returns (address);\n\n    /**\n     * @notice Returns the maximum oracle delay\n     * @return The maximum acceptable delay in seconds\n     */\n    function maximumOracleDelay() external view returns (uint256);\n\n    /**\n     * @notice Gets the Chainlink price data\n     * @return _isBadData True if the data is stale or below threshold\n     * @return _updatedAt The timestamp of the last update\n     * @return _price The price from the oracle\n     */\n    function getChainlinkPrice() external view returns (bool _isBadData, uint256 _updatedAt, uint256 _price);\n\n    /**\n     * @notice Sets the maximum oracle delay\n     * @param _newMaxOracleDelay The new maximum delay in seconds\n     */\n    function setMaximumOracleDelay(uint256 _newMaxOracleDelay) external;\n\n    /**\n     * @notice Sets the oracle address\n     * @param _newOracle The new oracle address\n     */\n    function setOracle(address _newOracle) external;\n\n    /// @dev Event emitted when the address for the pricing oracle changes\n    event SetOracle(address oldOracle, address newOracle);\n\n    /// @dev Emitted when the max oracle delay is set\n    event SetMaximumOracleDelay(uint256 oldMaxOracleDelay, uint256 newMaxOracleDelay);\n\n    /**\n     * @dev Error thrown when oracle data is bad (stale or below threshold)\n     */\n    error BadChainlinkData();\n\n    /**\n     * @dev Error thrown when onchain subscriptions are disabled\n     */\n    error OnchainSubscriptionsDisabled();\n\n    /**\n     * @dev Error thrown when function arguments are invalid\n     */\n    error BadArgsOracleConsumable();\n}\n\n// protocol/token/src/interfaces/IPermittable.sol\n\n/**\n * @title IPermittable\n * @notice Interface for the Permittable contract implementing EIP-712 compliant permit functionality\n * @dev Defines functions for approving token spending through signatures (EIP-2612)\n */\ninterface IPermittable {\n    /**\n     * @dev Error thrown when signature has expired\n     */\n    error SignatureExpired();\n\n    /**\n     * @dev Error thrown when S value in signature is invalid\n     */\n    error InvalidSignatureS();\n\n    /**\n     * @dev Error thrown when signature verification fails\n     */\n    error BadSignatory();\n\n    /**\n     * @dev Returns the current nonce for an address\n     * @param owner The address to get the nonce for\n     * @return The current nonce\n     */\n    function nonces(address owner) external view returns (uint256);\n\n    /**\n     * @dev Sets approval amount for a spender via signature from signatory\n     * @param owner The address that signed the signature\n     * @param spender The address to authorize (or rescind authorization from)\n     * @param value Amount that `owner` is approving for `spender`\n     * @param deadline Expiration time for the signature\n     * @param v The recovery byte of the signature\n     * @param r Half of the ECDSA signature pair\n     * @param s Half of the ECDSA signature pair\n     */\n    function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)\n        external;\n\n    /**\n     * @dev Returns the domain separator used in the encoding of the signature for permit\n     * @return bytes32 The domain separator\n     */\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n\n// protocol/token/src/interfaces/IRedeemable.sol\n\n/**\n * @title IRedeemable\n * @notice Interface for tokens that can be redeemed through a dedicated redemption contract\n */\ninterface IRedeemable {\n    /**\n     * @notice Returns the current redemption contract address\n     * @return The address of the redemption contract\n     */\n    function getRedemptionContract() external view returns (address);\n\n    /**\n     * @notice Sets redemption contract address\n     * @dev Used for convenience for devs\n     * @dev Set to address(0) if no such contract exists for the token\n     * @param _newRedemptionContract New contract address\n     */\n    function setRedemptionContract(address _newRedemptionContract) external;\n\n    /**\n     * @notice Burns tokens from the caller's address for offchain redemption\n     * @param amount Amount of tokens to burn\n     */\n    function offchainRedeem(uint256 amount) external;\n\n    /// @dev Event emitted when the owner changes the redemption contract address\n    event SetRedemptionContract(address oldRedemptionContract, address newRedemptionContract);\n\n    /// @dev Event emitted when the users wants to redeem their shares with an offchain payout\n    event OffchainRedeem(address indexed burner, address indexed src, uint256 amount);\n\n    /**\n     * @dev Error thrown when function arguments are invalid\n     */\n    error BadArgsRedeemable();\n}\n\n// protocol/token/src/interfaces/ISubscribable.sol\n\n/**\n * @title ISubscribable\n * @notice Interface for contracts that allow token minting through stablecoin deposits\n * @custom:version 1.2.0\n */\ninterface ISubscribable {\n    struct StablecoinConfig {\n        address sweepDestination;\n        uint96 fee;\n    }\n\n    /**\n     * @notice Returns the configuration for a stablecoin\n     * @param stablecoin The stablecoin address\n     * @return The stablecoin configuration\n     */\n    function supportedStablecoins(address stablecoin) external view returns (StablecoinConfig memory);\n\n    /**\n     * @notice Sets the configuration for a stablecoin\n     * @param stablecoin The stablecoin address\n     * @param newSweepDestination The address to send stablecoins to\n     * @param newFee The fee in basis points (max 10 = 0.1%)\n     */\n    function setStablecoinConfig(address stablecoin, address newSweepDestination, uint96 newFee) external;\n\n    /**\n     * @notice Calculates the fee for a subscription\n     * @param amount The amount to calculate fee on\n     * @param subscriptionFee The fee percentage in basis points\n     * @return The fee amount\n     */\n    function calculateFee(uint256 amount, uint256 subscriptionFee) external pure returns (uint256);\n\n    /**\n     * @notice Calculates the amount of tokens to mint for a subscription\n     * @param inAmount The amount of stablecoin to subscribe with\n     * @param stablecoin The stablecoin address\n     * @return superstateTokenOutAmount The amount of tokens to mint\n     * @return stablecoinInAmountAfterFee The amount of stablecoin after fee\n     * @return feeOnStablecoinInAmount The fee amount\n     */\n    function calculateSuperstateTokenOut(uint256 inAmount, address stablecoin)\n        external\n        view\n        returns (uint256 superstateTokenOutAmount, uint256 stablecoinInAmountAfterFee, uint256 feeOnStablecoinInAmount);\n\n    /**\n     * @notice Processes a subscription\n     * @param to The recipient of the minted tokens\n     * @param inAmount The amount of stablecoin to subscribe with\n     * @param stablecoin The stablecoin address\n     */\n    function subscribe(address to, uint256 inAmount, address stablecoin) external;\n\n    /**\n     * @notice Processes a subscription with the caller as the recipient\n     * @param inAmount The amount of stablecoin to subscribe with\n     * @param stablecoin The stablecoin address\n     */\n    function subscribe(uint256 inAmount, address stablecoin) external;\n\n    /**\n     * @dev Emitted when a stablecoin configuration is updated\n     */\n    event SetStablecoinConfig(\n        address indexed stablecoin,\n        address oldSweepDestination,\n        address newSweepDestination,\n        uint96 oldFee,\n        uint96 newFee\n    );\n\n    /**\n     * @dev Emitted when stablecoins are used to Subscribe to a Superstate fund\n     * @param subscriber The address that paid the stablecoin (msg.sender)\n     * @param to The address that received the minted fund tokens\n     * @param stablecoin The stablecoin used to subscribe\n     * @param stablecoinInAmountAfterFee The stablecoin amount applied to the mint after the fee\n     * @param stablecoinInAmountBeforeFee The gross stablecoin amount deposited\n     * @param superstateTokenOutAmount The amount of fund tokens minted\n     * @param usdPerSuperstateTokenChainlinkRaw The Chainlink NAV price (USD per fund token, in oracle\n     *        feed decimals) used to price this subscription\n     */\n    event Subscribe(\n        address indexed subscriber,\n        address indexed to,\n        address stablecoin,\n        uint256 stablecoinInAmountAfterFee,\n        uint256 stablecoinInAmountBeforeFee,\n        uint256 superstateTokenOutAmount,\n        uint256 usdPerSuperstateTokenChainlinkRaw\n    );\n\n    /**\n     * @dev V5.1-compatible subscription event emitted alongside `Subscribe`\n     * @param subscriber The address that paid the stablecoin (msg.sender)\n     * @param to The address that received the minted fund tokens\n     * @param stablecoin The stablecoin used to subscribe\n     * @param stablecoinInAmountAfterFee The stablecoin amount applied to the mint after the fee\n     * @param stablecoinInAmountBeforeFee The gross stablecoin amount deposited\n     * @param superstateTokenOutAmount The amount of fund tokens minted\n     */\n    event SubscribeV2(\n        address indexed subscriber,\n        address indexed to,\n        address stablecoin,\n        uint256 stablecoinInAmountAfterFee,\n        uint256 stablecoinInAmountBeforeFee,\n        uint256 superstateTokenOutAmount\n    );\n\n    /**\n     * @dev Error thrown when a stablecoin is not supported\n     */\n    error StablecoinNotSupported();\n\n    /**\n     * @dev Error thrown when fee is too high\n     */\n    error FeeTooHigh();\n\n    /**\n     * @dev Error thrown when zero tokens would be output\n     */\n    error ZeroSuperstateTokensOutSubscribable();\n\n    /**\n     * @dev Error thrown when bad args are provided\n     */\n    error BadArgsSubscribable();\n}\n\n// dependencies/openzeppelin-contracts-upgradeable-v4.9.3-4.9.3/contracts/utils/StorageSlotUpgradeable.sol\n\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\n * _Available since v4.9 for `string`, `bytes`._\n */\nlibrary StorageSlotUpgradeable {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    struct StringSlot {\n        string value;\n    }\n\n    struct BytesSlot {\n        bytes value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n     */\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n     */\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := store.slot\n        }\n    }\n}\n\n// protocol/token/src/components/AccountingPausable.sol\n\n/**\n * @title AccountingPausable\n * @notice Abstract contract implementing pausable accounting functionality with ERC-7201 namespaced storage\n * @dev Allows pausing of minting and burning operations independently from transfers.\n *      The global `pause()` (PausableUpgradeable) freezes user transfers and subscriptions; this\n *      accounting pause freezes all issuance and burn paths (mint, bulkMint, adminBurn, offchainRedeem,\n *      bridge, buyTheDip, subscribe, and book-entry transfer-to-self). The two flags are orthogonal.\n *\n * @author Jake Goh Si Yuan @jakegsy (Superstate)\n * @custom:version 1.0.0\n * @custom:security-contact security@superstate.co\n */\nabstract contract AccountingPausable is IAccountingPausable {\n    /**\n     * @dev Storage struct using ERC-7201 namespaced pattern\n     * @custom:storage-location erc7201:superstate.storage.accountingPausable\n     */\n    struct AccountingPausableStorage {\n        bool accountingPaused;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(bytes(\"superstate.storage.accountingPausable\"))) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant ACCOUNTING_PAUSABLE_STORAGE_LOCATION =\n        0xa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e00;\n\n    /* Requirements for implementation:\n        1. _requireAuth() must be implemented by the inheriting contract\n    */\n\n    /**\n     * @dev Hook to require authorization for pausing/unpausing\n     * @notice Must be implemented by inheriting contract\n     */\n    function _requireAuth() internal view virtual;\n\n    /*\n        Provides the following to be used:\n        1. accountingPause() - pauses accounting operations, _requireAuth\n        2. accountingUnpause() - unpauses accounting operations, _requireAuth\n        3. isAccountingPaused() - returns whether accounting is paused, view only\n    */\n\n    /**\n     * @dev Pauses accounting operations (minting and burning)\n     * @notice Can only be called by authorized addresses (defined in inheriting contract)\n     */\n    function accountingPause() external virtual {\n        _requireAuth();\n        if (isAccountingPaused()) revert AccountingIsPaused();\n\n        _setAccountingPaused(true);\n        emit AccountingPaused(msg.sender);\n    }\n\n    /**\n     * @dev Unpauses accounting operations\n     * @notice Can only be called by authorized addresses (defined in inheriting contract)\n     */\n    function accountingUnpause() external virtual {\n        _requireAuth();\n        if (!isAccountingPaused()) revert AccountingIsNotPaused();\n\n        _setAccountingPaused(false);\n        emit AccountingUnpaused(msg.sender);\n    }\n\n    /**\n     * @dev Returns whether accounting is currently paused\n     * @return True if accounting is paused, false otherwise\n     */\n    function isAccountingPaused() public view virtual returns (bool) {\n        AccountingPausableStorage storage $ = _getAccountingPausableStorage();\n        return $.accountingPaused;\n    }\n\n    /**\n     * @dev Returns the AccountingPausableStorage struct\n     * @return $ Storage pointer to the AccountingPausableStorage struct\n     */\n    function _getAccountingPausableStorage() private pure returns (AccountingPausableStorage storage $) {\n        assembly {\n            $.slot := ACCOUNTING_PAUSABLE_STORAGE_LOCATION\n        }\n    }\n\n    /**\n     * @dev Sets the paused state of accounting\n     * @param paused The new paused state\n     */\n    function _setAccountingPaused(bool paused) internal {\n        AccountingPausableStorage storage $ = _getAccountingPausableStorage();\n        $.accountingPaused = paused;\n    }\n\n    function __AccountingPausable_init() internal {\n        _setAccountingPaused(false); // Unnecessary as starts false by default, done for clarity\n    }\n}\n\n// protocol/token/src/components/Bridgeable.sol\n\n/**\n * @title Bridgeable\n * @notice Abstract contract implementing cross-chain bridging functionality with ERC-7201 namespaced storage\n * @dev Allows tokens to be burned on one chain and minted on another chain via off-chain settlement.\n *      Chain ID 0 is reserved for book-entry conversions (burn to Superstate's off-chain ledger).\n *\n * @dev Key Features:\n *      - ERC-7201 namespaced storage pattern for upgrade safety\n *      - Configurable supported chain IDs for bridging destinations\n *      - Support for both EVM (address) and non-EVM (string) destination addresses\n *      - Book-entry conversion via chain ID 0\n *\n * @author Jake Goh Si Yuan @jakegsy (Superstate)\n * @custom:version 1.0.0\n * @custom:security-contact security@superstate.co\n */\nabstract contract Bridgeable is IBridgeable {\n    /**\n     * @dev Storage struct using ERC-7201 namespaced pattern\n     * @custom:storage-location erc7201:superstate.storage.bridgeable\n     */\n    struct BridgeableStorage {\n        mapping(uint256 chainId => bool supported) supportedChainIds;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(bytes(\"superstate.storage.bridgeable\"))) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant BRIDGEABLE_STORAGE_LOCATION =\n        0xe4e4f071f9b1db3b4b73cfb89f93997eef9d90809fdd474c473bf010d9361e00;\n    /*\n        Requirements for implementation:\n        1. _requireAuth() must be implemented by the inheriting contract\n        2. _requireNotAccountingPaused() must be implemented by the inheriting contract\n        3. _requireAllowed() must be implemented by the inheriting contract\n        4. _burn() must be implemented by the inheriting contract\n    */\n\n    /**\n     * @dev Hook to require authorization for administrative actions\n     * @notice Must be implemented by inheriting contract\n     */\n    function _requireAuth() internal view virtual;\n\n    /**\n     * @dev Hook to verify accounting (minting and burning) is not paused\n     * @notice Must be implemented by inheriting contract\n     */\n    function _requireNotAccountingPaused() internal view virtual;\n\n    /**\n     * @dev Hook to verify if an address is allowed\n     * @param addr The address to check\n     * @notice Must be implemented by inheriting contract\n     */\n    function _requireAllowed(address addr) internal view virtual;\n\n    /**\n     * @dev Hook to burn tokens\n     * @param from The address to burn tokens from\n     * @param amount The amount of tokens to burn\n     * @notice Must be implemented by inheriting contract\n     */\n    function _burn(address from, uint256 amount) internal virtual;\n\n    /*\n        Provides the following to be used:\n        1. setChainIdSupport(uint256 chainId, bool supported) - sets support status for a specific chain ID, _requireAuth\n        2. isChainIdSupported(uint256 chainId) public view\n        3. bridge(uint256 amount,\n        address ethDestinationAddress,\n        string memory otherDestinationAddress,\n        uint256 chainId)\n        4. bridgeToBookEntry(uint256 amount)\n    */\n    /**\n     * @dev Returns whether a chain ID is supported for bridging\n     * @param chainId The chain ID to check\n     * @return True if the chain ID is supported, false otherwise\n     */\n    function isChainIdSupported(uint256 chainId) public view returns (bool) {\n        BridgeableStorage storage $ = _getBridgeableStorage();\n        return $.supportedChainIds[chainId];\n    }\n\n    /**\n     * @dev Sets support status for a specific chain ID\n     * @param chainId The chain ID to update\n     * @param supported Whether the chain ID should be supported\n     */\n    function setChainIdSupport(uint256 chainId, bool supported) external virtual {\n        _requireAuth();\n\n        _setChainIdSupport(chainId, supported);\n    }\n\n    /**\n     * @notice Burns tokens from the caller to bridge to another chain\n     * @dev Reverts if chainId is not supported.\n     * @dev If destination address on chainId isn't on allowlist on the other chain, tokens burn to book entry.\n     * @dev Use chainId 0 to burn tokens to Superstate book entry.\n     * @param amount Amount of tokens to burn\n     * @param ethDestinationAddress ETH address to send to on another chain\n     * @param otherDestinationAddress Non-EVM addresses to send to on another chain\n     * @param chainId Numerical identifier of destination chain to send tokens to\n     */\n    function bridge(\n        uint256 amount,\n        address ethDestinationAddress,\n        string memory otherDestinationAddress,\n        uint256 chainId\n    ) public virtual {\n        _requireNotAccountingPaused();\n        _requireAllowed(msg.sender);\n\n        if (amount == 0) revert ZeroSuperstateTokensOutBridgeable();\n\n        if (ethDestinationAddress != address(0) && bytes(otherDestinationAddress).length != 0) {\n            revert TwoDestinationsInvalid();\n        }\n\n        if (chainId == 0 && (ethDestinationAddress != address(0) || bytes(otherDestinationAddress).length != 0)) {\n            revert OnchainDestinationSetForBridgeToBookEntry();\n        }\n\n        if (!isChainIdSupported(chainId)) revert BridgeChainIdDestinationNotSupported();\n\n        _burn(msg.sender, amount);\n\n        emit Bridge({\n            caller: msg.sender,\n            src: msg.sender,\n            amount: amount,\n            ethDestinationAddress: ethDestinationAddress,\n            otherDestinationAddress: otherDestinationAddress,\n            chainId: chainId\n        });\n    }\n\n    /**\n     * @dev Burns tokens from the caller to bridge to Superstate book entry\n     * @param amount Amount of tokens to burn\n     */\n    function bridgeToBookEntry(uint256 amount) external virtual {\n        bridge({\n            amount: amount,\n            ethDestinationAddress: address(0),\n            otherDestinationAddress: string(new bytes(0)),\n            chainId: 0\n        });\n    }\n    /**\n     * @dev Returns the BridgeableStorage struct\n     * @return $ Storage pointer to the BridgeableStorage struct\n     */\n\n    function _getBridgeableStorage() private pure returns (BridgeableStorage storage $) {\n        assembly {\n            $.slot := BRIDGEABLE_STORAGE_LOCATION\n        }\n    }\n\n    /**\n     * @dev Sets support status for a chain ID\n     * @param chainId The chain ID to update\n     * @param supported Whether the chain ID should be supported\n     */\n    function _setChainIdSupport(uint256 chainId, bool supported) internal {\n        BridgeableStorage storage $ = _getBridgeableStorage();\n\n        bool oldSupported = $.supportedChainIds[chainId];\n        if (oldSupported == supported) revert BadArgsBridgeable();\n        if (chainId == block.chainid) revert BridgeChainIdDestinationNotSupported();\n\n        $.supportedChainIds[chainId] = supported;\n\n        emit SetChainIdSupport({chainId: chainId, oldSupported: oldSupported, newSupported: supported});\n    }\n\n    function __Bridgeable_init() internal {\n        // Support chainId 0 for book entry\n        _setChainIdSupport(0, true);\n    }\n}\n\n// protocol/token/src/base/ERC20MetadataSettable.sol\n\n/**\n * @title ERC20MetadataSettable\n * @notice Abstract component for owner-controlled ERC20 name and symbol updates\n * @dev OZ `ERC20Upgradeable` stores `_name` and `_symbol` as private strings and only writes\n *      them from `__ERC20_init_unchained` under `onlyInitializing`. This component writes the\n *      inherited continuous-layout slots directly via `StorageSlotUpgradeable.getStringSlot`, so\n *      the compiler still emits the correct short/long string encoding.\n *\n *      Slot reference, inherited from `ERC20Upgradeable` through the token core:\n *      - Slot 54: `_name`\n *      - Slot 55: `_symbol`\n *\n *      Re-verify with `forge inspect FundToken storage` / `forge inspect EquityToken storage` if any\n *      inherited contract is upgraded or reordered.\n *\n * @dev This mixin only makes sense on top of {SuperstateTokenCore}'s linearization, which pins\n *      `_name`/`_symbol` to slots 54/55. To make that dependency structural rather than a loose\n *      convention, `SuperstateTokenCore is ERC20MetadataSettable` (this is its base, co-located in\n *      `src/base/`) — so tokens get these setters via the core and never mix this in against a\n *      foreign layout. The full layout table lives in {SuperstateTokenCore}; the 54/55 invariant is\n *      pinned by `FundTokenV5StorageLayoutTests`.\n *\n * @author Jake Goh Si Yuan @jakegsy (Superstate)\n * @custom:version 1.0.0\n * @custom:security-contact security@superstate.co\n */\nabstract contract ERC20MetadataSettable {\n    /// @dev Storage slot of `ERC20Upgradeable._name`.\n    bytes32 private constant ERC20_NAME_SLOT = bytes32(uint256(54));\n\n    /// @dev Storage slot of `ERC20Upgradeable._symbol`.\n    bytes32 private constant ERC20_SYMBOL_SLOT = bytes32(uint256(55));\n\n    /// @notice Emitted when the token name is updated by the owner\n    /// @param oldName The previous name returned by `name()`\n    /// @param newName The new name returned by `name()`\n    event NameSet(string oldName, string newName);\n\n    /// @notice Emitted when the token symbol is updated by the owner\n    /// @param oldSymbol The previous symbol returned by `symbol()`\n    /// @param newSymbol The new symbol returned by `symbol()`\n    event SymbolSet(string oldSymbol, string newSymbol);\n\n    /// @notice Reverts when attempting to set an empty token name\n    error InvalidName();\n\n    /// @notice Reverts when attempting to set an empty token symbol\n    error InvalidSymbol();\n\n    /*\n        Requirements for implementation:\n        1. _requireAuth() must be implemented by the inheriting contract\n    */\n\n    /**\n     * @dev Hook to require authorization for administrative actions\n     * @notice Must be implemented by inheriting contract\n     */\n    function _requireAuth() internal view virtual;\n\n    /**\n     * @notice Updates the token name returned by `name()`\n     * @param newName The new token name (must be non-empty)\n     *\n     * @dev Owner-only. Writes directly to `ERC20Upgradeable._name` (slot 54 in the continuous\n     *      storage layout), so all read paths — `name()`, derived `_name()`, and the EIP-712\n     *      `DOMAIN_SEPARATOR` (which hashes `_name()` on every call) — automatically reflect the\n     *      new value. Because the domain separator changes, any in-flight permit signatures bound\n     *      to the previous name are invalidated.\n     *\n     * @custom:access-control Only callable by contract owner\n     * @custom:throws InvalidName if `newName` is empty\n     * @custom:event Emits NameSet(oldName, newName)\n     */\n    function setName(string calldata newName) public virtual {\n        _requireAuth();\n        _setName(newName);\n    }\n\n    function _setName(string calldata newName) internal {\n        if (bytes(newName).length == 0) revert InvalidName();\n\n        string memory oldName = StorageSlotUpgradeable.getStringSlot(ERC20_NAME_SLOT).value;\n        StorageSlotUpgradeable.getStringSlot(ERC20_NAME_SLOT).value = newName;\n\n        emit NameSet(oldName, newName);\n    }\n\n    /**\n     * @notice Updates the token symbol returned by `symbol()`\n     * @param newSymbol The new token symbol (must be non-empty)\n     *\n     * @dev Owner-only. Writes directly to `ERC20Upgradeable._symbol` (slot 55 in the continuous\n     *      storage layout) via `StorageSlotUpgradeable.getStringSlot` for the same reason as\n     *      `setName`: OZ exposes no runtime setter and `_symbol` is `string private`.\n     *\n     * @dev Allowlist implications:\n     *      - Private instruments: `Allowlistable.isAllowed(addr)` calls\n     *        `IAllowlistAddressPermissions.isAddressAllowedForPrivateInstrument(addr, symbol())`,\n     *        so renaming the symbol re-keys the allowlist. Entities permissioned under the prior\n     *        symbol will no longer pass `isAllowed` until re-permissioned under the new symbol.\n     *        Admin operators must coordinate the symbol change with the allowlist contract.\n     *      - Public instruments: the public-instrument lookup does not take a symbol, so this\n     *        re-keying does not apply.\n     *\n     * @dev EIP-712: the permit domain separator hashes `_name()`, not the symbol, so symbol\n     *      changes do not invalidate outstanding permit signatures.\n     *\n     * @custom:access-control Only callable by contract owner\n     * @custom:throws InvalidSymbol if `newSymbol` is empty\n     * @custom:event Emits SymbolSet(oldSymbol, newSymbol)\n     */\n    function setSymbol(string calldata newSymbol) public virtual {\n        _requireAuth();\n        _setSymbol(newSymbol);\n    }\n\n    function _setSymbol(string calldata newSymbol) internal {\n        if (bytes(newSymbol).length == 0) revert InvalidSymbol();\n\n        string memory oldSymbol = StorageSlotUpgradeable.getStringSlot(ERC20_SYMBOL_SLOT).value;\n        StorageSlotUpgradeable.getStringSlot(ERC20_SYMBOL_SLOT).value = newSymbol;\n\n        emit SymbolSet(oldSymbol, newSymbol);\n    }\n}\n\n// dependencies/openzeppelin-contracts-v4.8.0-4.8.0/contracts/interfaces/IERC165.sol\n\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol)\n\n// dependencies/openzeppelin-contracts-v4.8.0-4.8.0/contracts/interfaces/IERC20.sol\n\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)\n\n// dependencies/openzeppelin-contracts-v4.8.0-4.8.0/contracts/token/ERC20/extensions/IERC20Metadata.sol\n\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol)\n\n/**\n * @dev Interface for the optional metadata functions from the ERC-20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n\n// dependencies/openzeppelin-contracts-upgradeable-v4.9.3-4.9.3/contracts/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\n\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n\n// dependencies/openzeppelin-contracts-upgradeable-v4.9.3-4.9.3/contracts/interfaces/IERC20Upgradeable.sol\n\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)\n\n// dependencies/openzeppelin-contracts-upgradeable-v4.9.3-4.9.3/contracts/proxy/utils/Initializable.sol\n\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\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 Indicates that the contract has been initialized.\n     * @custom:oz-retyped-from bool\n     */\n    uint8 private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint8 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 functions marked with `initializer` can be nested in the context of a\n     * constructor.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        bool isTopLevelCall = !_initializing;\n        require(\n            (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n            \"Initializable: contract is already initialized\"\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 255 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint8 version) {\n        require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\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        require(_initializing, \"Initializable: contract is not initializing\");\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        require(!_initializing, \"Initializable: contract is initializing\");\n        if (_initialized != type(uint8).max) {\n            _initialized = type(uint8).max;\n            emit Initialized(type(uint8).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint8) {\n        return _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 _initializing;\n    }\n}\n\n// protocol/token/src/components/Redeemable.sol\n\n/**\n * @title Redeemable\n * @notice Abstract contract implementing redemption functionality with ERC-7201 namespaced storage\n * @dev Enables tokens to be redeemed through a dedicated redemption contract.\n *\n * @dev Key Features:\n *      - ERC-7201 namespaced storage pattern for upgrade safety\n *      - Configurable redemption contract address\n *      - Integration point for on-chain redemption workflows\n *\n * @author Jake Goh Si Yuan @jakegsy (Superstate)\n * @custom:version 1.0.0\n * @custom:security-contact security@superstate.co\n */\nabstract contract Redeemable is IRedeemable {\n    /**\n     * @dev Storage struct using ERC-7201 namespaced pattern\n     * @custom:storage-location erc7201:superstate.storage.redeemable\n     */\n    struct RedeemableStorage {\n        address redemptionContract;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(bytes(\"superstate.storage.redeemable\"))) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant REDEEMABLE_STORAGE_LOCATION =\n        0x42cf13beef4be89e96f7a42d686186f293b460f8ac2f0416fbe254d1afb6ff00;\n\n    /*  Requirements for implementation:\n        1. _requireAuth() must be implemented by the inheriting contract\n        2. _requireNotAccountingPaused() must be implemented by the inheriting contract\n        3. _requireAllowed() must be implemented by the inheriting contract\n        4. _burn() must be implemented by the inheriting contract\n    */\n\n    /*\n        Provides the following to be used on inheritance:\n        1. offchainRedeem(amount) - burns token and emits offchainRedeem\n        2. getRedemptionContract - returns the redemption contract\n        3. setRedemptionContract - sets the redemption contract, auth only\n\n    */\n\n    /**\n     * @dev Burns tokens from the caller's address for offchain redemption\n     * @param amount Amount of tokens to burn\n     */\n    function offchainRedeem(uint256 amount) external virtual {\n        _requireNotAccountingPaused();\n        _requireAllowed(msg.sender);\n\n        _burn(msg.sender, amount);\n        emit OffchainRedeem(msg.sender, msg.sender, amount);\n    }\n\n    /**\n     * @dev Returns the RedeemableStorage struct\n     * @return $ Storage pointer to the RedeemableStorage struct\n     */\n    function _getRedeemableStorage() private pure returns (RedeemableStorage storage $) {\n        assembly {\n            $.slot := REDEEMABLE_STORAGE_LOCATION\n        }\n    }\n\n    /**\n     * @dev Returns the current redemption contract address\n     * @return The address of the redemption contract\n     */\n    function getRedemptionContract() public view returns (address) {\n        RedeemableStorage storage $ = _getRedeemableStorage();\n        return $.redemptionContract;\n    }\n\n    /**\n     * @dev Sets the redemption contract address\n     * @param _newRedemptionContract The new redemption contract address\n     */\n    function _setRedemptionContract(address _newRedemptionContract) internal {\n        RedeemableStorage storage $ = _getRedeemableStorage();\n\n        if ($.redemptionContract == _newRedemptionContract) revert BadArgsRedeemable();\n\n        emit SetRedemptionContract($.redemptionContract, _newRedemptionContract);\n        $.redemptionContract = _newRedemptionContract;\n    }\n\n    /**\n     * @notice Sets redemption contract address\n     * @dev Used for convenience for devs\n     * @dev Set to address(0) if no such contract exists for the token\n     * @param _newRedemptionContract New contract address\n     */\n    function setRedemptionContract(address _newRedemptionContract) external virtual {\n        _requireAuth();\n        _setRedemptionContract(_newRedemptionContract);\n    }\n\n    /**\n     * @dev Hook to require authorization for administrative actions\n     * @notice Must be implemented by inheriting contract\n     */\n    function _requireAuth() internal view virtual;\n\n    /**\n     * @dev Hook to verify accounting (minting and burning) is not paused\n     * @notice Must be implemented by inheriting contract\n     */\n    function _requireNotAccountingPaused() internal view virtual;\n\n    /**\n     * @dev Hook to verify if an address is allowed\n     * @param addr The address to check\n     * @notice Must be implemented by inheriting contract\n     */\n    function _requireAllowed(address addr) internal view virtual;\n\n    /**\n     * @dev Hook to burn tokens\n     * @param from The address to burn tokens from\n     * @param amount The amount of tokens to burn\n     * @notice Must be implemented by inheriting contract\n     */\n    function _burn(address from, uint256 amount) internal virtual;\n\n    function __Redeemable_init(address redemption) internal {\n        // Skip if no redemption contract configured (e.g., USCC migration)\n        if (redemption != address(0)) {\n            _setRedemptionContract(redemption);\n        }\n    }\n}\n\n// protocol/token/src/components/Allowlistable.sol\n\n/**\n * @title Allowlistable.sol\n * @notice Abstract contract implementing allowlist functionality with ERC-7201 namespaced storage\n * @dev Enables checking if addresses have permission to interact with the token.\n *      Supports both public instruments (entity-level permissions) and private instruments\n *      (instrument-specific permissions keyed by token symbol).\n *\n * @dev Key Features:\n *      - ERC-7201 namespaced storage pattern for upgrade safety\n *      - Public/private instrument permission modes\n *      - Delegated permission checks to external allowlist contract\n *\n * @author Jake Goh Si Yuan @jakegsy (Superstate)\n * @custom:version 1.1.0\n * @custom:security-contact security@superstate.co\n */\nabstract contract Allowlistable is IAllowlistable {\n    /**\n     * @dev Storage struct using ERC-7201 namespaced pattern\n     * @custom:storage-location erc7201:superstate.storage.allowlistable\n     */\n    struct AllowlistableStorage {\n        address allowlist;\n        bool isPublicInstrument;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(bytes(\"superstate.storage.allowlistable\"))) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant ALLOWLISTABLE_STORAGE_LOCATION =\n        0x20f9d398b060d72baa41f68a4a570507058bbfd6bb960620e2b61718f38ded00;\n\n    /*\n        Provides the following to be used on inheritance:\n        1. allowlist() - returns the current allowlist contract address\n        2. _setAllowlist(address _newAllowlist) - sets the allowlist contract address\n        3. isAllowed(address addr) - checks if an address is allowed (auto-selects public/private check)\n        4. isPublicInstrument() - returns whether instrument is public or private\n        5. _setIsPublicInstrument(bool _isPublicInstrument) - sets instrument type\n        6. symbol() - abstract, must be implemented by inheriting contract\n    */\n\n    /**\n     * @dev Returns the current allowlist contract\n     * @return The allowlist contract instance\n     */\n    function allowlist() public view virtual returns (address) {\n        AllowlistableStorage storage $ = _getAllowlistableStorage();\n        return $.allowlist;\n    }\n\n    /**\n     * @dev Returns whether the instrument is public or private\n     * @return True if the instrument is public, false if private\n     */\n    function isPublicInstrument() public view virtual returns (bool) {\n        AllowlistableStorage storage $ = _getAllowlistableStorage();\n        return $.isPublicInstrument;\n    }\n\n    /**\n     * @dev Sets the allowlist contract\n     * @param _newAllowlist The new allowlist contract to use\n     */\n    function _setAllowlist(address _newAllowlist) internal {\n        if (_newAllowlist == address(0)) revert ZeroAddressNotAllowed();\n        AllowlistableStorage storage $ = _getAllowlistableStorage();\n        if ($.allowlist == _newAllowlist) revert AlreadySet();\n\n        emit AllowlistUpdated(address($.allowlist), address(_newAllowlist));\n        $.allowlist = _newAllowlist;\n    }\n\n    /**\n     * @dev Sets whether the instrument is public or private\n     * @param _isPublicInstrument True if the instrument is public, false if private\n     */\n    function _setIsPublicInstrument(bool _isPublicInstrument) internal {\n        AllowlistableStorage storage $ = _getAllowlistableStorage();\n\n        emit IsPublicInstrumentUpdated($.isPublicInstrument, _isPublicInstrument);\n        $.isPublicInstrument = _isPublicInstrument;\n    }\n\n    /**\n     * @dev Checks if an address is allowed based on instrument type\n     * @param addr The address to check\n     * @return True if the address is allowed, false otherwise\n     * @notice Automatically uses public or private permission check based on isPublicInstrument().\n     *         Uses V3 compat functions on allowlist for smooth AllowlistV3→V4 upgrade.\n     */\n    function isAllowed(address addr) public view virtual returns (bool) {\n        address _allowlist = allowlist();\n        if (_allowlist == address(0)) return false;\n\n        if (isPublicInstrument()) {\n            return IAllowlistAddressPermissions(_allowlist).isAddressAllowedForPublicInstrument(addr);\n        } else {\n            return IAllowlistAddressPermissions(_allowlist).isAddressAllowedForPrivateInstrument(addr, symbol());\n        }\n    }\n\n    /**\n     * @dev Returns the token symbol\n     * @return The token symbol\n     * @notice Inherited from ERC20 in implementing contracts\n     */\n    function symbol() public view virtual returns (string memory);\n\n    /**\n     * @dev Returns the AllowlistableStorage struct\n     * @return $ Storage pointer to the AllowlistableStorage struct\n     */\n    function _getAllowlistableStorage() private pure returns (AllowlistableStorage storage $) {\n        assembly {\n            $.slot := ALLOWLISTABLE_STORAGE_LOCATION\n        }\n    }\n\n    /**\n     * @dev Initialize the allowlist during contract initialization\n     * @param _allowlist The allowlist contract to set\n     * @param _isPublicInstrument Whether the instrument is public (true) or private (false)\n     */\n    function __Allowlistable_init(address _allowlist, bool _isPublicInstrument) internal {\n        _setAllowlist(_allowlist);\n        _setIsPublicInstrument(_isPublicInstrument);\n    }\n}\n\n// dependencies/openzeppelin-contracts-upgradeable-v4.9.3-4.9.3/contracts/utils/ContextUpgradeable.sol\n\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n\n// protocol/token/src/components/OracleConsumable.sol\n\n/**\n * @title OracleConsumable\n * @notice Abstract contract implementing Chainlink oracle consumption with ERC-7201 namespaced storage\n * @dev Enables fetching and validating price data from a Chainlink oracle.\n *\n * @dev Key Features:\n *      - ERC-7201 namespaced storage pattern for upgrade safety\n *      - Chainlink AggregatorV3Interface integration\n *      - Configurable maximum oracle delay for staleness checks\n *      - Minimum acceptable price floor ($7.00) to prevent manipulation\n *\n * @author Jake Goh Si Yuan @jakegsy (Superstate)\n * @custom:version 1.0.0\n * @custom:security-contact security@superstate.co\n */\nabstract contract OracleConsumable is IOracleConsumable {\n    /**\n     * @dev Storage struct using ERC-7201 namespaced pattern\n     * @custom:storage-location erc7201:superstate.storage.oracleConsumable\n     */\n    struct OracleConsumableStorage {\n        address superstateOracle;\n        uint256 maximumOracleDelay;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(bytes(\"superstate.storage.oracleConsumable\"))) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant ORACLE_CONSUMABLE_STORAGE_LOCATION =\n        0xa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d00;\n\n    /*  Requirements for implementation:\n        1. _requireAuth() must be implemented by the inheriting contract\n        2. _getMinimumAcceptablePrice() must be implemented by the inheriting contract\n    */\n\n    /**\n     * @dev Hook to require authorization for administrative actions\n     * @notice Must be implemented by inheriting contract\n     */\n    function _requireAuth() internal view virtual;\n\n    /**\n     * @dev Hook to get the minimum acceptable price\n     * @notice Must be implemented by inheriting contract\n     * @return The minimum acceptable price\n     */\n    function _getMinimumAcceptablePrice() internal view virtual returns (uint256);\n\n    /*\n        Provides the following to be used on inheritance:\n        1. superstateOracle() - returns the current oracle contract address, view only\n        2. getChainlinkPrice - returns the Chainlink price result tuple(_isBadData, _updatedAt, _price) view only\n        3. maximumOracleDelay() - returns the maximum oracle delay, view only\n        4. setMaximumOracleDelay(delay) - sets the maximum oracle delay, auth\n        5. setOracle(_newOracle) - sets the new oracle, auth\n        6. _requireOnchainSubscriptionsEnabled - as titled, gate.\n    */\n\n    /**\n     * @dev Returns the oracle address\n     * @return The address of the oracle\n     */\n    function superstateOracle() public view returns (address) {\n        OracleConsumableStorage storage $ = _getOracleConsumableStorage();\n        return $.superstateOracle;\n    }\n    /**\n     * @dev Gets the Chainlink price data\n     * @return _isBadData True if the data is stale or below threshold\n     * @return _updatedAt The timestamp of the last update\n     * @return _price The price from the oracle\n     */\n\n    function getChainlinkPrice() external view virtual returns (bool _isBadData, uint256 _updatedAt, uint256 _price) {\n        return _getChainlinkPrice();\n    }\n\n    /**\n     * @dev Returns the maximum oracle delay\n     * @return The maximum acceptable delay in seconds\n     */\n    function maximumOracleDelay() public view returns (uint256) {\n        OracleConsumableStorage storage $ = _getOracleConsumableStorage();\n        return $.maximumOracleDelay;\n    }\n\n    /**\n     * @dev Sets the maximum oracle delay\n     * @param _newMaxOracleDelay The new maximum delay in seconds\n     */\n    function setMaximumOracleDelay(uint256 _newMaxOracleDelay) external virtual {\n        _requireAuth();\n        _setMaximumOracleDelay(_newMaxOracleDelay);\n    }\n\n    /**\n     * @dev Sets the oracle address\n     * @param _newOracle The new oracle address\n     */\n    function setOracle(address _newOracle) external virtual {\n        _requireAuth();\n        _setOracle(_newOracle);\n    }\n\n    /**\n     * @dev Checks if onchain subscriptions are enabled\n     */\n    function _requireOnchainSubscriptionsEnabled() internal view {\n        if (superstateOracle() == address(0) || maximumOracleDelay() == 0) {\n            revert OnchainSubscriptionsDisabled();\n        }\n    }\n\n    /**\n     * @dev Sets the oracle address\n     * @param _newOracle The new oracle address\n     */\n    function _setOracle(address _newOracle) internal {\n        OracleConsumableStorage storage $ = _getOracleConsumableStorage();\n\n        if (_newOracle == $.superstateOracle) revert BadArgsOracleConsumable();\n\n        emit SetOracle($.superstateOracle, _newOracle);\n        $.superstateOracle = _newOracle;\n    }\n\n    /**\n     * @dev Sets the maximum oracle delay\n     * @param _newMaxOracleDelay The new maximum delay in seconds\n     * @notice Oracle integration inspired by: https://github.com/FraxFinance/frax-oracles/blob/bd56532a3c33da95faed904a5810313deab5f13c/src/abstracts/ChainlinkOracleWithMaxDelay.sol\n     */\n    function _setMaximumOracleDelay(uint256 _newMaxOracleDelay) internal {\n        OracleConsumableStorage storage $ = _getOracleConsumableStorage();\n\n        if (_newMaxOracleDelay == $.maximumOracleDelay) revert BadArgsOracleConsumable();\n\n        emit SetMaximumOracleDelay($.maximumOracleDelay, _newMaxOracleDelay);\n        $.maximumOracleDelay = _newMaxOracleDelay;\n    }\n\n    /**\n     * @dev Gets the Chainlink price data\n     * @return _isBadData True if the data is stale or below threshold\n     * @return _updatedAt The timestamp of the last update\n     * @return _price The price from the oracle\n     */\n    function _getChainlinkPrice() internal view returns (bool _isBadData, uint256 _updatedAt, uint256 _price) {\n        _requireOnchainSubscriptionsEnabled();\n\n        (, int256 _answer,, uint256 _chainlinkUpdatedAt,) = AggregatorV3Interface(superstateOracle()).latestRoundData();\n\n        // If data is stale or below first price, set bad data to true and return\n        // 10_000_000 is $10.000000 in the oracle format (6 decimals), that was our starting NAV per Share price for SUPERSTATE_TOKEN\n        // The oracle should never return a price much lower than this\n\n        // If data is stale or below minimum acceptable price, set bad data to true\n        _isBadData = _answer < int256(_getMinimumAcceptablePrice())\n            || ((block.timestamp - _chainlinkUpdatedAt) > maximumOracleDelay());\n        _updatedAt = _chainlinkUpdatedAt;\n        _price = uint256(_answer);\n    }\n\n    /**\n     * @dev Returns the OracleConsumableStorage struct\n     * @return $ Storage pointer to the OracleConsumableStorage struct\n     */\n    function _getOracleConsumableStorage() private pure returns (OracleConsumableStorage storage $) {\n        assembly {\n            $.slot := ORACLE_CONSUMABLE_STORAGE_LOCATION\n        }\n    }\n\n    function __OracleConsumable_init(address oracle, uint256 maxDelay) internal {\n        // Skip if no oracle configured (e.g., USCC migration)\n        if (oracle != address(0)) {\n            _setOracle(oracle);\n            _setMaximumOracleDelay(maxDelay);\n        }\n    }\n}\n\n// protocol/token/src/components/Permittable.sol\n\n/**\n * @title Permittable\n * @notice Abstract contract implementing EIP-712 compliant permit functionality with ERC-7201 namespaced storage\n * @dev Allows approval of token spending through signatures (EIP-2612).\n *\n * @dev Key Features:\n *      - ERC-7201 namespaced storage pattern for upgrade safety\n *      - EIP-2612 permit() for gasless approvals\n *      - EIP-712 typed structured data signing\n *      - Per-address nonce tracking for replay protection\n *      - Domain separator caching with chain ID validation\n *\n * @author Jake Goh Si Yuan @jakegsy (Superstate)\n * @custom:version 1.0.0\n * @custom:security-contact security@superstate.co\n */\nabstract contract Permittable is IPermittable {\n    /**\n     * @dev Storage struct using ERC-7201 namespaced pattern\n     * @custom:storage-location erc7201:superstate.storage.permittable\n     */\n    struct PermittableStorage {\n        /// @notice The next expected nonce for an address, for validating authorizations via signature\n        mapping(address => uint256) nonces;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(bytes(\"superstate.storage.permittable\"))) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant PERMITTABLE_STORAGE_LOCATION =\n        0x61eb30d84d4dfa1c5d0f066f60f5c357c05c83c2a042c60a480d47da76483800;\n    /* Requirements for implementation:\n        1. _approve() must be implemented by the inheriting contract\n        2. _name() must be implemented by the inheriting contract, referencing to token name to be used for domain separator\n        3. _version() must be implemented by the inheriting contract, referencing to contract version to be used for domain separator\n    */\n\n    /**\n     * @dev Hook to approve token spending\n     * @param owner The token owner\n     * @param spender The token spender\n     * @param amount The amount of tokens to approve\n     * @notice Must be implemented by inheriting contract\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual;\n\n    /**\n     * @dev Hook to get the token name\n     * @notice Must be implemented by inheriting contract\n     * @return The name of the token\n     */\n    function _name() internal view virtual returns (string memory);\n\n    /**\n     * @dev Hook to get the version\n     * @notice Must be implemented by inheriting contract\n     * @return The version string\n     */\n    function _version() internal view virtual returns (string memory);\n\n    /*\n        Provides the following to be used on inheritance:\n        1. nonces(address owner) public view virtual returns (uint256)\n        2. permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)\n        3. DOMAIN_SEPARATOR() public view virtual returns (bytes32)\n    *\n    */\n\n    /**\n     * @dev Returns the current nonce for an address\n     * @param owner The address to get the nonce for\n     * @return The current nonce\n     */\n    function nonces(address owner) public view virtual returns (uint256) {\n        PermittableStorage storage $ = _getPermittableStorage();\n        return $.nonces[owner];\n    }\n    /**\n     * @dev Sets approval amount for a spender via signature from signatory\n     * @param owner The address that signed the signature\n     * @param spender The address to authorize (or rescind authorization from)\n     * @param value Amount that `owner` is approving for `spender`\n     * @param deadline Expiration time for the signature\n     * @param v The recovery byte of the signature\n     * @param r Half of the ECDSA signature pair\n     * @param s Half of the ECDSA signature pair\n     */\n\n    function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)\n        external\n        virtual\n    {\n        if (block.timestamp > deadline) revert SignatureExpired();\n\n        uint256 currentNonce = nonces(owner);\n        bytes32 structHash =\n            keccak256(abi.encode(AUTHORIZATION_TYPEHASH, owner, spender, value, currentNonce, deadline));\n        bytes32 digest = keccak256(abi.encodePacked(\"\\x19\\x01\", DOMAIN_SEPARATOR(), structHash));\n\n        if (_isValidSignature(owner, digest, v, r, s)) {\n            _incrementNonce(owner);\n            _approve(owner, spender, value);\n        }\n    }\n    /**\n     * @dev Returns the domain separator used in the encoding of the signature for permit\n     * @return bytes32 The domain separator\n     */\n\n    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\n        return keccak256(\n            abi.encode(\n                DOMAIN_TYPEHASH, keccak256(bytes(_name())), keccak256(bytes(_version())), block.chainid, address(this)\n            )\n        );\n    }\n\n    /// @dev The EIP-712 typehash for authorization via permit\n    bytes32 internal constant AUTHORIZATION_TYPEHASH =\n        keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n\n    /// @dev The EIP-712 typehash for the contract's domain\n    bytes32 internal constant DOMAIN_TYPEHASH =\n        keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n    /**\n     * @dev Returns the PermittableStorage struct\n     * @return $ Storage pointer to the PermittableStorage struct\n     */\n    function _getPermittableStorage() private pure returns (PermittableStorage storage $) {\n        assembly {\n            $.slot := PERMITTABLE_STORAGE_LOCATION\n        }\n    }\n\n    /**\n     * @dev Increments the nonce for an address\n     * @param owner The address to increment the nonce for\n     */\n    function _incrementNonce(address owner) internal {\n        PermittableStorage storage $ = _getPermittableStorage();\n        $.nonces[owner]++;\n    }\n\n    /**\n     * @dev Checks if a signature is valid\n     * @param signer The address that signed the signature\n     * @param digest The hashed message that is signed\n     * @param v The recovery byte of the signature\n     * @param r Half of the ECDSA signature pair\n     * @param s Half of the ECDSA signature pair\n     * @return bool Whether the signature is valid\n     */\n    function _isValidSignature(address signer, bytes32 digest, uint8 v, bytes32 r, bytes32 s)\n        internal\n        pure\n        returns (bool)\n    {\n        (address recoveredSigner, ECDSA.RecoverError recoverError,) = ECDSA.tryRecover(digest, v, r, s);\n\n        if (recoverError == ECDSA.RecoverError.InvalidSignatureS) revert InvalidSignatureS();\n        if (recoverError == ECDSA.RecoverError.InvalidSignature) revert BadSignatory();\n        if (recoveredSigner != signer) revert BadSignatory();\n\n        return true;\n    }\n\n    function __Permittable_init() internal {}\n}\n\n// dependencies/openzeppelin-contracts-upgradeable-v4.9.3-4.9.3/contracts/access/OwnableUpgradeable.sol\n\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    function __Ownable_init() internal onlyInitializing {\n        __Ownable_init_unchained();\n    }\n\n    function __Ownable_init_unchained() internal onlyInitializing {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n\n// dependencies/openzeppelin-contracts-upgradeable-v4.9.3-4.9.3/contracts/security/PausableUpgradeable.sol\n\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n    /**\n     * @dev Emitted when the pause is triggered by `account`.\n     */\n    event Paused(address account);\n\n    /**\n     * @dev Emitted when the pause is lifted by `account`.\n     */\n    event Unpaused(address account);\n\n    bool private _paused;\n\n    /**\n     * @dev Initializes the contract in unpaused state.\n     */\n    function __Pausable_init() internal onlyInitializing {\n        __Pausable_init_unchained();\n    }\n\n    function __Pausable_init_unchained() internal onlyInitializing {\n        _paused = false;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is not paused.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    modifier whenNotPaused() {\n        _requireNotPaused();\n        _;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is paused.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    modifier whenPaused() {\n        _requirePaused();\n        _;\n    }\n\n    /**\n     * @dev Returns true if the contract is paused, and false otherwise.\n     */\n    function paused() public view virtual returns (bool) {\n        return _paused;\n    }\n\n    /**\n     * @dev Throws if the contract is paused.\n     */\n    function _requireNotPaused() internal view virtual {\n        require(!paused(), \"Pausable: paused\");\n    }\n\n    /**\n     * @dev Throws if the contract is not paused.\n     */\n    function _requirePaused() internal view virtual {\n        require(paused(), \"Pausable: not paused\");\n    }\n\n    /**\n     * @dev Triggers stopped state.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    function _pause() internal virtual whenNotPaused {\n        _paused = true;\n        emit Paused(_msgSender());\n    }\n\n    /**\n     * @dev Returns to normal state.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    function _unpause() internal virtual whenPaused {\n        _paused = false;\n        emit Unpaused(_msgSender());\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n\n// dependencies/openzeppelin-contracts-v4.8.0-4.8.0/contracts/interfaces/IERC1363.sol\n\n// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol)\n\n/**\n * @title IERC1363\n * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].\n *\n * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract\n * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.\n */\ninterface IERC1363 is IERC20, IERC165 {\n    /*\n     * Note: the ERC-165 identifier for this interface is 0xb0202a11.\n     * 0xb0202a11 ===\n     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))\n     */\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @param data Additional data with no specified format, sent in call to `spender`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);\n}\n\n// dependencies/openzeppelin-contracts-upgradeable-v4.9.3-4.9.3/contracts/access/Ownable2StepUpgradeable.sol\n\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\n    function __Ownable2Step_init() internal onlyInitializing {\n        __Ownable_init_unchained();\n    }\n\n    function __Ownable2Step_init_unchained() internal onlyInitializing {\n    }\n    address private _pendingOwner;\n\n    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Returns the address of the pending owner.\n     */\n    function pendingOwner() public view virtual returns (address) {\n        return _pendingOwner;\n    }\n\n    /**\n     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual override onlyOwner {\n        _pendingOwner = newOwner;\n        emit OwnershipTransferStarted(owner(), newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual override {\n        delete _pendingOwner;\n        super._transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev The new owner accepts the ownership transfer.\n     */\n    function acceptOwnership() public virtual {\n        address sender = _msgSender();\n        require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n        _transferOwnership(sender);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n\n// dependencies/openzeppelin-contracts-upgradeable-v4.9.3-4.9.3/contracts/token/ERC20/ERC20Upgradeable.sol\n\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n        __ERC20_init_unchained(name_, symbol_);\n    }\n\n    function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, allowance(owner, spender) + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        uint256 currentAllowance = allowance(owner, spender);\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(owner, spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n            // decrementing then incrementing.\n            _balances[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        unchecked {\n            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n            _balances[account] += amount;\n        }\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n            // Overflow not possible: amount <= accountBalance <= totalSupply.\n            _totalSupply -= amount;\n        }\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[45] private __gap;\n}\n\n// dependencies/openzeppelin-contracts-v4.8.0-4.8.0/contracts/token/ERC20/utils/SafeERC20.sol\n\n// OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/utils/SafeERC20.sol)\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC-20 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    /**\n     * @dev An operation with an ERC-20 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 Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {\n        return _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value)));\n    }\n\n    /**\n     * @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {\n        return _callOptionalReturnBool(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     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\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     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\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     * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function\n     * only sets the \"standard\" allowance. Any temporary allowance will remain active, in addition to the value being\n     * set here.\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 Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            safeTransfer(token, to, value);\n        } else if (!token.transferAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target\n     * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferFromAndCallRelaxed(\n        IERC1363 token,\n        address from,\n        address to,\n        uint256 value,\n        bytes memory data\n    ) internal {\n        if (to.code.length == 0) {\n            safeTransferFrom(token, from, to, value);\n        } else if (!token.transferFromAndCall(from, to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.\n     * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}\n     * once without retrying, and relies on the returned value to be true.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            forceApprove(token, to, value);\n        } else if (!token.approveAndCall(to, value, data)) {\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 {_callOptionalReturnBool} that reverts if call fails to meet the requirements.\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        uint256 returnSize;\n        uint256 returnValue;\n        assembly (\"memory-safe\") {\n            let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n            // bubble errors\n            if iszero(success) {\n                let ptr := mload(0x40)\n                returndatacopy(ptr, 0, returndatasize())\n                revert(ptr, returndatasize())\n            }\n            returnSize := returndatasize()\n            returnValue := mload(0)\n        }\n\n        if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {\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 silently catches all reverts and returns a bool instead.\n     */\n    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n        bool success;\n        uint256 returnSize;\n        uint256 returnValue;\n        assembly (\"memory-safe\") {\n            success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n            returnSize := returndatasize()\n            returnValue := mload(0)\n        }\n        return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);\n    }\n}\n\n// protocol/token/src/interfaces/IFundTokenV1.sol\n\n/**\n * @title IFundTokenV1\n * @notice Comprehensive interface for Superstate's FundToken implementation with subscription and redemption support\n * @dev This interface defines the complete API for Superstate's fund tokens (e.g., USTB, USCC), including:\n *      - ERC20 standard token functionality\n *      - KYC/AML compliance through allowlist integration\n *      - Multi-chain bridging capabilities\n *      - EIP-2612 permit functionality for gasless approvals\n *      - On-chain subscription via stablecoin with Chainlink oracle pricing\n *      - On-chain USDC redemption integration\n *      - Admin controls for minting and burning\n *\n * @dev Interface Composition:\n *      The interface extends multiple specialized interfaces:\n *      - IERC20Upgradeable: Standard ERC20 token operations\n *      - IPermittable: EIP-2612 gasless approval support\n *      - IAccountingPausable: Accounting pause for all mint/burn operations\n *      - IBridgeable: Cross-chain and book-entry transfer capabilities\n *      - IAllowlistable: KYC/AML compliance enforcement\n *      - IRedeemable: On-chain USDC redemption\n *      - ISubscribable: Stablecoin subscription (minting) with oracle pricing\n *\n * @author Jake Goh Si Yuan @jakegsy (Superstate)\n * @custom:version 1.3.0\n * @custom:security-contact security@superstate.co\n */\ninterface IFundTokenV1 is\n    IERC20Upgradeable,\n    IPermittable,\n    IAccountingPausable,\n    IBridgeable,\n    IAllowlistable,\n    IRedeemable,\n    ISubscribable\n{\n    /*//////////////////////////////////////////////////////////////\n                    V5.1 COMPATIBILITY GETTERS\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Returns the fixed six-decimal token precision used by V5.1 integrations\n    function SUPERSTATE_TOKEN_PRECISION() external view returns (uint256);\n\n    /// @notice V5.1-compatible alias for `isAccountingPaused()`\n    function accountingPaused() external view returns (bool);\n\n    /// @notice V5.1-compatible alias for `allowlist()`\n    function allowlistV2() external view returns (address);\n\n    /// @notice V5.1-compatible alias for `getRedemptionContract()`\n    function redemptionContract() external view returns (address);\n\n    /// @notice V5.1-compatible alias for `isChainIdSupported(uint256)`\n    function supportedChainIds(uint256 chainId) external view returns (bool);\n\n    /*//////////////////////////////////////////////////////////////\n                                ERRORS\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice Thrown when attempting to call the disabled renounceOwnership function\n    /// @dev Ownership renunciation is permanently disabled to prevent loss of contract control\n    error RenounceOwnershipDisabled();\n\n    /// @notice Thrown when attempting an invalid transfer to the token contract itself\n    /// @dev Transfers to self are handled specially as off-chain redemption operations\n    error InvalidTransferToTokenContract();\n\n    /// @notice Thrown when array parameters have mismatched or zero lengths\n    /// @dev Used in bulk operations like bulkMint\n    error InvalidArgumentLengths();\n\n    /// @notice Thrown when a caller lacks the required authorization\n    /// @dev Typically thrown when non-owner attempts admin operations\n    error Unauthorized();\n\n    /*//////////////////////////////////////////////////////////////\n                                EVENTS\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     * @notice Emitted when an admin burns tokens from any address\n     * @param burner The admin address that initiated the burn\n     * @param src The address from which tokens were burned\n     * @param amount The amount of tokens burned (6 decimals)\n     *\n     * @dev Distinct from standard Transfer event to track admin actions\n     * @custom:security Allows tracking of admin-initiated burns for audit purposes\n     */\n    event AdminBurn(address indexed burner, address indexed src, uint256 amount);\n\n    /**\n     * @notice Emitted when new tokens are minted\n     * @param minter The admin address that initiated the mint\n     * @param to The address receiving the newly minted tokens\n     * @param amount The amount of tokens minted (6 decimals)\n     *\n     * @dev Supplements the standard Transfer event for mint tracking\n     * @custom:security Critical for supply tracking and audit trails\n     */\n    event Mint(address indexed minter, address indexed to, uint256 amount);\n\n    /*//////////////////////////////////////////////////////////////\n                        PAUSE MANAGEMENT\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     * @notice Pauses all token transfers\n     *\n     * @dev Emergency Control Function:\n     *      - Halts all transfer operations\n     *      - Can only be called when currently unpaused\n     *\n     * @custom:access-control Only callable by contract owner\n     * @custom:event Emits Paused event from PausableUpgradeable\n     */\n    function pause() external;\n\n    /**\n     * @notice Unpauses token transfers\n     *\n     * @dev Resume Operations:\n     *      - Re-enables all previously paused transfer operations\n     *      - Can only be called when currently paused\n     *\n     * @custom:access-control Only callable by contract owner\n     * @custom:event Emits Unpaused event from PausableUpgradeable\n     */\n    function unpause() external;\n\n    /*//////////////////////////////////////////////////////////////\n                        ADMIN FUNCTIONS\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     * @notice Burns tokens from a specified address (admin function)\n     * @param src Address from which tokens will be burned\n     * @param amount Amount of tokens to burn (6 decimals)\n     *\n     * @dev Admin Burn Capabilities:\n     *      - Allows admin to burn tokens from any address without approval\n     *      - Requires contract not to be paused\n     *\n     * @custom:access-control Only callable by contract owner\n     * @custom:event Emits AdminBurn(admin, src, amount) and Transfer(src, address(0), amount)\n     */\n    function adminBurn(address src, uint256 amount) external;\n\n    /**\n     * @notice Mints new tokens to a specified address\n     * @param dst The address to receive the minted tokens\n     * @param amount The amount of tokens to mint (6 decimals)\n     *\n     * @dev Minting Controls:\n     *      - Centralized issuance model (admin-only)\n     *      - Recipient must be allowlisted\n     *      - Cannot mint when paused\n     *\n     * @custom:access-control Only callable by contract owner\n     * @custom:validation dst must pass allowlist checks\n     * @custom:event Emits Mint(admin, dst, amount) and Transfer(address(0), dst, amount)\n     */\n    function mint(address dst, uint256 amount) external;\n\n    /**\n     * @notice Mints tokens to multiple recipients in a single transaction\n     * @param dsts Array of recipient addresses\n     * @param amounts Array of token amounts to mint (6 decimals)\n     *\n     * @dev Batch Minting:\n     *      - Arrays must have matching non-zero lengths\n     *      - All recipients must be allowlisted\n     *      - Atomic operation (all succeed or all revert)\n     *\n     * @custom:access-control Only callable by contract owner\n     * @custom:throws InvalidArgumentLengths if arrays don't match or are empty\n     * @custom:event Emits Mint and Transfer events for each recipient\n     */\n    function bulkMint(address[] calldata dsts, uint256[] calldata amounts) external;\n\n    /*//////////////////////////////////////////////////////////////\n                        CONFIGURATION FUNCTIONS\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     * @notice Sets a new allowlist contract address\n     * @param _allowlist The address of the new allowlist contract\n     *\n     * @dev Allowlist Configuration:\n     *      - Critical function that changes compliance rules\n     *      - Must be non-zero address (validated internally)\n     *      - Immediately affects all transfer operations\n     *\n     * @custom:access-control Only callable by contract owner\n     * @custom:validation _allowlist must be non-zero address\n     */\n    function setAllowlist(address _allowlist) external;\n\n    /**\n     * @notice Sets whether the instrument is public or private\n     * @dev Only callable by the admin\n     * @param _isPublicInstrument True if the instrument is public, false if private\n     */\n    function setIsPublicInstrument(bool _isPublicInstrument) external;\n\n    /**\n     * @notice Updates the token name returned by `name()`\n     * @param newName The new token name (must be non-empty)\n     *\n     * @dev Name Update Semantics:\n     *      - Writes the inherited ERC20Upgradeable `_name` slot; subsequent `name()` calls return this value\n     *      - EIP-712 domain separator (used by `permit`) derives from `_name()` on each call,\n     *        so renaming invalidates any in-flight permit signatures bound to the prior name\n     *\n     * @custom:access-control Only callable by contract owner\n     * @custom:throws InvalidName if `newName` is empty\n     * @custom:event Emits NameSet(oldName, newName)\n     */\n    function setName(string calldata newName) external;\n\n    /**\n     * @notice Updates the token symbol returned by `symbol()`\n     * @param newSymbol The new token symbol (must be non-empty)\n     *\n     * @dev Symbol Update Semantics:\n     *      - Writes the inherited ERC20Upgradeable `_symbol` slot; subsequent `symbol()` calls return this value\n     *      - Private instruments: `isAllowed` queries the allowlist keyed by `symbol()`, so renaming the\n     *        symbol re-keys the allowlist. Entities permissioned under the prior symbol lose access until\n     *        re-permissioned under the new symbol — coordinate with the allowlist operator.\n     *      - Public instruments: the public-instrument allowlist lookup is symbol-independent.\n     *      - EIP-712 domain separator is unaffected (it hashes `_name()`, not the symbol)\n     *\n     * @custom:access-control Only callable by contract owner\n     * @custom:throws InvalidSymbol if `newSymbol` is empty\n     * @custom:event Emits SymbolSet(oldSymbol, newSymbol)\n     */\n    function setSymbol(string calldata newSymbol) external;\n}\n\n// protocol/token/src/components/Subscribable.sol\n\n/**\n * @title Subscribable\n * @notice Abstract contract implementing subscription functionality with ERC-7201 namespaced storage\n * @dev Enables token minting through stablecoin deposits at the current Chainlink oracle price.\n *      Subscribers deposit supported stablecoins and receive fund tokens at the current NAV.\n *\n * @dev Key Features:\n *      - ERC-7201 namespaced storage pattern for upgrade safety\n *      - Configurable stablecoin support with per-stablecoin fee and sweep destination\n *      - Chainlink oracle integration for NAV-based pricing\n *      - Subscribe-on-behalf: Any allowlisted address can subscribe for any other allowlisted address\n *      - Fee precision at 0.01% (basis points with 10000 denominator)\n *\n * @author Jake Goh Si Yuan @jakegsy (Superstate)\n * @custom:version 1.2.0\n * @custom:security-contact security@superstate.co\n */\nabstract contract Subscribable is ISubscribable, IOracleConsumable, OracleConsumable {\n    using SafeERC20 for IERC20;\n    /// @notice Base 10000 for 0.01% precision\n\n    uint256 public constant FEE_DENOMINATOR = 10_000;\n\n    /**\n     * @dev Storage struct using ERC-7201 namespaced pattern\n     * @custom:storage-location erc7201:superstate.storage.subscribable\n     */\n    struct SubscribableStorage {\n        mapping(address stablecoin => ISubscribable.StablecoinConfig) supportedStablecoins;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(bytes(\"superstate.storage.subscribable\"))) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant SUBSCRIBABLE_STORAGE_LOCATION =\n        0x6640ca63ab1055811b2fff34942dd505f4876e53399ef208ab1dce6ae1a05d00;\n\n    /*  Requirements for implementation:\n        1. _requireAuth() must be implemented by the inheriting contract\n        2. _requireNotPaused() must be implemented by the inheriting contract\n        3. _requireNotAccountingPaused() must be implemented by the inheriting contract\n        4. _mint() must be implemented by the inheriting contract for token creation\n        5. decimals() must be implemented by the inheriting contract\n    */\n\n    /**\n     * @dev Hook to require authorization for administrative actions\n     * @notice Must be implemented by inheriting contract\n     */\n    function _requireAuth() internal view virtual override;\n\n    /**\n     * @dev Hook to check if contract is paused\n     * @notice Must be implemented by inheriting contract\n     */\n    function _requireNotPaused() internal view virtual;\n\n    /**\n     * @dev Hook to verify accounting (minting and burning) is not paused\n     * @notice Must be implemented by inheriting contract\n     */\n    function _requireNotAccountingPaused() internal view virtual;\n\n    /**\n     * @dev Hook to mint tokens\n     * @param to The recipient\n     * @param amount The amount to mint\n     * @notice Must be implemented by inheriting contract\n     */\n    function _mint(address to, uint256 amount) internal virtual;\n\n    /**\n     * @dev Hook to get the token decimals\n     * @notice Must be implemented by inheriting contract\n     * @return The token decimals\n     */\n    function decimals() public pure virtual returns (uint8);\n\n    /*\n        Provides the following to be used on inheritance:\n        1. supportedStablecoins() - returns the configuration for a stablecoin, view only\n        2. setStablecoinConfig() - sets the configuration for a stablecoin (admin function)\n        3. calculateFee() - calculates the fee for a subscription amount\n        4. calculateSuperstateTokenOut() - calculates the amount of tokens to mint for a subscription\n        5. subscribe() - processes a subscription with two variants:\n           - subscribe(address to, uint256 inAmount, address stablecoin) - for subscriptions on behalf of another address\n           - subscribe(uint256 inAmount, address stablecoin) - for subscriptions to self\n    */\n\n    /**\n     * @dev Returns the SubscribableStorage struct\n     * @return $ Storage pointer to the SubscribableStorage struct\n     */\n    function _getSubscribableStorage() private pure returns (SubscribableStorage storage $) {\n        assembly {\n            $.slot := SUBSCRIBABLE_STORAGE_LOCATION\n        }\n    }\n\n    /**\n     * @dev Returns the configuration for a stablecoin\n     * @param stablecoin The stablecoin address\n     * @return The stablecoin configuration\n     */\n    function supportedStablecoins(address stablecoin) public view returns (ISubscribable.StablecoinConfig memory) {\n        SubscribableStorage storage $ = _getSubscribableStorage();\n        return $.supportedStablecoins[stablecoin];\n    }\n\n    /**\n     * @dev Sets the configuration for a stablecoin\n     * @dev Requires msg.sender to be the owner address\n     * @param stablecoin The stablecoin address\n     * @param newSweepDestination The address to send stablecoins to\n     * @param newFee The fee in basis points (max 10 = 0.1%)\n     */\n    function setStablecoinConfig(address stablecoin, address newSweepDestination, uint96 newFee) external virtual {\n        _requireAuth();\n        _setStablecoinConfig(stablecoin, newSweepDestination, newFee);\n    }\n\n    /**\n     * @dev Calculates the fee for a subscription using ceiling division\n     * @dev Rounds up to prevent fee avoidance via small transaction splitting\n     * @param amount The amount to calculate fee on\n     * @param subscriptionFee The fee percentage in basis points\n     * @return The fee amount (rounded up)\n     */\n    function calculateFee(uint256 amount, uint256 subscriptionFee) public pure virtual returns (uint256) {\n        uint256 numerator = amount * subscriptionFee;\n        return (numerator + FEE_DENOMINATOR - 1) / FEE_DENOMINATOR;\n    }\n\n    /**\n     * @dev Calculates the amount of tokens to mint for a subscription\n     * @param inAmount The amount of stablecoin to subscribe with\n     * @param stablecoin The stablecoin address\n     * @return superstateTokenOutAmount The amount of tokens to mint\n     * @return stablecoinInAmountAfterFee The amount of stablecoin after fee\n     * @return feeOnStablecoinInAmount The fee amount\n     */\n    function calculateSuperstateTokenOut(uint256 inAmount, address stablecoin)\n        public\n        view\n        virtual\n        returns (uint256 superstateTokenOutAmount, uint256 stablecoinInAmountAfterFee, uint256 feeOnStablecoinInAmount)\n    {\n        (superstateTokenOutAmount, stablecoinInAmountAfterFee, feeOnStablecoinInAmount,) =\n            _calculateSuperstateTokenOut(inAmount, stablecoin);\n    }\n\n    /**\n     * @dev Shared subscription math. Returns the same `usdPerSuperstateTokenChainlinkRaw` raw\n     *      NAV price used to size `superstateTokenOutAmount`. Callers that need to surface the\n     *      price (e.g. the `Subscribe` event) take it from here rather than re-reading the\n     *      oracle, so the emitted price is exactly the value the mint was priced at — one\n     *      oracle read, no chance of a second read drifting.\n     * @param inAmount The amount of stablecoin to subscribe with\n     * @param stablecoin The stablecoin address\n     * @return superstateTokenOutAmount The amount of tokens to mint\n     * @return stablecoinInAmountAfterFee The amount of stablecoin after fee\n     * @return feeOnStablecoinInAmount The fee amount\n     * @return usdPerSuperstateTokenChainlinkRaw The raw Chainlink NAV price used for the conversion\n     */\n    function _calculateSuperstateTokenOut(uint256 inAmount, address stablecoin)\n        internal\n        view\n        returns (\n            uint256 superstateTokenOutAmount,\n            uint256 stablecoinInAmountAfterFee,\n            uint256 feeOnStablecoinInAmount,\n            uint256 usdPerSuperstateTokenChainlinkRaw\n        )\n    {\n        StablecoinConfig memory config = supportedStablecoins(stablecoin);\n        if (config.sweepDestination == address(0)) revert StablecoinNotSupported();\n\n        feeOnStablecoinInAmount = calculateFee({amount: inAmount, subscriptionFee: config.fee});\n        stablecoinInAmountAfterFee = inAmount - feeOnStablecoinInAmount;\n\n        bool isBadData;\n        (isBadData,, usdPerSuperstateTokenChainlinkRaw) = _getChainlinkPrice();\n        if (isBadData) revert BadChainlinkData();\n\n        uint256 stablecoinDecimals = IERC20Metadata(stablecoin).decimals();\n        uint256 stablecoinPrecision = 10 ** stablecoinDecimals;\n        uint256 chainlinkFeedPrecision = 10 ** AggregatorV3Interface(superstateOracle()).decimals();\n\n        // Converts from a USD amount to a SUPERSTATE_TOKEN amount\n        superstateTokenOutAmount = (stablecoinInAmountAfterFee * chainlinkFeedPrecision * 10 ** decimals())\n            / (usdPerSuperstateTokenChainlinkRaw * stablecoinPrecision);\n    }\n\n    /**\n     * @dev Processes a subscription\n     * @param to The recipient of the minted tokens\n     * @param inAmount The amount of stablecoin to subscribe with\n     * @param stablecoin The stablecoin address\n     */\n    function subscribe(address to, uint256 inAmount, address stablecoin) external virtual {\n        _subscribe(to, inAmount, stablecoin);\n    }\n\n    /**\n     * @dev Processes a subscription with the caller as the recipient\n     * @param inAmount The amount of stablecoin to subscribe with\n     * @param stablecoin The stablecoin address\n     */\n    function subscribe(uint256 inAmount, address stablecoin) external virtual {\n        _subscribe(msg.sender, inAmount, stablecoin);\n    }\n\n    /**\n     * @dev Sets the configuration for a stablecoin\n     * @param stablecoin The stablecoin address\n     * @param newSweepDestination The address to send stablecoins to\n     * @param newFee The fee in basis points (max 10 = 0.1%)\n     */\n    function _setStablecoinConfig(address stablecoin, address newSweepDestination, uint96 newFee) internal {\n        if (newFee > 10) revert FeeTooHigh(); // Max 0.1% fee\n\n        SubscribableStorage storage $ = _getSubscribableStorage();\n\n        StablecoinConfig memory oldConfig = $.supportedStablecoins[stablecoin];\n        if (newSweepDestination == oldConfig.sweepDestination && newFee == oldConfig.fee) revert BadArgsSubscribable();\n\n        $.supportedStablecoins[stablecoin] = StablecoinConfig({sweepDestination: newSweepDestination, fee: newFee});\n\n        emit SetStablecoinConfig({\n            stablecoin: stablecoin,\n            oldSweepDestination: oldConfig.sweepDestination,\n            newSweepDestination: newSweepDestination,\n            oldFee: oldConfig.fee,\n            newFee: newFee\n        });\n    }\n\n    /**\n     * @dev Processes a subscription\n     * @param to The recipient of the minted tokens\n     * @param inAmount The amount of stablecoin to subscribe with\n     * @param stablecoin The stablecoin address\n     * @notice Any caller can subscribe on behalf of any `to` address.\n     *         The caller (msg.sender) pays the stablecoin; the `to` address receives the fund tokens.\n     *         Both addresses must be allowlisted to hold the fund token.\n     */\n    function _subscribe(address to, uint256 inAmount, address stablecoin) internal {\n        if (inAmount == 0) revert BadArgsSubscribable();\n        _requireNotPaused();\n        _requireNotAccountingPaused();\n\n        (\n            uint256 superstateTokenOutAmount,\n            uint256 stablecoinInAmountAfterFee,,\n            uint256 usdPerSuperstateTokenChainlinkRaw\n        ) = _calculateSuperstateTokenOut({inAmount: inAmount, stablecoin: stablecoin});\n\n        if (superstateTokenOutAmount == 0) revert ZeroSuperstateTokensOutSubscribable();\n\n        IERC20(stablecoin)\n            .safeTransferFrom({\n                from: msg.sender, to: supportedStablecoins(stablecoin).sweepDestination, value: inAmount\n            });\n\n        _mint(to, superstateTokenOutAmount);\n\n        emit Subscribe({\n            subscriber: msg.sender,\n            to: to,\n            stablecoin: stablecoin,\n            stablecoinInAmountAfterFee: stablecoinInAmountAfterFee,\n            stablecoinInAmountBeforeFee: inAmount,\n            superstateTokenOutAmount: superstateTokenOutAmount,\n            usdPerSuperstateTokenChainlinkRaw: usdPerSuperstateTokenChainlinkRaw\n        });\n        emit SubscribeV2({\n            subscriber: msg.sender,\n            to: to,\n            stablecoin: stablecoin,\n            stablecoinInAmountAfterFee: stablecoinInAmountAfterFee,\n            stablecoinInAmountBeforeFee: inAmount,\n            superstateTokenOutAmount: superstateTokenOutAmount\n        });\n    }\n\n    function __Subscribable_init(address oracle, uint256 maxDelay) internal {\n        __OracleConsumable_init(oracle, maxDelay);\n    }\n}\n\n// protocol/token/src/base/SuperstateTokenCore.sol\n\n/**\n * @title SuperstateTokenCore\n * @notice Abstract base contract providing core ERC20 token functionality with upgradeability\n * @dev Combines OpenZeppelin's ERC20, Pausable, and Ownable2Step upgradeable contracts.\n *      Uses continuous (non-namespaced) storage layout for backward compatibility with\n *      already-deployed Token V5/V5.1 contracts.\n *\n * @dev Two pause flags are exposed by the inheriting token:\n *      - PausableUpgradeable.paused() — global pause; freezes user transfers and subscriptions.\n *      - AccountingPausable.isAccountingPaused() — accounting pause; freezes all issuance and burn\n *        paths (mint, bulkMint, adminBurn, offchainRedeem, bridge, buyTheDip, subscribe, and the\n *        book-entry transfer-to-self burn). The two flags are orthogonal and engaged independently.\n *\n * @dev Key Features:\n *      - ERC20 token with 6 decimals\n *      - Pausable transfers for emergency stops\n *      - Two-step ownership transfer for safety\n *      - Continuous storage layout (slots 0-150) for upgrade compatibility\n *\n * @dev Inherited Continuous Storage Layout (linearized; identical for FundToken and EquityToken —\n *      verify with `forge inspect FundToken storage` / `forge inspect EquityToken storage`, and pinned\n *      for both by `FundTokenV5StorageLayoutTests.testCoreContinuousStorageLayout` and `testNameSymbolSlotPin`):\n *\n *      | Slot     | Field                                | Source contract                                |\n *      |----------|--------------------------------------|------------------------------------------------|\n *      | 0        | _initialized (uint8), _initializing  | Initializable                                  |\n *      | 1..50    | __gap[50]                            | Initializable                                  |\n *      | 51       | _balances (mapping)                  | ERC20Upgradeable                               |\n *      | 52       | _allowances (mapping)                | ERC20Upgradeable                               |\n *      | 53       | _totalSupply (uint256)               | ERC20Upgradeable                               |\n *      | 54       | _name (string)                       | ERC20Upgradeable                               |\n *      | 55       | _symbol (string)                     | ERC20Upgradeable                               |\n *      | 56..100  | __gap[45]                            | ERC20Upgradeable                               |\n *      | 101      | _paused (bool)                       | PausableUpgradeable                            |\n *      | 102..150 | __gap[49]                            | PausableUpgradeable                            |\n *      | 151      | _owner (address)                     | OwnableUpgradeable (via Ownable2StepUpgradeable) |\n *      | 152..200 | __gap[49]                            | OwnableUpgradeable                             |\n *      | 201      | _pendingOwner (address)              | Ownable2StepUpgradeable                        |\n *      | 202..250 | __gap[49]                            | Ownable2StepUpgradeable                        |\n *\n *      Subclasses add further continuous slots beyond 250 (e.g. `initializeV1_2_0` in FundToken\n *      reads `superstateOracle` at slot 756, `allowlistV2` at 758). Newer component state\n *      (accounting-pause, permittable, etc.) lives in ERC-7201 namespaced slots and does not\n *      consume continuous slots.\n *\n * @dev Bundled mixin: this core `is ERC20MetadataSettable`, so every token built on it inherits\n *      owner-controlled `setName`/`setSymbol`. That mixin is deliberately co-located in `src/base/`\n *      and folded in here — rather than mixed into each token independently — precisely because it\n *      depends on this contract's linearization: it writes the `_name`/`_symbol` entries (slots 54\n *      and 55 in the table above) directly. It is storage-less, so it adds no continuous slots; the\n *      coupling is structural, not a layout change. The `FundTokenV5StorageLayoutTests` slot pin\n *      guards the 54/55 invariant the mixin relies on.\n *\n * @author Jake Goh Si Yuan @jakegsy (Superstate)\n * @custom:version 1.2.0 (shared by FundToken 1.2.0 / EquityToken 1.4.0)\n * @custom:security-contact security@superstate.co\n */\nabstract contract SuperstateTokenCore is\n    ERC20Upgradeable,\n    PausableUpgradeable,\n    Ownable2StepUpgradeable,\n    ERC20MetadataSettable\n{}\n\n// protocol/token/src/fund/v1.3.0/FundTokenV1_3_0.sol\n\n/**\n * @title FundToken\n * @notice Upgradeable ERC20 token representing tokenized fund instruments (USTB, USCC) with compliance, redemption, and subscription capabilities\n * @dev This contract serves as the core implementation for Superstate's fund token products, providing:\n *      - KYC/AML compliance through allowlist integration\n *      - Multi-chain bridging capabilities with book-entry support\n *      - On-chain redemption via integrated redemption contracts\n *      - NAV-based subscription with oracle price feeds\n *      - EIP-2612 permit functionality for gasless approvals\n *\n * @dev Architecture Overview:\n *      The contract inherits from multiple specialized components:\n *      - SuperstateTokenCore: Base token functionality with upgrade support; also bundles\n *        ERC20MetadataSettable (owner-controlled `setName`/`setSymbol`), which is layout-coupled to\n *        the core and therefore inherited through it rather than mixed in here directly\n *      - AccountingPausable: Accounting pause freezing all mint/burn (issuance and redemption) paths\n *      - Allowlistable: KYC/AML compliance enforcement\n *      - Permittable: EIP-2612 gasless approval support\n *      - Bridgeable: Cross-chain transfer capabilities\n *      - Redeemable: On-chain token redemption mechanics\n *      - Subscribable: NAV-based subscription with stablecoin payments\n *\n * @dev Key Features:\n *      - 6 decimal precision for all token amounts\n *      - Two-step ownership transfer for security\n *      - Global pause (freezes user transfers and subscriptions) and accounting pause\n *        (freezes all mint/burn) as independent emergency controls\n *      - Public/private instrument modes with different allowlist rules\n *      - Admin-controlled minting and burning\n *      - Bridge-to-book-entry via transfer to contract address\n *      - Chainlink oracle integration for NAV pricing\n *      - Minimum acceptable price floor ($7.00) for subscriptions\n *\n * @dev Storage Layout:\n *      Uses EIP-7201 namespaced storage for upgrade safety.\n *      Migration from v5_1 continuous storage handled via initializeV1_2_0().\n *\n * @author Jake Goh Si Yuan @jakegsy (Superstate)\n * @custom:version 1.3.0\n * @custom:security-contact security@superstate.co\n */\ncontract FundToken is\n    IFundTokenV1,\n    SuperstateTokenCore,\n    AccountingPausable,\n    Permittable,\n    Allowlistable,\n    Bridgeable,\n    Redeemable,\n    Subscribable\n{\n    using SafeERC20 for IERC20;\n\n    /*//////////////////////////////////////////////////////////////\n                                CONSTANTS\n    //////////////////////////////////////////////////////////////*/\n\n    /// @notice The version of this contract implementation\n    /// @dev Used for upgrade compatibility verification and EIP-712 domain separator\n    string public constant VERSION = \"1.3.0\";\n\n    /// @notice Token decimal precision (matches USDC standard)\n    /// @dev All token amounts use 6 decimal places for consistency\n    uint8 private constant DECIMALS = 6;\n\n    /// @notice V5.1-compatible getter for the token precision\n    /// @dev Retained so integrations using the legacy selector continue to return 1e6\n    uint256 public constant SUPERSTATE_TOKEN_PRECISION = 10 ** DECIMALS;\n\n    /// @notice Lowest acceptable Chainlink oracle price for subscriptions\n    /// @dev Set to $7.00 (7_000_000 in 6 decimals) as a safety floor\n    uint256 public immutable MINIMUM_ACCEPTABLE_PRICE;\n\n    /*//////////////////////////////////////////////////////////////\n                        CONSTRUCTOR & INITIALIZERS\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     * @notice Disables initializers to prevent implementation contract misuse\n     * @dev This is the implementation contract; actual instances must call initialize() via proxy\n     *      Sets MINIMUM_ACCEPTABLE_PRICE to $7.00 as a safety floor for oracle prices\n     * @custom:oz-upgrades-unsafe-allow constructor\n     */\n    constructor() {\n        // SUPERSTATE_TOKEN starts at $10.000000, Chainlink oracle with 6 decimals would represent as 10_000_000.\n        // This math will give us 7_000_000 or $7.000000.\n        MINIMUM_ACCEPTABLE_PRICE = 7 * (10 ** uint256(DECIMALS));\n\n        _disableInitializers();\n    }\n\n    /**\n     * @notice Initializes the proxy contract instance for fresh deployments\n     * @param name_ The token name (e.g., \"Superstate USTB\")\n     * @param symbol_ The token symbol (e.g., \"USTB\")\n     * @param allowlist The allowlist contract address for KYC/AML compliance\n     * @param _isPublicInstrument Whether this is a public instrument (true) or private instrument (false)\n     * @param redemption The redemption contract address for on-chain redemptions\n     * @param oracle The Chainlink oracle contract address for NAV pricing\n     * @param maxDelay The maximum acceptable oracle staleness in seconds\n     *\n     * @dev Initialization Sequence:\n     *      1. ERC20 base initialization with name and symbol\n     *      2. Pausable initialization (sets paused = false)\n     *      3. AccountingPausable initialization (sets accountingPaused = false)\n     *      4. Permittable initialization (prepares EIP-2612 support)\n     *      5. Allowlistable initialization (sets allowlist contract and instrument type)\n     *      6. Bridgeable initialization (enables book-entry with chain_id = 0)\n     *      7. Redeemable initialization (sets redemption contract)\n     *      8. Subscribable initialization (sets oracle and max delay)\n     *\n     * @custom:security Can only be called once per proxy deployment\n     * @custom:validation allowlist must be non-zero address\n     * @custom:event Emits OwnershipTransferred with (address(0), msg.sender)\n     */\n    function initialize(\n        string calldata name_,\n        string calldata symbol_,\n        address allowlist,\n        bool _isPublicInstrument,\n        address redemption,\n        address oracle,\n        uint256 maxDelay\n    ) public initializer {\n        __ERC20_init(name_, symbol_);\n        __Ownable2Step_init(); // Sets msg.sender as owner\n        __Pausable_init();\n        __AccountingPausable_init(); // sets accountingPaused = false\n        __Permittable_init(); // doesnt really do anything, for consistency\n        __Allowlistable_init(allowlist, _isPublicInstrument); // sets allowlist and instrument type\n        __Bridgeable_init(); // sets chainId 0 for book entry to true\n        __Redeemable_init(redemption); // sets redemption contract\n        __Subscribable_init(oracle, maxDelay); // sets oracle and maxDelay, no stablecoins initialized\n    }\n\n    /**\n     * @notice Migrates existing deployments and atomically replays non-enumerable mapping config\n     * @param stablecoins Stablecoin addresses to configure after namespace initialization\n     * @param stablecoinConfigs Stablecoin sweep destination and fee configs aligned with `stablecoins`\n     * @param supportedChainIds_ Bridge destination chain IDs to mark supported after namespace initialization\n     *\n     * @dev Migration Details:\n     *      - Reads state from v5_1 continuous storage slots (see forge inspect SuperstateTokenV5_1 storageLayout)\n     *      - Initializes all component namespaces with migrated state\n     *      - Sets instrument type to private (existing USTB/USCC behavior)\n     *      - Replays mapping data (supportedStablecoins, supportedChainIds) supplied by the caller\n     *\n     * @dev Solidity mappings are not enumerable on-chain, so callers must supply the known keys captured\n     *      before the upgrade. Pass empty arrays when there is no mapping config to replay. This keeps the\n     *      storage migration and mapping replay in one owner transaction.\n     *\n     * @dev Storage Slot Reference (v5_1):\n     *      - Slot 754: accountingPaused\n     *      - Slot 755: maximumOracleDelay\n     *      - Slot 756: superstateOracle\n     *      - Slot 758: allowlistV2\n     *      - Slot 759: redemptionContract\n     *\n     * @custom:access-control Only callable by contract owner\n     * @custom:security Uses reinitializer(6) to prevent re-execution\n     * @custom:migration For existing USTB/USCC deployments only; fresh deployments use initialize()\n     */\n    function initializeV1_2_0(\n        address[] calldata stablecoins,\n        ISubscribable.StablecoinConfig[] calldata stablecoinConfigs,\n        uint256[] calldata supportedChainIds_\n    ) external reinitializer(6) {\n        _requireAuth();\n        _initializeV1_2_0();\n        _initializeV1_2_0MigrationConfig(stablecoins, stablecoinConfigs, supportedChainIds_);\n    }\n\n    function _initializeV1_2_0() internal {\n        // Read v5_1 state from continuous storage slots\n        // See `forge inspect SuperstateTokenV5_1 storageLayout` for reference\n        bool legacyAccountingPaused = _getBoolFromSlot(754); // accountingPaused\n        uint256 maxDelay = _getUint256FromSlot(755); // maximumOracleDelay\n        address oracle = _getAddressFromSlot(756); // superstateOracle\n        address allowlist = _getAddressFromSlot(758); // allowlistV2\n        address redemption = _getAddressFromSlot(759); // redemptionContract\n\n        // Initialize all component namespaces with migrated state\n        __AccountingPausable_init(); // Accounting pause starts disengaged in the new ERC-7201 namespace\n        // Carry over the v5_1 accounting-pause flag (continuous slot 754). Without this, migrating while\n        // accounting-paused (e.g. during an incident) would silently re-enable all mint/burn/bridge/redeem/\n        // subscribe paths while paused() still reports true, diverging the two pause levers.\n        _setAccountingPaused(legacyAccountingPaused);\n        __Permittable_init(); // Nonces reset to 0 in ERC-7201 namespace; old signatures invalid due to new VERSION in domain separator\n        __Allowlistable_init(allowlist, false); // Migrate allowlist, set as private instrument\n        __Bridgeable_init(); // Initialize chainId 0 support for book entry\n        __Redeemable_init(redemption); // Migrate redemption contract\n        __Subscribable_init(oracle, maxDelay); // Migrate oracle and delay settings\n    }\n\n    function _initializeV1_2_0MigrationConfig(\n        address[] calldata stablecoins,\n        ISubscribable.StablecoinConfig[] calldata stablecoinConfigs,\n        uint256[] calldata supportedChainIds_\n    ) internal {\n        if (stablecoins.length != stablecoinConfigs.length) revert InvalidArgumentLengths();\n\n        for (uint256 i = 0; i < stablecoins.length; ++i) {\n            _setStablecoinConfig({\n                stablecoin: stablecoins[i],\n                newSweepDestination: stablecoinConfigs[i].sweepDestination,\n                newFee: stablecoinConfigs[i].fee\n            });\n        }\n\n        for (uint256 i = 0; i < supportedChainIds_.length; ++i) {\n            _setChainIdSupport(supportedChainIds_[i], true);\n        }\n    }\n\n    function _getAddressFromSlot(uint256 slot) internal view returns (address) {\n        address result;\n        assembly {\n            result := sload(slot)\n        }\n        return result;\n    }\n\n    function _getUint256FromSlot(uint256 slot) internal view returns (uint256) {\n        uint256 result;\n        assembly {\n            result := sload(slot)\n        }\n        return result;\n    }\n\n    function _getBoolFromSlot(uint256 slot) internal view returns (bool) {\n        uint256 result;\n        assembly {\n            result := sload(slot)\n        }\n        return result != 0;\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                        CONFIGURATION FUNCTIONS\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     * @notice Sets a new allowlist contract address\n     * @param _allowlist The address of the new allowlist contract\n     *\n     * @dev Security Considerations:\n     *      - Critical function that changes compliance rules\n     *      - _setAllowlist validates non-zero address internally\n     *      - Immediately affects all transfer operations\n     *\n     * @custom:access-control Only callable by contract owner\n     * @custom:validation _allowlist must be non-zero address\n     * @custom:event Emits AllowlistSet with new allowlist address\n     */\n    function setAllowlist(address _allowlist) external {\n        _requireAuth();\n        _setAllowlist(_allowlist);\n    }\n\n    /**\n     * @notice Sets whether this token is a public or private instrument\n     * @param _isPublicInstrument True for public instrument, false for private\n     *\n     * @dev Instrument Type Implications:\n     *      - Public: Uses entity-based allowlist permissions\n     *      - Private: Uses instrument-specific allowlist permissions with token symbol\n     *      This affects how isAllowed() queries the allowlist contract\n     *\n     * @custom:access-control Only callable by contract owner\n     * @custom:event Emits IsPublicInstrumentSet with new setting\n     */\n    function setIsPublicInstrument(bool _isPublicInstrument) external {\n        _requireAuth();\n        _setIsPublicInstrument(_isPublicInstrument);\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                        PAUSE MANAGEMENT\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     * @notice Engages the global pause, freezing user transfers and subscriptions\n     *\n     * @dev Emergency Control:\n     *      - Blocks regular transfers/transferFrom and subscribe\n     *      - Does NOT block mint/burn paths — those are gated by the separate accounting pause\n     *        (mint, bulkMint, adminBurn, offchainRedeem, bridge, book-entry transfer-to-self)\n     *      - Independent of accountingPause(); each is engaged/released separately\n     *      - Can only pause if currently unpaused\n     *\n     * @custom:access-control Only callable by contract owner\n     * @custom:throws AlreadyPaused if contract is already paused\n     * @custom:event Emits Paused(owner)\n     */\n    function pause() external {\n        _checkOwner();\n        _requireNotPaused();\n\n        _pause();\n    }\n\n    /**\n     * @notice Releases the global pause, re-enabling transfers and subscriptions\n     *\n     * @dev Resume Operations:\n     *      - Re-enables regular transfers and subscribe\n     *      - Can only unpause if currently paused\n     *\n     * @custom:access-control Only callable by contract owner\n     * @custom:throws NotPaused if contract is not paused\n     * @custom:event Emits Unpaused(owner)\n     */\n    function unpause() external {\n        _checkOwner();\n        _requirePaused();\n\n        _unpause();\n    }\n\n    /**\n     * @notice Permanently disabled ownership renunciation\n     *\n     * @dev Security Feature:\n     *      - Prevents accidental loss of contract control\n     *      - Ownership can still be transferred via two-step process\n     *      - Always reverts with RenounceOwnershipDisabled\n     *\n     * @custom:security Critical safety feature to prevent permanent loss of admin control\n     * @custom:throws RenounceOwnershipDisabled always\n     */\n    function renounceOwnership() public virtual override onlyOwner {\n        revert RenounceOwnershipDisabled();\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                        TOKEN METADATA\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     * @notice Returns the number of decimals used for token amounts\n     * @return uint8 Always returns 6\n     *\n     * @dev Fixed at 6 decimals for all Superstate tokens (matches USDC standard)\n     * @custom:invariant This value never changes\n     */\n    function decimals() public pure override(ERC20Upgradeable, Subscribable) returns (uint8) {\n        return DECIMALS;\n    }\n\n    /**\n     * @notice Returns the token symbol\n     * @return The token symbol\n     * @dev Overrides both ERC20Upgradeable and Allowlistable to resolve inheritance conflict\n     */\n    function symbol() public view override(ERC20Upgradeable, Allowlistable) returns (string memory) {\n        return super.symbol();\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                        TOKEN TRANSFER FUNCTIONS\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     * @notice Moves tokens from caller to destination address\n     * @param dst Address to receive the tokens\n     * @param amount Amount of tokens to transfer (6 decimals)\n     * @return bool Always returns true on success (reverts on failure)\n     *\n     * @dev Special Behavior:\n     *      - If dst == address(this): Burns tokens and emits OffchainRedeem event (book-entry conversion)\n     *      - Otherwise: Standard ERC20 transfer with allowlist checks\n     *\n     * @custom:validation Both sender and recipient must be allowlisted\n     * @custom:throws Paused if contract is paused\n     * @custom:throws InsufficientPermissions if sender or recipient not allowlisted\n     * @custom:event Emits Transfer(msg.sender, dst, amount) or OffchainRedeem for book-entry\n     */\n    function transfer(address dst, uint256 amount) public override(IERC20Upgradeable, ERC20Upgradeable) returns (bool) {\n        if (!isAllowed(msg.sender)) revert InsufficientPermissions();\n\n        if (dst == address(this)) {\n            _requireNotAccountingPaused();\n            _burn(msg.sender, amount);\n            emit OffchainRedeem({burner: msg.sender, src: msg.sender, amount: amount});\n        } else {\n            _requireNotPaused();\n            if (!isAllowed(dst)) revert InsufficientPermissions();\n            _transfer(msg.sender, dst, amount);\n        }\n\n        return true;\n    }\n\n    /**\n     * @notice Moves tokens from source to destination using caller's allowance\n     * @param src Address to transfer tokens from\n     * @param dst Address to receive the tokens\n     * @param amount Amount of tokens to transfer (6 decimals)\n     * @return bool Always returns true on success (reverts on failure)\n     *\n     * @dev Special Behavior:\n     *      - If dst == address(this): Burns from src and emits OffchainRedeem event\n     *      - Allowance is always consumed regardless of destination\n     *      - Caller can be different from src (uses allowance mechanism)\n     *\n     * @custom:validation src and dst must be allowlisted\n     * @custom:throws Paused if contract is paused\n     * @custom:throws InsufficientPermissions if src or dst not allowlisted\n     * @custom:throws InsufficientAllowance if caller lacks allowance\n     * @custom:event Emits Transfer(src, dst, amount) or OffchainRedeem for book-entry\n     */\n    function transferFrom(address src, address dst, uint256 amount)\n        public\n        override(IERC20Upgradeable, ERC20Upgradeable)\n        returns (bool)\n    {\n        if (!isAllowed(src)) revert InsufficientPermissions();\n\n        if (dst == address(this)) {\n            _requireNotAccountingPaused();\n            _spendAllowance({owner: src, spender: msg.sender, amount: amount});\n            _burn(src, amount);\n            // burner receives redemption payout from src\n            emit OffchainRedeem({burner: msg.sender, src: src, amount: amount});\n        } else {\n            _requireNotPaused();\n            if (!isAllowed(dst)) revert InsufficientPermissions();\n            ERC20Upgradeable.transferFrom({from: src, to: dst, amount: amount});\n        }\n\n        return true;\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                        MINTING FUNCTIONS\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     * @notice Mints new tokens to a specified address\n     * @param dst The address to receive the minted tokens\n     * @param amount The amount of tokens to mint (6 decimals)\n     *\n     * @dev Minting Constraints:\n     *      - Only owner can mint (centralized issuance model)\n     *      - Recipient must be allowlisted\n     *\n     * @custom:access-control Only callable by contract owner\n     * @custom:validation dst must be allowlisted\n     * @custom:throws InsufficientPermissions if dst not allowlisted\n     * @custom:event Emits Mint(owner, dst, amount) and Transfer(address(0), dst, amount)\n     */\n    function mint(address dst, uint256 amount) external {\n        _checkOwner();\n        _requireNotAccountingPaused();\n\n        _mint(dst, amount);\n    }\n\n    /**\n     * @notice Mints tokens to multiple recipients in a single transaction\n     * @param dsts Array of recipient addresses\n     * @param amounts Array of token amounts to mint (6 decimals)\n     *\n     * @dev Batch Processing:\n     *      - Arrays must have matching lengths and be non-empty\n     *      - All recipients must be allowlisted\n     *      - Atomically mints to all recipients or reverts entirely\n     *\n     * @custom:access-control Only callable by contract owner\n     * @custom:validation All addresses in dsts must be allowlisted\n     * @custom:throws InvalidArgumentLengths if array lengths mismatch or empty\n     * @custom:gas-optimization Batch processing reduces transaction costs\n     * @custom:event Emits Mint and Transfer events for each recipient\n     */\n    function bulkMint(address[] calldata dsts, uint256[] calldata amounts) external {\n        _requireAuth();\n        _requireNotAccountingPaused();\n        if (dsts.length != amounts.length || dsts.length == 0) revert InvalidArgumentLengths();\n\n        uint256 length = dsts.length;\n\n        for (uint256 i = 0; i < length; ++i) {\n            _mint({to: dsts[i], amount: amounts[i]});\n        }\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                        BURNING FUNCTIONS\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     * @notice Burns tokens from a specified address (admin function)\n     * @param src Address from which tokens will be burned\n     * @param amount Amount of tokens to burn (6 decimals)\n     *\n     * @dev Admin Burn Features:\n     *      - Allows owner to burn tokens from any address\n     *      - Does not require src to be msg.sender\n     *      - Used for administrative corrections and redemption processing\n     *\n     * @custom:access-control Only callable by contract owner\n     * @custom:throws Unauthorized if caller is not owner\n     * @custom:event Emits AdminBurn(owner, src, amount) and Transfer(src, address(0), amount)\n     */\n    function adminBurn(address src, uint256 amount) external {\n        _requireAuth();\n        _requireNotAccountingPaused();\n\n        _burn(src, amount);\n        emit AdminBurn({burner: msg.sender, src: src, amount: amount});\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                    V5.1 COMPATIBILITY GETTERS\n    //////////////////////////////////////////////////////////////*/\n\n    /// @inheritdoc IFundTokenV1\n    function accountingPaused() external view returns (bool) {\n        return isAccountingPaused();\n    }\n\n    /// @inheritdoc IFundTokenV1\n    function allowlistV2() external view returns (address) {\n        return allowlist();\n    }\n\n    /// @inheritdoc IFundTokenV1\n    function redemptionContract() external view returns (address) {\n        return getRedemptionContract();\n    }\n\n    /// @inheritdoc IFundTokenV1\n    function supportedChainIds(uint256 chainId) external view returns (bool) {\n        return isChainIdSupported(chainId);\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                        INTERNAL FUNCTIONS\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     * @dev Returns the contract version for internal use\n     * @return string The version constant\n     */\n    function _version() internal pure override returns (string memory) {\n        return VERSION;\n    }\n\n    /**\n     * @dev Returns the token name for internal use\n     * @return string The token name from ERC20 storage\n     */\n    function _name() internal view override returns (string memory) {\n        return super.name();\n    }\n\n    /**\n     * @dev Returns the minimum acceptable oracle price\n     * @return uint256 The minimum price floor ($7.00 in 6 decimals)\n     */\n    function _getMinimumAcceptablePrice() internal view override returns (uint256) {\n        return MINIMUM_ACCEPTABLE_PRICE;\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                        AUTHORIZATION CHECKS\n    //////////////////////////////////////////////////////////////*/\n\n    /**\n     * @dev Requires caller to be contract owner\n     * @custom:inheritance Resolves multi-inheritance conflict\n     * @custom:throws Unauthorized if caller is not owner\n     */\n    function _requireAuth()\n        internal\n        view\n        override(ERC20MetadataSettable, AccountingPausable, Bridgeable, Redeemable, Subscribable)\n    {\n        if (msg.sender != owner()) revert Unauthorized();\n    }\n\n    /**\n     * @dev Requires address to be allowlisted\n     * @param addr Address to check\n     * @custom:inheritance Implements Bridgeable and Redeemable requirement\n     * @custom:throws InsufficientPermissions if address is not allowlisted\n     */\n    function _requireAllowed(address addr) internal view override(Bridgeable, Redeemable) {\n        if (!isAllowed(addr)) revert InsufficientPermissions();\n    }\n\n    /**\n     * @dev Requires the global pause not to be engaged\n     * @custom:inheritance Resolves multi-inheritance from PausableUpgradeable and Subscribable\n     */\n    function _requireNotPaused() internal view override(PausableUpgradeable, Subscribable) {\n        super._requireNotPaused();\n    }\n\n    /**\n     * @dev Requires the accounting pause not to be engaged (gates all mint/burn paths)\n     * @custom:inheritance Resolves multi-inheritance from Bridgeable, Redeemable, and Subscribable\n     * @custom:throws AccountingIsPaused if accounting is paused\n     */\n    function _requireNotAccountingPaused() internal view override(Bridgeable, Redeemable, Subscribable) {\n        if (isAccountingPaused()) revert AccountingIsPaused();\n    }\n\n    /**\n     * @dev Internal mint function with allowlist enforcement\n     * @param to Recipient address (must be allowlisted)\n     * @param amount Amount to mint\n     * @custom:inheritance Resolves multi-inheritance for Subscribable and ERC20Upgradeable\n     * @custom:security Enforces allowlist check on every mint path (admin, bulk, subscribe)\n     */\n    function _mint(address to, uint256 amount) internal override(ERC20Upgradeable, Subscribable) {\n        _requireAllowed(to);\n        super._mint(to, amount);\n        emit Mint(msg.sender, to, amount);\n    }\n\n    /**\n     * @dev Internal burn function\n     * @param from Address to burn tokens from\n     * @param amount Amount to burn\n     * @custom:inheritance Resolves multi-inheritance for Bridgeable, Redeemable, and ERC20Upgradeable\n     */\n    function _burn(address from, uint256 amount) internal override(ERC20Upgradeable, Bridgeable, Redeemable) {\n        super._burn(from, amount);\n    }\n\n    /**\n     * @dev Internal approve function routing for multi-inheritance\n     * @param owner Token owner granting approval\n     * @param spender Address receiving approval\n     * @param amount Amount approved\n     * @custom:inheritance Routes through Permittable for EIP-2612 support\n     */\n    function _approve(address owner, address spender, uint256 amount) internal override(ERC20Upgradeable, Permittable) {\n        super._approve(owner, spender, amount);\n    }\n\n    /// @inheritdoc ERC20MetadataSettable\n    function setName(string calldata newName) public override(ERC20MetadataSettable, IFundTokenV1) {\n        super.setName(newName);\n    }\n\n    /// @inheritdoc ERC20MetadataSettable\n    function setSymbol(string calldata newSymbol) public override(ERC20MetadataSettable, IFundTokenV1) {\n        super.setSymbol(newSymbol);\n    }\n}\n","deployed_bytecode":"0x6080806040526004361015610012575f80fd5b5f905f3560e01c9081630560187e146137805750806306dd04191461369257806306fdde0314613659578063095ea7b3146135ac5780630a1b8005146135545780630b9a59ea146134f55780631397edf91461218457806318160ddd146134ba57806323b872dd146133365780632b47da52146128b7578063313ce567146132fd57806334e73122146132be5780633644e5151461327e578063395093511461319b5780633aeef3d31461314e5780633f4ba83a146130b457806340c10f191461306157806349c7e1fb14612fff5780634cf2ab3214612f2357806350a4efb814612f8f5780635633cb9914612f2357806358bf3c7f14612edc57806359e6951d14612e995780635adcf3a314612e305780635c975abb14612df0578063678f9da2146129275780636953f15a146128b75780636ae459bd146127bb57806370a0823114612758578063715018a6146126fa578063774e522c1461251157806379ba5097146124375780637adbf973146123ee5780637ecebe001461236c5780638456cb59146122d65780638da5cb5b1461228557806394c685da1461222d57806395d89b41146121f457806396fe914f14612184578063a1bee8f1146120b2578063a32da3c714611dc5578063a457c2d714611c5e578063a9059cbb1461199f578063b84c824614611790578063b9bd40fa14611753578063babcc53914611707578063bf4f6c6a1461158a578063bf7d911914611512578063c3d0773d1461141c578063c47f0027146111cd578063cb69605114611181578063cdd0e64c14611134578063cede91a4146110d9578063d028139c14611091578063d2333be71461104b578063d505accf14610bf3578063d73792a914610bb8578063dd62ed3e14610b3f578063e228db9e14610a47578063e30c3978146109f5578063f2fde38b14610935578063f5ea6aff146103275763ffa1ad74146102d3575f80fd5b3461032457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245761032061030c6139d5565b604051918291602083526020830190613845565b0390f35b80fd5b50346103245760e07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610324578060043567ffffffffffffffff8111610932576103789036906004016139a7565b60243567ffffffffffffffff811161092f576103989036906004016139a7565b6103a3939193613822565b60643591821515830361092b576084359373ffffffffffffffffffffffffffffffffffffffff851685036109275760a4359673ffffffffffffffffffffffffffffffffffffffff8816968789036109235761045e92610456918b5460ff8160081c1615809d819e8f92610916575b80156108ff575b61042190613cc4565b60017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0084161790556108d1575b503691613943565b923691613943565b9061047860ff8a5460081c166104738161539d565b61539d565b80519067ffffffffffffffff82116108a45761049e82610499603654613a10565b615478565b602090601f83116001146107e5576104eb92918b91836106e6575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b6036555b80519067ffffffffffffffff82116107b85761051582610510603754613a10565b615428565b602090601f83116001146106f157826106329361063796959361056a938d926106e65750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b6037555b61058260ff8a5460081c166104738161539d565b61058b33614a2e565b61059f60ff8a5460081c166104738161539d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00606554166065557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e0054167fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e0055614528565b61513a565b61063f615057565b73ffffffffffffffffffffffffffffffffffffffff81166106d7575b506106bd575b506106695780f35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff81541681557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160018152a180f35b6106c690614ac1565b6106d160c435615320565b5f610661565b6106e09061520b565b5f61065b565b015190505f806104b9565b60378a527f42a7b7dd785cd69714a189dffb3fd7d7174edc9ece837694ce50f7078f7c31ae91907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084168b5b8181106107a057509260019285926106329661063799989610610769575b505050811b0160375561056e565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690555f808061075b565b9293602060018192878601518155019501930161073d565b6024897f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b60368b527f4a11f94e20a93c79f6ec743a1954ec4fc2c08429ae2122118bf234b2185c81b891907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084168c5b81811061088c5750908460019594939210610855575b505050811b016036556104ef565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690555f8080610847565b92936020600181928786015181550195019301610831565b60248a7f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016610101178d555f61044e565b50303b158015610418575060ff8316600114610418565b50600160ff841610610411565b8980fd5b8780fd5b8680fd5b50505b50fd5b50346103245760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245773ffffffffffffffffffffffffffffffffffffffff6109826137dc565b61098a61433e565b16807fffffffffffffffffffffffff000000000000000000000000000000000000000060c954161760c95573ffffffffffffffffffffffffffffffffffffffff609754167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227008380a380f35b503461032457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261032457602073ffffffffffffffffffffffffffffffffffffffff60c95416604051908152f35b503461032457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261032457610a7e613fb2565b7fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e005460ff8116610b17577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001177fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e0055337fcde56c25ba81700e735cf994c9de43284a320e875b46acd6f675e159447997aa8280a280f35b6004827f3c5827f5000000000000000000000000000000000000000000000000000000008152fd5b50346103245760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245773ffffffffffffffffffffffffffffffffffffffff6040610b8e6137dc565b9282610b986137ff565b9416815260346020522091165f52602052602060405f2054604051908152f35b503461032457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245760206040516127108152f35b50346103245760e07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261032457610c2b6137dc565b610c336137ff565b604435606435926084359060ff821682036110475784421161101f579073ffffffffffffffffffffffffffffffffffffffff610d679216938487527f61eb30d84d4dfa1c5d0f066f60f5c357c05c83c2a042c60a480d47da764838006020526040872054956040519073ffffffffffffffffffffffffffffffffffffffff60208301937f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98552886040850152169788606084015286608084015260a083015260c082015260c08152610d0660e082613902565b519020610d11613c4f565b916040519160208301937f190100000000000000000000000000000000000000000000000000000000000085526022840152604283015260428252610d57606283613902565b60c4359260a43592519020615520565b506004811015610ff25760038114610fca57600114610fa25773ffffffffffffffffffffffffffffffffffffffff83911603610f7a578184527f61eb30d84d4dfa1c5d0f066f60f5c357c05c83c2a042c60a480d47da764838006020526040842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610f4d5760010190558115610eca578215610e465760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925918386526034825260408620855f5282528060405f2055604051908152a380f35b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152fd5b60846040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152fd5b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6004847f40622f2c000000000000000000000000000000000000000000000000000000008152fd5b6004857f40622f2c000000000000000000000000000000000000000000000000000000008152fd5b6004867fbf4bf5b8000000000000000000000000000000000000000000000000000000008152fd5b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526021600452fd5b6004867f0819bdcd000000000000000000000000000000000000000000000000000000008152fd5b8580fd5b50346103245760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261032457611083613fb2565b61108e600435615320565b80f35b50346103245760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245761108e6110cc6137dc565b6110d4613fb2565b61520b565b503461032457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245760207fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d0154604051908152f35b50346103245760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245761108e61116f6137dc565b611177613822565b9060243590614642565b50346103245760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245760043580151581036111c95761108e90610632613fb2565b5080fd5b50346103245760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245760043567ffffffffffffffff81116111c95761121d9036906004016139a7565b9190611227613fb2565b82156113f457611235613a61565b67ffffffffffffffff84116113c75761125384610499603654613a10565b8293601f81116001146112e557806112c4816112d49387987f08f5223707b366131adf7d7c8ff02aed1f008d8500e0e5b9c43eea5f16692e5298916112da575b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b6036555b604051938493846154c8565b0390a180f35b90508601355f611293565b603684527f4a11f94e20a93c79f6ec743a1954ec4fc2c08429ae2122118bf234b2185c81b87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08216855b8181106113af5750907f08f5223707b366131adf7d7c8ff02aed1f008d8500e0e5b9c43eea5f16692e529596836112d4949310611377575b5050600181811b016036556112c8565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c19908601351690555f80611367565b8588013583556020978801976001909301920161132f565b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b6004827f430f13b3000000000000000000000000000000000000000000000000000000008152fd5b503461032457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261032457611453613fb2565b7fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e005460ff8116156114ea577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00167fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e0055337ff1cb11a61654eb38373854bba216f488f035ac011099ffb689e05b750791264c8280a280f35b6004827f7cbbe1d7000000000000000000000000000000000000000000000000000000008152fd5b50346103245760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261032457604061155461154f6137dc565b613f2b565b6bffffffffffffffffffffffff602083519273ffffffffffffffffffffffffffffffffffffffff81511684520151166020820152f35b50346103245760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261032457600435602435801515808203611703576115d2613fb2565b8284527fe4e4f071f9b1db3b4b73cfb89f93997eef9d90809fdd474c473bf010d9361e0060205260ff6040852054169080821515146116db574684146116b357907fc945e628af909bf426e51924c5a4510c956fc646f614bbe7e71846d0c5ed8ba892918486527fe4e4f071f9b1db3b4b73cfb89f93997eef9d90809fdd474c473bf010d9361e00602052604086209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691161790556116ad604051928392839092916020906040830194151583521515910152565b0390a280f35b6004857f933f5da2000000000000000000000000000000000000000000000000000000008152fd5b6004857f06530442000000000000000000000000000000000000000000000000000000008152fd5b8380fd5b50346103245760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245760206117496117446137dc565b613dc5565b6040519015158152f35b503461032457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610324576020620f4240604051908152f35b50346103245760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245760043567ffffffffffffffff81116111c9576117e09036906004016139a7565b91906117ea613fb2565b8215611977576117f8613b36565b67ffffffffffffffff84116113c75761181684610510603754613a10565b8293601f81116001146118955780611886816112d49387987fc2d62737ded2ee7abbfe468ddaeaf27a953710dfb69dfb43f511adac8050c66498916112da57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b603755604051938493846154c8565b603784527f42a7b7dd785cd69714a189dffb3fd7d7174edc9ece837694ce50f7078f7c31ae7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08216855b81811061195f5750907fc2d62737ded2ee7abbfe468ddaeaf27a953710dfb69dfb43f511adac8050c6649596836112d4949310611927575b5050600181811b016037556112c8565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c19908601351690555f80611917565b858801358355602097880197600190930192016118df565b6004827f04119bc4000000000000000000000000000000000000000000000000000000008152fd5b50346103245760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610324576119d76137dc565b602435906119e433613dc5565b15611bd85773ffffffffffffffffffffffffffffffffffffffff81163003611bb0575090611a10613ffb565b3315611b2c5733815260336020526040812054828110611aa8578290338352603360205203604082205581603554036035556040518281527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60203392a360405190815233907f5380355699fac5266e4d95cf6985cf6a48abe03aa33d07723bdd0338a367af2560203392a35b602060405160018152f35b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152fd5b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152fd5b60ff60655416611c0057611bc381613dc5565b15611bd857611bd3925033614e30565b611a9d565b6004837fc397ba60000000000000000000000000000000000000000000000000000000008152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152fd5b50346103245760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261032457611c966137dc565b60243533835260346020526040832073ffffffffffffffffffffffffffffffffffffffff83165f5260205260405f2054818110611d415703903315610eca5773ffffffffffffffffffffffffffffffffffffffff16918215610e4657604090338152603460205220825f526020528060405f20556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152fd5b346120ae5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae576040516020600435611e068284613902565b5f83527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082013683850137611e39613ffb565b611e4233614a1e565b801561208657825161205e575f80527fe4e4f071f9b1db3b4b73cfb89f93997eef9d90809fdd474c473bf010d9361e00825260ff60405f20541615612036573315611fb257335f526033825260405f2054818110611f2e575f93827fb636c803e5654f044e1b724dda035449558155d348b39be4ffb37988592461bf93611f1f93338852603387520360408720558060355403603555856040518281527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef873392a360405194338652850152608060408501526080840190613845565b918360608201528033930390a3005b608483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152fd5b608482604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152fd5b7f933f5da2000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f2ef88f20000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f53ad03e5000000000000000000000000000000000000000000000000000000005f5260045ffd5b5f80fd5b346120ae5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae576004356120ec613ffb565b6120f533614a1e565b3315611b2c57335f52603360205260405f2054818110611aa8578190335f5260336020520360405f205580603554036035555f6040518281527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60203392a360405190815233907f5380355699fac5266e4d95cf6985cf6a48abe03aa33d07723bdd0338a367af2560203392a3005b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57602073ffffffffffffffffffffffffffffffffffffffff7f42cf13beef4be89e96f7a42d686186f293b460f8ac2f0416fbe254d1afb6ff005416604051908152f35b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5761032061030c613b36565b346120ae5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5760606122716122696137ff565b600435614bef565b509060405192835260208301526040820152f35b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57602073ffffffffffffffffffffffffffffffffffffffff60975416604051908152f35b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5761230c61433e565b60655460ff8116611c00577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0060019116176065557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a1005b346120ae5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5773ffffffffffffffffffffffffffffffffffffffff6123b86137dc565b165f527f61eb30d84d4dfa1c5d0f066f60f5c357c05c83c2a042c60a480d47da76483800602052602060405f2054604051908152f35b346120ae5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae576124356124286137dc565b612430613fb2565b614ac1565b005b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae573373ffffffffffffffffffffffffffffffffffffffff60c954160361248d5761243533614a2e565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f74207468652060448201527f6e6577206f776e657200000000000000000000000000000000000000000000006064820152fd5b346120ae5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5760043561254b6137ff565b60443567ffffffffffffffff81116120ae57366023820112156120ae5761257c903690602481600401359101613943565b60643591612588613ffb565b61259133614a1e565b83156120865773ffffffffffffffffffffffffffffffffffffffff1692831580159081806126f0575b6126c857841591826126b0575b505061205e57825f527fe4e4f071f9b1db3b4b73cfb89f93997eef9d90809fdd474c473bf010d9361e0060205260ff60405f20541615612036573315611b2c57335f52603360205260405f2054818110611aa8577fb636c803e5654f044e1b724dda035449558155d348b39be4ffb37988592461bf92826126a292335f5260336020520360405f205582603554036035555f6040518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60203392a3604051923384526020840152608060408401526080830190613845565b9260608201528033930390a3005b91506126be575b85806125c7565b50815115156126b7565b7fea2cbb63000000000000000000000000000000000000000000000000000000005f5260045ffd5b50835115156125ba565b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5761273061433e565b7fffc0fd93000000000000000000000000000000000000000000000000000000005f5260045ffd5b346120ae5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5773ffffffffffffffffffffffffffffffffffffffff6127a46137dc565b165f526033602052602060405f2054604051908152f35b346120ae5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5760043567ffffffffffffffff81116120ae5761280a903690600401613888565b9060243567ffffffffffffffff81116120ae5761282b903690600401613888565b90612834613fb2565b61283c613ffb565b8184148015906128af575b612887575f5b84811061285657005b8061288161286f61286a6001948989613d4f565b613d8c565b61287a838787613d4f565b3590614428565b0161284d565b7fd9b53380000000000000000000000000000000000000000000000000000000005f5260045ffd5b508315612847565b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57602073ffffffffffffffffffffffffffffffffffffffff7f20f9d398b060d72baa41f68a4a570507058bbfd6bb960620e2b61718f38ded005416604051908152f35b346120ae5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5760043567ffffffffffffffff81116120ae57612976903690600401613888565b9060243567ffffffffffffffff81116120ae57366023820112156120ae5780600401359167ffffffffffffffff83116120ae576024820191602436918560061b0101116120ae5760443567ffffffffffffffff81116120ae576129dd903690600401613888565b9390946101067fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00005f5460ff8160081c161580612de3575b612a1d90613cc4565b16175f55612a29613fb2565b6102f25415156102f3546102f45491612b1a6102f6546102f754927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e0054167fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e005560ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e0054169116177fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e0055614528565b7fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7f20f9d398b060d72baa41f68a4a570507058bbfd6bb960620e2b61718f38ded00547f2bf00e6a94aca31259c54cb21e7ee1f3ef61ee449428a091ba79184f2f068fbe6040805160ff8460a01c16151581525f6020820152a1167f20f9d398b060d72baa41f68a4a570507058bbfd6bb960620e2b61718f38ded0055612bbf615057565b73ffffffffffffffffffffffffffffffffffffffff8116612dd4575b5073ffffffffffffffffffffffffffffffffffffffff8216612dbc575b5050818103612887575f5b818110612d685786865f5b818110612c68577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff5f54165f557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160068152a1005b612c73818385613d4f565b3590815f527fe4e4f071f9b1db3b4b73cfb89f93997eef9d90809fdd474c473bf010d9361e0060205260ff60405f20541615159160018314612d4057468114612036577fc945e628af909bf426e51924c5a4510c956fc646f614bbe7e71846d0c5ed8ba86040600194835f527fe4e4f071f9b1db3b4b73cfb89f93997eef9d90809fdd474c473bf010d9361e00602052815f20867fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008254161790558151908152856020820152a201612c0e565b7f06530442000000000000000000000000000000000000000000000000000000005f5260045ffd5b612d7661286a828487613d4f565b90612d8561286a828689614a0e565b916020612d9383878a614a0e565b01356bffffffffffffffffffffffff811681036120ae57600193612db692614826565b01612c03565b612dc8612dcd92614ac1565b615320565b8680612bf8565b612ddd9061520b565b88612bdb565b50600660ff821610612a14565b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57602060ff606554166040519015158152f35b346120ae5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57612e676137dc565b612e6f6137ff565b604435906bffffffffffffffffffffffff821682036120ae5761243592612e94613fb2565b614826565b346120ae5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57612435612ed36137ff565b60043533614642565b346120ae5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57612435612f166137dc565b612f1e613fb2565b614528565b346120ae5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae576004355f527fe4e4f071f9b1db3b4b73cfb89f93997eef9d90809fdd474c473bf010d9361e00602052602060ff60405f2054166040519015158152f35b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57602073ffffffffffffffffffffffffffffffffffffffff7fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d005416604051908152f35b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57602060ff7f20f9d398b060d72baa41f68a4a570507058bbfd6bb960620e2b61718f38ded005460a01c166040519015158152f35b346120ae5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5761243561309b6137dc565b6130a361433e565b6130ab613ffb565b60243590614428565b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae576130ea61433e565b6130f26143bd565b6130fa6143bd565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00606554166065557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a1005b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5760606131866141af565b90604051921515835260208301526040820152f35b346120ae5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae576131d26137dc565b335f52603460205260405f2073ffffffffffffffffffffffffffffffffffffffff82165f5260205261320b60405f206024359054613c0b565b903315610eca5773ffffffffffffffffffffffffffffffffffffffff16908115610e4657335f52603460205260405f20825f526020528060405f20556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5760206132b6613c4f565b604051908152f35b346120ae5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5760206132b6602435600435613c25565b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57602060405160068152f35b346120ae5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5761336d6137dc565b6133756137ff565b6044359061338283613dc5565b156134925773ffffffffffffffffffffffffffffffffffffffff8116300361346657509073ffffffffffffffffffffffffffffffffffffffff906133c4613ffb565b6133cf83338361404e565b16908115611b2c57815f52603360205260405f2054818110611aa8578190835f5260336020520360405f205580603554036035555f827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6020604051858152a36040519081527f5380355699fac5266e4d95cf6985cf6a48abe03aa33d07723bdd0338a367af2560203392a3602060405160018152f35b60ff60655416611c005761347981613dc5565b1561349257611bd39261348d83338361404e565b614e30565b7fc397ba60000000000000000000000000000000000000000000000000000000005f5260045ffd5b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae576020603554604051908152f35b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57602060ff7fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e0054166040519015158152f35b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5760206040517f00000000000000000000000000000000000000000000000000000000006acfc08152f35b346120ae5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae576135e36137dc565b602435903315610eca5773ffffffffffffffffffffffffffffffffffffffff16908115610e4657335f52603460205260405f20825f526020528060405f20556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5761032061030c613a61565b346120ae5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae576136c96137dc565b73ffffffffffffffffffffffffffffffffffffffff602435916136ea613fb2565b6136f2613ffb565b16908115611b2c57815f52603360205260405f2054818110611aa8578190835f5260336020520360405f205580603554036035555f827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6020604051858152a36040519081527fa0222c54f2ca627a77e5ce2b2b1346919bc0357e1501f9817c567e5151397c8160203392a3005b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5760209060ff7fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e00541615158152f35b6004359073ffffffffffffffffffffffffffffffffffffffff821682036120ae57565b6024359073ffffffffffffffffffffffffffffffffffffffff821682036120ae57565b6044359073ffffffffffffffffffffffffffffffffffffffff821682036120ae57565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602080948051918291828752018686015e5f8582860101520116010190565b9181601f840112156120ae5782359167ffffffffffffffff83116120ae576020808501948460051b0101116120ae57565b6040810190811067ffffffffffffffff8211176138d557604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176138d557604052565b92919267ffffffffffffffff82116138d5576040519161398b601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200184613902565b8294818452818301116120ae578281602093845f960137010152565b9181601f840112156120ae5782359167ffffffffffffffff83116120ae57602083818601950101116120ae57565b604051906139e4604083613902565b600582527f312e332e300000000000000000000000000000000000000000000000000000006020830152565b90600182811c92168015613a57575b6020831014613a2a57565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b91607f1691613a1f565b604051905f8260365491613a7483613a10565b8083529260018116908115613af95750600114613a9a575b613a9892500383613902565b565b5060365f90815290917f4a11f94e20a93c79f6ec743a1954ec4fc2c08429ae2122118bf234b2185c81b85b818310613add575050906020613a9892820101613a8c565b6020919350806001915483858901015201910190918492613ac5565b60209250613a989491507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001682840152151560051b820101613a8c565b604051905f8260375491613b4983613a10565b8083529260018116908115613af95750600114613b6c57613a9892500383613902565b5060375f90815290917f42a7b7dd785cd69714a189dffb3fd7d7174edc9ece837694ce50f7078f7c31ae5b818310613baf575050906020613a9892820101613a8c565b6020919350806001915483858901015201910190918492613b97565b81810292918115918404141715613bde57565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b91908201809211613bde57565b91908203918211613bde57565b90613c2f91613bcb565b612710810190818111613bde5761270f01908111613bde57612710900490565b613c57613a61565b60208151910120613c666139d5565b602081519101206040519060208201927f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8452604083015260608201524660808201523060a082015260a08152613cbe60c082613902565b51902090565b15613ccb57565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152fd5b9190811015613d5f5760051b0190565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b3573ffffffffffffffffffffffffffffffffffffffff811681036120ae5790565b908160209103126120ae575180151581036120ae5790565b7f20f9d398b060d72baa41f68a4a570507058bbfd6bb960620e2b61718f38ded00549073ffffffffffffffffffffffffffffffffffffffff8216918215613f245760a01c60ff1615613ea65773ffffffffffffffffffffffffffffffffffffffff602460209260405194859384927fd67d92930000000000000000000000000000000000000000000000000000000084521660048301525afa908115613e9b575f91613e6f575090565b613e91915060203d602011613e94575b613e898183613902565b810190613dad565b90565b503d613e7f565b6040513d5f823e3d90fd5b602090613f0f9273ffffffffffffffffffffffffffffffffffffffff613eca613b36565b92604051958694859384937f3f699532000000000000000000000000000000000000000000000000000000008552166004840152604060248401526044830190613845565b03915afa908115613e9b575f91613e6f575090565b5050505f90565b73ffffffffffffffffffffffffffffffffffffffff905f6020604051613f50816138b9565b8281520152165f527f6640ca63ab1055811b2fff34942dd505f4876e53399ef208ab1dce6ae1a05d0060205260405f2060405190613f8d826138b9565b5473ffffffffffffffffffffffffffffffffffffffff8116825260a01c602082015290565b73ffffffffffffffffffffffffffffffffffffffff609754163303613fd357565b7f82b42900000000000000000000000000000000000000000000000000000000005f5260045ffd5b60ff7fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e00541661402657565b7f3c5827f5000000000000000000000000000000000000000000000000000000005f5260045ffd5b73ffffffffffffffffffffffffffffffffffffffff909291921690815f52603460205260405f2073ffffffffffffffffffffffffffffffffffffffff84165f5260205260405f20547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81036140c4575b50505050565b81811061413a5703918115610eca5773ffffffffffffffffffffffffffffffffffffffff16918215610e465760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591835f526034825260405f20855f5282528060405f2055604051908152a35f8080806140be565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152fd5b519069ffffffffffffffffffff821682036120ae57565b73ffffffffffffffffffffffffffffffffffffffff7fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d00541680158015614315575b6142ed5760a0600491604051928380927ffeaf968c0000000000000000000000000000000000000000000000000000000082525afa918215613e9b575f915f93614297575b507f00000000000000000000000000000000000000000000000000000000006acfc08212801561426457929190565b5061426f8342613c18565b7fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d015410929190565b9150915060a0813d60a0116142e5575b816142b460a09383613902565b810103126120ae576142c581614198565b5060208101516142dc608060608401519301614198565b5090915f614235565b3d91506142a7565b7fdbf0cc51000000000000000000000000000000000000000000000000000000005f5260045ffd5b507fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d0154156141f0565b73ffffffffffffffffffffffffffffffffffffffff60975416330361435f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b60ff60655416156143ca57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152fd5b73ffffffffffffffffffffffffffffffffffffffff9061444781614a1e565b169081156144ca5761445b81603554613c0b565b603555815f52603360205260405f20818154019055815f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6020604051858152a36040519081527fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f860203392a3565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152fd5b73ffffffffffffffffffffffffffffffffffffffff16801561461a577f20f9d398b060d72baa41f68a4a570507058bbfd6bb960620e2b61718f38ded005473ffffffffffffffffffffffffffffffffffffffff8116908282146145f257827fffffffffffffffffffffffff0000000000000000000000000000000000000000927fc1339da2f9b42376ace637f1b42ade9d753a039e5a3e5804408bf6eca2a748da5f80a316177f20f9d398b060d72baa41f68a4a570507058bbfd6bb960620e2b61718f38ded0055565b7fa741a045000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f8579befe000000000000000000000000000000000000000000000000000000005f5260045ffd5b91909182156147fe5760ff60655416611c005761465d613ffb565b6146678284614bef565b959280949150156147d65760205f73ffffffffffffffffffffffffffffffffffffffff61469681891698613f2b565b5116604051838101917f23b872dd0000000000000000000000000000000000000000000000000000000083523360248301526044820152866064820152606481526146e2608482613902565b519082895af115613e9b575f513d6147cd5750843b155b6147a1578061471d8573ffffffffffffffffffffffffffffffffffffffff93614428565b1680956040519086825283602083015284604083015285606083015260808201527f266cb7b7fab0e05f62db43ccf0f69ea06da18caacaa5455f660f446c8052420260a03392a36040519384526020840152604083015260608201527f555c71c6830c54b86264d925c520cf52a5e6bd594131f3304642cf22fecb0c4a60803392a3565b847f5274afe7000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b600114156146f9565b7f0c52973e000000000000000000000000000000000000000000000000000000005f5260045ffd5b7fca09496c000000000000000000000000000000000000000000000000000000005f5260045ffd5b90916bffffffffffffffffffffffff1690600a82116149e65773ffffffffffffffffffffffffffffffffffffffff1691825f527f6640ca63ab1055811b2fff34942dd505f4876e53399ef208ab1dce6ae1a05d0060205260405f20906040519161488f836138b9565b549273ffffffffffffffffffffffffffffffffffffffff84169384845260a01c73ffffffffffffffffffffffffffffffffffffffff60208501938285521694851490816149dc575b506147fe577f014b4057d13fb46e4995114fcdff6155d3f8f6420a685ae0a02d1f0e592788aa936bffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff60809560405161492f816138b9565b848152602081018681528a5f527f6640ca63ab1055811b2fff34942dd505f4876e53399ef208ab1dce6ae1a05d006020528360405f209251167fffffffffffffffffffffffff000000000000000000000000000000000000000083541617825551837fffffffffffffffffffffffff000000000000000000000000000000000000000083549260a01b169116179055511693511690604051938452602084015260408301526060820152a2565b905081145f6148d7565b7fcd4e6167000000000000000000000000000000000000000000000000000000005f5260045ffd5b9190811015613d5f5760061b0190565b614a2790613dc5565b1561349257565b7fffffffffffffffffffffffff000000000000000000000000000000000000000060c9541660c95573ffffffffffffffffffffffffffffffffffffffff80609754921691827fffffffffffffffffffffffff0000000000000000000000000000000000000000821617609755167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3565b7fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d00549073ffffffffffffffffffffffffffffffffffffffff82169173ffffffffffffffffffffffffffffffffffffffff821692808414614bae576040805173ffffffffffffffffffffffffffffffffffffffff92831681529390911660208401527fffffffffffffffffffffffff0000000000000000000000000000000000000000927fb7261e9c33aa7c56209c3bf60b424a8f9551ce28876c0ab3d0c487695e9434879190a116177fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d0055565b7f42ee2e36000000000000000000000000000000000000000000000000000000005f5260045ffd5b908160209103126120ae575160ff811681036120ae5790565b614bf882613f2b565b73ffffffffffffffffffffffffffffffffffffffff81511615614e0857614c346bffffffffffffffffffffffff6020614c3b9301511683613c25565b8092613c18565b91614c446141af565b809293915092614de057602073ffffffffffffffffffffffffffffffffffffffff916004604051809481937f313ce567000000000000000000000000000000000000000000000000000000008352165afa8015613e9b5760ff915f91614dc1575b501690604d8211613bde576004602073ffffffffffffffffffffffffffffffffffffffff7fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d005416604051928380927f313ce5670000000000000000000000000000000000000000000000000000000082525afa8015613e9b5760ff915f91614d92575b501690604d8211613bde57614d50614d46614d5a93600a0a88613bcb565b620f424090613bcb565b92600a0a90613bcb565b908115614d65570493565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b614db4915060203d602011614dba575b614dac8183613902565b810190614bd6565b5f614d28565b503d614da2565b614dda915060203d602011614dba57614dac8183613902565b5f614ca5565b7fc5a38048000000000000000000000000000000000000000000000000000000005f5260045ffd5b7fed0df96f000000000000000000000000000000000000000000000000000000005f5260045ffd5b73ffffffffffffffffffffffffffffffffffffffff16908115614fd35773ffffffffffffffffffffffffffffffffffffffff16918215614f4f57815f52603360205260405f2054818110614ecb57817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92602092855f52603384520360405f2055845f526033825260405f20818154019055604051908152a3565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152fd5b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152fd5b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152fd5b5f80527fe4e4f071f9b1db3b4b73cfb89f93997eef9d90809fdd474c473bf010d9361e006020527f39f507266064196ef52880354655c05de9f267498299ad0e126312ace22002545460ff16151560018114612d40574615612036577fc945e628af909bf426e51924c5a4510c956fc646f614bbe7e71846d0c5ed8ba860405f928380527fe4e4f071f9b1db3b4b73cfb89f93997eef9d90809fdd474c473bf010d9361e0060205281842060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00825416179055815190815260016020820152a2565b7fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff74ff00000000000000000000000000000000000000007f20f9d398b060d72baa41f68a4a570507058bbfd6bb960620e2b61718f38ded0054927f2bf00e6a94aca31259c54cb21e7ee1f3ef61ee449428a091ba79184f2f068fbe604051806151db8460ff8960a01c16839092916020906040830194151583521515910152565b0390a1151560a01b169116177f20f9d398b060d72baa41f68a4a570507058bbfd6bb960620e2b61718f38ded0055565b7f42cf13beef4be89e96f7a42d686186f293b460f8ac2f0416fbe254d1afb6ff00549073ffffffffffffffffffffffffffffffffffffffff82169173ffffffffffffffffffffffffffffffffffffffff8216928381146152f8576040805173ffffffffffffffffffffffffffffffffffffffff92831681529390911660208401527fffffffffffffffffffffffff0000000000000000000000000000000000000000927f64e7fc3f3d24b9b7ea1e0c7fbe7fdb5a9e9e1aab410fa818accc1d545e809cb89190a116177f42cf13beef4be89e96f7a42d686186f293b460f8ac2f0416fbe254d1afb6ff0055565b7f084bd677000000000000000000000000000000000000000000000000000000005f5260045ffd5b7fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d0154808214614bae5760407fd72ef688fa430b6a285b84371ba35e8a8e0762b32c1deb7be9d9c111ca79f5ea918151908152836020820152a17fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d0155565b156153a457565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152fd5b601f8111615434575050565b60375f5260205f20906020601f840160051c8301931061546e575b601f0160051c01905b818110615463575050565b5f8155600101615458565b909150819061544f565b601f8111615484575050565b60365f5260205f20906020601f840160051c830193106154be575b601f0160051c01905b8181106154b3575050565b5f81556001016154a8565b909150819061549f565b9183602094601f926155037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe095604088526040880190613845565b9587818803910152818652868601375f8582860101520116010190565b91907f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a084116155a4579160209360809260ff5f9560405194855216868401526040830152606082015282805260015afa15613e9b575f5173ffffffffffffffffffffffffffffffffffffffff81161561559a57905f905f90565b505f906001905f90565b5050505f916003919056fea2646970667358221220cfdf8376a8be9a697e763c8b69beba4c10aaa9880cb02afb5b5610105b78d88c64736f6c634300081c0033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"prague","libraries":{},"optimizer":{"enabled":true,"runs":1000000},"outputSelection":{"*":{"":["*"],"*":["*"]}},"viaIR":true},"optimization_runs":1000000,"sourcify_repo_url":null,"decoded_constructor_args":null,"compiler_version":"v0.8.28+commit.7893614a","is_verified_via_verifier_alliance":false,"verified_at":"2026-08-05T19:59:42.826111Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x60a080604052346100d657626acfc06080525f549060ff8260081c16610084575060ff8082160361004a575b6040516155e590816100db823960805181818161358901526142380152f35b60ff90811916175f557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160ff8152a15f61002b565b62461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b6064820152608490fd5b5f80fdfe6080806040526004361015610012575f80fd5b5f905f3560e01c9081630560187e146137805750806306dd04191461369257806306fdde0314613659578063095ea7b3146135ac5780630a1b8005146135545780630b9a59ea146134f55780631397edf91461218457806318160ddd146134ba57806323b872dd146133365780632b47da52146128b7578063313ce567146132fd57806334e73122146132be5780633644e5151461327e578063395093511461319b5780633aeef3d31461314e5780633f4ba83a146130b457806340c10f191461306157806349c7e1fb14612fff5780634cf2ab3214612f2357806350a4efb814612f8f5780635633cb9914612f2357806358bf3c7f14612edc57806359e6951d14612e995780635adcf3a314612e305780635c975abb14612df0578063678f9da2146129275780636953f15a146128b75780636ae459bd146127bb57806370a0823114612758578063715018a6146126fa578063774e522c1461251157806379ba5097146124375780637adbf973146123ee5780637ecebe001461236c5780638456cb59146122d65780638da5cb5b1461228557806394c685da1461222d57806395d89b41146121f457806396fe914f14612184578063a1bee8f1146120b2578063a32da3c714611dc5578063a457c2d714611c5e578063a9059cbb1461199f578063b84c824614611790578063b9bd40fa14611753578063babcc53914611707578063bf4f6c6a1461158a578063bf7d911914611512578063c3d0773d1461141c578063c47f0027146111cd578063cb69605114611181578063cdd0e64c14611134578063cede91a4146110d9578063d028139c14611091578063d2333be71461104b578063d505accf14610bf3578063d73792a914610bb8578063dd62ed3e14610b3f578063e228db9e14610a47578063e30c3978146109f5578063f2fde38b14610935578063f5ea6aff146103275763ffa1ad74146102d3575f80fd5b3461032457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245761032061030c6139d5565b604051918291602083526020830190613845565b0390f35b80fd5b50346103245760e07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610324578060043567ffffffffffffffff8111610932576103789036906004016139a7565b60243567ffffffffffffffff811161092f576103989036906004016139a7565b6103a3939193613822565b60643591821515830361092b576084359373ffffffffffffffffffffffffffffffffffffffff851685036109275760a4359673ffffffffffffffffffffffffffffffffffffffff8816968789036109235761045e92610456918b5460ff8160081c1615809d819e8f92610916575b80156108ff575b61042190613cc4565b60017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0084161790556108d1575b503691613943565b923691613943565b9061047860ff8a5460081c166104738161539d565b61539d565b80519067ffffffffffffffff82116108a45761049e82610499603654613a10565b615478565b602090601f83116001146107e5576104eb92918b91836106e6575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b6036555b80519067ffffffffffffffff82116107b85761051582610510603754613a10565b615428565b602090601f83116001146106f157826106329361063796959361056a938d926106e65750507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b6037555b61058260ff8a5460081c166104738161539d565b61058b33614a2e565b61059f60ff8a5460081c166104738161539d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00606554166065557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e0054167fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e0055614528565b61513a565b61063f615057565b73ffffffffffffffffffffffffffffffffffffffff81166106d7575b506106bd575b506106695780f35b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff81541681557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160018152a180f35b6106c690614ac1565b6106d160c435615320565b5f610661565b6106e09061520b565b5f61065b565b015190505f806104b9565b60378a527f42a7b7dd785cd69714a189dffb3fd7d7174edc9ece837694ce50f7078f7c31ae91907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084168b5b8181106107a057509260019285926106329661063799989610610769575b505050811b0160375561056e565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690555f808061075b565b9293602060018192878601518155019501930161073d565b6024897f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b60368b527f4a11f94e20a93c79f6ec743a1954ec4fc2c08429ae2122118bf234b2185c81b891907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084168c5b81811061088c5750908460019594939210610855575b505050811b016036556104ef565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690555f8080610847565b92936020600181928786015181550195019301610831565b60248a7f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016610101178d555f61044e565b50303b158015610418575060ff8316600114610418565b50600160ff841610610411565b8980fd5b8780fd5b8680fd5b50505b50fd5b50346103245760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245773ffffffffffffffffffffffffffffffffffffffff6109826137dc565b61098a61433e565b16807fffffffffffffffffffffffff000000000000000000000000000000000000000060c954161760c95573ffffffffffffffffffffffffffffffffffffffff609754167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227008380a380f35b503461032457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261032457602073ffffffffffffffffffffffffffffffffffffffff60c95416604051908152f35b503461032457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261032457610a7e613fb2565b7fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e005460ff8116610b17577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001177fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e0055337fcde56c25ba81700e735cf994c9de43284a320e875b46acd6f675e159447997aa8280a280f35b6004827f3c5827f5000000000000000000000000000000000000000000000000000000008152fd5b50346103245760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245773ffffffffffffffffffffffffffffffffffffffff6040610b8e6137dc565b9282610b986137ff565b9416815260346020522091165f52602052602060405f2054604051908152f35b503461032457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245760206040516127108152f35b50346103245760e07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261032457610c2b6137dc565b610c336137ff565b604435606435926084359060ff821682036110475784421161101f579073ffffffffffffffffffffffffffffffffffffffff610d679216938487527f61eb30d84d4dfa1c5d0f066f60f5c357c05c83c2a042c60a480d47da764838006020526040872054956040519073ffffffffffffffffffffffffffffffffffffffff60208301937f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98552886040850152169788606084015286608084015260a083015260c082015260c08152610d0660e082613902565b519020610d11613c4f565b916040519160208301937f190100000000000000000000000000000000000000000000000000000000000085526022840152604283015260428252610d57606283613902565b60c4359260a43592519020615520565b506004811015610ff25760038114610fca57600114610fa25773ffffffffffffffffffffffffffffffffffffffff83911603610f7a578184527f61eb30d84d4dfa1c5d0f066f60f5c357c05c83c2a042c60a480d47da764838006020526040842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610f4d5760010190558115610eca578215610e465760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925918386526034825260408620855f5282528060405f2055604051908152a380f35b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152fd5b60846040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152fd5b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6004847f40622f2c000000000000000000000000000000000000000000000000000000008152fd5b6004857f40622f2c000000000000000000000000000000000000000000000000000000008152fd5b6004867fbf4bf5b8000000000000000000000000000000000000000000000000000000008152fd5b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526021600452fd5b6004867f0819bdcd000000000000000000000000000000000000000000000000000000008152fd5b8580fd5b50346103245760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261032457611083613fb2565b61108e600435615320565b80f35b50346103245760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245761108e6110cc6137dc565b6110d4613fb2565b61520b565b503461032457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245760207fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d0154604051908152f35b50346103245760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245761108e61116f6137dc565b611177613822565b9060243590614642565b50346103245760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245760043580151581036111c95761108e90610632613fb2565b5080fd5b50346103245760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245760043567ffffffffffffffff81116111c95761121d9036906004016139a7565b9190611227613fb2565b82156113f457611235613a61565b67ffffffffffffffff84116113c75761125384610499603654613a10565b8293601f81116001146112e557806112c4816112d49387987f08f5223707b366131adf7d7c8ff02aed1f008d8500e0e5b9c43eea5f16692e5298916112da575b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b6036555b604051938493846154c8565b0390a180f35b90508601355f611293565b603684527f4a11f94e20a93c79f6ec743a1954ec4fc2c08429ae2122118bf234b2185c81b87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08216855b8181106113af5750907f08f5223707b366131adf7d7c8ff02aed1f008d8500e0e5b9c43eea5f16692e529596836112d4949310611377575b5050600181811b016036556112c8565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c19908601351690555f80611367565b8588013583556020978801976001909301920161132f565b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b6004827f430f13b3000000000000000000000000000000000000000000000000000000008152fd5b503461032457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261032457611453613fb2565b7fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e005460ff8116156114ea577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00167fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e0055337ff1cb11a61654eb38373854bba216f488f035ac011099ffb689e05b750791264c8280a280f35b6004827f7cbbe1d7000000000000000000000000000000000000000000000000000000008152fd5b50346103245760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261032457604061155461154f6137dc565b613f2b565b6bffffffffffffffffffffffff602083519273ffffffffffffffffffffffffffffffffffffffff81511684520151166020820152f35b50346103245760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261032457600435602435801515808203611703576115d2613fb2565b8284527fe4e4f071f9b1db3b4b73cfb89f93997eef9d90809fdd474c473bf010d9361e0060205260ff6040852054169080821515146116db574684146116b357907fc945e628af909bf426e51924c5a4510c956fc646f614bbe7e71846d0c5ed8ba892918486527fe4e4f071f9b1db3b4b73cfb89f93997eef9d90809fdd474c473bf010d9361e00602052604086209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691161790556116ad604051928392839092916020906040830194151583521515910152565b0390a280f35b6004857f933f5da2000000000000000000000000000000000000000000000000000000008152fd5b6004857f06530442000000000000000000000000000000000000000000000000000000008152fd5b8380fd5b50346103245760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245760206117496117446137dc565b613dc5565b6040519015158152f35b503461032457807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610324576020620f4240604051908152f35b50346103245760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103245760043567ffffffffffffffff81116111c9576117e09036906004016139a7565b91906117ea613fb2565b8215611977576117f8613b36565b67ffffffffffffffff84116113c75761181684610510603754613a10565b8293601f81116001146118955780611886816112d49387987fc2d62737ded2ee7abbfe468ddaeaf27a953710dfb69dfb43f511adac8050c66498916112da57507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790565b603755604051938493846154c8565b603784527f42a7b7dd785cd69714a189dffb3fd7d7174edc9ece837694ce50f7078f7c31ae7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08216855b81811061195f5750907fc2d62737ded2ee7abbfe468ddaeaf27a953710dfb69dfb43f511adac8050c6649596836112d4949310611927575b5050600181811b016037556112c8565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c19908601351690555f80611917565b858801358355602097880197600190930192016118df565b6004827f04119bc4000000000000000000000000000000000000000000000000000000008152fd5b50346103245760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610324576119d76137dc565b602435906119e433613dc5565b15611bd85773ffffffffffffffffffffffffffffffffffffffff81163003611bb0575090611a10613ffb565b3315611b2c5733815260336020526040812054828110611aa8578290338352603360205203604082205581603554036035556040518281527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60203392a360405190815233907f5380355699fac5266e4d95cf6985cf6a48abe03aa33d07723bdd0338a367af2560203392a35b602060405160018152f35b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152fd5b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152fd5b60ff60655416611c0057611bc381613dc5565b15611bd857611bd3925033614e30565b611a9d565b6004837fc397ba60000000000000000000000000000000000000000000000000000000008152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152fd5b50346103245760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261032457611c966137dc565b60243533835260346020526040832073ffffffffffffffffffffffffffffffffffffffff83165f5260205260405f2054818110611d415703903315610eca5773ffffffffffffffffffffffffffffffffffffffff16918215610e4657604090338152603460205220825f526020528060405f20556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152fd5b346120ae5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae576040516020600435611e068284613902565b5f83527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082013683850137611e39613ffb565b611e4233614a1e565b801561208657825161205e575f80527fe4e4f071f9b1db3b4b73cfb89f93997eef9d90809fdd474c473bf010d9361e00825260ff60405f20541615612036573315611fb257335f526033825260405f2054818110611f2e575f93827fb636c803e5654f044e1b724dda035449558155d348b39be4ffb37988592461bf93611f1f93338852603387520360408720558060355403603555856040518281527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef873392a360405194338652850152608060408501526080840190613845565b918360608201528033930390a3005b608483604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152fd5b608482604051907f08c379a00000000000000000000000000000000000000000000000000000000082526004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152fd5b7f933f5da2000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f2ef88f20000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f53ad03e5000000000000000000000000000000000000000000000000000000005f5260045ffd5b5f80fd5b346120ae5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae576004356120ec613ffb565b6120f533614a1e565b3315611b2c57335f52603360205260405f2054818110611aa8578190335f5260336020520360405f205580603554036035555f6040518281527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60203392a360405190815233907f5380355699fac5266e4d95cf6985cf6a48abe03aa33d07723bdd0338a367af2560203392a3005b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57602073ffffffffffffffffffffffffffffffffffffffff7f42cf13beef4be89e96f7a42d686186f293b460f8ac2f0416fbe254d1afb6ff005416604051908152f35b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5761032061030c613b36565b346120ae5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5760606122716122696137ff565b600435614bef565b509060405192835260208301526040820152f35b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57602073ffffffffffffffffffffffffffffffffffffffff60975416604051908152f35b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5761230c61433e565b60655460ff8116611c00577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0060019116176065557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a1005b346120ae5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5773ffffffffffffffffffffffffffffffffffffffff6123b86137dc565b165f527f61eb30d84d4dfa1c5d0f066f60f5c357c05c83c2a042c60a480d47da76483800602052602060405f2054604051908152f35b346120ae5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae576124356124286137dc565b612430613fb2565b614ac1565b005b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae573373ffffffffffffffffffffffffffffffffffffffff60c954160361248d5761243533614a2e565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f74207468652060448201527f6e6577206f776e657200000000000000000000000000000000000000000000006064820152fd5b346120ae5760807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5760043561254b6137ff565b60443567ffffffffffffffff81116120ae57366023820112156120ae5761257c903690602481600401359101613943565b60643591612588613ffb565b61259133614a1e565b83156120865773ffffffffffffffffffffffffffffffffffffffff1692831580159081806126f0575b6126c857841591826126b0575b505061205e57825f527fe4e4f071f9b1db3b4b73cfb89f93997eef9d90809fdd474c473bf010d9361e0060205260ff60405f20541615612036573315611b2c57335f52603360205260405f2054818110611aa8577fb636c803e5654f044e1b724dda035449558155d348b39be4ffb37988592461bf92826126a292335f5260336020520360405f205582603554036035555f6040518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60203392a3604051923384526020840152608060408401526080830190613845565b9260608201528033930390a3005b91506126be575b85806125c7565b50815115156126b7565b7fea2cbb63000000000000000000000000000000000000000000000000000000005f5260045ffd5b50835115156125ba565b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5761273061433e565b7fffc0fd93000000000000000000000000000000000000000000000000000000005f5260045ffd5b346120ae5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5773ffffffffffffffffffffffffffffffffffffffff6127a46137dc565b165f526033602052602060405f2054604051908152f35b346120ae5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5760043567ffffffffffffffff81116120ae5761280a903690600401613888565b9060243567ffffffffffffffff81116120ae5761282b903690600401613888565b90612834613fb2565b61283c613ffb565b8184148015906128af575b612887575f5b84811061285657005b8061288161286f61286a6001948989613d4f565b613d8c565b61287a838787613d4f565b3590614428565b0161284d565b7fd9b53380000000000000000000000000000000000000000000000000000000005f5260045ffd5b508315612847565b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57602073ffffffffffffffffffffffffffffffffffffffff7f20f9d398b060d72baa41f68a4a570507058bbfd6bb960620e2b61718f38ded005416604051908152f35b346120ae5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5760043567ffffffffffffffff81116120ae57612976903690600401613888565b9060243567ffffffffffffffff81116120ae57366023820112156120ae5780600401359167ffffffffffffffff83116120ae576024820191602436918560061b0101116120ae5760443567ffffffffffffffff81116120ae576129dd903690600401613888565b9390946101067fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00005f5460ff8160081c161580612de3575b612a1d90613cc4565b16175f55612a29613fb2565b6102f25415156102f3546102f45491612b1a6102f6546102f754927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e0054167fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e005560ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e0054169116177fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e0055614528565b7fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff7f20f9d398b060d72baa41f68a4a570507058bbfd6bb960620e2b61718f38ded00547f2bf00e6a94aca31259c54cb21e7ee1f3ef61ee449428a091ba79184f2f068fbe6040805160ff8460a01c16151581525f6020820152a1167f20f9d398b060d72baa41f68a4a570507058bbfd6bb960620e2b61718f38ded0055612bbf615057565b73ffffffffffffffffffffffffffffffffffffffff8116612dd4575b5073ffffffffffffffffffffffffffffffffffffffff8216612dbc575b5050818103612887575f5b818110612d685786865f5b818110612c68577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff5f54165f557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160068152a1005b612c73818385613d4f565b3590815f527fe4e4f071f9b1db3b4b73cfb89f93997eef9d90809fdd474c473bf010d9361e0060205260ff60405f20541615159160018314612d4057468114612036577fc945e628af909bf426e51924c5a4510c956fc646f614bbe7e71846d0c5ed8ba86040600194835f527fe4e4f071f9b1db3b4b73cfb89f93997eef9d90809fdd474c473bf010d9361e00602052815f20867fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008254161790558151908152856020820152a201612c0e565b7f06530442000000000000000000000000000000000000000000000000000000005f5260045ffd5b612d7661286a828487613d4f565b90612d8561286a828689614a0e565b916020612d9383878a614a0e565b01356bffffffffffffffffffffffff811681036120ae57600193612db692614826565b01612c03565b612dc8612dcd92614ac1565b615320565b8680612bf8565b612ddd9061520b565b88612bdb565b50600660ff821610612a14565b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57602060ff606554166040519015158152f35b346120ae5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57612e676137dc565b612e6f6137ff565b604435906bffffffffffffffffffffffff821682036120ae5761243592612e94613fb2565b614826565b346120ae5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57612435612ed36137ff565b60043533614642565b346120ae5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57612435612f166137dc565b612f1e613fb2565b614528565b346120ae5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae576004355f527fe4e4f071f9b1db3b4b73cfb89f93997eef9d90809fdd474c473bf010d9361e00602052602060ff60405f2054166040519015158152f35b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57602073ffffffffffffffffffffffffffffffffffffffff7fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d005416604051908152f35b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57602060ff7f20f9d398b060d72baa41f68a4a570507058bbfd6bb960620e2b61718f38ded005460a01c166040519015158152f35b346120ae5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5761243561309b6137dc565b6130a361433e565b6130ab613ffb565b60243590614428565b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae576130ea61433e565b6130f26143bd565b6130fa6143bd565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00606554166065557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a1005b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5760606131866141af565b90604051921515835260208301526040820152f35b346120ae5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae576131d26137dc565b335f52603460205260405f2073ffffffffffffffffffffffffffffffffffffffff82165f5260205261320b60405f206024359054613c0b565b903315610eca5773ffffffffffffffffffffffffffffffffffffffff16908115610e4657335f52603460205260405f20825f526020528060405f20556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5760206132b6613c4f565b604051908152f35b346120ae5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5760206132b6602435600435613c25565b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57602060405160068152f35b346120ae5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5761336d6137dc565b6133756137ff565b6044359061338283613dc5565b156134925773ffffffffffffffffffffffffffffffffffffffff8116300361346657509073ffffffffffffffffffffffffffffffffffffffff906133c4613ffb565b6133cf83338361404e565b16908115611b2c57815f52603360205260405f2054818110611aa8578190835f5260336020520360405f205580603554036035555f827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6020604051858152a36040519081527f5380355699fac5266e4d95cf6985cf6a48abe03aa33d07723bdd0338a367af2560203392a3602060405160018152f35b60ff60655416611c005761347981613dc5565b1561349257611bd39261348d83338361404e565b614e30565b7fc397ba60000000000000000000000000000000000000000000000000000000005f5260045ffd5b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae576020603554604051908152f35b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae57602060ff7fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e0054166040519015158152f35b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5760206040517f00000000000000000000000000000000000000000000000000000000000000008152f35b346120ae5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae576135e36137dc565b602435903315610eca5773ffffffffffffffffffffffffffffffffffffffff16908115610e4657335f52603460205260405f20825f526020528060405f20556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5761032061030c613a61565b346120ae5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae576136c96137dc565b73ffffffffffffffffffffffffffffffffffffffff602435916136ea613fb2565b6136f2613ffb565b16908115611b2c57815f52603360205260405f2054818110611aa8578190835f5260336020520360405f205580603554036035555f827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6020604051858152a36040519081527fa0222c54f2ca627a77e5ce2b2b1346919bc0357e1501f9817c567e5151397c8160203392a3005b346120ae575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126120ae5760209060ff7fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e00541615158152f35b6004359073ffffffffffffffffffffffffffffffffffffffff821682036120ae57565b6024359073ffffffffffffffffffffffffffffffffffffffff821682036120ae57565b6044359073ffffffffffffffffffffffffffffffffffffffff821682036120ae57565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602080948051918291828752018686015e5f8582860101520116010190565b9181601f840112156120ae5782359167ffffffffffffffff83116120ae576020808501948460051b0101116120ae57565b6040810190811067ffffffffffffffff8211176138d557604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176138d557604052565b92919267ffffffffffffffff82116138d5576040519161398b601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200184613902565b8294818452818301116120ae578281602093845f960137010152565b9181601f840112156120ae5782359167ffffffffffffffff83116120ae57602083818601950101116120ae57565b604051906139e4604083613902565b600582527f312e332e300000000000000000000000000000000000000000000000000000006020830152565b90600182811c92168015613a57575b6020831014613a2a57565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b91607f1691613a1f565b604051905f8260365491613a7483613a10565b8083529260018116908115613af95750600114613a9a575b613a9892500383613902565b565b5060365f90815290917f4a11f94e20a93c79f6ec743a1954ec4fc2c08429ae2122118bf234b2185c81b85b818310613add575050906020613a9892820101613a8c565b6020919350806001915483858901015201910190918492613ac5565b60209250613a989491507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001682840152151560051b820101613a8c565b604051905f8260375491613b4983613a10565b8083529260018116908115613af95750600114613b6c57613a9892500383613902565b5060375f90815290917f42a7b7dd785cd69714a189dffb3fd7d7174edc9ece837694ce50f7078f7c31ae5b818310613baf575050906020613a9892820101613a8c565b6020919350806001915483858901015201910190918492613b97565b81810292918115918404141715613bde57565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b91908201809211613bde57565b91908203918211613bde57565b90613c2f91613bcb565b612710810190818111613bde5761270f01908111613bde57612710900490565b613c57613a61565b60208151910120613c666139d5565b602081519101206040519060208201927f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f8452604083015260608201524660808201523060a082015260a08152613cbe60c082613902565b51902090565b15613ccb57565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152fd5b9190811015613d5f5760051b0190565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b3573ffffffffffffffffffffffffffffffffffffffff811681036120ae5790565b908160209103126120ae575180151581036120ae5790565b7f20f9d398b060d72baa41f68a4a570507058bbfd6bb960620e2b61718f38ded00549073ffffffffffffffffffffffffffffffffffffffff8216918215613f245760a01c60ff1615613ea65773ffffffffffffffffffffffffffffffffffffffff602460209260405194859384927fd67d92930000000000000000000000000000000000000000000000000000000084521660048301525afa908115613e9b575f91613e6f575090565b613e91915060203d602011613e94575b613e898183613902565b810190613dad565b90565b503d613e7f565b6040513d5f823e3d90fd5b602090613f0f9273ffffffffffffffffffffffffffffffffffffffff613eca613b36565b92604051958694859384937f3f699532000000000000000000000000000000000000000000000000000000008552166004840152604060248401526044830190613845565b03915afa908115613e9b575f91613e6f575090565b5050505f90565b73ffffffffffffffffffffffffffffffffffffffff905f6020604051613f50816138b9565b8281520152165f527f6640ca63ab1055811b2fff34942dd505f4876e53399ef208ab1dce6ae1a05d0060205260405f2060405190613f8d826138b9565b5473ffffffffffffffffffffffffffffffffffffffff8116825260a01c602082015290565b73ffffffffffffffffffffffffffffffffffffffff609754163303613fd357565b7f82b42900000000000000000000000000000000000000000000000000000000005f5260045ffd5b60ff7fa9bb159d35c3405794a368b076cfb461c3cfec91ff00ca1c544d07e26a468e00541661402657565b7f3c5827f5000000000000000000000000000000000000000000000000000000005f5260045ffd5b73ffffffffffffffffffffffffffffffffffffffff909291921690815f52603460205260405f2073ffffffffffffffffffffffffffffffffffffffff84165f5260205260405f20547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81036140c4575b50505050565b81811061413a5703918115610eca5773ffffffffffffffffffffffffffffffffffffffff16918215610e465760207f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591835f526034825260405f20855f5282528060405f2055604051908152a35f8080806140be565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152fd5b519069ffffffffffffffffffff821682036120ae57565b73ffffffffffffffffffffffffffffffffffffffff7fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d00541680158015614315575b6142ed5760a0600491604051928380927ffeaf968c0000000000000000000000000000000000000000000000000000000082525afa918215613e9b575f915f93614297575b507f00000000000000000000000000000000000000000000000000000000000000008212801561426457929190565b5061426f8342613c18565b7fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d015410929190565b9150915060a0813d60a0116142e5575b816142b460a09383613902565b810103126120ae576142c581614198565b5060208101516142dc608060608401519301614198565b5090915f614235565b3d91506142a7565b7fdbf0cc51000000000000000000000000000000000000000000000000000000005f5260045ffd5b507fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d0154156141f0565b73ffffffffffffffffffffffffffffffffffffffff60975416330361435f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b60ff60655416156143ca57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152fd5b73ffffffffffffffffffffffffffffffffffffffff9061444781614a1e565b169081156144ca5761445b81603554613c0b565b603555815f52603360205260405f20818154019055815f7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6020604051858152a36040519081527fab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f860203392a3565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152fd5b73ffffffffffffffffffffffffffffffffffffffff16801561461a577f20f9d398b060d72baa41f68a4a570507058bbfd6bb960620e2b61718f38ded005473ffffffffffffffffffffffffffffffffffffffff8116908282146145f257827fffffffffffffffffffffffff0000000000000000000000000000000000000000927fc1339da2f9b42376ace637f1b42ade9d753a039e5a3e5804408bf6eca2a748da5f80a316177f20f9d398b060d72baa41f68a4a570507058bbfd6bb960620e2b61718f38ded0055565b7fa741a045000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f8579befe000000000000000000000000000000000000000000000000000000005f5260045ffd5b91909182156147fe5760ff60655416611c005761465d613ffb565b6146678284614bef565b959280949150156147d65760205f73ffffffffffffffffffffffffffffffffffffffff61469681891698613f2b565b5116604051838101917f23b872dd0000000000000000000000000000000000000000000000000000000083523360248301526044820152866064820152606481526146e2608482613902565b519082895af115613e9b575f513d6147cd5750843b155b6147a1578061471d8573ffffffffffffffffffffffffffffffffffffffff93614428565b1680956040519086825283602083015284604083015285606083015260808201527f266cb7b7fab0e05f62db43ccf0f69ea06da18caacaa5455f660f446c8052420260a03392a36040519384526020840152604083015260608201527f555c71c6830c54b86264d925c520cf52a5e6bd594131f3304642cf22fecb0c4a60803392a3565b847f5274afe7000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b600114156146f9565b7f0c52973e000000000000000000000000000000000000000000000000000000005f5260045ffd5b7fca09496c000000000000000000000000000000000000000000000000000000005f5260045ffd5b90916bffffffffffffffffffffffff1690600a82116149e65773ffffffffffffffffffffffffffffffffffffffff1691825f527f6640ca63ab1055811b2fff34942dd505f4876e53399ef208ab1dce6ae1a05d0060205260405f20906040519161488f836138b9565b549273ffffffffffffffffffffffffffffffffffffffff84169384845260a01c73ffffffffffffffffffffffffffffffffffffffff60208501938285521694851490816149dc575b506147fe577f014b4057d13fb46e4995114fcdff6155d3f8f6420a685ae0a02d1f0e592788aa936bffffffffffffffffffffffff73ffffffffffffffffffffffffffffffffffffffff60809560405161492f816138b9565b848152602081018681528a5f527f6640ca63ab1055811b2fff34942dd505f4876e53399ef208ab1dce6ae1a05d006020528360405f209251167fffffffffffffffffffffffff000000000000000000000000000000000000000083541617825551837fffffffffffffffffffffffff000000000000000000000000000000000000000083549260a01b169116179055511693511690604051938452602084015260408301526060820152a2565b905081145f6148d7565b7fcd4e6167000000000000000000000000000000000000000000000000000000005f5260045ffd5b9190811015613d5f5760061b0190565b614a2790613dc5565b1561349257565b7fffffffffffffffffffffffff000000000000000000000000000000000000000060c9541660c95573ffffffffffffffffffffffffffffffffffffffff80609754921691827fffffffffffffffffffffffff0000000000000000000000000000000000000000821617609755167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3565b7fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d00549073ffffffffffffffffffffffffffffffffffffffff82169173ffffffffffffffffffffffffffffffffffffffff821692808414614bae576040805173ffffffffffffffffffffffffffffffffffffffff92831681529390911660208401527fffffffffffffffffffffffff0000000000000000000000000000000000000000927fb7261e9c33aa7c56209c3bf60b424a8f9551ce28876c0ab3d0c487695e9434879190a116177fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d0055565b7f42ee2e36000000000000000000000000000000000000000000000000000000005f5260045ffd5b908160209103126120ae575160ff811681036120ae5790565b614bf882613f2b565b73ffffffffffffffffffffffffffffffffffffffff81511615614e0857614c346bffffffffffffffffffffffff6020614c3b9301511683613c25565b8092613c18565b91614c446141af565b809293915092614de057602073ffffffffffffffffffffffffffffffffffffffff916004604051809481937f313ce567000000000000000000000000000000000000000000000000000000008352165afa8015613e9b5760ff915f91614dc1575b501690604d8211613bde576004602073ffffffffffffffffffffffffffffffffffffffff7fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d005416604051928380927f313ce5670000000000000000000000000000000000000000000000000000000082525afa8015613e9b5760ff915f91614d92575b501690604d8211613bde57614d50614d46614d5a93600a0a88613bcb565b620f424090613bcb565b92600a0a90613bcb565b908115614d65570493565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b614db4915060203d602011614dba575b614dac8183613902565b810190614bd6565b5f614d28565b503d614da2565b614dda915060203d602011614dba57614dac8183613902565b5f614ca5565b7fc5a38048000000000000000000000000000000000000000000000000000000005f5260045ffd5b7fed0df96f000000000000000000000000000000000000000000000000000000005f5260045ffd5b73ffffffffffffffffffffffffffffffffffffffff16908115614fd35773ffffffffffffffffffffffffffffffffffffffff16918215614f4f57815f52603360205260405f2054818110614ecb57817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92602092855f52603384520360405f2055845f526033825260405f20818154019055604051908152a3565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152fd5b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152fd5b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152fd5b5f80527fe4e4f071f9b1db3b4b73cfb89f93997eef9d90809fdd474c473bf010d9361e006020527f39f507266064196ef52880354655c05de9f267498299ad0e126312ace22002545460ff16151560018114612d40574615612036577fc945e628af909bf426e51924c5a4510c956fc646f614bbe7e71846d0c5ed8ba860405f928380527fe4e4f071f9b1db3b4b73cfb89f93997eef9d90809fdd474c473bf010d9361e0060205281842060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00825416179055815190815260016020820152a2565b7fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff74ff00000000000000000000000000000000000000007f20f9d398b060d72baa41f68a4a570507058bbfd6bb960620e2b61718f38ded0054927f2bf00e6a94aca31259c54cb21e7ee1f3ef61ee449428a091ba79184f2f068fbe604051806151db8460ff8960a01c16839092916020906040830194151583521515910152565b0390a1151560a01b169116177f20f9d398b060d72baa41f68a4a570507058bbfd6bb960620e2b61718f38ded0055565b7f42cf13beef4be89e96f7a42d686186f293b460f8ac2f0416fbe254d1afb6ff00549073ffffffffffffffffffffffffffffffffffffffff82169173ffffffffffffffffffffffffffffffffffffffff8216928381146152f8576040805173ffffffffffffffffffffffffffffffffffffffff92831681529390911660208401527fffffffffffffffffffffffff0000000000000000000000000000000000000000927f64e7fc3f3d24b9b7ea1e0c7fbe7fdb5a9e9e1aab410fa818accc1d545e809cb89190a116177f42cf13beef4be89e96f7a42d686186f293b460f8ac2f0416fbe254d1afb6ff0055565b7f084bd677000000000000000000000000000000000000000000000000000000005f5260045ffd5b7fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d0154808214614bae5760407fd72ef688fa430b6a285b84371ba35e8a8e0762b32c1deb7be9d9c111ca79f5ea918151908152836020820152a17fa23b43bfe83d41df5f8ed4398624686e341868824ee845f21d830b0276bb0d0155565b156153a457565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152fd5b601f8111615434575050565b60375f5260205f20906020601f840160051c8301931061546e575b601f0160051c01905b818110615463575050565b5f8155600101615458565b909150819061544f565b601f8111615484575050565b60365f5260205f20906020601f840160051c830193106154be575b601f0160051c01905b8181106154b3575050565b5f81556001016154a8565b909150819061549f565b9183602094601f926155037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe095604088526040880190613845565b9587818803910152818652868601375f8582860101520116010190565b91907f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a084116155a4579160209360809260ff5f9560405194855216868401526040830152606082015282805260015afa15613e9b575f5173ffffffffffffffffffffffffffffffffffffffff81161561559a57905f905f90565b505f906001905f90565b5050505f916003919056fea2646970667358221220cfdf8376a8be9a697e763c8b69beba4c10aaa9880cb02afb5b5610105b78d88c64736f6c634300081c0033","name":"FundToken","is_blueprint":false,"license_type":"none","is_fully_verified":false,"is_verified_via_eth_bytecode_db":true,"language":"solidity","evm_version":"prague","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":false,"additional_sources":[],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccountingIsNotPaused","type":"error"},{"inputs":[],"name":"AccountingIsPaused","type":"error"},{"inputs":[],"name":"AlreadySet","type":"error"},{"inputs":[],"name":"BadArgsBridgeable","type":"error"},{"inputs":[],"name":"BadArgsOracleConsumable","type":"error"},{"inputs":[],"name":"BadArgsRedeemable","type":"error"},{"inputs":[],"name":"BadArgsSubscribable","type":"error"},{"inputs":[],"name":"BadChainlinkData","type":"error"},{"inputs":[],"name":"BadSignatory","type":"error"},{"inputs":[],"name":"BridgeChainIdDestinationNotSupported","type":"error"},{"inputs":[],"name":"FeeTooHigh","type":"error"},{"inputs":[],"name":"InsufficientPermissions","type":"error"},{"inputs":[],"name":"InvalidArgumentLengths","type":"error"},{"inputs":[],"name":"InvalidName","type":"error"},{"inputs":[],"name":"InvalidSignatureS","type":"error"},{"inputs":[],"name":"InvalidSymbol","type":"error"},{"inputs":[],"name":"InvalidTransferToTokenContract","type":"error"},{"inputs":[],"name":"OnchainDestinationSetForBridgeToBookEntry","type":"error"},{"inputs":[],"name":"OnchainSubscriptionsDisabled","type":"error"},{"inputs":[],"name":"RenounceOwnershipDisabled","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"SignatureExpired","type":"error"},{"inputs":[],"name":"StablecoinNotSupported","type":"error"},{"inputs":[],"name":"TwoDestinationsInvalid","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"ZeroAddressNotAllowed","type":"error"},{"inputs":[],"name":"ZeroSuperstateTokensOutBridgeable","type":"error"},{"inputs":[],"name":"ZeroSuperstateTokensOutSubscribable","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pauser","type":"address"}],"name":"AccountingPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"unpauser","type":"address"}],"name":"AccountingUnpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"burner","type":"address"},{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AdminBurn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldAllowlist","type":"address"},{"indexed":true,"internalType":"address","name":"newAllowlist","type":"address"}],"name":"AllowlistUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"ethDestinationAddress","type":"address"},{"indexed":false,"internalType":"string","name":"otherDestinationAddress","type":"string"},{"indexed":false,"internalType":"uint256","name":"chainId","type":"uint256"}],"name":"Bridge","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"oldIsPublicInstrument","type":"bool"},{"indexed":false,"internalType":"bool","name":"newIsPublicInstrument","type":"bool"}],"name":"IsPublicInstrumentUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"oldName","type":"string"},{"indexed":false,"internalType":"string","name":"newName","type":"string"}],"name":"NameSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"burner","type":"address"},{"indexed":true,"internalType":"address","name":"src","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"OffchainRedeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"chainId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"oldSupported","type":"bool"},{"indexed":false,"internalType":"bool","name":"newSupported","type":"bool"}],"name":"SetChainIdSupport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMaxOracleDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxOracleDelay","type":"uint256"}],"name":"SetMaximumOracleDelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOracle","type":"address"},{"indexed":false,"internalType":"address","name":"newOracle","type":"address"}],"name":"SetOracle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldRedemptionContract","type":"address"},{"indexed":false,"internalType":"address","name":"newRedemptionContract","type":"address"}],"name":"SetRedemptionContract","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stablecoin","type":"address"},{"indexed":false,"internalType":"address","name":"oldSweepDestination","type":"address"},{"indexed":false,"internalType":"address","name":"newSweepDestination","type":"address"},{"indexed":false,"internalType":"uint96","name":"oldFee","type":"uint96"},{"indexed":false,"internalType":"uint96","name":"newFee","type":"uint96"}],"name":"SetStablecoinConfig","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"subscriber","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"stablecoin","type":"address"},{"indexed":false,"internalType":"uint256","name":"stablecoinInAmountAfterFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stablecoinInAmountBeforeFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"superstateTokenOutAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"usdPerSuperstateTokenChainlinkRaw","type":"uint256"}],"name":"Subscribe","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"subscriber","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"stablecoin","type":"address"},{"indexed":false,"internalType":"uint256","name":"stablecoinInAmountAfterFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stablecoinInAmountBeforeFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"superstateTokenOutAmount","type":"uint256"}],"name":"SubscribeV2","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"oldSymbol","type":"string"},{"indexed":false,"internalType":"string","name":"newSymbol","type":"string"}],"name":"SymbolSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINIMUM_ACCEPTABLE_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUPERSTATE_TOKEN_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"accountingPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"accountingPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accountingUnpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"adminBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowlist","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowlistV2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"ethDestinationAddress","type":"address"},{"internalType":"string","name":"otherDestinationAddress","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"}],"name":"bridge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"bridgeToBookEntry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"dsts","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"bulkMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"subscriptionFee","type":"uint256"}],"name":"calculateFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"inAmount","type":"uint256"},{"internalType":"address","name":"stablecoin","type":"address"}],"name":"calculateSuperstateTokenOut","outputs":[{"internalType":"uint256","name":"superstateTokenOutAmount","type":"uint256"},{"internalType":"uint256","name":"stablecoinInAmountAfterFee","type":"uint256"},{"internalType":"uint256","name":"feeOnStablecoinInAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getChainlinkPrice","outputs":[{"internalType":"bool","name":"_isBadData","type":"bool"},{"internalType":"uint256","name":"_updatedAt","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRedemptionContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"address","name":"allowlist","type":"address"},{"internalType":"bool","name":"_isPublicInstrument","type":"bool"},{"internalType":"address","name":"redemption","type":"address"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"uint256","name":"maxDelay","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"stablecoins","type":"address[]"},{"components":[{"internalType":"address","name":"sweepDestination","type":"address"},{"internalType":"uint96","name":"fee","type":"uint96"}],"internalType":"struct ISubscribable.StablecoinConfig[]","name":"stablecoinConfigs","type":"tuple[]"},{"internalType":"uint256[]","name":"supportedChainIds_","type":"uint256[]"}],"name":"initializeV1_2_0","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isAccountingPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"}],"name":"isChainIdSupported","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPublicInstrument","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maximumOracleDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"offchainRedeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"redemptionContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_allowlist","type":"address"}],"name":"setAllowlist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bool","name":"supported","type":"bool"}],"name":"setChainIdSupport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_isPublicInstrument","type":"bool"}],"name":"setIsPublicInstrument","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMaxOracleDelay","type":"uint256"}],"name":"setMaximumOracleDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newName","type":"string"}],"name":"setName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOracle","type":"address"}],"name":"setOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newRedemptionContract","type":"address"}],"name":"setRedemptionContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"stablecoin","type":"address"},{"internalType":"address","name":"newSweepDestination","type":"address"},{"internalType":"uint96","name":"newFee","type":"uint96"}],"name":"setStablecoinConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newSymbol","type":"string"}],"name":"setSymbol","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"inAmount","type":"uint256"},{"internalType":"address","name":"stablecoin","type":"address"}],"name":"subscribe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"inAmount","type":"uint256"},{"internalType":"address","name":"stablecoin","type":"address"}],"name":"subscribe","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"superstateOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"}],"name":"supportedChainIds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"stablecoin","type":"address"}],"name":"supportedStablecoins","outputs":[{"components":[{"internalType":"address","name":"sweepDestination","type":"address"},{"internalType":"uint96","name":"fee","type":"uint96"}],"internalType":"struct ISubscribable.StablecoinConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":true,"constructor_args":null}